Class IFFParser
Abstract
"EA IFF 85" is the standard interchange file format on Commodore Amiga Computers. An IFF File is built up of primitive data types, local chunks and group chunks.
The format for primitive data types is the same as used by the Motorola MC68000 processor. The high byte and high word of a number are stored first. All primitives larger than one byte are aligned on even byte addresses relative to the start of the file. Zeros should be stored in all the pad bytes. Characters and strings are usually coded according to ISO/DIS 6429.2 and ANSI X3.64-1979.
Data objects are built up with information blocks (or C structs) called local
chunks. IFF supports the three different kinds called 'data chunk', 'property
chunk', 'collection chunk'.
Data chunks contain the essential information
that build up an object, say the bitmap data of a picture or the text of a
document.
Property chunks specify attributes for following data chunks. A
property chunk essentially says "identifier=value". When designing an object,
property chunks do describe context information like the size of an image or
the color of the text. Specifying the same property chunk more then once
overrides the previous setting.
Collection chunks describe a property
that can occur multiple times. All occurences of a collection chunk must be
collected within the scope of the current group chunk.
Group chunks are full fledged selfcontained data objects. A FORM Group stands for a single data object where as a CAT Group stands for an untyped group of data objects. A LIST defines a group very much like CAT but also gives a scope for shared properties (stored in PROP Groups).
For more information refer to "Amiga ROM Kernel Reference Manual, Devices, Third Edition, Addison Wesley".
Grammar for IFF streams
IFFFile ::= 'FORM' FormGroup | 'CAT ' CatGroup | 'LIST' ListGroup
GroupChunk ::= FormGroup | CatGroup | ListGroup | PropGroup | IFFStream FormGroup ::= size FormType { ChunkID LocalChunk [pad] | 'FORM' FormGroup [pad] | 'LIST ' ListGroup [pad] | 'CAT ' CatGroup [pad] } CatGroup ::= size CatType { 'FORM' FormGroup [pad] | 'LIST ' ListGroup [pad] | 'CAT ' CatGroup [pad] } ListGroup ::= size ListType { 'PROP' PropGroup [pad] } { 'FORM' FormGroup [pad] | 'LIST' CatGroup [pad] | 'CAT ' ListGroup [pad] } PropGroup ::= size PropType { ChunkID PropertyChunk [pad] }
LocalChunk ::= DataChunk | CollectionChunk | PropertyChunk DataChunk ::= size struct CollectionChunk ::= size struct PropertyChunk ::= size struct
size ::= ULONG FormType ::= ULONG CatType ::= ULONG ListType ::= ULONG PropType ::= ULONG ChunkID ::= ULONG pad ::= a single byte of value 0. struct ::= any C language struct built with primitive data types.
Examples
Traversing the raw structure of an IFF file
To traverse the file structure you must first set up an IFFVisitor object that does something useful at each call to the visit method. Then create an instance of IFFParser and invoke the #interpret method.
class IFFRawTraversal
. {
. static class Visitor
. implements IFFVisitor
. {
. ...implement the visitor interface here...
. }
.
. public static void main(String[] args)
. {
. try {
. Visitor visitor = new Visitor();
. FileInputStream stream = new FileInputStream(args[0]);
. IFFParser p = new IFFParser();
. p.interpret(stream,visitor);
. stream.close();
. }
. catch (IOException e) { System.out.println(e); }
. catch (InterpreterException e) { System.out.println(e); }
. catch (AbortedException e) { System.out.println(e); }
. }
. }
Traversing the IFF file and interpreting its content.
Since IFF files are not completely self describing (there is no information that helps differentiate between data chunks, property chunks and collection chunks) a reader must set up the interpreter with some contextual information before starting the interpreter.
Once at least one chunk has been declared, the interpreter will only call the
visitor for occurences of the declared group chunks and data chunks. The
property chunks and the collection chunks can be obtained from the current
group chunk by calling #getProperty or #getCollection.
Note: All
information the visitor can obtain during interpretation is only valid during
the actual #visit... call. Dont try to get information about properties or
collections for chunks that the visitor is not visiting right now.
class InterpretingAnILBMFile
. {
. static class Visitor
. implements IFFVisitor
. {
. ...
. }
.
. public static void main(String[] args)
. {
. try {
. Visitor visitor = new Visitor();
. FileInputStream stream = new FileInputStream(args[0]);
. IFFParser p = new IFFParser();
. p.declareGroupChunk('FORM','ILBM');
. p.declarePropertyChunk('ILBM','BMHD');
. p.declarePropertyChunk('ILBM','CMAP');
. p.declareCollectionChunk('ILBM','CRNG');
. p.declareDataChunk('ILBM','BODY');
. p.interpret(stream,visitor);
. stream.close();
. }
. catch (IOException e) { System.out.println(e); }
. catch (InterpreterException e) { System.out.println(e); }
. catch (AbortedException e) { System.out.println(e); }
. }
. }
- Author:
- Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intID for CATGroupExpression.static final intID for unlabeled CATGroupExpressions.static final intID for FORMGroupExpression.static final intID for CATGroupExpression.static final intID for PROPGroupExpression.static final int[]The reserved group IDs "LIST", "FORM", "PROP", "CAT ", " ", "LIS1" through "LIS9", "FOR1" through "FOR9" and "CAT1" through "CAT9" may not be used for type IDs and for local chunk IDs. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoiddeclareCollectionChunk(int type, int id) Declares a collection chunk.voiddeclareDataChunk(int type, int id) Declares a data chunk.voiddeclareGroupChunk(int type, int id) Declares a FORM group chunk.voiddeclarePropertyChunk(int type, int id) Declares a property chunk.static StringidToString(int anID) Convert an integer IFF identifier to String.protected booleanisCollectionChunk(IFFChunk chunk) Checks wether the ID of the chunk has been declared as a collection chunk.static booleanisContentType(int id) Returns wether the argument is a valid Content Type ID.protected booleanisDataChunk(IFFChunk chunk) Checks whether the ID of the chunk has been declared as a data chunk.static booleanisFormType(int id) Returns wether the argument is a valid FormType.protected booleanisGroupChunk(IFFChunk chunk) Checks wether the ID of the chunk has been declared as a group chunk.static booleanisGroupID(int id) Checks wether the argument represents a valid IFF GroupID.static booleanisID(int id) Checks if the argument represents a valid IFF ID.static booleanisLocalChunkID(int id) Returns whether the argument is a valid Local Chunk ID.protected booleanisPropertyChunk(IFFChunk chunk) Checks wether the ID of the chunk has been declared as a property chunk.booleanstatic booleanisReservedID(int id) voidparse(InputStream in, IFFVisitor v) Interprets the IFFFileExpression located at the current position of the indicated InputStream.voidsetReadData(boolean readData) static intstringToID(String aString) Converts the first four letters of the String into an IFF Identifier.
-
Field Details
-
ID_FORM
public static final int ID_FORMID for FORMGroupExpression.- See Also:
-
ID_CAT
public static final int ID_CATID for CATGroupExpression.- See Also:
-
ID_LIST
public static final int ID_LISTID for CATGroupExpression.- See Also:
-
ID_PROP
public static final int ID_PROPID for PROPGroupExpression.- See Also:
-
ID_FILLER
public static final int ID_FILLERID for unlabeled CATGroupExpressions.- See Also:
-
RESERVED_IDs
public static final int[] RESERVED_IDsThe reserved group IDs "LIST", "FORM", "PROP", "CAT ", " ", "LIS1" through "LIS9", "FOR1" through "FOR9" and "CAT1" through "CAT9" may not be used for type IDs and for local chunk IDs.
-
-
Constructor Details
-
IFFParser
public IFFParser()Constructs a new IFF parser.
-
-
Method Details
-
parse
Interprets the IFFFileExpression located at the current position of the indicated InputStream. Lets the visitor traverse the IFF parse tree during interpretation.Pre condition
- Data-, property- and collection chunks must have been declared prior to this call.
- When the client never declared chunks, then all local chunks will be interpreted as data chunks.
- The stream must be positioned at the beginning of the IFFFileExpression.
Post condition
- When no exception was thrown then the stream is positioned after the IFFFileExpression.
Obligation The visitor may throw an ParseException or an AbortException during tree traversal.
- Throws:
ParseException- Is thrown when an interpretation error occured. The stream is positioned where the error occured.AbortException- Is thrown when the visitor decided to abort the interpretation.IOException
-
isDataChunk
Checks whether the ID of the chunk has been declared as a data chunk.Pre condition
- Data chunks must have been declared before the interpretation has been started.
- This method will always return true when neither data chunks, property chunks nor collection chunks have been declared,
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the parameter is a data chunk.
-
isGroupChunk
Checks wether the ID of the chunk has been declared as a group chunk.Pre condition
- Group chunks must have been declared before the interpretation has been started. (Otherwise the response is always true).
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the visitor is interested in this is a group chunk.
-
isPropertyChunk
Checks wether the ID of the chunk has been declared as a property chunk.Pre condition
- Property chunks must have been declared before the interpretation has been started.
- This method will always return false when neither data chunks, property chunks nor collection chunks have been declared.
-
isCollectionChunk
Checks wether the ID of the chunk has been declared as a collection chunk.Pre condition
- Collection chunks must have been declared before the interpretation has been started.
- This method will always return true when neither data chunks, property chunks nor collection chunks have been declared.
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the parameter is a collection chunk.
-
declareDataChunk
public void declareDataChunk(int type, int id) Declares a data chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an IFFFileExpression.
Post condition
- Data chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
declareGroupChunk
public void declareGroupChunk(int type, int id) Declares a FORM group chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an IFFFileExpression.
Post condition
- Group chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isContentsType.
-
declarePropertyChunk
public void declarePropertyChunk(int type, int id) Declares a property chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an IFFFileExpression.
Post condition
- Group chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
declareCollectionChunk
public void declareCollectionChunk(int type, int id) Declares a collection chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an IFFFileExpression.
Post condition
- Group chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
isGroupID
public static boolean isGroupID(int id) Checks wether the argument represents a valid IFF GroupID.Validation
- Group ID must be one of FORM_ID, CAT_ID, LIST_ID or PROP_ID.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a valid Group ID.
-
isID
public static boolean isID(int id) Checks if the argument represents a valid IFF ID.Validation
- Every byte of an ID must be in the range of 0x20..0x7e
- The id may not have leading spaces (unless the id is a NULL_ID).
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the ID is a valid IFF chunk ID.
-
isLocalChunkID
public static boolean isLocalChunkID(int id) Returns whether the argument is a valid Local Chunk ID.Validation
- Local Chunk IDs may not be a NULL_ID and may not have leading spaces.
- Local Chunk IDs may not collid with GroupIDs.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a Local Chunk ID.
-
isReservedID
public static boolean isReservedID(int id) -
isFormType
public static boolean isFormType(int id) Returns wether the argument is a valid FormType.Validation:
- The FORM type is a restricted ID that may not contain lower case letters or punctuation characters.
- FORM type may not collide with GroupID.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a Form Type.
-
isContentType
public static boolean isContentType(int id) Returns wether the argument is a valid Content Type ID.Validation
- The Content type is a FORM type ID or a NULL_ID
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a Contents Type.
-
idToString
Convert an integer IFF identifier to String.- Parameters:
anID- ID to be converted.- Returns:
- String representation of the ID.
-
stringToID
Converts the first four letters of the String into an IFF Identifier.- Parameters:
aString- String to be converted.- Returns:
- ID representation of the String.
-
isReadData
public boolean isReadData() -
setReadData
public void setReadData(boolean readData)
-