def testDecoderBase(self): # Allocate message, write reference payload msg = Message() msg.init(MSGID) msg.buf.skip(12) msg.buf.write(PAYLOAD) msg.finish() # Allocate and init decoder dec = Decoder() dec.init(msg) # Read try: i8 = dec.readI8() u8 = dec.readU8() i16 = dec.readI16() u16 = dec.readU16() i32 = dec.readI32() u32 = dec.readU32() i64 = dec.readI64() u64 = dec.readU64() sval = dec.readStr() buf = dec.readBuf() f32 = dec.readF32() f64 = dec.readF64() # Check self.assertEqual(VAL_I8, i8) self.assertEqual(VAL_U8, u8) self.assertEqual(VAL_I16, i16) self.assertEqual(VAL_U16, u16) self.assertEqual(VAL_I32, i32) self.assertEqual(VAL_U32, u32) self.assertEqual(VAL_I64, i64) self.assertEqual(VAL_U64, u64) self.assertEqual(VAL_STR, sval) self.assertEqual(len(VAL_BUF), len(buf)) self.assertEqual(VAL_BUF, buf) self.assertEqual(VAL_F32, f32) self.assertEqual(VAL_F64, f64) except DecodeException as ex: self.fail(ex.message) # Clear dec.clear() msg.clear()
def testEncoderBase(self): # Allocate message */ msg = Message() msg.init(MSGID) # Allocate and init encoder enc = Encoder() enc.init(msg) # Write try: enc.writeI8(VAL_I8) enc.writeU8(VAL_U8) enc.writeI16(VAL_I16) enc.writeU16(VAL_U16) enc.writeI32(VAL_I32) enc.writeU32(VAL_U32) enc.writeI64(VAL_I64) enc.writeU64(VAL_U64) enc.writeStr(VAL_STR) enc.writeBuf(VAL_BUF) enc.writeF32(VAL_F32) enc.writeF64(VAL_F64) except EncodeException as ex: self.fail(ex.message) msg.finish() # Buffer check data = msg.buf.getData() header = data[:12] payload = data[12:] self.assertEqual(len(HEADER), len(header)) self.assertEqual(len(PAYLOAD), len(payload)) self.assertEqual(HEADER, header) self.assertEqual(PAYLOAD, payload) # Clear enc.clear() msg.clear()
class Protocol(object): _STATE_IDLE = 0 _STATE_HEADER_MAGIC_0 = 1 _STATE_HEADER_MAGIC_1 = 2 _STATE_HEADER_MAGIC_2 = 3 _STATE_HEADER_MAGIC_3 = 4 _STATE_HEADER = 5 _STATE_PAYLOAD = 6 def __init__(self): self.state = Protocol._STATE_IDLE self.headerBuf = None self.header = None self.msg = None self.bufSrc = None self.offSrc = 0 self.lenSrc = 0 self._reset() def decode(self, buf, off): rxMsg = None # If idle start a new parsing if self.state == Protocol._STATE_IDLE: self.state = Protocol._STATE_HEADER_MAGIC_0 # Setup source buffer self.bufSrc = buf self.offSrc = off self.lenSrc = len(buf) - off while self.lenSrc > 0 and self.state != Protocol._STATE_IDLE: if self.state == Protocol._STATE_HEADER_MAGIC_0: self._reset() self.state = Protocol._STATE_HEADER_MAGIC_0 self._copyOne(self.headerBuf) self._checkMagic(0, POMP_MAGIC_0, Protocol._STATE_HEADER_MAGIC_1) elif self.state == Protocol._STATE_HEADER_MAGIC_1: self._copyOne(self.headerBuf) self._checkMagic(1, POMP_MAGIC_1, Protocol._STATE_HEADER_MAGIC_2) elif self.state == Protocol._STATE_HEADER_MAGIC_2: self._copyOne(self.headerBuf) self._checkMagic(2, POMP_MAGIC_2, Protocol._STATE_HEADER_MAGIC_3) elif self.state == Protocol._STATE_HEADER_MAGIC_3: self._copyOne(self.headerBuf) self._checkMagic(3, POMP_MAGIC_3, Protocol._STATE_HEADER) elif self.state == Protocol._STATE_HEADER: self._copy(self.headerBuf, HEADER_SIZE) if len(self.headerBuf) == HEADER_SIZE: self._decodeHeader() elif self.state == Protocol._STATE_PAYLOAD: self._copy(self.msg.buf, self.header.size) else: assert False # Check end of payload if (self.state == Protocol._STATE_PAYLOAD and len(self.msg.buf) == self.header.size): # Give ownership of message to caller self.msg.setFinished() rxMsg = self.msg self.msg = None self.state = Protocol._STATE_IDLE return (self.offSrc, rxMsg) def _reset(self): self.state = Protocol._STATE_IDLE self.headerBuf = Buffer() self.header = None self.msg = None def _checkMagic(self, idx, val, state): if isinstance(self.headerBuf.getData(), str): magic = ord(self.headerBuf.getData()[idx]) else: magic = self.headerBuf.getData()[idx] if magic != val: _log.warning("Bad header magic %d: 0x%02x(0x%02x)", idx, magic, val) self.state = Protocol._STATE_HEADER_MAGIC_0 else: self.state = state def _copyOne(self, bufDst): bufDst.write(self.bufSrc[self.offSrc:self.offSrc+1]) self.offSrc += 1 self.lenSrc -= 1 def _copy(self, bufDst, sizeDst): cpyLen = min(self.lenSrc, sizeDst - len(bufDst)) bufDst.write(self.bufSrc[self.offSrc:self.offSrc+cpyLen]) self.offSrc += cpyLen self.lenSrc -= cpyLen def _decodeHeader(self): try: # Decode header fields self.headerBuf.rewind() magic = self.headerBuf.readInt() msgid = self.headerBuf.readInt() size = self.headerBuf.readInt() self.header = Header(magic, msgid, size) # Check header and setup payload decoding */ if self.header.size < HEADER_SIZE: _log.warning("Bad header size: %d", self.header.size) self.state = Protocol._STATE_HEADER_MAGIC_0 else: self._allocMsg(self.header.msgid, self.header.size) self.msg.buf.write(self.headerBuf.getData()) self.state = Protocol._STATE_PAYLOAD except struct.error as ex: _log.error(ex) self.state = Protocol._STATE_HEADER_MAGIC_0 def _allocMsg(self, msgid, size): from pomp.message import Message self.msg = Message() self.msg.init(msgid)