Scid  4.6.5
codec_scid4.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 CodecScid4 class, which manages the databases encoded
22  * in Scid format version 4.
23  */
24 
25 #ifndef CODEC_SCID4_H
26 #define CODEC_SCID4_H
27 
28 #include "codec_memory.h"
29 #include "common.h"
30 #include "filebuf.h"
31 
32 #if !CPP11_SUPPORT
33 #define override
34 #endif
35 
36 /**
37  * This class manages databases encoded in Scid format v4.
38  */
39 class CodecScid4 : public CodecMemory {
40  std::string filename_;
41  FilebufAppend gfile_;
42  char gamecache_[128*1024];
43 
44 public:
45  Codec getType() override { return ICodecDatabase::SCID4; }
46 
47  /**
48  * Returns the full path of the three files (index, namebase and gamefile)
49  * used by the database.
50  */
51  std::vector<std::string> getFilenames() override {
52  std::vector<std::string> res;
53  res.push_back(filename_ + INDEX_SUFFIX);
54  res.push_back(filename_ + NameBase::Suffix());
55  res.push_back(filename_ + ".sg4");
56  return res;
57  };
58 
59  const byte* getGameData(uint32_t offset, uint32_t length) override {
60  if (offset >= gfile_.size())
61  return NULL;
62  if (length > sizeof(gamecache_))
63  return NULL;
64 
65  if (gfile_.pubseekpos(offset) == -1)
66  return NULL;
67  if (gfile_.sgetn(gamecache_, length) != std::streamsize(length))
68  return NULL;
69 
70  return reinterpret_cast<const byte*>(gamecache_);
71  }
72 
73  errorT flush() override {
74  errorT err = CodecMemory::flush();
75  if (err != OK) return err;
76 
77  err = idx_->flush();
78  if (err == OK) {
79  // *** Compatibility ***
80  // Even if name's frequency is no longer used, it's necessary to
81  // keep the compatibility with older Scid versions, forcing a
82  // recalculation.
84  err = nb_->flush(idx_);
85  }
86  errorT errGfile = (gfile_.pubsync() == 0) ? OK : ERROR_FileWrite;
87 
88  return (err == OK) ? errGfile : err;
89  }
90 
91 protected:
92  errorT dyn_open(fileModeT fMode, const char* filename,
93  const Progress& progress, Index* idx,
94  NameBase* nb) override {
95  if (filename == 0 || idx == 0 || nb == 0) return ERROR;
96 
97  errorT err = CodecMemory::dyn_open(FMODE_Memory, 0, progress, idx, nb);
98  if (err != OK) return err;
99 
100  filename_ = filename;
101  if (filename_.empty()) return ERROR_FileOpen;
102 
103  err = gfile_.open(filename_ + ".sg4", fMode);
104  if (err != OK) return err;
105 
106  if (fMode == FMODE_Create) {
107  err = idx->Create(filename);
108  if (err == OK) err = nb->Create(filename);
109  } else {
110  err = idx->Open(filename, fMode);
111  if (err == OK) err = nb->ReadEntireFile(filename);
112  if (err == OK) err = idx->ReadEntireFile(nb, progress);
113  }
114 
115  return err;
116  }
117 
118  std::pair<errorT, uint32_t> dyn_addGameData(const byte* src,
119  size_t length) override {
120  ASSERT(src != 0);
121  const char* data = reinterpret_cast<const char*>(src);
122 
123  // The Scid4 format uses 32-bits to store games' offset.
124  size_t offset = gfile_.size();
125  static const uint32_t MAXSZ = std::numeric_limits<uint32_t>::max();
126  if (offset >= MAXSZ || length >= MAXSZ - offset)
127  return std::make_pair(ERROR_Full, 0);
128 
129  // The Scid4 format stores games into blocks of 128KB.
130  // If the current block does not have enough space, we fill it with
131  // random data and use the next one.
132  static const size_t GF_BLOCK = 128 * 1024;
133  if (length > GF_BLOCK)
134  return std::make_pair(ERROR_Full, 0);
135  size_t blockSpace = GF_BLOCK - (offset % GF_BLOCK);
136  if (blockSpace < length) {
137  errorT err = gfile_.append(data, blockSpace);
138  if (err != OK)
139  return std::make_pair(err, 0);
140  offset += blockSpace;
141  }
142 
143  errorT err = gfile_.append(data, length);
144  return std::make_pair(err, uint32_t(offset));
145  }
146 };
147 
148 #if !CPP11_SUPPORT
149 #undef override
150 #endif
151 
152 #endif
unsigned char byte
Definition: common.h:97
const errorT ERROR_Full
Definition: error.h:49
errorT append(const char_type *s, std::streamsize count)
Writes, at the end of the file, count characters from the character array whose first element is poin...
Definition: filebuf.h:223
Manages memory databases that do not have associated files.
Definition: codec_memory.h:47
errorT flush(const Index *idx)
Definition: namebase.h:89
std::streamoff pubseekpos(std::streamoff pos)
Repositions the internal buffer or invoke filebuf::seekpos().
Definition: filebuf.h:252
const errorT OK
Definition: error.h:23
uint max(int a, int b)
Definition: crosstab.cpp:237
const errorT ERROR_FileWrite
Definition: error.h:32
#define ASSERT(f)
Definition: common.h:67
Codec getType() override
Returns the Codec type.
Definition: codec_scid4.h:45
errorT dyn_open(fileModeT fMode, const char *, const Progress &, Index *idx, NameBase *nb) override
Opens/Creates a database.
Definition: codec_memory.h:105
errorT open(const std::string &filename, fileModeT fmode)
Opens a file and store its size.
Definition: filebuf.h:197
Definition: misc.h:124
void hackedNameFreq()
Definition: namebase.h:95
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_scid4.h:59
errorT ReadEntireFile(const char *filename)
NameBase::ReadNameFile() - Reads a NameBase file into memory.
Definition: namebase.cpp:110
size_t size() const
Returns the size of the file.
Definition: filebuf.h:210
int pubsync()
Invokes std::filebuf::sync() to write all pending output to the file.
Definition: filebuf.h:216
static const char * Suffix()
Definition: namebase.h:81
errorT flush()
flush() - writes all cached data to the file
Definition: index.h:239
errorT Create(const char *filename)
NameBase::Create() - Create an empty NameBase file : the filename (without extension) ...
Definition: namebase.cpp:83
Definition: index.h:61
errorT ReadEntireFile(NameBase *nb, const Progress &progress)
Definition: index.cpp:137
Index * idx_
Definition: codec_memory.h:49
std::vector< std::string > getFilenames() override
Returns the full path of the three files (index, namebase and gamefile) used by the database...
Definition: codec_scid4.h:51
unsigned short errorT
Definition: error.h:20
errorT Open(const char *filename, fileModeT fmode)
Definition: index.cpp:79
NameBase * nb_
Definition: codec_memory.h:50
const char INDEX_SUFFIX[]
Definition: index.h:38
errorT Create(const char *filename)
Definition: index.cpp:55
This class manages databases encoded in Scid format v4.
Definition: codec_scid4.h:39
Optimizes std::filebuf for random-access reading.
Definition: filebuf.h:184
errorT flush() override
Writes all pending output to the files.
Definition: codec_memory.h:100
std::streamsize sgetn(char_type *s, std::streamsize count)
Invoke filebuf::xsgetn() and update filePos_.
Definition: filebuf.h:241
Extends the std:filebuf class with performance improvements.
fileModeT
Definition: common.h:144
const errorT ERROR
Definition: error.h:26
errorT dyn_open(fileModeT fMode, const char *filename, const Progress &progress, Index *idx, NameBase *nb) override
Opens/Creates a database.
Definition: codec_scid4.h:92
errorT flush() override
Writes all pending output to the files.
Definition: codec_scid4.h:73
const errorT ERROR_FileOpen
Definition: error.h:31
Implements the CodecMemory class, which manages the memory representation of the open databases...
std::pair< errorT, uint32_t > dyn_addGameData(const byte *src, size_t length) override
Stores the data of the game into the database.
Definition: codec_scid4.h:118