diff options
Diffstat (limited to 'lib/common/Archive.h')
-rw-r--r-- | lib/common/Archive.h | 92 |
1 files changed, 66 insertions, 26 deletions
diff --git a/lib/common/Archive.h b/lib/common/Archive.h index 6d5ce88b..2b27b303 100644 --- a/lib/common/Archive.h +++ b/lib/common/Archive.h @@ -26,7 +26,7 @@ class Archive { public: Archive(IOStream &Stream, int Timeout) - : mrStream(Stream) + : mrStream(Stream) { mTimeout = Timeout; } @@ -38,6 +38,7 @@ public: ~Archive() { } + // // // @@ -46,21 +47,29 @@ public: Write((int) Item); } void WriteExact(uint32_t Item) { Write((int)Item); } + // TODO FIXME: use of "int" here is dangerous and deprecated. It can lead to + // incompatible serialisation on non-32-bit machines. Passing anything other + // than one of the specifically supported fixed size types should be forbidden. void Write(int Item) { int32_t privItem = htonl(Item); - mrStream.Write(&privItem, sizeof(privItem)); + mrStream.Write(&privItem, sizeof(privItem), mTimeout); } void Write(int64_t Item) { int64_t privItem = box_hton64(Item); - mrStream.Write(&privItem, sizeof(privItem)); + mrStream.Write(&privItem, sizeof(privItem), mTimeout); + } + void WriteInt16(uint16_t Item) + { + uint16_t privItem = htons(Item); + mrStream.Write(&privItem, sizeof(privItem), mTimeout); } void WriteExact(uint64_t Item) { Write(Item); } void Write(uint64_t Item) { uint64_t privItem = box_hton64(Item); - mrStream.Write(&privItem, sizeof(privItem)); + mrStream.Write(&privItem, sizeof(privItem), mTimeout); } void Write(uint8_t Item) { @@ -71,7 +80,7 @@ public: { int size = Item.size(); Write(size); - mrStream.Write(Item.c_str(), size); + mrStream.Write(Item.c_str(), size, mTimeout); } // // @@ -100,17 +109,29 @@ public: void Read(int &rItemOut) { int32_t privItem; - if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */)) + if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), + 0 /* not interested in bytes read if this fails */, + mTimeout)) { - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) + THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead); } rItemOut = ntohl(privItem); } + void ReadFullBuffer(void* Buffer, size_t Size) + { + if(!mrStream.ReadFullBuffer(Buffer, Size, + 0 /* not interested in bytes read if this fails */, + mTimeout)) + { + THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead); + } + } void ReadIfPresent(int &rItemOut, int ValueIfNotPresent) { int32_t privItem; int bytesRead; - if(mrStream.ReadFullBuffer(&privItem, sizeof(privItem), &bytesRead)) + if(mrStream.ReadFullBuffer(&privItem, sizeof(privItem), + &bytesRead, mTimeout)) { rItemOut = ntohl(privItem); } @@ -122,48 +143,70 @@ public: else { // bad number of remaining bytes - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) + THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead); } } void Read(int64_t &rItemOut) { int64_t privItem; - if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */)) - { - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) - } + ReadFullBuffer(&privItem, sizeof(privItem)); rItemOut = box_ntoh64(privItem); } void ReadExact(uint64_t &rItemOut) { Read(rItemOut); } void Read(uint64_t &rItemOut) { uint64_t privItem; - if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */)) - { - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) - } + ReadFullBuffer(&privItem, sizeof(privItem)); rItemOut = box_ntoh64(privItem); } + void ReadInt16(uint16_t &rItemOut) + { + uint16_t privItem; + ReadFullBuffer(&privItem, sizeof(privItem)); + rItemOut = ntohs(privItem); + } void Read(uint8_t &rItemOut) { int privItem; Read(privItem); rItemOut = privItem; } + void ReadIfPresent(std::string &rItemOut, const std::string& ValueIfNotPresent) + { + ReadString(rItemOut, &ValueIfNotPresent); + } void Read(std::string &rItemOut) { + ReadString(rItemOut, NULL); + } +private: + void ReadString(std::string &rItemOut, const std::string* pValueIfNotPresent) + { int size; - Read(size); + int bytesRead; + if(!mrStream.ReadFullBuffer(&size, sizeof(size), &bytesRead, mTimeout)) + { + if(bytesRead == 0 && pValueIfNotPresent != NULL) + { + // item is simply not present + rItemOut = *pValueIfNotPresent; + return; + } + else + { + // bad number of remaining bytes + THROW_EXCEPTION(CommonException, + ArchiveBlockIncompleteRead) + } + } + size = ntohl(size); // Assume most strings are relatively small char buf[256]; if(size < (int) sizeof(buf)) { // Fetch rest of pPayload, relying on the Protocol to error on stupidly large sizes for us - if(!mrStream.ReadFullBuffer(buf, size, 0 /* not interested in bytes read if this fails */, mTimeout)) - { - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) - } + ReadFullBuffer(buf, size); // assign to this string, storing the header and the extra payload rItemOut.assign(buf, size); } @@ -174,10 +217,7 @@ public: char *ppayload = dataB; // Fetch rest of pPayload, relying on the Protocol to error on stupidly large sizes for us - if(!mrStream.ReadFullBuffer(ppayload, size, 0 /* not interested in bytes read if this fails */, mTimeout)) - { - THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead) - } + ReadFullBuffer(ppayload, size); // assign to this string, storing the header and the extra pPayload rItemOut.assign(ppayload, size); } |