LCOV - code coverage report
Current view: top level - src - codec_memory.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 37 45 82.2 %
Date: 2019-01-29 11:06:41 Functions: 12 13 92.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2016-2017  Fulvio Benini
       3             : 
       4             :  * This file is part of Scid (Shane's Chess Information Database).
       5             :  *
       6             :  * Scid is free software: you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation.
       9             :  *
      10             :  * Scid is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with Scid.  If not, see <http://www.gnu.org/licenses/>.
      17             :  *
      18             :  */
      19             : 
      20             : /** @file
      21             :  * Implements the CodecMemory class, which represent a memory database.
      22             :  */
      23             : 
      24             : #ifndef CODEC_MEMORY_H
      25             : #define CODEC_MEMORY_H
      26             : 
      27             : #include "codec_native.h"
      28             : 
      29             : /**
      30             :  * Manages memory databases that do not have associated files.
      31             :  * Every open database should have a native representation in memory: to satisfy
      32             :  * this requirement non-native codecs should be derived from this class.
      33             :  */
      34          83 : class CodecMemory : public CodecNative<CodecMemory> {
      35             :         VectorChunked<byte, 24> v_;
      36             : 
      37             :         enum : uint64_t {
      38             :                 LIMIT_GAMEOFFSET = 1ULL << 46,
      39             :                 LIMIT_GAMELEN = 1ULL << 18,
      40             :                 LIMIT_NUMGAMES = (1ULL << 32) - 2,
      41             :                 LIMIT_UNIQUENAMES = 1ULL << 28,
      42             :                 LIMIT_NAMELEN = 255
      43             :         };
      44             : 
      45             : public: // ICodecDatabase interface
      46           1 :         Codec getType() const override { return ICodecDatabase::MEMORY; }
      47             : 
      48           4 :         std::vector<std::string> getFilenames() const override {
      49           4 :                 return std::vector<std::string>();
      50             :         }
      51             : 
      52             :         std::vector<std::pair<const char*, std::string>>
      53           0 :         getExtraInfo() const override {
      54           0 :                 std::vector<std::pair<const char*, std::string>> res;
      55           0 :                 res.emplace_back("type", std::to_string(idx_->GetType()));
      56           0 :                 return res;
      57             :         }
      58             : 
      59        7021 :         const byte* getGameData(uint64_t offset, uint32_t length) override {
      60        7021 :                 ASSERT(offset < v_.size());
      61        7021 :                 ASSERT(length <= v_.size() - offset);
      62        7021 :                 ASSERT(v_.contiguous(static_cast<size_t>(offset)) >= length);
      63        7021 :                 return &v_[offset];
      64             :         }
      65             : 
      66          19 :         errorT flush() override { return OK; }
      67             : 
      68          34 :         errorT dyn_open(fileModeT fMode, const char*, const Progress&, Index* idx,
      69             :                         NameBase* nb) override {
      70          34 :                 if (idx == 0 || nb == 0)
      71           0 :                         return ERROR;
      72          34 :                 if (fMode != FMODE_Memory)
      73           4 :                         return ERROR;
      74          30 :                 idx_ = idx;
      75          30 :                 nb_ = nb;
      76          30 :                 return OK;
      77             :         }
      78             : 
      79             : public: // CodecNative CRTP
      80             :         /**
      81             :          * Stores the data of a game into memory.
      82             :          * @param src:    valid pointer to a buffer that contains the game data
      83             :          *                (encoded in native format).
      84             :          * @param length: the length of the buffer @p src (in bytes).
      85             :          * @returns
      86             :          * - on success, a @e std::pair containing OK and the offset of the stored
      87             :          * data (usable to retrieve the data with getGameData()).
      88             :          * - on failure, a @e std::pair containing an error code and 0.
      89             :          */
      90        8018 :         std::pair<errorT, uint64_t> dyn_addGameData(const byte* src,
      91             :                                                     size_t length) {
      92        8018 :                 ASSERT(src != 0);
      93             : 
      94        8018 :                 if (length >= LIMIT_GAMELEN)
      95           0 :                         return std::make_pair(ERROR_GameLengthLimit, 0);
      96             : 
      97        8018 :                 auto offset = v_.size();
      98        8018 :                 auto capacity = v_.capacity();
      99        8018 :                 if (capacity - offset < length) // Do not fit in the current chunk
     100          28 :                         offset = capacity;
     101        8018 :                 if (offset >= LIMIT_GAMEOFFSET)
     102           0 :                         return std::make_pair(ERROR_OffsetLimit, 0);
     103             : 
     104        8018 :                 v_.resize(offset + length);
     105        8018 :                 ASSERT(v_.contiguous(offset) >= length);
     106        8018 :                 std::copy_n(src, length, &v_[offset]);
     107        8018 :                 return {OK, offset};
     108             :         }
     109             : 
     110             :         /**
     111             :          * Given a name (string), retrieve the corresponding ID.
     112             :          * The name is added to @e nb_ if do not already exists in the NameBase.
     113             :          * @param nt:   nameT type of the name to retrieve.
     114             :          * @param name: the name to retrieve.
     115             :          * @returns
     116             :          * - on success, a @e std::pair containing OK and the ID.
     117             :          * - on failure, a @e std::pair containing an error code and 0.
     118             :          */
     119       40090 :         std::pair<errorT, idNumberT> dyn_addName(nameT nt, const char* name) {
     120       40090 :                 return nb_->addName(nt, name, LIMIT_NAMELEN, LIMIT_UNIQUENAMES);
     121             :         }
     122             : 
     123             :         /**
     124             :          * Add an IndexEntry to @e idx_.
     125             :          * @param ie: the IndexEntry object to add.
     126             :          * @returns OK if successful or an error code.
     127             :          */
     128        7017 :         errorT dyn_addIndexEntry(const IndexEntry& ie) {
     129        7017 :                 auto nGames = idx_->GetNumGames();
     130        7017 :                 if (nGames >= LIMIT_NUMGAMES)
     131           0 :                         return ERROR_NumGamesLimit;
     132             : 
     133        7017 :                 return idx_->WriteEntry(&ie, nGames);
     134             :         }
     135             : 
     136             :         /**
     137             :          * Replace an IndexEntry.
     138             :          * @param ie:       the IndexEntry with the new data.
     139             :          * @param replaced: valid gamenumT of the game to be replaced.
     140             :          * @returns OK if successful or an error code.
     141             :          */
     142        1001 :         errorT dyn_saveIndexEntry(const IndexEntry& ie, gamenumT replaced) {
     143        1001 :                 return idx_->WriteEntry(&ie, replaced);
     144             :         }
     145             : };
     146             : 
     147             : #endif

Generated by: LCOV version 1.13