Overview | Package | Class | Tree | Deprecated | Index | Help
| Copyright 2012-04-26 Werner Randelshofer
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## org.monte.media.iff
Class IFFParser

    java.lang.Object
      org.monte.media.iff.IFFParser

    public class IFFParser

extends java.lang.Object

Interprets IFF streams.

Design Pattern

- Interpreter

  Design Role

- Interpreter

  Responsibility

- Hide the physical representation of an IFF stream from the client.
- Let the client declare chunks to be visited by the visitor object.
- Let a visitor object traverse the IFF parse tree.

  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); }
       .              }
       .      }

  Version:
    2010-06-27 Fixed EOF exception when encountering 0 length chunks.
    2006-12-15 Renamed ID constants.
    2005-01-09 Minor bug fixes in comments.
    2003-03-31 Replaced all occurences of in_.skip() with in_.skipFully().
    1999-05-13 Class IFFContext integrated into this class.
    history 1999-01-02 Reworked.
    history 1997-08-30 Created.
  Author:
    Werner Randelshofer, Hausmatt 10, CH-6405 Immensee, Switzerland
  See Also:
    `IFFVisitor`

  Field Summary
  `static int` | `ID_CAT` ID for CATGroupExpression.
  `static int` | `ID_FILLER` ID for unlabeled CATGroupExpressions.
  `static int` | `ID_FORM` ID for FORMGroupExpression.
  `static int` | `ID_LIST` ID for CATGroupExpression.
  `static int` | `ID_PROP` ID for PROPGroupExpression.
  `static int[]` | `RESERVED_IDs` 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
  `IFFParser()` Constructs a new IFF parser.

  Method Summary
  `void` | `declareCollectionChunk(int type, int id)` Declares a collection chunk.
  `void` | `declareDataChunk(int type, int id)` Declares a data chunk.
  `void` | `declareGroupChunk(int type, int id)` Declares a FORM group chunk.
  `void` | `declarePropertyChunk(int type, int id)` Declares a property chunk.
  `static java.lang.String` | `idToString(int anID)` Convert an integer IFF identifier to String.
  `protected boolean` | `isCollectionChunk(IFFChunk chunk)` Checks wether the ID of the chunk has been declared as a collection chunk.
  `static boolean` | `isContentType(int id)` Returns wether the argument is a valid Content Type ID.
  `protected boolean` | `isDataChunk(IFFChunk chunk)` Checks whether the ID of the chunk has been declared as a data chunk.
  `static boolean` | `isFormType(int id)` Returns wether the argument is a valid FormType.
  `protected boolean` | `isGroupChunk(IFFChunk chunk)` Checks wether the ID of the chunk has been declared as a group chunk.
  `static boolean` | `isGroupID(int id)` Checks wether the argument represents a valid IFF GroupID.
  `static boolean` | `isID(int id)` Checks if the argument represents a valid IFF ID.
  `static boolean` | `isLocalChunkID(int id)` Returns whether the argument is a valid Local Chunk ID.
  `protected boolean` | `isPropertyChunk(IFFChunk chunk)` Checks wether the ID of the chunk has been declared as a property chunk.
  `static boolean` | `isReservedID(int id)`
  `void` | `parse(java.io.InputStream in, IFFVisitor v)` Interprets the IFFFileExpression located at the current position of the indicated InputStream.
  `static int` | `stringToID(java.lang.String aString)` Converts the first four letters of the String into an IFF Identifier.

  Methods inherited from class java.lang.Object
  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

  Field Detail

  ### ID_FORM

      public static final int ID_FORM

    ID for FORMGroupExpression.

    See Also:
      Constant Field Values

  ### ID_CAT

      public static final int ID_CAT

    ID for CATGroupExpression.

    See Also:
      Constant Field Values

  ### ID_LIST

      public static final int ID_LIST

    ID for CATGroupExpression.

    See Also:
      Constant Field Values

  ### ID_PROP

      public static final int ID_PROP

    ID for PROPGroupExpression.

    See Also:
      Constant Field Values

  ### ID_FILLER

      public static final int ID_FILLER

    ID for unlabeled CATGroupExpressions.

    See Also:
      Constant Field Values

  ### RESERVED_IDs

      public static final int[] RESERVED_IDs

    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 Detail

  ### IFFParser

      public IFFParser()

    Constructs a new IFF parser.

  Method Detail

  ### parse

      public void parse(java.io.InputStream in,
                        IFFVisitor v)
                 throws ParseException,
                        AbortException,
                        java.io.IOException

    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.
      `java.io.IOException`

  ### isDataChunk

      protected boolean isDataChunk(IFFChunk chunk)

    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

      protected boolean isGroupChunk(IFFChunk chunk)

    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

      protected boolean isPropertyChunk(IFFChunk chunk)

    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

      protected boolean isCollectionChunk(IFFChunk chunk)

    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

      public static java.lang.String idToString(int anID)

    Convert an integer IFF identifier to String.

    Parameters:
      `anID` - ID to be converted.
    Returns:
      String representation of the ID.

  ### stringToID

      public static int stringToID(java.lang.String aString)

    Converts the first four letters of the String into an IFF Identifier.

    Parameters:
      `aString` - String to be converted.
    Returns:
      ID representation of the String.

  Overview | Package | Class | Tree | Deprecated | Index | Help
  | Copyright 2012-04-26 Werner Randelshofer
  PREV CLASS NEXT CLASS | FRAMES NO FRAMES
  SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD