196 lines
4.8 KiB
C
196 lines
4.8 KiB
C
|
#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;
|
||
|
}
|
||
|
|