2

My C++ project has a buffer which could be any size and is filled by Bluetooth. The format of the incoming messages is like 0x43 0x0B 0x00 0x06 0xA2 0x03 0x03 0x00 0x01 0x01 0x0A 0x0B 0x0B 0xE6 0x0D in which starts with 0x43 and ends with 0x0D. So, it means that each time when buffer is filled, it can have different order of contents according to the above message format.

static const int BufferSize = 1024;
byte buffer[BufferSize];
  1. What is the best way to parse the incoming messages in this buffer?
  2. Since I have come from Java and .NET, What is the best way to make each extracted message as an object? Class could be solution?
  3. I have created a separate class for parsing the buffer like bellow, am I in a right direction?

#include<parsingClass.h>
class A
{
   parsingClass ps;
public:
   parsingClass.parse(buffer, BufferSize);
}
1
  • Thank you, I was trying to put them in the code style. Commented Oct 18, 2012 at 12:21

4 Answers 4

2
class ReturnMessage{
    char *message; 
    public:
    char *getMessage(unsigned char *buffer,int count){
         message = new char[count];
         for(int i = 1; i < count-2; i++){
            message[i-1] = buffer[i];
         }
         message[count-2] = '\0';
         return message;
    }
};
class ParserToMessage{
static int BufferSize = 1024;
unsigned char buffer[BufferSize];
unsigned int counter;
public:
  static char *parse_buffer()
  {
     ReturnMessage rm;
     unsigned char buffByte;
     buffByte = blueToothGetByte(); //fictional getchar() kind of function for bluetooth
     if(buffByte == 0x43){
        buffer[counter++] = buffByte;
        //continue until you find 0x0D
        while((buffByte = blueToothGetByte()) != 0x0D){
            buffer[counter++] = buffByte;
        }
     }
     return rm.getMessage(buffer,counter);
   }
};
Sign up to request clarification or add additional context in comments.

Comments

2

Can you have the parser as a method of a 'ProtocolUnit' class? The method could take a buffer pointer/length as a parameter and return an int that indicates how many bytes it consumed from the buffer before it correctly assembled a complete protocol unit, or -1 if it needs more bytes from the next buffer.

Once you have a complete ProtocolUnit, you can do what you wish with it, (eg. queue it off to some processing thread), and create a new one for the remaining bytes/next buffer.

Comments

1

My C++ project has a buffer which could be any size

The first thing I notice is that you have hard-coded the buffer size. You are in danger of buffer overflow if an attempt is made to read data bigger than the size you have specified into the buffer.

If possible keep the buffer size dynamic and create the byte array according to the size of the data to be received into the buffer. Try and inform the object where your byte array lives of the incoming buffer size, before you create the byte array.

int nBufferSize = GetBufferSize();
UCHAR* szByteArray = new UCHAR[nBufferSize];

What is the best way to parse the incoming messages in this buffer?

You are on the right lines, in that you have created and are using a parser class. I would suggest using memcpy to copy the individual data items one at a time, from the buffer to a variable of your choice. Not knowing the wider context of your intention at this point, I cannot add much to that.

Since I have come from Java and .NET, What is the best way to make each extracted message as an object? Class could be solution?

Depending on the complexity of the data you are reading from the buffer and what your plans are, you could use a class or a struct. If you do not need to create an object with this data, which provides services to other objects, you could use a struct. Structs are great when your need isn't so complex, whereby a full class might be overkill.

I have created a separate class for parsing the buffer like bellow, am I in a right direction?

I think so.

I hope that helps for starters!

Comments

1

The question "how should I parse this" depends largely on how you want to parse the data. Two things are missing from your question:

  1. Exactly how do you receive the data? You mention Bluetooth but what is the programming medium? Are you reading from a socket? Do you have some other kind of API? Do you receive it byte at a time or in blocks?
  2. What are the rules for dealing with the data you are receiving? Most data is delimited in some way or of fixed field length. In your case, you mention that it can be of any length but unless you explain how you want to parse it, I can't help.

One suggestion I would make is to change the type of your buffer to use std::vector :

std::vector<unsigned char> buffer(normalSize)

You should choose normalSize to be something around the most frequently observed size of your incoming message. A vector will grow as you push items onto it so, unlike the array you created, you won't need to worry about buffer overrun if you get a large message. However, if you do go above normalSize under the covers the vector will reallocate enough memory to cope with your extended requirements. This can be expensive so you don't want to do it too often.

You use a vector in pretty much the same way as your array. One key difference is that you can simply push elements onto the end of the vector, rather than having to keep a running pointer. SO imagine you received a single int at a time from the Bluetooth source, your code might look something like this:

// Clear out the previous contents of the buffer.
buffer.clear();

int elem(0);
// Find the start of your message. Throw away elements
// that we don't need.
while ( 0x43 != ( elem = getNextBluetoothInt() ) );

// Push elements of the message into the buffer until
// we hit the end.
while ( 0x0D != elem )
{
    buffer.push_back( elem );
}
buffer.push_back( elem ); // Remember to add on the last one.

The key benefit is that array will automatically resize the vector without you having to do it no matter whether the amount of characters pushed on is 10 or 10,000.

2 Comments

Could you give me simple example how I can use vector in this context.
@pima.developer: I'd be happy to but, as I said in the answer, without knowing exactly what you're doing, it's a bit tricky to be precise. I've added more details on how to capture the data in a vector but as to how you'd want to parse it, I'm afraid there's not enough to go on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.