001: /*
002: * $Id: Parser.java,v 1.4 2002/03/17 03:51:34 skavish Exp $
003: *
004: * ===========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.parser;
052:
053: import java.io.*;
054: import java.util.*;
055: import java.util.zip.*;
056:
057: import org.openlaszlo.iv.flash.api.*;
058: import org.openlaszlo.iv.flash.util.*;
059:
060: public final class Parser extends FlashBuffer {
061:
062: private int tagStartPos;
063: private int tagDataPos;
064: private int tagLength;
065: private int tagEndPos;
066: private int tagCode;
067:
068: private byte[] temp_bufb;
069: private char[] temp_bufc;
070:
071: // file
072: private FlashFile file;
073:
074: public Parser() {
075: }
076:
077: public int getTag() {
078: tagStartPos = getPos();
079: int code = getUWord();
080: int length = code & 0x3f;
081: code = code >> 6;
082:
083: if (length == 0x3f) {
084: length = getUDWord();
085: }
086:
087: tagDataPos = getPos();
088: tagLength = length;
089: tagCode = code;
090: tagEndPos = tagDataPos + length;
091: return code;
092: }
093:
094: public void addDef(FlashDef def) {
095: file.addDef(def);
096: }
097:
098: public FlashDef getDef(int id) {
099: return file.getDef(id);
100: }
101:
102: public void addDefToLibrary(String name, FlashDef def) {
103: file.addDefToLibrary(name, def);
104: }
105:
106: public FlashDef getDefFromLibrary(String name) {
107: return file.getDefFromLibrary(name);
108: }
109:
110: public int getTagStartPos() {
111: return tagStartPos;
112: }
113:
114: public int getTagDataPos() {
115: return tagDataPos;
116: }
117:
118: public int getTagLength() {
119: return tagLength;
120: }
121:
122: public int getTagEndPos() {
123: return tagEndPos;
124: }
125:
126: public int getTagCode() {
127: return tagCode;
128: }
129:
130: public byte[] getTempByteBuf(int size) {
131: if (temp_bufb == null || temp_bufb.length < size) {
132: temp_bufb = new byte[size];
133: }
134: return temp_bufb;
135: }
136:
137: public char[] getTempCharBuf(int size) {
138: if (temp_bufc == null || temp_bufc.length < size) {
139: temp_bufc = new char[size];
140: }
141: return temp_bufc;
142: }
143:
144: public FlashObject newUnknownTag() {
145: return new UnparsedTag(tagCode, getBuf(), tagStartPos,
146: tagEndPos);
147: }
148:
149: public void skipLastTag() {
150: setPos(tagEndPos);
151: }
152:
153: public FlashFile getFile() {
154: return file;
155: }
156:
157: /**
158: * Parse input stream
159: */
160: public void parseStream(InputStream is, FlashFile file)
161: throws IVException, IOException {
162:
163: byte[] fileHdr = new byte[8];
164:
165: if (is.read(fileHdr, 0, 8) != 8) {
166: throw new IVException(Resource.CANTREADHEADER,
167: new Object[] { file.getFullName() });
168: }
169:
170: if (fileHdr[1] != 'W' || fileHdr[2] != 'S') {
171: throw new IVException(Resource.ILLEGALHEADER,
172: new Object[] { file.getFullName() });
173: }
174:
175: boolean isCompressed = false;
176: if (fileHdr[0] == 'C') {
177: isCompressed = true;
178: } else if (fileHdr[0] != 'F') {
179: throw new IVException(Resource.ILLEGALHEADER,
180: new Object[] { file.getFullName() });
181: }
182:
183: // get the file size.
184: int fileSize = Util.getUDWord(fileHdr[4], fileHdr[5],
185: fileHdr[6], fileHdr[7]);
186:
187: if (fileSize < 21) {
188: throw new IVException(Resource.FILETOOSHORT,
189: new Object[] { file.getFullName() });
190: }
191:
192: FlashBuffer fb;
193: try {
194: fb = new FlashBuffer(fileSize + 8);
195: } catch (OutOfMemoryError e) {
196: throw new IVException(Resource.FILETOOBIG,
197: new Object[] { file.getFullName() });
198: }
199:
200: fb.writeArray(fileHdr, 0, 8);
201:
202: if (isCompressed) {
203: is = new InflaterInputStream(is);
204: }
205:
206: fb.write(is);
207:
208: file.setCompressed(isCompressed);
209: _parseBuffer(fb, file);
210: }
211:
212: /**
213: * Parse FlashBuffer
214: */
215: public void parseBuffer(FlashBuffer fob, FlashFile file)
216: throws IVException {
217: boolean isCompressed = false;
218:
219: if (fob.getBuf()[0] == 'C') {
220: isCompressed = true;
221: } else if (fob.getBuf()[0] != 'F') {
222: throw new IVException(Resource.ILLEGALHEADER,
223: new Object[] { file.getFullName() });
224: }
225:
226: if (isCompressed) { // decompress buffer
227: int fileSize = fob.getDWordAt(4);
228:
229: if (fileSize < 21) {
230: throw new IVException(Resource.FILETOOSHORT,
231: new Object[] { file.getFullName() });
232: }
233:
234: FlashBuffer fb;
235: try {
236: fb = new FlashBuffer(fileSize + 8);
237: } catch (OutOfMemoryError e) {
238: throw new IVException(Resource.FILETOOBIG,
239: new Object[] { file.getFullName() });
240: }
241:
242: fb.writeArray(fob.getBuf(), 0, 8);
243:
244: try {
245: fb
246: .write(new InflaterInputStream(fob
247: .getInputStream(8)));
248: } catch (IOException e) {
249: throw new IVException(e);
250: }
251: fob = fb;
252: }
253:
254: file.setCompressed(isCompressed);
255: _parseBuffer(fob, file);
256: }
257:
258: /**
259: */
260: private void _parseBuffer(FlashBuffer fb, FlashFile file)
261: throws IVException {
262: this .file = file;
263:
264: init(fb.getBuf(), 0, fb.getSize());
265:
266: // get version
267: file.setVersion((int) getByteAt(3));
268:
269: setPos(8);
270:
271: // get frame size
272: file.setFrameSize(getRect());
273:
274: // get frame rate
275: file.setFrameRate(getUWord());
276:
277: // parse main script
278: file.setMainScript(Script.parse(this , true));
279: }
280:
281: }
|