> I see C/CIF supports many chess variants but it would've been more fitting
> to provide a link to the home page instead:
> http://ccif.sourceforge.net/index.html.
Thanks, this was a copy & paste error, the homepage of C/CIF is of
course <http://ccif.sourceforge.net/index.html>.
The C/CIF library is in progress, and the writer is nearly finished. I hope
that the implementation of the reader is less work, the writer already
provides many basic functionality.
After finishing the library I will do the patches for Scid and Scid vs PC.
I've attached a C++ skeleton file, it gives an overview how the library
works, but only the writer, the interface for the reader is not yet
existing.
In Scidb a C/CIF archive can be opened as a virtual database - this
concept is already realized due to the fact that Scidb is supporting
various database formats - the opening of a C/CIF library will be
super-fast (hopefully) compared to the opening of a PGN file. It
will be possible to do a header search on C/CIF archives, but
position search cannot be done, for this functionality acceleration
data is required, and only the .sci and the .si4 format is providing this.
void
Database::writeArchive(stl::ostream& myOutputStream)
{
cif::Archive arch;
// We want a compact CIF file.
arch.start(myOutputStream, cif::format::Binary, myCreator);
// Setup archive information.
{
cif::ArchiveInfo& info = arch.info();
info.setSource(...);
info.addAuthor(...);
}
// Write a document (for example a HTML description about this archive),
// which will be the first item inside the archive (in this example).
// For ChessBase the sequence order is important.
if (haveDocuments())
{
cif:Document& document = arch.document();
document.start();
document.addBlob(...);
document.finish();
}
// Write the namebase data. In this example we are traversing the
// list of games, but this is not the only way.
{
cif::Namebase& namebase = arch.namebase();
namebase.start();
for (GameIterator g; g = games().begin(); g != games().end())
{
if (!g->event().site().alreadyWritten())
{
cif::Namebase::Site& site = namebase.site(g->event().site().id());
site.putName(...);
site.putCountry(...);
g->event().site().setAlreadyWritten(true);
}
if (!g->event().alreadyWritten())
{
cif::Namebase::Event& site = namebase.event(g->event().id());
event.putTitle(...);
event.putSiteID(g->event().site().id());
event.putDate(...);
event.putType(...);
g->event().setAlreadyWritten(true);
}
if (!g->whitePlayer().alreadyWritten())
{
if (!g->whitePlayer().team().alreadyWritten())
{
cif::Namebase::Team& team = namebase.team(g->whitePlayer().team().id());
team.putName(...);
team.putNation(...);
g->whitePlayer().team().setAlreadyWritten();
}
cif::Namebase::Player& player = namebase.player(g->whitePlayer().id());
player.putName(...);
player.putNation(...);
player.putGender(...);
player.putSpecies(...);
player.putTeamID(g->whitePlayer().team().id());
player.addPlayerID(cif::organization::FIDE, g->whitePlayer().fideID());
}
if (!g->blackPlayer().alreadyWritten())
{
if (!g->black().team().alreadyWritten())
{
cif::Namebase::Team& team = namebase.team(g->blackPlayer().team().id());
team.putName(...);
team.putNation(...);
g->blackPlayer().team().setAlreadyWritten();
}
cif::Namebase::Player& player = namebase.player(g->blackPlayer().id());
player.putName(...);
player.putNation(...);
player.putGender(...);
player.putSpecies(...);
player.putTeamID(g->blackPlayer().team().id());
player.addPlayerID(cif::organization::FIDE, g->blackPlayer().fideID());
}
if (!g->annotator().alreadyWritten())
{
cif::Namebase::Annotator& annotator = namebase.annotator(g->annotator().id());
annotator.putAnnotatorName(...);
g->annotator().setAlreadyWritten();
}
neamebase.flush();
}
namebase.finish();
}
// Write index data (game header information of all games inside the archive).
{
cif::Index index = arch.index();
index.start();
for (GameIterator g; g = games().begin(); g != games().end())
{
{
cif::GameInfo& info = index.game(g->id());
info.setVariant(...);
info.setBoardSize(...);
info.setPieces(...);
}
{
cif::GameInfo::Flags& flags = info.flags();
flags.put(...);
flags.put(...);
}
{
cif::GameAttributes& attrs = info.attributes();
attrs.player(cif::color::White).setID(g->whitePlayer().id());
attrs.player(cif::color::White).team().setID(g->whitePlayer().team().id());
attrs.player(cif::color::Black).setID(g->blackPlayer().id());
attrs.player(cif::color::Black).team().setID(g->blackPlayer().team().id());
attrs.event().setID(g->event().id());
attrs.characteristics().putResult(...);
attrs.characteristics().putRound(...);
attrs.opening().putECO(...);
attrs.extraneous().setAnnotatorID(g->annotator().id());
}
index.flush();
}
index.finish();
}
// Now write the games with the move sections.
{
for (GameIterator g; g = games().begin(); g != games().end())
{
cif::Game& game = arch.game(g->id()); // reference to index
game.start();
// The game header should come first.
{
// We will set some additional attributes.
{
GameAttributes& attrs = game.gameInfo().attributes();
{
cif::GameAttributes::Player& player = attrs.player(cif::color::White);
player.putFederation(...);
player.addTitle(...);
}
{
cif::GameAttributes::Player& player = attrs.player(cif::color::Black);
player.putFederation(...);
player.addTitle(...);
}
}
// Write some private tags.
game.addPrivateTag(...);
game.addPrivateTag(...);
}
// Now write the move section (even if the move section is empty).
{
cif::MoveSection& moves = game.moves();
moves.start();
writeMoveSection(moves, g->mainVariation());
moves.finish(); // will also flush the game header
}
// Finally write the data section if required,
// e.g. the videos referenced inside the move section.
if (g->haveAddOns())
{
cif::GameData& data = game.data();
data.start();
data.addBlob(...);
data.finish();
}
game.finish();
}
}
// Write some binary data (e.g documents), not belonging to any
// specific game or document. This data can be written everywhere,
// but the end of the archive is in general the best place.
if (myDatabase.haveAddOns())
{
cif::ArchiveData& archData = arch.data();
archData.start();
archData.addBlob(...);
archData.finish();
}
arch.finish(); // this object is re-usable
}
void
Database::writeMoveSection(cif::MoveSection& moves, Variation const& var)
{
moves.addPrologue(...);
moves.addEpilogue(...);
for ( ; m = var.begin(); m != var.end())
{
cif::Move& move = moves.move();
move.setFrom(...);
move.setTo(...);
move.setDroppedPiece(...);
move.addPrecedingComment(...);
move.addPostComment(...);
move.setIsEnPassant(...);
move.addAnnotation(...);
move.addBlob(...); // a reference to a BLOb
moves.flush(); // don't forget to flush
for ( ; v = m.variations().begin(); v != m.variations.end())
{
moves.startVariation();
writeMoveSection(moves, *v);
moves.endVariation();
}
}
}
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Scidb-users mailing list
Scidb-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/scidb-users