LCOV - code coverage report
Current view: top level - src - codec_memory.h (source / functions) Hit Total Coverage
Test: test_coverage.info Lines: 60 61 98.4 %
Date: 2017-06-21 14:32:49 Functions: 15 15 100.0 %

          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 manages the memory representation of
      22             :  * the open databases.
      23             :  */
      24             : 
      25             : #ifndef CODEC_MEMORY_H
      26             : #define CODEC_MEMORY_H
      27             : 
      28             : #include "bytebuf.h"
      29             : #include "codec.h"
      30             : #include "common.h"
      31             : #include "game.h"
      32             : #include "index.h"
      33             : #include "namebase.h"
      34             : #include <vector>
      35             : #include <limits>
      36             : 
      37             : #if !CPP11_SUPPORT
      38             : #define override
      39             : #endif
      40             : 
      41             : /**
      42             :  * Manages memory databases that do not have associated files.
      43             :  * This class stores the data of the games into a std::vector; derived classes
      44             :  * can override the virtual functions dyn_addGameData() and getGameData() in
      45             :  * order to store the data into a different container or file.
      46             :  */
      47         157 : class CodecMemory : public ICodecDatabase {
      48             : protected:
      49             :         Index* idx_;
      50             :         NameBase* nb_;
      51             : 
      52             : private:
      53             :         std::vector<byte> v_;
      54             :         ByteBuffer bbuf_;
      55             : 
      56             : public:
      57         141 :         CodecMemory() : idx_(0), nb_(0), bbuf_(BBUF_SIZE) {}
      58             : 
      59           1 :         Codec getType() override { return ICodecDatabase::MEMORY; }
      60             : 
      61           5 :         std::vector<std::string> getFilenames() override {
      62           5 :                 return std::vector<std::string>();
      63             :         }
      64             : 
      65        8015 :         const byte* getGameData(uint32_t offset, uint32_t length) override {
      66       16030 :                 ASSERT(offset < v_.size());
      67        8015 :                 ASSERT(length <= v_.size() - offset);
      68             :                 #if !CPP11_SUPPORT
      69             :                 return &v_.front() + offset;
      70             :                 #else
      71       16030 :                 return v_.data() + offset;
      72             :                 #endif
      73             :         }
      74             : 
      75        2003 :         errorT addGame(IndexEntry* ie, const byte* src, size_t length) override {
      76        3003 :                 return doAddGame(ie, src, length);
      77             :         }
      78             : 
      79        2000 :         errorT saveGame(IndexEntry* ie, const byte* src, size_t length,
      80             :                         gamenumT replaced) override {
      81        2000 :                 return doAddGame(ie, src, length, true, replaced);
      82             :         }
      83             : 
      84        9008 :         errorT addGame(Game* game) override {
      85             :                 IndexEntry ie;
      86        9008 :                 errorT err = encodeGame(game, &ie, &bbuf_);
      87        9008 :                 if (err != OK) return err;
      88             : 
      89        9008 :                 return doAddGame(&ie, bbuf_.getData(), bbuf_.GetByteCount());
      90             :         }
      91             : 
      92        2001 :         errorT saveGame(Game* game, gamenumT replaced) override {
      93             :                 IndexEntry ie;
      94        2001 :                 errorT err = encodeGame(game, &ie, &bbuf_);
      95        2001 :                 if (err != OK) return err;
      96             : 
      97        2001 :                 return doAddGame(&ie, bbuf_.getData(), bbuf_.GetByteCount(), true, replaced);
      98             :         }
      99             : 
     100          24 :         errorT flush() override {
     101          24 :                 return OK;
     102             :         }
     103             : 
     104             : protected:
     105          16 :         errorT dyn_open(fileModeT fMode, const char*, const Progress&, Index* idx,
     106             :                         NameBase* nb) override {
     107          47 :                 if (idx == 0 || nb == 0) return ERROR;
     108          16 :                 if (fMode != FMODE_Memory) return ERROR;
     109          43 :                 idx_ = idx;
     110          43 :                 nb_ = nb;
     111          12 :                 return OK;
     112             :         }
     113             : 
     114             :         /**
     115             :          * Stores the data of the game into the database.
     116             :          * A derived class can override this function to store the data into a
     117             :          * different container or file. In that case it must also override the
     118             :          * virtual function getGameData().
     119             :          * @param src:    valid pointer to a buffer that contains the game data
     120             :          *                (encoded in native format).
     121             :          * @param length: the length of the buffer @p src (in bytes).
     122             :          * @returns
     123             :          * - on success, a @e std::pair containing OK and the offset of the stored
     124             :          * data (usable to retrieve the data with getGameData()).
     125             :          * - on failure, a @e std::pair containing an error code and 0.
     126             :          */
     127       10012 :         virtual std::pair<errorT, uint32_t> dyn_addGameData(const byte* src,
     128             :                                                             size_t length) {
     129       10012 :                 ASSERT(src != 0);
     130             : 
     131       20024 :                 if (v_.size() >= std::numeric_limits<uint32_t>::max())
     132           0 :                         return std::make_pair(ERROR_Full, 0);
     133             : 
     134       10012 :                 uint32_t offset = v_.size();
     135       40048 :                 v_.insert(v_.end(), src, src + length);
     136       10012 :                 return std::make_pair(OK, offset);
     137             :         }
     138             : 
     139             : private:
     140             :         CodecMemory(const CodecMemory&);
     141             :         CodecMemory& operator=(const CodecMemory&);
     142             : 
     143             :         /**
     144             :          * Add/Replace a game into the database.
     145             :          * Calls the virtual function dyn_addGameData() to store the game data and
     146             :          * obtain the corresponding offset. The offset and the @p length are stored
     147             :          * in @p ie; then the game will be added/replaced in the Index object idx_.
     148             :          * @param ie:       valid pointer to the new header data of the game.
     149             :          * @param src:      valid pointer to the new game data of the game.
     150             :          * @param length:   length of the game data (in bytes).
     151             :          * @param replace:  false to add a game or true to replace an existing one.
     152             :          * @param replaced: valid gamenumT of the game to be replaced (used only
     153             :          *                  when @p replace is true).
     154             :          * @returns OK if successful or an error code.
     155             :          */
     156       16012 :         errorT doAddGame(IndexEntry* ie, const byte* src, size_t length,
     157             :                          bool replace = false, gamenumT replaced = 0) {
     158       16012 :                 if (replace && replaced >= idx_->GetNumGames()) return ERROR_BadArg;
     159             : 
     160       16012 :                 std::pair<errorT, uint32_t> offset = dyn_addGameData(src, length);
     161       16012 :                 if (offset.first != OK)
     162             :                         return offset.first;
     163       32024 :                 ie->SetOffset(offset.second);
     164       16012 :                 ie->SetLength(length);
     165             : 
     166       16012 :                 if (replace)
     167        4001 :                         return idx_->WriteEntry(ie, replaced);
     168             :                 else
     169       12011 :                         return idx_->AddGame(ie);
     170             :         }
     171             : 
     172             :         /**
     173             :          * Encodes a Game object to native format.
     174             :          * The names are added to the member NameBase object @p nb_, if necessary.
     175             :          * @param game:         valid pointer to the Game object to be encoded.
     176             :          * @param[out] resIe:   valid pointer to the IndexEntry object that will
     177             :          *                      receive the encoded header data.
     178             :          * @param[out] resBBuf: valid pointer to the ByteBuffer object that will
     179             :          *                      receive the encoded games data.
     180             :          * @returns OK if successful or an error code.
     181             :          */
     182       11009 :         errorT encodeGame(Game* game, IndexEntry* resIe, ByteBuffer* resBbuf) {
     183       11009 :                 resIe->Init();
     184       11009 :                 errorT err = game->Encode(resBbuf, resIe);
     185       11009 :                 if (err != OK) return err;
     186             : 
     187       11009 :                 err = resIe->SetWhiteName(nb_, game->GetWhiteStr());
     188       11009 :                 if (err != OK) return err;
     189       11009 :                 err = resIe->SetBlackName(nb_, game->GetBlackStr());
     190       11009 :                 if (err != OK) return err;
     191       11009 :                 err = resIe->SetEventName(nb_, game->GetEventStr());
     192       11009 :                 if (err != OK) return err;
     193       11009 :                 err = resIe->SetSiteName(nb_, game->GetSiteStr());
     194       11009 :                 if (err != OK) return err;
     195       11009 :                 err = resIe->SetRoundName(nb_, game->GetRoundStr());
     196       11009 :                 if (err != OK) return err;
     197             : 
     198       44036 :                 nb_->AddElo(resIe->GetWhite(), resIe->GetWhiteElo());
     199       33027 :                 nb_->AddElo(resIe->GetBlack(), resIe->GetBlackElo());
     200             : 
     201             :                 return err;
     202             :         }
     203             : };
     204             : 
     205             : #if !CPP11_SUPPORT
     206             : #undef override
     207             : #endif
     208             : 
     209             : #endif

Generated by: LCOV version 1.12