Browse Source

Corrections to fix tests and detect more errors

master
Zack Marvel 1 year ago
parent
commit
2cd953c674
9 changed files with 122 additions and 28 deletions
  1. +23
    -16
      Makefile
  2. +4
    -0
      asan_env
  3. +15
    -1
      include/nbt.hpp
  4. +38
    -3
      src/nbt.cpp
  5. +1
    -1
      src/nbt_dump.cpp
  6. +1
    -1
      test/data/compound_tag.hex
  7. +14
    -0
      test/data/decode.py
  8. +16
    -2
      test/data/list_compound_tag.hex
  9. +10
    -4
      test/test_nbt.cpp

+ 23
- 16
Makefile View File

@@ -5,11 +5,14 @@ TEST_EXE = test_nbt

STATIC_LIB = libnbtpp.a

SRCS = \
LIB_SRCS = src/nbt.cpp \

LIB_OBJS := $(LIB_SRCS:%.cpp=%.o)

EXE_SRCS = \
src/nbt_dump.cpp \
src/nbt.cpp \

OBJS := $(SRCS:%.cpp=%.o)
EXE_OBJS := $(EXE_SRCS:%.cpp=%.o)

INCDIRS = -Iinclude

@@ -26,42 +29,46 @@ TEST_OBJS := $(TEST_SRCS:%.cpp=%.o)

TEST_INCDIRS = -Ilib/Catch2/single_include

TEST_CXXFLAGS := $(CXXFLAGS) $(TEST_INCDIRS)

DEPS := $(SRCS:%.cpp=%.d) $(TEST_SRCS:%.cpp=%.d)
DEPS := $(LIB_SRCS:%.cpp=%.d) $(EXE_SRCS:%.cpp=%.d) $(TEST_SRCS:%.cpp=%.d)

all: $(EXE) $(STATIC_LIB)

.PHONY: test
test: $(TEST_EXE) test_data

$(EXE): src/nbt_dump.o $(STATIC_LIB)
$(EXE): $(EXE_OBJS) $(STATIC_LIB)
$(CXX) $(LDFLAGS) -o [email protected] $^

$(STATIC_LIB): src/nbt.o
$(EXE_OBJS): $(STATIC_LIB)

%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -o [email protected] $<

$(STATIC_LIB): $(LIB_OBJS)
ar rcs [email protected] $^

$(TEST_OBJS): CXXFLAGS += $(TEST_CXXFLAGS)
$(TEST_OBJS): CXXFLAGS += $(TEST_INCDIRS)

$(TEST_EXE): $(TEST_OBJS) $(STATIC_LIB) test_data
$(CXX) $(LDFLAGS) -o [email protected] $(TEST_OBJS) $(STATIC_LIB)

$(TEST_EXE): $(TEST_OBJS) $(STATIC_LIB)
$(CXX) $(LDFLAGS) -o [email protected] $^

.PHONY: test_data
test_data:
make -C test/data
$(MAKE) -C test/data

.PHONY: check
check: test
check: $(TEST_EXE)
./$(TEST_EXE)


.PHONY: clean
clean:
rm -f $(EXE) $(STATIC_LIB) $(OBJS) $(TEST_EXE) $(TEST_OBJS) $(DEPS)
rm -f $(EXE) $(STATIC_LIB) $(LIB_OBJS) $(EXE_OBJS) $(TEST_EXE) $(TEST_OBJS) $(DEPS)
make -C test/data clean

.PHONY: tags
tags:
.PHONY: tags ctags
tags ctags:
ctags -R src include test

-include $(DEPS)

+ 4
- 0
asan_env View File

@@ -0,0 +1,4 @@
export ASAN_OPTIONS=symbolize=1
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer
export CXXFLAGS="-lasan -fsanitize=address -fno-omit-frame-pointer"
export LDFLAGS="-lasan -g -fno-omit-frame-pointer"

+ 15
- 1
include/nbt.hpp View File

@@ -429,7 +429,7 @@ class NBTTagException : public std::exception {

virtual const char* what() const noexcept
{
std::string expl = why + ": " + std::to_string(static_cast<int>(id));
static std::string expl = why + ": " + std::to_string(static_cast<unsigned int>(id));
return expl.c_str();
}

@@ -437,6 +437,20 @@ class NBTTagException : public std::exception {
std::string why;
};

class NBTException : public std::exception {
public:
explicit NBTException(const char* why) :
why{why}
{ }

virtual const char* what() const noexcept
{
return why;
}

private:
const char* why;
};

class NBTFile {
public:


+ 38
- 3
src/nbt.cpp View File

@@ -224,6 +224,10 @@ LongArrayTag::type LongArrayTag::htof(LongArrayTag::type unswapped) {
TagID NBTFile::readID() {
char rawID;
file.read(&rawID, sizeof(char));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading ID"};
}
std::cout << "Read ID " << static_cast<unsigned int>(rawID) << std::endl;
return static_cast<TagID>(rawID);
}

@@ -234,18 +238,27 @@ std::string NBTFile::readName() {
nameSize = swap16(nameSize);
std::unique_ptr<char[]> name = std::make_unique<char[]>(nameSize);
file.read(name.get(), nameSize);
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading name"};
}
return std::string{name.get(), nameSize};
}

int32_t NBTFile::readSize() {
int32_t size;
file.read(reinterpret_cast<char*>(&size), sizeof(size));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading size"};
}
return swap32(size);
}

int32_t NBTFile::readListSize() {
int32_t size;
file.read(reinterpret_cast<char*>(&size), sizeof(size));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading list size"};
}
return swap32(size);
}

