00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdarg.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #include "global.h"
00028 #include "libproto.h"
00029 #include "stringbuffer.h"
00030
00031
00032 struct StringBuffer {
00037 char *buf;
00038
00044 size_t pos;
00045
00049 size_t size;
00050 };
00051
00052
00061 static void stringbuffer_ensure(StringBuffer *sb, size_t len);
00062
00063
00064 StringBuffer *stringbuffer_new(void) {
00065 StringBuffer *sb;
00066
00067 sb = malloc(sizeof(*sb));
00068 if (sb == NULL) {
00069 fatal(OUT_OF_MEMORY);
00070 }
00071
00072 sb->size = 256;
00073 sb->buf = malloc(sb->size);
00074 sb->pos = 0;
00075 return sb;
00076 }
00077
00078 char *stringbuffer_finish(StringBuffer *sb) {
00079 char *result;
00080
00081 sb->buf[sb->pos] = '\0';
00082 result = sb->buf;
00083 free(sb);
00084 return result;
00085 }
00086
00087 sstring stringbuffer_finish_shared(StringBuffer *sb) {
00088 char *str;
00089 sstring result;
00090
00091 str = stringbuffer_finish(sb);
00092 result = add_string(str);
00093 free(str);
00094 return result;
00095 }
00096
00097 void stringbuffer_append_string(StringBuffer *sb, const char *str) {
00098 size_t len;
00099
00100 len = strlen(str);
00101 stringbuffer_ensure(sb, len+1);
00102 memcpy(sb->buf+sb->pos, str, len);
00103 sb->pos += len;
00104 }
00105
00106 void stringbuffer_append_printf(StringBuffer *sb, const char *format, ...) {
00107 size_t size;
00108
00109 size = 100;
00110 for (;;) {
00111 int n;
00112 va_list arg;
00113
00114 stringbuffer_ensure(sb, size);
00115
00116 va_start(arg, format);
00117 n = vsnprintf(sb->buf+sb->pos, size, format, arg);
00118 va_end(arg);
00119
00120 if (n > -1 && (size_t)n < size) {
00121 sb->pos += (size_t)n;
00122 break;
00123 }
00124
00125 if (n > -1) {
00126 size = n+1;
00127 } else {
00128 size *= 2;
00129 }
00130 }
00131 }
00132
00133 void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2) {
00134 stringbuffer_ensure(sb, sb2->pos+1);
00135 memcpy(sb->buf+sb->pos, sb2->buf, sb2->pos);
00136 sb->pos += sb2->pos;
00137 }
00138
00139 static void stringbuffer_ensure(StringBuffer *sb, size_t len) {
00140 char *tmp;
00141 size_t new_size;
00142
00143 if (sb->pos+len <= sb->size) {
00144 return;
00145 }
00146
00147 new_size = sb->pos+len+256;
00148 tmp = realloc(sb->buf, new_size);
00149 if (tmp == NULL) {
00150 fatal(OUT_OF_MEMORY);
00151 }
00152 sb->buf = tmp;
00153 sb->size = new_size;
00154 }