IFF Format Library 0.1
Sponsored Links
IFF Format Library 0.1 Ranking & Summary
File size:
0.026 MB
Platform:
Any Platform
License:
MIT/X Consortium License
Price:
Downloads:
1070
Date added:
2006-12-07
Publisher:
Mike Sharov
IFF Format Library 0.1 description
IFF Format Library provides header structures and utility functions for reading and writing data files in the Interchange Files.
The Interchange File Format is a simple structured binary file format consisting of sized and typed chunks of data, selectively readable without having to know the format of each chunk.
This functionality is similar to what XML provides for text documents, and the IFF format can indeed be viewed as a sort of a binary XML. IFFs extensibility is an excellent way of not breaking old applications when the file format changes, making it an excellent choice for your next applications data files.
The IFF is also the simplest and the smallest such data format, ensuring that your files consist of real data rather than overhead and that your code spends more time on real work than on parsing the data file. This library defines the IFF header structures and provides simple algorithms for directly writing many of your objects as chunks and containers.
Installation:
This library can be downloaded from SourceForge, as can its sole prerequisite:
libiff - The library source package.
uSTL - An STL implementation, required.
First, unpack and install uSTL, as described in its documentation. Unpack libiff and run ./configure; make install, which will install the library to /usr/local/lib and headers to /usr/local/include. ./configure --help lists available configuration options, in the usual autoconf fashion. The one thing to be aware of is that by default the library will not be completely conforming to EA85 specification. Why that is so, and why you should take the default options anyway, is discussed in detail in the next section. If you really want to use the original EA85 format, you can to pass --with-bigendian --with-2grain to configure.
Usage:
If you are using C++, chances are you already have an object-oriented design of some kind. You have a collection of objects, related to each other in some way, and you want to write them all to a file in some way. It is, of course, possible to just write them all to the file, one after the other, but that approach makes things difficult if you ever decide to change the structure of those objects, write more or fewer of them, or explain to other people how to read your format. Hence, it is desirable to create some kind of structure in the file, to be able to determine where each objects begins and ends, and what kind of object is where. When using an IFF format, youll make simple objects into chunks, and objects containing other objects into FORMs, LISTs, or CATs.
The first task is to make each of your objects readable and writable through uSTL streams. To do that youll need to define three methods, read, write, and stream_size, and create flow operator overrides with a STD_STREAMABLE macro. Here is a typical example:
#include < iff.h > // iff header includes ustl.h, but doesnt use the namespace.
using namespace ustl; // it is recommended to leave iff:: namespace on.
/// Stores players vital statistics.
class CPlayerStats {
public:
void read (istream& is);
void write (ostream& os) const;
size_t stream_size (void) const;
private:
uint16_t m_HP;
uint16_t m_MaxHP;
uint16_t m_Mana;
uint16_t m_MaxMana;
};
// Since the object is simple, and contains no other objects,
// well make it a simple chunk.
enum { // Define a chunk format for writing this object.
fmt_PlayerStats = IFF_FMT(S,T,A,T)
}; // In a hex editor youll see STAT at the beginning of the object
// making it easy to find when you want to hack something in it.
/// Reads the object from stream p is
void CPlayerStats::read (istream& is)
{
is >> m_HP >> m_MaxHP >> m_Mana >> m_MaxMana;
}
/// Writes the object to stream p os.
void CPlayerStats::write (ostream& os) const
{
os << m_HP << m_MaxHP << m_Mana << m_MaxMana;
}
/// Returns the size of the written object
inline size_t CPlayerStats::stream_size (void) const
{
return (stream_size_of (m_HP) + // This evaluates at compile time to 8,
stream_size_of (m_MaxHP) + // so making this function inline is
stream_size_of (m_Mana) + // usually a good idea.
stream_size_of (m_MaxMana));
}
STD_STREAMABLE(CPlayerStats)
This needs to happen in all your objects. Make them streamable and define a format id. Then, to save everything, use iff::Read/Write functions from iff/utils.h (no, you dont need to include it separately), like this:
void SomeDocumentObject::SavePlayer (const string& filename) const
{
// uSTL streams work on memory blocks, not on files directly,
// so the needed buffer has to be preallocated.
//
memblock buf (iff::form_size_of (m_Player));
//
// Well need a stream to write the player object to.
//
ostream os (buf);
//
// This writes it as a FORM, which just happens to be one of the three
// allowable top-level chunk types. When a file starts with FORM, LIST,
// or CAT, programs know it is an IFF file. The top level chunk should
// contain the entire file, and nothing should follow it.
//
iff::WriteFORM (os, m_Player, fmt_MyGamePlayer);
buf.write_file ("player.sav");
}
// The following will be in the player class
/// Reads the player object from stream p is
size_t CPlayer::stream_size (istream& is)
{
// Player is a compound object, a FORM, so it can only contain other
// chunks and FORMs, not simple values.
return (iff::chunk_size_of (m_Name) + // m_Name is a string
iff::chunk_size_of (m_Stats) + // CPlayerStats object
iff::vector_size_of (m_Inventory) + // a vector, chunk saved
// Quests is a special manager object that writes each quest
// as a chunk or a form with some common settings.
iff::list_size_of (m_Quests));
}
/// Reads the player object from stream p is
void CPlayer::write (ostream& os) const
{
iff::WriteChunk (os, m_Name, fmt_PlayerName);
iff::WriteChunk (os, m_Stats, fmt_PlayerStats);
iff::WriteVector (os, m_Inventory, fmt_Inventory);
iff::WriteLIST (os, m_Quests, fmt_Quests);
}
/// Reads the player object from stream p is
void CPlayer::read (istream& is)
{
iff::ReadChunk (is, m_Name, fmt_PlayerName);
iff::ReadChunk (is, m_Stats, fmt_PlayerStats);
iff::ReadVector (is, m_Inventory, fmt_Inventory);
iff::ReadLIST (is, m_Quests, fmt_Quests);
}
The above is enough to get you a structured file with format checking on read. If you try reading something that is not a player savegame file or if the file is somehow corrupted, youll get an informative exception. The read method above is the simplest implementation, to be used if you really do not expect things to change at this level. A player will always have a name, some stats, and stuff in his pockets. But what if you decided to add, say, a known spell list?
The read function will then break. Sure you can hack up some conversion routine for yourself, but what about your users who already have an old version of your game? Are you going to tell them that those fifty four hours of gameplay they saved will have to be replayed just because you added one lousy feature? Well, some companies are like that. But with IFF, you have the formats and sizes in each header, so you can make a more resilient read that will support new and old formats alike:
/// Reads the player object from stream p is
void CPlayer::read (istream& is)
{
while (is.remaining()) {
//
// The Peek function will get the format without moving the stream
// pointer, handling also the case of compound chunks.
//
switch (iff::PeekChunkOrGroupFormat (is)) {
case fmt_PlayerName: iff::ReadChunk (is, m_Name, fmt_PlayerName); break;
case fmt_PlayerStats: iff::ReadChunk (is, m_Stats, fmt_PlayerStats); break;
case fmt_Inventory: iff::ReadVector(is, m_Inventory, fmt_Inventory); break;
case fmt_Quests: iff::ReadLIST (is, m_Quests, fmt_Quests); break;
default: iff::SkipChunk (is); break;
}
}
}
This way missing chunks will not cause a problem, resulting in defaults being used for the corresponding object, and neither will new ones, which will be skipped. Once you have this set up, changing the file format becomes more or less easy and painless, both for you and your users. All this you get for a very small cost of changing simple flow writes to WriteChunk and the like. As you can see above, the code remains readable, maintainable, and compact. Finally, if a user sends you his savefile that reproduces some bug, and you need to find out whether he was low on mana, youll be able to find the right number at a glance in a hex editor; its bytes 8 and 9 after STAT.
Enhancements:
- This is the initial release of the library, featuring basic functionality of reading and writing simple and compound chunks.
The Interchange File Format is a simple structured binary file format consisting of sized and typed chunks of data, selectively readable without having to know the format of each chunk.
This functionality is similar to what XML provides for text documents, and the IFF format can indeed be viewed as a sort of a binary XML. IFFs extensibility is an excellent way of not breaking old applications when the file format changes, making it an excellent choice for your next applications data files.
The IFF is also the simplest and the smallest such data format, ensuring that your files consist of real data rather than overhead and that your code spends more time on real work than on parsing the data file. This library defines the IFF header structures and provides simple algorithms for directly writing many of your objects as chunks and containers.
Installation:
This library can be downloaded from SourceForge, as can its sole prerequisite:
libiff - The library source package.
uSTL - An STL implementation, required.
First, unpack and install uSTL, as described in its documentation. Unpack libiff and run ./configure; make install, which will install the library to /usr/local/lib and headers to /usr/local/include. ./configure --help lists available configuration options, in the usual autoconf fashion. The one thing to be aware of is that by default the library will not be completely conforming to EA85 specification. Why that is so, and why you should take the default options anyway, is discussed in detail in the next section. If you really want to use the original EA85 format, you can to pass --with-bigendian --with-2grain to configure.
Usage:
If you are using C++, chances are you already have an object-oriented design of some kind. You have a collection of objects, related to each other in some way, and you want to write them all to a file in some way. It is, of course, possible to just write them all to the file, one after the other, but that approach makes things difficult if you ever decide to change the structure of those objects, write more or fewer of them, or explain to other people how to read your format. Hence, it is desirable to create some kind of structure in the file, to be able to determine where each objects begins and ends, and what kind of object is where. When using an IFF format, youll make simple objects into chunks, and objects containing other objects into FORMs, LISTs, or CATs.
The first task is to make each of your objects readable and writable through uSTL streams. To do that youll need to define three methods, read, write, and stream_size, and create flow operator overrides with a STD_STREAMABLE macro. Here is a typical example:
#include < iff.h > // iff header includes ustl.h, but doesnt use the namespace.
using namespace ustl; // it is recommended to leave iff:: namespace on.
/// Stores players vital statistics.
class CPlayerStats {
public:
void read (istream& is);
void write (ostream& os) const;
size_t stream_size (void) const;
private:
uint16_t m_HP;
uint16_t m_MaxHP;
uint16_t m_Mana;
uint16_t m_MaxMana;
};
// Since the object is simple, and contains no other objects,
// well make it a simple chunk.
enum { // Define a chunk format for writing this object.
fmt_PlayerStats = IFF_FMT(S,T,A,T)
}; // In a hex editor youll see STAT at the beginning of the object
// making it easy to find when you want to hack something in it.
/// Reads the object from stream p is
void CPlayerStats::read (istream& is)
{
is >> m_HP >> m_MaxHP >> m_Mana >> m_MaxMana;
}
/// Writes the object to stream p os.
void CPlayerStats::write (ostream& os) const
{
os << m_HP << m_MaxHP << m_Mana << m_MaxMana;
}
/// Returns the size of the written object
inline size_t CPlayerStats::stream_size (void) const
{
return (stream_size_of (m_HP) + // This evaluates at compile time to 8,
stream_size_of (m_MaxHP) + // so making this function inline is
stream_size_of (m_Mana) + // usually a good idea.
stream_size_of (m_MaxMana));
}
STD_STREAMABLE(CPlayerStats)
This needs to happen in all your objects. Make them streamable and define a format id. Then, to save everything, use iff::Read/Write functions from iff/utils.h (no, you dont need to include it separately), like this:
void SomeDocumentObject::SavePlayer (const string& filename) const
{
// uSTL streams work on memory blocks, not on files directly,
// so the needed buffer has to be preallocated.
//
memblock buf (iff::form_size_of (m_Player));
//
// Well need a stream to write the player object to.
//
ostream os (buf);
//
// This writes it as a FORM, which just happens to be one of the three
// allowable top-level chunk types. When a file starts with FORM, LIST,
// or CAT, programs know it is an IFF file. The top level chunk should
// contain the entire file, and nothing should follow it.
//
iff::WriteFORM (os, m_Player, fmt_MyGamePlayer);
buf.write_file ("player.sav");
}
// The following will be in the player class
/// Reads the player object from stream p is
size_t CPlayer::stream_size (istream& is)
{
// Player is a compound object, a FORM, so it can only contain other
// chunks and FORMs, not simple values.
return (iff::chunk_size_of (m_Name) + // m_Name is a string
iff::chunk_size_of (m_Stats) + // CPlayerStats object
iff::vector_size_of (m_Inventory) + // a vector, chunk saved
// Quests is a special manager object that writes each quest
// as a chunk or a form with some common settings.
iff::list_size_of (m_Quests));
}
/// Reads the player object from stream p is
void CPlayer::write (ostream& os) const
{
iff::WriteChunk (os, m_Name, fmt_PlayerName);
iff::WriteChunk (os, m_Stats, fmt_PlayerStats);
iff::WriteVector (os, m_Inventory, fmt_Inventory);
iff::WriteLIST (os, m_Quests, fmt_Quests);
}
/// Reads the player object from stream p is
void CPlayer::read (istream& is)
{
iff::ReadChunk (is, m_Name, fmt_PlayerName);
iff::ReadChunk (is, m_Stats, fmt_PlayerStats);
iff::ReadVector (is, m_Inventory, fmt_Inventory);
iff::ReadLIST (is, m_Quests, fmt_Quests);
}
The above is enough to get you a structured file with format checking on read. If you try reading something that is not a player savegame file or if the file is somehow corrupted, youll get an informative exception. The read method above is the simplest implementation, to be used if you really do not expect things to change at this level. A player will always have a name, some stats, and stuff in his pockets. But what if you decided to add, say, a known spell list?
The read function will then break. Sure you can hack up some conversion routine for yourself, but what about your users who already have an old version of your game? Are you going to tell them that those fifty four hours of gameplay they saved will have to be replayed just because you added one lousy feature? Well, some companies are like that. But with IFF, you have the formats and sizes in each header, so you can make a more resilient read that will support new and old formats alike:
/// Reads the player object from stream p is
void CPlayer::read (istream& is)
{
while (is.remaining()) {
//
// The Peek function will get the format without moving the stream
// pointer, handling also the case of compound chunks.
//
switch (iff::PeekChunkOrGroupFormat (is)) {
case fmt_PlayerName: iff::ReadChunk (is, m_Name, fmt_PlayerName); break;
case fmt_PlayerStats: iff::ReadChunk (is, m_Stats, fmt_PlayerStats); break;
case fmt_Inventory: iff::ReadVector(is, m_Inventory, fmt_Inventory); break;
case fmt_Quests: iff::ReadLIST (is, m_Quests, fmt_Quests); break;
default: iff::SkipChunk (is); break;
}
}
}
This way missing chunks will not cause a problem, resulting in defaults being used for the corresponding object, and neither will new ones, which will be skipped. Once you have this set up, changing the file format becomes more or less easy and painless, both for you and your users. All this you get for a very small cost of changing simple flow writes to WriteChunk and the like. As you can see above, the code remains readable, maintainable, and compact. Finally, if a user sends you his savefile that reproduces some bug, and you need to find out whether he was low on mana, youll be able to find the right number at a glance in a hex editor; its bytes 8 and 9 after STAT.
Enhancements:
- This is the initial release of the library, featuring basic functionality of reading and writing simple and compound chunks.
IFF Format Library 0.1 Screenshot
IFF Format Library 0.1 Keywords
IFF
IFF Format Library
IFF Format Library 0.1
CPlayerStats
Interchange Files
Files
writing data files
reading and writing
Writing Data
utility functions
t m
Files In
data files
format
library
data
Bookmark IFF Format Library 0.1
IFF Format Library 0.1 Copyright
WareSeeker periodically updates pricing and software information of IFF Format Library 0.1 full version from the publisher, so some information may be slightly out-of-date. You should confirm all information before relying on it. Software piracy is theft, Using crack, password, serial numbers, registration codes, key generators is illegal and prevent future development of IFF Format Library 0.1 Edition. Download links are directly from our publisher sites, torrent files or links from rapidshare.com, yousendit.com or megaupload.com are not allowed
Featured Software
Want to place your software product here?
Please contact us for consideration.
Contact WareSeeker.com
Related Information
teachers college reading and writing project
reading and writing project
critical reading and writing
reading and writing decimals
reading and writing quarterly
reading and writing across the curriculum
library supplies
formatting
objects that reflect light
reading and writing decimal numbers
english 101 essays reading and writing
reading and writing workshop
myspace falling objects
public library
mla format
reading and writing connection
objects in motion
formative assessment
Related Software
Audio File Library is a uniform API for accessing standard digital audio file formats. Free Download
MS CHM library is a library for dealing with Microsoft ITSS/CHM format files. Free Download
C Generic Library is a generic data structure library is a bunch of data structures. Free Download
Data.FormValidators aim is to bring all the benefits of the perl module Data::FormValidator over to javascript. Free Download
Memory Structures Library (MemSL) is a complete data structures/collection classes library with memory tracing. Free Download
liborphy project is an orphy hardwares data acquisition library for GNU/Linux. Free Download
obcode anti-debugging library is a library that produces code which is difficult to reverse engineer. Free Download
This provides an interface library for Astral data flows. Free Download
Latest Software
Popular Software
Favourite Software