:: # Copyright 2013, Big Switch Networks, Inc.
:: #
:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
:: # the following special exception:
:: #
:: # LOXI Exception
:: #
:: # As a special exception to the terms of the EPL, you may distribute libraries
:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
:: # from the LoxiGen Libraries and the notice provided below is (i) included in
:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
:: # documentation for the LoxiGen Libraries, if distributed in binary form.
:: #
:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
:: #
:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
:: # a copy of the EPL at:
:: #
:: # http://www.eclipse.org/legal/epl-v10.html
:: #
:: # Unless required by applicable law or agreed to in writing, software
:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
:: # EPL for the specific language governing permissions and limitations
:: # under the EPL.
::
:: include('_copyright.c')

#if !defined(_OF_WIRE_BUF_H_)
#define _OF_WIRE_BUF_H_

#include <string.h>
#include <loci/loci_base.h>
#include <loci/of_object.h>
#include <loci/of_match.h>
#include <loci/of_buffer.h>

/****************************************************************
 *
 * Wire buffer declaration, constructor, data alloc, delete
 *
 ****************************************************************/

/* Maximum length of an OpenFlow message. All wire buffers allocated for
 * new objects (that don't come from a message) are this length to avoid
 * needing to grow the buffers. */
#define OF_WIRE_BUFFER_MAX_LENGTH 65535

/**
 * Buffer management structure
 */
typedef struct of_wire_buffer_s {
    /** Pointer to a monolithic data buffer */
    uint8_t *buf;

    /** Length of buffer actually allocated */
    int alloc_bytes;
    /** Current extent actually used */
    int current_bytes;
    /** If not NULL, use this to dealloc buf */
    of_buffer_free_f free;
} of_wire_buffer_t;

#define WBUF_BUF(wbuf) (wbuf)->buf
#define WBUF_ALLOC_BYTES(wbuf) (wbuf)->alloc_bytes
#define WBUF_CURRENT_BYTES(wbuf) (wbuf)->current_bytes

/**
 * For read access, throw an error code if current buffer
 * is not big enough.
 * @param wbuf Pointer to an of_wire_buffer_t structure
 * @param offset The extent of the buffer required
 */
#define OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset)                      \
    LOCI_ASSERT(((wbuf) != NULL) && (WBUF_BUF(wbuf) != NULL) &&             \
           (offset > 0) && (WBUF_CURRENT_BYTES(wbuf) >= offset))

/*
 * Index a wire buffer
 * Index a wire object (from obj_offset)
 * Index a LOCI object
 */

/**
 * Return a pointer to a particular offset in a wire buffer's data
 * @param wbuf Pointer to an of_wire_buffer_t structure
 * @param offset The location to reference
 */
#define OF_WIRE_BUFFER_INDEX(wbuf, offset) (&((WBUF_BUF(wbuf))[offset]))

/****************************************************************
 * Object specific macros; of_object_t includes a wire_object
 ****************************************************************/

/**
 * Return a pointer to a particular offset in the underlying buffer
 * associated with a wire object
 * @param obj Pointer to an of_object_t object
 * @param offset The location to reference relative to the start of the object
 */
#define OF_OBJECT_BUFFER_INDEX(obj, offset) \
    OF_WIRE_BUFFER_INDEX((obj)->wbuf, (obj)->obj_offset + offset)

/**
 * Return the absolute offset as an integer from a object-relative offset
 * @param obj Pointer to an of_wire_object_t structure
 * @param offset The location to reference relative to the start of the object
 */
#define OF_OBJECT_ABSOLUTE_OFFSET(obj, offset) \
    ((obj)->obj_offset + offset)


/**
 * Map a generic object to the underlying wire buffer object (not the octets)
 *
 * Treat as private
 */
#define OF_OBJECT_TO_WBUF(obj) ((obj)->wbuf)



/**
 * Minimum allocation size for wire buffer object
 */
#define OF_WIRE_BUFFER_MIN_ALLOC_BYTES 128

/**
 * Allocate a wire buffer object and the underlying data buffer.
 * The wire buffer is initally empty (current_bytes == 0).
 * @param a_bytes The number of bytes to allocate.
 * @returns A wire buffer object if successful or NULL
 */
