LCOV - code coverage report
Current view: top level - src - codec_proxy.h (source / functions) Hit Total Coverage
Test: test_coverage.info Lines: 32 42 76.2 %
Date: 2017-06-21 14:32:49 Functions: 4 8 50.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 CodecProxy class, which serves as base class for non-native
      22             :  * databases.
      23             :  */
      24             : 
      25             : #ifndef CODEC_PROXY_H
      26             : #define CODEC_PROXY_H
      27             : 
      28             : #include "codec.h"
      29             : #include "codec_memory.h"
      30             : #include "common.h"
      31             : #include "game.h"
      32             : 
      33             : #if !CPP11_SUPPORT
      34             : #define override
      35             : #endif
      36             : 
      37             : /**
      38             :  * Base class for non-native databases.
      39             :  * Every class derived from ICodecDatabase must keep an @e Index object and the
      40             :  * corresponding @e NameBase object fully updated in memory.
      41             :  * This implies that the virtual function dyn_open() must load in memory the
      42             :  * header's data of all the games; however a dependency between the codecs and
      43             :  * the @e Index class is not desirable.
      44             :  * This class provides an interface that encapsulates the codecs, requiring only
      45             :  * the ability to exchange @e Game objects.
      46             :  */
      47             : template <typename Derived>
      48          26 : class CodecProxy : public CodecMemory {
      49             : protected:
      50             :         /**
      51             :          * Opens/creates a database encoded in a non-native format.
      52             :          * @param filename: full path of the database to be opened.
      53             :          * @param fMode:    valid file access mode.
      54             :          * @returns OK in case of success, an @p errorT code otherwise.
      55             :          */
      56             :         errorT open(const char* filename, fileModeT fMode);
      57             : 
      58             :         /**
      59             :          * Reads the next game.
      60             :          * A derived class implements this function to sequentially read the games
      61             :          * contained into the database.
      62             :          * @param Game*: valid pointer to the Game object where the data will be stored.
      63             :          * @returns
      64             :          * - OK on success.
      65             :          * - ERROR_NotFound if there are no more games to be read.
      66             :          * - ERROR code if the game cannot be read and was skipped.
      67             :          */
      68             :         errorT parseNext(Game*) {
      69             :                 return ERROR_NotFound;
      70             :         }
      71             : 
      72             :         /**
      73             :          * Returns info about the parsing progress.
      74             :          * @returns a pair<size_t, size_t> where first element is the quantity of
      75             :          * data parsed and second one is the total amount of data of the database.
      76             :          */
      77             :         std::pair<size_t, size_t> parseProgress() {
      78             :                 return std::pair<size_t, size_t>(1, 1);
      79             :         }
      80             : 
      81             :         /**
      82             :          * Returns the list of errors produced by parseNext() calls.
      83             :          */
      84             :         const char* parseErrors() {
      85             :                 return NULL;
      86             :         }
      87             : 
      88             :         /**
      89             :          * Adds a game into the database.
      90             :          * @param Game*: valid pointer to a Game object with the new data.
      91             :          * @returns OK in case of success, an @p errorT code otherwise.
      92             :          */
      93             :         errorT dyn_addGame(Game*) {
      94             :                 return ERROR_CodecUnsupFeat;
      95             :         }
      96             : 
      97             :         /**
      98             :          * Replaces a game in the database.
      99             :          * @param Game*:    valid pointer to a Game object with the new data.
     100             :          * @param gamenumT: valid gamenumT of the game to be replaced.
     101             :          * @returns OK in case of success, an @p errorT code otherwise.
     102             :          */
     103             :         errorT dyn_saveGame(Game*, gamenumT) {
     104             :                 return ERROR_CodecUnsupFeat;
     105             :         }
     106             : 
     107             : 
     108             : private:
     109        1000 :         errorT addGame(Game* game) override {
     110        1000 :                 errorT err = getDerived()->dyn_addGame(game);
     111        1000 :                 if (err != OK) return err;
     112             : 
     113        1000 :                 return CodecMemory::addGame(game);
     114             :         }
     115             : 
     116           0 :         errorT saveGame(Game* game, gamenumT replaced) override {
     117           0 :                 errorT err = getDerived()->dyn_saveGame(game, replaced);
     118             :                 if (err != OK) return err;
     119             : 
     120             :                 return CodecMemory::saveGame(game, replaced);
     121             :         }
     122             : 
     123        1000 :         errorT addGame(IndexEntry* ie, const byte* src, size_t length) override {
     124        2000 :                 Game game;
     125        1000 :                 errorT err = decodeGame(ie, src, length, game);
     126        1000 :                 if (err != OK) return err;
     127             : 
     128        1000 :                 err = getDerived()->dyn_addGame(&game);
     129        1000 :                 if (err != OK) return err;
     130             : 
     131        1000 :                 return CodecMemory::addGame(ie, src, length);
     132             :         }
     133             : 
     134           0 :         errorT saveGame(IndexEntry* ie, const byte* src, size_t length,
     135             :                         gamenumT replaced) override {
     136           0 :                 Game game;
     137           0 :                 errorT err = decodeGame(ie, src, length, game);
     138           0 :                 if (err != OK) return err;
     139             : 
     140           0 :                 err = getDerived()->dyn_saveGame(&game, replaced);
     141           0 :                 if (err != OK) return err;
     142             : 
     143             :                 return CodecMemory::saveGame(ie, src, length, replaced);
     144             :         }
     145             : 
     146             :         /*
     147             :          * Creates a memory database and invokes the function open(), which will
     148             :          * open the non-native database @p filename. Subsequently, the function
     149             :          * parseNext() is repeatedly called until it returns ERROR_NotFound, and
     150             :          * the games are copied into the memory database.
     151             :          */
     152          13 :         errorT dyn_open(fileModeT fMode, const char* filename,
     153             :                         const Progress& progress, Index* idx,
     154             :                         NameBase* nb) override {
     155          13 :                 if (filename == 0) return ERROR;
     156             : 
     157          26 :                 errorT err = CodecMemory::dyn_open(FMODE_Memory, filename, progress, idx, nb);
     158          13 :                 if (err != OK) return err;
     159             : 
     160          13 :                 err = getDerived()->open(filename, fMode);
     161          13 :                 if (err != OK) return err;
     162             : 
     163          22 :                 Game g;
     164             :                 uint nImported = 0;
     165        4022 :                 while ((err = getDerived()->parseNext(&g)) != ERROR_NotFound) {
     166        2000 :                         if (err != OK) continue;
     167             : 
     168        2000 :                         err = CodecMemory::addGame(&g);
     169        2000 :                         if (err != OK) break;
     170             : 
     171        2000 :                         if (++nImported % 1024 == 0) {
     172           0 :                                 std::pair<size_t, size_t> count = getDerived()->parseProgress();
     173           0 :                                 if (!progress.report(count.first, count.second)) {
     174             :                                         err = ERROR_UserCancel;
     175             :                                         break;
     176             :                                 }
     177             :                         }
     178             :                 }
     179          33 :                 progress(1, 1, getDerived()->parseErrors());
     180             : 
     181          11 :                 return (err == ERROR_NotFound) ? OK : err;
     182             :         }
     183             : 
     184             :         /**
     185             :          * Decodes a Game object from native format.
     186             :          * @param srcIe:        valid pointer to the header data.
     187             :          * @param src:          valid pointer to a buffer containing the game data
     188             :          *                      (encoded in native format).
     189             :          * @param length:       length of the game data (in bytes).
     190             :          * @param[out] resGame: the Game object where the data will be decoded.
     191             :          * @returns OK in case of success, an @p errorT code otherwise.
     192             :          */
     193        1000 :         errorT decodeGame(const IndexEntry* srcIe, const byte* src, size_t length,
     194             :                           Game& resGame) {
     195        2000 :                 ByteBuffer buf(0);
     196        1000 :                 buf.ProvideExternal(const_cast<byte*>(src), length);
     197        1000 :                 errorT err = resGame.Decode(&buf, GAME_DECODE_ALL);
     198        1000 :                 if (err == OK) err = resGame.LoadStandardTags(srcIe, nb_);
     199        2000 :                 return err;
     200             :         }
     201             : 
     202             :         /**
     203             :          * Return a pointer to the derived class.
     204             :          */
     205             :         Derived* getDerived() { return static_cast<Derived*>(this); }
     206             : };
     207             : 
     208             : #if !CPP11_SUPPORT
     209             : #undef override
     210             : #endif
     211             : 
     212             : #endif

Generated by: LCOV version 1.12