git-svn-id: svn://db.shs.com.ru/pip@860 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-10-28 09:10:18 +00:00
parent 604095672f
commit bbb7cbaf35
9 changed files with 191 additions and 39 deletions

View File

@@ -29,12 +29,22 @@
class PIP_EXPORT PIChunkStream
{
public:
//! Version of data packing. Read-access %PIChunkStream automatic detect version, but write-access
//! %PIChunkStream by default write in new version, be careful!
enum Version {
Version_1 /*! First, old version */,
Version_2 /*! Second, more optimized version */ = 2,
};
//! Contructs stream for read from "data"
PIChunkStream(const PIByteArray & data) {setSource(data);}
PIChunkStream(const PIByteArray & data): version_(Version_2) {setSource(data);}
//! Contructs stream for read or write to/from "data", or empty stream for write
PIChunkStream(PIByteArray * data = 0) {setSource(data);}
PIChunkStream(PIByteArray * data = 0, Version v = Version_2): version_(v) {setSource(data);}
//! Contructs empty stream for write with version \"v\"
PIChunkStream(Version v): version_(v) {setSource(0);}
~PIChunkStream();
@@ -58,11 +68,17 @@ public:
PIByteArray data() const {return tmp_data;}
//! Returns if there is end of stream
bool atEnd() const {return data_->isEmpty();}
bool atEnd() const {return data_->size_s() <= 1;}
//! Returns stream version
Version version() const {return (Version)version_;}
//! Read one chunk from stream and returns its ID
int read() {(*data_) >> last_id >> last_data; return last_id;}
int read();
//! Read all chunks from stream
void readAll();
//! Returns last readed chunk ID
int getID() {return last_id;}
@@ -71,15 +87,29 @@ public:
template <typename T>
T getData() const {T ret; PIByteArray s(last_data); s >> ret; return ret;}
//! Place value of last readed chunk into "v"
//! Place value of last readed chunk into \"v\"
template <typename T>
void get(T & v) const {v = getData<T>();}
//! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function!
template <typename T>
const PIChunkStream & get(int id, T & v) const {
PIByteArray ba = data_map.value(id);
if (!ba.isEmpty())
ba >> v;
return *this;
}
private:
void _init();
static uint readVInt(PIByteArray & s);
static void writeVInt(PIByteArray & s, uint val);
int last_id;
uchar version_;
PIByteArray * data_, last_data, tmp_data;
PIMap<int, PIByteArray> data_map;
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
};
@@ -88,7 +118,19 @@ template <typename T>
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c) {
PIByteArray ba;
ba << c.data;
(*(s.data_)) << c.id << ba;
switch (s.version_) {
case PIChunkStream::Version_1:
(*(s.data_)) << c.id << ba;
break;
case PIChunkStream::Version_2:
if (s.data_->isEmpty())
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
PIChunkStream::writeVInt(*(s.data_), c.id);
PIChunkStream::writeVInt(*(s.data_), ba.size());
s.data_->append(ba);
break;
default: break;
}
return s;
}