(file) Return to buf.c CVS log (file) (dir) Up to [OMI] / omi / base

Diff for /omi/base/buf.c between version 1.2 and 1.3

version 1.2, 2015/04/20 18:10:09 version 1.3, 2015/04/20 18:19:49
Line 23 
Line 23 
 */ */
  
 #include "buf.h" #include "buf.h"
 #include "strings.h"  #include <pal/strings.h>
  
 #define _MIN_CAPACITY 256 #define _MIN_CAPACITY 256
  
Line 66 
Line 66 
         capacity = _MIN_CAPACITY;         capacity = _MIN_CAPACITY;
  
     /* Allocate data buffer */     /* Allocate data buffer */
     page = (Page*)malloc(sizeof(Page) + capacity);      page = (Page*)PAL_Malloc(sizeof(Page) + capacity);
  
     if (!page)     if (!page)
         return MI_RESULT_FAILED;         return MI_RESULT_FAILED;
Line 81 
Line 81 
     self->offset = 0;     self->offset = 0;
  
 #ifdef CONFIG_ENABLE_DEBUG #ifdef CONFIG_ENABLE_DEBUG
   #ifdef _PREFAST_
       #pragma prefast(push)
       #pragma prefast(disable:22107)
   #endif
     memset(self->data,0xAA,self->capacity);     memset(self->data,0xAA,self->capacity);
   #ifdef _PREFAST_
       #pragma prefast(pop)
   #endif
 #endif #endif
  
     return MI_RESULT_OK;     return MI_RESULT_OK;
