ARM Shanghai IoT Team (Internal) / newMiniTLS-GPL

Fork of MiniTLS-GPL by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers buffer.c Source File

buffer.c

Go to the documentation of this file.
00001 /*
00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
00003 Author: Donatien Garnier
00004 Copyright (C) 2013-2014 AppNearMe Ltd
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 *//**
00020  * \file buffer.c
00021  * \copyright Copyright (c) AppNearMe Ltd 2013
00022  * \author Donatien Garnier
00023  * \desc Module to ease buffers' management
00024  */
00025 
00026 /** \addtogroup Core
00027  *  @{
00028  *  \name Buffers
00029  *  @{
00030  */
00031 
00032 #include "core/fwk.h"
00033 #include "buffer.h"
00034 
00035 /** Initialize buffer using underlying byte array, set buffer's length to 0 (empty)
00036  * \param pBuf pointer to buffer_t structure to initialize
00037  * \param bufdata byte array to use
00038  * \param size size of byte array
00039  */
00040 void buffer_init(buffer_t* pBuf, uint8_t* bufdata, size_t size)
00041 {
00042   pBuf->bufdata = (uint8_t*) bufdata;
00043   pBuf->size = size;
00044 
00045   pBuf->start = pBuf->bufdata;
00046   pBuf->first_byte_length = 0;
00047 
00048   pBuf->end = pBuf->start;
00049   pBuf->last_byte_length = 8; //In bits
00050 
00051   pBuf->next = NULL;
00052 }
00053 
00054 /** Initialize buffer using underlying byte array, set buffer's length to array's size (full)
00055  * \param pBuf pointer to buffer_t structure to initialize
00056  * \param bufdata byte array to use
00057  * \param size size of byte array
00058  */
00059 void buffer_byref(buffer_t* pBuf, uint8_t* bufdata, size_t length) //New buffer_t by ref on a size_t array, no malloc (useful on PIC for instance)
00060 {
00061   buffer_init(pBuf, bufdata, length);
00062   buffer_set_length(pBuf, length);
00063 }
00064 
00065 #ifdef USE_MALLOC
00066 buffer_t* buffer_new(size_t size) //malloc
00067 {
00068   buffer_t* pBuf = (buffer_t*) malloc(sizeof(buffer_t));
00069   buffer_init(pBuf, (uint8_t*) malloc(size), size);
00070   return pBuf;
00071 }
00072 #endif
00073 
00074 /** Get buffer's underlying byte array
00075  * \param pBuf pointer to buffer_t structure
00076  * \return underlying array
00077  */
00078 uint8_t* buffer_data(buffer_t* pBuf)
00079 {
00080   return pBuf->bufdata;
00081 }
00082 
00083 /** Reset buffer (empty)
00084  * \param pBuf pointer to buffer_t structure
00085  */
00086 void buffer_reset(buffer_t* pBuf)
00087 {
00088   buffer_init(pBuf, pBuf->bufdata, pBuf->size);
00089 }
00090 
00091 /** Get buffer's size
00092  * \param pBuf pointer to buffer_t structure
00093  * \return buffer's size
00094  */
00095 size_t buffer_size(buffer_t* pBuf)
00096 {
00097   return pBuf->size;
00098 }
00099 
00100 /** Get buffer's length
00101  * \param pBuf pointer to buffer_t structure
00102  * \return number of valid bytes in buffer
00103  */
00104 size_t buffer_length(buffer_t* pBuf)
00105 {
00106   return (pBuf->end - pBuf->start);
00107 }
00108 
00109 /** Get space in buffer
00110  * \param pBuf pointer to buffer_t structure
00111  * \return number of free bytes in buffer
00112  */
00113 size_t buffer_space(buffer_t* pBuf)
00114 {
00115   return pBuf->bufdata + pBuf->size - pBuf->end;
00116 }
00117 
00118 /** Is buffer empty
00119  * \param pBuf pointer to buffer_t structure
00120  * \return true if buffer is empty
00121  */
00122 bool buffer_empty(buffer_t* pBuf)
00123 {
00124   return !buffer_length(pBuf);
00125 }
00126 
00127 /** Set buffer's length
00128  * \param pBuf pointer to buffer_t structure
00129  * \param length number of valid bytes in buffer
00130  */
00131 void buffer_set_length(buffer_t* pBuf, size_t length)
00132 {
00133   pBuf->end = pBuf->start + length;
00134   pBuf->first_byte_length = 0;
00135   pBuf->last_byte_length = 8;
00136 }
00137 
00138 /** Get buffer's last byte's length
00139  * \param pBuf pointer to buffer_t structure
00140  * \return number of valid bits in buffer's last byte
00141  */
00142 size_t buffer_last_byte_length(buffer_t* pBuf)
00143 {
00144   return pBuf->last_byte_length;
00145 }
00146 
00147 /** Set buffer's last byte's length
00148  * \param pBuf pointer to buffer_t structure
00149  * \param length number of valid bits in buffer's last byte
00150  */
00151 void buffer_set_last_byte_length(buffer_t* pBuf, size_t length)
00152 {
00153   pBuf->last_byte_length = length;
00154 }
00155 
00156 /** Get buffer's bits count
00157  * \param pBuf pointer to buffer_t structure
00158  * \return total number of valid bits in buffer
00159  */
00160 size_t buffer_bits_count(buffer_t* pBuf)
00161 {
00162   size_t length;
00163   length = buffer_length(pBuf);
00164   if(length == 0)
00165   {
00166      return 0;
00167   }
00168   else if(length == 1)
00169   {
00170     return pBuf->first_byte_length;
00171   }
00172   else // > 2
00173   {
00174     return pBuf->first_byte_length + 8*(length - 2) + pBuf->last_byte_length;
00175   }
00176 }
00177 
00178 /** Write one byte to buffer
00179  * \param pBuf pointer to buffer_t structure
00180  * \param b byte to append
00181  */
00182 void buffer_write_byte(buffer_t* pBuf, uint8_t b)
00183 {
00184   size_t i;
00185   if(pBuf->end >= pBuf->start + pBuf->size) //buffer_t full
00186     return;
00187   if(pBuf->last_byte_length == 8)
00188   {
00189     *(pBuf->end) = b;
00190     pBuf->end++;
00191   }
00192   else
00193   {
00194     for(i = 0; i < 8; i++)
00195     {
00196       buffer_write_bit(pBuf, (b>>i)&1);
00197     }
00198   }
00199 
00200 }
00201 
00202 /** Write one bit to buffer
00203  * \param pBuf pointer to buffer_t structure
00204  * \param b bit to append
00205  */
00206 void buffer_write_bit(buffer_t* pBuf, uint8_t b)
00207 {
00208   if(pBuf->end >= pBuf->start + pBuf->size)
00209     return;
00210   if(pBuf->last_byte_length == 8)
00211   {
00212     if( (pBuf->end + 1) >= pBuf->start + pBuf->size)
00213        return;
00214     pBuf->end++;
00215     pBuf->last_byte_length = 0;
00216     *(pBuf->end) = 0;
00217   }
00218   *(pBuf->end) = (*(pBuf->end) << pBuf->last_byte_length) | (b & 1);
00219   pBuf->last_byte_length++;
00220 }
00221 
00222 /** Get next buffer in chain
00223  * \param pBuf pointer to buffer_t structure
00224  * \return pointer to next buffer
00225  */
00226 buffer_t* buffer_next(buffer_t* pBuf)
00227 {
00228   return pBuf->next;
00229 }
00230 
00231 /** Set next buffer in chain
00232  * \param pBuf pointer to buffer_t structure
00233  * \param pNextBuf pointer to next buffer (or NULL to break chain)
00234  */
00235 void buffer_set_next(buffer_t* pBuf, buffer_t* pNextBuf)
00236 {
00237   pBuf->next = (buffer_t*) pNextBuf;
00238 }
00239 
00240 /** Append next buffer to the whole chain
00241  * \param pBuf pointer to buffer_t structure
00242  * \param pAppBuf pointer to buffer to append
00243  */
00244 void buffer_append(buffer_t* pBuf, buffer_t* pAppBuf)
00245 {
00246   buffer_t* p;
00247   p = (buffer_t*) pBuf;
00248   while( p->next )
00249   {
00250     p = p->next;
00251   }
00252   p->next = pAppBuf;
00253 }
00254 
00255 /** Split chain at specified buffer
00256  * \param pBuf pointer to buffer_t structure
00257  * \param pLinkedBuf pointer to buffer from which to split the chain
00258  */
00259 void buffer_unlink(buffer_t* pBuf, buffer_t* pLinkedBuf)
00260 {
00261   buffer_t* p;
00262   p = (buffer_t*) pBuf;
00263   while( p->next && (p->next != pLinkedBuf) )
00264   {
00265     p = p->next;
00266   }
00267   p->next = NULL;
00268 }
00269 
00270 /** Get buffer chain's total size
00271  * \param pBuf pointer to buffer_t structure
00272  * \return sum of each buffer's size
00273  */
00274 size_t buffer_total_size(buffer_t* pBuf)
00275 {
00276   size_t size;
00277   buffer_t* p;
00278   size = 0;
00279   p = (buffer_t*) pBuf;
00280   do
00281   {
00282     size += buffer_size(p);
00283   } while( (p = p->next) != NULL );
00284   return size;
00285 }
00286 
00287 /** Get buffer chain's total length
00288  * \param pBuf pointer to buffer_t structure
00289  * \return number of valid bytes in the whole chain
00290  */
00291 size_t buffer_total_length(buffer_t* pBuf)
00292 {
00293   size_t len;
00294   buffer_t* p;
00295   len = 0;
00296   p = pBuf;
00297   do
00298   {
00299     len += buffer_length(p);
00300   } while( (p = p->next) != NULL );
00301   return len;
00302 }
00303 
00304 /** Set buffer chain's total length (fill up one buffer and move to the next if needed)
00305  * \param pBuf pointer to buffer_t structure
00306  * \param length total length
00307  */
00308 void buffer_set_total_length(buffer_t* pBuf, size_t length)
00309 {
00310   size_t remaining_len;
00311   buffer_t* p;
00312   remaining_len = length;
00313   p = pBuf;
00314   do
00315   {
00316     buffer_set_length(p, MIN(p->size,remaining_len));
00317     remaining_len -= MIN(p->size,remaining_len);
00318   } while( (p = p->next) != NULL );
00319 }
00320 
00321 #if 0
00322 size_t buffer_read_byte(buffer_t* pBuf, uint8_t b)
00323 {
00324 
00325 }
00326 
00327 size_t buffer_read_bit(buffer_t* pBuf, uint8_t b)
00328 {
00329 
00330 }
00331 #endif
00332 
00333 #ifdef USE_MALLOC
00334 void buffer_free(buffer_t* pBuf)
00335 {
00336   free(pBuf->bufdata);
00337   free(pBuf);
00338 }
00339 #endif
00340 
00341 /** Dump a buffer's content to stdout (useful for debugging)
00342  * \param pBuf pointer to buffer_t structure
00343  */
00344 void buffer_dump(buffer_t* pBuf)
00345 {
00346   size_t len;
00347   buffer_t* p;
00348   uint8_t* bufdata;
00349   int i;
00350   int j;
00351   p = (buffer_t*) pBuf;
00352   debugx_enter();
00353   do
00354   {
00355     len = buffer_length(p);
00356     bufdata = p->start;
00357     i = 0;
00358     while(i < len)
00359     {
00360       for(j = i; j < MIN(len, i + 16); j++)
00361       {
00362         debugx("%02x ", bufdata[j]);
00363       }
00364       debugx("\r\n");
00365       i = j;
00366     }
00367     if(p->next)
00368     {
00369       debugx("->\r\n");
00370     }
00371   } while( (p = p->next) != NULL );
00372   debugx_leave();
00373 }
00374 
00375 /**
00376  * @}
00377  * @}
00378  * */