Commit 20237a821e3233ca509bb110cf758994d190c0ff

Authored by Imanol-Mikel Barba Sabariego
0 parents

Initial import

Showing 2 changed files with 223 additions and 0 deletions
nbt.c 0 → 100644
  1 +++ a/nbt.c
  1 +#include "nbt.h"
  2 +
  3 +void destroyTag(Tag* t);
  4 +void destroyTagList(TagList* l);
  5 +void destroyTagCompound(TagCompound* tc);
  6 +unsigned int parsePayload(void* addr,Tag* t);
  7 +
  8 +void destroyTag(Tag* t) {
  9 + if(t->nameLength) {
  10 + free(t->name);
  11 + }
  12 +
  13 + if(t->type == TAG_BYTEARRAY || t->type == TAG_INTARRAY || t->type == TAG_LIST) {
  14 + destroyTagList((TagList*)t->payload);
  15 + } else if(t->type == TAG_COMPOUND) {
  16 + destroyTagCompound((TagCompound*)t->payload);
  17 + }
  18 +
  19 + if(t->payloadLength) {
  20 + free(t->payload);
  21 + }
  22 +}
  23 +
  24 +void destroyTagList(TagList* l) {
  25 + for(int i = 0; i < l->size; ++i) {
  26 + destroyTag(&l->list[i]);
  27 + }
  28 +}
  29 +
  30 +void destroyTagCompound(TagCompound* tc) {
  31 + for(int i = 0; i < tc->numTags; ++i) {
  32 + destroyTag(&tc->list[i]);
  33 + }
  34 +}
  35 +
  36 +size_t getTypeSize(uint8_t type) {
  37 + switch(type) {
  38 + case TAG_BYTE:
  39 + return sizeof(uint8_t);
  40 + break;
  41 + case TAG_SHORT:
  42 + return sizeof(uint16_t);
  43 + break;
  44 + case TAG_INT:
  45 + return sizeof(uint32_t);
  46 + break;
  47 + case TAG_LONG:
  48 + return sizeof(uint64_t);
  49 + break;
  50 + case TAG_FLOAT:
  51 + return sizeof(float);
  52 + break;
  53 + case TAG_DOUBLE:
  54 + return sizeof(double);
  55 + break;
  56 + default:
  57 + break;
  58 + }
  59 + return 0;
  60 +}
  61 +
  62 +unsigned int parseList(void* addr, TagList* tl, uint8_t type) {
  63 + void* pos = addr;
  64 + if(type == TAG_LIST) {
  65 + tl->type = *((uint8_t*)pos);
  66 + pos += sizeof(uint8_t);
  67 + } else if(type == TAG_BYTEARRAY) {
  68 + tl->type = TAG_BYTE;
  69 + } else if(type == TAG_INTARRAY) {
  70 + tl->type = TAG_INT;
  71 + }
  72 +
  73 + tl->size = __bswap_32(*((uint32_t*)pos));
  74 + pos += sizeof(uint32_t);
  75 + tl->list = NULL;
  76 + if(tl->type != TAG_END) {
  77 + tl->list = calloc(tl->size,sizeof(Tag));
  78 + for(int i = 0; i < tl->size; ++i) {
  79 + Tag *t = &tl->list[i];
  80 + t->type = tl->type;
  81 + t->name = NULL;
  82 + t->nameLength = 0;
  83 + pos += parsePayload(pos,t);
  84 + }
  85 + }
  86 + return pos - addr;
  87 +}
  88 +
  89 +unsigned int parseCompound(void* addr, TagCompound* tc) {
  90 + void* pos = addr;
  91 + unsigned int numTags = 0;
  92 + Tag* list = calloc(REALLOC_SIZE,sizeof(Tag));
  93 + do {
  94 + if(numTags && !(numTags % REALLOC_SIZE)) {
  95 + void* newptr = reallocarray(list, numTags + REALLOC_SIZE, sizeof(Tag));
  96 + if(!newptr) {
  97 + fprintf(stderr,"Unable to request memory realloc\n");
  98 + break;
  99 + }
  100 + list = newptr;
  101 + }
  102 + pos += parseTag(pos,&list[numTags]);
  103 + } while(list[numTags++].type != TAG_END);
  104 +
  105 + tc->list = list;
  106 + tc->numTags = numTags-1;
  107 + return pos - addr;
  108 +}
  109 +
  110 +unsigned int parsePayload(void* addr,Tag* t) {
  111 + void* pos = addr;
  112 + t->payloadLength = getTypeSize(t->type); // initially, then particularly for lists/compounds/strings
  113 + TagCompound* tc;
  114 + TagList *tl;
  115 + switch(t->type) {
  116 + case TAG_BYTE:
  117 + case TAG_SHORT:
  118 + case TAG_INT:
  119 + case TAG_LONG:
  120 + case TAG_FLOAT:
  121 + case TAG_DOUBLE:
  122 + t->payload = calloc(1,t->payloadLength);
  123 + memcpy(t->payload,pos,t->payloadLength);
  124 + pos += t->payloadLength;
  125 + break;
  126 + case TAG_STRING:
  127 + t->payloadLength = __bswap_16(*((uint16_t*)pos));
  128 + t->payload = NULL;
  129 + if(t->payloadLength) {
  130 + t->payload = calloc(t->payloadLength,sizeof(char));
  131 + memcpy(t->payload,pos+sizeof(uint16_t),t->payloadLength);
  132 + }
  133 + pos += sizeof(uint16_t) + t->payloadLength;
  134 + break;
  135 + case TAG_COMPOUND:
  136 + tc = (TagCompound*)calloc(1,sizeof(TagCompound));
  137 + t->payloadLength = sizeof(sizeof(TagCompound));
  138 + t->payload = tc;
  139 + pos += parseCompound(pos,tc);
  140 + break;
  141 + case TAG_LIST:
  142 + case TAG_BYTEARRAY:
  143 + case TAG_INTARRAY:
  144 + tl = (TagList*)calloc(1,sizeof(TagList));
  145 + t->payloadLength = sizeof(sizeof(TagList));
  146 + t->payload = tl;
  147 + pos += parseList(pos,tl,t->type);
  148 + break;
  149 + }
  150 + return pos - addr;
  151 +}
  152 +
  153 +unsigned int parseTag(void* addr, Tag* t) {
  154 + void* pos = addr;
  155 + t->type = *((uint8_t*)pos);
  156 + t->nameLength = 0;
  157 + t->payloadLength = 0;
  158 + pos += sizeof(uint8_t);
  159 + if(t->type != TAG_END) {
  160 + t->nameLength = __bswap_16(*((uint16_t*)pos));
  161 + t->name = NULL;
  162 + if(t->nameLength) {
  163 + t->name = calloc(t->nameLength,sizeof(char));
  164 + memcpy(t->name,pos+sizeof(uint16_t),t->nameLength);
  165 + }
  166 + pos += sizeof(uint16_t) + t->nameLength;
  167 + }
  168 + pos += parsePayload(pos,t);
  169 +
  170 + return pos-addr;
  171 +}