static inline of_wire_buffer_t *
of_wire_buffer_new(int a_bytes)
{
    of_wire_buffer_t *wbuf;

    wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
    if (wbuf == NULL) {
        return NULL;
    }
    MEMSET(wbuf, 0, sizeof(of_wire_buffer_t));

    if (a_bytes < OF_WIRE_BUFFER_MIN_ALLOC_BYTES) {
        a_bytes = OF_WIRE_BUFFER_MIN_ALLOC_BYTES;
    }

    if ((wbuf->buf = (uint8_t *)MALLOC(a_bytes)) == NULL) {
        FREE(wbuf);
        return NULL;
    }
    MEMSET(wbuf->buf, 0, a_bytes);
    wbuf->current_bytes = 0;
    wbuf->alloc_bytes = a_bytes;

    return (of_wire_buffer_t *)wbuf;
}

/**
 * Allocate a wire buffer object and bind it to an existing buffer.
 * @param buf       Existing buffer.
 * @param bytes     Size of buf.
 * @param buf_free  Function called to deallocate buf.
 * @returns A wire buffer object if successful or NULL
 */
static inline of_wire_buffer_t *
of_wire_buffer_new_bind(uint8_t *buf, int bytes, of_buffer_free_f buf_free)
{
    of_wire_buffer_t *wbuf;

    wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
    if (wbuf == NULL) {
        return NULL;
    }

    wbuf->buf = buf;
    wbuf->free = buf_free;
    wbuf->current_bytes = bytes;
    wbuf->alloc_bytes = bytes;

    return (of_wire_buffer_t *)wbuf;
}

static inline void
of_wire_buffer_free(of_wire_buffer_t *wbuf)
{
    if (wbuf == NULL) return;

    if (wbuf->buf != NULL) {
        if (wbuf->free != NULL) {
            wbuf->free(wbuf->buf);
        } else {
            FREE(wbuf->buf);
        }
    }

    FREE(wbuf);
}

static inline void
of_wire_buffer_steal(of_wire_buffer_t *wbuf, uint8_t **buffer)
{
    *buffer = wbuf->buf;
    /* Mark underlying data buffer as taken */
    wbuf->buf = NULL;
    of_wire_buffer_free(wbuf);
}

/**
 * Increase the currently used length of the wire buffer.
 * Will fail an assertion if the allocated length is not long enough.
 *
 * @param wbuf Pointer to the wire buffer structure
 * @param bytes Total number of bytes buffer should grow to
 */

static inline void
of_wire_buffer_grow(of_wire_buffer_t *wbuf, int bytes)
{
    LOCI_ASSERT(wbuf != NULL);
    LOCI_ASSERT(wbuf->alloc_bytes >= bytes);
    if (bytes > wbuf->current_bytes) {
        wbuf->current_bytes = bytes;
    }
}

/* TBD */


/**
 * Get a uint8_t scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u8_get(of_wire_buffer_t *wbuf, int offset, uint8_t *value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
    buf_u8_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Set a uint8_t scalar in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u8_set(of_wire_buffer_t *wbuf, int offset, uint8_t value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
    buf_u8_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Get a uint16_t scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u16_get(of_wire_buffer_t *wbuf, int offset, uint16_t *value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
    buf_u16_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Set a uint16_t scalar in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u16_set(of_wire_buffer_t *wbuf, int offset, uint16_t value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
    buf_u16_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Get a uint32_t scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u32_get(of_wire_buffer_t *wbuf, int offset, uint32_t *value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
    buf_u32_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Set a uint32_t scalar in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u32_set(of_wire_buffer_t *wbuf, int offset, uint32_t value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
    buf_u32_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}


/**
 * Get a uint32_t scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_ipv4_get(of_wire_buffer_t *wbuf, int offset, of_ipv4_t *value)
{
    of_wire_buffer_u32_get(wbuf, offset, value);
}

/**
 * Set a ipv4 (uint32_t) scalar in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_ipv4_set(of_wire_buffer_t *wbuf, int offset, of_ipv4_t value)
{
    of_wire_buffer_u32_set(wbuf, offset, value);
}


/**
 * Get a uint64_t scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u64_get(of_wire_buffer_t *wbuf, int offset, uint64_t *value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
    buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Set a uint64_t scalar in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 *
 * The underlying buffer accessor funtions handle endian and alignment.
 */

static inline void
of_wire_buffer_u64_set(of_wire_buffer_t *wbuf, int offset, uint64_t value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
    buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}

