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
00036 #include "OW_config.h"
00037 #include "OW_BinarySerialization.hpp"
00038 #include "OW_AutoPtr.hpp"
00039 #include "OW_ByteSwap.hpp"
00040 #include "OW_CIMBase.hpp"
00041 #include "OW_IOException.hpp"
00042 #include "OW_Format.hpp"
00043 #include "OW_ResultHandlerIFC.hpp"
00044 #include <cerrno>
00045
00046 namespace OW_NAMESPACE
00047 {
00048
00049 namespace BinarySerialization
00050 {
00052 template <typename Handler, typename ReaderFunc>
00053 static inline void readEnum(std::istream& istrm, Handler& result,
00054 const ReaderFunc& read, const Int32 beginsig, const Int32 endsig)
00055 {
00056 verifySignature(istrm, beginsig);
00057 bool done = false;
00058 while (!done)
00059 {
00060 try
00061 {
00062 result.handle(read(istrm));
00063 }
00064 catch (const BadCIMSignatureException& e)
00065 {
00066
00067 verifySignature(istrm, endsig);
00068 done = true;
00069 }
00070 }
00071 }
00073
00074 void
00075 readObjectPathEnum(std::istream& istrm, CIMObjectPathResultHandlerIFC& result)
00076 {
00077 readEnum(istrm, result, &readObjectPath, BINSIG_OPENUM, END_OPENUM);
00078 }
00080
00081 void
00082 readClassEnum(std::istream& istrm, CIMClassResultHandlerIFC& result)
00083 {
00084 readEnum(istrm, result, &readClass, BINSIG_CLSENUM, END_CLSENUM);
00085 }
00087
00088 void
00089 readInstanceEnum(std::istream& istrm, CIMInstanceResultHandlerIFC& result)
00090 {
00091 readEnum(istrm, result, &readInstance, BINSIG_INSTENUM, END_INSTENUM);
00092 }
00094
00095 void
00096 readQualifierTypeEnum(std::istream& istrm, CIMQualifierTypeResultHandlerIFC& result)
00097 {
00098 readEnum(istrm, result, &readQualType, BINSIG_QUAL_TYPEENUM, END_QUALENUM);
00099 }
00101
00102 void
00103 readStringEnum(std::istream& istrm, StringResultHandlerIFC& result)
00104 {
00105 readEnum(istrm, result, &readString, BINSIG_STRINGENUM, END_STRINGENUM);
00106 }
00108
00109 void
00110 writeLen(std::ostream& ostrm, UInt32 len)
00111 {
00112
00113
00114
00115
00116
00117 if ( len <= 127 )
00118 {
00119 UInt8 length_byte = static_cast<UInt8>(len);
00120 write(ostrm, &length_byte, 1);
00121 return;
00122 }
00123
00124
00125
00126
00127
00128 UInt8 lenlen;
00129 if (len <= 255)
00130 {
00131 lenlen = 1;
00132 }
00133 else if (len <= 65536)
00134 {
00135 lenlen = 2;
00136 }
00137 else if (len <= 16777216)
00138 {
00139 lenlen = 3;
00140 }
00141 else
00142 {
00143 lenlen = 4;
00144 }
00145 UInt8 netlenlen = lenlen | 0x80UL;
00146
00147 write(ostrm, &netlenlen, 1);
00148 UInt8 netlen[sizeof(len)];
00149 for (int j = 0; j < lenlen; j++)
00150 {
00151 netlen[(sizeof(len)-1) - j] = static_cast<UInt8>(len & 0xffU);
00152 len >>= 8;
00153 }
00154
00155 write(ostrm, static_cast<void *>(&netlen[sizeof(len)-lenlen]), lenlen);
00156 }
00158
00159 void
00160 readLen(std::istream& istrm, UInt32& len)
00161 {
00162
00163 UInt8 lc;
00164 read(istrm, lc);
00165 if (lc & 0x80U)
00166 {
00167 UInt8 noctets = lc & 0x7fU;
00168 if ( noctets > sizeof(len) ) {
00169 OW_THROW(IOException, Format("Failed reading data: length length (%1) is too large (> %2)", noctets, sizeof(len)).c_str());
00170 }
00171 UInt8 netlen[sizeof(len)];
00172 read(istrm, static_cast<void *>(netlen), noctets);
00173 len = 0;
00174 for (int i = 0; i < noctets; i++ ) {
00175 len <<= 8;
00176 len |= netlen[i];
00177 }
00178 } else {
00179 len = lc;
00180 }
00181 }
00183
00184 void
00185 write(std::ostream& ostrm, const void* dataOut,
00186 int dataOutLen)
00187 {
00188 if (!ostrm.write(reinterpret_cast<const char*>(dataOut), dataOutLen))
00189 {
00190 OW_THROW_ERRNO_MSG(IOException, "Failed writing data");
00191 }
00192 }
00194
00195 void
00196 verifySignature(std::istream& istrm, UInt8 validSig)
00197 {
00198 UInt8 val;
00199 read(istrm, val);
00200 if (val != validSig)
00201 {
00202 OW_THROW(BadCIMSignatureException,
00203 Format("Received invalid signature. Got: %1 Expected: %2", Int32(val),
00204 Int32(validSig)).c_str());
00205 }
00206 }
00208
00209 void
00210 writeStringArray(std::ostream& ostrm,
00211 const StringArray* propertyList)
00212 {
00213 bool nullPropertyList = (propertyList == 0);
00214 writeBool(ostrm, nullPropertyList);
00215 if (!nullPropertyList)
00216 {
00217 writeStringArray(ostrm, *propertyList);
00218 }
00219 }
00221
00222 void
00223 read(std::istream& istrm, void* dataIn, int dataInLen)
00224 {
00225 if (!istrm.read(reinterpret_cast<char*>(dataIn), dataInLen))
00226 {
00227 OW_THROW_ERRNO_MSG(IOException, "Failed reading data");
00228 }
00229 }
00230 }
00231
00232 }
00233