00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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
00318 signal_error();
00319 return;
00320 }
00321 *lenp = new_len + 1;
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
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
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
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 }