Line 91 
Line 98 
     Buf* self)     Buf* self)
 { {
     if (self->data)     if (self->data)
         free((Page*)self->data - 1);          PAL_Free((Page*)self->data - 1);
 } }
  
 MI_Result Buf_Reserve( MI_Result Buf_Reserve(
Line 108 
Line 115 
         if (self->data)         if (self->data)
         {         {
             page = (Page*)self->data - 1;             page = (Page*)self->data - 1;
             page = (Page*)realloc(page, sizeof(Page) + capacity);              page = (Page*)PAL_Realloc(page, sizeof(Page) + capacity);
 #ifdef CONFIG_ENABLE_DEBUG #ifdef CONFIG_ENABLE_DEBUG
               if (page)
             memset(((char*)(page+1)) + self->capacity,0xAA,capacity - self->capacity);             memset(((char*)(page+1)) + self->capacity,0xAA,capacity - self->capacity);
 #endif #endif
         }         }
         else         else
         {         {
             page = (Page*)malloc(sizeof(Page) + capacity);              page = (Page*)PAL_Malloc(sizeof(Page) + capacity);
 #ifdef CONFIG_ENABLE_DEBUG #ifdef CONFIG_ENABLE_DEBUG
               if(page)
             memset(page,0xAA,sizeof(Page) + capacity);             memset(page,0xAA,sizeof(Page) + capacity);
 #endif #endif
         }         }
Line 132 
Line 141 
     return MI_RESULT_OK;     return MI_RESULT_OK;
 } }
  
 MI_Result Buf_App(  MI_Result __Buf_App(
     Buf* self,     Buf* self,
     const void* data,     const void* data,
     MI_Uint32 size)     MI_Uint32 size)
 { {
     /* Calculate the new size */      MI_Result r = Buf_Reserve(self, self->size + size);
     MI_Uint32 newSize = self->size + size;  
   
     /* Expand allocation if we need more space */  
     if (newSize > self->capacity)  
     {  
         MI_Result r = Buf_Reserve(self, newSize);  
  
         if (r != MI_RESULT_OK)         if (r != MI_RESULT_OK)
             return MI_RESULT_FAILED;             return MI_RESULT_FAILED;
     }  
  
     /* Copy in the new data */  
     memcpy((char*)self->data + self->size, data, size);     memcpy((char*)self->data + self->size, data, size);
     self->size += size;     self->size += size;
  
Line 158 
Line 159 
  
 MI_Result Buf_PackStr( MI_Result Buf_PackStr(
     Buf* self,     Buf* self,
     const MI_Char* x)      const ZChar* x)
 { {
     MI_Uint32 size;     MI_Uint32 size;
  
Line 167 
Line 168 
         return Buf_PackU32(self, 0);         return Buf_PackU32(self, 0);
  
     /* Pack the size of the string (size including null terminator) */     /* Pack the size of the string (size including null terminator) */
     size = (MI_Uint32)Zlen(x) + 1;      size = (MI_Uint32)Tcslen(x) + 1;
     MI_RETURN_ERR(Buf_PackU32(self, size));     MI_RETURN_ERR(Buf_PackU32(self, size));
  
     /* Pack the characters (including the null terminator) */     /* Pack the characters (including the null terminator) */
     MI_RETURN_ERR(Buf_App(self, x, size * sizeof(MI_Char)));      MI_RETURN_ERR(Buf_App(self, x, size * sizeof(ZChar)));
   
       return MI_RESULT_OK;
   }
   
   MI_Result Buf_PackStrLen(
       Buf* self,
       const ZChar* x,
       MI_Uint32 size)
   {
       /* Pack null strings as 0 */
       if (!x)
           return Buf_PackU32(self, 0);
   
       /* Pack the size of the string (size including null terminator) */
       MI_RETURN_ERR(Buf_PackU32(self, size + 1));
   
       /* Pack the characters (including the null terminator) */
       MI_RETURN_ERR(Buf_App(self, x, (size + 1) * sizeof(ZChar)));
  
     return MI_RESULT_OK;     return MI_RESULT_OK;
 } }
Line 281 
Line 300 
  
 MI_Result Buf_UnpackStr( MI_Result Buf_UnpackStr(
     Buf* self,     Buf* self,
     const MI_Char** x)      const ZChar** x)
 { {
     MI_Uint32 size;     MI_Uint32 size;
  
Line 295 
Line 314 
     }     }
  
     /* Check whether there are enough bytes left */     /* Check whether there are enough bytes left */
     if (self->offset + size * sizeof(MI_Char) > self->size)      if (self->offset + size * sizeof(ZChar) > self->size)
         return MI_RESULT_FAILED;         return MI_RESULT_FAILED;
  
     /* Store pointer to array */     /* Store pointer to array */
     *x = (const MI_Char*)((char*)self->data + self->offset);      *x = (const ZChar*)((char*)self->data + self->offset);
     self->offset += size * sizeof(MI_Char);      self->offset += size * sizeof(ZChar);
  
     return MI_RESULT_OK;     return MI_RESULT_OK;
 } }
  
   MI_Result Buf_PackPtrdiff_t (
           Buf* self,
           ptrdiff_t data)
   {
   #if defined(PAL_64BIT)
           MI_RETURN_ERR(Buf_PackU64(self, (MI_Uint64)data));
   #elif defined(PAL_32BIT)
           MI_RETURN_ERR(Buf_PackU32(self, (MI_Uint32)data));
   #else
       return MI_RESULT_NOT_SUPPORTED;
   #endif
           return MI_RESULT_OK;
   }
   
   MI_Result Buf_UnpackPtrdiff_t (
           Buf* self,
           ptrdiff_t* x)
   {
   #if defined(PAL_64BIT)
           MI_RETURN_ERR(Buf_UnpackU64(self, (MI_Uint64*)x));
   #elif defined(PAL_32BIT)
           MI_RETURN_ERR(Buf_UnpackU32(self, (MI_Uint32*)x));
   #else
           return MI_RESULT_NOT_SUPPORTED;
   #endif
           return MI_RESULT_OK;
   }
   
 MI_Result Buf_PackStrA( MI_Result Buf_PackStrA(
     Buf* self,     Buf* self,
     const MI_Char** data,      const ZChar** data,
     MI_Uint32 size)     MI_Uint32 size)
 { {
     MI_Uint32 i;     MI_Uint32 i;
Line 317 
Line 364 
  
     if (size)     if (size)
     {     {
         MI_Uint32 sizes[64];          ptrdiff_t sizes[64];
           ptrdiff_t offset;
  
         if (!data)         if (!data)
             return MI_RESULT_FAILED;             return MI_RESULT_FAILED;
  
         /* Put sizes of all strings first. Each size is encoded as a 64-bit          MI_RETURN_ERR(Buf_Pad64(self));
   
           /* Let "size(string) times size(ZChar)" be denoted by ZCharSize(string).
           * Put ZCharSize offsets of all strings first.
           *
           * For example: consider the string  "RED\0GREEN\0BLUE\0"
           * We put four ZCharSize offsets in the buffer:
           *           0*sizeof(ZChar) | (4)*sizeof(ZChar) | (4+6)*sizeof(ZChar) | (4+6+5)*sizeof(ZChar)
           *
           * Each ZCharSize offset is encoded as a 64-bit
          * integer. The unpack function replaces this integer with a pointer          * integer. The unpack function replaces this integer with a pointer
          * to the corresponding string. This avoids having to allocate memory          * to the corresponding string. This avoids having to allocate memory
          * for the pointer array while unpacking.          * for the pointer array while unpacking.
          */          */
   
           /* Pack the ZCharSize offsets */
           offset = 0;
         for (i = 0; i < size; i++)         for (i = 0; i < size; i++)
         {         {
             MI_Uint32 n;              ptrdiff_t n;
  
             if (!data[i])             if (!data[i])
                 return MI_RESULT_FAILED;                 return MI_RESULT_FAILED;
  
             n = (MI_Uint32)Zlen(data[i]) + 1;              n = ((ptrdiff_t)Tcslen(data[i]) + 1) * sizeof(ZChar);
  
             /* Save size so that it will not have to be recalculated by the             /* Save size so that it will not have to be recalculated by the
              * next loop using strlen.              * next loop using strlen.
Line 342 
Line 402 
             if (i < MI_COUNT(sizes))             if (i < MI_COUNT(sizes))
                 sizes[i] = n;                 sizes[i] = n;
  
             MI_RETURN_ERR(Buf_PackU64(self, (MI_Uint64)n));              /* Pack according to the platform */
               MI_RETURN_ERR(Buf_PackPtrdiff_t (self, offset));
   
               /* Accumulate the ZCharSizes */
               offset += n;
         }         }
  
           /* Pack the total size */
           MI_RETURN_ERR(Buf_PackPtrdiff_t(self, offset));
   
         /* Pack strings one after the other. */         /* Pack strings one after the other. */
         for (i = 0; i < size; i++)         for (i = 0; i < size; i++)
         {         {
             MI_Uint32 n;             MI_Uint32 n;
  
             if (i < MI_COUNT(sizes))             if (i < MI_COUNT(sizes))
                 n = sizes[i];                  n = (MI_Uint32)sizes[i];
             else             else
                 n = (MI_Uint32)Zlen(data[i]) + 1;                  n = ((MI_Uint32)Tcslen(data[i]) + 1) * sizeof(ZChar);
  
             MI_RETURN_ERR(Buf_App(self, data[i], n * sizeof(MI_Char)));              MI_RETURN_ERR(Buf_App(self, data[i], n));
         }         }
     }     }
  
Line 364 
Line 431 
  
 MI_Result Buf_UnpackStrA( MI_Result Buf_UnpackStrA(
     Buf* self,     Buf* self,
     const MI_Char*** dataOut,      const ZChar*** dataOut,
     MI_Uint32* sizeOut)     MI_Uint32* sizeOut)
 { {
     const MI_Char** data;      const ZChar** data;
     MI_Uint32 size;     MI_Uint32 size;
     MI_Uint32 i;     MI_Uint32 i;
     MI_Uint32 offset;     MI_Uint32 offset;
       ptrdiff_t start;
  
     /* Unpack the size of the array */     /* Unpack the size of the array */
     MI_RETURN_ERR(Buf_UnpackU32(self, &size));     MI_RETURN_ERR(Buf_UnpackU32(self, &size));
Line 387 
Line 455 
     MI_RETURN_ERR(Buf_Align64(self));     MI_RETURN_ERR(Buf_Align64(self));
  
     /* Set pointer data array */     /* Set pointer data array */
     data = (const MI_Char**)((char*)self->data + self->offset);      data = (const ZChar**)((char*)self->data + self->offset);
  
     /* Calculate offset to first string in array (data[0]) */     /* Calculate offset to first string in array (data[0]) */
     offset = self->offset + (size * sizeof(MI_Uint64));      offset = self->offset + ((size+1) * sizeof(ptrdiff_t));
  
     /* Fail if offset is beyond end of buffer */     /* Fail if offset is beyond end of buffer */
     if (offset > self->size)     if (offset > self->size)
         return MI_RESULT_FAILED;         return MI_RESULT_FAILED;
  
     /* Unpack the string sizes and covert to string pointers */      /* Unpack the string ZCharSizes/pointers and convert to string pointers
     for (i = 0; i < size; i++)      *  We intentionally iterate (size + 1) times.
       */
       start = 0;
       for (i = 0; i <= size; i++)
     {     {
         MI_Uint64 tmp;          ptrdiff_t n;
         MI_Uint32 n;  
  
         /* Unpack size of next string in array */         /* Unpack size of next string in array */
         MI_RETURN_ERR(Buf_UnpackU64(self, &tmp));          MI_RETURN_ERR(Buf_UnpackPtrdiff_t (self, &n));
         n = (MI_Uint32)tmp;  
           /* Remember the first element - this will be the base */
           if (i == 0)
               start = n;
  
         /* Fail if not enough room left in buffer for string */         /* Fail if not enough room left in buffer for string */
         if (offset + n * sizeof(MI_Char) > self->size)          if (offset + (n-start) > self->size)
             return MI_RESULT_FAILED;             return MI_RESULT_FAILED;
  
         /* Add string to array */          /* Add string pointer to array */
         data[i] = (MI_Char*)((char*)self->data + offset);          data[i] = (ZChar*)((char*)self->data + offset + (n-start));
         offset += n * sizeof(MI_Char);  
     }     }
  
     /* Update the offset */     /* Update the offset */
     self->offset = offset;      self->offset = offset + (MI_Uint32)(((ptrdiff_t)data[size]) - ((ptrdiff_t)data[0]));
  
     /* Set the output parameters */     /* Set the output parameters */
     *dataOut = data;     *dataOut = data;
Line 505 
Line 577 
  
     return NULL;     return NULL;
 } }
   
   MI_Result Buf_AppStr(
       Buf* self,
       const ZChar* str)
   {
       return Buf_App(self, str, (MI_Uint32)Tcslen(str) * sizeof(ZChar));
   }
   
   MI_Result Buf_AppStrN(
       Buf* self,
       const ZChar* str,
       size_t size)
   {
       return Buf_App(self, str, (MI_Uint32)size * sizeof(ZChar));
   }
   


Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

ViewCVS 0.9.2