def unpack_new (raw, offset):
    h, = struct.unpack_from("!L", raw, offset)
    offset += 4
    t = h >> 9
    has_mask = (h & (1<<8)) != 0
    length = h & 0x7f
    offset,data = of._read(raw, offset, length)
    mask = None
    if has_mask:
      assert not (length & 1), "Odd length with mask"
      mask = data[length/2:]
      data = data[length/2]

    c = _nxm_type_to_class.get(t)
    if c is None:
      e = NXM_GENERIC()
      e._nxm_length = length
      if has_mask:
        e._nxm_length /= 2
      e._nxm_type = t
    else:
      e = c()
    assert data is not None
    assert len(data) == (e._nxm_length * (2 if has_mask else 1))
    e._value = data
    e._mask = mask
    if mask is not None:
      e._force_mask = True

    return offset, e
  def unpack_new (raw, offset):
    t,has_mask,length = nxm_entry.unpack_header(raw, offset)
    offset += 4
    offset,data = of._read(raw, offset, length)
    mask = None
    if has_mask:
      assert not (length & 1), "Odd length with mask"
      mask = data[length/2:]
      data = data[:length/2]

    #NOTE: Should use _class_for_nxm_header?
    c = _nxm_type_to_class.get(t)
    if c is None:
      e = NXM_GENERIC()
      e._nxm_length = length
      if has_mask:
        e._nxm_length /= 2
      e._nxm_type = t
    else:
      e = c()
    assert data is not None
    assert len(data) == e._nxm_length, "%s != %s" % (len(data), e._nxm_length)
    assert mask is None or len(mask) == e._nxm_length
    e._value = data
    e._mask = mask
    if mask is not None:
      e._force_mask = True

    return offset, e
  def unpack (self, raw, offset=0):
    _offset = offset
    offset,length = self._unpack_header(raw, offset)
    offset,(vendor,subtype) = _unpack("!LL", raw, offset)
    assert subtype == self.subtype
    #print "vendor %08x  subtype %i" % (vendor,subtype)
    offset,(self._buffer_id, self._total_len, self.reason, self.table_id,
            self.cookie, match_len) = _unpack("!LHBBQH", raw, offset)
    offset = _skip(raw, offset, 6)

    self.match = None
    offset = self.match.unpack(raw, offset, match_len)

    offset = _skip(raw, offset, (match_len + 7)//8*8 - match_len)
    offset = _skip(raw, offset, 2)

    offset,self.data = _read(raw, offset, length-(offset-_offset))
    assert length == len(self)
    return offset,length