9 NetMsgs Run-Time Library Packing and Unpacking ITV Module. 66 import NetMsgsBase
as nmBase
67 from NetMsgsLib
import *
68 import NetMsgsLibStreamBuf
as nmStream
77 """ RoadNarrows Identifier-Type-Value encoded Net Messages Class. 79 ITV message encoding provides field headers to identify and process 80 fields. Fields may be in any order. Unknown field are ignored. 85 """ Initialize NetMsgsITV instance. 88 msgdefset - Set of message definitions. 89 kwargs - Optional keyword arguments. See NetMsgsStreamBuf. 91 kwargs[
'encoding'] =
'itv' 92 nmStream.NetMsgsStreamBuf.__init__(self, msgdefset, **kwargs)
102 """ Create a new packing/unpacking operational state. 104 The operational state contains message information plus a stack of 105 current field processing states. Each field state has header, 106 control, run-time determined values, and tracing parameters. 110 op - Operation string. One of: 'pack', 'unpack'. 111 kwargs - Optional initial state overrides and implementation 115 State id which is a key into the specific state. 117 stateId = nmStream.NetMsgsStreamBuf.StateNew(self, msgid, op, **kwargs)
118 self.StateFieldSet(stateId,
'fctl', has_hdr=
True)
129 """ Pack ITV field header. 132 fielddef - Field definition. 133 val - Field value(s). 134 stateId - Packing state id. 140 fstate = self.StateFieldGet(stateId)
142 ftype = fstate[
'ftype']
143 self.ChkReqFValType(fielddef, val, stateId=stateId)
144 if not fstate[
'fctl'][
'has_hdr']:
149 buf =
PackU8(fid, endian=self.mEndian)
150 buf +=
PackU8(ftype, endian=self.mEndian)
151 buf +=
PackU8(count, endian=self.mEndian)
153 fhdr[
'ftype'] = ftype
154 fhdr[
'count'] = count
156 msgdef = fielddef[
'msgdef']
157 count = msgdef[
'max_count']
158 buf =
PackU8(fid, endian=self.mEndian)
159 buf +=
PackU8(ftype, endian=self.mEndian)
160 buf +=
PackU8(count, endian=self.mEndian)
162 fhdr[
'ftype'] = ftype
163 fhdr[
'count'] = count
165 vdef = fielddef[
'vdef']
166 vtype = vdef[
'ftype']
168 buf =
PackU8(fid, endian=self.mEndian)
169 buf +=
PackU8(ftype, endian=self.mEndian)
170 buf +=
PackU8(count, endian=self.mEndian)
171 buf +=
PackU8(vtype, endian=self.mEndian)
173 fhdr[
'ftype'] = ftype
174 fhdr[
'count'] = count
175 fhdr[
'vtype'] = vtype
178 buf =
PackU8(fid, endian=self.mEndian)
179 buf +=
PackU8(ftype, endian=self.mEndian)
181 fhdr[
'ftype'] = ftype
182 fhdr[
'fhdr_size'] = len(buf)
183 self.StateFieldSet(stateId, fhdr=fhdr)
189 """ Pack variable length string field. 192 fielddef - Field definition. 194 stateId - Packing state id. 199 self.ChkReqFValType(fielddef, val)
201 max_count = fielddef.get(
'max_count', nmBase.NMStringMaxCount)
202 if count > max_count:
203 self.Error(
"%s" % fielddef[
'name'],
204 "%s %u > %u" % (EMsgStringRange, count, max_count),
206 self.StateFieldSet(stateId, count=count)
209 if self.mTrace: self.TraceField(fielddef, val, buf, stateId)
215 """ Pack variable vector field. 218 fielddef - Field definition. 219 vallist - Vector (list) of vector item values. 220 stateId - Packing state id. 225 self.ChkReqFValType(fielddef, vallist)
226 vdef = fielddef[
'vdef']
228 vtype = vdef[
'ftype']
230 max_count = fielddef[
'max_count']
231 if count > max_count:
232 self.Error(
"%s" % fielddef[
'name'],
233 "%s %u > %u" % (EMsgVectorRange, count, max_count),
235 self.StateFieldSet(stateId, count=count)
237 if self.mTrace: self.TraceField(fielddef, vallist, buf, stateId)
238 setfunc = self.mFuncMap[vtype][self.SETFUNC]
239 packfunc = self.mFuncMap[vtype][self.PACKFUNC]
241 self.StateFieldPush(stateId, fname=vname, fid=0, ftype=vtype)
242 if vtype
in nmBase.NMFTypeCodeSimple:
243 self.StateFieldSet(stateId,
'fctl', has_hdr=
False)
245 self.StateFieldSet(stateId, i=i)
246 self.StateFieldSet(stateId, fid=i+1)
247 val = setfunc(vdef, val, stateId)
248 buf += packfunc(vdef, val, stateId)
250 self.StateFieldPop(stateId)
256 """ Pack message header. 259 msgid - Message identifier. 260 msgdef - Message definition. 261 stateId - Packing state id. 266 count = msgdef[
'max_count']
267 buf =
PackU16(msgid, endian=self.mEndian)
268 buf +=
PackU8(count, endian=self.mEndian)
269 msghdr = {
'msghdr_size':len(buf),
'msgid':msgid,
'count':count}
270 self.StateSet(stateId, msghdr=msghdr)
281 """ Unpack ITV field header. 284 buf - Buffer to unpack. 285 offset - Buffer offset where unpacking begins. 286 stateId - Unpacking state id. 292 fstate = self.StateFieldGet(stateId)
294 if self.StateFieldGet(stateId,
'fctl',
'has_hdr'):
296 fid, offset =
UnpackU8(buf, offset, endian=self.mEndian)
297 ftype, offset =
UnpackU8(buf, offset, endian=self.mEndian)
300 fhdr[
'ftype'] = ftype
302 fhdr[
'count'], offset =
UnpackU8(buf, offset, endian=self.mEndian)
304 fhdr[
'count'], offset =
UnpackU8(buf, offset, endian=self.mEndian)
306 fhdr[
'count'], offset =
UnpackU8(buf, offset, endian=self.mEndian)
307 vtype, offset =
UnpackU8(buf, offset, endian=self.mEndian)
308 fhdr[
'vtype'] =
"%c" % vtype
309 fhdr[
'fhdr_size'] = offset - start
310 self.StateFieldSet(stateId, fhdr=fhdr)
316 """ Unpack variable number of pad bytes from the buffer. 318 No field values are set. 321 fielddef - Field definition. 322 buf - Buffer to unpack. 323 offset - Buffer offset where unpacking begins. 324 fvals - Dictionary to hold unpacked field values. 325 stateId - Unpacking state id. 331 while (ord(buf[offset]) == nmBase.NMPadFVal)
and (offset < len(buf)):
334 self.StateFieldSet(stateId, count=count)
335 self.StateFieldSet(stateId,
'trace', trace_end=offset)
336 if self.mTrace: self.TraceField(fielddef, nmBase.NMPadFVal, buf, stateId)
342 """ Unpack variable lenght string field from the buffer. 345 fielddef - Field definition. 346 buf - Buffer to unpack. 347 offset - Buffer offset where unpacking begins. 348 fvals - Dictionary to hold unpacked field values. 349 stateId - Unpacking state id. 354 fname = fielddef[
'name']
355 count = self.StateFieldGet(stateId,
'fhdr',
'count')
356 max_count = fielddef[
'max_count']
357 if count > max_count:
358 self.Error(
"%s" % fielddef[
'name'],
359 "%s %u > %u" % (EMsgStringRange, count, max_count),
362 if not self.StateFieldGet(stateId,
'fctl',
'noexec'):
364 self.StateFieldSet(stateId, count=count)
365 self.StateFieldSet(stateId,
'trace', trace_end=offset)
366 if self.mTrace: self.TraceField(fielddef, val, buf, stateId)
372 """ Unpack structure field from the buffer. 375 fielddef - Field definition. 376 buf - Buffer to unpack. 377 offset - Buffer offset where unpacking begins. 378 fvals - Dictionary to hold unpacked field values. 379 stateId - Unpacking state id. 384 fname = fielddef[
'name']
385 msgdef = fielddef[
'msgdef']
386 max_count = msgdef[
'max_count']
387 fhdr = self.StateFieldGet(stateId,
'fhdr')
388 count = fhdr[
'count']
389 if count > max_count:
390 self.Error(
"%s" % fielddef[
'name'],
391 "%s %u > %u" % (EMsgStructRange, count, max_count),
393 self.StateFieldSet(stateId, count=count)
394 self.StateFieldSet(stateId,
'trace', trace_end=offset)
395 if not self.StateFieldGet(stateId,
'fctl',
'noexec'):
400 if self.mTrace: self.TraceField(fielddef, val, buf, stateId)
406 """ Unpack variable vector field from the buffer. 409 fielddef - Field definition. 410 buf - Buffer to unpack. 411 offset - Buffer offset where unpacking begins. 412 fvals - Dictionary to hold unpacked field values. 413 stateId - Unpacking state id. 418 fname = fielddef[
'name']
419 vdef = fielddef[
'vdef']
421 vtype = vdef[
'ftype']
422 max_count = fielddef[
'max_count']
423 fhdr = self.StateFieldGet(stateId,
'fhdr')
424 count = fhdr[
'count']
425 if vtype != fhdr[
'vtype']:
426 self.Error(
"%s" % fielddef[
'name'], EMsgBadMsg,
427 "unpacked vtype=%c != expected vtype=%c" % (fhdr[
'vtype'], vtype),
429 if count > max_count:
430 self.Error(
"%s" % fielddef[
'name'],
431 "%s %u > %u" % (EMsgVectorRange, count, max_count),
433 self.StateFieldSet(stateId, count=count)
434 self.StateFieldSet(stateId,
'trace', trace_end=offset)
435 if not self.StateFieldGet(stateId,
'fctl',
'noexec'):
440 if self.mTrace: self.TraceField(fielddef, val, buf, stateId)
441 if vtype
in nmBase.NMFTypeCodeSimple:
442 self.StateFieldSet(stateId,
'fctl', has_hdr=
False)
444 self.StateFieldSet(stateId,
'fctl', has_hdr=
True)
445 unpackfunc = self.mFuncMap[vtype][self.UNPACKFUNC]
448 self.StateFieldPush(stateId, fname=vname, fid=0, ftype=vtype)
450 self.StateFieldSet(stateId,
'trace', trace_start=offset)
451 self.StateFieldSet(stateId, i=i)
453 offset = unpackfunc(vdef, buf, offset, vval, stateId)
457 self.StateFieldPop(stateId)
463 """ Unpack a field stream from the buffer. 466 msgdef - Message definition. 467 buf - Buffer to unpack. 468 offset - Buffer offset where unpacking begins. 469 stateId - Unpacking state id. 474 msgname = msgdef[
'name']
475 fdeflist = msgdef[
'fielddef']
476 max_count = msgdef[
'max_count']
477 count = self.StateFieldGet(stateId,
'count')
478 if count > max_count:
479 self.Error(
"%s" % fielddef[
'name'],
480 "%s %u > %u" % (EMsgStructRange, count, max_count),
484 self.StateFieldPush(stateId)
485 self.StateFieldSet(stateId,
'trace', trace_start=offset)
486 if ord(buf[offset]) == nmBase.NMPadFVal:
488 ftype = nmBase.NMFCode(
'pad')
489 fielddef = {
'name':
'pad',
'fid':0,
'ftype':ftype}
492 fid = self.StateFieldGet(stateId,
'fhdr',
'fid')
493 ftype = self.StateFieldGet(stateId,
'fhdr',
'ftype')
494 fielddef = self.FindFId(msgdef, fid)
496 fname = fielddef[
'name']
497 fid = fielddef[
'fid']
498 if ftype != fielddef[
'ftype']:
499 self.Error(
"%s" % fname,
500 "%s received '%s' != expected '%s'" % \
501 (EMsgBadMsg, ftype, fielddef[
'ftype']),
503 self.StateFieldSet(stateId, fname=fname, fid=fid, ftype=ftype)
504 unpackfunc = self.mFuncMap[ftype][self.UNPACKFUNC]
505 offset = unpackfunc(fielddef, buf, offset, fvals, stateId)
507 self.Warning(
"fid=%u" % (fid),
"Field not defined - ignoring")
508 self.StateFieldSet(stateId,
'fctl', noexec=
True)
509 unpackfunc = self.mFuncMap[ftype][self.UNPACKFUNC]
510 offset = unpackfunc(fielddef, buf, offset, fvals, stateId)
511 self.StateFieldPop(stateId)
518 """ Unpack ITV message header. 521 msgid - Message identifier. 522 msgdef - Message definition. 523 buf - Buffer to unpack. 524 offset - Buffer offset where unpacking begins. 525 fvals - Dictionary to hold unpacked field values. 526 stateId - Unpacking state id. 533 msghdr[
'msgid'], offset =
UnpackU16(buf, offset, endian=self.mEndian)
534 msghdr[
'count'], offset =
UnpackU8(buf, offset, endian=self.mEndian)
535 msghdr[
'msghdr_size'] = offset - start
536 if msgid != msghdr[
'msgid']:
537 self.Error(
"%s" % msgdef[
'name'], EMsgBadMsg,
538 "unpacked msgid=%u != expected msgid=%u" % (msghdr[
'msgid'], msgid),
540 count = msghdr[
'count']
541 max_count = msgdef[
'max_count']
542 if count > max_count:
543 self.Error(
"%s" % msgdef[
'name'],
544 "%s %u > %u" % (EMsgStructRange, count, max_count),
546 self.StateSet(stateId, msghdr=msghdr)
547 self.StateFieldSet(stateId, count=count)
def nmUnpackMsgHdr(self, msgid, msgdef, buf, offset, fvals, stateId)
def UnpackU8(buf, offset=0, endian='big')
def nmUnpackStream(self, msgdef, buf, offset, fvals, stateId)
def PackU16(val, endian='big')
def UnpackString(buf, count, offset=0)
def nmUnpackFieldHdr(self, buf, offset, stateId)
def nmUnpackPad(self, fielddef, buf, offset, fvals, stateId)
def nmPackVector(self, fielddef, vallist, stateId)
def nmUnpackVector(self, fielddef, buf, offset, fvals, stateId)
def nmPackString(self, fielddef, val, stateId)
def UnpackU16(buf, offset=0, endian='big')
def nmPackMsgHdr(self, msgid, msgdef, stateId)
def nmUnpackString(self, fielddef, buf, offset, fvals, stateId)
def nmUnpackStruct(self, fielddef, buf, offset, fvals, stateId)
def PackU8(val, endian='big')
def __init__(self, msgdefset, kwargs)
def PackString(val, count=None)
def nmPackFieldHdr(self, fielddef, val, stateId)
def StateNew(self, msgid, op, kwargs)