Simple data buffer splitter and re-assembler.

Files at this revision

API Documentation at this revision

Comitter:
ansond
Date:
Thu Feb 12 20:06:15 2015 +0000
Parent:
0:12a931a6161c
Child:
2:5614523d641b
Commit message:
updates and renamed

Changed in this revision

DataFragmenterAssembler.cpp Show diff for this revision Revisions of this file
DataFragmenterAssembler.h Show diff for this revision Revisions of this file
SplitterAssembler.cpp Show annotated file Show diff for this revision Revisions of this file
SplitterAssembler.h Show annotated file Show diff for this revision Revisions of this file
diff -r 12a931a6161c -r 9f05dbd1c2c7 DataFragmenterAssembler.cpp
--- 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
diff -r 12a931a6161c -r 9f05dbd1c2c7 DataFragmenterAssembler.h
--- a/DataFragmenterAssembler.h	Thu Feb 12 20:00:36 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/**
- * @file    DataFragmenterAssembler.h
- * @brief   data fragmenter and assembler (for BLE UARTService...) header
- * @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.
- */
- 
-#ifndef __DATA_FRAGMENTER_ASSEMBLER_H__
-#define __DATA_FRAGMENTER_ASSEMBLER_H__
-
-#include "mbed.h"
-
-// TUNABLES
-#define MAX_FRAGMENTS           100     // maximum number of supported fragments... increase as needed...
-#define DEF_FRAGMENT_LENGTH     20      // Typically identical to BLE_UART_SERVICE_MAX_DATA_LEN in UARTService.h
-
-class DataFragmenterAssembler {
-    public:
-        /**
-        Constructor
-        */
-        DataFragmenterAssembler();
-        
-        /**
-        Fragment a data stream into "n" fragments of the given input fragement (from constructor) size
-        @param data input input data buffer
-        @param data_length input input data buffer length
-        @returns number of fragments created for the input buffer
-        */
-        int fragment(uint8_t *data,int data_length);
-        
-        /**
-        Get the ith fragment
-        @param index input the ith index value
-        @return the ith fragment pointer (null terminated)
-        */
-        uint8_t *get(int index);
-        
-        /**
-        Reset the Fragmenter/Assembler
-        */
-        void reset(void);
-        
-        /**
-        Add a fragment
-        @param fragment input fragment to add 
-        @param fragment_length input the input fragment length (sanity checks...)
-        @return the number of fragments currently stored
-        */
-        int add(uint8_t *fragment,int fragment_length);
-        
-        /**
-        Assemble fragments
-        @param buffer input the result buffer
-        @param buffer_length input the result buffer length (maximum)
-        @param reset_after_assemble input reset the Fragmenter/Assembler after assembly is complete (default: TRUE)
-        */
-        void assemble(uint8_t *buffer,int buffer_length,bool reset_after_assemble = true);
-        
-    private:
-        int     calculateNumFragments(uint8_t *data,int data_length);
-        int     calculateAssemblyLength(int buffer_length);
-        void    dump(void);
-        
-        int     m_num_fragments;
-        int     m_last_fragment_length;
-        uint8_t m_fragments[DEF_FRAGMENT_LENGTH+1][MAX_FRAGMENTS];
-};
-
-#endif // __DATA_FRAGMENTER_ASSEMBLER_H__
\ No newline at end of file
diff -r 12a931a6161c -r 9f05dbd1c2c7 SplitterAssembler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SplitterAssembler.cpp	Thu Feb 12 20:06:15 2015 +0000
@@ -0,0 +1,217 @@
+/**
+ * @file    SplitterAssembler.cpp
+ * @brief   data buffer splitter and assembler 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 "SplitterAssembler.h"
+ 
+// we have to redefine DBG as its used differently here...
+#ifdef DBG
+    #undef DBG
+#endif
+#define DBG  printf
+ 
+ // constructor
+ SplitterAssembler::SplitterAssembler() 
+ { 
+    this->reset();  
+ }
+ 
+ // fragment a buffer 
+ int SplitterAssembler::split(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 SplitterAssembler::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 *SplitterAssembler::get(int index)
+ {
+     if (index >= 0 && index < this->m_num_fragments) 
+        return this->m_fragments[index];
+    return NULL;
+ }
+ 
+ // reset the Fragmenter/Assembler
+ void SplitterAssembler::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 SplitterAssembler::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 SplitterAssembler::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 SplitterAssembler::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 SplitterAssembler::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->get(i),strlen((const char *)this->get(i)));
+     }
+     DBG("\r\n");
+ }
+ 
+ 
+ 
\ No newline at end of file
diff -r 12a931a6161c -r 9f05dbd1c2c7 SplitterAssembler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SplitterAssembler.h	Thu Feb 12 20:06:15 2015 +0000
@@ -0,0 +1,85 @@
+/**
+ * @file    SplitterAssembler.h
+ * @brief   data buffer splitter and assembler header
+ * @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.
+ */
+ 
+#ifndef __SPLITTER_ASSEMBLER_H__
+#define __SPLITTER_ASSEMBLER_H__
+
+#include "mbed.h"
+
+// TUNABLES
+#define MAX_FRAGMENTS           100     // maximum number of supported fragments... increase as needed...
+#define DEF_FRAGMENT_LENGTH     20      // Typically identical to BLE_UART_SERVICE_MAX_DATA_LEN in UARTService.h
+
+class SplitterAssembler {
+    public:
+        /**
+        Constructor
+        */
+        SplitterAssembler();
+        
+        /**
+        Split a data stream into "n" fragments of the given input fragement (from constructor) size
+        @param data input input data buffer
+        @param data_length input input data buffer length
+        @returns number of fragments created for the input buffer
+        */
+        int split(uint8_t *data,int data_length);
+        
+        /**
+        Get the ith fragment
+        @param index input the ith index value
+        @return the ith fragment pointer (null terminated)
+        */
+        uint8_t *get(int index);
+        
+        /**
+        Reset the Fragmenter/Assembler
+        */
+        void reset(void);
+        
+        /**
+        Add a fragment
+        @param fragment input fragment to add 
+        @param fragment_length input the input fragment length (sanity checks...)
+        @return the number of fragments currently stored
+        */
+        int add(uint8_t *fragment,int fragment_length);
+        
+        /**
+        Assemble fragments
+        @param buffer input the result buffer
+        @param buffer_length input the result buffer length (maximum)
+        @param reset_after_assemble input reset the Fragmenter/Assembler after assembly is complete (default: TRUE)
+        */
+        void assemble(uint8_t *buffer,int buffer_length,bool reset_after_assemble = true);
+        
+    private:
+        int     calculateNumFragments(uint8_t *data,int data_length);
+        int     calculateAssemblyLength(int buffer_length);
+        void    dump(void);
+        
+        int     m_num_fragments;
+        int     m_last_fragment_length;
+        uint8_t m_fragments[DEF_FRAGMENT_LENGTH+1][MAX_FRAGMENTS];
+};
+
+#endif // __SPLITTER_ASSEMBLER_H__
\ No newline at end of file