📄 memory_store.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: memory_store.cpp,v $ * PRODUCTION Revision 1000.1 2004/06/01 19:19:14 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8 * PRODUCTION * =========================================================================== *//* $Id: memory_store.cpp,v 1000.1 2004/06/01 19:19:14 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Vladimir Soussov * * File Description: RAM storage implementation * */#include <ncbi_pch.hpp>#include "memory_store.hpp"#include <string.h>BEGIN_NCBI_SCOPECMemStore::SMemBlock* CMemStore::x_AddBlock(void){ SMemBlock* n_blk = new SMemBlock; if ( !n_blk ) return 0; n_blk->body = new char[m_BlockSize]; if ( !n_blk->body ) { delete n_blk; return 0; } n_blk->next = 0; n_blk->free_space = m_BlockSize; n_blk->prev = m_Last; if (m_First) { m_Last->next = n_blk; } else { m_First = m_Current = n_blk; } m_Last = n_blk; return n_blk; }size_t CMemStore::Append(const void* buff, size_t size){ if (!buff || !size) return 0; if (!m_Last || !m_Last->free_space) { if ( !x_AddBlock() ) return 0; } TSize f_free; TSize n = 0; char* b = (char*) buff; if(size > kMax_BlobSize) size= kMax_BlobSize; TSize nof_bytes = (TSize) size; while (nof_bytes > 0) { f_free = m_BlockSize - m_Last->free_space; if (nof_bytes <= m_Last->free_space) { // we have enough space in last block memcpy(&m_Last->body[f_free], b+n, nof_bytes); m_Last->free_space -= nof_bytes; n += nof_bytes; break; } // space in this block is insufficient memcpy(&m_Last->body[f_free], b + n, m_Last->free_space); n += m_Last->free_space; nof_bytes -= m_Last->free_space; m_Last->free_space = 0; if ( !x_AddBlock() ) break; } m_Size += n; return (size_t) n;}size_t CMemStore::Read(void* buff, size_t size){ if (!m_Current || !buff || !size) return 0; if(size > kMax_BlobSize) size= kMax_BlobSize; TSize n = 0; char* b = (char*) buff; for (TSize nof_bytes = (TSize) size; nof_bytes > 0; ) { TSize f_free = m_BlockSize - m_Current->free_space; if ((m_BlockPos + nof_bytes) <= f_free) { // we have all needed bytes in this block memcpy(b, &m_Current->body[m_BlockPos], nof_bytes); m_BlockPos += nof_bytes; n += nof_bytes; if (m_BlockPos >= f_free) { // we have read all bytes from this block m_Current = m_Current->next; m_BlockPos = 0; } break; } // we can read just a part from this block TSize k = f_free - m_BlockPos; memcpy(b, &m_Current->body[m_BlockPos], k); n += k; b += k; nof_bytes -= k; m_BlockPos = 0; m_Current = m_Current->next; if ( !m_Current ) break; } m_Pos += n; return (size_t) n;}CMemStore::TSize CMemStore::x_SeekCURR(CMemStore::TSize offset){ if ( !m_Current ) return x_SeekTAIL(offset); if (offset == 0) return m_Pos; if (offset <= -m_Pos) return x_SeekHEAD(0); if (offset > 0) { // go toward the tail while (offset > 0) { TSize n = m_BlockSize - m_Current->free_space; if ((m_BlockPos + offset) < n) { // we have to move inside this block m_BlockPos += offset; m_Pos += offset; break; } // we have to move outside the block n -= m_BlockPos; m_Pos += n; m_BlockPos = 0; m_Current = m_Current->next; if (!m_Current) break; offset -= n; } } else { // go toward the head while (offset < 0) { if ((m_BlockPos + offset) >= 0) { // we have to move inside this block m_BlockPos += offset; m_Pos += offset; break; } // we have to move outside the block m_Pos -= m_BlockPos + 1; offset += m_BlockPos + 1; m_Current = m_Current->prev; m_BlockPos = m_BlockSize - (m_Current->free_space + 1); } } return m_Pos;}CMemStore::TSize CMemStore::x_SeekHEAD(CMemStore::TSize offset){ if (offset <= 0) { m_Current = m_First; m_Pos = 0; m_BlockPos = 0; return 0; } if (offset == m_Pos) return m_Pos; if (!m_Current || (offset < m_Pos && offset < m_Pos - offset)) { x_SeekHEAD(0); return x_SeekCURR(offset); } return x_SeekCURR(offset - m_Pos);}CMemStore::TSize CMemStore::x_SeekTAIL(CMemStore::TSize offset){ if (offset >= 0) { m_BlockPos = 0; m_Current = 0; m_Pos = m_Size; return m_Pos; } return x_SeekHEAD(m_Size + offset);}long CMemStore::Seek(long offset, EWhence whence){ if ( !m_Last ) return -1; switch (whence) { case eHead: return (long) x_SeekHEAD((TSize) offset); case eTail: return (long) x_SeekTAIL((TSize) offset); case eCurr: return (long) x_SeekCURR((TSize) offset); } return -1; // error}size_t CMemStore::Write(const void* buff, size_t size){ if (!buff || !size) return 0; if(size > kMax_BlobSize) size= kMax_BlobSize; char* b = (char*) buff; TSize nof_bytes = (TSize) size; TSize n = 0; if ( m_Current ) { while (nof_bytes > 0) { TSize f_free = m_BlockSize - m_Current->free_space; if ((m_BlockPos + nof_bytes) <= f_free) { // we have all needed bytes in this block memcpy(&m_Current->body[m_BlockPos], b + n, nof_bytes); m_BlockPos += nof_bytes; n += nof_bytes; nof_bytes = 0; if (m_BlockPos >= f_free) { // we have written all bytes to this block m_Current = m_Current->next; m_BlockPos = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -