/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <vppinfra/cache.h>
#include <vppinfra/fifo.h>
#include <vppinfra/error.h>
#include <vppinfra/string.h>

/*
  General first in/first out queues.
  FIFOs can have arbitrary size and type.
  Let T be any type (i.e. char, int, struct foo, etc.).

  A null fifo is initialized:

    T * f = 0;

  For example, typedef struct { int a, b; } T;

  Elements can be added in 3 ways.

    #1 1 element is added:
       T x;
       x.a = 10; x.b = 20;
       fifo_add1 (f, x);

    #2 n elements are added
       T buf[10];
       initialize buf[0] .. buf[9];
       fifo_add (f, buf, 10);

    #3 1 element is added, pointer is returned
       T * x;
       fifo_add2 (f, x);
       x->a = 10;
       x->b = 20;

   Elements are removed 1 at a time:
       T x;
       fifo_sub1 (f, x);

   fifo_free (f) frees fifo.
*/

__clib_export void *
_clib_fifo_resize (void *v_old, uword n_new_elts, uword elt_bytes)
{
  void *end, *head;
  u8 *v_new = 0;
  uword n_old_elts;
  uword n_copy_bytes, n_zero_bytes;
  clib_fifo_header_t *f_new, *f_old;

  n_old_elts = clib_fifo_elts (v_old);
  n_new_elts += n_old_elts;
  if (n_new_elts < 32)
    n_new_elts = 32;
  else
    n_new_elts = max_pow2 (n_new_elts);

  vec_alloc_ha (v_new, n_new_elts * elt_bytes, sizeof (clib_fifo_header_t), 0);
  _vec_len (v_new) = n_new_elts;

  f_new = clib_fifo_header (v_new);
  f_new->head_index = 0;
  f_new->tail_index = n_old_elts;

  /* Copy old -> new. */
  n_copy_bytes = n_old_elts * elt_bytes;
  if (n_copy_bytes > 0)
    {
      f_old = clib_fifo_header (v_old);
      end = v_old + _vec_len (v_old) * elt_bytes;
      head = v_old + f_old->head_index * elt_bytes;

      if (head + n_copy_bytes >= end)
	{
	  uword n = end - head;
	  clib_memcpy_fast (v_new, head, n);
	  clib_memcpy_fast (v_new + n, v_old, n_copy_bytes - n);
	}
      else
	clib_memcpy_fast (v_new, head, n_copy_bytes);
    }

  /* Zero empty space. */
  n_zero_bytes = (n_new_elts - n_old_elts) * elt_bytes;
  clib_memset (v_new + n_copy_bytes, 0, n_zero_bytes);

  clib_fifo_free (v_old);

  return v_new;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
