change some parameters in the library to meet the needs of the website httpbin.org

Fork of MiniTLS-GPL by Donatien Garnier

core/buffer.c

Committer:
shiyilei
Date:
2015-02-06
Revision:
5:95f70ebfe61f
Parent:
3:eb324ffffd2b

File content as of revision 5:95f70ebfe61f:

/*
MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
Author: Donatien Garnier
Copyright (C) 2013-2014 AppNearMe Ltd

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.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*//**
 * \file buffer.c
 * \copyright Copyright (c) AppNearMe Ltd 2013
 * \author Donatien Garnier
 * \desc Module to ease buffers' management
 */

/** \addtogroup Core
 *  @{
 *  \name Buffers
 *  @{
 */

#include "core/fwk.h"
#include "buffer.h"

/** Initialize buffer using underlying byte array, set buffer's length to 0 (empty)
 * \param pBuf pointer to buffer_t structure to initialize
 * \param bufdata byte array to use
 * \param size size of byte array
 */
void buffer_init(buffer_t* pBuf, uint8_t* bufdata, size_t size)
{
  pBuf->bufdata = (uint8_t*) bufdata;
  pBuf->size = size;

  pBuf->start = pBuf->bufdata;
  pBuf->first_byte_length = 0;

  pBuf->end = pBuf->start;
  pBuf->last_byte_length = 8; //In bits

  pBuf->next = NULL;
}

/** Initialize buffer using underlying byte array, set buffer's length to array's size (full)
 * \param pBuf pointer to buffer_t structure to initialize
 * \param bufdata byte array to use
 * \param size size of byte array
 */
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)
{
  buffer_init(pBuf, bufdata, length);
  buffer_set_length(pBuf, length);
}

#ifdef USE_MALLOC
buffer_t* buffer_new(size_t size) //malloc
{
  buffer_t* pBuf = (buffer_t*) malloc(sizeof(buffer_t));
  buffer_init(pBuf, (uint8_t*) malloc(size), size);
  return pBuf;
}
#endif

/** Get buffer's underlying byte array
 * \param pBuf pointer to buffer_t structure
 * \return underlying array
 */
uint8_t* buffer_data(buffer_t* pBuf)
{
  return pBuf->bufdata;
}

/** Reset buffer (empty)
 * \param pBuf pointer to buffer_t structure
 */
void buffer_reset(buffer_t* pBuf)
{
  buffer_init(pBuf, pBuf->bufdata, pBuf->size);
}

/** Get buffer's size
 * \param pBuf pointer to buffer_t structure
 * \return buffer's size
 */
size_t buffer_size(buffer_t* pBuf)
{
  return pBuf->size;
}

/** Get buffer's length
 * \param pBuf pointer to buffer_t structure
 * \return number of valid bytes in buffer
 */
size_t buffer_length(buffer_t* pBuf)
{
  return (pBuf->end - pBuf->start);
}

/** Get space in buffer
 * \param pBuf pointer to buffer_t structure
 * \return number of free bytes in buffer
 */
size_t buffer_space(buffer_t* pBuf)
{
  return pBuf->bufdata + pBuf->size - pBuf->end;
}

/** Is buffer empty
 * \param pBuf pointer to buffer_t structure
 * \return true if buffer is empty
 */
bool buffer_empty(buffer_t* pBuf)
{
  return !buffer_length(pBuf);
}

/** Set buffer's length
 * \param pBuf pointer to buffer_t structure
 * \param length number of valid bytes in buffer
 */
void buffer_set_length(buffer_t* pBuf, size_t length)
{
  pBuf->end = pBuf->start + length;
  pBuf->first_byte_length = 0;
  pBuf->last_byte_length = 8;
}

/** Get buffer's last byte's length
 * \param pBuf pointer to buffer_t structure
 * \return number of valid bits in buffer's last byte
 */
size_t buffer_last_byte_length(buffer_t* pBuf)
{
  return pBuf->last_byte_length;
}

/** Set buffer's last byte's length
 * \param pBuf pointer to buffer_t structure
 * \param length number of valid bits in buffer's last byte
 */
void buffer_set_last_byte_length(buffer_t* pBuf, size_t length)
{
  pBuf->last_byte_length = length;
}

/** Get buffer's bits count
 * \param pBuf pointer to buffer_t structure
 * \return total number of valid bits in buffer
 */
size_t buffer_bits_count(buffer_t* pBuf)
{
  size_t length;
  length = buffer_length(pBuf);
  if(length == 0)
  {
     return 0;
  }
  else if(length == 1)
  {
    return pBuf->first_byte_length;
  }
  else // > 2
  {
    return pBuf->first_byte_length + 8*(length - 2) + pBuf->last_byte_length;
  }
}

/** Write one byte to buffer
 * \param pBuf pointer to buffer_t structure
 * \param b byte to append
 */