/**
 * Get a generic OF match structure from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to the structure to update
 *
 * NOT IMPLEMENTED.
 *
 */

static inline void
of_wire_buffer_match_get(int version, of_wire_buffer_t *wbuf, int offset,
                      of_match_t *value)
{
    LOCI_ASSERT(0);
}

/**
 * Set a generic OF match structure in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to the structure to store
 *
 * NOT IMPLEMENTED.
 *
 */

static inline void
of_wire_buffer_match_set(int version, of_wire_buffer_t *wbuf, int offset,
                      of_match_t *value)
{
    LOCI_ASSERT(0);
}

/**
 * Get a port description object from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to the structure to fill out
 *
 * NOT IMPLEMENTED.
 *
 * @fixme Where should this go?
 */

static inline void
of_wire_buffer_of_port_desc_get(int version, of_wire_buffer_t *wbuf, int offset,
                             void *value)
{
    LOCI_ASSERT(0);
}

/**
 * Set a port description object in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to the structure to fill out
 *
 * NOT IMPLEMENTED.
 *
 * @fixme Where should this go?
 */

static inline void
of_wire_buffer_of_port_desc_set(int version, of_wire_buffer_t *wbuf, int offset,
                             void *value)
{
    LOCI_ASSERT(0);
}

/**
 * Get a port number scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * Port numbers are version specific.
 */

