Simple data buffer splitter and re-assembler.
Diff: DataFragmenterAssembler.cpp
- Revision:
- 1:9f05dbd1c2c7
- Parent:
- 0:12a931a6161c
- Child:
- 2:5614523d641b
--- a/DataFragmenterAssembler.cpp Thu Feb 12 20:00:36 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -/** - * @file DataFragmenterAssembler.cpp - * @brief data fragmenter and assembler (for BLE UARTService...) implementation - * @author Doug Anson - * @version 1.0 - * @see - * - * Copyright (c) 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - #include "DataFragmenterAssembler.h" - -// we have to redefine DBG as its used differently here... -#ifdef DBG - #undef DBG -#endif -#define DBG printf - - // constructor - DataFragmenterAssembler::DataFragmenterAssembler() - { - this->reset(); - } - - // fragment a buffer - int DataFragmenterAssembler::fragment(uint8_t *data,int data_length) - { - // reset - this->reset(); - - // get our number of fragments - this->m_num_fragments = this->calculateNumFragments(data,data_length); - - // DEBUG - //DBG("fragment() num_fragments=%d data_length=%d\r\n",this->m_num_fragments,data_length); - - // make sure we have a positive number... - if (this->m_num_fragments > 0) { - // check for the simple case first - if (this->m_num_fragments == 1) { - // simple case... just 1 fragment - memcpy(this->m_fragments[0],data,data_length); - this->m_last_fragment_length = data_length; - } - else { - // must iterate over the buffer and fragment... - for(int i=0;i<this->m_num_fragments;++i) { - int offset = i*DEF_FRAGMENT_LENGTH; - if (i < (this->m_num_fragments-1)) { - // interior... will always be fixed length - memcpy(this->m_fragments[i],(data + offset),DEF_FRAGMENT_LENGTH); - } - else { - // trailing... may be partial length... - this->m_last_fragment_length = data_length - offset; - memcpy(this->m_fragments[i],(data + offset),this->m_last_fragment_length); - } - } - } - } - else { - // unable to fragment... invalid parameters - DBG("ERROR: invalid parameters in fragment()\r\n"); - } - - // DEBUG - //this->dump(); - - // return our number of fragments - return this->m_num_fragments; - } - - // calculate the number of fragments - int DataFragmenterAssembler::calculateNumFragments(uint8_t *data,int data_length) - { - int num_fragments = 0; - - // param checking - if (data != NULL && data_length > 0) { - // check for simple case... - if (data_length <= DEF_FRAGMENT_LENGTH) { - num_fragments = 1; - } - else { - num_fragments = 1; - data_length -= DEF_FRAGMENT_LENGTH; - while(data_length > 0) { - ++num_fragments; - data_length -= DEF_FRAGMENT_LENGTH; - } - } - } - else { - // invalid parameters - DBG("ERROR: invalid parameters in calculateNumFragments() data_length=%d\r\n",data_length); - } - - return num_fragments; - } - - // get the ith fragment - uint8_t *DataFragmenterAssembler::get(int index) - { - if (index >= 0 && index < this->m_num_fragments) - return this->m_fragments[index]; - return NULL; - } - - // reset the Fragmenter/Assembler - void DataFragmenterAssembler::reset(void) - { - memset(this->m_fragments,0,sizeof(this->m_fragments)); - this->m_num_fragments = 0; - this->m_last_fragment_length = 0; - } - - // add a fragment to assemble later - int DataFragmenterAssembler::add(uint8_t *fragment,int fragment_length) - { - if (this->m_num_fragments < (MAX_FRAGMENTS-1)) { - int length = fragment_length; - if (length > DEF_FRAGMENT_LENGTH) { - length = DEF_FRAGMENT_LENGTH; - //DBG("WARNING: Truncating input fragment in add() fragment_length=%d\r\n",fragment_length); - } - memcpy(this->m_fragments[this->m_num_fragments],fragment,length); - ++this->m_num_fragments; - } - else { - // not enough memory to hold all the fragments - DBG("ERROR: Maximum number of fragments permissible reached, Please increase MAX_FRAGMENTS...\r\n"); - } - return this->m_num_fragments; - } - - // assemble all input fragments - void DataFragmenterAssembler::assemble(uint8_t *buffer,int buffer_length,bool reset_after_assemble) - { - // calculate the final assembly length - int length = this->calculateAssemblyLength(buffer_length); - if (length > 0) { - // initialize the return buffer - memset(buffer,0,buffer_length); - - // check for the simple case.. 1 fragment - if (this->m_num_fragments == 1) { - // simple case detected... just copy over - memset(buffer,0,buffer_length); - memcpy(buffer,this->m_fragments[0],length); - } - else { - // we have to loop and copy/append - for(int i=0;i<this->m_num_fragments;++i) { - int offset = (i*DEF_FRAGMENT_LENGTH); - if (i < (this->m_num_fragments-1)) { - // interior... will always be fixed length - memcpy((buffer+offset),this->m_fragments[i],DEF_FRAGMENT_LENGTH); - } - else { - // trailing... may be partial length... - memcpy((buffer+offset),this->m_fragments[i],this->m_last_fragment_length); - } - } - } - - // DEBUG - //DBG("assemble(): buffer=[%s] length=%d\r\n",buffer,buffer_length); - } - else { - // unable to assemble... - DBG("ERROR: Unable to assemble. calculateAssemblyLength() failed (%d)\r\n",length); - } - } - - // calculate the assembled packet length - int DataFragmenterAssembler::calculateAssemblyLength(int buffer_length) { - int length = 0; - - for(int i=0;i<this->m_num_fragments;++i) { - if (i < (this->m_num_fragments-1)) length += DEF_FRAGMENT_LENGTH; - else length += this->m_last_fragment_length; - } - - // sanity check - if (length > buffer_length) { - // input buffer is too small... - DBG("ERROR: calculateAssemblyLength() input buffer too small: %d bytes. required length: %d bytes.\r\n",buffer_length,length); - length = -1; - } - - return length; - } - - // dump the state of the Fragmenter/Assembler - void DataFragmenterAssembler::dump(void) - { - DBG("\r\nDUMP: Number of fragments: %d last_length=%d\r\n",this->m_num_fragments,this->m_last_fragment_length); - for(int i=0;i<this->m_num_fragments;++i) { - DBG("DUMP: Fragment[%d]=[%s] length=%d\r\n",i,this->m_fragments[i],strlen((const char *)this->m_fragments[i])); - } - DBG("\r\n"); - } - - - \ No newline at end of file