def DeserializeInstructions(self, frame, packing_instructions, huff): """ Takes SPDY4 wire-format data and de-serializes it into in-memory operations It returns the group ID and these operations. (group_id, ops) """ ops = [] bb = BitBucket() bb.StoreBits(frame.GetAllBits()) flags = 0 #print 'DeserializeInstructions' while flags == 0: frame_len = bb.GetBits16() * 8 # in bits #print 'frame_len: ', frame_len frame_type = bb.GetBits8() #print 'frame_type: ', frame_type flags = bb.GetBits8() #print 'flags: ', flags stream_id = bb.GetBits32() #print 'stream_id: ', stream_id group_id = bb.GetBits8() #print 'group_id: ', group_id while frame_len > 8: bits_remaining_at_start = bb.BitsRemaining() try: opcode_val_and_op_count = bb.GetBits8() opcode_val = opcode_val_and_op_count >> 4 op_count = (opcode_val_and_op_count & 0x0f) + 1 opcode_description = g_opcode_to_op[opcode_val] opcode = opcode_description[0] fields = opcode_description[1:] for i in xrange(op_count): op = {'opcode': opcode} for field_name in g_packing_order: if not field_name in fields: continue (params, _, unpack_fn) = packing_instructions[field_name] val = unpack_fn(bb, params, huff) #print val op[field_name] = val #print "BitsRemaining: %d (%d)" % (bb.BitsRemaining(), bb.BitsRemaining() % 8) #print "Deser %d" % (bb.NumBits() - bb.BitsRemaining()) #print op ops.append(op) bits_consumed = (bits_remaining_at_start - bb.BitsRemaining()) #if not bits_consumed % 8 == 0: # print "somehow didn't consume whole bytes..." # print "Bits consumed: %d (%d)" % (bits_consumed, bits_consumed % 8) # raise StandardError() frame_len -= bits_consumed except: break #print 'ops: ', ops return (group_id, ops)
def test_GetBits32(self): bb = BitBucket() inp = [0xdddddddd, 0xeeeeeeee, 0xaaaaaaaa, 0xdddddddd] bitstr = "|11011101"*4 + \ "|11101110"*4 + \ "|10101010"*4 + \ "|11011101"*4 + \ " [0]" for offset in xrange(64): bb.Clear() StoreBitsFromString(bb, ("1" * offset) + bitstr) for i in xrange(offset): bb.GetBit() for i in xrange(len(inp)): assert bb.GetBits32() == inp[i]