blob: a320914c36184e65583e53a2ed8c1b262893d343 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_CLL_IntegerRingBuffer_Functions
//
// Purpose:
// This module supports public functions of ring buffer management.
// The ring buffer type defined by this module is able to store *integer* values.
//
// Module Parameters:
// -
//
// Module depends on:
// <EPTF_CLL_RingBuffer_Definitions>
// <EPTF_CLL_RingBuffer_PrivateFunctions>
//
// Current Owner:
// Istvan Falusi (EISTFAL)
//
// Last Review Date:
// 2007-11-19
//
///////////////////////////////////////////////////////////
module EPTF_CLL_IntegerRingBuffer_Functions
{
//=========================================================================
// Import Part
//=========================================================================
import from EPTF_CLL_RingBuffer_Definitions all;
import from EPTF_CLL_RingBuffer_PrivateFunctions all;
//=========================================================================
// Public Functions
//=========================================================================
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_init
//
// Purpose:
// Function to initialise an empty EPTF_RingBuffer.
//
// Parameters:
// pl_buffer - *inout* <EPTF_IntegerRingBuffer> - the ring buffer to be initialized
// pl_capacity - *in* <integer> - the maximum nuber of elements can be stored in the buffer
//
// Return Value:
// -
//
// Detailed Comments:
// The default value of <pl_capacity> is defined by <c_EPTF_RB_default_capacity> constant.
///////////////////////////////////////////////////////////
public function f_EPTF_RB_init(
inout EPTF_IntegerRingBuffer pl_buffer,
in integer pl_capacity := c_EPTF_RB_default_capacity
)
{
pl_buffer.data := {};
pl_buffer.status := c_EPTF_emptyRingBufferStatus;
if (pl_capacity > 0)
{
pl_buffer.status.capacity := pl_capacity;
}
f_EPTF_RB_clear(pl_buffer);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_size
//
// Purpose:
// Function to ask the size of the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// *integer* - the number of stored elements.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_size( in EPTF_IntegerRingBuffer pl_buffer ) return integer
{
return pl_buffer.status.content_size;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_capacity
//
// Purpose:
// Function to ask the capacity of the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// *integer* - the possible maximum nuber of elements can be stored in the buffer.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_capacity( in EPTF_IntegerRingBuffer pl_buffer ) return integer
{
return pl_buffer.status.capacity;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_empty
//
// Purpose:
// Checks whether the buffer is empty.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// *boolean* - true, if the buffer is empty, otherwise false.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_empty( in EPTF_IntegerRingBuffer pl_buffer ) return boolean
{
return (pl_buffer.status.content_size == 0) ;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_front
//
// Purpose:
// Function to get the first (eldest) element from the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// <EPTF_RingBufferDataItem> - the head of the buffer.
//
// Detailed Comments:
// IMPORTANT NOTE: the function does not perform boundary check.
// On empty buffer the operstion leads to undefined behaviour.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_front(in EPTF_IntegerRingBuffer pl_buffer) return EPTF_RingBufferDataItem
{
return(pl_buffer.data[pl_buffer.status.head]);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_back
//
// Purpose:
// Function to get the last (latest) element from the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// <EPTF_RingBufferDataItem> - the tail of the buffer.
//
// Detailed Comments:
// IMPORTANT NOTE: the function does not perform boundary check.
// On empty buffer the operation leads to undefined behaviour.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_back(in EPTF_IntegerRingBuffer pl_buffer) return EPTF_RingBufferDataItem
{
return(pl_buffer.data[pl_buffer.status.tail]);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_push_back
//
// Purpose:
// Function to store a new data item at end of the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_dataItem - *in* <EPTF_RingBufferDataItem> - the data item to be stored
//
// Return Value:
// -
//
// Detailed Comments:
// The operation is always possible. If buffer is full,
// the first data item (item at beginning of buffer) is overwritten.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_push_back(
inout EPTF_IntegerRingBuffer pl_buffer,
in EPTF_RingBufferDataItem pl_dataItem
)
{
f_EPTF_RB_increment_tail(pl_buffer.status);
pl_buffer.data[pl_buffer.status.tail] := pl_dataItem;
if (pl_buffer.status.content_size > pl_buffer.status.capacity)
{
f_EPTF_RB_increment_head(pl_buffer.status);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_push_front
//
// Purpose:
// Function to store a new data item at beginning of the buffer.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_dataItem - *in* <EPTF_RingBufferDataItem> - the data item to be stored
//
// Return Value:
// -
//
// Detailed Comments:
// The operation is always possible. If buffer is full,
// the last data item is (item at end of buffer) overwritten.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_push_front(
inout EPTF_IntegerRingBuffer pl_buffer,
in EPTF_RingBufferDataItem pl_dataItem
)
{
f_EPTF_RB_decrement_head(pl_buffer.status);
pl_buffer.data[pl_buffer.status.head] := pl_dataItem;
if (pl_buffer.status.content_size > pl_buffer.status.capacity)
{
f_EPTF_RB_decrement_tail(pl_buffer.status);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_pop_front
//
// Purpose:
// Function to drop the first data item.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_dataItem - *in* <EPTF_RingBufferDataItem> - the data item to be stored
//
// Return Value:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_pop_front( inout EPTF_IntegerRingBuffer pl_buffer )
{
if (pl_buffer.status.content_size != 0)
{
f_EPTF_RB_increment_head(pl_buffer.status);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_pop_back
//
// Purpose:
// Function to drop the last data item.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_dataItem - *in* <EPTF_RingBufferDataItem> - the data item to be stored
//
// Return Value:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_pop_back( inout EPTF_IntegerRingBuffer pl_buffer )
{
if (pl_buffer.status.content_size != 0)
{
f_EPTF_RB_decrement_tail(pl_buffer.status);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_clear
//
// Purpose:
// Function to remove all data from the buffer.
//
// Parameters:
// pl_buffer - *inout* <EPTF_IntegerRingBuffer> - the ring buffer
//
// Return Value:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_clear( inout EPTF_IntegerRingBuffer pl_buffer)
{
pl_buffer.status.head := 0;
pl_buffer.status.tail := pl_buffer.status.capacity - 1;
pl_buffer.status.content_size := 0;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_get
//
// Purpose:
// Function to perform an unchecked random access to the buffer.
//
// Parameters:
// pl_buffer - *inout* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_index - *in* *integer* - the index of desired data item
//
// Return Value:
// <EPTF_RingBufferDataItem> - the data item at the given index.
//
// Detailed Comments:
// - IMPORTANT NOTE: the function does not perform boundary check.
// If index is invalid the operation leads to undefined behaviour.
// - The index of the first (eldest) item is 0.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_get(
in EPTF_IntegerRingBuffer pl_buffer,
in integer pl_index
) return EPTF_RingBufferDataItem
{
return(pl_buffer.data[(pl_buffer.status.head + pl_index) mod pl_buffer.status.capacity]);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_at
//
// Purpose:
// Function to perform a secure access to the buffer.
//
// Parameters:
// pl_buffer - *inout* <EPTF_IntegerRingBuffer> - the ring buffer
//
// pl_index - *in* *integer* - the index of desired data item
//
// pl_dataItem - *out* <EPTF_RingBufferDataItem> - the data item at the given index.
//
// Return Value:
// *boolean* - false, if index is invalid, otherwise true.
//
// Detailed Comments:
// - The function performs boundary check.
// - The index of the first (eldest) item is 0.
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_at(
in EPTF_IntegerRingBuffer pl_buffer,
in integer pl_index,
out EPTF_RingBufferDataItem pl_dataItem
) return boolean
{
if (pl_index < 0 or pl_index >= f_EPTF_RB_size(pl_buffer))
{
return false;
}
pl_dataItem := f_EPTF_RB_get(pl_buffer, pl_index);
return true;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_RB_dump
//
// Purpose:
// Function to dump the content of the buffer into a list.
//
// Parameters:
// pl_buffer - *in* <EPTF_IntegerRingBuffer> - the ring buffer to be dumped
//
// pl_index - *out* <EPTF_RingBufferDataList> - the destination array
//
// Return Value:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_RB_dump( in EPTF_IntegerRingBuffer pl_buffer, out EPTF_RingBufferDataList pl_dest)
{
pl_dest:= {};
for (var integer i:=0; i<pl_buffer.status.content_size; i:= i+1)
{
pl_dest[i] := pl_buffer.data[(pl_buffer.status.head + i) mod pl_buffer.status.capacity];
}
}
} // end of module