:: # 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')

/****************************************************************
 *
 * of_wire_buf.c
 *
 * Implementation of more complicated of_wire_buf operations
 *
 ****************************************************************/

#include <loci/loci.h>

#if 0
static of_match_v1_t *
wire_buf_v1_to_match(of_wire_buffer_t *wbuf, int offset)
{
    of_match_v1_t *match;
    match = of_match_v1_new(OF_VERSION_1_0);
    return match;
}

/*
 * First pass at wire buf to match conversions.  These involve a lot
 * of copying and could be made more efficient.
 */
int
of_wire_buffer_of_match_get(of_object_t *obj, int offset, of_match_t *match)
{
    switch (obj->version) {
    case OF_VERSION_1_0:
        break;
    case OF_VERSION_1_1:
        break;
    case OF_VERSION_1_2:
        break;
    default:
        return OF_ERROR_VERSION;
        break;
    }

    return OF_ERROR_NONE;
}

/**
 * Write a host match structure into the wire buffer
 * @param obj The object that owns the buffer to write to
 * @param offset The start location in the wire buffer
 * @param match Pointer to the host match object
 * @param cur_len The current length of the object in the buffer
 *
 * If the current length is different than the length of the new data
 * being written, then move the remains of the buffer.  This only applies
 * to version 1.2 (though it should apply to 1.1).
 */

int
of_wire_buffer_of_match_set(of_object_t *obj, int offset, 
                            of_match_t *match, int cur_len)
{
    // of_octets_t octets;

    switch (obj->version) {
    case OF_VERSION_1_0:
        break;
    case OF_VERSION_1_1:
        break;
    case OF_VERSION_1_2:
        // of_match_v3_serialize(match, &octets);
        break;
    default:
        return OF_ERROR_VERSION;
        break;
    }

    return OF_ERROR_NONE;
}
#endif

/**
 * Replace data in the data buffer, possibly with a new
 * length or appending to buffer.
 *
 * @param wbuf The wire buffer being updated.
 * @param offset The start point of the update
 * @param old_len The number of bytes being replaced
 * @param data Source of bytes to write into the buffer
 * @param new_len The number of bytes to write
 *
 * The buffer may grow for this operation.  Current byte count
 * is pre-grow for the replace.
 *
 * The current byte count for the buffer is updated.
 * 
 */

void
of_wire_buffer_replace_data(of_wire_buffer_t *wbuf, 
                            int offset, 
                            int old_len,
                            uint8_t *data,
                            int new_len)
{
    int bytes;
    uint8_t *src_ptr, *dst_ptr;
    int cur_bytes;

    LOCI_ASSERT(wbuf != NULL);

    cur_bytes = wbuf->current_bytes;

    /* Doesn't make sense; mismatch in current buffer info */
    LOCI_ASSERT(old_len + offset <= wbuf->current_bytes);

    wbuf->current_bytes += (new_len - old_len); // may decrease size

    if ((old_len + offset < cur_bytes) && (old_len != new_len)) {
        /* Need to move back of buffer */
        src_ptr = &wbuf->buf[offset + old_len];
        dst_ptr = &wbuf->buf[offset + new_len];
        bytes = cur_bytes - (offset + old_len);
        MEMMOVE(dst_ptr, src_ptr, bytes);
    }

    dst_ptr = &wbuf->buf[offset];
    MEMCPY(dst_ptr, data, new_len);

    LOCI_ASSERT(wbuf->current_bytes == cur_bytes + (new_len - old_len));
}