static inline void
of_wire_buffer_port_no_get(int version, of_wire_buffer_t *wbuf, int offset,
                        of_port_no_t *value)
{
    uint16_t v16;
    uint32_t v32;

    switch (version) {
    case OF_VERSION_1_0:
        of_wire_buffer_u16_get(wbuf, offset, &v16);
        *value = v16;
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u32_get(wbuf, offset, &v32);
        *value = v32;
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/**
 * Set a port number scalar from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store in the buffer
 *
 * Port numbers are version specific.
 */

static inline void
of_wire_buffer_port_no_set(int version, of_wire_buffer_t *wbuf, int offset,
                      of_port_no_t value)
{

    switch (version) {
    case OF_VERSION_1_0:
        of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/**
 * Get a flow mod command value from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 */

static inline void
of_wire_buffer_fm_cmd_get(int version, of_wire_buffer_t *wbuf, int offset,
                        of_fm_cmd_t *value)
{
    uint16_t v16;
    uint8_t v8;

    switch (version) {
    case OF_VERSION_1_0:
        of_wire_buffer_u16_get(wbuf, offset, &v16);
        *value = v16;
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u8_get(wbuf, offset, &v8);
        *value = v8;
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/**
 * Set a flow mod command value in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 */

static inline void
of_wire_buffer_fm_cmd_set(int version, of_wire_buffer_t *wbuf, int offset,
                      of_fm_cmd_t value)
{
    switch (version) {
    case OF_VERSION_1_0:
        of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u8_set(wbuf, offset, (uint8_t)value);
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/**
 * Get a wild card bitmap value from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to store the value
 */

static inline void
of_wire_buffer_wc_bmap_get(int version, of_wire_buffer_t *wbuf, int offset,
                        of_wc_bmap_t *value)
{
    uint32_t v32;
    uint64_t v64;

    switch (version) {
    case OF_VERSION_1_0:
    case OF_VERSION_1_1:
        of_wire_buffer_u32_get(wbuf, offset, &v32);
        *value = v32;
        break;
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u64_get(wbuf, offset, &v64);
        *value = v64;
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/**
 * Set a wild card bitmap value in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value The value to store
 */

static inline void
of_wire_buffer_wc_bmap_set(int version, of_wire_buffer_t *wbuf, int offset,
                      of_wc_bmap_t value)
{
    switch (version) {
    case OF_VERSION_1_0:
    case OF_VERSION_1_1:
        of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
        break;
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        of_wire_buffer_u64_set(wbuf, offset, (uint64_t)value);
        break;
    default:
        LOCI_ASSERT(0);
    }
}

/* match bitmap and wildcard bitmaps followed the same pattern */
#define of_wire_buffer_match_bmap_get of_wire_buffer_wc_bmap_get
#define of_wire_buffer_match_bmap_set of_wire_buffer_wc_bmap_set

/* Derived functions, mostly for fixed length name strings */
#define of_wire_buffer_char_get of_wire_buffer_u8_get
#define of_wire_buffer_char_set of_wire_buffer_u8_set


/**
 * Get an octet object from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to where to put value
 *
 * of_octets_t is treated specially as the high level functions pass around
 * pointers for "get" operators.
 *
 * Important: The length of data to copy is stored in the value->bytes
 * variable.
 */

static inline void
of_wire_buffer_octets_data_get(of_wire_buffer_t *wbuf, int offset,
                               of_octets_t *value)
{
    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
    buf_octets_get(OF_WIRE_BUFFER_INDEX(wbuf, offset),
                   OF_OCTETS_POINTER_GET(value),
                   OF_OCTETS_BYTES_GET(value));
}

/**
 * Set an octet object in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param value Pointer to the octet stream to store
 * @param cur_len Current length of data in the buffer
 *
 * of_octets_t is treated specially as the high level functions pass around
 * pointers for "get" operators.
 *
 * @fixme Need to take into account cur_len
 */

static inline void
of_wire_buffer_octets_data_set(of_wire_buffer_t *wbuf, int offset,
                               of_octets_t *value, int cur_len)
{
    // FIXME need to adjust length of octets member in buffer
    LOCI_ASSERT(cur_len == 0 || cur_len == value->bytes);

    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
    buf_octets_set(OF_WIRE_BUFFER_INDEX(wbuf, offset),
                   OF_OCTETS_POINTER_GET(value),
                   OF_OCTETS_BYTES_GET(value));
}

static inline void
_wbuf_octets_set(of_wire_buffer_t *wbuf, int offset, uint8_t *src, int bytes) {
    of_octets_t octets;
    OF_OCTETS_POINTER_SET(&octets, src);
    OF_OCTETS_BYTES_SET(&octets, bytes);
    of_wire_buffer_octets_data_set(wbuf, offset, &octets, bytes);
}

static inline void
_wbuf_octets_get(of_wire_buffer_t *wbuf, int offset, uint8_t *dst, int bytes) {
    of_octets_t octets;
    OF_OCTETS_POINTER_SET(&octets, dst);
    OF_OCTETS_BYTES_SET(&octets, bytes);
    of_wire_buffer_octets_data_get(wbuf, offset, &octets);
}


/**
 * Get a MAC address from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param mac Pointer to the mac address location
 *
 * Uses the octets function.
 */

#define of_wire_buffer_mac_get(buf, offset, mac) \
    _wbuf_octets_get(buf, offset, (uint8_t *)mac, 6)

/**
 * Set a MAC address in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param mac The variable holding the mac address to store
 *
 * Uses the octets function.
 */

#define of_wire_buffer_mac_set(buf, offset, mac) \
    _wbuf_octets_set(buf, offset, (uint8_t *)&mac, 6)


/**
 * Get a port name string from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param mac The mac address
 *
 * Uses the octets function.
 */
#define of_wire_buffer_port_name_get(buf, offset, portname) \
    _wbuf_octets_get(buf, offset, (uint8_t *)portname, \
                           OF_MAX_PORT_NAME_LEN)

/**
 * Set a port name address in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param portname Where to store the port name
 *
 * Uses the octets function.
 */

#define of_wire_buffer_port_name_set(buf, offset, portname) \
    _wbuf_octets_set(buf, offset, (uint8_t *)portname, \
                           OF_MAX_PORT_NAME_LEN)


/**
 * Get a table name string from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param portname The port name
 *
 * Uses the octets function.
 */

#define of_wire_buffer_tab_name_get(buf, offset, tabname) \
    _wbuf_octets_get(buf, offset, (uint8_t *)tabname, \
                           OF_MAX_TABLE_NAME_LEN)

/**
 * Set a table name address in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param mac Where to store the table name
 *
 * Uses the octets function.
 */

#define of_wire_buffer_tab_name_set(buf, offset, tabname) \
    _wbuf_octets_set(buf, offset, (uint8_t *)tabname, \
                           OF_MAX_TABLE_NAME_LEN)

/**
 * Get a description string from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param desc Where to store the description string
 *
 * Uses the octets function.
 */

#define of_wire_buffer_desc_str_get(buf, offset, desc) \
    _wbuf_octets_get(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)

/**
 * Set a description string in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param desc The description string
 *
 * Uses the octets function.
 */

#define of_wire_buffer_desc_str_set(buf, offset, desc) \
    _wbuf_octets_set(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)

/**
 * Get a serial number string from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param sernum Where to store the serial number string
 *
 * Uses the octets function.
 */

#define of_wire_buffer_ser_num_get(buf, offset, sernum) \
    _wbuf_octets_get(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)

/**
 * Set a serial number string in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param desc The serial number string
 *
 * Uses the octets function.
 */

#define of_wire_buffer_ser_num_set(buf, offset, sernum) \
    _wbuf_octets_set(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)

/**
 * Get a str64 string from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param s The string
 *
 * Uses the octets function.
 */

#define of_wire_buffer_str64_get(buf, offset, s) \
    _wbuf_octets_get(buf, offset, (uint8_t *)s, 64)

/**
 * Set a str64 string in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param s Where to store the str64
 *
 * Uses the octets function.
 */

#define of_wire_buffer_str64_set(buf, offset, s) \
    _wbuf_octets_set(buf, offset, (uint8_t *)s, 64)

/**
 * Get an ipv6 address from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param addr Pointer to where to store the ipv6 address
 *
 * Uses the octets function.
 */

#define of_wire_buffer_ipv6_get(buf, offset, addr) \
    _wbuf_octets_get(buf, offset, (uint8_t *)addr, sizeof(of_ipv6_t))

/**
 * Set an ipv6 address in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param addr The variable holding ipv6 address to store
 *
 * Uses the octets function.
 */

#define of_wire_buffer_ipv6_set(buf, offset, addr) \
    _wbuf_octets_set(buf, offset, (uint8_t *)&addr, sizeof(of_ipv6_t))

/**
 * Get an bitmap_128 address from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param addr Pointer to where to store the bitmap_128 address
 *
 * Uses the octets function.
 */

#define of_wire_buffer_bitmap_128_get(buf, offset, addr) \
    (of_wire_buffer_u64_get(buf, offset, &addr->hi), of_wire_buffer_u64_get(buf, offset+8, &addr->lo))

/**
 * Set an bitmap_128 address in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param addr The variable holding bitmap_128 address to store
 *
 * Uses the octets function.
 */

#define of_wire_buffer_bitmap_128_set(buf, offset, addr) \
    (of_wire_buffer_u64_set(buf, offset, addr.hi), of_wire_buffer_u64_set(buf, offset+8, addr.lo))

/**
 * Get a checksum_128 from a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param checksum Pointer to where to store the checksum_128
 */

#define of_wire_buffer_checksum_128_get(buf, offset, checksum) \
    (of_wire_buffer_u64_get(buf, offset, &checksum->hi), of_wire_buffer_u64_get(buf, offset+8, &checksum->lo))

/**
 * Set a checksum_128 in a wire buffer
 * @param wbuf The pointer to the wire buffer structure
 * @param offset Offset in the wire buffer
 * @param checksum The variable holding checksum_128 to store
 */

#define of_wire_buffer_checksum_128_set(buf, offset, checksum) \
    (of_wire_buffer_u64_set(buf, offset, checksum.hi), of_wire_buffer_u64_set(buf, offset+8, checksum.lo))

/* Relocate data from start offset to the end of the buffer to a new position */
static inline void
of_wire_buffer_move_end(of_wire_buffer_t *wbuf, int start_offset, int new_offset)
{
    int bytes;
    int new_length;

    if (new_offset > start_offset) {
        bytes =  new_offset - start_offset;
        new_length = wbuf->alloc_bytes + bytes;
        OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, new_length);
    } else {
        bytes =  start_offset - new_offset;
        new_length = wbuf->alloc_bytes - bytes;
    }

    MEMMOVE(&wbuf->buf[new_offset], &wbuf->buf[start_offset], bytes);
    wbuf->alloc_bytes = new_length;
}

/* Given a wire buffer object and the offset of the start of an of_match struct,
 * return its total length in the buffer
 */
static inline int
of_match_bytes(of_wire_buffer_t *wbuf, int offset) {
    uint16_t len;
    of_wire_buffer_u16_get(wbuf, offset + 2, &len);
    return OF_MATCH_BYTES(len);
}

extern void
of_wire_buffer_replace_data(of_wire_buffer_t *wbuf, 
                            int offset, 
                            int old_len,
                            uint8_t *data,
                            int new_len);

#endif /* _OF_WIRE_BUF_H_ */
