Nigel Rantor / azure_c_shared_utility

Fork of azure_c_shared_utility by Azure IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers buffer.c Source File

buffer.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #include <stddef.h>
00006 #include <string.h>
00007 #include <stdbool.h>
00008 #include "azure_c_shared_utility/gballoc.h"
00009 #include "azure_c_shared_utility/buffer_.h"
00010 #include "azure_c_shared_utility/optimize_size.h"
00011 #include "azure_c_shared_utility/xlogging.h"
00012 
00013 typedef struct BUFFER_TAG
00014 {
00015     unsigned char* buffer;
00016     size_t size;
00017 } BUFFER;
00018 
00019 /* Codes_SRS_BUFFER_07_001: [BUFFER_new shall allocate a BUFFER_HANDLE that will contain a NULL unsigned char*.] */
00020 BUFFER_HANDLE BUFFER_new(void)
00021 {
00022     BUFFER* temp = (BUFFER*)malloc(sizeof(BUFFER));
00023     /* Codes_SRS_BUFFER_07_002: [BUFFER_new shall return NULL on any error that occurs.] */
00024     if (temp != NULL)
00025     {
00026         temp->buffer = NULL;
00027         temp->size = 0;
00028     }
00029     return (BUFFER_HANDLE)temp;
00030 }
00031 
00032 static int BUFFER_safemalloc(BUFFER* handleptr, size_t size)
00033 {
00034     int result;
00035     size_t sizetomalloc = size;
00036     if (size == 0)
00037     {
00038         sizetomalloc = 1;
00039     }
00040     handleptr->buffer = (unsigned char*)malloc(sizetomalloc);
00041     if (handleptr->buffer == NULL)
00042     {
00043         /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.]*/
00044         LogError("Failure allocating data");
00045         result = __FAILURE__;
00046     }
00047     else
00048     {
00049         // we still consider the real buffer size is 0
00050         handleptr->size = size;
00051         result = 0;
00052     }
00053     return result;
00054 }
00055 
00056 BUFFER_HANDLE BUFFER_create(const unsigned char* source, size_t size)
00057 {
00058     BUFFER* result;
00059     /*Codes_SRS_BUFFER_02_001: [If source is NULL then BUFFER_create shall return NULL.]*/
00060     if (source == NULL)
00061     {
00062         LogError("invalid parameter source: %p", source);
00063         result = NULL;
00064     }
00065     else
00066     {
00067         /*Codes_SRS_BUFFER_02_002: [Otherwise, BUFFER_create shall allocate memory to hold size bytes and shall copy from source size bytes into the newly allocated memory.] */
00068         result = (BUFFER*)malloc(sizeof(BUFFER));
00069         if (result == NULL)
00070         {
00071             /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.] */
00072             /*fallthrough*/
00073             LogError("Failure allocating BUFFER structure");
00074         }
00075         else
00076         {
00077             /* Codes_SRS_BUFFER_02_005: [If size parameter is 0 then 1 byte of memory shall be allocated yet size of the buffer shall be set to 0.]*/
00078             if (BUFFER_safemalloc(result, size) != 0)
00079             {
00080                 LogError("unable to BUFFER_safemalloc ");
00081                 free(result);
00082                 result = NULL;
00083             }
00084             else
00085             {
00086                 /*Codes_SRS_BUFFER_02_004: [Otherwise, BUFFER_create shall return a non-NULL handle.] */
00087                 (void)memcpy(result->buffer, source, size);
00088             }
00089         }
00090     }
00091     return (BUFFER_HANDLE)result;
00092 }
00093 
00094 /* Codes_SRS_BUFFER_07_003: [BUFFER_delete shall delete the data associated with the BUFFER_HANDLE along with the Buffer.] */
00095 void BUFFER_delete(BUFFER_HANDLE handle)
00096 {
00097     /* Codes_SRS_BUFFER_07_004: [BUFFER_delete shall not delete any BUFFER_HANDLE that is NULL.] */
00098     if (handle != NULL)
00099     {
00100         BUFFER* b = (BUFFER*)handle;
00101         if (b->buffer != NULL)
00102         {
00103             /* Codes_SRS_BUFFER_07_003: [BUFFER_delete shall delete the data associated with the BUFFER_HANDLE along with the Buffer.] */
00104             free(b->buffer);
00105         }
00106         free(b);
00107     }
00108 }
00109 
00110 /*return 0 if the buffer was copied*/
00111 /*else return different than zero*/
00112 /* Codes_SRS_BUFFER_07_008: [BUFFER_build allocates size_t bytes, copies the unsigned char* into the buffer and returns zero on success.] */
00113 int BUFFER_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
00114 {
00115     int result;
00116     if (handle == NULL)
00117     {
00118         /* Codes_SRS_BUFFER_07_009: [BUFFER_build shall return nonzero if handle is NULL ] */
00119         result = __FAILURE__;
00120     }
00121     /* Codes_SRS_BUFFER_01_002: [The size argument can be zero, in which case the underlying buffer held by the buffer instance shall be freed.] */
00122     else if (size == 0)
00123     {
00124         /* Codes_SRS_BUFFER_01_003: [If size is zero, source can be NULL.] */
00125         BUFFER* b = (BUFFER*)handle;
00126         free(b->buffer);
00127         b->buffer = NULL;
00128         b->size = 0;
00129 
00130         result = 0;
00131     }
00132     else
00133     {
00134         if (source == NULL)
00135         {
00136             /* Codes_SRS_BUFFER_01_001: [If size is positive and source is NULL, BUFFER_build shall return nonzero] */
00137             result = __FAILURE__;
00138         }
00139         else
00140         {
00141             BUFFER* b = (BUFFER*)handle;
00142             /* Codes_SRS_BUFFER_07_011: [BUFFER_build shall overwrite previous contents if the buffer has been previously allocated.] */
00143             unsigned char* newBuffer = (unsigned char*)realloc(b->buffer, size);
00144             if (newBuffer == NULL)
00145             {
00146                 /* Codes_SRS_BUFFER_07_010: [BUFFER_build shall return nonzero if any error is encountered.] */
00147                 LogError("Failure reallocating buffer");
00148                 result = __FAILURE__;
00149             }
00150             else
00151             {
00152                 b->buffer = newBuffer;
00153                 b->size = size;
00154                 /* Codes_SRS_BUFFER_01_002: [The size argument can be zero, in which case nothing shall be copied from source.] */
00155                 (void)memcpy(b->buffer, source, size);
00156 
00157                 result = 0;
00158             }
00159         }
00160     }
00161 
00162     return result;
00163 }
00164 
00165 int BUFFER_append_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
00166 {
00167     int result;
00168     if (handle == NULL || source == NULL || size == 0)
00169     {
00170         /* Codes_SRS_BUFFER_07_029: [ BUFFER_append_build shall return nonzero if handle or source are NULL or if size is 0. ] */
00171         LogError("BUFFER_append_build failed invalid parameter handle: %p, source: %p, size: %uz", handle, source, size);
00172         result = __FAILURE__;
00173     }
00174     else
00175     {
00176         if (handle->buffer == NULL)
00177         {
00178             /* Codes_SRS_BUFFER_07_030: [ if handle->buffer is NULL BUFFER_append_build shall allocate the a buffer of size bytes... ] */
00179             if (BUFFER_safemalloc(handle, size) != 0)
00180             {
00181                 /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
00182                 LogError("Failure with BUFFER_safemalloc");
00183                 result = __FAILURE__;
00184             }
00185             else
00186             {
00187                 /* Codes_SRS_BUFFER_07_031: [ ... and copy the contents of source to handle->buffer. ] */
00188                 (void)memcpy(handle->buffer, source, size);
00189                 /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
00190                 result = 0;
00191             }
00192         }
00193         else
00194         {
00195             /* Codes_SRS_BUFFER_07_032: [ if handle->buffer is not NULL BUFFER_append_build shall realloc the buffer to be the handle->size + size ] */
00196             unsigned char* temp = (unsigned char*)realloc(handle->buffer, handle->size + size);
00197             if (temp == NULL)
00198             {
00199                 /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
00200                 LogError("Failure reallocating temporary buffer");
00201                 result = __FAILURE__;
00202             }
00203             else
00204             {
00205                 /* Codes_SRS_BUFFER_07_033: [ ... and copy the contents of source to the end of the buffer. ] */
00206                 handle->buffer = temp;
00207                 // Append the BUFFER
00208                 (void)memcpy(&handle->buffer[handle->size], source, size);
00209                 handle->size += size;
00210                 /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
00211                 result = 0;
00212             }
00213         }
00214     }
00215     return result;
00216 }
00217 
00218 /*return 0 if the buffer was pre-build(that is, had its space allocated)*/
00219 /*else return different than zero*/
00220 /* Codes_SRS_BUFFER_07_005: [BUFFER_pre_build allocates size_t bytes of BUFFER_HANDLE and returns zero on success.] */
00221 int BUFFER_pre_build(BUFFER_HANDLE handle, size_t size)
00222 {
00223     int result;
00224     if (handle == NULL)
00225     {
00226         /* Codes_SRS_BUFFER_07_006: [If handle is NULL or size is 0 then BUFFER_pre_build shall return a nonzero value.] */
00227         result = __FAILURE__;
00228     }
00229     else if (size == 0)
00230     {
00231         /* Codes_SRS_BUFFER_07_006: [If handle is NULL or size is 0 then BUFFER_pre_build shall return a nonzero value.] */
00232         result = __FAILURE__;
00233     }
00234     else
00235     {
00236         BUFFER* b = (BUFFER*)handle;
00237         if (b->buffer != NULL)
00238         {
00239             /* Codes_SRS_BUFFER_07_007: [BUFFER_pre_build shall return nonzero if the buffer has been previously allocated and is not NULL.] */
00240             LogError("Failure buffer data is NULL");
00241             result = __FAILURE__;
00242         }
00243         else
00244         {
00245             if ((b->buffer = (unsigned char*)malloc(size)) == NULL)
00246             {
00247                 /* Codes_SRS_BUFFER_07_013: [BUFFER_pre_build shall return nonzero if any error is encountered.] */
00248                 LogError("Failure allocating buffer");
00249                 result = __FAILURE__;
00250             }
00251             else
00252             {
00253                 b->size = size;
00254                 result = 0;
00255             }
00256         }
00257     }
00258     return result;
00259 }
00260 
00261 /* Codes_SRS_BUFFER_07_019: [BUFFER_content shall return the data contained within the BUFFER_HANDLE.] */
00262 int BUFFER_content(BUFFER_HANDLE handle, const unsigned char** content)
00263 {
00264     int result;
00265     if ((handle == NULL) || (content == NULL))
00266     {
00267         /* Codes_SRS_BUFFER_07_020: [If the handle and/or content*is NULL BUFFER_content shall return nonzero.] */
00268         result = __FAILURE__;
00269     }
00270     else
00271     {
00272         BUFFER* b = (BUFFER*)handle;
00273         *content = b->buffer;
00274         result = 0;
00275     }
00276     return result;
00277 }
00278 
00279 /*return 0 if everything went ok and whatever was built in the buffer was unbuilt*/
00280 /* Codes_SRS_BUFFER_07_012: [BUFFER_unbuild shall clear the underlying unsigned char* data associated with the BUFFER_HANDLE this will return zero on success.] */
00281 extern int BUFFER_unbuild(BUFFER_HANDLE handle)
00282 {
00283     int result;
00284     if (handle == NULL)
00285     {
00286         /* Codes_SRS_BUFFER_07_014: [BUFFER_unbuild shall return a nonzero value if BUFFER_HANDLE is NULL.] */
00287         result = __FAILURE__;
00288     }
00289     else
00290     {
00291         BUFFER* b = (BUFFER*)handle;
00292         if (b->buffer != NULL)
00293         {
00294             LogError("Failure buffer data is NULL");
00295             free(b->buffer);
00296             b->buffer = NULL;
00297             b->size = 0;
00298             result = 0;
00299         }
00300         else
00301         {
00302             /* Codes_SRS_BUFFER_07_015: [BUFFER_unbuild shall return a nonzero value if the unsigned char* referenced by BUFFER_HANDLE is NULL.] */
00303             result = __FAILURE__;
00304         }
00305     }
00306     return result;
00307 }
00308 
00309 /* Codes_SRS_BUFFER_07_016: [BUFFER_enlarge shall increase the size of the unsigned char* referenced by BUFFER_HANDLE.] */
00310 int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
00311 {
00312     int result;
00313     if (handle == NULL)
00314     {
00315         /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
00316         LogError("Failure: handle is invalid.");
00317         result = __FAILURE__;
00318     }
00319     else if (enlargeSize == 0)
00320     {
00321         /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
00322         LogError("Failure: enlargeSize size is 0.");
00323         result = __FAILURE__;
00324     }
00325     else
00326     {
00327         BUFFER* b = (BUFFER*)handle;
00328         unsigned char* temp = (unsigned char*)realloc(b->buffer, b->size + enlargeSize);
00329         if (temp == NULL)
00330         {
00331             /* Codes_SRS_BUFFER_07_018: [BUFFER_enlarge shall return a nonzero result if any error is encountered.] */
00332             LogError("Failure: allocating temp buffer.");
00333             result = __FAILURE__;
00334         }
00335         else
00336         {
00337             b->buffer = temp;
00338             b->size += enlargeSize;
00339             result = 0;
00340         }
00341     }
00342     return result;
00343 }
00344 
00345 int BUFFER_shrink(BUFFER_HANDLE handle, size_t decreaseSize, bool fromEnd)
00346 {
00347     int result;
00348     if (handle == NULL)
00349     {
00350         /* Codes_SRS_BUFFER_07_036: [ if handle is NULL, BUFFER_shrink shall return a non-null value ]*/
00351         LogError("Failure: handle is invalid.");
00352         result = __FAILURE__;
00353     }
00354     else if (decreaseSize == 0)
00355     {
00356         /* Codes_SRS_BUFFER_07_037: [ If decreaseSize is equal zero, BUFFER_shrink shall return a non-null value ] */
00357         LogError("Failure: decrease size is 0.");
00358         result = __FAILURE__;
00359     }
00360     else if (decreaseSize > handle->size)
00361     {
00362         /* Codes_SRS_BUFFER_07_038: [ If decreaseSize is less than the size of the buffer, BUFFER_shrink shall return a non-null value ] */
00363         LogError("Failure: decrease size is less than buffer size.");
00364         result = __FAILURE__;
00365     }
00366     else
00367     {
00368         /* Codes_SRS_BUFFER_07_039: [ BUFFER_shrink shall allocate a temporary buffer of existing buffer size minus decreaseSize. ] */
00369         size_t alloc_size = handle->size - decreaseSize;
00370         if (alloc_size == 0)
00371         {
00372             /* Codes_SRS_BUFFER_07_043: [ If the decreaseSize is equal the buffer size , BUFFER_shrink shall deallocate the buffer and set the size to zero. ] */
00373             free(handle->buffer);
00374             handle->buffer = NULL;
00375             handle->size = 0;
00376             result = 0;
00377         }
00378         else
00379         {
00380             unsigned char* tmp = malloc(alloc_size);
00381             if (tmp == NULL)
00382             {
00383                 /* Codes_SRS_BUFFER_07_042: [ If a failure is encountered, BUFFER_shrink shall return a non-null value ] */
00384                 LogError("Failure: allocating temp buffer.");
00385                 result = __FAILURE__;
00386             }
00387             else
00388             {
00389                 if (fromEnd)
00390                 {
00391                     /* Codes_SRS_BUFFER_07_040: [ if the fromEnd variable is true, BUFFER_shrink shall remove the end of the buffer of size decreaseSize. ] */
00392                     memcpy(tmp, handle->buffer, alloc_size);
00393                     free(handle->buffer);
00394                     handle->buffer = tmp;
00395                     handle->size = alloc_size;
00396                     result = 0;
00397                 }
00398                 else
00399                 {
00400                     /* Codes_SRS_BUFFER_07_041: [ if the fromEnd variable is false, BUFFER_shrink shall remove the beginning of the buffer of size decreaseSize. ] */
00401                     memcpy(tmp, handle->buffer + decreaseSize, alloc_size);
00402                     free(handle->buffer);
00403                     handle->buffer = tmp;
00404                     handle->size = alloc_size;
00405                     result = 0;
00406                 }
00407             }
00408         }
00409     }
00410     return result;
00411 }
00412 
00413 /* Codes_SRS_BUFFER_07_021: [BUFFER_size shall place the size of the associated buffer in the size variable and return zero on success.] */
00414 int BUFFER_size(BUFFER_HANDLE handle, size_t* size)
00415 {
00416     int result;
00417     if ((handle == NULL) || (size == NULL))
00418     {
00419         /* Codes_SRS_BUFFER_07_022: [BUFFER_size shall return a nonzero value for any error that is encountered.] */
00420         result = __FAILURE__;
00421     }
00422     else
00423     {
00424         BUFFER* b = (BUFFER*)handle;
00425         *size = b->size;
00426         result = 0;
00427     }
00428     return result;
00429 }
00430 
00431 /* Codes_SRS_BUFFER_07_024: [BUFFER_append concatenates b2 onto b1 without modifying b2 and shall return zero on success.] */
00432 int BUFFER_append(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
00433 {
00434     int result;
00435     if ( (handle1 == NULL) || (handle2 == NULL) || (handle1 == handle2) )
00436     {
00437         /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
00438         result = __FAILURE__;
00439     }
00440     else
00441     {
00442         BUFFER* b1 = (BUFFER*)handle1;
00443         BUFFER* b2 = (BUFFER*)handle2;
00444         if (b1->buffer == NULL) 
00445         {
00446             /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
00447             result = __FAILURE__;
00448         }
00449         else if (b2->buffer == NULL)
00450         {
00451             /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
00452             result = __FAILURE__;
00453         }
00454         else
00455         {
00456             if (b2->size ==0)
00457             {
00458                 // b2->size = 0, whatever b1->size is, do nothing
00459                 result = 0;
00460             }
00461             else
00462             {
00463                 // b2->size != 0, whatever b1->size is
00464                 unsigned char* temp = (unsigned char*)realloc(b1->buffer, b1->size + b2->size);
00465                 if (temp == NULL)
00466                 {
00467                     /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
00468                     LogError("Failure: allocating temp buffer.");
00469                     result = __FAILURE__;
00470                 }
00471                 else
00472                 {
00473                     /* Codes_SRS_BUFFER_07_024: [BUFFER_append concatenates b2 onto b1 without modifying b2 and shall return zero on success.]*/
00474                     b1->buffer = temp;
00475                     // Append the BUFFER
00476                     (void)memcpy(&b1->buffer[b1->size], b2->buffer, b2->size);
00477                     b1->size += b2->size;
00478                     result = 0;
00479                 }
00480             }
00481         }
00482     }
00483     return result;
00484 }
00485 
00486 int BUFFER_prepend(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
00487 {
00488     int result;
00489     if ((handle1 == NULL) || (handle2 == NULL) || (handle1 == handle2))
00490     {
00491         /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
00492         result = __FAILURE__;
00493     }
00494     else
00495     {
00496         BUFFER* b1 = (BUFFER*)handle1;
00497         BUFFER* b2 = (BUFFER*)handle2;
00498         if (b1->buffer == NULL)
00499         {
00500             /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
00501             result = __FAILURE__;
00502         }
00503         else if (b2->buffer == NULL)
00504         {
00505             /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
00506             result = __FAILURE__;
00507         }
00508         else
00509         {
00510             //put b2 ahead of b1: [b2][b1], return b1
00511             if (b2->size ==0)
00512             {
00513                 // do nothing
00514                 result = 0;
00515             }
00516             else
00517             {
00518                 // b2->size != 0
00519                 unsigned char* temp = (unsigned char*)malloc(b1->size + b2->size);
00520                 if (temp == NULL)
00521                 {
00522                     /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
00523                     LogError("Failure: allocating temp buffer.");
00524                     result = __FAILURE__;
00525                 }
00526                 else
00527                 {
00528                     /* Codes_SRS_BUFFER_01_004: [ BUFFER_prepend concatenates handle1 onto handle2 without modifying handle1 and shall return zero on success. ]*/
00529                     // Append the BUFFER
00530                     (void)memcpy(temp, b2->buffer, b2->size);
00531                     // start from b1->size to append b1
00532                     (void)memcpy(&temp[b2->size], b1->buffer, b1->size);
00533                     free(b1->buffer);
00534                     b1->buffer = temp;
00535                     b1->size += b2->size;
00536                     result = 0;
00537                 }
00538             }
00539         }
00540     }
00541     return result;
00542 }
00543 
00544 int BUFFER_fill(BUFFER_HANDLE handle, unsigned char fill_char)
00545 {
00546     int result;
00547     if (handle == NULL)
00548     {
00549         /* Codes_SRS_BUFFER_07_002: [ If handle is NULL BUFFER_fill shall return a non-zero value. ] */
00550         LogError("Invalid parameter specified, handle == NULL.");
00551         result = __FAILURE__;
00552     }
00553     else
00554     {
00555         size_t index;
00556         /* Codes_SRS_BUFFER_07_001: [ BUFFER_fill shall fill the supplied BUFFER_HANDLE with the supplied fill character. ] */
00557         BUFFER* buffer_data = (BUFFER*)handle;
00558         for (index = 0; index < buffer_data->size; index++)
00559         {
00560             buffer_data->buffer[index] = fill_char;
00561         }
00562         result = 0;
00563     }
00564     return result;
00565 }
00566 
00567 
00568 /* Codes_SRS_BUFFER_07_025: [BUFFER_u_char shall return a pointer to the underlying unsigned char*.] */
00569 unsigned char* BUFFER_u_char(BUFFER_HANDLE handle)
00570 {
00571     BUFFER* handleData = (BUFFER*)handle;
00572     unsigned char* result;
00573     if (handle == NULL || handleData->size == 0)
00574     {
00575         /* Codes_SRS_BUFFER_07_026: [BUFFER_u_char shall return NULL for any error that is encountered.] */
00576         /* Codes_SRS_BUFFER_07_029: [BUFFER_u_char shall return NULL if underlying buffer size is zero.] */
00577         result = NULL;
00578     }
00579     else
00580     {
00581         result = handleData->buffer;
00582     }
00583     return result;
00584 }
00585 
00586 /* Codes_SRS_BUFFER_07_027: [BUFFER_length shall return the size of the underlying buffer.] */
00587 size_t BUFFER_length(BUFFER_HANDLE handle)
00588 {
00589     size_t result;
00590     if (handle == NULL)
00591     {
00592         /* Codes_SRS_BUFFER_07_028: [BUFFER_length shall return zero for any error that is encountered.] */
00593         result = 0;
00594     }
00595     else
00596     {
00597         BUFFER* b = (BUFFER*)handle;
00598         result = b->size;
00599     }
00600     return result;
00601 }
00602 
00603 BUFFER_HANDLE BUFFER_clone(BUFFER_HANDLE handle)
00604 {
00605     BUFFER_HANDLE result;
00606     if (handle == NULL)
00607     {
00608         result = NULL;
00609     }
00610     else
00611     {
00612         BUFFER* suppliedBuff = (BUFFER*)handle;
00613         BUFFER* b = (BUFFER*)malloc(sizeof(BUFFER));
00614         if (b != NULL)
00615         {
00616             if (BUFFER_safemalloc(b, suppliedBuff->size) != 0)
00617             {
00618                 LogError("Failure: allocating temp buffer.");
00619                 result = NULL;
00620             }
00621             else
00622             {
00623                 (void)memcpy(b->buffer, suppliedBuff->buffer, suppliedBuff->size);
00624                 b->size = suppliedBuff->size;
00625                 result = (BUFFER_HANDLE)b;
00626             }
00627         }
00628         else
00629         {
00630             result = NULL;
00631         }
00632     }
00633     return result;
00634 }