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: 2018-02-05 16:49:44 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(&ie, srcData, dataLen,
      57             :                                   srcNb->GetName(NAME_PLAYER, srcIe->GetWhite()),
      58             :                                   srcNb->GetName(NAME_PLAYER, srcIe->GetBlack()),
      59             :                                   srcNb->GetName(NAME_EVENT, srcIe->GetEvent()),
      60             :                                   srcNb->GetName(NAME_SITE, srcIe->GetSite()),
      61             :                                   srcNb->GetName(NAME_ROUND, srcIe->GetRound()));
      62        3003 :                 if (err != OK)
      63           0 :                         return err;
      64             : 
      65        3003 :                 return derived()->dyn_addIndexEntry(ie);
      66             :         }
      67             : 
      68        7014 :         errorT addGame(Game* game) override {
      69        7014 :                 std::pair<errorT, IndexEntry> ie = addGameHelper(game);
      70        7014 :                 if (ie.first != OK)
      71           0 :                         return ie.first;
      72             : 
      73        7014 :                 return derived()->dyn_addIndexEntry(ie.second);
      74             :         }
      75             : 
      76        2001 :         errorT saveGame(Game* game, gamenumT replaced) override {
      77        2001 :                 if (replaced >= idx_->GetNumGames())
      78           0 :                         return ERROR_BadArg;
      79             : 
      80        2001 :                 std::pair<errorT, IndexEntry> ie = addGameHelper(game);
      81        2001 :                 if (ie.first != OK)
      82           0 :                         return ie.first;
      83             : 
      84        2001 :                 return derived()->dyn_saveIndexEntry(ie.second, replaced);
      85             :         }
      86             : 
      87           0 :         errorT saveIndexEntry(const IndexEntry& ie, gamenumT replaced) override {
      88           0 :                 return derived()->dyn_saveIndexEntry(ie, replaced);
      89             :         }
      90             : 
      91           0 :         std::pair<errorT, idNumberT> addName(nameT nt, const char* name) override {
      92           0 :                 return derived()->dyn_addName(nt, name);
      93             :         }
      94             : 
      95             : private:
      96        9015 :         std::pair<errorT, IndexEntry> addGameHelper(Game* game) {
      97        9015 :                 std::pair<errorT, IndexEntry> res;
      98        9015 :                 res.second.Init();
      99        9015 :                 res.first = game->Encode(&bbuf_, &res.second);
     100        9015 :                 if (res.first == OK) {
     101        9015 :                         res.first = addGameHelper(&res.second, bbuf_.getData(),
     102             :                                                   bbuf_.GetByteCount(), game->GetWhiteStr(),
     103             :                                                   game->GetBlackStr(), game->GetEventStr(),
     104             :                                                   game->GetSiteStr(), game->GetRoundStr());
     105             :                 }
     106        9015 :                 return res;
     107             :         }
     108             : 
     109       12018 :         errorT addGameHelper(IndexEntry* ie, const byte* srcData, size_t dataLen,
     110             :                              const char* white, const char* black,
     111             :                              const char* event, const char* site,
     112             :                              const char* round) {
     113       12018 :                 std::pair<errorT, idNumberT> id =
     114             :                     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