X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Frawdata.cpp;fp=source%2Frawdata.cpp;h=7a90c9df3870c835a134494975a3b1e5343073d5;hp=0000000000000000000000000000000000000000;hb=c80b23de8b70776e37f37e4b8fc2003c553448d6;hpb=aa671cf18f5a0b2847bef673c0a6e2a17c7b1baf diff --git a/source/rawdata.cpp b/source/rawdata.cpp new file mode 100644 index 0000000..7a90c9d --- /dev/null +++ b/source/rawdata.cpp @@ -0,0 +1,92 @@ +#include +#include +#include "collection.h" +#include "except.h" +#include "rawdata.h" + +using namespace std; + +namespace Msp { +namespace DataFile { + +RawData::~RawData() +{ + delete owned_data; + delete compressed; + if(in_owned) + delete in; +} + +void RawData::open_file(Collection &coll, const string &fn) +{ + if(in) + throw logic_error("input already exists"); + + RefPtr opened = coll.open_raw(fn); + if(!opened) + throw IO::file_not_found(fn); + + open_io(*opened, fn); + opened.release(); + in_owned = true; +} + +void RawData::open_io(IO::Base &i, const string &fn) +{ + if(in) + throw logic_error("input already exists"); + + char header[14]; + unsigned len = i.read(header, sizeof(header)); + if(len!=sizeof(header)) + throw data_error(fn, 0, "Missing header"); + if(header[0]!='M' || header[1]!='D' || header[2]!='R' || header[3]!=1) + throw data_error(fn, 0, "Bad header"); + + size = 0; + for(unsigned j=0; j<8; ++j) + size = (size<<8) | static_cast(header[4+j]); + + uint16_t flags = (static_cast(header[12])<<8) | static_cast(header[13]); + + src_name = fn; + in = &i; + if(flags&COMPRESSED) + compressed = new IO::ZlibCompressed(*in, IO::M_READ); +} + +void RawData::load() +{ + if(!in) + throw logic_error("no input"); + if(data) + throw logic_error("already loaded"); + + owned_data = new char[size]; + load_into(owned_data); +} + +void RawData::load_into(void *buffer) +{ + if(!in) + throw logic_error("no input"); + + data = static_cast(buffer); + + IO::Base *src = (compressed ? compressed : in); + size_t pos = 0; + while(posread(data+pos, size-pos); + if(!len) + throw data_error(src_name, 0, "Truncated data"); + pos += len; + } + + if(in_owned) + delete in; + in = nullptr; +} + +} // namespace DataFile +} // namespace Msp