From 981e4c61b5b80d4b2e01cdb3ec6012717d6c8ac5 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 8 Jul 2013 13:45:38 +0200 Subject: [PATCH] Tags files missing in last commit --- libraries/voxels/src/Tags.cpp | 218 ++++++++++++++++++++++++++++++++++ libraries/voxels/src/Tags.h | 152 ++++++++++++++++++++++++ 2 files changed, 370 insertions(+) create mode 100644 libraries/voxels/src/Tags.cpp create mode 100644 libraries/voxels/src/Tags.h diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp new file mode 100644 index 0000000000..81cf4dbe95 --- /dev/null +++ b/libraries/voxels/src/Tags.cpp @@ -0,0 +1,218 @@ +#include "Tags.h" +#include + +#include +#include + +#include + +Tag::Tag(int tagId, std::stringstream &ss) : _tagId(tagId) { + int size(ss.get() << 8 | ss.get()); + + _name.clear(); + for (int i(0); i < size; ++i) { + _name += ss.get(); + } +} + +Tag* Tag::readTag(int tagId, std::stringstream &ss) { + + switch (tagId) { + case TAG_Byte: + return new TagByte(ss); + case TAG_Short: + return new TagShort(ss); + case TAG_Int: + return new TagInt(ss); + case TAG_Long: + return new TagLong(ss); + case TAG_Byte_Array: + return new TagByteArray(ss); + case TAG_String: + return new TagString(ss); + case TAG_List: + return new TagList(ss); + case TAG_Compound: + return new TagCompound(ss); + case TAG_Int_Array: + return new TagIntArray(ss); + case TAG_Float: + case TAG_Double: + default: + //TODO + exit(EXIT_FAILURE); + break; + } +} + +TagByte::TagByte(std::stringstream &ss) : Tag(TAG_Byte, ss) { + _data = ss.get(); +} + +TagShort::TagShort(std::stringstream &ss) : Tag(TAG_Short, ss) { + _data = ss.get() << 8 | ss.get(); +} + +TagInt::TagInt(std::stringstream &ss) : Tag(TAG_Int, ss) { + _data = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); +} + +TagLong::TagLong(std::stringstream &ss) : Tag(TAG_Long, ss) { + _data = (((int64_t) ss.get()) << 56 | ((int64_t) ss.get()) << 48 + | ((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 + | ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get()); +} + +TagByteArray::TagByteArray(std::stringstream &ss) : Tag(TAG_Byte_Array, ss) { + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new char[_size]; + for (int i(0); i < _size; ++i) { + _data[i] = ss.get(); + } +} + +TagString::TagString(std::stringstream &ss) : Tag(TAG_String, ss) { + _size = ss.get() << 8 | ss.get(); + + for (int i(0); i < _size; ++i) { + _data += ss.get(); + } +} + +TagList::TagList(std::stringstream &ss) : Tag(TAG_List, ss) { + _tagId = ss.get(); + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + for (int i(0); i < _size; ++i) { + ss.putback(0); + ss.putback(0); + _data.push_back(readTag(_tagId, ss)); + } +} + +TagCompound::TagCompound(std::stringstream &ss) : Tag(TAG_Compound, ss), + _size(0), + _width(0), + _length(0), + _height(0), + _blocksId(NULL), + _blocksData(NULL) { + int tagId; + + while (TAG_End != (tagId = ss.get())) { + _data.push_back(readTag(tagId, ss)); + ++_size; + + if (TAG_Short == tagId) { + if ("Width" == _data.back()->name()) { + _width = ((TagShort*) _data.back())->data(); + } else if ("Height" == _data.back()->name()) { + _height = ((TagShort*) _data.back())->data(); + } else if ("Length" == _data.back()->name()) { + _length = ((TagShort*) _data.back())->data(); + } + } else if (TAG_Byte_Array == tagId) { + if ("Blocks" == _data.back()->name()) { + _blocksId = ((TagByteArray*) _data.back())->data(); + } else if ("Data" == _data.back()->name()) { + _blocksData = ((TagByteArray*) _data.back())->data(); + } + } + } +} + +TagIntArray::TagIntArray(std::stringstream &ss) : Tag(TAG_Int_Array, ss) { + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new int[_size]; + for (int i(0); i < _size; ++i) { + _data[i] = ss.get(); + } +} + +int retrieveData(std::string filename, std::stringstream &ss) { + std::ifstream file(filename.c_str(), std::ios::binary); + + int type = file.peek(); + if (0x0A == type) { + ss.flush(); + ss << file; + return 0; + } + if (0x1F == type) { + return ungzip(file, ss); + } + + return 1; +} + +int ungzip(std::ifstream &file, std::stringstream &ss) { + std::string gzipedBytes; + gzipedBytes.clear(); + ss.flush(); + + while (!file.eof()) { + gzipedBytes += (char) file.get(); + } + file.close(); + + if ( gzipedBytes.size() == 0 ) { + ss << gzipedBytes; + return 0; + } + + unsigned int full_length = gzipedBytes.size(); + unsigned int half_length = gzipedBytes.size()/2; + unsigned int uncompLength = full_length; + + char* uncomp = (char*) calloc(sizeof(char), uncompLength); + + z_stream strm; + strm.next_in = (Bytef *) gzipedBytes.c_str(); + strm.avail_in = gzipedBytes.size(); + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + + bool done = false; + + if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) { + free(uncomp); + return 1; + } + + while (!done) { + // If our output buffer is too small + if (strm.total_out >= uncompLength) { + // Increase size of output buffer + char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); + memcpy( uncomp2, uncomp, uncompLength ); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + strm.next_out = (Bytef *) (uncomp + strm.total_out); + strm.avail_out = uncompLength - strm.total_out; + + // Inflate another chunk. + int err = inflate (&strm, Z_SYNC_FLUSH); + if (err == Z_STREAM_END) done = true; + else if (err != Z_OK) break; + } + + if (inflateEnd (&strm) != Z_OK) { + free(uncomp); + return 1; + } + + for (size_t i=0; i +#include + +#include +#include +#include + +#define TAG_End 0 +#define TAG_Byte 1 +#define TAG_Short 2 +#define TAG_Int 3 +#define TAG_Long 4 +#define TAG_Float 5 +#define TAG_Double 6 +#define TAG_Byte_Array 7 +#define TAG_String 8 +#define TAG_List 9 +#define TAG_Compound 10 +#define TAG_Int_Array 11 + +int retrieveData(std::string filename, std::stringstream &ss); +int ungzip(std::ifstream &file, std::stringstream &ss); + +class Tag { + protected: + int _tagId; + std::string _name; + + public: + Tag(int tagId, std::stringstream &ss); + + int tagId() const {return _tagId;} + std::string name () const {return _name; } + + static Tag* readTag(int tagId, std::stringstream &ss); +}; + +class TagByte : public Tag { + private: + int8_t _data; + + public: + TagByte(std::stringstream &ss); + + int8_t data() const {return _data;} +}; + +class TagShort : public Tag { + private: + int16_t _data; + + public: + TagShort(std::stringstream &ss); + + int16_t data() const {return _data;} +}; + +class TagInt : public Tag { + private: + int32_t _data; + + public: + TagInt(std::stringstream &ss); + + int32_t data() const {return _data;} +}; + +class TagLong : public Tag { + private: + int64_t _data; + + public: + TagLong(std::stringstream &ss); + + int64_t data() const {return _data;} +}; + +class TagByteArray : public Tag { + private: + int _size; + char* _data; + + public: + TagByteArray(std::stringstream &ss); + + int size() const {return _size;} + char* data() const {return _data;} +}; + +class TagString : public Tag { + private: + int _size; + std::string _data; + + public: + TagString(std::stringstream &ss); + + int size() const {return _size;} + std::string data() const {return _data;} +}; + +class TagList : public Tag { + private: + int _tagId; + int _size; + std::list _data; + + public: + TagList(std::stringstream &ss); + + int tagId() const {return _tagId;} + int size () const {return _size; } + std::list data () const {return _data; } +}; + +class TagCompound : public Tag { + private: + int _size; + std::list _data; + + // Specific to schematics file + int _width; + int _length; + int _height; + char* _blocksData; + char* _blocksId; + + public: + TagCompound(std::stringstream &ss); + + int size () const {return _size; } + std::list data () const {return _data; } + + int width () const {return _width; } + int length () const {return _length; } + int height () const {return _height; } + char* blockId () const {return _blocksId; } + char* blocksData() const {return _blocksData;} +}; + +class TagIntArray : public Tag { + private: + int _size; + int* _data; + + public: + TagIntArray(std::stringstream &ss); + ~TagIntArray() {delete _data;} + + int size() const {return _size;} + int* data() const {return _data;} +};