38 std::streamsize fileSize_ = 0;
39 std::string filename_;
40 std::vector<char> buf_;
49 return std::vector<std::string>(1, filename_);
55 return (errFile !=
OK) ? errFile : errProxy;
67 ASSERT(filename && !file_.is_open());
69 if (filename_.empty())
76 buf_.resize(128 * 1024);
77 nRead_ = nParsed_ = buf_.size();
78 file_.pubsetbuf(
nullptr, nRead_);
80 fileSize_ = file_.pubseekoff(0, std::ios::end);
96 const auto verge = 3 * (nRead_ / 4);
97 if (nParsed_ > verge && nRead_ == buf_.size()) {
100 std::copy_n(buf_.data() + verge, nRead_, buf_.data());
101 nRead_ += file_.sgetn(buf_.data() + nRead_, verge);
107 {buf_.data() + nParsed_, buf_.data() + nRead_}, visitor);
109 bool eof = (nRead_ - nParsed_ == parse.first);
110 if (eof && nRead_ == buf_.size()) {
112 if (nRead_ <= 128 * 1024 * 1024) {
114 buf_.resize(nRead_ * 2);
115 nRead_ += file_.sgetn(buf_.data() + nRead_, nRead_);
119 nRead_ = nParsed_ = 0;
120 parseLog_.
log.append(
"PGN parsing aborted.\n");
124 nParsed_ += parse.first;
125 parseLog_.
logGame(parse.first, visitor);
138 return std::make_pair(parseLog_.
n_bytes / 1024, fileSize_ / 1024);
163 std::pair<const char*, unsigned>
pgn = game->
WriteToPGN(75,
true);
166 file_.pubseekpos(fileSize_);
167 if (file_.sputn(pgn.first, pgn.second) == pgn.second) {
168 fileSize_ += pgn.second;
182 dest.push_back(
'\n');
188 dest.insert(dest.end(), next_move,
189 next_move + std::strlen(next_move));
196 template <
typename TCont>
198 auto format_tag = [&dest](
const char* tag,
const char* value) {
200 dest.insert(dest.end(), tag, tag + std::strlen(tag));
204 auto value_begin = dest.size();
205 dest.insert(dest.end(), value, value + std::strlen(value));
210 dest.push_back(
'\n');
212 auto format_tag_question_mark = [&format_tag](
const char* tag,
214 format_tag(tag, (*value) ? value :
"?");
217 size_t tags_size = dest.size();
220 return dest.size() - tags_size;
errorT flush() final
Writes all pending output to the files.
#define PGN_STYLE_COMMENTS
std::pair< std::size_t, bool > parse_game(pgn_impl::InputMemory input, TVisitor &&parser)
Read a PGN game from memory, grouping characters in tokens and dispatching them to a PGN parser...
void tags_extra(const Game &game, TFunc visitor)
const char * GetNextSAN()
std::vector< std::string > getFilenames() const final
Returns the full path of the files used by the database.
errorT gameAdd(Game *game)
Add a game into the database.
const errorT ERROR_FileWrite
This class implements a PGN "visitor" that invokes the appropriate member functions of the associated...
const char * GetMoveComment() const
bool logGame(size_t nBytes, const PgnVisitor &visitor)
Format and store errors occurred while parsing a Game.
Codec getType() const final
Returns the Codec type.
errorT MoveForwardInPGN()
std::pair< size_t, size_t > parseProgress()
Returns info about the parsing progress.
std::pair< const char *, unsigned > WriteToPGN(uint lineWidth=0, bool NewLineAtEnd=false, bool newLineToSpaces=true)
errorT Open(const char *filename, fileModeT fmode)
Opens a file.
#define PGN_STYLE_SCIDFLAGS
Implements a parser that converts PGN text into SCID's Game objects.
Implements the CodecProxy class, which serves as base class for non-native databases.
static size_t encode(Game &game, TCont &dest)
Encode a game into PGN format.
unsigned long long n_bytes
void SetPgnFormat(gameFormatT gf)
static size_t encodeTags(Game &game, TCont &dest)
Base class for non-native databases.
errorT parseNext(Game &game)
Reads the next game.
const errorT ERROR_FileSeek
errorT flush() override
Writes all pending output to the files.
Adds some helper functions to std::filebuf:
void tags_STR(const Game &game, TFunc visitor)
errorT open(const char *filename, fileModeT fmode)
Opens/creates a PGN database.
Extends the std:filebuf class with performance improvements.
void escape_string(TString &str, std::size_t pos)
Escape quote and backslash chars according to the PGN standard: "A quote inside a string is represent...
const errorT ERROR_NotFound
const errorT ERROR_FileOpen
const char * parseErrors()
Returns the list of errors produced by parseNext() calls.