MarshalSerialize.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 #include "debug/DebugUtils.h"
00018 #include "debug/Log.h"
00019 #include "util/StringUtils.h"
00020 #include "util/CRC32.h"
00021 
00022 #include "MarshalSerialize.h"
00023 
00024 namespace oasys {
00025 
00026 /******************************************************************************
00027  *
00028  * Marshal
00029  *
00030  *****************************************************************************/
00031 Marshal::Marshal(context_t context, u_char* buf, size_t length, int options)
00032     : BufferedSerializeAction(MARSHAL, context, buf, length, options)
00033 {
00034 }
00035 
00036 Marshal::Marshal(context_t context, ExpandableBuffer* buf, int options)
00037     : BufferedSerializeAction(MARSHAL, context, buf, options)
00038 {
00039 }
00040 
00041 void
00042 Marshal::end_action()
00043 {
00044     if (options_ & USE_CRC)
00045     {
00046         CRC32 crc;
00047 
00048         if (buf() != 0) 
00049         {
00050             crc.update(buf(), offset());
00051             CRC32::CRC_t crc_val = crc.value();
00052             process("crc", &crc_val);
00053 
00054             if (log_) {
00055                 logf(log_, LOG_DEBUG, "crc32 is 0x%x", crc_val);
00056             }
00057         }
00058     }
00059 }
00060 
00061 void
00062 Marshal::process(const char* name, u_int64_t* i)
00063 {
00064     u_char* buf = next_slice(8);
00065     if (buf == NULL) return;
00066 
00067     buf[0] = ((*i)>>56) & 0xff;
00068     buf[1] = ((*i)>>48) & 0xff;
00069     buf[2] = ((*i)>>40) & 0xff;
00070     buf[3] = ((*i)>>32) & 0xff;
00071     buf[4] = ((*i)>>24) & 0xff;
00072     buf[5] = ((*i)>>16) & 0xff;
00073     buf[6] = ((*i)>>8)  & 0xff;
00074     buf[7] = (*i)       & 0xff;
00075 
00076     if (log_) logf(log_, LOG_DEBUG, "int64  %s=>(%llu)", name, U64FMT(*i));
00077 }
00078 
00079 void
00080 Marshal::process(const char* name, u_int32_t* i)
00081 {
00082     u_char* buf = next_slice(4);
00083     if (buf == NULL) return;
00084 
00085     buf[0] = ((*i)>>24) & 0xff;
00086     buf[1] = ((*i)>>16) & 0xff;
00087     buf[2] = ((*i)>>8)  & 0xff;
00088     buf[3] = (*i)       & 0xff;
00089 
00090     if (log_) logf(log_, LOG_DEBUG, "int32  %s=>(%d)", name, *i);
00091 }
00092 
00093 void 
00094 Marshal::process(const char* name, u_int16_t* i)
00095 {
00096     u_char* buf = next_slice(2);
00097     if (buf == NULL) return;
00098 
00099     buf[0] = ((*i)>>8) & 0xff;
00100     buf[1] = (*i)      & 0xff;
00101     
00102     if (log_) logf(log_, LOG_DEBUG, "int16  %s=>(%d)", name, *i);
00103 }
00104 
00105 void 
00106 Marshal::process(const char* name, u_int8_t* i)
00107 {
00108     u_char* buf = next_slice(1);
00109     if (buf == NULL) return;
00110     
00111     buf[0] = (*i);
00112     
00113     if (log_) logf(log_, LOG_DEBUG, "int8   %s=>(%d)", name, *i);
00114 }
00115 
00116 void 
00117 Marshal::process(const char* name, bool* b)
00118 {
00119     u_char* buf = next_slice(1);
00120     if (buf == NULL) return;
00121 
00122     buf[0] = (*b) ? 1 : 0;
00123     
00124     if (log_) logf(log_, LOG_DEBUG, "bool   %s=>(%c)", name, *b ? 'T' : 'F');
00125 }
00126 
00127 void 
00128 Marshal::process(const char* name, u_char* bp, u_int32_t len)
00129 {
00130     u_char* buf = next_slice(len);
00131     if (buf == NULL) return;
00132 
00133     memcpy(buf, bp, len);
00134     if (log_) {
00135         std::string s;
00136         hex2str(&s, bp, len < 16 ? len : 16);
00137         logf(log_, LOG_DEBUG, "bufc   %s=>(%u: '%.*s')",
00138              name, len, (int)s.length(), s.data());
00139     }
00140 }
00141     
00142 void 
00143 Marshal::process(const char* name, u_char** bp,
00144                  u_int32_t* lenp, int flags)
00145 {
00146     int str_len;
00147 
00148     if (flags & Serialize::NULL_TERMINATED) {
00149         str_len = strlen(reinterpret_cast<char*>(*bp)) + 1;
00150     } else {
00151         std::string len_name = name;
00152         len_name += ".len";
00153         process(len_name.c_str(), lenp);
00154         str_len = *lenp;
00155     }
00156 
00157     if (*lenp != 0) {
00158         u_char* buf = next_slice(str_len);
00159         if (buf == NULL) return;
00160     
00161         memcpy(buf, *bp, str_len);
00162     }
00163     
00164     if (log_) {
00165         std::string s;
00166         hex2str(&s, *bp, *lenp < 16 ? *lenp : 16);
00167         logf(log_, LOG_DEBUG, "bufc   %s=>(%u: '%.*s')",
00168              name, str_len, (int)s.length(), s.data());
00169     }
00170 }
00171 
00172 void 
00173 Marshal::process(const char* name, std::string* s)
00174 {
00175     u_int32_t len = s->length();
00176     process(name, &len);
00177 
00178     u_char* buf = next_slice(len);
00179     if (buf == NULL) return;
00180     
00181     memcpy(buf, s->data(), len);
00182     
00183     if (log_) {
00184         if (len < 32)
00185             logf(log_, LOG_DEBUG, "string %s=>(%u: '%.*s')",
00186                  name, len, len, s->data());
00187         else 
00188             logf(log_, LOG_DEBUG, "string %s=>(%u: '%.*s'...)",
00189                  name, len, 32, s->data());
00190     }
00191 }
00192 
00193 /******************************************************************************
00194  *
00195  * Unmarshal
00196  *
00197  *****************************************************************************/
00198 Unmarshal::Unmarshal(context_t context, const u_char* buf, size_t length,
00199                      int options)
00200     : BufferedSerializeAction(UNMARSHAL, context, 
00201                               (u_char*)(buf), length, options)
00202 {
00203 }
00204 
00205 void
00206 Unmarshal::begin_action()
00207 {
00208     if (options_ & USE_CRC)
00209     {
00210         CRC32 crc;
00211         CRC32::CRC_t crc_val;
00212         
00213         crc_val = CRC32::from_bytes(buf() + length() -
00214                                     sizeof(CRC32::CRC_t)); 
00215         crc.update(buf(), length() - sizeof(CRC32::CRC_t));
00216         
00217         if (crc.value() != crc_val)
00218         {
00219             if (log_)
00220             {
00221                 logf(log_, LOG_WARN, "crc32 mismatch, 0x%x != 0x%x",
00222                      crc.value(), crc_val);
00223                 signal_error();
00224             }
00225         }
00226         else
00227         {
00228             logf(log_, LOG_INFO, "crc32 is good");
00229         }
00230     }
00231 }
00232 
00233 void
00234 Unmarshal::process(const char* name, u_int64_t* i)
00235 {
00236     u_char* buf = next_slice(8);
00237     if (buf == NULL) return;
00238 
00239     u_int64_t high = *i = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
00240     u_int64_t low  = *i = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
00241     
00242     *i = (high << 32) | low;
00243     if (log_) logf(log_, LOG_DEBUG, "int32  %s<=(%llu)", name, U64FMT(*i));
00244 }
00245 
00246 void
00247 Unmarshal::process(const char* name, u_int32_t* i)
00248 {
00249     u_char* buf = next_slice(4);
00250     if (buf == NULL) return;
00251     
00252     *i = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];        
00253     if (log_) logf(log_, LOG_DEBUG, "int32  %s<=(%d)", name, *i);
00254 }
00255 
00256 void 
00257 Unmarshal::process(const char* name, u_int16_t* i)
00258 {
00259     u_char* buf = next_slice(2);
00260     if (buf == NULL) return;
00261     
00262     *i = (buf[0] << 8) | buf[1];        
00263     if (log_) logf(log_, LOG_DEBUG, "int16  %s<=(%d)", name, *i);
00264 }
00265 
00266 void 
00267 Unmarshal::process(const char* name, u_int8_t* i)
00268 {
00269     u_char* buf = next_slice(1);
00270     if (buf == NULL) return;
00271     
00272     *i = buf[0];        
00273     if (log_) logf(log_, LOG_DEBUG, "int8   %s<=(%d)", name, *i);
00274 }
00275 
00276 void 
00277 Unmarshal::process(const char* name, bool* b)
00278 {
00279     u_char* buf = next_slice(1);
00280     if (buf == NULL) return;
00281     
00282     *b = buf[0];
00283     if (log_) logf(log_, LOG_DEBUG, "bool   %s<=(%c)", name, *b ? 'T' : 'F');
00284 }
00285 
00286 void 
00287 Unmarshal::process(const char* name, u_char* bp, u_int32_t len)
00288 {
00289     u_char* buf = next_slice(len);
00290     if (buf == NULL) return;
00291     
00292     memcpy(bp, buf, len);
00293 
00294     if (log_) {
00295         std::string s;
00296         hex2str(&s, bp, len < 16 ? len : 16);
00297         logf(log_, LOG_DEBUG, "bufc   %s<=(%u: '%.*s')",
00298              name, len, (int)s.length(), s.data());
00299     }
00300 }
00301 
00302 void 
00303 Unmarshal::process(const char* name, u_char** bp, u_int32_t* lenp, int flags)
00304 {
00305     if (flags & Serialize::NULL_TERMINATED) {
00306         u_char* cbuf = buf() + offset();
00307         int new_len = 0;
00308         
00309         while (cbuf != buf() + length()) {
00310             if(*cbuf == '\0')
00311                 break;
00312             cbuf++;
00313             new_len++;
00314         }
00315         
00316         if (cbuf == buf() + length()) {
00317             // no null character found
00318             signal_error();
00319             return;
00320         }
00321         *lenp = new_len + 1; // length of string + '\0'
00322     } else {
00323         std::string len_name = name;
00324         len_name += ".len";
00325         process(len_name.c_str(), lenp);
00326     }
00327 
00328     if (*lenp != 0) {
00329         u_char* buf = next_slice(*lenp);
00330         if (buf == NULL) return;
00331         
00332         if (flags & Serialize::ALLOC_MEM) {
00333             *bp = (u_char*)malloc(*lenp);
00334             memcpy(*bp, buf, *lenp);
00335         } else {
00336             *bp = buf;
00337         }
00338     } else {
00339         *bp = 0;
00340     }
00341     
00342     if (log_) {
00343         std::string s;
00344         hex2str(&s, *bp, *lenp < 16 ? *lenp : 16);
00345         logf(log_, LOG_DEBUG, "bufc   %s<=(%u: '%.*s')",
00346              name, *lenp, (int)s.length(), s.data());
00347     }
00348 }
00349 
00350 void 
00351 Unmarshal::process(const char* name, std::string* s)
00352 {
00353     ASSERT(s != 0);
00354 
00355     u_int32_t len;
00356     process(name, &len);
00357 
00358     u_char* buf = next_slice(len);
00359     if (buf == 0) return;
00360     
00361     s->assign((char*)buf, len);
00362     if (log_) {
00363         if (len < 32)
00364             logf(log_, LOG_DEBUG, "string %s<=(%u: '%.*s')",
00365                  name, len, len, s->data());
00366         else 
00367             logf(log_, LOG_DEBUG, "string %s<=(%u: '%.*s'...)",
00368                  name, len, 32, s->data());
00369     }
00370 }
00371 
00372 /******************************************************************************
00373  *
00374  * MarshalSize 
00375  *
00376  *****************************************************************************/
00377 
00378 void
00379 MarshalSize::begin_action()
00380 {
00381     if (options_ & USE_CRC) {
00382         size_ += sizeof(CRC32::CRC_t);
00383     }
00384 }
00385 
00386 void
00387 MarshalSize::process(const char* name, u_int64_t* i)
00388 {
00389     (void)name;
00390     size_ += get_size(i);
00391 }
00392 
00393 void
00394 MarshalSize::process(const char* name, u_int32_t* i)
00395 {
00396     (void)name;
00397     size_ += get_size(i);
00398 }
00399 
00400 void
00401 MarshalSize::process(const char* name, u_int16_t* i)
00402 {
00403     (void)name;
00404     size_ += get_size(i);
00405 }
00406 
00407 void
00408 MarshalSize::process(const char* name, u_int8_t* i)
00409 {
00410     (void)name;
00411     size_ += get_size(i);
00412 }
00413 
00414 void
00415 MarshalSize::process(const char* name, bool* b)
00416 {
00417     (void)name;
00418     size_ += get_size(b);
00419 }
00420 
00421 void
00422 MarshalSize::process(const char* name, u_char* bp, u_int32_t len)
00423 {
00424     (void)name;
00425     size_ += get_size(bp, len);
00426 }
00427 
00428 void
00429 MarshalSize::process(const char* name, std::string* s)
00430 {
00431     (void)name;
00432     size_ += get_size(s);
00433 }
00434 
00435 void
00436 MarshalSize::process(const char* name, u_char** bp,
00437                      u_int32_t* lenp, int flags)
00438 {
00439     (void)name;
00440     if(flags & Serialize::NULL_TERMINATED) {
00441         size_ += strlen(reinterpret_cast<char*>(*bp)) + sizeof('\0');
00442     } else {
00443         size_ += *lenp + sizeof(u_int32_t);
00444     }
00445 }
00446 
00447 
00448 /******************************************************************************
00449  *
00450  * MarshalCRC
00451  *
00452  *****************************************************************************/
00453 #define DECL_CRC(_type)                         \
00454 void                                            \
00455 MarshalCRC::process(const char* name, _type* i) \
00456 {                                               \
00457     (void)name;                                 \
00458     crc_.update((u_char*)i, sizeof(_type));     \
00459 }
00460 
00461 DECL_CRC(u_int32_t)
00462 DECL_CRC(u_int16_t)
00463 DECL_CRC(u_int8_t)
00464 DECL_CRC(bool)
00465 
00466 void
00467 MarshalCRC::process(const char* name, u_char* bp, u_int32_t len)
00468 {
00469     (void)name;
00470     crc_.update(bp, len);
00471 }
00472 
00473 void
00474 MarshalCRC::process(const char* name, u_char** bp,
00475                      u_int32_t* lenp, int flags)
00476 {
00477     (void)name;
00478     if(flags & Serialize::NULL_TERMINATED) {
00479         crc_.update(*bp, strlen(reinterpret_cast<char*>(*bp)));
00480     } else {
00481         crc_.update(*bp, *lenp);
00482     }
00483 }
00484 
00485 void
00486 MarshalCRC::process(const char* name, std::string* s)
00487 {
00488     (void)name;
00489     crc_.update((u_char*)s->c_str(), s->size());
00490 }
00491 
00492 
00493 /******************************************************************************
00494  *
00495  * MarshalCopy
00496  *
00497  *****************************************************************************/
00498 u_int32_t
00499 MarshalCopy::copy(ExpandableBuffer* buf,
00500                   const SerializableObject* src,
00501                   SerializableObject* dst)
00502 {
00503     Marshal m(Serialize::CONTEXT_LOCAL, buf);
00504     if (m.action(src) != 0) {
00505         PANIC("error marshalling object");
00506     }
00507     
00508     Unmarshal um(Serialize::CONTEXT_LOCAL,
00509                  (const u_char*)buf->raw_buf(), buf->len());
00510     if (um.action(dst) != 0) {
00511         PANIC("error marshalling object");
00512     }
00513 
00514     return buf->len();
00515 }
00516 
00517 
00518 } // namespace oasys

Generated on Thu Jun 7 16:56:50 2007 for DTN Reference Implementation by  doxygen 1.5.1