/** ******************************************************************************* * @file EdnEdnVectorBuf.cpp * @brief Editeur De N'ours : Basic EdnVectorBuf Basic binary vector for all type of storage * @author Edouard DUPIN * @date 07/04/2011 * @par Project * Edn * * @par Copyright * Copyright 2010 Edouard DUPIN, all right reserved * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY. * * Licence summary : * You can modify and redistribute the sources code and binaries. * You can send me the bug-fix * You can not earn money with this Software (if the source extract from Edn * represent less than 50% of original Sources) * Term of the licence in in the file licence.txt. * ******************************************************************************* */ #include "tools_debug.h" #include "tools_globals.h" #include "toolsMemory.h" #include "EdnVectorBuf.h" #undef __class__ #define __class__ "EdnEdnVectorBuf" /** * @brief Create an empty vector * * @param[in] count Minimum request size of the Buffer * * @return --- * */ EdnVectorBuf::EdnVectorBuf(int32_t count) { m_data = NULL; m_allocated = 0; m_gapStart = 0; m_gapEnd = GAP_SIZE_MIN; ChangeAllocation(count+GAP_SIZE_MIN); } /** * @brief Re-copy constructor (copy all needed data) * * @param[in] Evb Vector that might be copy * * @return --- * */ EdnVectorBuf::EdnVectorBuf(const EdnVectorBuf & Evb) { m_allocated = Evb.m_allocated; m_data = NULL; m_gapStart = Evb.m_gapStart; m_gapEnd = Evb.m_gapEnd; // allocate all same data EDN_MALLOC(m_data, m_allocated, int8_t); EDN_ASSERT(NULL!=m_data, "Error in data allocation"); // Copy all data ... memcpy(m_data, Evb.m_data, m_allocated * sizeof(int8_t) ); } /** * @brief Destructor of the current Class * * @param --- * * @return --- * */ EdnVectorBuf::~EdnVectorBuf() { if (NULL!=m_data) { EDN_FREE(m_data); m_data = NULL; m_allocated = 0; m_gapStart = 0; m_gapEnd = 0; } } static int32_t getFileSize(FILE *myFile) { if (NULL == myFile) { return 0; } int32_t size = 0; fseek(myFile, 0, SEEK_END); size = ftell(myFile); fseek(myFile, 0, SEEK_SET); return size; } /** * @brief Save in the current file open * * @param[in,out] myFile pointer on the file where data might be writed * * @return true if OK / false if an error occured * */ bool EdnVectorBuf::DumpIn(FILE *myFile) { bool ret = true; // write Data (void)fwrite(m_data, sizeof(int8_t), m_gapStart, myFile); (void)fwrite(&m_data[m_gapEnd], sizeof(int8_t), m_allocated - m_gapEnd, myFile); return ret; } /** * @brief Load in the current file open * * @param[in,out] myFile pointer on the file where data might be read * * @return true if OK / false if an error occured * */ bool EdnVectorBuf::DumpFrom(FILE *myFile) { bool ret = true; int32_t length = getFileSize(myFile); // error case ... if (length < 0) { length = 0; } // allocate the current buffer : ChangeAllocation(length + GAP_SIZE_MIN); // insert Data int32_t nbReadData = fread(&m_data[GAP_SIZE_MIN], sizeof(int8_t), length, myFile); EDN_INFO("load data : filesize=" << length << ", readData=" << nbReadData); // check ERROR if (nbReadData != length) { EDN_ERROR("load data pb : filesize=" << length << ", readData=" << nbReadData); ret = false; } // set the gapsize at the end ... m_gapStart = 0; m_gapEnd = GAP_SIZE_MIN; return ret; } /** * @brief Re-copy operator * * @param[in] Evb Vector that might be copy * * @return reference on the curent re-copy vector * */ EdnVectorBuf& EdnVectorBuf::operator=(const EdnVectorBuf & Evb) { if( this != &Evb ) // avoid copy to itself { if (NULL!=m_data) { EDN_FREE(m_data); m_data = NULL; } // Set the new value m_allocated = Evb.m_allocated; m_gapStart = Evb.m_gapStart; m_gapEnd = Evb.m_gapEnd; // allocate all same data EDN_MALLOC(m_data, m_allocated, int8_t); EDN_ASSERT(NULL!=m_data, "Error in data allocation"); // Copy all data ... memcpy(m_data, Evb.m_data, m_allocated * sizeof(int8_t) ); } // Return the curent pointer return *this; } int8_t EdnVectorBuf::operator[] (int32_t pos) { EDN_ASSERT(0 <= pos || pos < Size(), "try to read an element non existing"); if (pos < m_gapStart) { return m_data[pos]; } return m_data[pos + m_gapEnd-m_gapStart]; } /** * @brief Get a current element in the vector * * @param[in] pos Desired position read * * @return Reference on the Element * */ int8_t& EdnVectorBuf::Get(int32_t pos) { EDN_ASSERT(0 <= pos || pos < Size(), "try to read an element non existing"); if (pos < m_gapStart) { return m_data[pos]; } return m_data[pos + m_gapEnd-m_gapStart]; } /** * @brief * * @param[in,out] --- * * @return --- * */ void EdnVectorBuf::Get(int32_t pos, int32_t nbElement, Edn::VectorType &tmpBuffer) { tmpBuffer.Clear(); if (pos < m_gapStart) { if (pos + nbElement < m_gapStart) { tmpBuffer.PushBack(&m_data[pos], nbElement); } else { tmpBuffer.PushBack(&m_data[pos], m_gapStart - pos); tmpBuffer.PushBack(&m_data[m_gapEnd], nbElement - (m_gapStart - pos) ); } } else { tmpBuffer.PushBack(&m_data[pos+(m_gapEnd-m_gapStart)], nbElement); } } /** * @brief Add at the Last position of the Vector * * @param[in] item Element to add at the end of vector * * @return --- * */ void EdnVectorBuf::PushBack(const int8_t& item) { Insert( Size(), item); } /** * @brief Remove the last element of the vector * * @param --- * * @return --- * */ void EdnVectorBuf::PopBack(void) { if (Size()>0) { Remove( Size() ); } } /** * @brief Remove data in the buffer * * @param[in] * * @return --- * */ void EdnVectorBuf::Remove(int32_t pos, int32_t nbRemoveElement) { if( pos > Size() || pos < 0 ) { EDN_ERROR("Request higher than buffer size : pos="< " << newSize); // check if something is allocated : if (NULL == m_data) { // no data allocated ==> request an allocation (might be the first) EDN_MALLOC(m_data, newSize, int8_t); } else { // move datas EDN_REALLOC(m_data, newSize, int8_t); } // Check result with assert : EDN_ASSERT(NULL!=m_data, "Error in data allocation"); // set the new allocation size m_allocated = newSize; } /** * @brief * * @param[in,out] --- * * @return --- * */ void EdnVectorBuf::Insert(int32_t pos, const int8_t& item) { if( pos > Size() || pos < 0 ) { EDN_ERROR("Request higher than buffer size : pos="< items; items.PushBack('i'); items.PushBack('j'); items.PushBack('k'); items.PushBack('l'); items.PushBack('m'); items.PushBack('n'); items.PushBack('o'); items.PushBack('p'); myBufferTmp.Insert(3, items); myBufferTmp.Display(); plop='7'; myBufferTmp.Insert(7, plop); myBufferTmp.Display(); myBufferTmp.Replace(8, 'z'); myBufferTmp.Display(); items.Clear(); items.PushBack('1'); items.PushBack('2'); items.PushBack('3'); myBufferTmp.Replace(10, 4, items); myBufferTmp.Display(); myBufferTmp.PushBack('a'); myBufferTmp.PushBack('a'); myBufferTmp.PushBack('a'); myBufferTmp.PushBack('a'); myBufferTmp.Display(); myBufferTmp.PopBack(); myBufferTmp.PopBack(); myBufferTmp.PopBack(); myBufferTmp.PopBack(); myBufferTmp.Display(); myBufferTmp.Remove(2, 3); myBufferTmp.Display(); */ }