All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.monte.media.iff.MutableIFFChunk Maven / Gradle / Ivy

There is a newer version: 1.1
Show newest version
/*
 * @(#)MutableIFFChunk.java  1.0  December 25, 2006
 *
 * Copyright (c) 2006 Werner Randelshofer, Goldau, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package org.monte.media.iff;

import java.io.*;
import java.util.*;
import javax.swing.tree.*;

/**
 * MutableIFFChunk.
 * 

* Syntax of an IFF Chunk: *

 * Chunk        ::= ID #{ UBYTE* } [0]
 *
 * Property     ::= Chunk
 *
 * FORM         ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* }
 * FormType     ::= ID
 * LocalChunk   ::= Property | Chunk
 *
 * CAT          ::= "CAT " #{ ContentsType {FROM | LIST | CAT)* }
 * ContentsType ::= ID -- a hint or an "abstract data type" ID
 *
 * LIST         ::= "LIST" #{ ContentsType PROP* {FORM | LIST | CAT)* }
 * PROP         ::= "PROP" #{ FormType Property* }
 * 
* In this extended regular expression notation the token "#" represents * a count of the following braced data types. Literal items are shown in * "quotes", [square bracketed items] are optional, and "*" means 0 or more *instances. A sometimes-needed pad is shown as "[0]". * * * @author Werner Randelshofer * @version 1.0 December 25, 2006 Created. */ public class MutableIFFChunk extends DefaultMutableTreeNode { /** ID for FORMGroupExpression. */ public final static int ID_FORM = 0x464f524d; /** ID for CATGroupExpression. */ public final static int ID_CAT = 0x43415420; /** ID for CATGroupExpression. */ public final static int ID_LIST = 0x4c495354; /** ID for PROPGroupExpression. */ public final static int ID_PROP = 0x50524f50; /** ID for unlabeled CATGroupExpressions. */ public final static int ID_FILLER = 0x20202020; /** * The type of an IFF Chunk. */ private int type; /** * The id of an IFF Chunk. */ private int id; /** * The dat of an IFF Chunk. */ private byte[] data; /** Creates a new instance. */ public MutableIFFChunk() { } /** Creates a new instance. */ public MutableIFFChunk(int id, int type) { this.id = id; this.type = type; } /** Creates a new instance. */ public MutableIFFChunk(int id, byte[] data) { this.id = id; this.data = data; } /** Creates a new instance. */ public MutableIFFChunk(String id, String type) { this.id = stringToId(id); this.type = stringToId(type); } /** Creates a new instance. */ public MutableIFFChunk(String id, byte[] data) { this.id = stringToId(id); this.data = data; } public void setType(int newValue) { int oldValue = type; type = newValue; } public void setId(int newValue) { int oldValue = id; id = newValue; } public void setData(byte[] newValue) { byte[] oldValue = data; data = newValue; } public int getType() { return type; } public int getId() { return id; } public byte[] getData() { return data; } public int getLength() { if (data != null) { return data.length; } else { int length = 4; for (MutableIFFChunk child : childChunks()) { int childLength = child.getLength(); length += 8 + childLength + childLength % 2; } return length; } } public Vector childChunks() { return (children == null) ? new Vector(0) : new Vector(children); } public String dump() { return dump(0); } public String dump(int depth) { StringBuilder buf = new StringBuilder(); for (int i = 0; i < depth; i++) { buf.append('.'); } buf.append(idToString(getId())); buf.append(' '); buf.append(getLength()); if (getChildCount() > 0) { buf.append(' '); buf.append(idToString(getType())); for (MutableIFFChunk child : childChunks()) { buf.append('\n'); buf.append(child.dump(depth + 1)); } } return buf.toString(); } public String toString() { StringBuilder buf = new StringBuilder(); buf.append(idToString(getId())); buf.append(' '); buf.append(getLength()); if (data == null) { buf.append(' '); buf.append(idToString(getType())); } return buf.toString(); } /** * Convert an integer IFF identifier to String. * * @param anID to be converted. * @return String representation of the ID. */ public static String idToString(int anID) { byte[] bytes = new byte[4]; bytes[0] = (byte) (anID >>> 24); bytes[1] = (byte) (anID >>> 16); bytes[2] = (byte) (anID >>> 8); bytes[3] = (byte) (anID >>> 0); return new String(bytes); } /** * Converts the first four letters of the * String into an IFF Identifier. * * @param aString String to be converted. * @return ID representation of the String. */ public static int stringToId(String aString) { byte[] bytes = aString.getBytes(); return ((int) bytes[0]) << 24 | ((int) bytes[1]) << 16 | ((int) bytes[2]) << 8 | ((int) bytes[3]) << 0; } public void read(File f) throws IOException { MC68000InputStream in = new MC68000InputStream( new BufferedInputStream( new FileInputStream(f))); try { read(in); } finally { in.close(); } } public void read(MC68000InputStream in) throws IOException { id = in.readLONG(); long length = in.readULONG(); switch (id) { case ID_CAT: case ID_FORM: case ID_LIST: case ID_PROP: type = in.readLONG(); length -= 4; while (length > 1) { MutableIFFChunk child = new MutableIFFChunk(); child.read(in); add(child); int childLength = child.getLength(); length -= childLength + childLength % 2 + 8; } break; default: data = new byte[(int) length]; in.readFully(data, 0, (int) length); break; } if (length % 2 == 1) { in.read(); } } public void Write(File f) throws IOException { MC68000OutputStream out = new MC68000OutputStream( new BufferedOutputStream( new FileOutputStream(f))); try { write(out); } finally { out.close(); } } public void write(MC68000OutputStream out) throws IOException { out.writeULONG(id); long length = getLength(); out.writeULONG(length); if (data == null) { out.writeULONG(type); for (MutableIFFChunk child : childChunks()) { child.write(out); } } else { out.write(data); } if (length % 2 == 1) { out.write((byte) 0); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy