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 | 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 | ... | ... |