void buffer_write_byte(buffer_t* pBuf, uint8_t b)
{
  size_t i;
  if(pBuf->end >= pBuf->start + pBuf->size) //buffer_t full
    return;
  if(pBuf->last_byte_length == 8)
  {
    *(pBuf->end) = b;
    pBuf->end++;
  }
  else
  {
    for(i = 0; i < 8; i++)
    {
      buffer_write_bit(pBuf, (b>>i)&1);
    }
  }

}

/** Write one bit to buffer
 * \param pBuf pointer to buffer_t structure
 * \param b bit to append
 */
void buffer_write_bit(buffer_t* pBuf, uint8_t b)
{
  if(pBuf->end >= pBuf->start + pBuf->size)
    return;
  if(pBuf->last_byte_length == 8)
  {
    if( (pBuf->end + 1) >= pBuf->start + pBuf->size)
       return;
    pBuf->end++;
    pBuf->last_byte_length = 0;
    *(pBuf->end) = 0;
  }
  *(pBuf->end) = (*(pBuf->end) << pBuf->last_byte_length) | (b & 1);
  pBuf->last_byte_length++;
}

/** Get next buffer in chain
 * \param pBuf pointer to buffer_t structure
 * \return pointer to next buffer
 */
buffer_t* buffer_next(buffer_t* pBuf)
{
  return pBuf->next;
}

/** Set next buffer in chain
 * \param pBuf pointer to buffer_t structure
 * \param pNextBuf pointer to next buffer (or NULL to break chain)
 */
void buffer_set_next(buffer_t* pBuf, buffer_t* pNextBuf)
{
  pBuf->next = (buffer_t*) pNextBuf;
}

/** Append next buffer to the whole chain
 * \param pBuf pointer to buffer_t structure
 * \param pAppBuf pointer to buffer to append
 */
void buffer_append(buffer_t* pBuf, buffer_t* pAppBuf)
{
  buffer_t* p;
  p = (buffer_t*) pBuf;
  while( p->next )
  {
    p = p->next;
  }
  p->next = pAppBuf;
}

/** Split chain at specified buffer
 * \param pBuf pointer to buffer_t structure
 * \param pLinkedBuf pointer to buffer from which to split the chain
 */
void buffer_unlink(buffer_t* pBuf, buffer_t* pLinkedBuf)
{
  buffer_t* p;
  p = (buffer_t*) pBuf;
  while( p->next && (p->next != pLinkedBuf) )
  {
    p = p->next;
  }
  p->next = NULL;
}

/** Get buffer chain's total size
 * \param pBuf pointer to buffer_t structure
 * \return sum of each buffer's size
 */
size_t buffer_total_size(buffer_t* pBuf)
{
  size_t size;
  buffer_t* p;
  size = 0;
  p = (buffer_t*) pBuf;
  do
  {
    size += buffer_size(p);
  } while( (p = p->next) != NULL );
  return size;
}

/** Get buffer chain's total length
 * \param pBuf pointer to buffer_t structure
 * \return number of valid bytes in the whole chain
 */
size_t buffer_total_length(buffer_t* pBuf)
{
  size_t len;
  buffer_t* p;
  len = 0;
  p = pBuf;
  do
  {
    len += buffer_length(p);
  } while( (p = p->next) != NULL );
  return len;
}

/** Set buffer chain's total length (fill up one buffer and move to the next if needed)
 * \param pBuf pointer to buffer_t structure
 * \param length total length
 */
void buffer_set_total_length(buffer_t* pBuf, size_t length)
{
  size_t remaining_len;
  buffer_t* p;
  remaining_len = length;
  p = pBuf;
  do
  {
    buffer_set_length(p, MIN(p->size,remaining_len));
    remaining_len -= MIN(p->size,remaining_len);
  } while( (p = p->next) != NULL );
}

#if 0
size_t buffer_read_byte(buffer_t* pBuf, uint8_t b)
{

}

size_t buffer_read_bit(buffer_t* pBuf, uint8_t b)
{

}
#endif

#ifdef USE_MALLOC
void buffer_free(buffer_t* pBuf)
{
  free(pBuf->bufdata);
  free(pBuf);
}
#endif

/** Dump a buffer's content to stdout (useful for debugging)
 * \param pBuf pointer to buffer_t structure
 */
void buffer_dump(buffer_t* pBuf)
{
  size_t len;
  buffer_t* p;
  uint8_t* bufdata;
  int i;
  int j;
  p = (buffer_t*) pBuf;
  debugx_enter();
  do
  {
    len = buffer_length(p);
    bufdata = p->start;
    i = 0;
    while(i < len)
    {
      for(j = i; j < MIN(len, i + 16); j++)
      {
        debugx("%02x ", bufdata[j]);
      }
      debugx("\r\n");
      i = j;
    }
    if(p->next)
    {
      debugx("->\r\n");
    }
  } while( (p = p->next) != NULL );
  debugx_leave();
}

/**
 * @}
 * @}
 * */