Added SILC Server library.
[silc.git] / lib / silcutil / silcbuffmt.c
index a189c2903a7e145fb6ccc88ee9fbd31e4b4d298a..3c96f862ca1338f7bc93888a60407c170ff3adc2 100644 (file)
@@ -4,12 +4,11 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2002 Pekka Riikonen
+  Copyright (C) 1997 - 2005 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
+  the Free Software Foundation; version 2 of the License.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 */
 /* $Id$ */
 
-#include "silcincludes.h"
+#include "silc.h"
 
 /* Macros to check whether there is enough free space to add the
    required amount of data. For unformatting this means that there must
    be the data that is to be extracted. */
 #define FORMAT_HAS_SPACE(__x__, __req__)       \
   do {                                         \
-    if (__req__ > (__x__)->len)                        \
+    if (__req__ > silc_buffer_len((__x__)))    \
       goto fail;                               \
   } while(0)
 #define UNFORMAT_HAS_SPACE(__x__, __req__)     \
   do {                                         \
-    if (__req__ > (__x__)->len)                        \
+    if (__req__ > silc_buffer_len((__x__)))    \
       goto fail;                               \
     if ((__req__ + 1) <= 0)                    \
       goto fail;                               \
@@ -67,6 +66,19 @@ int silc_buffer_format_vp(SilcBuffer dst, va_list ap)
     fmt = va_arg(ap, SilcBufferParamType);
 
     switch(fmt) {
+    case SILC_BUFFER_PARAM_OFFSET:
+      {
+       int offst = va_arg(ap, int);
+       if (!offst)
+         break;
+       if (offst > 1) {
+         FORMAT_HAS_SPACE(dst, offst);
+         silc_buffer_pull(dst, offst);
+       } else {
+         silc_buffer_push(dst, -(offst));
+       }
+       break;
+      }
     case SILC_BUFFER_PARAM_SI8_CHAR:
       {
        char x = (char)va_arg(ap, int);
@@ -227,6 +239,19 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap)
     fmt = va_arg(ap, SilcBufferParamType);
 
     switch(fmt) {
+    case SILC_BUFFER_PARAM_OFFSET:
+      {
+       int offst = va_arg(ap, int);
+       if (!offst)
+         break;
+       if (offst > 1) {
+         UNFORMAT_HAS_SPACE(src, offst);
+         silc_buffer_pull(src, offst);
+       } else {
+         silc_buffer_push(src, -(offst));
+       }
+       break;
+      }
     case SILC_BUFFER_PARAM_SI8_CHAR:
       {
        char *x = va_arg(ap, char *);
@@ -517,7 +542,50 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap)
 
 int silc_buffer_strformat(SilcBuffer dst, ...)
 {
-  int len = dst->truelen;
+  int len = silc_buffer_truelen(dst);
+  va_list va;
+
+  va_start(va, dst);
+
+  /* Parse the arguments by formatting type. */
+  while(1) {
+    char *string = va_arg(va, char *);
+    unsigned char *d;
+    SilcInt32 slen;
+
+    if (!string)
+      continue;
+    if (string == (char *)SILC_BUFFER_PARAM_END)
+      goto ok;
+
+    slen = strlen(string);
+    d = silc_realloc(dst->head, sizeof(*dst->head) * (slen + len + 1));
+    if (!d)
+      return -1;
+    dst->head = d;
+    memcpy(dst->head + len, string, slen);
+    len += slen;
+    dst->head[len] = '\0';
+  }
+
+  SILC_LOG_DEBUG(("Error occured while formatting buffer"));
+  va_end(va);
+  return -1;
+
+ ok:
+  dst->end = dst->head + len;
+  dst->data = dst->head;
+  dst->tail = dst->end;
+
+  va_end(va);
+  return len;
+}
+
+/* Formats strings into a buffer.  Allocates memory from SilcStack. */
+
+int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...)
+{
+  int len = silc_buffer_truelen(dst);
   va_list va;
 
   va_start(va, dst);
@@ -525,18 +593,22 @@ int silc_buffer_strformat(SilcBuffer dst, ...)
   /* Parse the arguments by formatting type. */
   while(1) {
     char *string = va_arg(va, char *);
+    unsigned char *d;
+    SilcInt32 slen;
 
     if (!string)
       continue;
     if (string == (char *)SILC_BUFFER_PARAM_END)
       goto ok;
 
-    dst->head = silc_realloc(dst->head, sizeof(*dst->head) *
-                            (strlen(string) + len + 1));
-    if (!dst->head)
+    slen = strlen(string);
+    d = silc_srealloc_ua(stack, len, dst->head,
+                        sizeof(*dst->head) * (slen + len + 1));
+    if (!d)
       return -1;
-    memcpy(dst->head + len, string, strlen(string));
-    len += strlen(string);
+    dst->head = d;
+    memcpy(dst->head + len, string, slen);
+    len += slen;
     dst->head[len] = '\0';
   }
 
@@ -548,7 +620,6 @@ int silc_buffer_strformat(SilcBuffer dst, ...)
   dst->end = dst->head + len;
   dst->data = dst->head;
   dst->tail = dst->end;
-  dst->len = dst->truelen = len;
 
   va_end(va);
   return len;