/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** Supermodel is free software: you can redistribute it and/or modify it under
** the terms of the GNU General Public License as published by the Free
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see .
**/
/*
* BlockFile.h
*
* Header file for block format container file management.
*/
#ifndef INCLUDED_BLOCKFILE_H
#define INCLUDED_BLOCKFILE_H
#include
/*
* CBlockFile:
*
* Block format container file. The file format is a series of consecutive,
* variable-length blocks referenced by unique name strings.
*
* All strings (comments and names) will be truncated to 1024 bytes, not
* including the null terminator.
*
* Members do not generate any output messages.
*/
class CBlockFile
{
public:
/*
* Read(data, numBytes):
*
* Reads data from the current file position.
*
* Parameters:
* data Buffer to read to.
* numBytes Number of bytes to read.
*
* Returns:
* Number of bytes read. If not the same as numBytes, an error
* occurred.
*/
unsigned Read(void *data, unsigned numBytes);
/*
* FindBlock(name):
*
* Scans the file for a block with the given name string. When it is found,
* the file pointer is set to the beginning of the data region.
*
* Parameters:
* name Name of block to locate.
*
* Returns:
* OKAY if found, FAIL if unable to locate.
*/
bool FindBlock(const char *name);
/*
* Write(data, numBytes):
*
* Outputs data at the current file pointer position. Updates the block
* header appropriately.
*
* Parameters:
* data Data to write.
* numBytes Number of bytes to write.
*/
void Write(const void *data, unsigned numBytes);
/*
* NewBlock(name, comment):
*
* Begins a new block. Writes the block header and sets the file pointer to
* the beginning of its data area.
*
* Parameters:
* name Block name. Must be unique and not NULL.
* comment Comment string to embed in the block header.
*/
void NewBlock(const char *title, const char *comment);
/*
* Create(file, headerName, comment):
*
* Opens a block file for writing and creates the header block. This
* function must be called before attempting to write data. Otherwise, all
* write commands will be silently ignored. Read commands will be ignored
* and will always return 0's.
*
* Parameters:
* file File path.
* headerName Block name for header. Must be unique and not NULL.
* comment Comment string that will be embedded into file header.
*
* Returns:
* OKAY if successfully opened, otherwise FAIL.
*/
bool Create(const char *file, const char *headerName, const char *comment);
/*
* Load(file):
*
* Open a block file file for reading.
*
* Parameters:
* file File path.
*
* Returns:
* OKAY if successfully opened and confirmed to be a valid Supermodel
* block file, otherwise FAIL. If the file could not be opened, all
* subsequent operations will be silently ignored (reads will return
* 0's). Write commands will be ignored.
*/
bool Load(const char *file);
/*
* Close(void):
*
* Closes the file.
*/
void Close(void);
/*
* CBlockFile(void):
* ~CBlockFile(void):
*
* Constructor and destructor.
*/
CBlockFile(void);
~CBlockFile(void);
private:
// Helper functions
void ReadString(char *str, unsigned strLen, unsigned maxLen);
unsigned ReadBytes(void *data, unsigned numBytes);
unsigned ReadDWord(uint32_t *data);
void UpdateBlockSize(void);
void WriteByte(uint8_t data);
void WriteDWord(uint32_t data);
void WriteBytes(const void *data, unsigned numBytes);
void WriteBlockHeader(const char *name, const char *comment);
// File state data
char strBuf[1026]; // buffers up to a 1024-character string, its terminator, and an extra terminator (just in case)
FILE *fp;
int mode; // 'r' for read, 'w' for write
long int fileSize; // size of file in bytes
long int blockStartPos; // points to beginning of current block (or file) header
long int dataStartPos; // points to beginning of current block's data section
};
#endif // INCLUDED_BLOCKFILE_H