Added SILC errno API. Added SilcResult, generic error code and
[crypto.git] / lib / silcutil / silcbuffmt.c
index e980d2b6fc199613f4ce92debac66a5e4e527d84..3a789fc90c29935357036dcae871f38dbe43cc38 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2006 Pekka Riikonen
+  Copyright (C) 1997 - 2007 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
 
 /* Check that buffer has enough room to format data in it, if not
    allocate more. */
-#define FORMAT_HAS_SPACE(s, b, req)            \
-do {                                           \
-  if (!silc_buffer_senlarge(s, b, req))                \
-    goto fail;                                 \
-  flen += req;                                 \
+#define FORMAT_HAS_SPACE(s, b, req)                    \
+do {                                                   \
+  if (silc_unlikely(!silc_buffer_senlarge(s, b, req))) \
+    goto fail;                                         \
+  flen += req;                                         \
 } while(0)
 
 /* Check that there is data to be unformatted */
-#define UNFORMAT_HAS_SPACE(b, req)             \
-do {                                           \
-  if (req > silc_buffer_len(b))                        \
-    goto fail;                                 \
-  if ((req + 1) <= 0)                          \
-    goto fail;                                 \
+#define UNFORMAT_HAS_SPACE(b, req)                     \
+do {                                                   \
+  if (silc_unlikely(req > silc_buffer_len(b))) {       \
+    silc_set_errno(SILC_ERR_OVERFLOW);                 \
+    goto fail;                                         \
+  }                                                    \
+  if (silc_unlikely((req + 1) <= 0)) {                 \
+    silc_set_errno(SILC_ERR_UNDERFLOW);                        \
+    goto fail;                                         \
+  }                                                    \
 } while(0)
 
 
@@ -86,20 +90,13 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
     case SILC_PARAM_FUNC:
       {
        SilcBufferFormatFunc func;
-       SilcBufferSFormatFunc funcs;
        void *val;
        void *context;
        int tmp_len;
-       if (!stack)
-         func = va_arg(ap, SilcBufferFormatFunc);
-       else
-         funcs = va_arg(ap, SilcBufferSFormatFunc);
+       func = va_arg(ap, SilcBufferFormatFunc);
        val = va_arg(ap, void *);
        context = va_arg(ap, void *);
-       if (!stack)
-         tmp_len = func(dst, val, context);
-       else
-         tmp_len = funcs(stack, dst, val, context);
+       tmp_len = func(stack, dst, val, context);
        if (tmp_len < 0)
          goto fail;
        if (tmp_len) {
@@ -115,11 +112,13 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
     case SILC_PARAM_UI16_STRING_ALLOC:
     case SILC_PARAM_UI32_STRING_ALLOC:
       {
-       unsigned char *x = va_arg(ap, unsigned char *);
-       SilcUInt32 tmp_len = strlen(x);
-       FORMAT_HAS_SPACE(stack, dst, tmp_len);
-       silc_buffer_put(dst, x, tmp_len);
-       silc_buffer_pull(dst, tmp_len);
+       char *x = va_arg(ap, char *);
+       SilcUInt32 tmp_len = x ? strlen(x) : 0;
+       if (x && tmp_len) {
+         FORMAT_HAS_SPACE(stack, dst, tmp_len);
+         silc_buffer_put(dst, (unsigned char *)x, tmp_len);
+         silc_buffer_pull(dst, tmp_len);
+       }
        break;
       }
     case SILC_PARAM_UI8_NSTRING:
@@ -184,7 +183,7 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
       {
        char x = (char)va_arg(ap, int);
        FORMAT_HAS_SPACE(stack, dst, 1);
-       silc_buffer_put(dst, &x, 1);
+       silc_buffer_put(dst, (unsigned char *)&x, 1);
        silc_buffer_pull(dst, 1);
        break;
       }
@@ -239,8 +238,10 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
        if (!offst)
          break;
        if (offst > 1) {
-         if (offst > silc_buffer_len(dst))
+         if (offst > silc_buffer_len(dst)) {
+           silc_set_errno(SILC_ERR_OVERFLOW);
            goto fail;
+         }
          silc_buffer_pull(dst, offst);
          flen += offst;
        } else {
@@ -258,6 +259,8 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
     default:
       SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
                      "format the data.", fmt));
+      silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
+                           "Bad buffer formatting type %d", fmt);
       goto fail;
       break;
     }
@@ -323,20 +326,13 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
     case SILC_PARAM_FUNC:
       {
        SilcBufferUnformatFunc func;
-       SilcBufferSUnformatFunc funcs;
        void **val;
        void *context;
        int tmp_len;
-       if (!stack)
-         func = va_arg(ap, SilcBufferUnformatFunc);
-       else
-         funcs = va_arg(ap, SilcBufferSUnformatFunc);
+       func = va_arg(ap, SilcBufferUnformatFunc);
        val = va_arg(ap, void **);
        context = va_arg(ap, void *);
-       if (!stack)
-         tmp_len = func(src, val, context);
-       else
-         tmp_len = funcs(stack, src, val, context);
+       tmp_len = func(stack, src, val, context);
        if (tmp_len < 0)
          goto fail;
        if (tmp_len) {
@@ -350,7 +346,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        unsigned char **x = va_arg(ap, unsigned char **);
        SilcUInt32 len2 = va_arg(ap, SilcUInt32);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (len2 && x)
+       if (silc_likely(len2 && x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -361,7 +357,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        unsigned char **x = va_arg(ap, unsigned char **);
        SilcUInt32 len2 = va_arg(ap, SilcUInt32);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (len2 && x) {
+       if (silc_likely(len2 && x)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -372,7 +368,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        unsigned char *x = va_arg(ap, unsigned char *);
        UNFORMAT_HAS_SPACE(src, 1);
-       if (x)
+       if (silc_likely(x))
          *x = src->data[0];
        silc_buffer_pull(src, 1);
        break;
@@ -381,7 +377,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt16 *x = va_arg(ap, SilcUInt16 *);
        UNFORMAT_HAS_SPACE(src, 2);
-       if (x)
+       if (silc_likely(x))
          SILC_GET16_MSB(*x, src->data);
        silc_buffer_pull(src, 2);
        break;
@@ -390,7 +386,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt32 *x = va_arg(ap, SilcUInt32 *);
        UNFORMAT_HAS_SPACE(src, 4);
-       if (x)
+       if (silc_likely(x))
          SILC_GET32_MSB(*x, src->data);
        silc_buffer_pull(src, 4);
        break;
@@ -399,7 +395,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcUInt64 *x = va_arg(ap, SilcUInt64 *);
        UNFORMAT_HAS_SPACE(src, sizeof(SilcUInt64));
-       if (x)
+       if (silc_likely(x))
          SILC_GET64_MSB(*x, src->data);
        silc_buffer_pull(src, sizeof(SilcUInt64));
        break;
@@ -408,7 +404,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        char *x = va_arg(ap, char *);
        UNFORMAT_HAS_SPACE(src, 1);
-       if (x)
+       if (silc_likely(x))
          *x = src->data[0];
        silc_buffer_pull(src, 1);
        break;
@@ -417,7 +413,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt16 *x = va_arg(ap, SilcInt16 *);
        UNFORMAT_HAS_SPACE(src, 2);
-       if (x)
+       if (silc_likely(x))
          SILC_GET16_MSB(*x, src->data);
        silc_buffer_pull(src, 2);
        break;
@@ -426,7 +422,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt32 *x = va_arg(ap, SilcInt32 *);
        UNFORMAT_HAS_SPACE(src, 4);
-       if (x)
+       if (silc_likely(x))
          SILC_GET32_MSB(*x, src->data);
        silc_buffer_pull(src, 4);
        break;
@@ -435,7 +431,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
       {
        SilcInt64 *x = va_arg(ap, SilcInt64 *);
        UNFORMAT_HAS_SPACE(src, sizeof(SilcInt64));
-       if (x)
+       if (silc_likely(x))
          SILC_GET64_MSB(*x, src->data);
        silc_buffer_pull(src, sizeof(SilcInt64));
        break;
@@ -448,7 +444,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        len2 = (SilcUInt8)src->data[0];
        silc_buffer_pull(src, 1);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -461,7 +457,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET16_MSB(len2, src->data);
        silc_buffer_pull(src, 2);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -474,7 +470,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        len2 = (SilcUInt8)src->data[0];
        silc_buffer_pull(src, 1);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -489,7 +485,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET16_MSB(len2, src->data);
        silc_buffer_pull(src, 2);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -504,7 +500,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET32_MSB(len2, src->data);
        silc_buffer_pull(src, 4);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x)
+       if (silc_likely(x))
          *x = src->data;
        silc_buffer_pull(src, len2);
        break;
@@ -517,7 +513,7 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
        SILC_GET32_MSB(len2, src->data);
        silc_buffer_pull(src, 4);
        UNFORMAT_HAS_SPACE(src, len2);
-       if (x && len2) {
+       if (silc_likely(x && len2)) {
          *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
          memcpy(*x, src->data, len2);
        }
@@ -656,6 +652,8 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
     default:
       SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
                      "format the data.", fmt));
+      silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
+                           "Bad buffer formatting type %d", fmt);
       goto fail;
       break;
     }
@@ -702,7 +700,7 @@ int silc_buffer_strformat(SilcBuffer dst, ...)
 
     slen = strlen(string);
     d = silc_realloc(dst->head, sizeof(*dst->head) * (slen + len + 1));
-    if (!d)
+    if (silc_unlikely(!d))
       return -1;
     dst->head = d;
     memcpy(dst->head + len, string, slen);
@@ -745,9 +743,9 @@ int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...)
       goto ok;
 
     slen = strlen(string);
-    d = silc_srealloc_ua(stack, len + 1, dst->head,
-                        sizeof(*dst->head) * (slen + len + 1));
-    if (!d)
+    d = silc_srealloc(stack, len + 1, dst->head,
+                     sizeof(*dst->head) * (slen + len + 1));
+    if (silc_unlikely(!d))
       return -1;
     dst->head = d;
     memcpy(dst->head + len, string, slen);