LCOV - code coverage report
Current view: top level - src - codec_native.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 60 78.3 %
Date: 2019-01-29 11:06:41 Functions: 16 22 72.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 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 @e CodecNative, which is used as base class by native codecs.
      22             :  */
      23             : 
      24             : #ifndef CODEC_NATIVE_H
      25             : #define CODEC_NATIVE_H
      26             : 
      27             : #include "bytebuf.h"
      28             : #include "codec.h"
      29             : #include "game.h"
      30             : #include "index.h"
      31             : #include "namebase.h"
      32             : 
      33             : /**
      34             :  * This class stores the pointers to the @e Index and @e NameBase objects used
      35             :  * by a native codec. It also implements the addGame() and saveGame() functions
      36             :  * of the ICodecDatabase interface, splitting them into 2 function calls to a
      37             :  * derived class (CRTP technique):
      38             :  * - dyn_addName() should return the ID corresponding to a name, eventually
      39             :  *   adding the name to the @e nb_ if necessary;
      40             :  * - dyn_addGameData() should stores the data of the game, encoded in native
      41             :  *   format, and returns the offset that can be used to retrieve the data.
      42             :  */
      43          50 : template <typename Derived> class CodecNative : public ICodecDatabase {
      44             : protected:
      45             :         Index* idx_;
      46             :         NameBase* nb_;
      47             :         ByteBuffer bbuf_;
      48             : 
      49             : protected:
      50          50 :         CodecNative() : idx_(0), nb_(0), bbuf_(BBUF_SIZE) {}
      51             : 
      52             : public: // ICodecDatabase interface
      53        3003 :         errorT addGame(const IndexEntry* srcIe, const NameBase* srcNb,
      54             :                        const byte* srcData, size_t dataLen) override {
      55        3003 :                 IndexEntry ie = *srcIe;
      56        3003 :                 errorT err = addGameHelper(
      57             :                     &ie, srcData, dataLen,
      58             :                     srcNb->GetName(NAME_PLAYER, srcIe->GetWhite()),
      59             :                     srcNb->GetName(NAME_PLAYER, srcIe->GetBlack()),
      60             :                     srcNb->GetName(NAME_EVENT, srcIe->GetEvent()),
      61             :                     srcNb->GetName(NAME_SITE, srcIe->GetSite()),
      62             :                     srcNb->GetName(NAME_ROUND, srcIe->GetRound()));
      63        3003 :                 if (err != OK)
      64           0 :                         return err;
      65             : 
      66        3003 :                 return derived()->dyn_addIndexEntry(ie);
      67             :         }
      68             : 
      69        7014 :         errorT addGame(Game* game) override {
      70        7014 :                 std::pair<errorT, IndexEntry> ie = addGameHelper(game);
      71        7014 :                 if (ie.first != OK)
      72           0 :                         return ie.first;
      73             : 
      74        7014 :                 return derived()->dyn_addIndexEntry(ie.second);
      75             :         }
      76             : 
      77        2001 :         errorT saveGame(Game* game, gamenumT replaced) override {
      78        2001 :                 if (replaced >= idx_->GetNumGames())
      79           0 :                         return ERROR_BadArg;
      80             : 
      81        2001 :                 std::pair<errorT, IndexEntry> ie = addGameHelper(game);
      82        2001 :                 if (ie.first != OK)
      83           0 :                         return ie.first;
      84             : 
      85        2001 :                 return derived()->dyn_saveIndexEntry(ie.second, replaced);
      86             :         }
      87             : 
      88           0 :         errorT saveIndexEntry(const IndexEntry& ie, gamenumT replaced) override {
      89           0 :                 return derived()->dyn_saveIndexEntry(ie, replaced);
      90             :         }
      91             : 
      92           0 :         std::pair<errorT, idNumberT> addName(nameT nt, const char* name) override {
      93           0 :                 return derived()->dyn_addName(nt, name);
      94             :         }
      95             : 
      96             : private:
      97        9015 :         std::pair<errorT, IndexEntry> addGameHelper(Game* game) {
      98        9015 :                 std::pair<errorT, IndexEntry> res;
      99        9015 :                 res.second.Init();
     100        9015 :                 res.first = game->Encode(&bbuf_, &res.second);
     101        9015 :                 if (res.first == OK) {
     102        9015 :                         res.first = addGameHelper(&res.second, bbuf_.getData(),
     103             :                                                   bbuf_.GetByteCount(), game->GetWhiteStr(),
     104             :                                                   game->GetBlackStr(), game->GetEventStr(),
     105             :                                                   game->GetSiteStr(), game->GetRoundStr());
     106             :                 }
     107        9015 :                 return res;
     108             :         }
     109             : 
     110       12018 :         errorT addGameHelper(IndexEntry* ie, const byte* srcData, size_t dataLen,
     111             :                              const char* white, const char* black,
     112             :                              const char* event, const char* site,
     113             :                              const char* round) {
     114       12018 :                 auto id = derived()->dyn_addName(NAME_PLAYER, white);
     115       12018 :                 if (id.first != OK)
     116           0 :                         return id.first;
     117       12018 :                 ie->SetWhite(id.second);
     118       12018 :                 nb_->AddElo(id.second, ie->GetWhiteElo());
     119             : 
     120       12018 :                 id = derived()->dyn_addName(NAME_PLAYER, black);
     121       12018 :                 if (id.first != OK)
     122           0 :                         return id.first;
     123       12018 :                 ie->SetBlack(id.second);
     124       12018 :                 nb_->AddElo(id.second, ie->GetBlackElo());
     125             : 
     126       12018 :                 id = derived()->dyn_addName(NAME_EVENT, event);
     127       12018 :                 if (id.first != OK)
     128           0 :                         return id.first;
     129       12018 :                 ie->SetEvent(id.second);
     130             : 
     131       12018 :                 id = derived()->dyn_addName(NAME_SITE, site);
     132       12018 :                 if (id.first != OK)
     133           0 :                         return id.first;
     134       12018 :                 ie->SetSite(id.second);
     135             : 
     136       12018 :                 id = derived()->dyn_addName(NAME_ROUND, round);
     137       12018 :                 if (id.first != OK)
     138           0 :                         return id.first;
     139       12018 :                 ie->SetRound(id.second);
     140             : 
     141       12018 :                 auto offset = derived()->dyn_addGameData(srcData, dataLen);
     142       12018 :                 if (offset.first == OK) {
     143       12018 :                         ie->SetOffset(offset.second);
     144       12018 :                         ie->SetLength(dataLen);
     145             :                 }
     146       12018 :                 return offset.first;
     147             :         }
     148             : 
     149       84126 :         Derived* derived() { return static_cast<Derived*>(this); }
     150             : };
     151             : 
     152             : #endif

Generated by: LCOV version 1.13