diff options
author | Mike Jones <mjjones@us.ibm.com> | 2011-11-10 12:37:48 -0600 |
---|---|---|
committer | MIKE J. JONES <mjjones@us.ibm.com> | 2011-11-10 14:46:24 -0600 |
commit | 3038d54f6ca6a2ad945bc072aa34a2a64811829d (patch) | |
tree | 4b00ec7bb963efde3cdab04c7e855e2c964962b7 /src/usr/ecmddatabuffer | |
parent | bad2d60def0b66079eacb7ef7c11e2f0dd5420c0 (diff) | |
download | talos-hostboot-3038d54f6ca6a2ad945bc072aa34a2a64811829d.tar.gz talos-hostboot-3038d54f6ca6a2ad945bc072aa34a2a64811829d.zip |
Import ecmdDataBufferBase into HostBoot
Change-Id: I518319bcc06c4f89ee8000762f0e34e9e2af92c3
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/492
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Diffstat (limited to 'src/usr/ecmddatabuffer')
-rwxr-xr-x | src/usr/ecmddatabuffer/ecmdDataBuffer.C | 276 | ||||
-rw-r--r-- | src/usr/ecmddatabuffer/ecmdDataBufferBase.C | 2676 | ||||
-rw-r--r-- | src/usr/ecmddatabuffer/makefile | 7 |
3 files changed, 2682 insertions, 277 deletions
diff --git a/src/usr/ecmddatabuffer/ecmdDataBuffer.C b/src/usr/ecmddatabuffer/ecmdDataBuffer.C deleted file mode 100755 index 4b0323137..000000000 --- a/src/usr/ecmddatabuffer/ecmdDataBuffer.C +++ /dev/null @@ -1,276 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/ecmddatabuffer/ecmdDataBuffer.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -/** - * @file ecmdDataBuffer.C - * @brief Provides a means to handle data from the eCMD C API - * - ******************************************************************** - * @todo - This is only a temporary file created to compile code. - * We will use John Farrugia's version - ********************************************************************* - */ - -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include <stdint.h> -#include <string.h> -#include <trace/interface.H> -#include <ecmdDataBuffer.H> - -#define EDB_ADMIN_TOTAL_SIZE 2 -#define EDB_ADMIN_HEADER_SIZE 1 -#define EDB_ADMIN_FOOTER_SIZE 1 -#define EDB_ADMIN_TOTAL_SIZE 2 -#define EDB_RETURN_CODE 0 -#define EDB_RANDNUM 0x12345678 -#define ECMD_DBUF_BUFFER_OVERFLOW (ECMD_ERR_ECMD | 0x2011) - -// Trace definition -trace_desc_t* g_trac_ecmd = NULL; -TRAC_INIT(&g_trac_ecmd, "ECMD", 4096); - -//--------------------------------------------------------------------- -// Constructors -//--------------------------------------------------------------------- -ecmdDataBufferBase::ecmdDataBufferBase() // Default constructor -: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL) -{ - iv_UserOwned = true; -} - -ecmdDataBufferBase::ecmdDataBufferBase(uint32_t i_numBits) -: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL) -{ - iv_UserOwned = true; - if (i_numBits > 0) - { - setBitLength(i_numBits); - } -} - -//--------------------------------------------------------------------- -// Destructor -//--------------------------------------------------------------------- -ecmdDataBufferBase::~ecmdDataBufferBase() -{ - // Only call clear() if buffer is owned by this user (ie, not shared) - if (iv_UserOwned) - { - clear(); - } -} - -uint32_t ecmdDataBufferBase::getWordLength() const -{ - return (iv_NumBits + 31) / 32; -} - -uint32_t ecmdDataBufferBase::flushTo0() -{ - uint32_t rc = ECMD_DBUF_SUCCESS; - if (getWordLength() > 0) - { - memset(iv_Data, 0x00, getWordLength() * 4); /* init to 0 */ - } - return rc; -} - - -uint32_t ecmdDataBufferBase::clear() { - uint32_t rc = ECMD_DBUF_SUCCESS; - - if (iv_RealData != NULL) - { - /* That looked okay, reset everything else */ - /* Only do the delete if we alloc'd something */ - if (iv_RealData != iv_LocalData) - { - delete[] iv_RealData; - } - iv_RealData = NULL; - iv_Capacity = 0; - iv_NumBits = 0; - } - return rc; -} - -uint32_t ecmdDataBufferBase::setCapacity(uint32_t i_newCapacity) { - uint32_t rc = ECMD_DBUF_SUCCESS; - - if(!iv_UserOwned) { - TRACFCOMP(g_trac_ecmd, "**** ERROR (ecmdDataBuffer) : Attempt to modify non user owned buffer size."); - return 0; - } - - /* for case where i_newCapacity is 0 (like in unflatten) use iv_LocalData for iv_RealData */ - /* This allows for iv_Data, the header, and the tail to be setup right */ - if (iv_Capacity == 0) { - /* We are using iv_LocalData, so point iv_RealData to the start of that */ - iv_RealData = iv_LocalData; - } - - /* only resize to make the capacity bigger */ - if (iv_Capacity < i_newCapacity) { - iv_Capacity = i_newCapacity; - - /* Now setup iv_RealData */ - if (iv_Capacity <= 2) { - /* We are using iv_LocalData, so point iv_RealData to the start of that */ - iv_RealData = iv_LocalData; - } else { - /* If we are going from <= 64 to > 64, there was no malloc done so can't do delete */ - if ((iv_RealData != NULL) && (iv_RealData != iv_LocalData)) { - delete[] iv_RealData; - } - iv_RealData = NULL; - - iv_RealData = new uint32_t[iv_Capacity + EDB_ADMIN_TOTAL_SIZE]; - if (iv_RealData == NULL) { - TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setCapacity : Unable to allocate memory for new databuffer"); - return 0; - } - } - } - - /* Now setup iv_Data to point into the offset inside of iv_RealData */ - iv_Data = iv_RealData + EDB_ADMIN_HEADER_SIZE; - - /* We are all setup, now init everything to 0 */ - /* We want to do this regardless of if the buffer was resized. */ - /* This function is meant to be a destructive operation */ - /* Ok, now setup the header, and tail */ - iv_RealData[EDB_RETURN_CODE] = 0; ///< Reset error code - iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] = EDB_RANDNUM; - - rc = flushTo0(); - if (rc) return rc; - - return rc; -} - -uint32_t ecmdDataBufferBase::setBitLength(uint32_t i_newNumBits) { - uint32_t rc = ECMD_DBUF_SUCCESS; - - if ((i_newNumBits == 0) && (iv_NumBits == 0)) { - // Do Nothing: this data doesn't already have iv_RealData,iv_Data defined, and it doesn't want to define it - return rc; - } - - /* Assign i_newNumBits to iv_NumBits and figure out how many words that is */ - iv_NumBits = i_newNumBits; - - /* Now call setCapacity to do all the data buffer resizing and setup */ - rc = setCapacity(getWordLength()); - if (rc) return rc; - - return rc; -} - -uint32_t ecmdDataBufferBase::setDoubleWord(uint32_t i_doublewordoffset, uint64_t i_value) -{ - uint32_t rc = ECMD_DBUF_SUCCESS; - if (i_doublewordoffset >= ((getWordLength()+1)/2)) - { - TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)", - i_doublewordoffset, ((getWordLength()+1)/2)); - return (ECMD_DBUF_BUFFER_OVERFLOW); - } - - // Create mask if part of this byte is not in the valid part of the ecmdDataBuffer - if (((i_doublewordoffset + 1) == ((getWordLength()+1)/2)) && (iv_NumBits % 64)) - { - uint64_t bitMask = 0xFFFFFFFFFFFFFFFFul; - /* Shift it left by the amount of unused bits */ - bitMask <<= ((64 * ((getWordLength()+1)/2)) - iv_NumBits); - /* Clear the unused bits */ - i_value &= bitMask; - } - uint32_t hivalue = (uint32_t)((i_value & 0xFFFFFFFF00000000ul) >> 32); - uint32_t lovalue = (uint32_t)((i_value & 0x00000000FFFFFFFFul)); - - iv_Data[i_doublewordoffset*2] = hivalue; - /* Don't set the second word if we are on oddwords */ - if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) { - iv_Data[(i_doublewordoffset*2)+1] = lovalue; - } - return rc; -} - -uint64_t ecmdDataBufferBase::getDoubleWord(uint32_t i_doublewordoffset) const -{ - // Round up to the next word and check length - if (i_doublewordoffset >= ((getWordLength()+1)/2)) - { - TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::getDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)", - i_doublewordoffset, ((getWordLength()+1)/2)); - return 0; - } - uint64_t ret; - ret = ((uint64_t)(iv_Data[i_doublewordoffset*2])) << 32; - // If we have an odd length of words we can't pull the second word if we are at the end - if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) { - ret |= iv_Data[(i_doublewordoffset*2)+1]; - } - return ret; -} - -uint32_t ecmdDataBufferBase::setWord(uint32_t i_wordOffset, uint32_t i_value) -{ - uint32_t rc = ECMD_DBUF_SUCCESS; - - if (i_wordOffset >= getWordLength()) - { - TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setWord: wordoffset %d >= NumWords (%d)", i_wordOffset, getWordLength()); - return (ECMD_DBUF_BUFFER_OVERFLOW); - } - - // Create mask if part of this word is not in the valid part of the ecmdDataBuffer - if (((i_wordOffset + 1) == getWordLength()) && (iv_NumBits % 32)) - { - /* Create my mask */ - uint32_t bitMask = 0xFFFFFFFF; - /* Shift it left by the amount of unused bits */ - bitMask <<= ((32 * getWordLength()) - iv_NumBits); - /* Clear the unused bits */ - i_value &= bitMask; - } - - iv_Data[i_wordOffset] = i_value; - - return rc; -} - -uint32_t ecmdDataBufferBase::getWord(uint32_t i_wordOffset) const -{ - if (i_wordOffset >= getWordLength()) - { - TRACFCOMP(g_trac_ecmd,"**** ERROR : ecmdDataBuffer::getWord: i_wordOffset %d >= NumWords (%d)", - i_wordOffset, getWordLength()); - return 0; - } - - return this->iv_Data[i_wordOffset]; -} - - diff --git a/src/usr/ecmddatabuffer/ecmdDataBufferBase.C b/src/usr/ecmddatabuffer/ecmdDataBufferBase.C new file mode 100644 index 000000000..0ab6c2920 --- /dev/null +++ b/src/usr/ecmddatabuffer/ecmdDataBufferBase.C @@ -0,0 +1,2676 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/ecmddatabuffer/ecmdDataBufferBase.C $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +// IMPORTED FROM eCMD on 11/10/2011 + +// Copyright *********************************************************** +// +// File ecmdDataBufferBase.C +// +// IBM Confidential +// OCO Source Materials +// 9400 Licensed Internal Code +// (C) COPYRIGHT IBM CORP. 2002 +// +// The source code for this program is not published or otherwise +// divested of its trade secrets, irrespective of what has been +// deposited with the U.S. Copyright Office. +// +// End Copyright ******************************************************* + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- ----- ----------------------------- +// @01 STG4466 03/10/05 Prahl Fix up Beam errors +// End Change Log ***************************************************** + +// Get rid of some annoying lint errors that aren't real - cje +//lint -e613 Possible use of null pointer, lint doesn't understand we use iv_NumBits to check length and pointer validity +//lint -e668 Possible passing of a null pointer, same thing as above +//lint -e527 Lint doesn't understand that iv_UserOwned is changed in shareBuffer + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <ecmdDataBufferBase.H> +#include <prdfCompressBuffer.H> + +#ifndef __HOSTBOOT_MODULE +#include <ctype.h> +#include <fstream> +#include <iostream> +#include <zlib.h> +#include <netinet/in.h> +#else +#include <fapiUtil.H> +#include <fapiPlatTrace.H> +#define htonl(foo) (foo) +#define ntohl(foo) (foo) +#endif + +//---------------------------------------------------------------------- +// Global Variables +//---------------------------------------------------------------------- +#ifdef FIPSODE +tracDesc_t g_etrc; /** Trace Descriptor **/ +TRAC_INIT(&g_etrc, "ECMD", 0x1000); +#elif defined ZSERIES_SWITCH +#define TRACE_ID ECMDBUF +#endif + +//---------------------------------------------------------------------- +// Constants +//---------------------------------------------------------------------- +#define EDB_RANDNUM 0x12345678 +#define EDB_ADMIN_HEADER_SIZE 1 +#define EDB_ADMIN_FOOTER_SIZE 1 +// This define is the sum of EDB_ADMIN_HEADER_SIZE + EDB_ADMIN_FOOTER_SIZE +#define EDB_ADMIN_TOTAL_SIZE 2 +#define EDB_RETURN_CODE 0 + +// New Constants for improved performance +//#define MIN(x,y) (((x)<(y))?x:y) - Removed 7/23/08 because prdfCompressBuffer.H defines this function +#define UNIT_SZ 32 + +#define RETURN_ERROR(i_rc) if ((iv_RealData != NULL) && (iv_RealData[EDB_RETURN_CODE] == 0)) { iv_RealData[EDB_RETURN_CODE] = i_rc; } return i_rc; +#define SET_ERROR(i_rc) if ((iv_RealData != NULL) && (iv_RealData[EDB_RETURN_CODE] == 0)) { iv_RealData[EDB_RETURN_CODE] = i_rc; } + +//---------------------------------------------------------------------- +// Forward declarations +//---------------------------------------------------------------------- +uint32_t ecmdExtract(uint32_t *i_sourceData, uint32_t i_startBit, uint32_t i_numBitsToExtract, uint32_t *o_destData); +void * ecmdBigEndianMemCopy(void * dest, const void *src, size_t count); + +// new declaration here for performance improvement +// This function does NOT do input checks and does NOT handle xstate +inline uint32_t ecmdFastInsert(uint32_t *i_target, const uint32_t * i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart); + + +//---------------------------------------------------------------------- +// Inlined Functions used to improve Performance +//---------------------------------------------------------------------- +inline /* leave this inlined */ +uint32_t fast_mask32(int32_t i_pos, int32_t i_len) { + /* generates an arbitrary 32-bit mask using two + operations, not too shabby */ + + static const uint32_t l_mask32[] = { + 0x00000000, + 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, + 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, + 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, + 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, + 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, + 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, + 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, + 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF, + }; + return l_mask32[i_len] >> i_pos; +} + +inline /* leave this inlined */ +uint32_t fast_set32(uint32_t i_trg, int32_t i_pos, int32_t i_len) { + return fast_mask32(i_pos, i_len) | i_trg; +} + +inline /* leave this inlined */ +uint32_t fast_clear32(uint32_t i_trg, int32_t i_pos, int32_t i_len) { + return fast_mask32(i_pos, i_len) & ~i_trg; +} + +inline /* leave this inlined */ +uint8_t fast_reverse8(uint8_t data) { + static const uint8_t reverse8[] = { + 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0, + 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, + 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8, + 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, + 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4, + 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, + 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec, + 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, + 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2, + 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2, + 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea, + 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, + 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6, + 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, + 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee, + 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, + 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1, + 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, + 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9, + 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, + 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5, + 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, + 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed, + 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd, + 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3, + 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3, + 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb, + 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb, + 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7, + 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, + 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef, + 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff, + }; + return reverse8[data]; +} + +inline /* leave this inlined */ +uint32_t fast_reverse32(uint32_t data) { + return fast_reverse8((data & 0xFF000000) >> 24) | + fast_reverse8((data & 0x00FF0000) >> 16) << 8 | + fast_reverse8((data & 0x0000FF00) >> 8) << 16 | + fast_reverse8(data & 0x000000FF) << 24; +} + +//--------------------------------------------------------------------- +// Constructors +//--------------------------------------------------------------------- +ecmdDataBufferBase::ecmdDataBufferBase() // Default constructor +: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL) +{ + iv_UserOwned = true; + iv_BufferOptimizable = false; + +#ifndef REMOVE_SIM + iv_DataStr = NULL; + iv_XstateEnabled = false; +#endif +} + +ecmdDataBufferBase::ecmdDataBufferBase(uint32_t i_numBits) +: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL) +{ + iv_UserOwned = true; + iv_BufferOptimizable = false; + +#ifndef REMOVE_SIM + iv_DataStr = NULL; + iv_XstateEnabled = false; +#endif + + if (i_numBits > 0) { + setBitLength(i_numBits); + } +} + +ecmdDataBufferBase::ecmdDataBufferBase(const ecmdDataBufferBase& i_other) +: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL) +{ + iv_UserOwned = true; + iv_BufferOptimizable = false; + +#ifndef REMOVE_SIM + iv_DataStr = NULL; + iv_XstateEnabled = false; +#endif + + if (i_other.iv_NumBits != 0) { + + this->setBitLength(i_other.iv_NumBits); + // iv_Data + memcpy(iv_Data, i_other.iv_Data, getWordLength() * 4); + // Error state + iv_RealData[EDB_RETURN_CODE] = i_other.iv_RealData[EDB_RETURN_CODE]; + + } + /* else do nothing. already have an empty buffer */ + +} + +//--------------------------------------------------------------------- +// Destructor +//--------------------------------------------------------------------- +ecmdDataBufferBase::~ecmdDataBufferBase() +{ + // Only call clear() if buffer is owned by this user (ie, not shared) + if(iv_UserOwned) clear(); +} + +//--------------------------------------------------------------------- +// Public Member Function Specifications +//--------------------------------------------------------------------- +uint32_t ecmdDataBufferBase::clear() { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if(!iv_UserOwned) // If this buffer is shared + { + if (!isBufferOptimizable()) { // If the buffer is not optimizable, error + ETRAC0("**** ERROR (ecmdDataBufferBase) : Attempt to modify non user owned buffer size."); + RETURN_ERROR(ECMD_DBUF_NOT_OWNER); + } + else { // It's a shared/optimizable buffer, don't flag error + return ECMD_DBUF_SUCCESS; + } + } + + if (iv_RealData != NULL) { + + /* Let's check our header,footer info */ + if (iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] != EDB_RANDNUM) { + /* Ok, something is wrong here */ + ETRAC2("**** SEVERE ERROR (ecmdDataBufferBase) : iv_RealData[0]: %X, getWordLength(): %X",iv_RealData[EDB_RETURN_CODE],getWordLength()); + ETRAC1("**** SEVERE ERROR (ecmdDataBufferBase) : iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE]: %X",iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE]); + ETRAC0("**** SEVERE ERROR (ecmdDataBufferBase) : PROBLEM WITH DATABUFFER - INVALID HEADER/FOOTER"); +#ifdef __HOSTBOOT_MODULE + fapiAssert(false); +#else + abort(); +#endif + } + + /* That looked okay, reset everything else */ + /* Only do the delete if we alloc'd something */ + if (iv_RealData != iv_LocalData) { + delete[] iv_RealData; + } + iv_RealData = NULL; + iv_Capacity = 0; + iv_NumBits = 0; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::getDoubleWordLength() const { return (iv_NumBits + 63) / 64; } +uint32_t ecmdDataBufferBase::getWordLength() const { return (iv_NumBits + 31) / 32; } +uint32_t ecmdDataBufferBase::getHalfWordLength() const { return (iv_NumBits + 15) / 16; } +uint32_t ecmdDataBufferBase::getByteLength() const { return (iv_NumBits + 7) / 8; } +uint32_t ecmdDataBufferBase::getBitLength() const { return iv_NumBits; } +uint32_t ecmdDataBufferBase::getCapacity() const { return iv_Capacity; } + +uint32_t ecmdDataBufferBase::setDoubleWordLength(uint32_t i_newNumDoubleWords) { + return setBitLength(i_newNumDoubleWords * 64); +} + +uint32_t ecmdDataBufferBase::setWordLength(uint32_t i_newNumWords) { + return setBitLength(i_newNumWords * 32); +} + +uint32_t ecmdDataBufferBase::setHalfWordLength(uint32_t i_newNumHalfWords) { + return setBitLength(i_newNumHalfWords * 16); +} + +uint32_t ecmdDataBufferBase::setByteLength(uint32_t i_newNumBytes) { + return setBitLength(i_newNumBytes * 8); +} + +uint32_t ecmdDataBufferBase::setBitLength(uint32_t i_newNumBits) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if ((i_newNumBits == 0) && (iv_NumBits == 0)) { + // Do Nothing: this data doesn't already have iv_RealData,iv_Data defined, and it doesn't want to define it + return rc; + } + + /* Assign i_newNumBits to iv_NumBits and figure out how many words that is */ + iv_NumBits = i_newNumBits; + + /* Now call setCapacity to do all the data buffer resizing and setup */ + rc = setCapacity(getWordLength()); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::setCapacity(uint32_t i_newCapacity) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if(!iv_UserOwned) { + ETRAC0("**** ERROR (ecmdDataBufferBase) : Attempt to modify non user owned buffer size."); + RETURN_ERROR(ECMD_DBUF_NOT_OWNER); + } + + /* for case where i_newCapacity is 0 (like in unflatten) use iv_LocalData for iv_RealData */ + /* This allows for iv_Data, the header, and the tail to be setup right */ + if (iv_Capacity == 0) { + /* We are using iv_LocalData, so point iv_RealData to the start of that */ + iv_RealData = iv_LocalData; + } + + /* only resize to make the capacity bigger */ + if (iv_Capacity < i_newCapacity) { + iv_Capacity = i_newCapacity; + + /* Now setup iv_RealData */ + if (iv_Capacity <= 2) { + /* We are using iv_LocalData, so point iv_RealData to the start of that */ + iv_RealData = iv_LocalData; + } else { + /* If we are going from <= 64 to > 64, there was no malloc done so can't do delete */ + if ((iv_RealData != NULL) && (iv_RealData != iv_LocalData)) { + delete[] iv_RealData; + } + iv_RealData = NULL; + + iv_RealData = new uint32_t[iv_Capacity + EDB_ADMIN_TOTAL_SIZE]; + if (iv_RealData == NULL) { + ETRAC0("**** ERROR : ecmdDataBufferBase::setCapacity : Unable to allocate memory for new databuffer"); + RETURN_ERROR(ECMD_DBUF_INIT_FAIL); + } + } + + } + + /* Now setup iv_Data to point into the offset inside of iv_RealData */ + iv_Data = iv_RealData + EDB_ADMIN_HEADER_SIZE; + + /* We are all setup, now init everything to 0 */ + /* We want to do this regardless of if the buffer was resized. */ + /* This function is meant to be a destructive operation */ + /* Ok, now setup the header, and tail */ + iv_RealData[EDB_RETURN_CODE] = 0; ///< Reset error code + iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] = EDB_RANDNUM; + + rc = flushTo0(); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::shrinkBitLength(uint32_t i_newNumBits) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if(!iv_UserOwned) { + ETRAC0("**** ERROR (ecmdDataBufferBase::shrinkBitLength) : Attempt to modify non user owned buffer size."); + RETURN_ERROR(ECMD_DBUF_NOT_OWNER); + } + + if (i_newNumBits > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::shrinkBitLength: New Bit Length (%d) > current NumBits (%d)", i_newNumBits, iv_NumBits); + rc = ECMD_DBUF_BUFFER_OVERFLOW; + RETURN_ERROR(rc); + } + + /* If the length is the same, do nothing */ + if (i_newNumBits == iv_NumBits) { + return rc; + } + + // before shrinking, clear all data that is going to now be invalid + this->clearBit(i_newNumBits, (iv_NumBits-i_newNumBits)); + if (rc != ECMD_DBUF_SUCCESS) { + ETRAC3("**** ERROR : ecmdDataBufferBase::shrinkBitLength: Error Back from clearBit(%d, %d). rc=0x%x", i_newNumBits, (iv_NumBits-i_newNumBits), rc); + RETURN_ERROR(rc); + } + + iv_NumBits = i_newNumBits; + + /* Ok, now setup the header, and tail */ + iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] = EDB_RANDNUM; + + return rc; +} + +uint32_t ecmdDataBufferBase::growBitLength(uint32_t i_newNumBits) { + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t prevwordsize; + uint32_t prevbitsize; + + if(!iv_UserOwned) { + ETRAC0("**** ERROR (ecmdDataBufferBase::growBitLength) : Attempt to modify non user owned buffer size."); + RETURN_ERROR(ECMD_DBUF_NOT_OWNER); + } + + /* Maybe we don't need to do anything */ + if (iv_NumBits == i_newNumBits) { + return rc; + } else if (i_newNumBits < iv_NumBits) { + /* You can't grow smaller, use shrink */ + ETRAC0("**** ERROR (ecmdDataBufferBase::growBitLength) : Attempted to grow to a smaller size then current buffer size."); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); + } + + /* We need to verify we have room to do this shifting */ + /* Set our new length */ + prevwordsize = getWordLength(); + prevbitsize = iv_NumBits; + iv_NumBits = i_newNumBits; + if (getWordLength() > iv_Capacity) { + /* UhOh we are out of room, have to resize */ + uint32_t * tempBuf = new uint32_t[prevwordsize]; + if (tempBuf == NULL) { + ETRAC0("**** ERROR : ecmdDataBufferBase::growBitLength : Unable to allocate temp buffer"); + RETURN_ERROR(ECMD_DBUF_INIT_FAIL); + } + memcpy(tempBuf, iv_Data, prevwordsize * 4); + + /* Now resize with the new capacity */ + rc = setCapacity(getWordLength()); + if (rc) { + if (tempBuf) { + delete[] tempBuf; + } + return rc; + } + + /* Restore the data */ + ecmdBigEndianMemCopy(iv_Data, tempBuf, (prevbitsize + 7) / 8); + delete[] tempBuf; + + /* Clear any odd bits in the byte */ + for (uint32_t idx = prevbitsize; (idx < iv_NumBits) && (idx % 8); idx ++) { + clearBit(idx); + } + + } else if (prevwordsize < getWordLength()) { + /* We didn't have to grow the buffer capacity, but we did move into a new word(s) so clear that data space out */ + for (uint32_t idx = prevwordsize; idx < getWordLength(); idx++) { + memset(&iv_Data[idx], 0, 4); // Clear the word + } + } + + /* Only reset this stuff if things have changed */ + if (prevwordsize != getWordLength()) { + iv_RealData[EDB_RETURN_CODE] = 0; // error state + iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] = EDB_RANDNUM; + } + + return rc; +} + +bool ecmdDataBufferBase::getBit(uint32_t i_bit) const { + /* This just calls is bit set and returns that value */ + return this->isBitSet(i_bit); +} + + +uint32_t ecmdDataBufferBase::setBit(uint32_t i_bit) { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (i_bit >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setBit: bit %d >= NumBits (%d)", i_bit, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + int index = i_bit/32; + iv_Data[index] |= 0x00000001 << (31 - (i_bit-(index * 32))); + + return rc; +} + +uint32_t ecmdDataBufferBase::setBit(uint32_t i_bit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::setBit: bit %d + len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t idx = 0; idx < i_len; idx ++) { + rc |= this->setBit(i_bit + idx); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::writeBit(uint32_t i_bit, uint32_t i_value) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_value) { + rc = setBit(i_bit); + } else { + rc = clearBit(i_bit); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::setWord(uint32_t i_wordOffset, uint32_t i_value) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_wordOffset >= getWordLength()) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setWord: wordoffset %d >= NumWords (%d)", i_wordOffset, getWordLength()); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + // Create mask if part of this word is not in the valid part of the ecmdDataBufferBase + if (((i_wordOffset + 1) == getWordLength()) && (iv_NumBits % 32)) { + /* Create my mask */ + uint32_t bitMask = 0xFFFFFFFF; + /* Shift it left by the amount of unused bits */ + bitMask <<= ((32 * getWordLength()) - iv_NumBits); + /* Clear the unused bits */ + i_value &= bitMask; + } + + iv_Data[i_wordOffset] = i_value; + + return rc; +} + +uint32_t ecmdDataBufferBase::setByte(uint32_t i_byteOffset, uint8_t i_value) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_byteOffset >= getByteLength()) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setByte: byteOffset %d >= NumBytes (%d)", i_byteOffset, getByteLength()); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + // Create mask if part of this byte is not in the valid part of the ecmdDataBufferBase + if (((i_byteOffset + 1) == getByteLength()) && (iv_NumBits % 8)) { + /* Create my mask */ + uint8_t bitMask = 0xFF; + /* Shift it left by the amount of unused bits */ + bitMask <<= ((8 * getByteLength()) - iv_NumBits); + /* Clear the unused bits */ + i_value &= bitMask; + } + +#if defined (i386) + ((uint8_t*)(this->iv_Data))[i_byteOffset^3] = i_value; +#else + ((uint8_t*)(this->iv_Data))[i_byteOffset] = i_value; +#endif + + return rc; +} + +uint8_t ecmdDataBufferBase::getByte(uint32_t i_byteOffset) const { + if (i_byteOffset >= getByteLength()) { + ETRAC2("**** ERROR : ecmdDataBufferBase::getByte: byteOffset %d >= NumBytes (%d)", i_byteOffset, getByteLength()); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return 0; + } +#if defined (i386) + return ((uint8_t*)(this->iv_Data))[i_byteOffset^3]; +#else + return ((uint8_t*)(this->iv_Data))[i_byteOffset]; +#endif +} + + +uint32_t ecmdDataBufferBase::setHalfWord(uint32_t i_halfwordoffset, uint16_t i_value) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_halfwordoffset >= ((getByteLength()+1)/2)) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setHalfWord: halfWordOffset %d >= NumHalfWords (%d)", i_halfwordoffset, ((getByteLength()+1)/2)); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + // Create mask if part of this byte is not in the valid part of the ecmdDataBufferBase + if (((i_halfwordoffset + 1) == ((getByteLength()+1)/2)) && (iv_NumBits % 16)) { + /* Create my mask */ + uint16_t bitMask = 0xFFFF; + /* Shift it left by the amount of unused bits */ + bitMask <<= ((16 * ((getByteLength()+1)/2)) - iv_NumBits); + /* Clear the unused bits */ + i_value &= bitMask; + } + + uint32_t value32 = (uint32_t)i_value; + if (i_halfwordoffset % 2) { + iv_Data[i_halfwordoffset/2] = (iv_Data[i_halfwordoffset/2] & 0xFFFF0000) | (value32 & 0x0000FFFF); + } else { + iv_Data[i_halfwordoffset/2] = (iv_Data[i_halfwordoffset/2] & 0x0000FFFF) | ((value32 << 16) & 0xFFFF0000); + } + + return rc; +} + + +uint16_t ecmdDataBufferBase::getHalfWord(uint32_t i_halfwordoffset) const { + if (i_halfwordoffset >= ((getByteLength()+1)/2)) { + ETRAC2("**** ERROR : ecmdDataBufferBase::getHalfWord: halfWordOffset %d >= NumHalfWords (%d)", i_halfwordoffset, ((getByteLength()+1)/2)); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return 0; + } + uint16_t ret; + if (i_halfwordoffset % 2) + ret = (uint16_t)(iv_Data[i_halfwordoffset/2] & 0x0000FFFF); + else + ret = (uint16_t)(iv_Data[i_halfwordoffset/2] >> 16); + return ret; +} + +uint32_t ecmdDataBufferBase::setDoubleWord(uint32_t i_doublewordoffset, uint64_t i_value) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_doublewordoffset >= ((getWordLength()+1)/2)) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)" + , i_doublewordoffset, ((getWordLength()+1)/2)); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + // Create mask if part of this byte is not in the valid part of the ecmdDataBufferBase + if (((i_doublewordoffset + 1) == ((getWordLength()+1)/2)) && (iv_NumBits % 64)) { + /* Create my mask */ +#ifdef _LP64 + uint64_t bitMask = 0xFFFFFFFFFFFFFFFFul; +#else + uint64_t bitMask = 0xFFFFFFFFFFFFFFFFull; +#endif + /* Shift it left by the amount of unused bits */ + bitMask <<= ((64 * ((getWordLength()+1)/2)) - iv_NumBits); + /* Clear the unused bits */ + i_value &= bitMask; + } + +#ifdef _LP64 + uint32_t hivalue = (uint32_t)((i_value & 0xFFFFFFFF00000000ul) >> 32); + uint32_t lovalue = (uint32_t)((i_value & 0x00000000FFFFFFFFul)); +#else + uint32_t hivalue = (uint32_t)((i_value & 0xFFFFFFFF00000000ull) >> 32); + uint32_t lovalue = (uint32_t)((i_value & 0x00000000FFFFFFFFull)); +#endif + + iv_Data[i_doublewordoffset*2] = hivalue; + /* Don't set the second word if we are on oddwords */ + if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) { + iv_Data[(i_doublewordoffset*2)+1] = lovalue; + } + + return rc; +} + +uint64_t ecmdDataBufferBase::getDoubleWord(uint32_t i_doublewordoffset) const { + // Round up to the next word and check length + if (i_doublewordoffset >= ((getWordLength()+1)/2)) { + ETRAC2("**** ERROR : ecmdDataBufferBase::getDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)", + i_doublewordoffset, ((getWordLength()+1)/2)); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return 0; + } + uint64_t ret; + ret = ((uint64_t)(iv_Data[i_doublewordoffset*2])) << 32; + // If we have an odd length of words we can't pull the second word if we are at the end + if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) { + ret |= iv_Data[(i_doublewordoffset*2)+1]; + } + return ret; +} + +uint32_t ecmdDataBufferBase::clearBit(uint32_t i_bit) { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (i_bit >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::clearBit: bit %d >= NumBits (%d)", i_bit, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + int index = i_bit/32; + iv_Data[index] &= ~(0x00000001 << (31 - (i_bit-(index * 32)))); + + return rc; +} + +uint32_t ecmdDataBufferBase::clearBit(uint32_t i_bit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::clearBit: bit %d + len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t idx = 0; idx < i_len; idx ++) { + rc |= this->clearBit(i_bit + idx); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::flipBit(uint32_t i_bit) { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (i_bit >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::flipBit: bit %d >= NumBits (%d)", i_bit, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + if (this->isBitSet(i_bit)) { + rc = this->clearBit(i_bit); + } else { + rc = this->setBit(i_bit); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::flipBit(uint32_t i_bit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::flipBit: i_bit %d + i_len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i = 0; i < i_len; i++) { + this->flipBit(i_bit+i); + } + + return rc; +} + +bool ecmdDataBufferBase::isBitSet(uint32_t i_bit) const { + if (i_bit >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::isBitSet: i_bit %d >= NumBits (%d)", i_bit, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return false; + } + + uint32_t index = i_bit/32; + return (iv_Data[index] & 0x00000001 << (31 - (i_bit-(index * 32)))); +} + +bool ecmdDataBufferBase::isBitSet(uint32_t i_bit, uint32_t i_len) const { + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::isBitSet: i_bit %d + i_len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return false; + } + + bool rc = true; + for (uint32_t i = 0; i < i_len; i++) { + if (!this->isBitSet(i_bit + i)) { + rc = false; + break; + } + } + return rc; +} + +bool ecmdDataBufferBase::isBitClear(uint32_t i_bit) const { + if (i_bit >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::isBitClear: i_bit %d >= NumBits (%d)", i_bit, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return false; + } + + uint32_t index = i_bit/32; + return (!(iv_Data[index] & 0x00000001 << (31 - (i_bit-(index * 32))))); +} + +bool ecmdDataBufferBase::isBitClear(uint32_t i_bit, uint32_t i_len) const +{ + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::isBitClear: i_bit %d + i_len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return false; + } + + bool rc = true; + for (uint32_t i = 0; i < i_len; i++) { + if (!this->isBitClear(i_bit + i)) { + rc = false; + break; + } + } + + return rc; +} + +uint32_t ecmdDataBufferBase::getNumBitsSet(uint32_t i_bit, uint32_t i_len) const { + if (i_bit+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::getNumBitsSet: i_bit %d + i_len %d > NumBits (%d)", i_bit, i_len, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return 0; + } + static const uint8_t l_num_bits[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, + }; + + uint32_t count = 0; + + do { + const uint32_t * p_data = iv_Data + i_bit / UNIT_SZ; + int32_t slop = i_bit % UNIT_SZ; + + /* "cnt" = largest number of bits to be counted each pass */ + int32_t cnt = MIN(i_len, UNIT_SZ); + cnt = MIN(cnt, UNIT_SZ - slop); + + uint32_t bits = *p_data; + + /* "slop" = unaligned bits */ + if (slop || cnt < UNIT_SZ) + bits &= fast_mask32(slop, cnt); + + /* count the set bits in each byte */ + count += l_num_bits[(bits & 0x000000FF) >> 0]; + count += l_num_bits[(bits & 0x0000FF00) >> 8]; + count += l_num_bits[(bits & 0x00FF0000) >> 16]; + count += l_num_bits[(bits & 0xFF000000) >> 24]; + + i_bit += cnt; + i_len -= cnt; + } while (0 < i_len); + + return count; +} + +uint32_t ecmdDataBufferBase::shiftRight(uint32_t i_shiftNum, uint32_t i_offset) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* Error check */ + if (i_offset > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::shiftRight: i_offset %d > NumBits (%d)", i_offset, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + /* To shift the data, extact the piece being shifted and then re-insert it at the new location */ + ecmdDataBufferBase shiftData; + + // Get the hunk of data + rc = extract(shiftData, i_offset, (iv_NumBits - i_offset)); + if (rc) return rc; + + // Clear the hole that was opened + rc = clearBit(i_offset, i_shiftNum); + if (rc) return rc; + + // Stick the data back in + rc = insert(shiftData, (i_offset + i_shiftNum), (shiftData.getBitLength() - i_shiftNum)); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::shiftLeft(uint32_t i_shiftNum, uint32_t i_offset) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* If the offset is equal to 0xFFFFFFFF, take that to mean iv_NumBits, or the end of the buffer */ + if (i_offset == 0xFFFFFFFF) { + i_offset = iv_NumBits; + } + + /* Error check */ + if (i_offset > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::shiftLeft: i_offset %d > NumBits (%d)", i_offset, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + /* To shift the data, extact the piece being shifted and then re-insert it at the new location */ + ecmdDataBufferBase shiftData; + + // Get the hunk of data + rc = extract(shiftData, 0, i_offset); + if (rc) return rc; + + // Clear the hole that was opened + rc = clearBit((i_offset - i_shiftNum), i_shiftNum); + if (rc) return rc; + + // Stick the data back in + rc = insert(shiftData, 0, (shiftData.getBitLength() - i_shiftNum), i_shiftNum); + if (rc) return rc; + + return rc; +} + + +uint32_t ecmdDataBufferBase::shiftRightAndResize(uint32_t i_shiftNum, uint32_t i_offset) { + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t iv_NumBitsOrig = iv_NumBits; + + /* Make room in the data before we shift right */ + rc = growBitLength((iv_NumBitsOrig + i_shiftNum)); + if (rc) return rc; + + /* We have enough room, move our data over */ + rc = shiftRight(i_shiftNum, i_offset); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::shiftLeftAndResize(uint32_t i_shiftNum) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* Move our data over */ + rc = shiftLeft(i_shiftNum); + if (rc) return rc; + + /* Adjust our length based on the shift */ + rc = shrinkBitLength((iv_NumBits - i_shiftNum)); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::rotateRight(uint32_t i_rotateNum) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* The quickest way to rotate the data is to grab the two chunks and swap their position */ + ecmdDataBufferBase leftPart; + ecmdDataBufferBase rightPart; + + // Grab the two pieces + rc = extract(leftPart, 0, (iv_NumBits - i_rotateNum)); + if (rc) return rc; + + rc = extract(rightPart, (iv_NumBits - i_rotateNum), i_rotateNum); + if (rc) return rc; + + // Stick the two pieces back together in a different order + rc = insert(rightPart, 0, rightPart.getBitLength()); + if (rc) return rc; + + rc = insert(leftPart, rightPart.getBitLength(), leftPart.getBitLength()); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::rotateLeft(uint32_t i_rotateNum) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* The quickest way to rotate the data is to grab the two chunks and swap their position */ + ecmdDataBufferBase leftPart; + ecmdDataBufferBase rightPart; + + // Grab the two pieces + rc = extract(leftPart, 0, i_rotateNum); + if (rc) return rc; + + rc = extract(rightPart, i_rotateNum, (iv_NumBits - i_rotateNum)); + if (rc) return rc; + + // Stick the two pieces back together in a different order + rc = insert(rightPart, 0, rightPart.getBitLength()); + if (rc) return rc; + + rc = insert(leftPart, rightPart.getBitLength(), leftPart.getBitLength()); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::flushTo0() { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (getWordLength() > 0) { + memset(iv_Data, 0x00, getWordLength() * 4); /* init to 0 */ + } + return rc; +} + +uint32_t ecmdDataBufferBase::flushTo1() { + uint32_t rc = ECMD_DBUF_SUCCESS; + if (getWordLength() > 0) { + memset(iv_Data, 0xFF, getWordLength() * 4); /* init to 1 */ + + /* Call setword on the last word to mask off any extra bits past iv_NumBits */ + setWord((getWordLength()-1), 0xFFFFFFFF); + + } + return rc; +} + +uint32_t ecmdDataBufferBase::invert() { + uint32_t rc = ECMD_DBUF_SUCCESS; + rc = this->flipBit(0, iv_NumBits); + return rc; +} + +uint32_t ecmdDataBufferBase::reverse() { + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t l_words=0; + uint32_t l_slop = (iv_NumBits % UNIT_SZ); + + if (l_slop) + l_words = iv_NumBits/32+1; + else + l_words = iv_NumBits/32; + + // reverse words + for (uint32_t i=0;i< l_words/2;i++){ + uint32_t l_tmp = fast_reverse32(iv_Data[l_words-1-i]); + iv_Data[l_words-1-i] = fast_reverse32(iv_Data[i]); + iv_Data[i] = l_tmp; + } + + // if odd number of words, reverse middle word; if only 1 word, reverse this word + if (l_words&1){ + iv_Data[l_words/2 ] = fast_reverse32(iv_Data[l_words/2]); + } + + // now account for slop + if (l_slop != 0){ + + for (uint32_t i=0;i<l_words;i++){ // loop through all words + + if ((l_words>1)&&(i!=(l_words-1))){ // deal with most words here + uint32_t mask = 0xffffffff >> (32-l_slop); + uint32_t tmp1 = (iv_Data[i]& mask)<< (32-l_slop); + + mask =~mask; + uint32_t tmp2 = (iv_Data[i+1] & mask)>>l_slop; + + tmp1 |=tmp2; + iv_Data[i]=tmp1; + + } else { //dealing with the last word separately; Also, handle if there is only one word here + uint32_t mask = 0xffffffff >> (32-l_slop); + iv_Data[l_words-1] = (iv_Data[l_words-1]& mask) <<(32-l_slop); + } + } // end of for loop through all words + } // end of slop check + + return rc; +} + +uint32_t ecmdDataBufferBase::applyInversionMask(const ecmdDataBufferBase & i_invMaskBuffer, uint32_t i_invByteLen) { + return applyInversionMask(i_invMaskBuffer.iv_Data, (i_invMaskBuffer.getByteLength() < i_invByteLen) ? i_invMaskBuffer.getByteLength() : i_invByteLen); +} + + +uint32_t ecmdDataBufferBase::applyInversionMask(const uint32_t * i_invMask, uint32_t i_invByteLen) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + /* Do the smaller of data provided or size of buffer */ + uint32_t wordlen = (i_invByteLen / 4) + 1 < getWordLength() ? (i_invByteLen / 4) + 1 : getWordLength(); + + for (uint32_t i = 0; i < wordlen; i++) { + iv_Data[i] = iv_Data[i] ^ i_invMask[i]; /* Xor */ + } + + /* We need to make sure our last word is clean if numBits isn't on a word boundary */ + if ((wordlen == getWordLength()) && (iv_NumBits % 32)) { + /* Reading out the last word and writing it back will clear any bad bits on */ + uint32_t myWord = getWord((wordlen-1)); + rc = setWord((wordlen-1), myWord); + if (rc) return rc; + } + + return rc; +} + +inline uint32_t ecmdFastInsert(uint32_t *i_target, const uint32_t * i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + + uint32_t rc = ECMD_DBUF_SUCCESS; + + do { + const uint32_t * p_src = i_data + i_sourceStart / UNIT_SZ; + uint32_t * p_trg = i_target + i_targetStart / UNIT_SZ; + + // "slop" = unaligned bits + int32_t src_slop = i_sourceStart % UNIT_SZ; + int32_t trg_slop = i_targetStart % UNIT_SZ; + // "shift" = amount of shifting needed for target alignment + int32_t shift = trg_slop - src_slop; + + int32_t cnt = i_len; + + // "cnt" = largest number of bits to be moved each pass + cnt = MIN(cnt, UNIT_SZ); + cnt = MIN(cnt, UNIT_SZ - src_slop); + cnt = MIN(cnt, UNIT_SZ - trg_slop); + + // generate the source mask only once + uint32_t mask = fast_mask32(src_slop, cnt); + // read the source bits only once + uint32_t src_bits = *p_src & mask; + + // ideally (i << -1) would yield (i >> 1), but it + // doesn't, so we need an extra branch here + if (shift < 0) { + shift = -shift; + src_bits <<= shift; + mask <<= shift; + } else { + src_bits >>= shift; + mask >>= shift; + } + + // clear source '0' bits in the target + *p_trg &= ~mask; + // set source '1' bits in the target + *p_trg |= src_bits; + + + i_sourceStart += cnt; + i_targetStart += cnt; + + i_len -= cnt; + } while (0 < i_len); + + return rc; +} + + +uint32_t ecmdDataBufferBase::insert(const ecmdDataBufferBase &i_bufferIn, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_targetStart+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d + i_len %d > iv_NumBits (%d)", + i_targetStart, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_targetStart >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d >= iv_NumBits (%d)", + i_targetStart, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_len %d > iv_NumBits (%d)", + i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = ecmdFastInsert(this->iv_Data,i_bufferIn.iv_Data, i_targetStart, i_len, i_sourceStart ); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::insert(const uint32_t * i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_targetStart+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d + i_len %d > iv_NumBits (%d)", i_targetStart, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_targetStart >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d >= iv_NumBits (%d)", i_targetStart, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_len %d > iv_NumBits (%d)", i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = ecmdFastInsert(this->iv_Data,i_data, i_targetStart, i_len, i_sourceStart); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::insert(uint32_t i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if ( i_sourceStart + i_len > 32 ) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d + i_len %d > sizeof i_data (32)\n", i_sourceStart, i_len ); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_sourceStart >= 32) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d >= sizeof i_data (32)", i_sourceStart); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > 32) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_len %d > sizeof i_data (32)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks are perfomred in the insert function called below + + rc = this->insert(&i_data, i_targetStart, i_len, i_sourceStart); + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(const uint32_t * i_data, uint32_t i_start, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + int offset; + if((i_len % 32) == 0) { + offset = 0; + } else { + offset = 32 - (i_len % 32); + } + + if (i_start+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insertFromRight: start %d + len %d > iv_NumBits (%d)", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks happen below in setBit and clearBit + + uint32_t mask = 0x80000000 >> offset; + for (uint32_t i = 0; i < i_len; i++) { + if (i_data[(i+offset)/32] & mask) { + rc = this->setBit(i_start+i); + } + else { + rc = this->clearBit(i_start+i); + } + + mask >>= 1; + if (mask == 0x00000000) { + mask = 0x80000000; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(uint32_t i_data, uint32_t i_start, uint32_t i_len) { + + if (i_len > 32) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insertFromRight: i_len %d > sizeof i_data (32)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + // other input checks are perfomred in the insertFromRight function called below + } + + return this->insertFromRight(&i_data, i_start, i_len); +} + +uint32_t ecmdDataBufferBase::insert(const uint16_t * i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_targetStart+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d + i_len %d > iv_NumBits (%d)", i_targetStart, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_targetStart >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d >= iv_NumBits (%d)", i_targetStart, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_len %d > iv_NumBits (%d)", i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i = 0; i < i_len; i++) { + + int index = (i + i_sourceStart) / 16; + if (i_data[index] & 0x00000001 << (15-(i+i_sourceStart -(index*16)))) { + rc = this->setBit(i_targetStart + i); + } else { + rc = this->clearBit(i_targetStart + i); + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::insert(uint16_t i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if ( i_sourceStart + i_len > 16) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d + i_len %d > sizeof i_data (16)\n", i_sourceStart, i_len ); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_sourceStart >= 16) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d >= sizeof i_data (16)", i_sourceStart); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > 16) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_len %d > sizeof i_data (16)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks are perfomred in the insert function called below + + rc = this->insert(&i_data, i_targetStart, i_len, i_sourceStart); + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(const uint16_t * i_data, uint32_t i_start, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_start+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insertFromRight: start %d + len %d > iv_NumBits (%d)", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks happen below in setBit and clearBit + + int offset; + if ((i_len % 16) == 0) { + offset = 0; + } else { + offset = 16 - (i_len % 16); + } + + uint16_t mask = 0x8000 >> offset; + for (uint32_t i = 0; i < i_len; i++) { + if (i_data[(i+offset)/16] & mask) { + rc = this->setBit(i_start+i); + } + else { + rc = this->clearBit(i_start+i); + } + + mask >>= 1; + if (mask == 0x0000) { + mask = 0x8000; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(uint16_t i_data, uint32_t i_start, uint32_t i_len) { + + if (i_len > 16) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insertFromRight: i_len %d > sizeof i_data (16)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + // other input checks are perfomred in the insertFromRight function called below + } + + return this->insertFromRight(&i_data, i_start, i_len); +} + +uint32_t ecmdDataBufferBase::insert(const uint8_t *i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_targetStart+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insert: i_targetStart %d + i_len %d > iv_NumBits (%d)", i_targetStart, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + // other input checks are perfomred in the setBit(), clearBit() functions called below + } + + for (uint32_t i = 0; i < i_len; i++) { + + int index = (i + i_sourceStart) / 8; + if (i_data[index] & 0x00000001 << (7-(i+i_sourceStart -(index*8)))) { + rc = this->setBit(i_targetStart + i); + } else { + rc = this->clearBit(i_targetStart + i); + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::insert(uint8_t i_data, uint32_t i_targetStart, uint32_t i_len, uint32_t i_sourceStart) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if ( i_sourceStart + i_len > 8) { + ETRAC2("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d + i_len %d > sizeof i_data (8)\n", i_sourceStart, i_len ); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_sourceStart >= 8) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_sourceStart %d >= sizeof i_data (8)", i_sourceStart); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > 8) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insert: i_len %d > sizeof i_data (8)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks are perfomred in the insert function called below + + rc = this->insert(&i_data, i_targetStart, i_len, i_sourceStart); + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(const uint8_t *i_data, uint32_t i_start, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + int offset; + if((i_len % 8) == 0) { + offset = 0; + } else { + offset = 8 - (i_len % 8); + } + + if (i_start+i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::insertFromRight: start %d + len %d > iv_NumBits (%d)", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks happen below in setBit and clearBit + + uint8_t mask = 0x80 >> offset; + for (uint32_t i = 0; i < i_len; i++) { + if (i_data[(i+offset)/8] & mask) { + rc = this->setBit(i_start+i); + } + else { + rc = this->clearBit(i_start+i); + } + + mask >>= 1; + if (mask == 0x00) { + mask = 0x80; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::insertFromRight(uint8_t i_data, uint32_t i_start, uint32_t i_len) { + + if (i_len > 8) { + ETRAC1("**** ERROR : ecmdDataBufferBase::insertFromRight: i_len %d > sizeof i_data (8)", i_len); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + // other input checks are perfomred in the insertFromRight function called below + } + + return this->insertFromRight(&i_data, i_start, i_len); +} + +uint32_t ecmdDataBufferBase::extract(ecmdDataBufferBase& o_bufferOut, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // ecmdExtract can't make good input checks, so we have to do that here + if (i_start + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::extract: start %d + len %d > iv_NumBits (%d)\n", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_start >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: start %d >= iv_NumBits (%d)\n", i_start, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: len %d > iv_NumBits (%d)\n", i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = o_bufferOut.setBitLength(i_len); + if (rc) return rc; + + rc = ecmdExtract(this->iv_Data, i_start, i_len, o_bufferOut.iv_Data); + if (rc) return rc; + + return rc; +} + +uint32_t ecmdDataBufferBase::extract(uint32_t *o_data, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // ecmdExtract can't make good input checks, so we have to do that here + if (i_start + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::extract: i_start %d + i_len %d > iv_NumBits (%d)\n", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_start >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_start %d >= iv_NumBits (%d)", i_start, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_len %d > iv_NumBits (%d)", i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len == 0) { + return ECMD_DBUF_SUCCESS; + } + + rc = ecmdExtract(this->iv_Data, i_start, i_len, o_data); + if (rc) { + RETURN_ERROR(rc); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::extract(uint16_t *o_data, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // ecmdExtract can't make good input checks, so we have to do that here + if (i_start + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::extract: i_start %d + i_len %d > iv_NumBits (%d)\n", i_start, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_start >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_start %d >= iv_NumBits (%d)", i_start, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_len %d > iv_NumBits (%d)", i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_len == 0) { + return ECMD_DBUF_SUCCESS; + } + + // Put the users data into a temporary buffer, which will align it on byte boundaries. + // Then just loop over the extractBuffer, placing it byte by byte into o_data + ecmdDataBufferBase extractBuffer(i_len); + rc = extractBuffer.insert(*this, 0, i_len, i_start); + if (rc) { + RETURN_ERROR(rc); + } + + // Now do a byte loop, setting the data in o_data + int numHalfWords = extractBuffer.getHalfWordLength(); + for (int i = 0; i < numHalfWords; i++) { + o_data[i] = extractBuffer.getHalfWord(i); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::extract(uint8_t * o_data, uint32_t i_start, uint32_t i_bitLen) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // Error checking + if (i_start + i_bitLen > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::extract: i_start %d + i_bitLen %d > iv_NumBits (%d)\n", i_start, i_bitLen, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_start >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_start %d >= iv_NumBits (%d)", i_start, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_bitLen > iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::extract: i_bitLen %d > iv_NumBits (%d)", i_bitLen, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_bitLen == 0) { + return ECMD_DBUF_SUCCESS; + } + + // Put the users data into a temporary buffer, which will align it on byte boundaries. + // Then just loop over the extractBuffer, placing it byte by byte into o_data + ecmdDataBufferBase extractBuffer(i_bitLen); + rc = extractBuffer.insert(*this, 0, i_bitLen, i_start); + if (rc) { + RETURN_ERROR(rc); + } + + // Now do a byte loop, setting the data in o_data + int numBytes = extractBuffer.getByteLength(); + for (int i = 0; i < numBytes; i++) { + o_data[i] = extractBuffer.getByte(i); + } + + return rc; +} + + +// extractPreserve() takes data from current and inserts it in the passed in +// buffer at a given offset. This is the same as insert() with the args and +// the data flow reversed, so insert() is called to do the work +uint32_t ecmdDataBufferBase::extractPreserve(ecmdDataBufferBase & o_bufferOut, uint32_t i_start, uint32_t i_len, uint32_t i_targetStart) const { + // input checks done in the insert function + return o_bufferOut.insert( *this, i_targetStart, i_len, i_start ); +} + +// extractPreserve() with a generic data buffer is hard to work on, so the +// output buffer is first copied into an ecmdDataBufferBase object, then insert() +// is called to do the work +uint32_t ecmdDataBufferBase::extractPreserve(uint32_t *o_outBuffer, uint32_t i_start, uint32_t i_len, uint32_t i_targetStart) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + // input checks done in the insert function + + const uint32_t numWords = ( i_targetStart + i_len + 31 ) / 32; + if ( numWords == 0 ) return rc; + + ecmdDataBufferBase *tempBuf = new ecmdDataBufferBase; + + if ( NULL == tempBuf ) { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : Unable to allocate memory for new databuffer\n"); + RETURN_ERROR(ECMD_DBUF_INIT_FAIL); + } + + if(o_outBuffer == NULL) + { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : o_outBuffer of type uint32_t * is not initialized. NULL buffer passed."); + delete tempBuf; + tempBuf = NULL; + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = tempBuf->setWordLength( numWords ); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyIn( o_outBuffer, numWords * 4); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->insert( *this, i_targetStart, i_len, i_start); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyOut( o_outBuffer, numWords * 4); + + delete tempBuf; + return rc; +} + +// extractPreserve() with a generic data buffer is hard to work on, so the +// output buffer is first copied into an ecmdDataBufferBase object, then insert() +// is called to do the work +uint32_t ecmdDataBufferBase::extractPreserve(uint16_t *o_outBuffer, uint32_t i_start, uint32_t i_len, uint32_t i_targetStart) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + // input checks done in the insert function + + const uint32_t numHalfWords = ( i_targetStart + i_len + 15 ) / 16; + if ( numHalfWords == 0 ) return rc; + + ecmdDataBufferBase *tempBuf = new ecmdDataBufferBase; + + if ( NULL == tempBuf ) { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : Unable to allocate memory for new databuffer\n"); + RETURN_ERROR(ECMD_DBUF_INIT_FAIL); + } + + if(o_outBuffer == NULL) + { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : o_outBuffer of type uint16_t * is not initialized. NULL buffer passed."); + delete tempBuf; + tempBuf = NULL; + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = tempBuf->setHalfWordLength(numHalfWords); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyIn( o_outBuffer, numHalfWords * 2); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->insert( *this, i_targetStart, i_len, i_start); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyOut( o_outBuffer, numHalfWords * 2); + + delete tempBuf; + return rc; +} + +uint32_t ecmdDataBufferBase::extractPreserve(uint8_t * o_data, uint32_t i_start, uint32_t i_len, uint32_t i_targetStart) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + // input checks done in the insert function + + const uint32_t numBytes = ( i_targetStart + i_len + 7 ) / 8; + if ( numBytes == 0 ) return rc; + + ecmdDataBufferBase *tempBuf = new ecmdDataBufferBase; + + if ( NULL == tempBuf ) { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : Unable to allocate memory for new databuffer\n"); + RETURN_ERROR(ECMD_DBUF_INIT_FAIL); + } + + if(o_data == NULL) + { + ETRAC0("**** ERROR : ecmdDataBufferBase::extractPreserve : o_data of type uint8_t * is not initialized. NULL buffer passed."); + delete tempBuf; + tempBuf = NULL; + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = tempBuf->setByteLength( numBytes ); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyIn( o_data, numBytes); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->insert( *this, i_targetStart, i_len, i_start); + + if ( rc == ECMD_DBUF_SUCCESS ) + rc = tempBuf->memCopyOut( o_data, numBytes); + + delete tempBuf; + return rc; +} + +uint32_t ecmdDataBufferBase::extractToRight(ecmdDataBufferBase & o_bufferOut, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // input checks done in the extract function + rc = this->extract(o_bufferOut, i_start, i_len); + if (rc) return rc; + + if (i_len < 32) + rc = o_bufferOut.shiftRightAndResize(32 - i_len); + return rc; +} + +uint32_t ecmdDataBufferBase::extractToRight(uint32_t * o_data, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // input checks done in the extract function + rc = this->extract(o_data, i_start, i_len); + + if (i_len < 32) + *o_data >>= (32 - i_len); + return rc; +} + +uint32_t ecmdDataBufferBase::extractToRight(uint16_t * o_data, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + // input checks done in the extract function + rc = this->extract(o_data, i_start, i_len); + + if (i_len < 16) { + *o_data >>= (16 - i_len); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::extractToRight(uint8_t * o_data, uint32_t i_start, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + // input checks done in the extract function + rc = this->extract(o_data, i_start, i_len); + + if (i_len < 8) + *o_data >>= (8 - i_len); + return rc; +} + +uint32_t ecmdDataBufferBase::concat(const ecmdDataBufferBase & i_buf0, const ecmdDataBufferBase & i_buf1) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + rc = this->setBitLength(i_buf0.iv_NumBits + i_buf1.iv_NumBits); if (rc) return rc; + rc = this->insert(i_buf0, 0, i_buf0.iv_NumBits); if (rc) return rc; + rc = this->insert(i_buf1, i_buf0.iv_NumBits, i_buf1.iv_NumBits); + return rc; +} + +uint32_t ecmdDataBufferBase::concat(const std::vector<ecmdDataBufferBase> & i_bufs) { + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t totalSize = 0, offset = 0, x; + /* Loop through and get the total bit size and set length */ + for (x = 0; x < i_bufs.size(); x++) { + totalSize += i_bufs[x].iv_NumBits; + } + rc = this->setBitLength(totalSize); if (rc) return rc; + + /* Now that the size is set, loop through and insert */ + for (x = 0; x < i_bufs.size(); x++) { + rc = this->insert(i_bufs[x], offset, i_bufs[x].iv_NumBits); if (rc) return rc; + offset += i_bufs[x].iv_NumBits; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::setOr(const ecmdDataBufferBase& i_bufferIn, uint32_t i_startBit, uint32_t i_len) { + if (i_len > i_bufferIn.iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setOr: len %d > NumBits of incoming buffer (%d)", i_len, i_bufferIn.iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + return this->setOr(i_bufferIn.iv_Data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::setOr(const uint32_t * i_data, uint32_t i_startBit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_startBit + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::setOr: bit %d + len %d > NumBits (%d)", i_startBit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks done as part of setBit() + + uint32_t mask = 0x80000000; + for (uint32_t i = 0; i < i_len; i++) { + if (i_data[i/32] & mask) { + rc = this->setBit(i_startBit + i); + } + mask >>= 1; + if (mask == 0x00000000) { + mask = 0x80000000; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::setOr(uint32_t i_data, uint32_t i_startBit, uint32_t i_len) { + // input checks done as part of setOr() + return this->setOr(&i_data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::setXor(const ecmdDataBufferBase& i_bufferIn, uint32_t i_startBit, uint32_t i_len) { + if (i_len > i_bufferIn.iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setXor: len %d > NumBits of incoming buffer (%d)", i_len, i_bufferIn.iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks done as part of setXor() + return this->setXor(i_bufferIn.iv_Data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::setXor(const uint32_t * i_data, uint32_t i_startBit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_startBit + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::setOr: bit %d + len %d > NumBits (%d)", i_startBit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks done as part of writeBit() + + uint32_t mask = 0x80000000; + for (uint32_t i = 0; i < i_len; i++) { + rc = this->writeBit(i_startBit + i, ((i_data[i/32] & mask) ^ (this->iv_Data[i/32] & mask))); + mask >>= 1; + if (mask == 0x00000000) { + mask = 0x80000000; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::setXor(uint32_t i_data, uint32_t i_startBit, uint32_t i_len) { + // input checks done as part of setXor() + return this->setXor(&i_data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::merge(const ecmdDataBufferBase& i_bufferIn) { + if (iv_NumBits != i_bufferIn.iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::merge: NumBits in (%d) do not match NumBits (%d)", i_bufferIn.iv_NumBits, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else { + return this->setOr(i_bufferIn, 0, iv_NumBits); + } +} + +uint32_t ecmdDataBufferBase::setAnd(const ecmdDataBufferBase& i_bufferIn, uint32_t i_startBit, uint32_t i_len) { + if (i_len > i_bufferIn.iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::setAnd: len %d > NumBits of incoming buffer (%d)", i_len, i_bufferIn.iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + // other input checks done as part of setAnd() + return this->setAnd(i_bufferIn.iv_Data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::setAnd(const uint32_t * i_data, uint32_t i_startBit, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_startBit + i_len > iv_NumBits) { + ETRAC3("**** ERROR : ecmdDataBufferBase::setAnd: i_start %d + i_len %d > iv_NumBits (%d)", i_startBit, i_len, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + // other input checks done as part of setClearBit() + } + + uint32_t mask = 0x80000000; + for (uint32_t i = 0; i < i_len; i++) { + if (!(i_data[i/32] & mask)) { + this->clearBit(i_startBit + i); + } + mask >>= 1; + if (mask == 0x00000000) { + mask = 0x80000000; + } + if (rc) break; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::setAnd(uint32_t i_data, uint32_t i_startBit, uint32_t i_len) { + // input checks done as part of setAnd() + return this->setAnd(&i_data, i_startBit, i_len); +} + +uint32_t ecmdDataBufferBase::oddParity(uint32_t i_start, uint32_t i_stop) const { + int charOffset; + int posOffset; + uint32_t counter; + int parity = 1; + uint32_t mask; + + if (i_start >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::oddParity: i_start %d >= iv_NumBits (%d)\n", i_start, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_stop >= iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::oddParity: i_stop %d >= iv_NumBits (%d)\n", i_stop, iv_NumBits); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (i_start > i_stop) { + ETRAC2("**** ERROR : ecmdDataBufferBase::oddParity: i_start %d >= i_stop (%d)\n", i_start, i_stop); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else { + + charOffset = i_start / 32; + posOffset = i_start - charOffset * 32; + mask = 0x80000000 >> posOffset; + + for (counter = 0; counter < (i_stop - i_start + 1); counter++) { + if (mask & iv_Data[charOffset]) { + parity ^= 1; + } + posOffset++; + mask >>= 1; + if (posOffset > 31) { + charOffset++; + posOffset = 0; + mask = 0x80000000; + } + } + + } + + return parity; +} + +uint32_t ecmdDataBufferBase::evenParity(uint32_t i_start, uint32_t i_stop) const { + // input checks done as part of oddParity() + if (this->oddParity(i_start, i_stop)) { + return 0; + } else { + return 1; + } +} + +uint32_t ecmdDataBufferBase::oddParity(uint32_t i_start, uint32_t i_stop, uint32_t i_insertPos) { + // input checks done as part of oddParity() + if (this->oddParity(i_start,i_stop)) { + this->setBit(i_insertPos); + } else { + this->clearBit(i_insertPos); + } + + return 0; +} + +uint32_t ecmdDataBufferBase::evenParity(uint32_t i_start, uint32_t i_stop, uint32_t i_insertPos) { + // input checks done as part of evenParity()...which calls oddParity + if (this->evenParity(i_start,i_stop)) { + this->setBit(i_insertPos); + } else { + this->clearBit(i_insertPos); + } + + return 0; +} + +uint32_t ecmdDataBufferBase::getWord(uint32_t i_wordOffset) const { + if (i_wordOffset >= getWordLength()) { + ETRAC2("**** ERROR : ecmdDataBufferBase::getWord: i_wordOffset %d >= NumWords (%d)", i_wordOffset, getWordLength()); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + return 0; + } + + return this->iv_Data[i_wordOffset]; +} + +uint32_t ecmdDataBufferBase::copy(ecmdDataBufferBase &o_newCopy) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + rc = o_newCopy.setBitLength(iv_NumBits); + + if (!rc && iv_NumBits != 0) { + // iv_Data + memcpy(o_newCopy.iv_Data, iv_Data, getWordLength() * 4); + // Error state + o_newCopy.iv_RealData[EDB_RETURN_CODE] = iv_RealData[EDB_RETURN_CODE]; + } + return rc; + +} + +/* Copy Constructor */ +ecmdDataBufferBase& ecmdDataBufferBase::operator=(const ecmdDataBufferBase & i_master) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + rc = setBitLength(i_master.iv_NumBits); + + if (!rc && iv_NumBits != 0) { + // iv_Data + memcpy(iv_Data, i_master.iv_Data, getWordLength() * 4); + // Error state + iv_RealData[EDB_RETURN_CODE] = i_master.iv_RealData[EDB_RETURN_CODE]; + } + return *this; +} + + +uint32_t ecmdDataBufferBase::memCopyIn(const uint32_t* i_buf, uint32_t i_bytes) { /* Does a memcpy from supplied buffer into ecmdDataBufferBase */ + uint32_t rc = ECMD_DBUF_SUCCESS; + + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyIn: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + ecmdBigEndianMemCopy(iv_Data, i_buf, cbytes); + + /* We're worried we might have data on in our last byte copied in that excedes numbits */ + if (cbytes == getByteLength()) { + /* We'll cheat and do a getByte and then write that value back so the masking logic is done */ + uint8_t myByte = getByte((getByteLength() - 1)); + rc = setByte((getByteLength() - 1), myByte); + if (rc) return rc; + } + + return rc; +} + +uint32_t ecmdDataBufferBase::memCopyOut(uint32_t* o_buf, uint32_t i_bytes) const { /* Does a memcpy from ecmdDataBufferBase into supplied buffer */ + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyOut: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + ecmdBigEndianMemCopy(o_buf, iv_Data, cbytes); + + return rc; +} + +uint32_t ecmdDataBufferBase::memCopyIn(const uint16_t* i_buf, uint32_t i_bytes) { /* Does a memcpy from supplied buffer into ecmdDataBufferBase */ + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + uint32_t numHalfWords = (cbytes + 1) / 2; + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyIn: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i = 0; i < numHalfWords; i++) { + setHalfWord(i, i_buf[i]); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::memCopyOut(uint16_t* o_buf, uint32_t i_bytes) const { /* Does a memcpy from ecmdDataBufferBase into supplied buffer */ + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + uint32_t numHalfWords = (cbytes + 1) / 2; + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyOut: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i = 0; i < numHalfWords; i++) { + o_buf[i] = getHalfWord(i); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::memCopyIn(const uint8_t* i_buf, uint32_t i_bytes) { /* Does a memcpy from supplied buffer into ecmdDataBufferBase */ + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyIn: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i=0; i<cbytes; i++) { + setByte(i, i_buf[i]); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::memCopyOut(uint8_t* o_buf, uint32_t i_bytes) const { /* Does a memcpy from supplied buffer into ecmdDataBufferBase */ + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t cbytes = i_bytes < getByteLength() ? i_bytes : getByteLength(); + if (cbytes == 0) { + ETRAC0("**** ERROR : ecmdDataBufferBase: memCopyIn: Copy performed on buffer with length of 0"); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + for (uint32_t i=0; i<cbytes; i++) { + o_buf[i] = getByte(i); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::flatten(uint8_t * o_data, uint32_t i_len) const { + uint32_t rc = ECMD_DBUF_SUCCESS; + + uint32_t * o_ptr = (uint32_t *) o_data; + + if ((i_len < 8) || (iv_Capacity*32 > ((i_len - 8) * 8))) { + ETRAC2("**** ERROR : ecmdDataBufferBase::flatten: i_len %d bytes is too small to flatten a capacity of %d words ", i_len, iv_Capacity); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + memset(o_data, 0, this->flattenSize()); + o_ptr[0] = htonl(iv_Capacity*32); + o_ptr[1] = htonl(iv_NumBits); + if (iv_Capacity > 0) { + for (uint32_t i = 0; i < iv_Capacity; i++) + o_ptr[2+i] = htonl(iv_Data[i]); + } + + return rc; +} + +uint32_t ecmdDataBufferBase::unflatten(const uint8_t * i_data, uint32_t i_len) { + uint32_t rc = ECMD_DBUF_SUCCESS; + + uint32_t newCapacity; + uint32_t newBitLength; + uint32_t * i_ptr = (uint32_t *) i_data; + uint32_t newWordLength; + + newCapacity = (ntohl(i_ptr[0]) + 31) / 32; + newBitLength = ntohl(i_ptr[1]); + + if ((i_len < 8) || (newCapacity > ((i_len - 8) * 8))) { + ETRAC2("**** ERROR : ecmdDataBufferBase::unflatten: i_len %d bytes is too small to unflatten a capacity of %d words ", i_len, newCapacity); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else if (newBitLength > newCapacity * 32) { + ETRAC2("**** ERROR : ecmdDataBufferBase::unflatten: iv_NumBits %d cannot be greater than iv_Capacity*32 %d", newBitLength, newCapacity*32); + RETURN_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } + + rc = this->setCapacity(newCapacity); + if (rc != ECMD_DBUF_SUCCESS) { + ETRAC2("**** ERROR : ecmdDataBufferBase::unflatten: this->setCapacity() Failed. rc=0x%08x, newCapacity = %d words ", rc, newCapacity); + RETURN_ERROR(rc); + } + + rc = this->setBitLength(newBitLength); + if (rc != ECMD_DBUF_SUCCESS) { + ETRAC2("**** ERROR : ecmdDataBufferBase::unflatten: this->setBitLength() Failed. rc=0x%08x, newBitLength = %d bits ", rc, newBitLength); + RETURN_ERROR(rc); + } + + newWordLength = getWordLength(); + if (newCapacity > 0) { + for (uint32_t i = 0; i < newWordLength ; i++) { + rc = setWord(i, ntohl(i_ptr[i+2])); + if (rc != ECMD_DBUF_SUCCESS) { + ETRAC5("**** ERROR : ecmdDataBufferBase::unflatten: this->setWord() Failed. rc=0x%08x newBitLength = %d bits, newWordLength= %d words, newCapacity = %d words, loop parm i = %d ", rc, newBitLength, newWordLength, newCapacity, i); + RETURN_ERROR(rc); + } + } + } + + return rc; +} + +uint32_t ecmdDataBufferBase::flattenSize() const { + return (iv_Capacity + 2) * 4; +} + + +int ecmdDataBufferBase::operator == (const ecmdDataBufferBase& i_other) const { + + /* Check the length */ + uint32_t maxBits = 32; + uint32_t numBits = getBitLength(); + uint32_t numToFetch = numBits < maxBits ? numBits : maxBits; + uint32_t myData, otherData; + uint32_t wordCounter = 0; + + if (getBitLength() != i_other.getBitLength()) { + return 0; + } + + if (getBitLength() == 0) /* two empty buffers are equal */ + return 1; + + /* Now run through the data */ + while (numToFetch > 0) { + + myData = iv_Data[wordCounter]; + otherData = i_other.iv_Data[wordCounter]; + + if (numToFetch == maxBits) { + if (myData != otherData) + return 0; + } + else { + uint32_t mask = 0x80000000; + for (uint32_t i = 0; i < numToFetch; i++, mask >>= 1) { + if ( (myData & mask) != (otherData & mask) ) { + return 0; + } + } + } + + numBits -= numToFetch; + numToFetch = (numBits < maxBits) ? numBits : maxBits; + wordCounter++; + } + + /* Must have matched */ + return 1; +} + +int ecmdDataBufferBase::operator != (const ecmdDataBufferBase& i_other) const { + return !(*this == i_other); +} + +ecmdDataBufferBase ecmdDataBufferBase::operator & (const ecmdDataBufferBase& i_other) const { + + ecmdDataBufferBase newItem = *this; + + if (iv_NumBits != i_other.iv_NumBits) { + ETRAC2("**** ERROR : ecmdDataBufferBase::operater &: NumBits in (%d) do not match NumBits (%d)", i_other.iv_NumBits, iv_NumBits); + SET_ERROR(ECMD_DBUF_BUFFER_OVERFLOW); + } else { + newItem.setAnd(i_other.iv_Data, 0, iv_NumBits); + } + + return newItem; +} + +ecmdDataBufferBase ecmdDataBufferBase::operator | (const ecmdDataBufferBase& i_other) const { + + ecmdDataBufferBase newItem = *this; + + newItem.setOr(i_other.iv_Data, 0, iv_NumBits); + + return newItem; +} + + +uint32_t ecmdExtract(uint32_t *i_sourceData, uint32_t i_startBit, uint32_t i_numBitsToExtract, uint32_t *o_destData) { + uint32_t temp; + uint32_t len; + uint32_t mask1; + uint32_t mask2; + uint32_t offset; + uint32_t index; + uint32_t count; + + // Error check + if ((i_numBitsToExtract == 0) || (i_sourceData == NULL)){ + ETRAC0("**** ERROR : ecmdDataBufferBase ecmdExtract: Number of bits to extract = 0"); + o_destData = NULL; + return ECMD_DBUF_INVALID_ARGS; + } + + count = (i_numBitsToExtract + 31) / 32; + + /*------------------------------------------------------------------*/ + /* calculate number of fws (32-bit pieces) of the destination buffer*/ + /* to be processed. */ + /*----------------------------line 98-------------------------------*/ + /* all 32-bit (or < 32 bits) pieces of the destination buffer */ + for (uint32_t i = 0; i < count; i++) { + + len = i_numBitsToExtract; + /* length of bits to process is > 32 */ + if (len > 32) { + len = 32; + } + + /*******************************************************************/ + /* calculate index for accessing proper fw of the scan ring buffer */ + /*******************************************************************/ + index = i_startBit/32; + + /*----------------------------------------------------------------*/ + /* generate the mask to zero out some extra extracted bits (if */ + /* there are any) in the temporary buffer. */ + /*----------------------------------------------------------------*/ + if (len == 32) { + mask1 = 0xFFFFFFFF; + } else { + mask1 = ~(0xFFFFFFFF << len); + } + + /*-------------line 121--------------------------------------------*/ + /* generate the mask to prevent zeroing of unused bits positions */ + /* in the destination buffer. */ + /*----------------------------------------------------------------*/ + if (len == 0) { + mask2 = 0xFFFFFFFF; + } else { + mask2 = ~(mask1 << (32-len)); + } + + /******************************************************************/ + /* NOTE:- In this loop a max of 32 bits are extracted at a time. */ + /* we may require to access either one or two fw's of scan ring */ + /* buffer depending on the starting bit position & number of bits */ + /* to be extracted. */ + /******************************************************************/ + /* only one fw of scan ring buffer required to do extract */ + if (index == ((i_startBit + (len-1))/32)) { + /*--------------------------------------------------------------*/ + /* Extract required bits from the proper fw of the scan ring */ + /* buffer as shown below (follow the steps): */ + /* step1 - right justify bits to be extracted from the fw of the*/ + /* scan ring buffer.(we may have extra bits which are */ + /* not required to be extracted, in the high order bit */ + /* positions but they will be masked off later on). */ + /* step2 - left justify the extracted bits in the temp buffer. */ + /* result = (dest buffer with reqd bits zeroed) | step2 */ + /* (Unused bit positions in the dest buffer will not */ + /* be changed.) */ + /*--------------------------------------------------------------*/ + /* step1 */ + temp = ((*(i_sourceData + index)) >> (32-((i_startBit + len) - (index*32)))); + if ((32-((i_startBit + len) - (index*32))) >= 32) + temp = 0x0; + + if ((32 - len) >= 32) + temp = 0x0; + else + temp = (temp & mask1) << (32 - len); /* step2 */ + + *(o_destData + i) = (*(o_destData + i) & mask2) | temp; + /* two fws of scan ring buffer required to do extract */ + } else { + /*-----------------line 158--------------------------------------*/ + /* calculate number of bits to process in the 1st fw of the */ + /* scan ring buffer.(fw pointed by index) */ + /*--------------------------------------------------------------*/ + offset = (32 * (index + 1)) - i_startBit; + + /*--------------------------------------------------------------*/ + /* Extract required bits from the proper fws of the scan ring */ + /* buffer as shown below (follow the steps): */ + /* step1 - Shift 1st fw of the scan ring buffer left by the */ + /* number of bits to be extracted from the 2nd fw. */ + /* Shift 2nd fw of the scan ring buffer right such that */ + /* the required bits to be extracted are right justifed */ + /* in that fw. */ + /* OR the results of the above shifts and save it in a */ + /* temporary buffer. (we will have required bits */ + /* extracted and right justifed in the temp buffer. Also*/ + /* we may have some extra bits in the high order bits */ + /* position of the temp buffer, but they will be masked */ + /* off later on.) */ + /* step2 - left justify the extracted bits in the temp buffer. */ + /* result = (dest buffer with reqd bits zeroed) | step2 */ + /* (Unused bit positions in the dest buffer will not */ + /* be changed.) */ + /*--------------------------------------------------------------*/ + /* step1 */ + uint32_t val1 = 0x0; + uint32_t val2 = 0x0; + if (len-offset < 32) { + val1 = ((*(i_sourceData+index)) << (len-offset)); /* 1st fw*/ + } + + if ((32-(len-offset)) < 32) { + val2 = ((*(i_sourceData+index+1)) >> (32-(len-offset))); + } + temp = (val1 | val2);/* 2nd fw */ + + if (32-len >= 32) { + temp = 0x0; + } else { + temp = (temp & mask1) << (32-len); /* step2 */ + } + + *(o_destData+i) = (*(o_destData+i) & mask2) | temp; + } + i_numBitsToExtract -= 32; /* decrement length by a fw */ + i_startBit += 32; /* increment start by a fw */ + } + + return ECMD_DBUF_SUCCESS; +} + +uint32_t ecmdDataBufferBase::shareBuffer(ecmdDataBufferBase* i_sharingBuffer) +{ + uint32_t rc = ECMD_DBUF_SUCCESS; + + if(i_sharingBuffer == NULL) + return(ECMD_DBUF_INVALID_ARGS); + //delete data if currently has any + if (i_sharingBuffer->iv_RealData != NULL) + { + i_sharingBuffer->clear(); + } + + //copy the buffer called from minus the owner flag + i_sharingBuffer->iv_Capacity = iv_Capacity; + i_sharingBuffer->iv_NumBits = iv_NumBits; + i_sharingBuffer->iv_Data = iv_Data; + i_sharingBuffer->iv_RealData = iv_RealData; + i_sharingBuffer->iv_UserOwned = false; + return(rc); +} + +void ecmdDataBufferBase::queryErrorState( uint32_t & o_errorState) { + if (iv_RealData != NULL) { + o_errorState = iv_RealData[EDB_RETURN_CODE]; + } else { + o_errorState = 0; + } +} + +/* Here is the plan for the compression format + 3 byte header, includes a version + 4 byte length + Then the data as returned by the compression algorithm that PRD is kindly letting us use +*/ + +uint32_t ecmdDataBufferBase::compressBuffer(ecmdCompressionMode_t i_mode) { + uint32_t rc = ECMD_DBUF_SUCCESS; + ecmdDataBufferBase compressedBuffer; + uint32_t byteOffset = 0; + + /* Get the length, and make sure it doesn't over flow our length variable */ + uint32_t length = this->getBitLength(); + + /* Set it big enough for the header/length below. Then we'll grow as need */ + compressedBuffer.setBitLength(56); + + /* Set the header, which is C2A3FV, where V is the version */ + compressedBuffer.setByte(byteOffset++, 0xC2); + compressedBuffer.setByte(byteOffset++, 0xA3); + if (i_mode == ECMD_COMP_PRD) { + compressedBuffer.setByte(byteOffset++, 0xF2); + } else if (i_mode == ECMD_COMP_ZLIB || i_mode == ECMD_COMP_ZLIB_SPEED || i_mode == ECMD_COMP_ZLIB_COMPRESSION) { +#ifndef __HOSTBOOT_MODULE + // All three of these are zlib compression, so they get the same version + compressedBuffer.setByte(byteOffset++, 0xF3); +#else + ETRAC0("**** ERROR : zlib support removed!"); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); +#endif + } else { + ETRAC0("**** ERROR : Unknown compression mode passed in!"); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); + } + + /* Set the length, which is 4 bytes long */ + compressedBuffer.setByte(byteOffset++, ((0xFF000000 & length) >> 24)); + compressedBuffer.setByte(byteOffset++, ((0x00FF0000 & length) >> 16)); + compressedBuffer.setByte(byteOffset++, ((0x0000FF00 & length) >> 8)); + compressedBuffer.setByte(byteOffset++, (0x000000FF & length)); + + /* Our common variables used in all modes */ + size_t uncompressedSize = this->getByteLength(); + size_t compressedSize = 0; + uint8_t* uncompressedData = new uint8_t[uncompressedSize]; + uint8_t* compressedData = NULL; + /* The data has to be copied into a uint8_t buffer. If you try to pass in (uint8_t*)this->iv_Data + instead of uncompressedData, you have big endian vs little endian issues */ + this->extract(uncompressedData, 0, this->getBitLength()); + + if (compressedBuffer.getByte(2) == 0xF2) { + /* Now setup our inputs and call the compress */ + compressedSize = PrdfCompressBuffer::compressedBufferMax(uncompressedSize); + compressedData = new uint8_t[compressedSize]; + + PrdfCompressBuffer::compressBuffer(uncompressedData, uncompressedSize, compressedData, compressedSize); + } else if (compressedBuffer.getByte(2) == 0xF3) { +#ifndef __HOSTBOOT_MODULE + /* Now setup our inputs and call the compress */ + compressedSize = compressBound(uncompressedSize); + compressedData = new uint8_t[compressedSize]; + /* Select the proper compression level */ + int level; + if (i_mode == ECMD_COMP_ZLIB) { + level = Z_DEFAULT_COMPRESSION; + } else if (i_mode == ECMD_COMP_ZLIB_SPEED) { + level = Z_BEST_SPEED; + } else if (i_mode == ECMD_COMP_ZLIB_COMPRESSION) { + level = Z_BEST_COMPRESSION; + } else { + ETRAC0("**** ERROR : Unknown compression mode passed in!"); + delete[] uncompressedData; + delete[] compressedData; + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); + } + + /* Create a local compressedSize variable to get around a PFD compile error with -Os*/ + /* They didn't like it when we did (uLongf*)&compressedSize */ + uLongf l_compressedSize = compressedSize; + /* Do the work */ + uint32_t rc = compress2(compressedData, &l_compressedSize, uncompressedData, uncompressedSize, level); + if (rc) { + ETRAC0("**** ERROR : Error occurred on the zlib compress2 call!"); + RETURN_ERROR(rc); + } + + /* Assign the value back so we can use it below */ + compressedSize = l_compressedSize; +#endif + } + + /* Now grow the buffer to the size of the compressed data */ + compressedBuffer.growBitLength((compressedBuffer.getBitLength() + (compressedSize * 8))); + + /* Insert the data and cleanup after ourselves */ + compressedBuffer.insert(compressedData, (byteOffset * 8), (compressedSize * 8)); + delete[] uncompressedData; + delete[] compressedData; + + /* Finally, copy the compressBuffer into our current buffer */ + *this = compressedBuffer; + + return rc; +} + +uint32_t ecmdDataBufferBase::uncompressBuffer() { + uint32_t rc = ECMD_DBUF_SUCCESS; + uint32_t length = 0; + ecmdDataBufferBase uncompressedBuffer; + uint32_t byteOffset = 0; + ecmdCompressionMode_t mode; + + /* See if the compression header is there */ + uint32_t header = this->getWord(0); + if ((header & 0xFFFFF000) != 0xC2A3F000) { + ETRAC1("**** ERROR : Compression header doesn't match. Found: 0x%X.", header); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); + } + /* Make sure it's a supported version of compression */ + if ((header & 0x00000F00) == 0x00000200) { + mode = ECMD_COMP_PRD; + } else if ((header & 0x00000F00) == 0x00000300) { +#ifndef __HOSTBOOT_MODULE + mode = ECMD_COMP_ZLIB; +#else + ETRAC0("**** ERROR : zlib support removed!"); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); +#endif + } else { + ETRAC1("**** ERROR : Unknown version. Found: 0x%X.", header); + RETURN_ERROR(ECMD_DBUF_INVALID_ARGS); + } + byteOffset+=3; + + /* Get the length, use it to set the uncompress buffer length */ + // split the following line up to avoid warnings: + // length = (this->getByte(byteOffset++) << 24) | (this->getByte(byteOffset++) << 16) | (this->getByte(byteOffset++) << 8) | this->getByte(byteOffset++); + length = this->getByte(byteOffset++) << 24; + length |= this->getByte(byteOffset++) << 16; + length |= this->getByte(byteOffset++) << 8; + length |= this->getByte(byteOffset++); + + uncompressedBuffer.setBitLength(length); + + /* Setup our inputs and call the uncompress */ + size_t uncompressedSize = uncompressedBuffer.getByteLength(); + size_t compressedSize = this->getByteLength() - byteOffset; + uint8_t* uncompressedData = new uint8_t[uncompressedSize]; + uint8_t* compressedData = new uint8_t[compressedSize]; + /* The data has to be copied into a uint8_t buffer. If you try to pass in (uint8_t*)this->iv_Data + instead of compressedData, you have big endian vs little endian issues */ + this->extract(compressedData, (byteOffset * 8), (compressedSize * 8)); + + if (mode == ECMD_COMP_PRD) { + PrdfCompressBuffer::uncompressBuffer(compressedData, compressedSize, uncompressedData, uncompressedSize); + } else if (mode == ECMD_COMP_ZLIB) { +#ifndef __HOSTBOOT_MODULE + /* Create a local compressedSize variable to get around a PFD compile error with -Os*/ + /* They didn't like it when we did (uLongf*)&uncompressedSize */ + uLongf l_uncompressedSize = uncompressedSize; + /* Do the work */ + uint32_t rc = uncompress(uncompressedData, &l_uncompressedSize, compressedData, compressedSize); + if (rc) { + ETRAC0("**** ERROR : Error occurred on the zlib uncompress call!"); + RETURN_ERROR(rc); + } + /* Assign the value back so we can use it below */ + uncompressedSize = l_uncompressedSize; +#endif + } + + /* Error check the length */ + if (uncompressedBuffer.getByteLength() != uncompressedSize) { + ETRAC2("**** ERROR : Expected byte length of %d, got back %d", uncompressedBuffer.getByteLength(), uncompressedSize); + RETURN_ERROR(ECMD_DBUF_MISMATCH); + } + + /* Insert the data and cleanup after ourselves */ + uncompressedBuffer.insert(uncompressedData, 0, length); + delete[] uncompressedData; + delete[] compressedData; + + /* Finally, copy the uncompressBuffer into our current buffer */ + *this = uncompressedBuffer; + + return rc; +} + +bool ecmdDataBufferBase::isBufferCompressed() { + bool compressed = false; + + /* The first 5 nibbles are a fixed pattern when compressed. If the user happens to have this pattern in + uncompressed data, we could have a problem */ + if ((getWord(0) & 0xFFFFF000) == 0xC2A3F000) { + compressed = true; + } + + return compressed; +} + +void * ecmdBigEndianMemCopy(void * dest, const void *src, size_t count) { +#if defined (i386) + char *tmp = (char *) dest, *s = (char *) src; + int remainder = 0; + uint32_t whole_num = 0; + + remainder = count % 4; + whole_num = count - remainder; + + /* note: whole_num + remainder = count */ + + if (whole_num == count) { + while (count--) *tmp++ = *s++; + return dest; + } + if (whole_num) { + while (whole_num--) *tmp++ = *s++; + } + if (remainder == 3) { + tmp[1] = s[1]; + tmp[2] = s[2]; + tmp[3] = s[3]; + } + else if (remainder == 2) { + tmp[2] = s[2]; + tmp[3] = s[3]; + }//'constant condition' has been added to avoid BEAM errors + else if (remainder == 1) { /*constant condition*/ + tmp[3] = s[3]; + } + + return dest; +#else + return memcpy(dest,src,count); +#endif + +} + +uint32_t* ecmdDataBufferBaseImplementationHelper::getDataPtr( void* i_buffer ) { + if (i_buffer == NULL) return NULL; + ecmdDataBufferBase* buff = (ecmdDataBufferBase*)i_buffer; + return buff->iv_Data; +}; + + +/******************************************************************************** + These routines belong to derived class ecmdOptimizableDataBufferBase + ********************************************************************************/ + +ecmdOptimizableDataBufferBase::ecmdOptimizableDataBufferBase() +{ + iv_BufferOptimizable = true; +} + +ecmdOptimizableDataBufferBase::ecmdOptimizableDataBufferBase(uint32_t i_numBits) + : ecmdDataBufferBase(i_numBits) { + iv_BufferOptimizable = true; +} + diff --git a/src/usr/ecmddatabuffer/makefile b/src/usr/ecmddatabuffer/makefile index 57e84e73f..4988aff0d 100644 --- a/src/usr/ecmddatabuffer/makefile +++ b/src/usr/ecmddatabuffer/makefile @@ -23,9 +23,14 @@ ROOTPATH = ../../.. MODULE = ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer -OBJS = ecmdDataBuffer.o +CUSTOMFLAGS += -DPRDF_COMPRESSBUFFER_COMPRESS_FUNCTIONS=1 +CUSTOMFLAGS += -DPRDF_COMPRESSBUFFER_UNCOMPRESS_FUNCTIONS=1 + +OBJS = ecmdDataBufferBase.o SUBDIRS = test.d |