9 NetMsgs Run-Time Library Packing and Unpacking Base Module 66 import NetMsgsBase
as nmBase
78 warnings.simplefilter(
'error', DeprecationWarning)
79 warnings.simplefilter(
'always', RuntimeWarning)
91 EMsgBadId =
"Identifier not an integer" 93 EMsgEndian =
"Invalid byte order value" 95 EMsgNoMem =
"No space in buffer" 97 EMsgFValType =
"Invalid field value type" 99 EMsgNoFVal =
"Field value not defined" 101 EMsgRange =
"Field value out-of-range" 103 EMsgIntRange =
"Integer out-of-range" 105 EMsgFPNRange =
"Floating-point number out-of-range" 107 EMsgStringRange =
"String length out-of-range" 109 EMsgStructRange =
"Message/Struct field count out-of-range" 111 EMsgVectorRange =
"Vector length out-of-range" 113 EMsgBufType =
"Invalid buffer type" 115 EMsgNoMsgDef =
"Message definition not found" 117 EMsgReqKeyword =
"Required definition keyword not found" 119 EMsgNoIndex =
"Required index out of range" 121 EMsgBadMsg =
"Bad message format" 129 _EndianCode = {
'big':
'>',
'little':
'<',
'native':
'='}
141 """ Get the native byte order. 147 if not _EndianNative:
148 if PackU16(1, endian=
'native') ==
'\0x00\0x01':
149 _EndianNative =
'big' 151 _EndianNative =
'little' 161 def _PackException(ftype, val, endian, inst):
162 """ Parse raised exception during packing, and re-raise as NetMsgError. 165 ftype - Readable field type where exception occurred. 168 inst - Exception instance. 170 exception = type(inst)
173 if exception == KeyError:
174 raise nmBase.NetMsgsError(
"pack endian=%s: %s" % \
175 (repr(endian), EMsgEndian))
178 elif exception == TypeError:
179 raise nmBase.NetMsgsError(
"pack %s=%s: %s" % \
180 (ftype, repr(val), EMsgFValType))
183 elif exception == DeprecationWarning:
185 emsg = emsg.partition(
'format requires ')[2]
186 emsg = EMsgRange +
' ' + emsg
187 raise nmBase.NetMsgsError(
"pack %s=%s: %s" % (ftype, repr(val), emsg))
191 raise nmBase.NetMsgsError(
"pack %s: %s" % (ftype, inst))
196 """ Pack boolean into 1 byte. 206 return PackU8(1, endian=endian)
208 return PackU8(0, endian=endian)
213 """ Pack one 8-bit ASCII character into 1 byte. 223 return struct.pack(
'c', val)
224 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
225 _PackException(
'char', val, endian, inst)
230 """ Pack an 8-bit unsigned integer into 1 byte. 239 if (type(val) == str)
and len(val) == 1:
242 return struct.pack(_EndianCode[endian]+
'B', val)
243 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
244 _PackException(
'u8', val, endian, inst)
249 """ Pack an 8-bit signed integer into 1 byte. 258 if (type(val) == str)
and len(val) == 1:
261 return struct.pack(_EndianCode[endian]+
'b', val)
262 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
263 _PackException(
's8', val, endian, inst)
268 """ Pack a 16-bit unsigned integer into 2 bytes. 278 return struct.pack(_EndianCode[endian]+
'H', val)
279 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
280 _PackException(
'u16', val, endian, inst)
285 """ Pack a 16-bit signed integer into 2 bytes. 295 return struct.pack(_EndianCode[endian]+
'h', val)
296 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
297 _PackException(
's16', val, endian, inst)
302 """ Pack a 32-bit unsigned integer into 4 bytes. 312 return struct.pack(_EndianCode[endian]+
'I', val)
313 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
314 _PackException(
'u32', val, endian, inst)
319 """ Pack a 32-bit signed integer into 4 bytes. 329 return struct.pack(_EndianCode[endian]+
'i', val)
330 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
331 _PackException(
's32', val, endian, inst)
336 """ Pack a 64-bit unsigned integer into 8 bytes. 338 If native architectures only support 4 byte long long's, then the 4 MSBs 339 are padded with zero's. 348 if struct.calcsize(
'Q') == 8:
350 return struct.pack(_EndianCode[endian]+
'Q', val)
351 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
352 _PackException(
'u64', val, endian, inst)
353 elif endian ==
'big' or \
357 return PackU32(val, endian=
'little') +
PackU32(0, endian=
'little')
362 """ Pack a 64-bit signed integer into 8 bytes. 364 If native architectures only support 4 byte long long's, then the 4 MSBs 365 are padded with zero's. 374 if struct.calcsize(
'q') == 8:
376 return struct.pack(_EndianCode[endian]+
'q', val)
377 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
378 _PackException(
's64', val, endian, inst)
386 return PackS32(val, endian=
'little') +
PackS32(msb, endian=
'little')
391 """ Pack a 32-bit floating-point number into 4 bytes. 393 Is this guaranteed to be in IEEE 745 32-bit format? 403 return struct.pack(_EndianCode[endian]+
'f', val)
404 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
405 _PackException(
'f32', val, endian, inst)
410 """ Pack a 64-bit floating-point number into 8 bytes. 412 Is this guaranteed to be in IEEE 745 64-bit format? 413 Will this pack into 8 bytes on 32-bit architectures? 423 return struct.pack(_EndianCode[endian]+
'd', val)
424 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
425 _PackException(
'f64', val, endian, inst)
430 """ Pack a 32-bit floating-point number into 4 bytes. 433 Pointers are really foreign to python. However, a python application 434 may have a linked c library that requires it. And NetMsgs supports it. 437 Pointers are always packed in native byte order. 446 if struct.calcsize(
'L') == 4:
448 return struct.pack(_EndianCode[
'native']+
'L', val)
449 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
450 _PackException(
'p32', val, endian, inst)
453 lsb = val & 0xffffffff
455 warnings.warn(
"pack p32=%u: non-zero 4 MSB's truncated" % (val),
458 return struct.pack(_EndianCode[
'native']+
'I', lsb)
459 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
460 _PackException(
'p32', val, endian, inst)
465 """ Pack a 64-bit floating-point number into 8 bytes. 468 Pointers are really foreign to python. However, a python application 469 may have a linked c library that requires it. And NetMsgs supports it. 472 Pointers are always packed in native byte order. 481 if struct.calcsize(
'L') == 8:
483 return struct.pack(_EndianCode[
'native']+
'Q', val)
484 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
485 _PackException(
'p64', val, endian, inst)
489 return PackU32(val, endian=
'little') +
PackU32(0, endian=
'little')
496 The endianess is ignore. 497 The terminating Null is not packed. 501 count - Number of bytes to pack. None == all. 511 val += (count-n) *
'\x00' 512 except (TypeError)
as inst:
513 _PackException(
'string', val, endian, inst)
515 return struct.pack(
"%us" % (count), val)
516 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
517 _PackException(
'string', val, endian, inst)
526 def _UnpackException(ftype, offset, endian, inst):
527 """ Parse raised exception during unpacking, and re-raise as NetMsgError. 530 ftype - Readable field type where exception occurred. 531 offset - Offset in buffer where error occurred. 533 inst - Exception instance. 535 exception = type(inst)
538 if exception == KeyError:
539 raise nmBase.NetMsgsError(
"unpack endian=%s: %s" % \
540 (repr(endian), EMsgEndian))
543 elif exception == TypeError:
544 raise nmBase.NetMsgsError(
"unpack %s: offset=%u: %s" % \
545 (ftype, offset, EMsgBufType))
548 elif exception == struct.error:
550 emsg = emsg.partition(
'unpack_from ')[2]
551 emsg =
'Field ' + emsg
552 raise nmBase.NetMsgsError(
"unpack %s: offset=%u: %s" % \
553 (ftype, offset, emsg))
557 raise nmBase.NetMsgsError(
"unpack %s: offset=%u: %s" % \
558 (ftype, offset, inst))
563 """ Unpack boolean into 1 byte. 566 buf - Input packed buffer. 567 offset - Offset in buffer. 571 2-tuple of unpacked value, new buffer offset. 573 val, offset =
UnpackU8(buf, offset=offset, endian=endian)
582 """ Unpack one 8-bit ASCII character into 1 byte. 585 buf - Input packed buffer. 586 offset - Offset in buffer. 590 2-tuple of unpacked value, new buffer offset. 593 return (struct.unpack_from(_EndianCode[endian]+
'c', buf, offset)[0],
595 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
596 _UnpackException(
'char', offset, endian, inst)
601 """ Unpack an 8-bit unsigned integer into 1 byte. 604 buf - Input packed buffer. 605 offset - Offset in buffer. 609 2-tuple of unpacked value, new buffer offset. 612 return (struct.unpack_from(_EndianCode[endian]+
'B', buf, offset)[0],
614 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
615 _UnpackException(
'u8', offset, endian, inst)
620 """ Unpack an 8-bit signed integer into 1 byte. 623 buf - Input packed buffer. 624 offset - Offset in buffer. 628 2-tuple of unpacked value, new buffer offset. 631 return (struct.unpack_from(_EndianCode[endian]+
'b', buf, offset)[0],
633 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
634 _UnpackException(
's8', offset, endian, inst)
639 """ Unpack a 16-bit unsigned integer into 2 bytes. 642 buf - Input packed buffer. 643 offset - Offset in buffer. 647 2-tuple of unpacked value, new buffer offset. 650 return (struct.unpack_from(_EndianCode[endian]+
'H', buf, offset)[0],
652 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
653 _UnpackException(
'u16', offset, endian, inst)
658 """ Unpack a 16-bit signed integer into 2 bytes. 661 buf - Input packed buffer. 662 offset - Offset in buffer. 666 2-tuple of unpacked value, new buffer offset. 669 return (struct.unpack_from(_EndianCode[endian]+
'h', buf, offset)[0],
671 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
672 _UnpackException(
's16', offset, endian, inst)
677 """ Unpack a 32-bit unsigned integer into 4 bytes. 680 buf - Input packed buffer. 681 offset - Offset in buffer. 685 2-tuple of unpacked value, new buffer offset. 688 return (struct.unpack_from(_EndianCode[endian]+
'I', buf, offset)[0],
690 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
691 _UnpackException(
'u32', offset, endian, inst)
696 """ Unpack a 32-bit signed integer into 4 bytes. 699 buf - Input packed buffer. 700 offset - Offset in buffer. 704 2-tuple of unpacked value, new buffer offset. 707 return (struct.unpack_from(_EndianCode[endian]+
'i', buf, offset)[0],
709 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
710 _UnpackException(
's32', offset, endian, inst)
715 """ Unpack a 64-bit unsigned integer into 8 bytes. 717 If native architectures only support 4 byte long long's, then the 4 MSBs 718 are padded with zero's. 721 buf - Input packed buffer. 722 offset - Offset in buffer. 726 2-tuple of unpacked value, new buffer offset. 728 if struct.calcsize(
'Q') == 8:
730 return (struct.unpack_from(_EndianCode[endian]+
'Q', buf, offset)[0],
732 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
733 _UnpackException(
'u64', offset, endian, inst)
734 elif endian ==
'big' or \
736 msb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
737 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
739 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
740 msb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
742 warnings.warn(
"unpack u64=0x%08x%08x: non-zero 4 MSB's truncated" % \
743 (msb, lsb), RuntimeWarning)
749 """ Unpack a 64-bit signed integer into 8 bytes. 751 If native architectures only support 4 byte long long's, then the 4 MSBs 752 are padded with zero's. 755 buf - Input packed buffer. 756 offset - Offset in buffer. 760 2-tuple of unpacked value, new buffer offset. 762 if struct.calcsize(
'q') == 8:
764 return (struct.unpack_from(_EndianCode[endian]+
'q', buf, offset)[0],
766 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
767 _UnpackException(
's64', offset, endian, inst)
768 elif endian ==
'big' or \
770 msb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
771 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
773 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
774 msb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
775 if (msb != 0)
and (msb != 0xffffffff):
776 warnings.warn(
"unpack s64=0x%08x%08x: non-zero 4 MSB's truncated" % \
777 (msb, lsb), RuntimeWarning)
783 """ Unpack a 32-bit floating-point number into 4 bytes. 785 Is this guaranteed to be in IEEE 745 32-bit format? 788 buf - Input packed buffer. 789 offset - Offset in buffer. 793 2-tuple of unpacked value, new buffer offset. 796 return (struct.unpack_from(_EndianCode[endian]+
'f', buf, offset)[0],
798 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
799 _UnpackException(
'f32', offset, endian, inst)
804 """ Unpack a 64-bit floating-point number into 8 bytes. 806 Is this guaranteed to be in IEEE 745 64-bit format? 807 Will this pack into 8 bytes on 32-bit architectures? 810 buf - Input packed buffer. 811 offset - Offset in buffer. 815 2-tuple of unpacked value, new buffer offset. 818 return (struct.unpack_from(_EndianCode[endian]+
'd', buf, offset)[0],
820 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
821 _UnpackException(
'f64', offset, endian, inst)
826 """ Unpack a 32-bit floating-point number into 4 bytes. 829 Pointers are really foreign to python. However, a python application 830 may have a linked c library that requires it. And NetMsgs XML and 831 run-time C library supports it. 834 Pointers are always unpacked in native byte order. 837 buf - Input packed buffer. 838 offset - Offset in buffer. 842 2-tuple of unpacked value, new buffer offset. 845 return (struct.unpack_from(_EndianCode[
'native']+
'I', buf, offset)[0],
847 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
848 _UnpackException(
'p32', offset, endian, inst)
853 """ Unpack a 64-bit floating-point number into 8 bytes. 856 Pointers are really foreign to python. However, a python application 857 may have a linked c library that requires it. And NetMsgs supports it. 860 Pointers are always unpacked in native byte order. 863 buf - Input packed buffer. 864 offset - Offset in buffer. 868 2-tuple of unpacked value, new buffer offset. 870 if struct.calcsize(
'L') == 8:
872 return (struct.unpack_from(_EndianCode[endian]+
'L', buf, offset)[0],
874 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
875 _UnpackException(
'u8', offset, endian, inst)
877 msb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
878 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'big')
880 lsb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
881 msb, offset =
UnpackU32(buf, offset=offset, endian=
'little')
883 warnings.warn(
"unpack p64=0x%08x%08x: non-zero 4 MSB's truncated" % \
884 (msb, lsb), RuntimeWarning)
892 The endianess is ignore. 893 The terminating Null is not packed. 896 buf - Input packed buffer. 897 count - Number of bytes to unpack. 898 offset - Offset in buffer. 901 2-tuple of unpacked value, new buffer offset. 904 return (struct.unpack_from(
"%us" % (count), buf, offset)[0], offset+count)
905 except (KeyError, TypeError, DeprecationWarning, struct.error)
as inst:
906 _UnpackException(
'string', offset,
'big', inst)
def UnpackU8(buf, offset=0, endian='big')
def UnpackChar(buf, offset=0, endian='big')
def PackU64(val, endian='big')
def UnpackBool(buf, offset=0, endian='big')
def PackF64(val, endian='big')
def UnpackU32(buf, offset=0, endian='big')
def PackU16(val, endian='big')
def UnpackF32(buf, offset=0, endian='big')
def UnpackString(buf, count, offset=0)
def PackBool(val, endian='big')
def UnpackS8(buf, offset=0, endian='big')
def UnpackF64(buf, offset=0, endian='big')
def PackU32(val, endian='big')
def UnpackP32(buf, offset=0, endian='big')
def UnpackU16(buf, offset=0, endian='big')
def UnpackS64(buf, offset=0, endian='big')
def PackS32(val, endian='big')
def UnpackU64(buf, offset=0, endian='big')
def PackP64(val, endian='big')
def PackU8(val, endian='big')
def PackString(val, count=None)
def PackS8(val, endian='big')
def UnpackS16(buf, offset=0, endian='big')
def PackChar(val, endian='big')
def PackF32(val, endian='big')
def UnpackS32(buf, offset=0, endian='big')
def PackS16(val, endian='big')
def PackP32(val, endian='big')
def UnpackP64(buf, offset=0, endian='big')
def PackS64(val, endian='big')