OW_BinarySerialization.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
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          // read threw because we've read all the objects
00067          verifySignature(istrm, endsig);
00068          done = true;
00069       }
00070    }
00071 }
00073 // STATIC
00074 void
00075 readObjectPathEnum(std::istream& istrm, CIMObjectPathResultHandlerIFC& result)
00076 {
00077    readEnum(istrm, result, &readObjectPath, BINSIG_OPENUM, END_OPENUM);
00078 }
00080 // STATIC
00081 void
00082 readClassEnum(std::istream& istrm, CIMClassResultHandlerIFC& result)
00083 {
00084    readEnum(istrm, result, &readClass, BINSIG_CLSENUM, END_CLSENUM);
00085 }
00087 // STATIC
00088 void
00089 readInstanceEnum(std::istream& istrm, CIMInstanceResultHandlerIFC& result)
00090 {
00091    readEnum(istrm, result, &readInstance, BINSIG_INSTENUM, END_INSTENUM);
00092 }
00094 // STATIC
00095 void
00096 readQualifierTypeEnum(std::istream& istrm, CIMQualifierTypeResultHandlerIFC& result)
00097 {
00098    readEnum(istrm, result, &readQualType, BINSIG_QUAL_TYPEENUM, END_QUALENUM);
00099 }
00101 // STATIC
00102 void
00103 readStringEnum(std::istream& istrm, StringResultHandlerIFC& result)
00104 {
00105    readEnum(istrm, result, &readString, BINSIG_STRINGENUM, END_STRINGENUM);
00106 }
00108 // STATIC
00109 void
00110 writeLen(std::ostream& ostrm, UInt32 len)
00111 {
00112    // This is ASN.1 length encoding
00113    /*
00114     * short len if it's less than 128 - one byte giving the len,
00115     * with bit 8 0.
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     * long len otherwise - one byte with bit 8 set, giving the
00125     * length of the length, followed by the length itself.
00126     */
00127    /* find the first non-all-zero byte */
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    /* write the length of the length */
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    /* write the length itself */
00155    write(ostrm, static_cast<void *>(&netlen[sizeof(len)-lenlen]), lenlen);
00156 }
00158 // STATIC
00159 void
00160 readLen(std::istream& istrm, UInt32& len)
00161 {
00162    // This is ASN.1 length encoding
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 // STATIC
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 // STATIC
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 // STATIC
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 // STATIC
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 } // end namespace OW_NAMESPACE
00233 

Generated on Thu Feb 9 08:47:52 2006 for openwbem by  doxygen 1.4.6