"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "odt2txt-0.4/strbuf.c" of archive odt2txt-0.4.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /*
    2  * strbuf.c: A simple string buffer
    3  *
    4  * Copyright (c) 2006-2008 Dennis Stosberg <dennis@stosberg.net>
    5  *
    6  * This program is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU General Public License,
    8  * version 2 as published by the Free Software Foundation
    9  */
   10 
   11 #include "strbuf.h"
   12 
   13 static const size_t strbuf_start_sz = 128;
   14 static const size_t strbuf_grow_sz = 128;
   15 
   16 static void strbuf_grow(STRBUF *buf); /* enlarge a buffer by strbuf_grow_sz */
   17 
   18 #ifdef STRBUF_CHECK
   19 static void die(const char *format, ...) {
   20 	va_list argp;
   21 	va_start(argp, format);
   22 	vfprintf(stderr, format, argp);
   23 	va_end(argp);
   24 	fprintf(stderr, "\n");
   25 	exit(EXIT_FAILURE);
   26 }
   27 
   28 static void strbuf_check(STRBUF *buf)
   29 {
   30 	if (!buf)
   31 		die("buf is null");
   32 
   33 	if (!buf->data)
   34 		die("buf->data is null");
   35 
   36 	if (!(buf->opt & STRBUF_NULLOK) && strlen(buf->data) != buf->len)
   37 		die("length mismatch. strlen says %u, len says %u",
   38 		    (unsigned int)strlen(buf->data), buf->len);
   39 
   40 	if (buf->len + 1 > buf->buf_sz)
   41 		die("overlap");
   42 }
   43 #else
   44 #define strbuf_check(a)
   45 #endif
   46 
   47 STRBUF *strbuf_new(void)
   48 {
   49 	STRBUF *buf = ymalloc(sizeof(STRBUF));
   50 
   51 	buf->buf_sz = strbuf_start_sz;
   52 	buf->data = ymalloc(strbuf_start_sz);
   53 
   54 	buf->len = 0;
   55 	buf->data[0] = '\0';
   56 
   57 	buf->opt = 0;
   58 
   59 	strbuf_check(buf);
   60 	return buf;
   61 }
   62 
   63 void strbuf_free(STRBUF *buf)
   64 {
   65 	strbuf_check(buf);
   66 
   67 	yfree(buf->data);
   68 	yfree(buf);
   69 }
   70 
   71 void strbuf_shrink(STRBUF *buf)
   72 {
   73 	strbuf_check(buf);
   74 
   75 	buf->buf_sz = buf->len + 1;
   76 	buf->data = yrealloc(buf->data, buf->buf_sz);
   77 
   78 	strbuf_check(buf);
   79 }
   80 
   81 size_t strbuf_append_n(STRBUF *buf, const char *str, size_t n)
   82 {
   83 	strbuf_check(buf);
   84 
   85 	if (n == 0)
   86 		return buf->len;
   87 
   88 	while (buf->len + n + 1 > buf->buf_sz)
   89 		strbuf_grow(buf);
   90 
   91 	memcpy(buf->data + buf->len, str, n);
   92 	buf->len += n;
   93 	*(buf->data + buf->len) = 0;
   94 
   95 	strbuf_check(buf);
   96 	return buf->len;
   97 }
   98 
   99 size_t strbuf_append(STRBUF *buf, const char *str)
  100 {
  101 	return strbuf_append_n(buf, str, strlen(str));
  102 }
  103 
  104 const char *strbuf_get(STRBUF *buf)
  105 {
  106 	strbuf_check(buf);
  107 	return buf->data;
  108 }
  109 
  110 size_t strbuf_len(STRBUF *buf)
  111 {
  112 	strbuf_check(buf);
  113 	return buf->len;
  114 }
  115 
  116 int strbuf_subst(STRBUF *buf,
  117 		 size_t start, size_t stop,
  118 		 const char *subst)
  119 {
  120 	size_t len;
  121 	size_t subst_len;
  122 	int    diff;
  123 
  124 	strbuf_check(buf);
  125 
  126 	if (start > stop) {
  127 		size_t tmp = start;
  128 		start = stop;
  129 		stop = tmp;
  130 	}
  131 
  132 	len = stop - start;
  133 	subst_len = strlen(subst);
  134 	diff = subst_len - len;
  135 
  136 	if (0 > diff) {
  137 		memcpy(buf->data + start, subst, subst_len);
  138 		memmove(buf->data + start + subst_len, buf->data + stop,
  139 			buf->len - stop + 1);
  140 
  141 	} else if (0 == diff) {
  142 		memcpy(buf->data + start, subst, subst_len);
  143 
  144 	} else { /* 0 < diff */
  145 		while (buf->len + diff + 1 > buf->buf_sz)
  146 			strbuf_grow(buf);
  147 
  148 		memmove(buf->data + start + subst_len, buf->data + stop,
  149 			buf->len - stop + 1);
  150 		memcpy(buf->data + start, subst, subst_len);
  151 	}
  152 
  153 	buf->len += diff;
  154 
  155 	strbuf_check(buf);
  156 	return diff;
  157 }
  158 
  159 size_t strbuf_append_inflate(STRBUF *buf, FILE *in)
  160 {
  161 	size_t len;
  162 	z_stream strm;
  163 	Bytef readbuf[1024];
  164 	int z_ret;
  165 	int nullok;
  166 
  167 	strbuf_check(buf);
  168 
  169 	/* save NULLOK flag */
  170 	nullok = (buf->opt & STRBUF_NULLOK) ? 1 : 0;
  171 	strbuf_setopt(buf, STRBUF_NULLOK);
  172 
  173 	/* zlib init */
  174 	strm.zalloc   = Z_NULL;
  175 	strm.zfree    = Z_NULL;
  176 	strm.opaque   = Z_NULL;
  177 	strm.next_in  = Z_NULL;
  178 	strm.avail_in = 0;
  179 
  180 	z_ret = inflateInit2(&strm, -15);
  181 	if (z_ret != Z_OK) {
  182 		fprintf(stderr, "A: zlib returned error: %d\n", z_ret);
  183 		exit(EXIT_FAILURE);
  184 	}
  185 
  186 	do {
  187 		int f_err;
  188 
  189 		strm.avail_in = (uInt)fread(readbuf, 1, sizeof(readbuf), in);
  190 
  191 		f_err = ferror(in);
  192 		if (f_err) {
  193 			(void)inflateEnd(&strm);
  194 			fprintf(stderr, "stdio error: %d\n", f_err);
  195 			exit(EXIT_FAILURE); /* TODO: errmsg? continue? */
  196 		}
  197 
  198 		if (strm.avail_in == 0)
  199 			break;
  200 
  201 		strm.next_in = readbuf;
  202 		do {
  203 			size_t bytes_inflated;
  204 
  205 			while (buf->buf_sz < buf->len + sizeof(readbuf) * 2)
  206 				strbuf_grow(buf);
  207 
  208 			strm.next_out  = (Bytef*)(buf->data + buf->len);
  209 			strm.avail_out = (uInt)(buf->buf_sz - buf->len);
  210 
  211 			z_ret = inflate(&strm, Z_SYNC_FLUSH);
  212 			switch (z_ret) {
  213 			case Z_NEED_DICT:
  214 			case Z_DATA_ERROR:
  215 			case Z_MEM_ERROR:
  216 				(void)inflateEnd(&strm);
  217 				fprintf(stderr, "B: zlib returned error: %d\n", z_ret);
  218 				exit(EXIT_FAILURE);
  219 			}
  220 
  221 			bytes_inflated  = (buf->buf_sz - buf->len) - strm.avail_out;
  222 			buf->len       += bytes_inflated;
  223 
  224 		} while (strm.avail_out == 0);
  225 
  226 	} while (z_ret != Z_STREAM_END);
  227 
  228 	/* terminate buffer */
  229 	if (buf->len + 1 > buf->buf_sz)
  230 		strbuf_grow(buf);
  231 	*(buf->data + buf->len) = '\0';
  232 
  233 	/* restore NULLOK option */
  234 	if (!nullok)
  235 		strbuf_unsetopt(buf, STRBUF_NULLOK);
  236 
  237 	strbuf_check(buf);
  238 
  239 	len = (size_t)strm.total_out;
  240 	(void)inflateEnd(&strm);
  241 
  242 	if (z_ret != Z_STREAM_END) {
  243 		fprintf(stderr, "ERR\n");
  244 		exit(EXIT_FAILURE);
  245 	}
  246 
  247 	return len;
  248 }
  249 
  250 static void strbuf_grow(STRBUF *buf)
  251 {
  252 	buf->buf_sz += strbuf_grow_sz;
  253 	buf->data = yrealloc(buf->data, buf->buf_sz);
  254 
  255 	strbuf_check(buf);
  256 }
  257 
  258 STRBUF *strbuf_slurp(char *str)
  259 {
  260 	return strbuf_slurp_n(str, strlen(str));
  261 }
  262 
  263 STRBUF *strbuf_slurp_n(char *str, size_t len)
  264 {
  265 	STRBUF *buf = ymalloc(sizeof(STRBUF));
  266 	buf->len = len;
  267 	buf->buf_sz = len + 1;
  268 	buf->data = yrealloc(str, buf->buf_sz);
  269 	*(buf->data + len) = '\0';
  270 
  271 	buf->opt = 0;
  272 
  273 	return buf;
  274 }
  275 
  276 char *strbuf_spit(STRBUF *buf)
  277 {
  278 	char *data;
  279 
  280 	strbuf_check(buf);
  281 
  282 	strbuf_shrink(buf);
  283 	data = buf->data;
  284 	yfree(buf);
  285 
  286 	return data;
  287 }
  288 
  289 unsigned int strbuf_crc32(STRBUF *buf)
  290 {
  291 	uLong crc = crc32(0L, Z_NULL, 0);
  292 	crc = crc32(crc, (Bytef *)buf->data, buf->len);
  293 
  294 	return (unsigned int)crc;
  295 }
  296 
  297 void strbuf_setopt(STRBUF *buf, enum strbuf_opt opt)
  298 {
  299 	buf->opt |= opt;
  300 }
  301 
  302 void strbuf_unsetopt(STRBUF *buf, enum strbuf_opt opt)
  303 {
  304 	buf->opt &= ~opt;
  305 }