tags:

views:

159

answers:

4

I wanna pack some information plus some metadata in a byte array. In the following I have 3 bytes of information which have a certain offset plus 4 bytes of metadata added at the beginning of the packet in the end. Solution 1 I came up is pretty obvious to do that but requires a second tmp variable which I do not really like.

int size = 3;
int metadata = 4;

unsigned char * test = new unsigned char[size];
unsigned char * testComplete = new unsigned char[size+metadata];

test[offest1] = 'a';
test[offest2] = 'b';
test[offest3] = 'c';

set_first_4bytes(testComplete, val );           
memcpy(&testComplete[metadata], test, size);

Another straightforward solution would be to do it the following way:

unsigned char * testComplete = new unsigned char[size+metadata];

testComplete[offest1+metadata] = 'a';
testComplete[offest2+metadata] = 'b';
testComplete[offest3+metadata] = 'c';

set_first_4bytes(testComplete, val );

However, I don not like here the fact that each time I have the metadata offset to add so that I get the right index in my final packet. Is there another elegant solution which DOES not have the drawbacks of my approaches?

Thanks!

+2  A: 
unsigned char * testComplete = new unsigned char[size+metadata];
unsigned char * actualData = testComplete + metadata;
EFraim
That looks good, many thanks!
+1  A: 

Store the data and metadata on separate char arrays, inside a struct. Templatize the struct on the length of the arrays.

nagul
A: 
// Create space for the first four bytes.
std::vector<char> testComplete(metadata);
testComplete.reserve(metadata+size);     // to avoid re-allocation

// Add last three to the back.
testComplete.push_back('a');    // sets testComplete[metadata+offset1] to 'a'
testComplete.push_back('b');
testComplete.push_back('c');

// pass raw pointer to char, or change this function to take std::vector
set_first_4bytes(&(testComplete[0]), val);
Ryan
+2  A: 

I would recommend you to use the C++ facilities. Use a real class for the composition of the data. Inside the class, prefer std::vector<> over plain arrays to store the data (unless you do need the data to be stored in the heap). If you need it you can provide constant accessors to the internal data in the vector.

class data_type
{
public:
   data_type() : data_(), metadata_() {}

   const unsigned char * raw_data() const { // accessor to vector internal buffer
      return &data_[0];
   }
   const std::vector< unsigned char >& data() const {
      return data_;
   }
   const metadata_type& metadata() const {
      return metadata_;
   }
private:
   std::vector< unsigned char > data_;
   metadata_type metadata_; // it can be of any type
};
David Rodríguez - dribeas