net.sourceforge.foobase
Class CBFDatabase

java.lang.Object
  |
  +--net.sourceforge.foobase.CBFDatabase

public class CBFDatabase
extends java.lang.Object
implements IsGameDatabase

Implementation of old-style chessbase database.

This class is based on the sources of "CB Utilities" by Andy Duplain (version of 1-Apr-96, obtained from the Pittsburg University FTP site)

None of the code made it directly in this tool (obviously, because the original was written C ;-) but nonetheless, much of the information on which this source is based on, comes from that toolset.

The structure of the index file (.CBI file) is like this:

Byte-offsetLength in bytesContents
04Number of games + 1
.........
4 * (i + 1)4Location of game i (first game is 0) + (i + 2)
.........

The last entry in the index table contains the byte offset in the games datafile for the next game to enter. E.g. if the database contains 5 games, the index file will contain at byte offset 24 (next-game-index ( = 5 + 1) times 4 (length of entries in index file)) the 32-bit value (byte-length-games-file) + 12 (= 2 times index of next game (-= 5 + 1))

The data in the games file is seriously obfuscated, but the table below gives the logical structure without regard for the encoding schemes.

Each game is structured like this:


Field Summary
static java.lang.String __version
           
protected  java.lang.String _dbnam
          Name of the database.
protected  java.io.RandomAccessFile _gms
          Games data file.
protected  java.io.RandomAccessFile _idx
          Index file.
 
Fields inherited from interface net.sourceforge.foobase.IsGameDatabase
__version
 
Constructor Summary
CBFDatabase()
          Default public constructor.
 
Method Summary
 void add(Game g)
          Add a new Game to the database.
protected  void appendMoves(java.io.ByteArrayOutputStream bos, java.io.ByteArrayOutputStream cos, java.util.Vector mvs, Board brd, int halfmove)
          Build move list for game.
protected  void barf(java.io.RandomAccessFile f, long o, byte[] bar, int ofs, int len)
          Write specified byte array to file at given position.
protected  void barfByte(java.io.RandomAccessFile f, long o, byte b)
          Write out one single byte to file at given position.
protected  void barfInt(java.io.RandomAccessFile f, long o, int i)
          Local helper routine to convert 32-bit integer from Java representation to intel-CPU format.
protected  void barfShort(java.io.RandomAccessFile f, long o, int s)
          Write out a 16-bit integer to file at given position and in intel-CPU format.
protected  byte[] buildPlayersInfo(Game g)
          Build players info part of a game to store in the database.
protected  byte[] buildSourceInfo(Game g)
          Build game source info (that is: tournament, round and annotator).
 void close()
          Close a database.
 void create()
          Create a new database.
 void delete(Game g)
          Remove a Game from the database.
protected  java.lang.String extractAnnotator(byte[] p, int ofs)
          Extract annotator information from specified string.
protected  int extractBlackELO(byte[] hdr)
          Extract ELO of black player.
protected  java.lang.String extractECO(byte[] hdr)
          Extract ECO code for game.
protected  java.lang.String extractRound(byte[] p)
          Extract round information from specified string.
protected  int extractWhiteELO(byte[] hdr)
          Extract ELO of white player.
protected  int extractYear(byte[] hdr)
          Extract year game was played.
 Game get(int idx)
          Retrieve a game based on its index in the database.
 int getGameID(Game g)
          Return the game ID of the specified game in this database.
 java.util.Vector getGames()
          Retrieve all games present in the database.
 java.lang.String getHeader(int idx)
          Retrieve a game header text based on its index in the database.
 java.util.Vector getHeaders()
          Retrieve the headers for all games present in the database.
static CBFMoveGenerator getMoveGenerator()
          Get single instance of CBFMoveGenerator class to use for move generation.
 void open()
          Open an existing database.
protected  void parseHeader(byte[] hdr, Game g)
          Extract all relevant information from the game header bytes.
protected  java.lang.String[] parseHeaderText(byte[] txt, int plen)
          Process textual header information such as names of players, tournament etc.
protected  void parseHeaderText(byte[] txt, int plen, Game g)
          Process textual header information such as names of players, tournament etc.
protected  byte[] prepareGameForOutput(Game g, byte[] hdr)
          Prepare buffers to be written to the database.
protected  void processMoves(Game g, byte[] mvs, java.util.Vector notes)
          Process contents of moves and comments byte arrays and convert them to the proper format as required by this package.
 void setName(java.lang.String nam)
          Set name of Game collection.
 int size()
          Returns the number of Games stored in the database.
