> 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

Reply via email to