Skip to content

Instantly share code, notes, and snippets.

@leonardosnt
Created January 11, 2018 22:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonardosnt/41bcb44777893c6fa65f2a216062a850 to your computer and use it in GitHub Desktop.
Save leonardosnt/41bcb44777893c6fa65f2a216062a850 to your computer and use it in GitHub Desktop.
/**
* MIT License
*
* Copyright (c) 2018 leonardosnt <leonrdsnt@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef bytebuf__h_
#define bytebuf__h_
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#define CAN_WRITE(buf, size) (buf->offset + size <= buf->length)
/**
* Generate a function that looks like this:
*
* bool bytebuf_write_float(bytebuf_t* buf, float value) {
* if (!CAN_WRITE(buf, sizeof(float))) {
* return false;
* }
* *((float*) (buf->data + buf->offset)) = value;
* buf->offset += sizeof(float);
* return true;
* }
*/
#define WRITE_TEMPLATE(name_suffix, type) \
bool bytebuf_write_##name_suffix(bytebuf_t* buf, type value) { \
if (!CAN_WRITE(buf, sizeof(type))) { \
return false; \
} \
*((type*) (buf->data + buf->offset)) = value; \
buf->offset += sizeof(type); \
return true; \
}
/**
* Generate a function that looks like this:
*
* float bytebuf_read_float(bytebuf_t* buf) {
* float result = *((float*) (buf->data + buf->offset));
* buf->offset += sizeof(float);
* return result;
* }
*/
#define READ_TEMPLATE(name_suffix, type) \
type bytebuf_read_##name_suffix(bytebuf_t* buf) { \
type result = *((type*) (buf->data + buf->offset)); \
buf->offset += sizeof(type); \
return result; \
}
typedef struct {
uint8_t* data;
/* length of data */
size_t length;
/* current write/read offset */
uint32_t offset;
} bytebuf_t;
bytebuf_t* bytebuf_wrap(uint8_t* data, size_t length) {
bytebuf_t* buf = (bytebuf_t*) malloc(sizeof(bytebuf_t));
buf->data = data;
buf->length = length;
buf->offset = 0;
return buf;
}
/**
* Alloc a new bytebuf and return it
*/
bytebuf_t* bytebuf_alloc(size_t size) {
bytebuf_t* buf = (bytebuf_t*) malloc(sizeof(bytebuf_t));
buf->data = (uint8_t*) malloc(size);
buf->length = size;
buf->offset = 0;
return buf;
}
/**
* Alloc a new bytebuf and fill its data with zeros
*/
bytebuf_t* bytebuf_calloc(size_t size) {
bytebuf_t* buf = bytebuf_alloc(size);
memset(buf->data, 0, size);
return buf;
}
void bytebuf_free(bytebuf_t* buf) {
free(buf->data);
free(buf);
}
bool bytebuf_write(bytebuf_t* buf, char* data, size_t data_size) {
if (!CAN_WRITE(buf, data_size)) {
return false;
}
memcpy((buf->data + buf->offset), data, data_size);
buf->offset += data_size;
return true;
}
WRITE_TEMPLATE(i8, int8_t) /* bool bytebuf_write_i8(bytebuf_t* buf, int8_t value); */
WRITE_TEMPLATE(i16, int16_t) /* bool bytebuf_write_i16(bytebuf_t* buf, int16_t value); */
WRITE_TEMPLATE(i32, int32_t) /* bool bytebuf_write_i32(bytebuf_t* buf, int32_t value); */
WRITE_TEMPLATE(i64, int64_t) /* bool bytebuf_write_i64(bytebuf_t* buf, int64_t value); */
WRITE_TEMPLATE(float, float) /* bool bytebuf_write_float(bytebuf_t* buf, float value); */
WRITE_TEMPLATE(double, double) /* bool bytebuf_write_double(bytebuf_t* buf, double value); */
READ_TEMPLATE(i8, int8_t) /* int8_t bytebuf_read_i8(bytebuf_t* buf); */
READ_TEMPLATE(i16, int16_t) /* int16_t bytebuf_read_i16(bytebuf_t* buf); */
READ_TEMPLATE(i32, int32_t) /* int32_t bytebuf_read_i32(bytebuf_t* buf); */
READ_TEMPLATE(i64, int64_t) /* int64_t bytebuf_read_i64(bytebuf_t* buf); */
READ_TEMPLATE(float, float) /* float bytebuf_read_float(bytebuf_t* buf); */
READ_TEMPLATE(double, double) /* double bytebuf_read_double(bytebuf_t* buf); */
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment