8
\$\begingroup\$

This is a byte stream implementation in C. Its usage and purpose should be evident from main.

Implementation is not finished; this is just start. Comments are still welcome.

.h:

#include <stdint.h>
typedef struct
{
 uint8_t * data;
 uint32_t length;
 uint32_t offset;
} ByteStream;
int32_t BSInitWithSize(ByteStream *bs, uint32_t len);
uint32_t BSNrOfRemainingBytes(ByteStream *bs);
int32_t BSFreeUnderlyingArray(ByteStream *bs);
void BSPrintContents(ByteStream *bs);
void BSRewind(ByteStream *bs);
int32_t BSPutU8(ByteStream *bs, uint8_t v);
int32_t BSGetU8(ByteStream *bs, uint8_t *out);
int32_t BSPutU16LE(ByteStream *bs, uint16_t v);

.c:

#include "ByteStream.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int32_t BSInitWithSize(ByteStream *bs, uint32_t len)
{
 if (NULL == bs)
 return -1;
 // Allocate data array of sufficient length
 bs->data = (uint8_t*)malloc(len); // Note: Probably should check return value here
 memset(bs->data,0,len); // set values to nil
 bs->length = len;
 bs->offset = 0;
 return 0;
}
uint32_t BSNrOfRemainingBytes(ByteStream *bs)
{
 return bs->length - bs->offset;
}
void BSRewind(ByteStream *bs)
{
 bs->offset=0;
}
int32_t BSPutU8(ByteStream *bs, uint8_t v)
{
 if(BSNrOfRemainingBytes(bs)<1)
 return -1;
 bs->data[bs->offset]=v;
 bs->offset++;
 return 0;
}
int32_t BSGetU8(ByteStream *bs, uint8_t *out)
{
 if(BSNrOfRemainingBytes(bs)<1)
 return -1;
 bs->offset++;
 *out= bs->data[bs->offset-1];
 return 0;
}
int32_t BSPutU16LE(ByteStream *bs, uint16_t v)
{
 if(BSNrOfRemainingBytes(bs)<2)
 return -1;
 // This code compiles on LE machine, so
 // copying a integer to buffer will write
 // the integer into the buffer in a little endian way
 // exactly what this method is supposed to do
 // Note: Probably this is not portable
 memcpy(&bs->data[bs->offset],&v,2);
 bs->offset+=2;
 return 0;
}
void BSPrintContents(ByteStream *bs)
{
 int i = 0;
 for(i=0; i<bs->offset; i++)
 {
 printf("%02X ",bs->data[i]);
 }
}
int32_t BSFreeUnderlyingArray(ByteStream *bs)
{
 // Free underlying data array of BS object if it is not NULL
 if(NULL != bs->data)
 {
 free(bs->data);
 bs->data=NULL; // Set to NULL
 return 0;
 }
 return -1;
}

main:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern "C"
{
#include "ByteStream.h"
}
int _tmain(int argc, _TCHAR* argv[])
{
 ByteStream b;
 memset(&b,0,sizeof(b));
 // Init bs
 BSInitWithSize(&b,14);
 // Add values
 for(int i=0;i<12;i++)
 {
 if(-1 == BSPutU8(&b, (uint8_t)i))
 printf("Error putting data \n");
 printf("Remaining Free Bytes: %d\n",BSNrOfRemainingBytes(&b));
 }
 // Rewind
 printf("---\n");
 BSRewind(&b);
 // Print values
 for(int i=0;i<12;i++)
 {
 uint8_t t;
 if(-1 == BSGetU8(&b, &t))
 {
 printf("ERROR Getting value \n");
 }
 else
 printf("Value at %d is %d \n", i, t);
 }
 // Put short integer in a little endian way
 if(-1 == BSPutU16LE(&b,765))
 printf("Error putting short \n");
 BSPrintContents(&b);
 // Free underlying buffer
 BSFreeUnderlyingArray(&b);
 return 0;
}

In many cases I decided to return error code from functions, and pass return values as out parameters.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 25, 2014 at 12:01
\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

A few things:

  • You are casting the result of your calls to malloc. That is something you shouldn't do actually.
  • If possible, try not to used fixed-size integer types (uint32_t, int32_t, etc...) for they are only conditionally supported by the compiler. For example, I doubt that you need a fixed-size type for your error codes. At least, use int_least32_t instead.
  • When you are not using any format string, you should consider using puts to printf (e.g. puts("---") instead of printf("---\n"). That's both shorther and safer.
  • Also, you initialize i to 0 twice in BSPrintContents. That seems pretty useless.
answered Mar 25, 2014 at 13:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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