Scid  4.6.5
codec_memory.h
Go to the documentation of this file.
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 class CodecMemory : public ICodecDatabase {
48 protected:
51 
52 private:
53  std::vector<byte> v_;
54  ByteBuffer bbuf_;
55 
56 public:
57  CodecMemory() : idx_(0), nb_(0), bbuf_(BBUF_SIZE) {}
58 
59  Codec getType() override { return ICodecDatabase::MEMORY; }
60 
61  std::vector<std::string> getFilenames() override {
62  return std::vector<std::string>();
63  }
64 
65  const byte* getGameData(uint32_t offset, uint32_t length) override {
66  ASSERT(offset < v_.size());
67  ASSERT(length <= v_.size() - offset);
68  #if !CPP11_SUPPORT
69  return &v_.front() + offset;
70  #else
71  return v_.data() + offset;
72  #endif
73  }
74 
75  errorT addGame(IndexEntry* ie, const byte* src, size_t length) override {
76  return doAddGame(ie, src, length);
77  }
78 
79  errorT saveGame(IndexEntry* ie, const byte* src, size_t length,
80  gamenumT replaced) override {
81  return doAddGame(ie, src, length, true, replaced);
82  }
83 
84  errorT addGame(Game* game) override {
85  IndexEntry ie;
86  errorT err = encodeGame(game, &ie, &bbuf_);
87  if (err != OK) return err;
88 
89  return doAddGame(&ie, bbuf_.getData(), bbuf_.GetByteCount());
90  }
91 
92  errorT saveGame(Game* game, gamenumT replaced) override {
93  IndexEntry ie;
94  errorT err = encodeGame(game, &ie, &bbuf_);
95  if (err != OK) return err;
96 
97  return doAddGame(&ie, bbuf_.getData(), bbuf_.GetByteCount(), true, replaced);
98  }
99 
100  errorT flush() override {
101  return OK;
102  }
103 
104 protected:
105  errorT dyn_open(fileModeT fMode, const char*, const Progress&, Index* idx,
106  NameBase* nb) override {
107  if (idx == 0 || nb == 0) return ERROR;
108  if (fMode != FMODE_Memory) return ERROR;
109  idx_ = idx;
110  nb_ = nb;
111  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  virtual std::pair<errorT, uint32_t> dyn_addGameData(const byte* src,
128  size_t length) {
129  ASSERT(src != 0);
130 
131  if (v_.size() >= std::numeric_limits<uint32_t>::max())
132  return std::make_pair(ERROR_Full, 0);
133 
134  uint32_t offset = v_.size();
135  v_.insert(v_.end(), src, src + length);
136  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  errorT doAddGame(IndexEntry* ie, const byte* src, size_t length,
157  bool replace = false, gamenumT replaced = 0) {
158  if (replace && replaced >= idx_->GetNumGames()) return ERROR_BadArg;
159 
160  std::pair<errorT, uint32_t> offset = dyn_addGameData(src, length);
161  if (offset.first != OK)
162  return offset.first;
163  ie->SetOffset(offset.second);
164  ie->SetLength(length);
165 
166  if (replace)
167  return idx_->WriteEntry(ie, replaced);
168  else
169  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  errorT encodeGame(Game* game, IndexEntry* resIe, ByteBuffer* resBbuf) {
183  resIe->Init();
184  errorT err = game->Encode(resBbuf, resIe);
185  if (err != OK) return err;
186 
187  err = resIe->SetWhiteName(nb_, game->GetWhiteStr());
188  if (err != OK) return err;
189  err = resIe->SetBlackName(nb_, game->GetBlackStr());
190  if (err != OK) return err;
191  err = resIe->SetEventName(nb_, game->GetEventStr());
192  if (err != OK) return err;
193  err = resIe->SetSiteName(nb_, game->GetSiteStr());
194  if (err != OK) return err;
195  err = resIe->SetRoundName(nb_, game->GetRoundStr());
196  if (err != OK) return err;
197 
198  nb_->AddElo(resIe->GetWhite(), resIe->GetWhiteElo());
199  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
const byte * getGameData(uint32_t offset, uint32_t length) override
Fetches the data of a game (excluding index info), encoded in native format.
Definition: codec_memory.h:65
unsigned char byte
Definition: common.h:97
const errorT ERROR_Full
Definition: error.h:49
Manages memory databases that do not have associated files.
Definition: codec_memory.h:47
const char * GetRoundStr()
Definition: game.h:443
virtual std::pair< errorT, uint32_t > dyn_addGameData(const byte *src, size_t length)
Stores the data of the game into the database.
Definition: codec_memory.h:127
errorT addGame(Game *game) override
Add a game to the database.
Definition: codec_memory.h:84
const char * GetBlackStr()
Definition: game.h:442
const errorT OK
Definition: error.h:23
uint max(int a, int b)
Definition: crosstab.cpp:237
#define ASSERT(f)
Definition: common.h:67
void AddElo(idNumberT id, eloT elo)
Definition: namebase.h:101
errorT dyn_open(fileModeT fMode, const char *, const Progress &, Index *idx, NameBase *nb) override
Opens/Creates a database.
Definition: codec_memory.h:105
const errorT ERROR_BadArg
Definition: error.h:28
errorT AddGame(const IndexEntry *ie)
AddGame() - add a game to the Index : valid pointer to the IndexEntry object with data for the new ga...
Definition: index.h:232
Definition: misc.h:124
Defines the ICodecDatabase interface, which encapsulates the data representation of databases...
eloT GetBlackElo() const
Definition: indexentry.h:252
errorT saveGame(Game *game, gamenumT replaced) override
Replaces a game in the database.
Definition: codec_memory.h:92
const char * GetSiteStr()
Definition: game.h:440
errorT SetSiteName(NameBase *nb, const char *s)
Definition: indexentry.h:217
#define BBUF_SIZE
Definition: common.h:42
errorT addGame(IndexEntry *ie, const byte *src, size_t length) override
Add a game to the database.
Definition: codec_memory.h:75
const char * GetEventStr()
Definition: game.h:439
uint GetByteCount()
Definition: bytebuf.h:59
errorT SetEventName(NameBase *nb, const char *s)
Definition: indexentry.h:211
This interface separates the logic of a database from its representation.
Definition: codec.h:43
void Init()
Definition: indexentry.h:487
Definition: index.h:61
void SetLength(size_t length)
Definition: indexentry.h:92
gamenumT GetNumGames() const
Header getter functions.
Definition: index.h:141
errorT SetRoundName(NameBase *nb, const char *s)
Definition: indexentry.h:223
Index * idx_
Definition: codec_memory.h:49
unsigned short errorT
Definition: error.h:20
NameBase * nb_
Definition: codec_memory.h:50
errorT SetWhiteName(NameBase *nb, const char *s)
Definition: indexentry.h:199
errorT Encode(ByteBuffer *buf, IndexEntry *ie)
Definition: game.cpp:3704
Definition: game.h:227
errorT flush() override
Writes all pending output to the files.
Definition: codec_memory.h:100
errorT SetBlackName(NameBase *nb, const char *s)
Definition: indexentry.h:205
idNumberT GetBlack() const
Definition: indexentry.h:116
const char * GetWhiteStr()
Definition: game.h:441
std::vector< std::string > getFilenames() override
Returns the full path of the files used by the database.
Definition: codec_memory.h:61
uint gamenumT
Definition: common.h:159
fileModeT
Definition: common.h:144
eloT GetWhiteElo() const
Definition: indexentry.h:246
errorT WriteEntry(const IndexEntry *ie, gamenumT idx, bool flush=true)
WriteEntry() - modify a game in the Index.
Definition: index.h:217
const errorT ERROR
Definition: error.h:26
Codec getType() override
Returns the Codec type.
Definition: codec_memory.h:59
idNumberT GetWhite() const
Definition: indexentry.h:109
errorT saveGame(IndexEntry *ie, const byte *src, size_t length, gamenumT replaced) override
Replaces a game in the database.
Definition: codec_memory.h:79
Definition: indexentry.h:54
const byte * getData()
Definition: bytebuf.h:71
void SetOffset(uint32_t offset)
Definition: indexentry.h:88