00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/BinarySerialization.hpp"
00041 #include "blocxx/AutoPtr.hpp"
00042 #include "blocxx/ByteSwap.hpp"
00043 #include "blocxx/IOException.hpp"
00044 #include "blocxx/Format.hpp"
00045 #include <cerrno>
00046
00047 namespace BLOCXX_NAMESPACE
00048 {
00049
00050 namespace BinarySerialization
00051 {
00053
00054 void
00055 writeLen(std::streambuf & ostrm, UInt32 len)
00056 {
00057
00058
00059
00060
00061
00062 if (len < 128)
00063 {
00064 UInt8 length_byte = static_cast<UInt8>(len);
00065 write(ostrm, &length_byte, 1);
00066 return;
00067 }
00068
00069
00070
00071
00072
00073 UInt8 lenlen;
00074 if (len < (1 << 8))
00075 {
00076 lenlen = 1;
00077 }
00078 else if (len < (1 << 16))
00079 {
00080 lenlen = 2;
00081 }
00082 else if (len < (1 << 24))
00083 {
00084 lenlen = 3;
00085 }
00086 else
00087 {
00088 lenlen = 4;
00089 }
00090 UInt8 netlenlen = lenlen | 0x80UL;
00091
00092 write(ostrm, &netlenlen, 1);
00093 UInt8 netlen[sizeof(len)];
00094 for (int j = 0; j < lenlen; j++)
00095 {
00096 netlen[(sizeof(len)-1) - j] = static_cast<UInt8>(len & 0xffU);
00097 len >>= 8;
00098 }
00099
00100 write(ostrm, static_cast<void *>(&netlen[sizeof(len)-lenlen]), lenlen);
00101 }
00103
00104 void
00105 readLen(std::streambuf & istrm, UInt32 & len)
00106 {
00107
00108 UInt8 lc;
00109 read(istrm, lc);
00110 if (lc & 0x80U)
00111 {
00112 UInt8 noctets = lc & 0x7fU;
00113 if ( noctets > sizeof(len) )
00114 {
00115 BLOCXX_THROW(IOException, Format("Failed reading data: length length (%1) is too large (> %2)", static_cast<int>(noctets), sizeof(len)).c_str());
00116 }
00117 UInt8 netlen[sizeof(len)];
00118 read(istrm, static_cast<void *>(netlen), noctets);
00119 len = 0;
00120 for (int i = 0; i < noctets; i++ )
00121 {
00122 len <<= 8;
00123 len |= netlen[i];
00124 }
00125 }
00126 else
00127 {
00128 len = lc;
00129 }
00130 }
00132
00133 void
00134 write(std::streambuf & ostrm, void const * dataOut, size_t dataOutLen)
00135 {
00136 std::streamsize cnt = dataOutLen;
00137 if (ostrm.sputn(static_cast<char const *>(dataOut), cnt) != cnt)
00138 {
00139 BLOCXX_THROW_ERRNO_MSG(IOException, "Failed writing data");
00140 }
00141 }
00143
00144 void
00145 verifySignature(std::streambuf & istrm, UInt8 validSig)
00146 {
00147 UInt8 val;
00148 read(istrm, val);
00149 if (val != validSig)
00150 {
00151 BLOCXX_THROW(BadSignatureException,
00152 Format("Received invalid signature. Got: %1 Expected: %2", Int32(val),
00153 Int32(validSig)).c_str());
00154 }
00155 }
00157
00158 void
00159 writeStringArray(std::streambuf & ostrm, const StringArray * propertyList)
00160 {
00161 bool nullPropertyList = (propertyList == 0);
00162 writeBool(ostrm, nullPropertyList);
00163 if (!nullPropertyList)
00164 {
00165 writeStringArray(ostrm, *propertyList);
00166 }
00167 }
00169
00170 void
00171 read(std::streambuf & istrm, void * dataIn, size_t dataInLen)
00172 {
00173 std::streamsize cnt = dataInLen;
00174 if (istrm.sgetn(static_cast<char *>(dataIn), cnt) != cnt)
00175 {
00176 BLOCXX_THROW(IOException, "Failed reading data");
00177 }
00178 }
00179
00180 }
00181
00182 }
00183