Commit 20237a821e3233ca509bb110cf758994d190c0ff
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 | \ No newline at end of file | 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 | \ No newline at end of file | 53 | \ No newline at end of file |