MarshalSerialize.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #include "debug/DebugUtils.h"
00039 #include "debug/Log.h"
00040 #include "util/StringUtils.h"
00041 #include "util/CRC32.h"
00042 
00043 #include "MarshalSerialize.h"
00044 
00045 namespace oasys {
00046 
00047 /******************************************************************************
00048  *
00049  * Marshal
00050  *
00051  *****************************************************************************/
00052 Marshal::Marshal(context_t context, u_char* buf, size_t length, int options)
00053     : BufferedSerializeAction(MARSHAL, context, buf, length, options)
00054 {
00055 }
00056 
00057 Marshal::Marshal(context_t context, ExpandableBuffer* buf, int options)
00058     : BufferedSerializeAction(MARSHAL, context, buf, options)
00059 {
00060 }
00061 
00062 void
00063 Marshal::end_action()
00064 {
00065     if (options_ & USE_CRC)
00066     {
00067         CRC32 crc;
00068 
00069         if (buf() != 0) 
00070         {
00071             crc.update(buf(), offset());
00072             CRC32::CRC_t crc_val = crc.value();
00073             process("crc", &crc_val);
00074 
00075             if (log_) {
00076                 logf(log_, LOG_DEBUG, "crc32 is 0x%x", crc_val);
00077             }
00078         }
00079     }
00080 }
00081 
00082 void
00083 Marshal::process(const char* name, u_int32_t* i)
00084 {
00085     u_char* buf = next_slice(4);
00086     if (buf == NULL) return;
00087 
00088     buf[0] = ((*i)>>24) & 0xff;
00089     buf[1] = ((*i)>>16) & 0xff;
00090     buf[2] = ((*i)>>8)  & 0xff;
00091     buf[3] = (*i)       & 0xff;
00092 
00093     if (log_) logf(log_, LOG_DEBUG, "int32  %s=>(%d)", name, *i);
00094 }
00095 
00096 void 
00097 Marshal::process(const char* name, u_int16_t* i)
00098 {
00099     u_char* buf = next_slice(2);
00100     if (buf == NULL) return;
00101 
00102     buf[0] = ((*i)>>8) & 0xff;
00103     buf[1] = (*i)      & 0xff;
00104     
00105     if (log_) logf(log_, LOG_DEBUG, "int16  %s=>(%d)", name, *i);
00106 }
00107 
00108 void 
00109 Marshal::process(const char* name, u_int8_t* i)
00110 {
00111     u_char* buf = next_slice(1);
00112     if (buf == NULL) return;
00113     
00114     buf[0] = (*i);
00115     
00116     if (log_) logf(log_, LOG_DEBUG, "int8   %s=>(%d)", name, *i);
00117 }
00118 
00119 void 
00120 Marshal::process(const char* name, bool* b)
00121 {
00122     u_char* buf = next_slice(1);
00123     if (buf == NULL) return;
00124 
00125     buf[0] = (*b) ? 1 : 0;
00126     
00127     if (log_) logf(log_, LOG_DEBUG, "bool   %s=>(%c)", name, *b ? 'T' : 'F');
00128 }
00129 
00130 void 
00131 Marshal::process(const char* name, u_char* bp, size_t len)
00132 {
00133     u_char* buf = next_slice(len);
00134     if (buf == NULL) return;
00135 
00136     memcpy(buf, bp, len);
00137     if (log_) {
00138         std::string s;
00139         hex2str(&s, bp, len < 16 ? len : 16);
00140         logf(log_, LOG_DEBUG, "bufc   %s=>(%zu: '%.*s')",
00141              name, len, (int)s.length(), s.data());
00142     }
00143 }
00144     
00145 void 
00146 Marshal::process(const char* name, u_char** bp,
00147                  size_t* lenp, int flags)
00148 {
00149     int str_len;
00150 
00151     if (flags & Serialize::NULL_TERMINATED) {
00152         str_len = strlen(reinterpret_cast<char*>(*bp)) + 1;
00153     } else {
00154         std::string len_name = name;
00155         len_name += ".len";
00156         process(len_name.c_str(), (u_int32_t*)lenp);
00157         str_len = *lenp;
00158     }
00159 
00160     if (*lenp != 0) {
00161         u_char* buf = next_slice(str_len);
00162         if (buf == NULL) return;
00163     
00164         memcpy(buf, *bp, str_len);
00165     }
00166     
00167     if (log_) {
00168         std::string s;
00169         hex2str(&s, *bp, *lenp < 16 ? *lenp : 16);
00170         logf(log_, LOG_DEBUG, "bufc   %s=>(%u: '%.*s')",
00171              name, str_len, (int)s.length(), s.data());
00172     }
00173 }
00174 
00175 void 
00176 Marshal::process(const char* name, std::string* s)
00177 {
00178     size_t len = s->length();
00179     process(name, (u_int32_t*)&len);
00180 
00181     u_char* buf = next_slice(len);
00182     if (buf == NULL) return;
00183     
00184     memcpy(buf, s->data(), len);
00185     
00186     if (log_) {
00187         if (len < 32)
00188             logf(log_, LOG_DEBUG, "string %s=>(%zu: '%.*s')",
00189                  name, len, (int)len, s->data());
00190         else 
00191             logf(log_, LOG_DEBUG, "string %s=>(%zu: '%.*s'...)",
00192                  name, len, 32, s->data());
00193     }
00194 }
00195 
00196 /******************************************************************************
00197  *
00198  * Unmarshal
00199  *
00200  *****************************************************************************/
00201 Unmarshal::Unmarshal(context_t context, const u_char* buf, size_t length,
00202                      int options)
00203     : BufferedSerializeAction(UNMARSHAL, context, 
00204                               (u_char*)(buf), length, options)
00205 {
00206 }
00207 
00208 void
00209 Unmarshal::begin_action()
00210 {
00211     if (options_ & USE_CRC)
00212     {
00213         CRC32 crc;
00214         CRC32::CRC_t crc_val;
00215         
00216         crc_val = CRC32::from_bytes(buf() + length() -
00217                                     sizeof(CRC32::CRC_t)); 
00218         crc.update(buf(), length() - sizeof(CRC32::CRC_t));
00219         
00220         if (crc.value() != crc_val)
00221         {
00222             if (log_)
00223             {
00224                 logf(log_, LOG_WARN, "crc32 mismatch, 0x%x != 0x%x",
00225                      crc.value(), crc_val);
00226                 signal_error();
00227             }
00228         }
00229         else
00230         {
00231             logf(log_, LOG_INFO, "crc32 is good");
00232         }
00233     }
00234 }
00235 
00236 void
00237 Unmarshal::process(const char* name, u_int32_t* i)
00238 {
00239     u_char* buf = next_slice(4);
00240     if (buf == NULL) return;
00241     
00242     *i = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];        
00243     if (log_) logf(log_, LOG_DEBUG, "int32  %s<=(%d)", name, *i);
00244 }
00245 
00246 void 
00247 Unmarshal::process(const char* name, u_int16_t* i)
00248 {
00249     u_char* buf = next_slice(2);
00250     if (buf == NULL) return;
00251     
00252     *i = (buf[0] << 8) | buf[1];        
00253     if (log_) logf(log_, LOG_DEBUG, "int16  %s<=(%d)", name, *i);
00254 }
00255 
00256 void 
00257 Unmarshal::process(const char* name, u_int8_t* i)
00258 {
00259     u_char* buf = next_slice(1);
00260     if (buf == NULL) return;
00261     
00262     *i = buf[0];        
00263     if (log_) logf(log_, LOG_DEBUG, "int8   %s<=(%d)", name, *i);
00264 }
00265 
00266 void 
00267 Unmarshal::process(const char* name, bool* b)
00268 {
00269     u_char* buf = next_slice(1);
00270     if (buf == NULL) return;
00271     
00272     *b = buf[0];
00273     if (log_) logf(log_, LOG_DEBUG, "bool   %s<=(%c)", name, *b ? 'T' : 'F');
00274 }
00275 
00276 void 
00277 Unmarshal::process(const char* name, u_char* bp, size_t len)
00278 {
00279     u_char* buf = next_slice(len);
00280     if (buf == NULL) return;
00281     
00282     memcpy(bp, buf, len);
00283 
00284     if (log_) {
00285         std::string s;
00286         hex2str(&s, bp, len < 16 ? len : 16);
00287         logf(log_, LOG_DEBUG, "bufc   %s<=(%zu: '%.*s')",
00288              name, len, (int)s.length(), s.data());
00289     }
00290 }
00291 
00292 void 
00293 Unmarshal::process(const char* name, u_char** bp, size_t* lenp, int flags)
00294 {
00295     if (flags & Serialize::NULL_TERMINATED) {
00296         u_char* cbuf = buf() + offset();
00297         int new_len = 0;
00298         
00299         while (cbuf != buf() + length()) {
00300             if(*cbuf == '\0')
00301                 break;
00302             cbuf++;
00303             new_len++;
00304         }
00305         
00306         if (cbuf == buf() + length()) {
00307             // no null character found
00308             signal_error();
00309             return;
00310         }
00311         *lenp = new_len + 1; // length of string + '\0'
00312     } else {
00313         std::string len_name = name;
00314         len_name += ".len";
00315         process(len_name.c_str(), (u_int32_t*)lenp);
00316     }
00317 
00318     if (*lenp != 0) {
00319         u_char* buf = next_slice(*lenp);
00320         if (buf == NULL) return;
00321         
00322         if (flags & Serialize::ALLOC_MEM) {
00323             *bp = (u_char*)malloc(*lenp);
00324             memcpy(*bp, buf, *lenp);
00325         } else {
00326             *bp = buf;
00327         }
00328     } else {
00329         *bp = 0;
00330     }
00331     
00332     if (log_) {
00333         std::string s;
00334         hex2str(&s, *bp, *lenp < 16 ? *lenp : 16);
00335         logf(log_, LOG_DEBUG, "bufc   %s<=(%zu: '%.*s')",
00336              name, *lenp, (int)s.length(), s.data());
00337     }
00338 }
00339 
00340 void 
00341 Unmarshal::process(const char* name, std::string* s)
00342 {
00343     ASSERT(s != 0);
00344 
00345     size_t len;
00346     process(name, (u_int32_t*)&len);
00347 
00348     u_char* buf = next_slice(len);
00349     if (buf == 0) return;
00350     
00351     s->assign((char*)buf, len);
00352     if (log_) {
00353         if (len < 32)
00354             logf(log_, LOG_DEBUG, "string %s<=(%zu: '%.*s')",
00355                  name, len, (int)len, s->data());
00356         else 
00357             logf(log_, LOG_DEBUG, "string %s<=(%zu: '%.*s'...)",
00358                  name, len, 32, s->data());
00359     }
00360 }
00361 
00362 /******************************************************************************
00363  *
00364  * MarshalSize 
00365  *
00366  *****************************************************************************/
00367 
00368 void
00369 MarshalSize::begin_action()
00370 {
00371     if (options_ & USE_CRC) {
00372         size_ += sizeof(CRC32::CRC_t);
00373     }
00374 }
00375 
00376 void
00377 MarshalSize::process(const char* name, u_int32_t* i)
00378 {
00379     (void)name;
00380     size_ += get_size(i);
00381 }
00382 
00383 void
00384 MarshalSize::process(const char* name, u_int16_t* i)
00385 {
00386     (void)name;
00387     size_ += get_size(i);
00388 }
00389 
00390 void
00391 MarshalSize::process(const char* name, u_int8_t* i)
00392 {
00393     (void)name;
00394     size_ += get_size(i);
00395 }
00396 
00397 void
00398 MarshalSize::process(const char* name, bool* b)
00399 {
00400     (void)name;
00401     size_ += get_size(b);
00402 }
00403 
00404 void
00405 MarshalSize::process(const char* name, u_char* bp, size_t len)
00406 {
00407     (void)name;
00408     size_ += get_size(bp, len);
00409 }
00410 
00411 void
00412 MarshalSize::process(const char* name, std::string* s)
00413 {
00414     (void)name;
00415     size_ += get_size(s);
00416 }
00417 
00418 void
00419 MarshalSize::process(const char* name, u_char** bp,
00420                      size_t* lenp, int flags)
00421 {
00422     (void)name;
00423     if(flags & Serialize::NULL_TERMINATED) {
00424         size_ += strlen(reinterpret_cast<char*>(*bp)) + sizeof('\0');
00425     } else {
00426         size_ += *lenp + sizeof(u_int32_t);
00427     }
00428 }
00429 
00430 
00431 /******************************************************************************
00432  *
00433  * MarshalCRC
00434  *
00435  *****************************************************************************/
00436 #define DECL_CRC(_type)                         \
00437 void                                            \
00438 MarshalCRC::process(const char* name, _type* i) \
00439 {                                               \
00440     (void)name;                                 \
00441     crc_.update((u_char*)i, sizeof(_type));     \
00442 }
00443 
00444 DECL_CRC(u_int32_t)
00445 DECL_CRC(u_int16_t)
00446 DECL_CRC(u_int8_t)
00447 DECL_CRC(bool)
00448 
00449 void
00450 MarshalCRC::process(const char* name, u_char* bp, size_t len)
00451 {
00452     (void)name;
00453     crc_.update(bp, len);
00454 }
00455 
00456 void
00457 MarshalCRC::process(const char* name, u_char** bp,
00458                      size_t* lenp, int flags)
00459 {
00460     (void)name;
00461     if(flags & Serialize::NULL_TERMINATED) {
00462         crc_.update(*bp, strlen(reinterpret_cast<char*>(*bp)));
00463     } else {
00464         crc_.update(*bp, *lenp);
00465     }
00466 }
00467 
00468 void
00469 MarshalCRC::process(const char* name, std::string* s)
00470 {
00471     (void)name;
00472     crc_.update((u_char*)s->c_str(), s->size());
00473 }
00474 
00475 
00476 /******************************************************************************
00477  *
00478  * MarshalCopy
00479  *
00480  *****************************************************************************/
00481 size_t
00482 MarshalCopy::copy(ExpandableBuffer* buf,
00483                   const SerializableObject* src,
00484                   SerializableObject* dst)
00485 {
00486     Marshal m(Serialize::CONTEXT_LOCAL, buf);
00487     if (m.action(src) != 0) {
00488         PANIC("error marshalling object");
00489     }
00490     
00491     Unmarshal um(Serialize::CONTEXT_LOCAL,
00492                  (const u_char*)buf->raw_buf(), buf->len());
00493     if (um.action(dst) != 0) {
00494         PANIC("error marshalling object");
00495     }
00496 
00497     return buf->len();
00498 }
00499 
00500 
00501 } // namespace oasys

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1