1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.zmpp.iff;
24
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import org.zmpp.base.MemoryAccess;
31 import org.zmpp.base.MemorySection;
32
33 /***
34 * This class implements the FormChunk interface.
35 *
36 * @author Wei-ju Wu
37 * @version 1.0
38 */
39 public class DefaultFormChunk extends DefaultChunk implements FormChunk {
40
41 /***
42 * The sub type id.
43 */
44 private byte[] subId;
45
46 /***
47 * The list of sub chunks.
48 */
49 private List<Chunk> subChunks;
50
51 /***
52 * Constructor.
53 *
54 * @param memaccess a MemoryAccess object
55 */
56 public DefaultFormChunk(MemoryAccess memaccess) {
57
58 super(memaccess);
59 initBaseInfo();
60 readSubChunks();
61 }
62
63 /***
64 * Initialize the id field.
65 */
66 private void initBaseInfo() {
67
68
69 subId = new byte[CHUNK_ID_LENGTH];
70 int offset = CHUNK_HEADER_LENGTH;
71 for (int i = 0; i < 4; i++) {
72
73 subId[i] = memaccess.readByte(i + offset);
74 }
75 }
76
77 /***
78 * Read this form chunk's sub chunks.
79 */
80 private void readSubChunks() {
81
82 subChunks = new ArrayList<Chunk>();
83
84
85 int length = getSize();
86 int offset = CHUNK_HEADER_LENGTH + CHUNK_ID_LENGTH;
87 int chunkTotalSize = 0;
88
89 while (offset < length) {
90 MemoryAccess memarray = new MemorySection(memaccess, offset,
91 length - offset);
92 Chunk subchunk = new DefaultChunk(memarray);
93 subChunks.add(subchunk);
94 chunkTotalSize = subchunk.getSize() + CHUNK_HEADER_LENGTH;
95
96
97 chunkTotalSize = (chunkTotalSize % 2) == 0 ? chunkTotalSize :
98 chunkTotalSize + 1;
99 offset += chunkTotalSize;
100 }
101 }
102
103 /***
104 * {@inheritDoc}
105 */
106 public boolean isValid() {
107
108 return (new String(getId())).equals("FORM");
109 }
110
111 /***
112 * {@inheritDoc}
113 */
114 public byte[] getSubId() {
115
116 return subId;
117 }
118
119 /***
120 * {@inheritDoc}
121 */
122 public Iterator<Chunk> getSubChunks() {
123
124 return subChunks.iterator();
125 }
126
127 /***
128 * {@inheritDoc}
129 */
130 public Chunk getSubChunk(byte[] id) {
131
132 for (Chunk chunk : subChunks) {
133
134 if (Arrays.equals(id, chunk.getId())) {
135
136 return chunk;
137 }
138 }
139 return null;
140 }
141 }