# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
# Copyright (c) 2011, 2012 Open Networking Foundation
# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
# See the file LICENSE.pyloxi which should have been included in the source distribution
"""
Utility functions independent of the protocol version
"""

# Automatically generated by LOXI from template generic_util.py
# Do not modify

import loxi
import struct

def unpack_list(reader, deserializer):
    """
    The deserializer function should take an OFReader and return the new object.
    """
    entries = []
    while not reader.is_empty():
        entries.append(deserializer(reader))
    return entries

def unpack_list_lv16(reader, deserializer):
    """
    The deserializer function should take an OFReader and return the new object.
    """
    def wrapper(reader):
        length, = reader.peek('!H')
        return deserializer(reader.slice(length))
    return unpack_list(reader, wrapper)

def unpack_list_tlv16(reader, deserializer):
    """
    The deserializer function should take an OFReader and an integer type
    and return the new object.
    """
    def wrapper(reader):
        typ, length, = reader.peek('!HH')
        return deserializer(reader.slice(length), typ)
    return unpack_list(reader, wrapper)

def pad_to(alignment, length):
    """
    Return a string of zero bytes that will pad a string of length 'length' to
    a multiple of 'alignment'.
    """
    return "\x00" * ((length + alignment - 1)/alignment*alignment - length)

class OFReader(object):
    """
    Cursor over a read-only buffer

    OpenFlow messages are best thought of as a sequence of elements of
    variable size, rather than a C-style struct with fixed offsets and
    known field lengths. This class supports efficiently reading
    fields sequentially and is intended to be used recursively by the
    parsers of child objects which will implicitly update the offset.
    """
    def __init__(self, buf):
        self.buf = buf
        self.offset = 0

    def read(self, fmt):
        st = struct.Struct(fmt)
        if self.offset + st.size > len(self.buf):
            raise loxi.ProtocolError("Buffer too short")
        result = st.unpack_from(self.buf, self.offset)
        self.offset += st.size
        return result

    def read_all(self):
        buf = buffer(self.buf, self.offset)
        self.offset += len(buf)
        return str(buf)

    def peek(self, fmt):
        st = struct.Struct(fmt)
        if self.offset + st.size > len(self.buf):
            raise loxi.ProtocolError("Buffer too short")
        result = st.unpack_from(self.buf, self.offset)
        return result

    def skip(self, length):
        if self.offset + length > len(self.buf):
            raise loxi.ProtocolError("Buffer too short")
        self.offset += length

    def skip_align(self):
        new_offset = (self.offset + 7) / 8 * 8
        if new_offset > len(self.buf):
            raise loxi.ProtocolError("Buffer too short")
        self.offset = new_offset

    def is_empty(self):
        return self.offset == len(self.buf)

    # Used when parsing variable length objects which have external length
    # fields (e.g. the actions list in an OF 1.0 packet-out message).
    def slice(self, length):
        if self.offset + length > len(self.buf):
            raise loxi.ProtocolError("Buffer too short")
        buf = OFReader(buffer(self.buf, self.offset, length))
        self.offset += length
        return buf
