#include "tag.h" #include "lib.h" #include #include #include 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; }