|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00046 #include <global.h> 00047 #include <stdarg.h> 00048 00049 static void stringbuffer_ensure(StringBuffer *sb, size_t len); 00050 00054 StringBuffer *stringbuffer_new() 00055 { 00056 StringBuffer *sb = malloc(sizeof(StringBuffer)); 00057 00058 if (!sb) 00059 { 00060 LOG(llevError, "stringbuffer_new(): Out of memory."); 00061 } 00062 00063 sb->size = MAX_BUF; 00064 sb->buf = malloc(sb->size); 00065 sb->pos = 0; 00066 return sb; 00067 } 00068 00075 char *stringbuffer_finish(StringBuffer *sb) 00076 { 00077 char *result; 00078 00079 sb->buf[sb->pos] = '\0'; 00080 result = sb->buf; 00081 free(sb); 00082 return result; 00083 } 00084 00093 const char *stringbuffer_finish_shared(StringBuffer *sb) 00094 { 00095 char *str = stringbuffer_finish(sb); 00096 const char *result = add_string(str); 00097 00098 free(str); 00099 return result; 00100 } 00101 00106 void stringbuffer_append_string(StringBuffer *sb, const char *str) 00107 { 00108 size_t len = strlen(str); 00109 00110 stringbuffer_ensure(sb, len + 1); 00111 memcpy(sb->buf + sb->pos, str, len); 00112 sb->pos += len; 00113 } 00114 00119 void stringbuffer_append_printf(StringBuffer *sb, const char *format, ...) 00120 { 00121 size_t size = MAX_BUF; 00122 00123 for (; ;) 00124 { 00125 int n; 00126 va_list arg; 00127 00128 stringbuffer_ensure(sb, size); 00129 00130 va_start(arg, format); 00131 n = vsnprintf(sb->buf + sb->pos, size, format, arg); 00132 va_end(arg); 00133 00134 if (n > -1 && (size_t) n < size) 00135 { 00136 sb->pos += (size_t) n; 00137 break; 00138 } 00139 00140 /* Precisely what is needed */ 00141 if (n > -1) 00142 { 00143 size = n + 1; 00144 } 00145 /* Twice the old size */ 00146 else 00147 { 00148 size *= 2; 00149 } 00150 } 00151 } 00152 00158 void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2) 00159 { 00160 stringbuffer_ensure(sb, sb2->pos + 1); 00161 memcpy(sb->buf + sb->pos, sb2->buf, sb2->pos); 00162 sb->pos += sb2->pos; 00163 } 00164 00170 static void stringbuffer_ensure(StringBuffer *sb, size_t len) 00171 { 00172 char *tmp; 00173 size_t new_size; 00174 00175 if (sb->pos + len <= sb->size) 00176 { 00177 return; 00178 } 00179 00180 new_size = sb->pos + len + MAX_BUF; 00181 tmp = realloc(sb->buf, new_size); 00182 00183 if (tmp == NULL) 00184 { 00185 LOG(llevError, "stringbuffer_ensure(): Out of memory.\n"); 00186 } 00187 00188 sb->buf = tmp; 00189 sb->size = new_size; 00190 } 00191 00196 size_t stringbuffer_length(StringBuffer *sb) 00197 { 00198 return sb->pos; 00199 }
1.7.4