@@ -253,6 +266,9 @@ template <typename T>
T NBTFile::readTag(std::string name) {
typename T::type value;
file.read(reinterpret_cast<char*>(&value), sizeof(value));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading tag value"};
}
return T{name, T::ftoh(std::move(value))};
}

@@ -277,9 +293,15 @@ template <>
StringTag NBTFile::readTag<StringTag>(std::string name) {
int16_t length;
file.read(reinterpret_cast<char*>(&length), sizeof(length));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading string length"};
}
length = swap16(length);
std::string str(static_cast<size_t>(length), static_cast<char>('\0'));
file.read(&str[0], length*sizeof(char));
if (file.fail()) {
throw NBTException{"Unexpectedly reached end of file while reading string value"};
}
return StringTag{name, str};
}

@@ -319,9 +341,21 @@ LongArrayTag NBTFile::readTag<LongArrayTag>(std::string name) {

template <>
LongArrayTag NBTFile::readTag<LongArrayTag>() {
return readTag<LongArrayTag>(readName());;
return readTag<LongArrayTag>(readName());
}

#if 0
template <>
CompoundTag NBTFile::readTag<CompoundTag>(std::string name) {
return readCompoundTag(name);
}

template <>
CompoundTag NBTFile::readTag<CompoundTag>() {
return readTag<CompoundTag>(readName());
}
#endif

/**
* Helper for reading arrays of fixed-size values.
*/
@@ -352,7 +386,7 @@ template <typename T>
ListTag<T> NBTFile::readTagList() {
std::string name = readName();
TagID id = readID();
return std::move(readTagList<T>(id, name));
return readTagList<T>(id, name);
}


@@ -372,6 +406,7 @@ ListTag<CompoundTag> NBTFile::readTagList<CompoundTag>(TagID id, std::string nam
int32_t size = readSize();
ListTag<CompoundTag> list{name, id, size};
for (int i = 0; i < size; i++) {
std::cout << "readTagList<CompoundTag> " << i << std::endl;
list.push_back(readCompoundTag(""));
}
return list;
@@ -487,7 +522,7 @@ CompoundTag NBTFile::readCompoundTag(std::string name) {
ct.push_back(readTagList<LongArrayTag>(listID, listName));
break;
default:
throw NBTTagException(listID, "Unrecognized tag");
throw NBTTagException(listID, "Unrecognized tag in list");
break;
}
}


+ 1
- 1
src/nbt_dump.cpp View File

@@ -25,7 +25,7 @@ int main(int argc, char* argv[]) {
//TagID id = input.readID();

try {
ListTag<CompoundTag> root{input.readTagList<CompoundTag>()};
auto root{input.readCompoundTag("")};
}
catch (NBTTagException& e) {
std::cerr << "NBTTagException: " << e.what() << std::endl;


+ 1
- 1
test/data/compound_tag.hex View File

@@ -24,6 +24,6 @@
06
00 00 00 02
40 35 54 7a e1 47 ae 14
40 2a bd 70 a3 d7 a 3d
40 2a bd 70 a3 d7 0a 3d

00

+ 14
- 0
test/data/decode.py View File

@@ -0,0 +1,14 @@


def dec_string(value):
return ''.join([chr(int(v, 16)) for v in value.split(' ')])

if __name__ == '__main__':
import argparse as ap

parser = ap.ArgumentParser()
parser.add_argument('value',
help='Encoded value (hex)')
args = parser.parse_args()
print(dec_string(args.value))

+ 16
- 2
test/data/list_compound_tag.hex View File

@@ -7,17 +7,31 @@
00 00 00 02

08
00 0c
73 74 72 69 6e 67 20 63 68 69 6c 64
00 08
61 73 64 66 73 64 66 67

0c
00 00 00 10
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
00 10
6c 6f 6e 67 20 61 72 72 61 79 20 63 68 69 6c 64
00 00 00 02
00 01 02 03 04 05 06 07
08 09 0a 0b 0c 0d 0e 0f

00

03
00 09
69 6e 74 20 63 68 69 6c 64
01 02 03 04
02
00 0b
73 68 6f 72 74 20 63 68 69 6c 64
05 06
02
00 0c
73 68 6f 72 74 20 63 68 69 6c 64 32
07 08

00

+ 10
- 4
test/test_nbt.cpp View File

@@ -165,7 +165,7 @@ TEST_CASE("Reading from test files", "[nbtfile]") {
TagID id = file.readID();
REQUIRE(id == TagID::COMPOUND);
CompoundTag tag{file.readCompoundTag("")};
//REQUIRE(tag.size() == 4);
REQUIRE(tag.size() == 4);
{ // StringTag
REQUIRE(tag.at(0)->id() == TagID::STRING);
StringTag child = std::move(*std::dynamic_pointer_cast<StringTag>(tag.at(0)));
@@ -208,9 +208,15 @@ TEST_CASE("Reading from test files", "[nbtfile]") {
ListTag<CompoundTag> tag = file.readTagList<CompoundTag>();
REQUIRE(tag.name() == "listof compound");
REQUIRE(tag.size() == 2);
// TODO
//CompoundTag child0 = tag.at(0);
//REQUIRE(child0.idAt(0) == TagID::STRING);

{
//CompoundTag child0 = tag.at(0);
//REQUIRE(child0.at(0)->id() == TagID::STRING);
//StringTag string = *std::dynamic_pointer_cast<StringTag>(child0.at(0));
//REQUIRE(string.name() == "string child");
//REQUIRE(string.value() == "asdfsdfg");
//REQUIRE(child0.at(1)->id() == TagID::LONG_ARRAY);
}
}
}
// TODO


Loading…
Cancel
Save