Source Code Cross Referenced for FlashBuffer.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » iv » flash » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » org.openlaszlo.iv.flash.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: FlashBuffer.java,v 1.4 2002/07/15 02:15:03 skavish Exp $
0003:         *
0004:         * ===========================================================================
0005:         *
0006:         * The JGenerator Software License, Version 1.0
0007:         *
0008:         * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
0009:         *
0010:         * Redistribution and use in source and binary forms, with or without
0011:         * modification, are permitted provided that the following conditions are met:
0012:         *
0013:         * 1. Redistributions of source code must retain the above copyright
0014:         *    notice, this list of conditions and the following disclaimer.
0015:         *
0016:         * 2. Redistributions in binary form must reproduce the above copyright
0017:         *    notice, this list of conditions and the following disclaimer in
0018:         *    the documentation and/or other materials provided with the
0019:         *    distribution.
0020:         *
0021:         * 3. The end-user documentation included with the redistribution, if
0022:         *    any, must include the following acknowlegement:
0023:         *    "This product includes software developed by Dmitry Skavish
0024:         *     (skavish@usa.net, http://www.flashgap.com/)."
0025:         *    Alternately, this acknowlegement may appear in the software itself,
0026:         *    if and wherever such third-party acknowlegements normally appear.
0027:         *
0028:         * 4. The name "The JGenerator" must not be used to endorse or promote
0029:         *    products derived from this software without prior written permission.
0030:         *    For written permission, please contact skavish@usa.net.
0031:         *
0032:         * 5. Products derived from this software may not be called "The JGenerator"
0033:         *    nor may "The JGenerator" appear in their names without prior written
0034:         *    permission of Dmitry Skavish.
0035:         *
0036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039:         * DISCLAIMED.  IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
0040:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047:         * SUCH DAMAGE.
0048:         *
0049:         */
0050:
0051:        package org.openlaszlo.iv.flash.util;
0052:
0053:        import java.awt.geom.AffineTransform;
0054:        import java.awt.geom.Rectangle2D;
0055:        import java.io.*;
0056:        import org.openlaszlo.iv.flash.api.*;
0057:
0058:        /**
0059:         * Wrapper of array of bytes.
0060:         * <p>
0061:         * Provides reading and writing of flash related data types.
0062:         *
0063:         * @author Dmitry Skavish
0064:         * @see FlashOutput
0065:         */
0066:        public class FlashBuffer {
0067:
0068:            // bit buffer and position
0069:            private int bitBuf;
0070:            private int bitPos;
0071:
0072:            // byte array
0073:            private byte buf[];
0074:
0075:            // current position in the buffer for reading and writing
0076:            public int pos;
0077:
0078:            // size of the buffer
0079:            private int size;
0080:
0081:            public FlashBuffer() {
0082:            }
0083:
0084:            /**
0085:             * Allocates buffer of given capacity.<p>
0086:             * Sets current position and size to zero.
0087:             *
0088:             * @param capacity capacity of allocated buffer in bytes
0089:             */
0090:            public FlashBuffer(int capacity) {
0091:                this (new byte[capacity], 0, 0);
0092:            }
0093:
0094:            /**
0095:             * Creates buffer from given one.<p>
0096:             * Sets current position to zero and size to the size of the buffer.
0097:             *
0098:             * @param buf    buffer to init from
0099:             */
0100:            public FlashBuffer(byte[] buf) {
0101:                this (buf, 0, buf.length);
0102:            }
0103:
0104:            /**
0105:             * Creates buffer from given one of specified size.<p>
0106:             * Sets current position to zero and size to given value.
0107:             *
0108:             * @param buf    buffer to init from
0109:             * @param size   size of buffer
0110:             */
0111:            public FlashBuffer(byte[] buf, int size) {
0112:                this (buf, 0, size);
0113:            }
0114:
0115:            /**
0116:             * Creates buffer from given one of specified size and position.
0117:             *
0118:             * @param buf    buffer to init from
0119:             * @param pos    current position
0120:             * @param size   size of filled buffer (writer pos)
0121:             */
0122:            public FlashBuffer(byte[] buf, int pos, int size) {
0123:                init(buf, pos, size);
0124:            }
0125:
0126:            /**
0127:             * Creates FlashBuffer from input stream.<p>
0128:             * Reads InputStream into the buffer, sets current position
0129:             * to zero and size to the size of data read.
0130:             *
0131:             * @author Andrew Wason
0132:             * @author Dmitry Skavish
0133:             * @param is     InputStream to read from
0134:             * @exception IOException
0135:             */
0136:            public FlashBuffer(InputStream is) throws IOException {
0137:                size = 0;
0138:                try {
0139:                    int count = is.available();
0140:                    if (count <= 0)
0141:                        count = 4096;
0142:                    buf = new byte[count + 8]; // make it a little bit bigger to avoid reallocation
0143:                    for (;;) {
0144:                        count = is.read(buf, size, buf.length - size);
0145:                        if (count == -1)
0146:                            break;
0147:                        size += count;
0148:                        if (size == buf.length)
0149:                            ensureCapacity(buf.length + 4096 * 4);
0150:                    }
0151:                } finally {
0152:                    is.close();
0153:                }
0154:                pos = 0;
0155:                bitBuf = 0;
0156:                bitPos = 0;
0157:            }
0158:
0159:            public void init(byte[] buf, int pos, int size) {
0160:                this .buf = buf;
0161:                this .pos = pos;
0162:                this .size = size;
0163:                this .bitBuf = 0;
0164:                this .bitPos = 0;
0165:            }
0166:
0167:            /**
0168:             * Ensures that the buffer is as big as specified number of bytes
0169:             *
0170:             * @param cap required size of buffer
0171:             */
0172:            public final void ensureCapacity(int cap) {
0173:                if (cap > buf.length) {
0174:                    int max = buf.length * 2;
0175:                    if (cap > max)
0176:                        max = cap + 16;
0177:                    if (max < 4096)
0178:                        max = 4096;
0179:                    byte[] newBuf = new byte[max];
0180:                    System.arraycopy(buf, 0, newBuf, 0, buf.length);
0181:                    buf = newBuf;
0182:                }
0183:            }
0184:
0185:            /**
0186:             * Creates copy of the buffer.
0187:             *
0188:             * @return copy of the buffer
0189:             */
0190:            public FlashBuffer getCopy() {
0191:                byte[] myBuf = new byte[buf.length];
0192:                System.arraycopy(buf, 0, myBuf, 0, buf.length);
0193:                return new FlashBuffer(myBuf, pos, size);
0194:            }
0195:
0196:            /**
0197:             * Current read/write position.
0198:             *
0199:             * @return current read/write position
0200:             */
0201:            public final int getPos() {
0202:                return pos;
0203:            }
0204:
0205:            /**
0206:             * Returns size of the buffer.
0207:             *
0208:             * @return size of the buffer
0209:             */
0210:            public final int getSize() {
0211:                return size;
0212:            }
0213:
0214:            /**
0215:             * Sets current read/write position.<P>
0216:             * Does not increase the buffer if new position is larger
0217:             * than current capacity.
0218:             *
0219:             * @param pos    new position
0220:             * @see #ensureCapacity
0221:             */
0222:            public final void setPos(int pos) {
0223:                this .pos = pos;
0224:                if (pos > size)
0225:                    size = pos;
0226:            }
0227:
0228:            /**
0229:             * Increment current position.<p>
0230:             * Does not increase the buffer if new position is larger
0231:             * than current capacity.
0232:             *
0233:             * @see #ensureCapacity
0234:             * @see #setPos
0235:             */
0236:            public final void incPos() {
0237:                if (++pos > size)
0238:                    size = pos;
0239:            }
0240:
0241:            /**
0242:             * Sets new size of the buffer.<p>
0243:             * Does not increase the buffer if new position is larger
0244:             * than current capacity.
0245:             *
0246:             * @param size   new size of the buffer
0247:             */
0248:            public final void setSize(int size) {
0249:                this .size = size;
0250:            }
0251:
0252:            /**
0253:             * Skips bytes (changes current position).<P>
0254:             * Does not increase the buffer if new position is larger
0255:             * than current capacity.
0256:             *
0257:             * @param inc    advance value
0258:             */
0259:            public final void skip(int inc) {
0260:                setPos(pos + inc);
0261:            }
0262:
0263:            /**
0264:             * Returns the whole buffer.
0265:             *
0266:             * @return buffer
0267:             */
0268:            public final byte[] getBuf() {
0269:                return buf;
0270:            }
0271:
0272:            /*-----------------------------------------------------------------------
0273:             *                       W R I T E R
0274:             *-----------------------------------------------------------------------*/
0275:
0276:            /**
0277:             * Writes byte at specified position.<p>
0278:             * Does not change current position.
0279:             *
0280:             * @param b      byte to write
0281:             * @param pos    position to write
0282:             */
0283:            public final void writeByteAt(int b, int pos) {
0284:                buf[pos] = (byte) b;
0285:            }
0286:
0287:            /**
0288:             * Writes word at specified position.<p>
0289:             * Does not change current position.
0290:             *
0291:             * @param b      word to write
0292:             * @param pos    position to write
0293:             */
0294:            public final void writeWordAt(int b, int pos) {
0295:                buf[pos] = (byte) b;
0296:                buf[pos + 1] = (byte) (b >> 8);
0297:            }
0298:
0299:            /**
0300:             * Writes dword at specified position.<p>
0301:             * Does not change current position.
0302:             *
0303:             * @param b      dword to write
0304:             * @param pos    position to write
0305:             */
0306:            public final void writeDWordAt(int b, int pos) {
0307:                buf[pos] = (byte) b;
0308:                buf[pos + 1] = (byte) (b >> 8);
0309:                buf[pos + 2] = (byte) (b >> 16);
0310:                buf[pos + 3] = (byte) (b >> 24);
0311:            }
0312:
0313:            /**
0314:             * Writes byte and advance current position.
0315:             *
0316:             * @param b      byte to write
0317:             */
0318:            public final void writeByte(int b) {
0319:                ensureCapacity(pos + 1);
0320:                buf[pos] = (byte) b;
0321:                incPos();
0322:            }
0323:
0324:            /**
0325:             * Writes word and advance current position.
0326:             *
0327:             * @param b      word to write
0328:             */
0329:            public final void writeWord(int b) {
0330:                ensureCapacity(pos + 2);
0331:                buf[pos] = (byte) b;
0332:                buf[pos + 1] = (byte) (b >> 8);
0333:                setPos(pos + 2);
0334:            }
0335:
0336:            /**
0337:             * Writes dword and advance current position.
0338:             *
0339:             * @param b      dword to write
0340:             */
0341:            public final void writeDWord(int b) {
0342:                ensureCapacity(pos + 4);
0343:                buf[pos] = (byte) b;
0344:                buf[pos + 1] = (byte) (b >> 8);
0345:                buf[pos + 2] = (byte) (b >> 16);
0346:                buf[pos + 3] = (byte) (b >> 24);
0347:                setPos(pos + 4);
0348:            }
0349:
0350:            /****************************************************************
0351:             * Fast operations do not call ensureCapacity
0352:             */
0353:
0354:            /**
0355:             * Writes byte and advance current position.
0356:             *
0357:             * @param b      byte to write
0358:             */
0359:            public final void _writeByte(int b) {
0360:                buf[pos++] = (byte) b;
0361:            }
0362:
0363:            /**
0364:             * Writes word and advance current position.
0365:             *
0366:             * @param b      word to write
0367:             */
0368:            public final void _writeWord(int b) {
0369:                buf[pos++] = (byte) b;
0370:                buf[pos++] = (byte) (b >> 8);
0371:            }
0372:
0373:            /**
0374:             * Writes dword and advance current position.
0375:             *
0376:             * @param b      dword to write
0377:             */
0378:            public final void _writeDWord(int b) {
0379:                buf[pos++] = (byte) b;
0380:                buf[pos++] = (byte) (b >> 8);
0381:                buf[pos++] = (byte) (b >> 16);
0382:                buf[pos++] = (byte) (b >> 24);
0383:            }
0384:
0385:            /**
0386:             * Writes zero-ending string into the buffer and advance current position.
0387:             * (Flash5 back compatibility, uses Cp1252 encoding)
0388:             * @param s      string to write
0389:             */
0390:            public final byte[] _writeStringZ(String s) {
0391:                return _writeStringZ(s, "Cp1252");
0392:            }
0393:
0394:            /**
0395:             * Writes zero-ending string into the buffer and advance current position.
0396:             *
0397:             * @param s      string to write
0398:             * @return the string converted to a byte array in Flash's favorite encoding
0399:             */
0400:            public final byte[] _writeStringZ(String s, String encoding) {
0401:                byte chars[];
0402:                try {
0403:                    chars = s.getBytes(encoding);
0404:                } catch (UnsupportedEncodingException e) {
0405:                    throw new RuntimeException("could not convert string to "
0406:                            + encoding);
0407:                }
0408:                System.arraycopy(chars, 0, buf, pos, chars.length);
0409:                setPos(pos + chars.length);
0410:                buf[pos++] = 0; // null-terminate the string
0411:                return chars;
0412:            }
0413:
0414:            /**
0415:             * Writes array into this one and advance current position.
0416:             *
0417:             * @param b      intput buffer
0418:             * @param off    offset in the input buffer
0419:             * @param len    number of bytes in input buffer
0420:             */
0421:            public final void _writeArray(byte b[], int off, int len) {
0422:                System.arraycopy(b, off, buf, pos, len);
0423:                setPos(pos + len);
0424:            }
0425:
0426:            /****************************************************************/
0427:
0428:            /**
0429:             * Writes FlashBuffer into this one and advance current position.
0430:             *
0431:             * @param fob    buffer to write
0432:             */
0433:            public final void writeFOB(FlashBuffer fob) {
0434:                int len = fob.getSize();
0435:                ensureCapacity(pos + len);
0436:                System.arraycopy(fob.getBuf(), 0, buf, pos, len);
0437:                setPos(pos + len);
0438:            }
0439:
0440:            /**
0441:             * Writes array into this one and advance current position.
0442:             *
0443:             * @param b      intput buffer
0444:             * @param off    offset in the input buffer
0445:             * @param len    number of bytes in input buffer
0446:             */
0447:            public final void writeArray(byte b[], int off, int len) {
0448:                ensureCapacity(pos + len);
0449:                System.arraycopy(b, off, buf, pos, len);
0450:                setPos(pos + len);
0451:            }
0452:
0453:            /**
0454:             * Writes zero-ending string into the buffer and advance current position.
0455:             *
0456:             * +++ Back compatible with Jgen-1.4/Flash5
0457:             * Uses default encoding of JGen 1.4, "Cp1252".
0458:             * @param s      string to write
0459:             *
0460:             */
0461:
0462:            public final byte[] writeStringZ(String s) {
0463:                return writeStringZ(s, "Cp1252");
0464:            }
0465:
0466:            /**
0467:             * Writes zero-ending string into the buffer and advance current position.
0468:             *
0469:             * @param s      string to write
0470:             * @param encoding      charset encoding to use
0471:             *
0472:             */
0473:
0474:            public final byte[] writeStringZ(String s, String encoding) {
0475:                byte chars[];
0476:                try {
0477:                    // encode utf-8 for flash 6 
0478:                    chars = s.getBytes(encoding);
0479:                } catch (UnsupportedEncodingException e) {
0480:                    throw new RuntimeException("could not convert string to "
0481:                            + encoding);
0482:                }
0483:                ensureCapacity(pos + chars.length + 1);
0484:                for (int i = 0; i < chars.length; i++) {
0485:                    buf[pos++] = chars[i];
0486:                }
0487:                buf[pos] = 0;
0488:                incPos();
0489:                return chars;
0490:            }
0491:
0492:            /**
0493:             * Writes length-prefixed string into the buffer and advance current position.
0494:             *
0495:             * @param s      string to write
0496:             */
0497:            public final void writeStringL(String s) {
0498:                writeStringL(s, "Cp1252");
0499:            }
0500:
0501:            /**
0502:             * Writes length-prefixed string into the buffer and advance current position.
0503:             *
0504:             * @param s      string to write
0505:             * @param encoding      charset encoding to use
0506:             */
0507:            public final void writeStringL(String s, String encoding) {
0508:
0509:                byte chars[];
0510:                try {
0511:                    chars = s.getBytes(encoding);
0512:                } catch (UnsupportedEncodingException e) {
0513:                    throw new RuntimeException("could not convert string to "
0514:                            + encoding);
0515:                }
0516:                ensureCapacity(pos + chars.length + 1);
0517:                buf[pos++] = (byte) chars.length;
0518:                for (int i = 0; i < chars.length; i++) {
0519:                    buf[pos++] = chars[i];
0520:                }
0521:                setPos(pos); // to update size
0522:            }
0523:
0524:            /**
0525:             * Writes flash tag into the buffer and advance current position.<P>
0526:             * Depending on tag length writes short or long tag
0527:             *
0528:             * @param tagCode tag code
0529:             * @param tagSize tag size
0530:             * @see Tag
0531:             * @see #writeLongTag
0532:             * @see #writeLongTagAt
0533:             * @see #writeShortTagAt
0534:             */
0535:            public final void writeTag(int tagCode, int tagSize) {
0536:                if (tagSize >= 0x3f) {
0537:                    writeLongTag(tagCode, tagSize);
0538:                } else {
0539:                    writeWord((tagCode << 6) | tagSize);
0540:                }
0541:            }
0542:
0543:            /**
0544:             * Writes long flash tag into the buffer and advance current position.<P>
0545:             *
0546:             * @param tagCode tag code
0547:             * @param tagSize tag size
0548:             * @see Tag
0549:             * @see #writeTag
0550:             * @see #writeLongTagAt
0551:             * @see #writeShortTagAt
0552:             */
0553:            public final void writeLongTag(int tagCode, int tagSize) {
0554:                writeWord((tagCode << 6) | 0x3f);
0555:                writeDWord(tagSize);
0556:            }
0557:
0558:            /**
0559:             * Writes short flash tag into the buffer at specified position.<P>
0560:             * Does not advance position
0561:             *
0562:             * @param tagCode tag code
0563:             * @param tagSize tag size
0564:             * @see Tag
0565:             * @see #writeLongTag
0566:             * @see #writeLongTagAt
0567:             * @see #writeTag
0568:             */
0569:            public final void writeShortTagAt(int tagCode, int tagSize, int pos) {
0570:                writeWordAt((tagCode << 6) | tagSize, pos);
0571:            }
0572:
0573:            /**
0574:             * Writes long flash tag into the buffer at specified position.<P>
0575:             * Does not advance position
0576:             *
0577:             * @param tagCode tag code
0578:             * @param tagSize tag size
0579:             * @see Tag
0580:             * @see #writeLongTag
0581:             * @see #writeShortTagAt
0582:             * @see #writeTag
0583:             */
0584:            public final void writeLongTagAt(int tagCode, int tagSize, int pos) {
0585:                writeWordAt((tagCode << 6) | 0x3f, pos);
0586:                writeDWordAt(tagSize, pos + 2);
0587:            }
0588:
0589:            /**
0590:             * Writes lower bit to bit buffer.
0591:             *
0592:             * @param b      bit to write
0593:             * @see #initBits
0594:             * @see #flushBits
0595:             * @see #writeBits
0596:             */
0597:            public final void writeBit(int b) {
0598:                writeBits(b, 1);
0599:            }
0600:
0601:            /**
0602:             * Writes boolean as a bit to bit buffer.
0603:             *
0604:             * @param b      boolean to write
0605:             * @see #initBits
0606:             * @see #flushBits
0607:             */
0608:            public final void writeBool(boolean b) {
0609:                writeBits(b ? 1 : 0, 1);
0610:            }
0611:
0612:            /**
0613:             * Writes bits into the buffer.<P>
0614:             * Before starting writing bits you have to init or flush bits
0615:             * buffer using methods {@link #initBits} or {@link #flushBits}
0616:             *
0617:             * @param v      bits to write packed in integer
0618:             * @param len    number of bits to write
0619:             * @see #initBits
0620:             * @see #flushBits
0621:             */
0622:            public final void writeBits(int v, int len) {
0623:                ensureCapacity(pos + 4);
0624:                for (;;) {
0625:                    v = v & ((1 << len) - 1);
0626:                    int l = 8 - bitPos;
0627:                    int s = l - len;
0628:                    if (s >= 0) {
0629:                        bitBuf = (bitBuf << len) | v;
0630:                        bitPos += len;
0631:                        return;
0632:                    } else {
0633:                        s = -s;
0634:                        int bb = (bitBuf << l) | (v >>> s);
0635:                        buf[pos] = (byte) bb;
0636:                        incPos();
0637:                        len = s;
0638:                        bitBuf = 0;
0639:                        bitPos = 0;
0640:                    }
0641:                }
0642:            }
0643:
0644:            /**
0645:             * Flushes bits buffer into flash buffer.<P>
0646:             * Has to be called after you finished writing series of bits
0647:             *
0648:             * @see #writeBits
0649:             * @see #initBits
0650:             */
0651:            public final void flushBits() {
0652:                if (bitPos != 0) {
0653:                    int bb = bitBuf << (8 - bitPos);
0654:                    writeByte(bb);
0655:                }
0656:                bitBuf = 0;
0657:                bitPos = 0;
0658:            }
0659:
0660:            /**
0661:             * Inits bits buffer.<P>
0662:             * Has to be called before writing series of bits or
0663:             * before reading bits
0664:             *
0665:             * @see #writeBits
0666:             * @see #flushBits
0667:             * @see #skipBits
0668:             * @see #getBits
0669:             */
0670:            public final void initBits() {
0671:                bitBuf = 0;
0672:                bitPos = 0;
0673:            }
0674:
0675:            /**
0676:             * Writes specified inputstream to this buffer
0677:             *
0678:             * @param is     input stream
0679:             */
0680:            public final void write(InputStream is) throws IOException {
0681:                try {
0682:                    int count = is.available();
0683:                    if (count <= 0)
0684:                        count = 4096;
0685:                    ensureCapacity(pos + count + 8);
0686:                    for (;;) {
0687:                        count = is.read(buf, pos, buf.length - pos);
0688:                        if (count == -1)
0689:                            break;
0690:                        pos += count;
0691:                        if (pos == buf.length)
0692:                            ensureCapacity(buf.length + 4096 * 4);
0693:                    }
0694:                    setPos(pos);
0695:                } finally {
0696:                    is.close();
0697:                }
0698:            }
0699:
0700:            /*-----------------------------------------------------------------------
0701:             *                       R E A D E R
0702:             *-----------------------------------------------------------------------*/
0703:
0704:            /**
0705:             * Skips bits.
0706:             *
0707:             * @param n      number of bits to skip
0708:             * @see #initBits
0709:             */
0710:            public final void skipBits(int n) {
0711:                for (;;) {
0712:                    int s = n - bitPos;
0713:                    if (s > 0) {
0714:                        n -= bitPos;
0715:                        // get the next buffer
0716:                        bitBuf = getUByte();
0717:                        bitPos = 8;
0718:                    } else {
0719:                        // Consume a portion of the buffer
0720:                        s = -s;
0721:                        bitPos = s;
0722:                        bitBuf &= (1 << s) - 1; // mask off the consumed bits
0723:                        break;
0724:                    }
0725:                }
0726:            }
0727:
0728:            /**
0729:             * Reads <b>unsigned</b> bits from the buffer.<P>
0730:             *
0731:             * According to profiler this is probably the most
0732:             * time consuming operation. Below there is a new version,
0733:             * but I did not test it much, it's about 30% percent faster.
0734:             *
0735:             * @param n      number of bits to read
0736:             * @return read bits
0737:             * @see #initBits
0738:             * @see #getSBits
0739:             */
0740:            public final int getBits(int n) {
0741:                // get n bits from the stream.
0742:                int v = 0;
0743:
0744:                for (;;) {
0745:                    int s = n - bitPos;
0746:                    if (s > 0) {
0747:                        // Consume the entire buffer
0748:                        v |= bitBuf << s;
0749:                        n -= bitPos;
0750:
0751:                        // get the next buffer
0752:                        bitBuf = getUByte();
0753:                        bitPos = 8;
0754:                    } else {
0755:                        // Consume a portion of the buffer
0756:                        s = -s;
0757:                        v |= bitBuf >> s;
0758:                        bitPos = s;
0759:                        bitBuf &= (1 << s) - 1; // mask off the consumed bits
0760:                        return v;
0761:                    }
0762:                }
0763:            }
0764:
0765:            // new version of getBits
0766:            public final int new_getBits(int n) {
0767:                // get n bits from the stream.
0768:
0769:                int s = n - bitPos;
0770:                if (s > 0) {
0771:                    // Consume the entire buffer
0772:                    int v = bitBuf << s;
0773:                    n -= bitPos;
0774:
0775:                    // get the next buffer
0776:                    if (n <= 8) {
0777:                        bitBuf = getUByte();
0778:                        bitPos = 8;
0779:                    } else if (n <= 16) {
0780:                        bitBuf = (getUByte() << 8) | getUByte();
0781:                        bitPos = 16;
0782:                    } else if (n <= 24) {
0783:                        bitBuf = (getUByte() << 16) | (getUByte() << 8)
0784:                                | getUByte();
0785:                        bitPos = 24;
0786:                    } else {
0787:                        bitBuf = (getUByte() << 24) | (getUByte() << 16)
0788:                                | (getUByte() << 8) | getUByte();
0789:                        bitPos = 32;
0790:                    }
0791:                    bitPos -= n;
0792:                    v |= bitBuf >> bitPos;
0793:                    bitBuf &= (1 << bitPos) - 1;
0794:                    return v;
0795:                }
0796:
0797:                // Consume a portion of the buffer
0798:                s = -s;
0799:                int v = bitBuf >> s;
0800:                bitPos = s;
0801:                bitBuf &= (1 << s) - 1; // mask off the consumed bits
0802:                return v;
0803:            }
0804:
0805:            /**
0806:             * Reads <b>signed</b> bits from the buffer.<P>
0807:             *
0808:             * @param n      number of bits to read
0809:             * @return read bits extended with sign
0810:             * @see #initBits
0811:             * @see #getBits
0812:             */
0813:            public final int getSBits(int n) {
0814:                // get n bits from the string with sign extension.
0815:                // get the number as an unsigned value.
0816:                int v = getBits(n);
0817:
0818:                // Is the number negative?
0819:                if ((v & (1 << (n - 1))) != 0) {
0820:                    // Yes. Extend the sign.
0821:                    v |= -1 << n;
0822:                }
0823:
0824:                return v;
0825:            }
0826:
0827:            /**
0828:             * Reads one bit and returns it as boolean
0829:             *
0830:             * @return true - if bit is 1, false - if bit is 0
0831:             */
0832:            public boolean getBool() {
0833:                return getBits(1) == 1;
0834:            }
0835:
0836:            /**
0837:             * Reads bytes into given FlashBuffer.
0838:             *
0839:             * @param fob    flash buffer where to read bytes
0840:             * @param length number of bytes to read
0841:             */
0842:            public final void getTo(FlashBuffer fob, int length) {
0843:                fob.writeArray(buf, pos, length);
0844:                pos += length;
0845:            }
0846:
0847:            /**
0848:             * Reads zero-ending string.
0849:             *
0850:             * @return read string
0851:             */
0852:            public final String getString() {
0853:                int sp = pos;
0854:                while (buf[pos++] != 0)
0855:                    ;
0856:                return new String(buf, sp, pos - sp - 1);
0857:            }
0858:
0859:            /**
0860:             * Read string by its length.
0861:             *
0862:             * @param length string length
0863:             * @return read string
0864:             */
0865:            public final String getString(int length) {
0866:                int sp = pos;
0867:                pos += length;
0868:                return new String(buf, sp, length);
0869:            }
0870:
0871:            /**
0872:             * Reads bytes into array of bytes.
0873:             *
0874:             * @param length number of bytes to read
0875:             * @return created array of bytes with data
0876:             */
0877:            public final byte[] getBytes(int length) {
0878:                byte[] ba = new byte[length];
0879:                System.arraycopy(buf, pos, ba, 0, length);
0880:                pos += length;
0881:                return ba;
0882:            }
0883:
0884:            /**
0885:             * Reads one signed byte.
0886:             *
0887:             * @return signed byte
0888:             */
0889:            public final int getByte() {
0890:                return buf[pos++];
0891:            }
0892:
0893:            /**
0894:             * Reads one unsigned byte.
0895:             *
0896:             * @return unsigned byte
0897:             */
0898:            public final int getUByte() {
0899:                return buf[pos++] & 0xff;
0900:            }
0901:
0902:            public final int getByteAt(int p) {
0903:                return buf[p];
0904:            }
0905:
0906:            public final int getUByteAt(int p) {
0907:                return buf[p] & 0xff;
0908:            }
0909:
0910:            /**
0911:             * Reads one signed word.
0912:             *
0913:             * @return signed word
0914:             */
0915:            public final int getWord() {
0916:                int r = Util.getWord(buf[pos], buf[pos + 1]);
0917:                pos += 2;
0918:                return r;
0919:            }
0920:
0921:            public final int getWordAt(int p) {
0922:                return Util.getWord(buf[p], buf[p + 1]);
0923:            }
0924:
0925:            /**
0926:             * Reads one unsigned word.
0927:             *
0928:             * @return unsigned word
0929:             */
0930:            public final int getUWord() {
0931:                int r = Util.getUWord(buf[pos], buf[pos + 1]);
0932:                pos += 2;
0933:                return r;
0934:            }
0935:
0936:            public final int getUWordAt(int p) {
0937:                return Util.getUWord(buf[p], buf[p + 1]);
0938:            }
0939:
0940:            /**
0941:             * Reads one signed dword.
0942:             *
0943:             * @return signed dword
0944:             */
0945:            public int getDWord() {
0946:                int r = Util.getDWord(buf[pos], buf[pos + 1], buf[pos + 2],
0947:                        buf[pos + 3]);
0948:                pos += 4;
0949:                return r;
0950:            }
0951:
0952:            public int getDWordAt(int p) {
0953:                return Util
0954:                        .getDWord(buf[p], buf[p + 1], buf[p + 2], buf[p + 3]);
0955:            }
0956:
0957:            /**
0958:             * Reads one unsigned dword.
0959:             *
0960:             * @return unsigned dword
0961:             */
0962:            public int getUDWord() {
0963:                int r = Util.getUDWord(buf[pos], buf[pos + 1], buf[pos + 2],
0964:                        buf[pos + 3]);
0965:                pos += 4;
0966:                return r;
0967:            }
0968:
0969:            public int getUDWordAt(int p) {
0970:                return Util.getUDWord(buf[p], buf[p + 1], buf[p + 2],
0971:                        buf[p + 3]);
0972:            }
0973:
0974:            /*-----------------------------------------------------------------------
0975:             *                       InputStream
0976:             *-----------------------------------------------------------------------*/
0977:
0978:            /**
0979:             * Creates input stream which can be used to read data from this buffer.
0980:             *
0981:             * @return input stream
0982:             * @see #getOutputStream
0983:             */
0984:            public InputStream getInputStream() {
0985:                return new FlashBufferInputStream();
0986:            }
0987:
0988:            /**
0989:             * Creates input stream which can be used to read data from this buffer.
0990:             *
0991:             * @param pos    first input position, position to start reading from
0992:             * @return input stream
0993:             * @see #getOutputStream
0994:             */
0995:            public InputStream getInputStream(int pos) {
0996:                return new FlashBufferInputStream(pos);
0997:            }
0998:
0999:            public class FlashBufferInputStream extends InputStream {
1000:
1001:                private int curPos = 0;
1002:
1003:                public FlashBufferInputStream() {
1004:                }
1005:
1006:                public FlashBufferInputStream(int curPos) {
1007:                    this .curPos = curPos;
1008:                }
1009:
1010:                public int read() throws IOException {
1011:                    if (curPos >= size)
1012:                        return -1;
1013:                    return buf[curPos++] & 0xff;
1014:                }
1015:
1016:                public int read(byte b[], int off, int len) throws IOException {
1017:                    if (len == 0)
1018:                        return 0;
1019:                    int sz = Math.min(len, size - curPos);
1020:                    if (sz <= 0)
1021:                        return -1;
1022:                    System.arraycopy(buf, curPos, b, off, sz);
1023:                    curPos += sz;
1024:                    return sz;
1025:                }
1026:
1027:                public int available() throws IOException {
1028:                    return size - curPos;
1029:                }
1030:            }
1031:
1032:            /*-----------------------------------------------------------------------
1033:             *                       OutputStream
1034:             *-----------------------------------------------------------------------*/
1035:
1036:            /**
1037:             * Creates output stream which can be used to write data to this buffer.
1038:             *
1039:             * @return output stream
1040:             * @see #getInputStream
1041:             */
1042:            public OutputStream getOutputStream() {
1043:                return new FlashBufferOutputStream();
1044:            }
1045:
1046:            public class FlashBufferOutputStream extends OutputStream {
1047:
1048:                public FlashBufferOutputStream() {
1049:                }
1050:
1051:                public void write(int b) {
1052:                    writeByte(b);
1053:                }
1054:
1055:                public void write(byte b[], int off, int len) {
1056:                    writeArray(b, off, len);
1057:                }
1058:            }
1059:
1060:            /*-----------------------------------------------------------------------
1061:             *                       AffineTransform
1062:             *-----------------------------------------------------------------------*/
1063:
1064:            public AffineTransform getMatrix() {
1065:                initBits();
1066:
1067:                double m00; // scale x
1068:                double m10; // skew0 (y shear)
1069:                double m01; // skew1 (x shear)
1070:                double m11; // scale y
1071:                double m02; // translate x
1072:                double m12; // trasnlate y
1073:
1074:                // Scale terms
1075:                if (getBool()) {
1076:                    int nBits = getBits(5);
1077:                    m00 = Util.fixed2double(getSBits(nBits));
1078:                    m11 = Util.fixed2double(getSBits(nBits));
1079:                } else {
1080:                    m00 = 1.0;
1081:                    m11 = 1.0;
1082:                }
1083:
1084:                // Rotate/skew terms
1085:                if (getBool()) {
1086:                    int nBits = getBits(5);
1087:                    m10 = Util.fixed2double(getSBits(nBits));
1088:                    m01 = Util.fixed2double(getSBits(nBits));
1089:                } else {
1090:                    m10 = 0.0;
1091:                    m01 = 0.0;
1092:                }
1093:
1094:                // Translate terms
1095:                int nBits = getBits(5);
1096:                m02 = getSBits(nBits);
1097:                m12 = getSBits(nBits);
1098:
1099:                AffineTransform m = new AffineTransform(m00, m10, m01, m11,
1100:                        m02, m12);
1101:                return m;
1102:            }
1103:
1104:            /**
1105:             * Skips MATRIX tag without creating Matrix object
1106:             */
1107:            public void skipMatrix() {
1108:                initBits();
1109:                // Scale terms
1110:                if (getBool()) {
1111:                    int nBits = getBits(5);
1112:                    skipBits(nBits + nBits);
1113:                }
1114:                // Rotate/skew terms
1115:                if (getBool()) {
1116:                    int nBits = getBits(5);
1117:                    skipBits(nBits + nBits);
1118:                }
1119:                // Translate terms
1120:                int nBits = getBits(5);
1121:                skipBits(nBits + nBits);
1122:            }
1123:
1124:            public void write(AffineTransform m) {
1125:                initBits();
1126:
1127:                double m00 = m.getScaleX();
1128:                double m10 = m.getShearY();
1129:                double m01 = m.getShearX();
1130:                double m11 = m.getScaleY();
1131:                double m02 = m.getTranslateX();
1132:                double m12 = m.getTranslateY();
1133:
1134:                if (m00 != 1.0 || m11 != 1.0) {
1135:                    writeBit(1);
1136:                    int i_scaleX = Util.double2fixed(m00);
1137:                    int i_scaleY = Util.double2fixed(m11);
1138:                    int nBits = Util.getMinBitsS(Util
1139:                            .getMax(i_scaleX, i_scaleY));
1140:                    writeBits(nBits, 5);
1141:                    writeBits(i_scaleX, nBits);
1142:                    writeBits(i_scaleY, nBits);
1143:                } else {
1144:                    writeBit(0);
1145:                }
1146:
1147:                if (m10 != 0.0 || m01 != 0.0) {
1148:                    writeBit(1);
1149:                    int i_rotateSkew0 = Util.double2fixed(m10);
1150:                    int i_rotateSkew1 = Util.double2fixed(m01);
1151:                    int nBits = Util.getMinBitsS(Util.getMax(i_rotateSkew0,
1152:                            i_rotateSkew1));
1153:                    writeBits(nBits, 5);
1154:                    writeBits(i_rotateSkew0, nBits);
1155:                    writeBits(i_rotateSkew1, nBits);
1156:                } else {
1157:                    writeBit(0);
1158:                }
1159:
1160:                int i_translateX = (int) m02;
1161:                int i_translateY = (int) m12;
1162:                int nBits = Util.getMinBitsS(Util.getMax(i_translateX,
1163:                        i_translateY));
1164:                writeBits(nBits, 5);
1165:                writeBits(i_translateX, nBits);
1166:                writeBits(i_translateY, nBits);
1167:                flushBits();
1168:            }
1169:
1170:            /*-----------------------------------------------------------------------
1171:             *                       Rectangle2D
1172:             *-----------------------------------------------------------------------*/
1173:
1174:            public Rectangle2D getRect() {
1175:                initBits();
1176:                int nBits = getBits(5);
1177:                int xmin = getSBits(nBits);
1178:                int xmax = getSBits(nBits);
1179:                int ymin = getSBits(nBits);
1180:                int ymax = getSBits(nBits);
1181:
1182:                Rectangle2D r = GeomHelper.newRectangle(xmin, ymin,
1183:                        xmax - xmin, ymax - ymin);
1184:                return r;
1185:            }
1186:
1187:            /**
1188:             * Skips rectangle
1189:             */
1190:            public void skipRect() {
1191:                initBits();
1192:                int nBits = getBits(5);
1193:                skip(((5 + (nBits * 4)) + 7) / 8 - 1);
1194:            }
1195:
1196:            public void write(Rectangle2D r) {
1197:                initBits();
1198:
1199:                int xmin = (int) r.getMinX();
1200:                int xmax = (int) r.getMaxX();
1201:                int ymin = (int) r.getMinY();
1202:                int ymax = (int) r.getMaxY();
1203:
1204:                int nBits = Util.getMinBitsS(Util
1205:                        .getMax(xmin, xmax, ymin, ymax));
1206:                writeBits(nBits, 5);
1207:                writeBits(xmin, nBits);
1208:                writeBits(xmax, nBits);
1209:                writeBits(ymin, nBits);
1210:                writeBits(ymax, nBits);
1211:                flushBits();
1212:            }
1213:
1214:            public String toString() {
1215:                return new String(buf, 0, pos);
1216:            }
1217:
1218:            public String toString(String encoding)
1219:                    throws java.io.UnsupportedEncodingException {
1220:                return new String(buf, 0, pos, encoding);
1221:            }
1222:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.