blob: dc06fc1fffcada07b971a29cfac5fd0d1ddaf130 [file] [log] [blame]
/*==============================================================================
ds_ASBuffer.cpp
GENERAL DESCRIPTION
A buffer class with utility functions for parsing raw bytes.
EXTERNALIZED FUNCTIONS
INITIALIZATION AND SEQUENCING REQUIREMENTS
None
Copyright (c) 2014 by Qualcomm Technologies Incorporated. All Rights Reserved.
==============================================================================*/
/*==============================================================================
EDIT HISTORY FOR MODULE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
when who what, where, why
-------- --- ----------------------------------------------------------
06/03/15 ml Remove memory allocation on default constructor
05/20/15 ml Use memory from modem heap
04/21/14 ml Created file/Initial version.
==============================================================================*/
#include "ds_ASBuffer.h"
//#include "ds_appsrv_mem.h"
#include <string.h>
#include <mbtk_type.h>
#include <stdlib.h>
#include <cctype> // isspace
// temp
#include "ds_ASString.h"
#define DEFAULT_BUFFER_SIZE 256
// static const uint8 EMPTY_STRING[] = "";
void memscpy(void* dest, size_t destLen, const void* src, size_t srcLen) {
if (srcLen <= destLen)
memcpy(dest, src, srcLen);
}
ASBuffer::ASBuffer()
: buffer(NULL), buffer_size(0), buffer_capacity(DEFAULT_BUFFER_SIZE), error_status(false)
{ }
ASBuffer::ASBuffer(uint32 capacity)
: buffer(NULL), buffer_size(0), buffer_capacity(capacity), error_status(false)
{ }
ASBuffer::ASBuffer(ASBuffer &buf)
: buffer(NULL), buffer_size(0), buffer_capacity(buf.buffer_capacity), error_status(false)
{
init();
append(buf);
}
ASBuffer::ASBuffer(const ASBuffer &buf)
: buffer(NULL), buffer_size(0), buffer_capacity(buf.buffer_capacity), error_status(false)
{
init();
append(buf);
}
ASBuffer::ASBuffer(const uint8* buf, uint32 buf_size)
: buffer(NULL), buffer_size(0), buffer_capacity(buf_size), error_status(false)
{
init();
append(buf, buf_size);
}
ASBuffer::~ASBuffer()
{
if(NULL != buffer)
{
free(buffer);
buffer = NULL;
}
}
ASBuffer& ASBuffer::operator=(const ASBuffer &rhs)
{
clear();
append(rhs);
return *this;
}
void ASBuffer::init()
{
if(0 == buffer_capacity)
{
error_status = true;
}
else if(NULL == buffer)
{
buffer = (uint8*)malloc(sizeof(uint8) * (buffer_capacity+1));
error_status = (NULL == buffer);
}
}
// temp name
#define DO_NOT_DOUBLE_IF_LARGER 2147483647
bool ASBuffer::increment_buffer_capacity(const uint32 req_size)
{
uint32 new_capacity = buffer_capacity;
uint8* tmp = NULL;
while(req_size > new_capacity)
{
// will cause overflow if doubled
if(DO_NOT_DOUBLE_IF_LARGER < new_capacity)
return false;
new_capacity *= 2;
}
tmp = (uint8*)malloc(sizeof(uint8) * new_capacity+1);
if(NULL == tmp)
return false;
memset(tmp, 0, new_capacity+1);
memscpy(tmp, new_capacity, buffer, buffer_size);
free(buffer);
buffer = NULL;
buffer = tmp;
buffer_capacity = new_capacity;
return true;
}
uint8* ASBuffer::non_const_content()
{
return buffer;
}
const uint8* ASBuffer::content() const
{
return buffer;
}
const char* ASBuffer::c_str() const
{
if(NULL == buffer)
return "";
else
return (const char*)buffer;
}
uint32 ASBuffer::size() const
{
return buffer_size;
}
bool ASBuffer::empty() const
{
return (0 == buffer_size);
}
bool ASBuffer::error() const
{
return error_status;
}
void ASBuffer::clear()
{
if(NULL == buffer)
{
init();
}
else
{
memset(buffer, 0, buffer_capacity+1);
}
buffer_size = 0;
}
bool ASBuffer::append(const uint8* append_buffer, const uint32 append_size)
{
if(NULL == append_buffer || 0 == append_size)
return true;
if(NULL == buffer)
init();
if(error_status) // do nothing if in error state
return false;
uint32 new_size = buffer_size + append_size;
if(new_size > buffer_capacity)
{
if(!increment_buffer_capacity(new_size))
{
error_status = true;
return false;
}
}
memscpy(
buffer + buffer_size,
buffer_capacity - buffer_size,
append_buffer,
append_size
);
buffer_size = new_size;
return true;
}
bool ASBuffer::append(const char* append_buffer)
{
if(NULL == append_buffer)
return false;
else
return append((uint8*)append_buffer, strlen(append_buffer));
}
bool ASBuffer::append(const char append_buffer)
{
char buffer[1];
buffer[0] = append_buffer;
return append((uint8*)buffer, 1);
}
bool ASBuffer::append(const char* append_buffer, const uint32 size)
{
if(NULL == append_buffer)
return false;
else
return append((uint8*)append_buffer, size);
}
bool ASBuffer::append(const ASBuffer& append_buffer)
{
if(append_buffer.empty())
return false;
else
return append(append_buffer.content(), append_buffer.size());
}
bool ASBuffer::append(const ASString& append_buffer)
{
if(append_buffer.empty())
return false;
else
return append((uint8*)append_buffer.c_str(), append_buffer.size());
}