Atrinik Server 2.5
server/stringbuffer.c
Go to the documentation of this file.
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 }