protected  byte[] slurp(java.io.RandomAccessFile f, long o, int len)
          Local helper method for reading a specified amount of bytes from a file, starting at the specified file offset.
protected  int slurpByte(java.io.RandomAccessFile f, long o)
          Local helper routine to read and convert unsigned 8-bit integer (i.e.
protected  int slurpInt(java.io.RandomAccessFile f, long o)
          Local helper routine to read and convert 32-bit integer in intel-CPU format to Java representation.
protected  int slurpShort(java.io.RandomAccessFile f, long o)
          Local helper routine to read and convert 16-bit integer in intel-CPU format to Java representation.
 void update(Game g)
          Update a Game in the database.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_dbnam

protected java.lang.String _dbnam
Name of the database.

This name contains both the location (directory) and the pure name part of the database.


_idx

protected java.io.RandomAccessFile _idx
Index file.

_gms

protected java.io.RandomAccessFile _gms
Games data file.

__version

public static final java.lang.String __version
Constructor Detail

CBFDatabase

public CBFDatabase()
Default public constructor.
Method Detail

getMoveGenerator

public static CBFMoveGenerator getMoveGenerator()
Get single instance of CBFMoveGenerator class to use for move generation.
Returns:
CBFMoveGenerator to use for old-style chessbase databases

setName

public void setName(java.lang.String nam)
             throws java.lang.Exception
Set name of Game collection.

The meaning of this name is implementation dependent, that is, it is up to the implementing classes to interprete this name.

For example, this may be the name of a PGN file or it may be the basename for an old-style Chessbase database (that will use files with this basename followed by the extensions ".CBI" and ".CBF")

Specified by:
setName in interface IsGameDatabase
Parameters:
nam - String specifying the name of the database.
Throws:
java.lang.Exception - is thrown whenever the name is not acceptable.

create

public void create()
            throws java.lang.Exception
Create a new database.

Note that if the database already exists, its index pointers will be reset, thus effectively emptying the database.

Specified by:
create in interface IsGameDatabase
Throws:
java.lang.Exception - if the database could not be created.

open

public void open()
          throws java.lang.Exception
Open an existing database.
Specified by:
open in interface IsGameDatabase
Throws:
java.lang.Exception - if the database could not be opened.

size

public int size()
         throws java.lang.Exception
Returns the number of Games stored in the database.
Specified by:
size in interface IsGameDatabase
Returns:
int containing the number of Games.
Throws:
java.lang.Exception - if an error occured during the operation.

getGames

public java.util.Vector getGames()
                          throws java.lang.Exception
Retrieve all games present in the database.
Specified by:
getGames in interface IsGameDatabase
Returns:
Vector containing the games present in the database.
Throws:
java.lang.Exception - if an error occured during the operation.

getHeaders

public java.util.Vector getHeaders()
                            throws java.lang.Exception
Retrieve the headers for all games present in the database.
Specified by:
getHeaders in interface IsGameDatabase
Returns:
Vector containing the header strings for all the games present in the database.
Throws:
java.lang.Exception - if an error occured during the operation.

getHeader

public java.lang.String getHeader(int idx)
                           throws java.lang.Exception
Retrieve a game header text based on its index in the database.

The information retrieved by this method serves mainly to display an overview of the games stored in a database.

Contrary to the get() method, this method does not throw an exception if the specified game is deleted.

Parameters:
idx - int zero-based index of the game to retrieve
Returns:
String containing the header information of the specified game (index number, name of white, name of black) or null in case the game is deleted.
Throws:
java.lang.Exception - if an error occured during the operation.

get

public Game get(int idx)
         throws java.lang.Exception
Retrieve a game based on its index in the database.
Specified by:
get in interface IsGameDatabase
Parameters:
idx - int zero-based index of the game to retrieve
Returns:
Game containing the specified game
Throws:
java.lang.Exception - if an error occured during the operation.

add

public void add(Game g)
         throws java.lang.Exception
Add a new Game to the database.

This method is not required to verify insertion of duplicate Games.

Note that the input parameter is changed: its game ID is set.

Specified by:
add in interface IsGameDatabase
Parameters:
g - Game to add to the database.
Throws:
java.lang.Exception - if an error occured during the operation.

prepareGameForOutput

protected byte[] prepareGameForOutput(Game g,
                                      byte[] hdr)
                               throws java.lang.Exception
Prepare buffers to be written to the database.

This method uses a somewhat dubious technique to return two pieces of data (well, two byte arrays): one is a fixed size array that needs to be pre-allocated and passed to the function as an argument, the other one is the function result.

Parameters:
g - Game to add to the database.
hdr - byte[] to store the header information in (this buffer should contain HEADER_LEN bytes)
Returns:
byte[] containing the data to write to the database file (including everything but the kitchen sink^H^H^H^H^H^H^H^H^H^H^H^H header)
Throws:
java.lang.Exception - if an error occured during the operation.

update

public void update(Game g)
            throws java.lang.Exception
Update a Game in the database.

Note that this method is only required to work on Games that were previously read from the same database as the update is being done.

Specified by:
update in interface IsGameDatabase
Parameters:
g - Game to update in the database.
Throws:
java.lang.Exception - if an error occured during the operation.

delete

public void delete(Game g)
            throws java.lang.Exception
Remove a Game from the database.

Note that this method is only required to work on Games that were previously read from the same database as the update is being done.

Specified by:
delete in interface IsGameDatabase
Parameters:
g - Game to remove from the database.
Throws:
java.lang.Exception - if an error occured during the operation.

close

public void close()
           throws java.lang.Exception
Close a database.
Specified by:
close in interface IsGameDatabase
Throws:
java.lang.Exception - if an error occured during the operation.

getGameID

public int getGameID(Game g)
Return the game ID of the specified game in this database.
Parameters:
g - Game to test for its presence in this database
Returns:
int containing the internal game ID in this database for the specified game, or -1 if the game is not stored in this database.

parseHeader

protected void parseHeader(byte[] hdr,
                           Game g)
Extract all relevant information from the game header bytes.
Parameters:
hdr - byte[] containing the decoded header bytes read from the database
g - Game to initialize with the extracted header information

extractYear

protected int extractYear(byte[] hdr)
Extract year game was played.
Parameters:
hdr - byte[] containing the decoded header bytes read from the database
Returns:
int containing the year that the game was played, or 0 in case no year information was present in the header

extractWhiteELO

protected int extractWhiteELO(byte[] hdr)
Extract ELO of white player.
Parameters:
hdr - byte[] containing the decoded header bytes read from the database
Returns:
int containing the ELO points of white or 0 in case no such information was present

extractBlackELO

protected int extractBlackELO(byte[] hdr)
Extract ELO of black player.
Parameters:
hdr - byte[] containing the decoded header bytes read from the database
Returns:
int containing the ELO points of black or 0 in case no such information was present

extractECO

protected java.lang.String extractECO(byte[] hdr)
Extract ECO code for game.
Parameters:
hdr - byte[] containing the decoded header bytes read from the database
Returns:
String containing the ECO code for the game

parseHeaderText

protected void parseHeaderText(byte[] txt,
                               int plen,
                               Game g)
Process textual header information such as names of players, tournament etc.
Parameters:
txt - byte[] containing the decoded game header text bytes
plen - int containing the length of the players section in txt
g - Game to store information in

parseHeaderText

protected java.lang.String[] parseHeaderText(byte[] txt,
                                             int plen)
Process textual header information such as names of players, tournament etc.
Parameters:
txt - byte[] containing the decoded game header text bytes
plen - int containing the length of the players section in txt
g - Game to store information in
Returns:
String[] containing the different game info strings. The returned items are like this:

SubscriptContents
0Round
1Annotator
2Name white player
3Name black player
4Tournament

Whenever a certain item is not present in the game, its entry is set to null


extractRound

protected java.lang.String extractRound(byte[] p)
Extract round information from specified string.

Round information is expected to be between parenthesis or brackets, but a slash, followed by a left parenthesis is not a valid round prefix.

On return, the input parameter may be changed in that the bytes that contained the round information are set to spaces.

Parameters:
p - byte[] containing the text to search for round information
Returns:
String containing the round information or null in case no round information was found.

extractAnnotator

protected java.lang.String extractAnnotator(byte[] p,
                                            int ofs)
Extract annotator information from specified string.

Annotator information is expected to be between brackets.

On return, the input parameter may be changed.

Parameters:
p - byte[] containing the text to search for annotator information
ofs - int containing the byte offset from where to start looking for the annotator.
Returns:
String containing the annotator information or null in case no annotator information was found.

processMoves

protected void processMoves(Game g,
                            byte[] mvs,
                            java.util.Vector notes)
                     throws java.lang.Exception
Process contents of moves and comments byte arrays and convert them to the proper format as required by this package.
Parameters:
g - Game to which the moves belong. The properties of this object will be changed by this method.
mvs - byte[] containing the game moves
notes - Vector containing the move comments. Note that this Vector is gradually emptied until is is either empty or contains only the game level annotation entry.
Throws:
java.lang.Exception - if an error occured during the operation.

buildPlayersInfo

protected byte[] buildPlayersInfo(Game g)
Build players info part of a game to store in the database.
Parameters:
g - Game to grab information from
Returns:
byte[] containing the players information

buildSourceInfo

protected byte[] buildSourceInfo(Game g)
Build game source info (that is: tournament, round and annotator).
Parameters:
g - Game to grab information from
Returns:
byte[] containing the source information.

appendMoves

protected void appendMoves(java.io.ByteArrayOutputStream bos,
                           java.io.ByteArrayOutputStream cos,
                           java.util.Vector mvs,
                           Board brd,
                           int halfmove)
Build move list for game.
Parameters:
bos - ByteArrayOutputStream to write moves to
cos - ByteArrayOutputStream to write comments to
mvs - Vector containing the variation to process
brd - Board with setup at beginning of the variation
halfmove - int containing the number of the halfmove that is at the start of the variation (first move of the game is halfmove one)

slurpInt

protected int slurpInt(java.io.RandomAccessFile f,
                       long o)
                throws java.io.IOException
Local helper routine to read and convert 32-bit integer in intel-CPU format to Java representation.

The intel format stores a 32-bit 0x12345678 as bytes 0x34, 0x12, 0x78, 0x56.

Parameters:
f - RandomAccessFile to read from
o - long offset to read from
Returns:
int containing the java 32-bit integer value
Throws:
java.io.IOException - if an I/O error occurs

slurpShort

protected int slurpShort(java.io.RandomAccessFile f,
                         long o)
                  throws java.io.IOException
Local helper routine to read and convert 16-bit integer in intel-CPU format to Java representation.

The intel format stores a 16-bit 0x1234 as bytes 0x34, 0x12.

Parameters:
f - RandomAccessFile to read from
o - long offset to read from
Returns:
int containing the java 16-bit integer value
Throws:
java.io.IOException - if an I/O error occurs

slurpByte

protected int slurpByte(java.io.RandomAccessFile f,
                        long o)
                 throws java.io.IOException
Local helper routine to read and convert unsigned 8-bit integer (i.e. one byte)
Parameters:
f - RandomAccessFile to read from
o - long offset to read from
Returns:
int containing the java 8-bit integer value
Throws:
java.io.IOException - if an I/O error occurs

slurp

protected byte[] slurp(java.io.RandomAccessFile f,
                       long o,
                       int len)
                throws java.io.IOException
Local helper method for reading a specified amount of bytes from a file, starting at the specified file offset.

Note that this method will block until all requested bytes are read (or until an end-of-file or an exception is detected)

Parameters:
f - RandomAccessFile to read from
o - long offset to read from
len - int number of bytes to read.
Returns:
byte[] of length len bytes containing the requested data.
Throws:
java.io.IOException - if an I/O error occurs

barfInt

protected void barfInt(java.io.RandomAccessFile f,
                       long o,
                       int i)
                throws java.io.IOException
Local helper routine to convert 32-bit integer from Java representation to intel-CPU format.

The intel format stores a 32-bit 0x12345678 as bytes 0x34, 0x12, 0x78, 0x56.

Parameters:
f - RandomAccessFile to read from
o - long offset to read from
i - int to write
Throws:
java.io.IOException - if an I/O error occurs

barfShort

protected void barfShort(java.io.RandomAccessFile f,
                         long o,
                         int s)
                  throws java.io.IOException
Write out a 16-bit integer to file at given position and in intel-CPU format.

The intel format stores a 16-bit 0x1234 as bytes 0x34, 0x12.

Parameters:
f - RandomAccessFile to write to
o - long offset to write to
s - int 16-bit integer to write
Throws:
java.io.IOException - if an I/O error occurs

barfByte

protected void barfByte(java.io.RandomAccessFile f,
                        long o,
                        byte b)
                 throws java.io.IOException
Write out one single byte to file at given position.
Parameters:
f - RandomAccessFile to write to
o - long offset to write to
b - byte to write
Throws:
java.io.IOException - if an I/O error occurs

barf

protected void barf(java.io.RandomAccessFile f,
                    long o,
                    byte[] bar,
                    int ofs,
                    int len)
             throws java.io.IOException
Write specified byte array to file at given position.
Parameters:
f - RandomAccessFile to write to
o - long offset to write to
bar - byte[] to write
ofs - int offset in bar from where to write out its contents
len - int number of bytes to write
Throws:
java.io.IOException - if an I/O error occurs