001: /* ****************************************************************************
002: * SWFByte.java
003: * ****************************************************************************/
004:
005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006: * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
007: * Use is subject to license terms. *
008: * J_LZ_COPYRIGHT_END *********************************************************/
009:
010: package org.openlaszlo.connection;
011:
012: import org.openlaszlo.iv.flash.api.action.Actions;
013: import org.openlaszlo.iv.flash.api.action.Program;
014: import org.openlaszlo.iv.flash.util.FlashBuffer;
015: import org.openlaszlo.iv.flash.util.Tag;
016: import org.openlaszlo.xml.internal.DataCompiler;
017: import java.io.FileNotFoundException;
018: import java.io.FileOutputStream;
019: import java.io.IOException;
020: import java.awt.geom.Rectangle2D;
021: import java.util.Vector;
022: import org.jdom.Element;
023:
024: //**** Note: SWF files are stored little-endian (least significant bits first in order)
025:
026: /** Helper class to send dribbled event information down to Flash client.
027: */
028: public class SwfByte {
029: /** Default buffer size to set FlashBuffer */
030: static private final int DEFAULT_FLASH_BUFFER_SIZE = 100;
031:
032: /** Default header length to send */
033: static public final int DEFAULT_HEADER_LENGTH = 65535;
034:
035: /** Default header x-min */
036: static public final int DEFAULT_HEADER_X_MIN = 0;
037:
038: /** Default header x-max */
039: static public final int DEFAULT_HEADER_X_MAX = 400;
040:
041: /** Default header y-min */
042: static public final int DEFAULT_HEADER_Y_MIN = 0;
043:
044: /** Default header y-max */
045: static public final int DEFAULT_HEADER_Y_MAX = 400;
046:
047: /** Default header frame rate */
048: static public final double DEFAULT_HEADER_FRAME_RATE = 12.0;
049:
050: /** Default header frame count */
051: static public final int DEFAULT_HEADER_FRAME_COUNT = 4200;
052:
053: /** Flash buffer to send partial information */
054: private FlashBuffer mBuf = null;
055:
056: private int mFlashVersion = 5;
057:
058: /** Makes sure that a buffer has been created.
059: */
060: private void ensureBuffer() {
061: if (mBuf == null)
062: mBuf = new FlashBuffer(DEFAULT_FLASH_BUFFER_SIZE);
063: }
064:
065: /** Returns exact number of bytes written to buffer.
066: * @return buffer
067: */
068: public byte[] getBuf() {
069: return getExactBytes(mBuf);
070: }
071:
072: /** Sets the exact length of bytes written to header at moment this method
073: * is called.
074: */
075: public SwfByte setLength() {
076: return this .setLength(mBuf.getPos());
077: }
078:
079: /** Sets the specified length of bytes to header.
080: * @param length length to set
081: */
082: public SwfByte setLength(int length) {
083: mBuf.writeDWordAt(length, 4);
084: return this ;
085: }
086:
087: /** Creates SWF header with default values. Length must be explicitly set by
088: * calling on the setLength() methods. If header has been set before this,
089: * it will be overridden.
090: */
091: public SwfByte setHeader(int version) {
092: ensureBuffer();
093:
094: return this .setHeader(version, DEFAULT_HEADER_X_MIN,
095: DEFAULT_HEADER_X_MAX, DEFAULT_HEADER_Y_MIN,
096: DEFAULT_HEADER_Y_MAX, DEFAULT_HEADER_FRAME_RATE,
097: DEFAULT_HEADER_FRAME_COUNT);
098: }
099:
100: /** Creates SWF header. Length must be explicitly set by calling on the
101: * setLength() methods. If header has been set before this,
102: * it will be overridden.
103: * @param version version number of SWF
104: * @param xMin x-min coordinates for frame size (in TWIPS)
105: * @param xMax x-max coordinates for frame size (in TWIPS)
106: * @param yMin x-min coordinates for frame size (in TWIPS)
107: * @param yMax y-max coordinates for frame size (in TWIPS)
108: * @param frameRate (not used)
109: * @param frameCount total number of frames in movie
110: */
111: public SwfByte setHeader(int version, int xMin, int xMax, int yMin,
112: int yMax, double frameRate, int frameCount) {
113: ensureBuffer();
114:
115: int w = xMax - xMin;
116: int h = yMax - yMin;
117: Rectangle2D rect = new Rectangle2D.Double(xMin, yMin, w, h);
118: return this .setHeader(version, rect, frameRate, frameCount);
119: }
120:
121: /** Creates SWF header. Length must be explicitly set by calling on the
122: * setLength() methods. If header has been set before this,
123: * it will be overridden.
124: * @param version version number of SWF
125: * @param rect rectangular coordinates for frame size (in TWIPS)
126: * @param frameRate (not used)
127: * @param frameCount total number of frames in movie
128: */
129: public SwfByte setHeader(int version, Rectangle2D rect,
130: double frameRate, int frameCount) {
131: ensureBuffer();
132:
133: // Signature - 1 byte for each letter
134: mBuf.writeByte('F');
135: mBuf.writeByte('W');
136: mBuf.writeByte('S');
137:
138: // Version - 1 byte
139: mBuf.writeByte(version);
140:
141: // Length of file - 4 bytes (skip for now)
142: mBuf.skip(4);
143:
144: // Frame size - RECT
145: mBuf.write(rect);
146:
147: // Frame rate - 2 bytes (8.8 fixed) [made it 12.0]
148: // (make sure this fixed point value is written little-endian)
149: mBuf.writeByte(0);
150: mBuf.writeByte(12);
151:
152: // Frame count - 2 bytes
153: mBuf.writeWord(frameCount);
154:
155: return this ;
156: }
157:
158: /** Write byte-code to set a variable with a value.
159: * @param lVal variable to set
160: * @param rVal value to set variable with
161: */
162: public SwfByte actionSetVariable(String lVal, String rVal) {
163: ensureBuffer();
164:
165: Program prg = new Program();
166: prg.push(lVal);
167: prg.push(rVal);
168: prg.setVar();
169: prg.none();
170:
171: // Setting the size of prgBuf will to pos will ensure we copy the exact
172: // number of bytes
173: FlashBuffer prgBuf = prg.body();
174: prgBuf.setSize(prgBuf.getPos());
175:
176: mBuf.writeTag(Tag.DOACTION, prgBuf.getSize());
177: mBuf.writeFOB(prgBuf);
178: return this ;
179: }
180:
181: /** Uses DataCompiler to generate action bytecode based on XML. */
182: public SwfByte actionSetElement(Element el) {
183: ensureBuffer();
184: Program prg = DataCompiler.makeProgram(el, mFlashVersion);
185: prg.none();
186: FlashBuffer prgBuf = prg.body();
187: mBuf.writeTag(Tag.DOACTION, prgBuf.getSize());
188: mBuf.writeFOB(prgBuf);
189: return this ;
190: }
191:
192: /** Write byte-code to show frame.
193: */
194: public SwfByte setShowFrame() {
195: ensureBuffer();
196: mBuf.writeTag(Tag.SHOWFRAME, 0);
197: return this ;
198: }
199:
200: /** Returns the actual amount written to the FlashBuffer, instead of
201: * returning the buffer itself. The buffer size is greater than or equal to
202: * the last position.
203: * @param buf flash buffer
204: * @return the actual bytes being stored in the buffer
205: */
206: static public byte[] getExactBytes(FlashBuffer buf) {
207: int len = buf.getPos();
208: byte[] oldBuf = buf.getBuf();
209: byte[] newBuf = new byte[len];
210: System.arraycopy(oldBuf, 0, newBuf, 0, len);
211: return newBuf;
212: }
213: }
|