0 172 \ No newline at end of file
... ...
nbt.h 0 → 100644
  1 +++ a/nbt.h
  1 +#ifndef _NBT_H
  2 +#define _NBT_H
  3 +
  4 +#include <stdint.h>
  5 +#include <byteswap.h>
  6 +#include <stdlib.h>
  7 +#include <stdio.h>
  8 +#include <malloc.h>
  9 +#include <string.h>
  10 +
  11 +#ifndef REALLOC_SIZE
  12 +#define REALLOC_SIZE 10
  13 +#endif
  14 +
  15 +typedef struct Tag {
  16 + uint8_t type;
  17 + char* name;
  18 + unsigned int nameLength;
  19 + unsigned int payloadLength;
  20 + void* payload;
  21 +} Tag;
  22 +
  23 +typedef struct TagList {
  24 + uint8_t type;
  25 + uint32_t size;
  26 + Tag* list;
  27 +} TagList;
  28 +
  29 +typedef struct TagCompound {
  30 + unsigned int numTags;
  31 + Tag* list;
  32 +} TagCompound;
  33 +
  34 +enum TAG {
  35 + TAG_END = 0,
  36 + TAG_BYTE,
  37 + TAG_SHORT,
  38 + TAG_INT,
  39 + TAG_LONG,
  40 + TAG_FLOAT,
  41 + TAG_DOUBLE,
  42 + TAG_BYTEARRAY,
  43 + TAG_STRING,
  44 + TAG_LIST,
  45 + TAG_COMPOUND,
  46 + TAG_INTARRAY
  47 +};
  48 +
  49 +void destroyTag(Tag* t);
  50 +unsigned int parseTag(void* addr, Tag* t);
  51 +
  52 +#endif
0 53 \ No newline at end of file
... ...