mirror of
https://github.com/richgel999/ufo_data.git
synced 2025-08-02 11:56:05 -04:00
new files
This commit is contained in:
parent
9939cb0031
commit
4a6cd91da7
417 changed files with 779031 additions and 0 deletions
297
libsoldout/buffer.c
Normal file
297
libsoldout/buffer.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/* buffer.c - automatic buffer structure */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, Natacha Porté
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/********************
|
||||
* GLOBAL VARIABLES *
|
||||
********************/
|
||||
|
||||
/*
|
||||
* COMPILE TIME OPTIONS
|
||||
*
|
||||
* BUFFER_STATS • if defined, stats are kept about memory usage
|
||||
*/
|
||||
|
||||
#ifdef BUFFER_STATS
|
||||
long buffer_stat_nb = 0;
|
||||
size_t buffer_stat_alloc_bytes = 0;
|
||||
#endif
|
||||
|
||||
|
||||
/***************************
|
||||
* STATIC HELPER FUNCTIONS *
|
||||
***************************/
|
||||
|
||||
/* lower • returns the lower-case variant of the input char */
|
||||
static char
|
||||
lower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; }
|
||||
|
||||
|
||||
|
||||
/********************
|
||||
* BUFFER FUNCTIONS *
|
||||
********************/
|
||||
|
||||
/* bufcasecmp • case-insensitive buffer comparison */
|
||||
int
|
||||
bufcasecmp(const struct buf *a, const struct buf *b) {
|
||||
size_t i = 0;
|
||||
size_t cmplen;
|
||||
if (a == b) return 0;
|
||||
if (!a) return -1; else if (!b) return 1;
|
||||
cmplen = (a->size < b->size) ? a->size : b->size;
|
||||
while (i < cmplen && lower(a->data[i]) == lower(b->data[i])) ++i;
|
||||
if (i < a->size) {
|
||||
if (i < b->size) return lower(a->data[i]) - lower(b->data[i]);
|
||||
else return 1; }
|
||||
else { if (i < b->size) return -1;
|
||||
else return 0; } }
|
||||
|
||||
|
||||
/* bufcmp • case-sensitive buffer comparison */
|
||||
int
|
||||
bufcmp(const struct buf *a, const struct buf *b) {
|
||||
size_t i = 0;
|
||||
size_t cmplen;
|
||||
if (a == b) return 0;
|
||||
if (!a) return -1; else if (!b) return 1;
|
||||
cmplen = (a->size < b->size) ? a->size : b->size;
|
||||
while (i < cmplen && a->data[i] == b->data[i]) ++i;
|
||||
if (i < a->size) {
|
||||
if (i < b->size) return a->data[i] - b->data[i];
|
||||
else return 1; }
|
||||
else { if (i < b->size) return -1;
|
||||
else return 0; } }
|
||||
|
||||
|
||||
/* bufcmps • case-sensitive comparison of a string to a buffer */
|
||||
int
|
||||
bufcmps(const struct buf *a, const char *b) {
|
||||
const size_t len = strlen(b);
|
||||
size_t cmplen = len;
|
||||
int r;
|
||||
if (!a || !a->size) return b ? 0 : -1;
|
||||
if (len < a->size) cmplen = a->size;
|
||||
r = strncmp(a->data, b, cmplen);
|
||||
if (r) return r;
|
||||
else if (a->size == len) return 0;
|
||||
else if (a->size < len) return -1;
|
||||
else return 1; }
|
||||
|
||||
|
||||
/* bufdup • buffer duplication */
|
||||
struct buf *
|
||||
bufdup(const struct buf *src, size_t dupunit) {
|
||||
size_t blocks;
|
||||
struct buf *ret;
|
||||
if (src == 0) return 0;
|
||||
ret = malloc(sizeof (struct buf));
|
||||
if (ret == 0) return 0;
|
||||
ret->unit = dupunit;
|
||||
ret->size = src->size;
|
||||
ret->ref = 1;
|
||||
if (!src->size) {
|
||||
ret->asize = 0;
|
||||
ret->data = 0;
|
||||
return ret; }
|
||||
blocks = (src->size + dupunit - 1) / dupunit;
|
||||
ret->asize = blocks * dupunit;
|
||||
ret->data = malloc(ret->asize);
|
||||
if (ret->data == 0) {
|
||||
free(ret);
|
||||
return 0; }
|
||||
memcpy(ret->data, src->data, src->size);
|
||||
#ifdef BUFFER_STATS
|
||||
buffer_stat_nb += 1;
|
||||
buffer_stat_alloc_bytes += ret->asize;
|
||||
#endif
|
||||
return ret; }
|
||||
|
||||
|
||||
/* bufgrow • increasing the allocated size to the given value */
|
||||
int
|
||||
bufgrow(struct buf *buf, size_t neosz) {
|
||||
size_t neoasz;
|
||||
void *neodata;
|
||||
if (!buf || !buf->unit) return 0;
|
||||
if (buf->asize >= neosz) return 1;
|
||||
neoasz = buf->asize + buf->unit;
|
||||
while (neoasz < neosz) neoasz += buf->unit;
|
||||
neodata = realloc(buf->data, neoasz);
|
||||
if (!neodata) return 0;
|
||||
#ifdef BUFFER_STATS
|
||||
buffer_stat_alloc_bytes += (neoasz - buf->asize);
|
||||
#endif
|
||||
buf->data = neodata;
|
||||
buf->asize = neoasz;
|
||||
return 1; }
|
||||
|
||||
|
||||
/* bufnew • allocation of a new buffer */
|
||||
struct buf *
|
||||
bufnew(size_t unit) {
|
||||
struct buf *ret;
|
||||
ret = malloc(sizeof (struct buf));
|
||||
if (ret) {
|
||||
#ifdef BUFFER_STATS
|
||||
buffer_stat_nb += 1;
|
||||
#endif
|
||||
ret->data = 0;
|
||||
ret->size = ret->asize = 0;
|
||||
ret->ref = 1;
|
||||
ret->unit = unit; }
|
||||
return ret; }
|
||||
|
||||
|
||||
/* bufnullterm • NUL-termination of the string array (making a C-string) */
|
||||
void
|
||||
bufnullterm(struct buf *buf) {
|
||||
if (!buf || !buf->unit) return;
|
||||
if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1))
|
||||
buf->data[buf->size] = 0; }
|
||||
|
||||
|
||||
/* bufprintf • formatted printing to a buffer */
|
||||
void
|
||||
bufprintf(struct buf *buf, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
if (!buf || !buf->unit) return;
|
||||
va_start(ap, fmt);
|
||||
vbufprintf(buf, fmt, ap);
|
||||
va_end(ap); }
|
||||
|
||||
|
||||
/* bufput • appends raw data to a buffer */
|
||||
void
|
||||
bufput(struct buf *buf, const void *data, size_t len) {
|
||||
if (!buf) return;
|
||||
if (buf->size + len > buf->asize && !bufgrow(buf, buf->size + len))
|
||||
return;
|
||||
memcpy(buf->data + buf->size, data, len);
|
||||
buf->size += len; }
|
||||
|
||||
|
||||
/* bufputs • appends a NUL-terminated string to a buffer */
|
||||
void
|
||||
bufputs(struct buf *buf, const char *str) {
|
||||
bufput(buf, str, strlen (str)); }
|
||||
|
||||
|
||||
/* bufputc • appends a single char to a buffer */
|
||||
void
|
||||
bufputc(struct buf *buf, char c) {
|
||||
if (!buf) return;
|
||||
if (buf->size + 1 > buf->asize && !bufgrow(buf, buf->size + 1))
|
||||
return;
|
||||
buf->data[buf->size] = c;
|
||||
buf->size += 1; }
|
||||
|
||||
|
||||
/* bufrelease • decrease the reference count and free the buffer if needed */
|
||||
void
|
||||
bufrelease(struct buf *buf) {
|
||||
if (!buf || !buf->unit) return;
|
||||
buf->ref -= 1;
|
||||
if (buf->ref == 0) {
|
||||
#ifdef BUFFER_STATS
|
||||
buffer_stat_nb -= 1;
|
||||
buffer_stat_alloc_bytes -= buf->asize;
|
||||
#endif
|
||||
free(buf->data);
|
||||
free(buf); } }
|
||||
|
||||
|
||||
/* bufreset • frees internal data of the buffer */
|
||||
void
|
||||
bufreset(struct buf *buf) {
|
||||
if (!buf || !buf->unit || !buf->asize) return;
|
||||
#ifdef BUFFER_STATS
|
||||
buffer_stat_alloc_bytes -= buf->asize;
|
||||
#endif
|
||||
free(buf->data);
|
||||
buf->data = 0;
|
||||
buf->size = buf->asize = 0; }
|
||||
|
||||
|
||||
/* bufset • safely assigns a buffer to another */
|
||||
void
|
||||
bufset(struct buf **dest, struct buf *src) {
|
||||
if (src) {
|
||||
if (!src->asize) src = bufdup(src, 1);
|
||||
else src->ref += 1; }
|
||||
bufrelease(*dest);
|
||||
*dest = src; }
|
||||
|
||||
|
||||
/* bufslurp • removes a given number of bytes from the head of the array */
|
||||
void
|
||||
bufslurp(struct buf *buf, size_t len) {
|
||||
if (!buf || !buf->unit || !len) return;
|
||||
if (len >= buf->size) {
|
||||
buf->size = 0;
|
||||
return; }
|
||||
buf->size -= len;
|
||||
memmove(buf->data, buf->data + len, buf->size); }
|
||||
|
||||
|
||||
/* buftoi • converts the numbers at the beginning of the buf into an int */
|
||||
int
|
||||
buftoi(struct buf *buf, size_t offset_i, size_t *offset_o) {
|
||||
int r = 0, neg = 0;
|
||||
size_t i = offset_i;
|
||||
if (!buf || !buf->size) return 0;
|
||||
if (buf->data[i] == '+') i += 1;
|
||||
else if (buf->data[i] == '-') {
|
||||
neg = 1;
|
||||
i += 1; }
|
||||
while (i < buf->size && buf->data[i] >= '0' && buf->data[i] <= '9') {
|
||||
r = (r * 10) + buf->data[i] - '0';
|
||||
i += 1; }
|
||||
if (offset_o) *offset_o = i;
|
||||
return neg ? -r : r; }
|
||||
|
||||
|
||||
|
||||
/* vbufprintf • stdarg variant of formatted printing into a buffer */
|
||||
void
|
||||
vbufprintf(struct buf *buf, const char *fmt, va_list ap) {
|
||||
int n;
|
||||
va_list ap_save;
|
||||
if (buf == 0
|
||||
|| (buf->size >= buf->asize && !bufgrow (buf, buf->size + 1)))
|
||||
return;
|
||||
va_copy(ap_save, ap);
|
||||
n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
||||
if (n >= buf->asize - buf->size) {
|
||||
if (buf->size + n + 1 > buf->asize
|
||||
&& !bufgrow (buf, buf->size + n + 1))
|
||||
return;
|
||||
n = vsnprintf (buf->data + buf->size,
|
||||
buf->asize - buf->size, fmt, ap_save); }
|
||||
va_end(ap_save);
|
||||
if (n < 0) return;
|
||||
buf->size += n; }
|
||||
|
||||
/* vim: set filetype=c: */
|
Loading…
Add table
Add a link
Reference in a new issue