diff options
author | Freya Murphy <freya@freyacat.org> | 2023-12-14 18:08:16 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2023-12-14 18:08:16 -0500 |
commit | 00c88659104ce423959151ff6f3f96f6537a6d68 (patch) | |
tree | c2745a95c2b7f15f69f8bfcaa85e0b12626f6142 /src/tag.c | |
download | nbtvis-00c88659104ce423959151ff6f3f96f6537a6d68.tar.gz nbtvis-00c88659104ce423959151ff6f3f96f6537a6d68.tar.bz2 nbtvis-00c88659104ce423959151ff6f3f96f6537a6d68.zip |
testing
Diffstat (limited to 'src/tag.c')
-rw-r--r-- | src/tag.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/tag.c b/src/tag.c new file mode 100644 index 0000000..ded1c07 --- /dev/null +++ b/src/tag.c @@ -0,0 +1,195 @@ +#include "tag.h" +#include "lib.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +bool tag_read_header(tag_t *tag, stream_t *stream, bool named) { + bool ok = true; + + if (stream_read_i8(stream, &tag->type) == false) + return false; + + if (tag->type == TAG_END) + named = false; + + if (named) { + if (stream_read_u16(stream, &tag->name_len) == false) + return false; + } else { + tag->name_len = 0; + } + + if (tag->name_len < 1) { + tag->name = ""; + } else { + tag->name = xalloc(tag->name_len); + ok = stream_read(stream, &tag->name, tag->name_len); + } + + if (!ok) + return false; + + return true; +} + + +static bool tag_read_byte_array(tagdata_t *data, stream_t *stream) { + if (stream_read_i32(stream, &data->b_arr.size) == false) + return false; + data->b_arr.data = xalloc(data->b_arr.size * sizeof(int8_t)); + for (int32_t i = 0; i < data->b_arr.size; i++) + if (stream_read_i8(stream, &data->b_arr.data[i]) == false) + return false; + return true; +} + +static bool tag_read_int_array(tagdata_t *data, stream_t *stream) { + if (stream_read_i32(stream, &data->i_arr.size) == false) + return false; + data->i_arr.data = xalloc(data->i_arr.size * sizeof(int32_t)); + for (int32_t i = 0; i < data->i_arr.size; i++) + if (stream_read_i32(stream, &data->i_arr.data[i]) == false) + return false; + return true; +} + +static bool tag_read_long_array(tagdata_t *data, stream_t *stream) { + if (stream_read_i32(stream, &data->l_arr.size) == false) + return false; + data->l_arr.data = xalloc(data->l_arr.size * sizeof(int64_t)); + for (int32_t i = 0; i < data->l_arr.size; i++) + if (stream_read_i64(stream, &data->l_arr.data[i]) == false) + return false; + return true; +} + +static bool tag_read_string(tagdata_t *data, stream_t *stream) { + if (stream_read_u16(stream, &data->string.size) == false) + return false; + data->string.data = xalloc(data->string.size); + if (stream_read(stream, &data->string.data, data->string.size) == false) + return false; + return true; +} + +static bool tag_read_list(tagdata_t *data, stream_t *stream) { + if (stream_read_i8(stream, &data->list.type) == false) + return false; + if (stream_read_i32(stream, &data->list.size) == false) + return false; + if (data->list.size <= 0) { + data->list.tags = NULL; + return true; + } else if (data->list.type == 0) { + // tag end is not allowed to be used with non empty list + return false; + } + data->list.tags = xalloc(data->list.size * sizeof(tag_t)); + for (int32_t i = 0; i < data->list.size; i++) { + tag_t tag; + tag.type = data->list.type; + tag.name = ""; + tag.name_len = 0; + if (tag_read_data(&tag, stream) == false) + return false; + data->list.tags[i] = tag; + } + return true; +} + +static bool tag_read_compound(tagdata_t *data, stream_t *stream) { + printf("entering tag read compound\n"); + int32_t size = 0; + int32_t capacity = 8; + tag_t *tags = xalloc(capacity * sizeof(tag_t)); + + while (1) { + + tag_t tag; + + if (tag_read_header(&tag, stream, true) == false) + return false; + + if (tag.type == TAG_END) + break; + + if (tag_read_data(&tag, stream) == false) + return false; + + if (size == capacity) { + capacity *= 2; + tags = xrealloc(tags, capacity * sizeof(tag_t)); + } + + tags[size++] = tag; + } + + data->compound.size = size; + data->compound.tags = xalloc(size * sizeof(tag_t)); + memcpy(data->compound.tags, tags, size * sizeof(tag_t)); + free(tags); + + printf("returning from tag read compound\n"); + return true; +} + +bool tag_read_data(tag_t *tag, stream_t *stream) { + printf("READING THE FUCKING DATA!!!!\n"); + void *p = NULL; + printf("%p\n", (void*)&p); + bool ok = true; + + switch (tag->type) { + case TAG_END: + // tag has no data + break; + case TAG_BYTE: + ok = stream_read_i8(stream, &tag->data.b); + break; + case TAG_SHORT: + ok = stream_read_i16(stream, &tag->data.s); + break; + case TAG_FLOAT: + case TAG_INT: + ok = stream_read_i32(stream, &tag->data.i); + break; + case TAG_DOUBLE: + case TAG_LONG: + ok = stream_read_i64(stream, &tag->data.l); + break; + case TAG_BYTE_ARRAY: + ok = tag_read_byte_array(&tag->data, stream); + break; + case TAG_STRING: + ok = tag_read_string(&tag->data, stream); + break; + case TAG_LIST: + ok = tag_read_list(&tag->data, stream); + break; + case TAG_COMPOUND: + printf("TAG OWO TAG OWO\n"); + ok = tag_read_compound(&tag->data, stream); + printf("TAG OWO TAG OWO PART 2\n"); + break; + case TAG_INT_ARRAY: + ok = tag_read_int_array(&tag->data, stream); + break; + case TAG_LONG_ARRAY: + ok = tag_read_long_array(&tag->data, stream); + break; + break; + }; + printf("read tag: %d\n", tag->type); + return ok; +} + +bool tag_read(tag_t *tag, stream_t *stream, bool named) { + memset(tag, 0, sizeof(tag_t)); + if (tag_read_header(tag, stream, named) == false) + return false; + if (tag_read_data(tag, stream) == false) + return false; + return true; +} + |