Sona 0.50 Source

Sona 0.50/tools/mml2sona/blob.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "blob.h"

// Default amount of memory allocated for a new blob
#define DEFAULT_BLOB_ALLOC    0x100

//***************************************************************************
// create_blob
// Allocates a new empty blob.
//---------------------------------------------------------------------------
// return: pointer to blob
//***************************************************************************

Blob *create_blob(void)
{
   // Allocate blob structure
   Blob *blob = (Blob*) malloc(sizeof(Blob));
   if (blob == NULL) {
      fputs(ERRORMSG_NOMEMORY, stderr);
      exit(EXIT_FAILURE);
   }
   
   // Set up blob state
   blob->len = 0;
   blob->allocated = DEFAULT_BLOB_ALLOC;
   
   // Allocate the default amount of space
   blob->data = (uint8_t*) malloc(blob->allocated);
   if (blob->data == NULL) {
      fputs(ERRORMSG_NOMEMORY, stderr);
      exit(EXIT_FAILURE);
   }
   
   // Return new blob
   return blob;
}

//***************************************************************************
// append_to_blob
// Appends a bunch of bytes to a blob.
//---------------------------------------------------------------------------
// param blob: pointer to blob
// param src:  pointer to data to append
// param len:  size of data to append
//***************************************************************************

void append_to_blob(Blob *blob, const uint8_t *src, size_t len)
{
   if (blob == NULL) return;
   
   // Update blob length and see if the allocated array needs to be resized
   blob->len += len;
   
   if (blob->allocated < blob->len) {
      while (blob->allocated < blob->len) {
         blob->allocated *= 2;
      }
      blob->data = (uint8_t*) realloc(blob->data, blob->allocated);
      if (blob->data == NULL) {
         fputs(ERRORMSG_NOMEMORY, stderr);
         exit(EXIT_FAILURE);
      }
   }
   
   // Copy over the data into the blob
   uint8_t *dest = &blob->data[blob->len - len];
   memcpy(dest, src, len);
}

//***************************************************************************
// delete_blob
// Deallocates a blob.
//---------------------------------------------------------------------------
// param blob: pointer to blob
//---------------------------------------------------------------------------
// note: the pointer to the blob becomes invalid after calling this.
//***************************************************************************

void delete_blob(Blob *blob)
{
   if (blob == NULL) return;
   free(blob->data);
   free(blob);
}