2015-07-29 2 views
1

У меня есть буфер данных с следующим содержанием:Обработка заголовка в буфере данных

00000000 20 7F 3E 15 38 34 37 2E 38 33 33 36 38 32 20 2F 
00000010 20 31 33 2E 30 30 35 34 31 39 20 3E 20 20 20 20  
00000020 20 3E 20 4E 4F 20 47 50 53 20 44 41 54 41 20 20 
00000030 20 20 20 20 20 20 20 20 20 20 20 20 

Теперь я хочу использовать «реальные» данные, чтобы обработать его в другой функции.

«Реальные» данные - это все после первых 5 байтов. Пятый байт в этом примере 0x38 - это длина данных. Как мне теперь сканировать буфер для заголовка 0x20 0x7F 0x3E 0x15 и байт длины данных и переместить реальное содержимое данных в другой буфер или, может быть, лучше, уложить текущий буфер только на содержимое данных?

Примечание: Я не могу выделить память динамически. Размер буфера всегда равен 60 байтам (включая заголовок).

Thx!

+0

Вы говорите, что «настоящие» данные - это все после первых 5 байтов »и« пятый байт - длина данных ». Итак, почему вы считаете, что вам нужно «сканировать» буфер для заголовка? – usr2564301

+0

Поскольку я хочу знать, получены ли данные, полученные от известного источника/устройства, поэтому мне нужно каждый раз проверять заголовок. – trek

+0

Вам все еще нужны первые пять байт после «удаления» буфера? – alk

ответ

1

Предполагая, что исходный буфер содержит, по меньшей мере, 5 байт:

#define CAPACITY UINT8_MAX 
uint8_t buf[CAPACITY], newbuf[CAPACITY - 5]; 
... 
int header_is_ok = 
    (buf[0] == 0x20 && buf[1] == 0x7F && buf[2] == 0x3E && buf[3] == 0x15); 

if (header_is_ok) { 
    uint8_t length = buf[4]; 

    if (length > 0 && length < CAPACITY - 5) { 
     uint8_t *contents = buf + 5; 
     memcpy(newbuf, contents, length); 
    } 
} 

memcpy бы переместить буфер в другое место после того, как начало содержимого и длины известны.

+1

Для полноты вам может потребоваться определить 'newBuf', а также' CAPACITY_OF_BUF'. – alk

+0

Ху, почему 'UINT8_MAX', а не только' 60'? – alk

+0

Поскольку 'length' является байтом и может быть' UINT8_MAX'. –

0

Мой первый вклад здесь в StackOverflow, надеюсь, вам понравится моя помощь.

Ответ выше достаточно хорош, но я хотел бы указать, как я это сделаю. Это облегчит вам отслеживание различных частей в заголовке и отделить заголовок от данных.

Недостатки в том, что вам нужно меньше комментариев, проще отлаживать и так далее.

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <string.h> 


//! Structure defining the different parts in the buffer 
typedef union 
{ 
    struct 
    { 
     uint8_t part1; 
     uint8_t part2; 
     uint8_t part3; 
     uint8_t part4; 
     uint8_t length; 
    }header; 
    uint8_t fullHeader[5]; 

    uint8_t *data; 
}tDataInfo; 


//! Size of header (in bytes) 
static const uint8_t sizeOfHeader = 5; 


//! Dummy data buffer 
static uint8_t dataBuffer[] = 
{ 
    0x20, 0x7F, 0x3E, 0x15, 0x0B, 0x34, 0x37, 0x2E, 0x38, 0x33, 0x33, 0x36, 0x38, 0x32, 0x20, 0x2F 
}; 


int main() 
{ 
    tDataInfo dataInfo; 
    uint8_t *dataPtr; 
    uint8_t cnt; 


    // Copy header information 
    memcpy(&dataInfo.header, dataBuffer, sizeOfHeader); 


    // Print out header information 
    printf("part1: %x\n", dataInfo.header.part1); 
    printf("part2: %x\n", dataInfo.header.part2); 
    printf("part3: %x\n", dataInfo.header.part3); 
    printf("part4: %x\n", dataInfo.header.part4); 
    printf("length: %d\n\n", dataInfo.header.length); 


    // Allocate space for the data 
    dataInfo.data = malloc(dataInfo.header.length); 

    // Point to first byte of data 
    dataPtr = dataBuffer + sizeOfHeader; 

    // Copy the data 
    memcpy(dataInfo.data, dataPtr, dataInfo.header.length); 

    // Print out the data 
    for (cnt = 0; cnt < dataInfo.header.length; cnt++) 
    { 
     printf("byte %d: %x\n", cnt, *(dataInfo.data+cnt)); 
    } 

    return 0; 
} 
0

Это решение напоминает одно из предыдущих, но более функционально. Это подразумевает, что машина использует малоформатный формат:

#include <stdio.h> 
#include <stdint.h> 

    typedef struct //pseudo structure describing the header and the data 
    { 
     int_16 key; //first 4 bytes as device key 
     unsigned char length; //length of data not including the 5 header bytes 
     char data[1] //pseudo array of buffer data 
    } DATA; 

    #define KEY 0x153e7f20 //The first 4 bytes used as a key to check for device 
    #define BUFSIZE 60  //buffer size 

    // The function return TRUE if any data is transferred to the buffer 
    BOOL ReadData(char *RawData, char *buf) 
    { 
     DATA *pdata = RawData; 
     if (KEY != pdata->key) 
      return FALSE; 

     memcpy(buf, pdata->data, pdata->length <= BUFSIZE ? pdata->length : BUFSIZE); 

     return TRUE; 
    } 
Смежные вопросы