Source Code Cross Referenced for AbstractIoBuffer.java in  » Net » mina-2.0.0-M1 » org » apache » mina » common » 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 » Net » mina 2.0.0 M1 » org.apache.mina.common 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one
0003:         *  or more contributor license agreements.  See the NOTICE file
0004:         *  distributed with this work for additional information
0005:         *  regarding copyright ownership.  The ASF licenses this file
0006:         *  to you under the Apache License, Version 2.0 (the
0007:         *  "License"); you may not use this file except in compliance
0008:         *  with the License.  You may obtain a copy of the License at
0009:         *
0010:         *    http://www.apache.org/licenses/LICENSE-2.0
0011:         *
0012:         *  Unless required by applicable law or agreed to in writing,
0013:         *  software distributed under the License is distributed on an
0014:         *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015:         *  KIND, either express or implied.  See the License for the
0016:         *  specific language governing permissions and limitations
0017:         *  under the License.
0018:         *
0019:         */
0020:        package org.apache.mina.common;
0021:
0022:        import java.io.EOFException;
0023:        import java.io.IOException;
0024:        import java.io.InputStream;
0025:        import java.io.ObjectInputStream;
0026:        import java.io.ObjectOutputStream;
0027:        import java.io.ObjectStreamClass;
0028:        import java.io.OutputStream;
0029:        import java.io.StreamCorruptedException;
0030:        import java.nio.BufferOverflowException;
0031:        import java.nio.BufferUnderflowException;
0032:        import java.nio.ByteBuffer;
0033:        import java.nio.ByteOrder;
0034:        import java.nio.CharBuffer;
0035:        import java.nio.DoubleBuffer;
0036:        import java.nio.FloatBuffer;
0037:        import java.nio.IntBuffer;
0038:        import java.nio.LongBuffer;
0039:        import java.nio.ShortBuffer;
0040:        import java.nio.charset.CharacterCodingException;
0041:        import java.nio.charset.CharsetDecoder;
0042:        import java.nio.charset.CharsetEncoder;
0043:        import java.nio.charset.CoderResult;
0044:        import java.util.EnumSet;
0045:        import java.util.Set;
0046:
0047:        /**
0048:         * A base implementation of {@link IoBuffer}.  This implementation
0049:         * assumes that {@link IoBuffer#buf()} always returns a correct NIO
0050:         * {@link ByteBuffer} instance.  Most implementations could
0051:         * extend this class and implement their own buffer management mechanism.
0052:         *
0053:         * @author The Apache MINA Project (dev@mina.apache.org)
0054:         * @version $Rev: 611312 $, $Date: 2008-01-11 14:59:43 -0700 (Fri, 11 Jan 2008) $
0055:         * @see IoBufferAllocator
0056:         */
0057:        public abstract class AbstractIoBuffer extends IoBuffer {
0058:
0059:            private final IoBufferAllocator allocator;
0060:            private final boolean derived;
0061:            private boolean autoExpand;
0062:            private boolean autoShrink;
0063:            private boolean recapacityAllowed = true;
0064:            private int minimumCapacity;
0065:
0066:            /**
0067:             * We don't have any access to Buffer.markValue(), so we need to track it down,
0068:             * which will cause small extra overhead.
0069:             */
0070:            private int mark = -1;
0071:
0072:            /**
0073:             * Creates a new parent buffer.
0074:             */
0075:            protected AbstractIoBuffer(IoBufferAllocator allocator,
0076:                    int initialCapacity) {
0077:                this .allocator = allocator;
0078:                this .recapacityAllowed = true;
0079:                this .derived = false;
0080:                this .minimumCapacity = initialCapacity;
0081:            }
0082:
0083:            /**
0084:             * Creates a new derived buffer.
0085:             */
0086:            protected AbstractIoBuffer(AbstractIoBuffer parent) {
0087:                this .allocator = parent.allocator;
0088:                this .recapacityAllowed = false;
0089:                this .derived = true;
0090:                this .minimumCapacity = parent.minimumCapacity;
0091:            }
0092:
0093:            @Override
0094:            public final boolean isDirect() {
0095:                return buf().isDirect();
0096:            }
0097:
0098:            @Override
0099:            public final boolean isReadOnly() {
0100:                return buf().isReadOnly();
0101:            }
0102:
0103:            /**
0104:             * Sets the underlying NIO buffer instance.
0105:             */
0106:            protected abstract void buf(ByteBuffer newBuf);
0107:
0108:            @Override
0109:            public final int minimumCapacity() {
0110:                return minimumCapacity;
0111:            }
0112:
0113:            @Override
0114:            public final IoBuffer minimumCapacity(int minimumCapacity) {
0115:                if (minimumCapacity < 0) {
0116:                    throw new IllegalArgumentException("minimumCapacity: "
0117:                            + minimumCapacity);
0118:                }
0119:                this .minimumCapacity = minimumCapacity;
0120:                return this ;
0121:            }
0122:
0123:            @Override
0124:            public final int capacity() {
0125:                return buf().capacity();
0126:            }
0127:
0128:            @Override
0129:            public final IoBuffer capacity(int newCapacity) {
0130:                if (!recapacityAllowed) {
0131:                    throw new IllegalStateException(
0132:                            "Derived buffers and their parent can't be expanded.");
0133:                }
0134:
0135:                // Allocate a new buffer and transfer all settings to it.
0136:                if (newCapacity > capacity()) {
0137:                    // Expand:
0138:                    //// Save the state.
0139:                    int pos = position();
0140:                    int limit = limit();
0141:                    ByteOrder bo = order();
0142:
0143:                    //// Reallocate.
0144:                    ByteBuffer oldBuf = buf();
0145:                    ByteBuffer newBuf = allocator.allocateNioBuffer(
0146:                            newCapacity, isDirect());
0147:                    oldBuf.clear();
0148:                    newBuf.put(oldBuf);
0149:                    buf(newBuf);
0150:
0151:                    //// Restore the state.
0152:                    buf().limit(limit);
0153:                    if (mark >= 0) {
0154:                        buf().position(mark);
0155:                        buf().mark();
0156:                    }
0157:                    buf().position(pos);
0158:                    buf().order(bo);
0159:                }
0160:
0161:                return this ;
0162:            }
0163:
0164:            @Override
0165:            public final boolean isAutoExpand() {
0166:                return autoExpand && recapacityAllowed;
0167:            }
0168:
0169:            @Override
0170:            public final boolean isAutoShrink() {
0171:                return autoShrink && recapacityAllowed;
0172:            }
0173:
0174:            @Override
0175:            public final boolean isDerived() {
0176:                return derived;
0177:            }
0178:
0179:            @Override
0180:            public final IoBuffer setAutoExpand(boolean autoExpand) {
0181:                if (!recapacityAllowed) {
0182:                    throw new IllegalStateException(
0183:                            "Derived buffers and their parent can't be expanded.");
0184:                }
0185:                this .autoExpand = autoExpand;
0186:                return this ;
0187:            }
0188:
0189:            @Override
0190:            public final IoBuffer setAutoShrink(boolean autoShrink) {
0191:                if (!recapacityAllowed) {
0192:                    throw new IllegalStateException(
0193:                            "Derived buffers and their parent can't be shrinked.");
0194:                }
0195:                this .autoShrink = autoShrink;
0196:                return this ;
0197:            }
0198:
0199:            @Override
0200:            public final IoBuffer expand(int expectedRemaining) {
0201:                return expand(position(), expectedRemaining);
0202:            }
0203:
0204:            @Override
0205:            public final IoBuffer expand(int pos, int expectedRemaining) {
0206:                if (!recapacityAllowed) {
0207:                    throw new IllegalStateException(
0208:                            "Derived buffers and their parent can't be expanded.");
0209:                }
0210:
0211:                int end = pos + expectedRemaining;
0212:                if (end > capacity()) {
0213:                    // The buffer needs expansion.
0214:                    capacity(end);
0215:                }
0216:
0217:                if (end > limit()) {
0218:                    // We call limit() directly to prevent StackOverflowError
0219:                    buf().limit(end);
0220:                }
0221:                return this ;
0222:            }
0223:
0224:            @Override
0225:            public final IoBuffer shrink() {
0226:
0227:                if (!recapacityAllowed) {
0228:                    throw new IllegalStateException(
0229:                            "Derived buffers and their parent can't be expanded.");
0230:                }
0231:
0232:                int position = position();
0233:                int capacity = capacity();
0234:                int limit = limit();
0235:                if (capacity == limit) {
0236:                    return this ;
0237:                }
0238:
0239:                int newCapacity = capacity;
0240:                int minCapacity = Math.max(minimumCapacity, limit);
0241:                for (;;) {
0242:                    if (newCapacity >>> 1 < minCapacity) {
0243:                        break;
0244:                    }
0245:                    newCapacity >>>= 1;
0246:                }
0247:
0248:                newCapacity = Math.max(minCapacity, newCapacity);
0249:
0250:                if (newCapacity == capacity) {
0251:                    return this ;
0252:                }
0253:
0254:                // Shrink and compact:
0255:                //// Save the state.
0256:                ByteOrder bo = order();
0257:
0258:                //// Reallocate.
0259:                ByteBuffer oldBuf = buf();
0260:                ByteBuffer newBuf = allocator.allocateNioBuffer(newCapacity,
0261:                        isDirect());
0262:                oldBuf.position(0);
0263:                oldBuf.limit(limit);
0264:                newBuf.put(oldBuf);
0265:                buf(newBuf);
0266:
0267:                //// Restore the state.
0268:                buf().position(position);
0269:                buf().limit(limit);
0270:                buf().order(bo);
0271:                mark = -1;
0272:
0273:                return this ;
0274:            }
0275:
0276:            @Override
0277:            public final int position() {
0278:                return buf().position();
0279:            }
0280:
0281:            @Override
0282:            public final IoBuffer position(int newPosition) {
0283:                autoExpand(newPosition, 0);
0284:                buf().position(newPosition);
0285:                if (mark > newPosition) {
0286:                    mark = -1;
0287:                }
0288:                return this ;
0289:            }
0290:
0291:            @Override
0292:            public final int limit() {
0293:                return buf().limit();
0294:            }
0295:
0296:            @Override
0297:            public final IoBuffer limit(int newLimit) {
0298:                autoExpand(newLimit, 0);
0299:                buf().limit(newLimit);
0300:                if (mark > newLimit) {
0301:                    mark = -1;
0302:                }
0303:                return this ;
0304:            }
0305:
0306:            @Override
0307:            public final IoBuffer mark() {
0308:                buf().mark();
0309:                mark = position();
0310:                return this ;
0311:            }
0312:
0313:            @Override
0314:            public final int markValue() {
0315:                return mark;
0316:            }
0317:
0318:            @Override
0319:            public final IoBuffer reset() {
0320:                buf().reset();
0321:                return this ;
0322:            }
0323:
0324:            @Override
0325:            public final IoBuffer clear() {
0326:                buf().clear();
0327:                mark = -1;
0328:                return this ;
0329:            }
0330:
0331:            @Override
0332:            public final IoBuffer sweep() {
0333:                clear();
0334:                return fillAndReset(remaining());
0335:            }
0336:
0337:            @Override
0338:            public final IoBuffer sweep(byte value) {
0339:                clear();
0340:                return fillAndReset(value, remaining());
0341:            }
0342:
0343:            @Override
0344:            public final IoBuffer flip() {
0345:                buf().flip();
0346:                mark = -1;
0347:                return this ;
0348:            }
0349:
0350:            @Override
0351:            public final IoBuffer rewind() {
0352:                buf().rewind();
0353:                mark = -1;
0354:                return this ;
0355:            }
0356:
0357:            @Override
0358:            public final int remaining() {
0359:                return limit() - position();
0360:            }
0361:
0362:            @Override
0363:            public final boolean hasRemaining() {
0364:                return limit() > position();
0365:            }
0366:
0367:            @Override
0368:            public final byte get() {
0369:                return buf().get();
0370:            }
0371:
0372:            @Override
0373:            public final short getUnsigned() {
0374:                return (short) (get() & 0xff);
0375:            }
0376:
0377:            @Override
0378:            public final IoBuffer put(byte b) {
0379:                autoExpand(1);
0380:                buf().put(b);
0381:                return this ;
0382:            }
0383:
0384:            @Override
0385:            public final byte get(int index) {
0386:                return buf().get(index);
0387:            }
0388:
0389:            @Override
0390:            public final short getUnsigned(int index) {
0391:                return (short) (get(index) & 0xff);
0392:            }
0393:
0394:            @Override
0395:            public final IoBuffer put(int index, byte b) {
0396:                autoExpand(index, 1);
0397:                buf().put(index, b);
0398:                return this ;
0399:            }
0400:
0401:            @Override
0402:            public final IoBuffer get(byte[] dst, int offset, int length) {
0403:                buf().get(dst, offset, length);
0404:                return this ;
0405:            }
0406:
0407:            @Override
0408:            public final IoBuffer put(ByteBuffer src) {
0409:                autoExpand(src.remaining());
0410:                buf().put(src);
0411:                return this ;
0412:            }
0413:
0414:            @Override
0415:            public final IoBuffer put(byte[] src, int offset, int length) {
0416:                autoExpand(length);
0417:                buf().put(src, offset, length);
0418:                return this ;
0419:            }
0420:
0421:            @Override
0422:            public final IoBuffer compact() {
0423:                int remaining = remaining();
0424:                int capacity = capacity();
0425:
0426:                if (capacity == 0) {
0427:                    return this ;
0428:                }
0429:
0430:                if (isAutoShrink() && remaining <= capacity >>> 2
0431:                        && capacity > minimumCapacity) {
0432:                    int newCapacity = capacity;
0433:                    int minCapacity = Math.max(minimumCapacity, remaining << 1);
0434:                    for (;;) {
0435:                        if (newCapacity >>> 1 < minCapacity) {
0436:                            break;
0437:                        }
0438:                        newCapacity >>>= 1;
0439:                    }
0440:
0441:                    newCapacity = Math.max(minCapacity, newCapacity);
0442:
0443:                    if (newCapacity == capacity) {
0444:                        return this ;
0445:                    }
0446:
0447:                    // Shrink and compact:
0448:                    //// Save the state.
0449:                    ByteOrder bo = order();
0450:
0451:                    //// Sanity check.
0452:                    if (remaining > newCapacity) {
0453:                        throw new IllegalStateException(
0454:                                "The amount of the remaining bytes is greater than "
0455:                                        + "the new capacity.");
0456:                    }
0457:
0458:                    //// Reallocate.
0459:                    ByteBuffer oldBuf = buf();
0460:                    ByteBuffer newBuf = allocator.allocateNioBuffer(
0461:                            newCapacity, isDirect());
0462:                    newBuf.put(oldBuf);
0463:                    buf(newBuf);
0464:
0465:                    //// Restore the state.
0466:                    buf().order(bo);
0467:                } else {
0468:                    buf().compact();
0469:                }
0470:                mark = -1;
0471:                return this ;
0472:            }
0473:
0474:            @Override
0475:            public final ByteOrder order() {
0476:                return buf().order();
0477:            }
0478:
0479:            @Override
0480:            public final IoBuffer order(ByteOrder bo) {
0481:                buf().order(bo);
0482:                return this ;
0483:            }
0484:
0485:            @Override
0486:            public final char getChar() {
0487:                return buf().getChar();
0488:            }
0489:
0490:            @Override
0491:            public final IoBuffer putChar(char value) {
0492:                autoExpand(2);
0493:                buf().putChar(value);
0494:                return this ;
0495:            }
0496:
0497:            @Override
0498:            public final char getChar(int index) {
0499:                return buf().getChar(index);
0500:            }
0501:
0502:            @Override
0503:            public final IoBuffer putChar(int index, char value) {
0504:                autoExpand(index, 2);
0505:                buf().putChar(index, value);
0506:                return this ;
0507:            }
0508:
0509:            @Override
0510:            public final CharBuffer asCharBuffer() {
0511:                return buf().asCharBuffer();
0512:            }
0513:
0514:            @Override
0515:            public final short getShort() {
0516:                return buf().getShort();
0517:            }
0518:
0519:            @Override
0520:            public final IoBuffer putShort(short value) {
0521:                autoExpand(2);
0522:                buf().putShort(value);
0523:                return this ;
0524:            }
0525:
0526:            @Override
0527:            public final short getShort(int index) {
0528:                return buf().getShort(index);
0529:            }
0530:
0531:            @Override
0532:            public final IoBuffer putShort(int index, short value) {
0533:                autoExpand(index, 2);
0534:                buf().putShort(index, value);
0535:                return this ;
0536:            }
0537:
0538:            @Override
0539:            public final ShortBuffer asShortBuffer() {
0540:                return buf().asShortBuffer();
0541:            }
0542:
0543:            @Override
0544:            public final int getInt() {
0545:                return buf().getInt();
0546:            }
0547:
0548:            @Override
0549:            public final IoBuffer putInt(int value) {
0550:                autoExpand(4);
0551:                buf().putInt(value);
0552:                return this ;
0553:            }
0554:
0555:            @Override
0556:            public final int getInt(int index) {
0557:                return buf().getInt(index);
0558:            }
0559:
0560:            @Override
0561:            public final IoBuffer putInt(int index, int value) {
0562:                autoExpand(index, 4);
0563:                buf().putInt(index, value);
0564:                return this ;
0565:            }
0566:
0567:            @Override
0568:            public final IntBuffer asIntBuffer() {
0569:                return buf().asIntBuffer();
0570:            }
0571:
0572:            @Override
0573:            public final long getLong() {
0574:                return buf().getLong();
0575:            }
0576:
0577:            @Override
0578:            public final IoBuffer putLong(long value) {
0579:                autoExpand(8);
0580:                buf().putLong(value);
0581:                return this ;
0582:            }
0583:
0584:            @Override
0585:            public final long getLong(int index) {
0586:                return buf().getLong(index);
0587:            }
0588:
0589:            @Override
0590:            public final IoBuffer putLong(int index, long value) {
0591:                autoExpand(index, 8);
0592:                buf().putLong(index, value);
0593:                return this ;
0594:            }
0595:
0596:            @Override
0597:            public final LongBuffer asLongBuffer() {
0598:                return buf().asLongBuffer();
0599:            }
0600:
0601:            @Override
0602:            public final float getFloat() {
0603:                return buf().getFloat();
0604:            }
0605:
0606:            @Override
0607:            public final IoBuffer putFloat(float value) {
0608:                autoExpand(4);
0609:                buf().putFloat(value);
0610:                return this ;
0611:            }
0612:
0613:            @Override
0614:            public final float getFloat(int index) {
0615:                return buf().getFloat(index);
0616:            }
0617:
0618:            @Override
0619:            public final IoBuffer putFloat(int index, float value) {
0620:                autoExpand(index, 4);
0621:                buf().putFloat(index, value);
0622:                return this ;
0623:            }
0624:
0625:            @Override
0626:            public final FloatBuffer asFloatBuffer() {
0627:                return buf().asFloatBuffer();
0628:            }
0629:
0630:            @Override
0631:            public final double getDouble() {
0632:                return buf().getDouble();
0633:            }
0634:
0635:            @Override
0636:            public final IoBuffer putDouble(double value) {
0637:                autoExpand(8);
0638:                buf().putDouble(value);
0639:                return this ;
0640:            }
0641:
0642:            @Override
0643:            public final double getDouble(int index) {
0644:                return buf().getDouble(index);
0645:            }
0646:
0647:            @Override
0648:            public final IoBuffer putDouble(int index, double value) {
0649:                autoExpand(index, 8);
0650:                buf().putDouble(index, value);
0651:                return this ;
0652:            }
0653:
0654:            @Override
0655:            public final DoubleBuffer asDoubleBuffer() {
0656:                return buf().asDoubleBuffer();
0657:            }
0658:
0659:            @Override
0660:            public final IoBuffer asReadOnlyBuffer() {
0661:                recapacityAllowed = false;
0662:                return asReadOnlyBuffer0();
0663:            }
0664:
0665:            /**
0666:             * Implement this method to return the unexpandable read only version of
0667:             * this buffer.
0668:             */
0669:            protected abstract IoBuffer asReadOnlyBuffer0();
0670:
0671:            @Override
0672:            public final IoBuffer duplicate() {
0673:                recapacityAllowed = false;
0674:                return duplicate0();
0675:            }
0676:
0677:            /**
0678:             * Implement this method to return the unexpandable duplicate of this
0679:             * buffer.
0680:             */
0681:            protected abstract IoBuffer duplicate0();
0682:
0683:            @Override
0684:            public final IoBuffer slice() {
0685:                recapacityAllowed = false;
0686:                return slice0();
0687:            }
0688:
0689:            @Override
0690:            public final IoBuffer getSlice(int index, int length) {
0691:                if (length < 0) {
0692:                    throw new IllegalArgumentException("length: " + length);
0693:                }
0694:                int pos = position();
0695:                int limit = limit();
0696:                int endIndex = pos + length;
0697:
0698:                if (capacity() < endIndex) {
0699:                    throw new IndexOutOfBoundsException("index + length ("
0700:                            + endIndex + ") is greater " + "than capacity ("
0701:                            + capacity() + ").");
0702:                }
0703:
0704:                clear();
0705:                position(index);
0706:                limit(endIndex);
0707:
0708:                IoBuffer slice = slice();
0709:                position(pos);
0710:                limit(limit);
0711:                return slice;
0712:            }
0713:
0714:            @Override
0715:            public final IoBuffer getSlice(int length) {
0716:                if (length < 0) {
0717:                    throw new IllegalArgumentException("length: " + length);
0718:                }
0719:                int pos = position();
0720:                int limit = limit();
0721:                int nextPos = pos + length;
0722:                if (limit < nextPos) {
0723:                    throw new IndexOutOfBoundsException("position + length ("
0724:                            + nextPos + ") is greater " + "than limit ("
0725:                            + limit + ").");
0726:                }
0727:
0728:                limit(pos + length);
0729:                IoBuffer slice = slice();
0730:                position(nextPos);
0731:                limit(limit);
0732:                return slice;
0733:            }
0734:
0735:            /**
0736:             * Implement this method to return the unexpandable slice of this
0737:             * buffer.
0738:             */
0739:            protected abstract IoBuffer slice0();
0740:
0741:            @Override
0742:            public int hashCode() {
0743:                int h = 1;
0744:                int p = position();
0745:                for (int i = limit() - 1; i >= p; i--) {
0746:                    h = 31 * h + get(i);
0747:                }
0748:                return h;
0749:            }
0750:
0751:            @Override
0752:            public boolean equals(Object o) {
0753:                if (!(o instanceof  IoBuffer)) {
0754:                    return false;
0755:                }
0756:
0757:                IoBuffer that = (IoBuffer) o;
0758:                if (this .remaining() != that.remaining()) {
0759:                    return false;
0760:                }
0761:
0762:                int p = this .position();
0763:                for (int i = this .limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
0764:                    byte v1 = this .get(i);
0765:                    byte v2 = that.get(j);
0766:                    if (v1 != v2) {
0767:                        return false;
0768:                    }
0769:                }
0770:                return true;
0771:            }
0772:
0773:            public int compareTo(IoBuffer that) {
0774:                int n = this .position()
0775:                        + Math.min(this .remaining(), that.remaining());
0776:                for (int i = this .position(), j = that.position(); i < n; i++, j++) {
0777:                    byte v1 = this .get(i);
0778:                    byte v2 = that.get(j);
0779:                    if (v1 == v2) {
0780:                        continue;
0781:                    }
0782:                    if (v1 < v2) {
0783:                        return -1;
0784:                    }
0785:
0786:                    return +1;
0787:                }
0788:                return this .remaining() - that.remaining();
0789:            }
0790:
0791:            @Override
0792:            public String toString() {
0793:                StringBuffer buf = new StringBuffer();
0794:                if (isDirect()) {
0795:                    buf.append("DirectBuffer");
0796:                } else {
0797:                    buf.append("HeapBuffer");
0798:                }
0799:                buf.append("[pos=");
0800:                buf.append(position());
0801:                buf.append(" lim=");
0802:                buf.append(limit());
0803:                buf.append(" cap=");
0804:                buf.append(capacity());
0805:                buf.append(": ");
0806:                buf.append(getHexDump(16));
0807:                buf.append(']');
0808:                return buf.toString();
0809:            }
0810:
0811:            @Override
0812:            public IoBuffer get(byte[] dst) {
0813:                return get(dst, 0, dst.length);
0814:            }
0815:
0816:            @Override
0817:            public IoBuffer put(IoBuffer src) {
0818:                return put(src.buf());
0819:            }
0820:
0821:            @Override
0822:            public IoBuffer put(byte[] src) {
0823:                return put(src, 0, src.length);
0824:            }
0825:
0826:            @Override
0827:            public int getUnsignedShort() {
0828:                return getShort() & 0xffff;
0829:            }
0830:
0831:            @Override
0832:            public int getUnsignedShort(int index) {
0833:                return getShort(index) & 0xffff;
0834:            }
0835:
0836:            @Override
0837:            public long getUnsignedInt() {
0838:                return getInt() & 0xffffffffL;
0839:            }
0840:
0841:            @Override
0842:            public int getMediumInt() {
0843:                byte b1 = get();
0844:                byte b2 = get();
0845:                byte b3 = get();
0846:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0847:                    return getMediumInt(b1, b2, b3);
0848:                } else {
0849:                    return getMediumInt(b3, b2, b1);
0850:                }
0851:            }
0852:
0853:            @Override
0854:            public int getUnsignedMediumInt() {
0855:                int b1 = getUnsigned();
0856:                int b2 = getUnsigned();
0857:                int b3 = getUnsigned();
0858:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0859:                    return b1 << 16 | b2 << 8 | b3;
0860:                } else {
0861:                    return b3 << 16 | b2 << 8 | b1;
0862:                }
0863:            }
0864:
0865:            @Override
0866:            public int getMediumInt(int index) {
0867:                byte b1 = get(index);
0868:                byte b2 = get(index + 1);
0869:                byte b3 = get(index + 2);
0870:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0871:                    return getMediumInt(b1, b2, b3);
0872:                } else {
0873:                    return getMediumInt(b3, b2, b1);
0874:                }
0875:            }
0876:
0877:            @Override
0878:            public int getUnsignedMediumInt(int index) {
0879:                int b1 = getUnsigned(index);
0880:                int b2 = getUnsigned(index + 1);
0881:                int b3 = getUnsigned(index + 2);
0882:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0883:                    return b1 << 16 | b2 << 8 | b3;
0884:                } else {
0885:                    return b3 << 16 | b2 << 8 | b1;
0886:                }
0887:            }
0888:
0889:            private int getMediumInt(byte b1, byte b2, byte b3) {
0890:                int ret = b1 << 16 & 0xff0000 | b2 << 8 & 0xff00 | b3 & 0xff;
0891:                // Check to see if the medium int is negative (high bit in b1 set)
0892:                if ((b1 & 0x80) == 0x80) {
0893:                    // Make the the whole int negative
0894:                    ret |= 0xff000000;
0895:                }
0896:                return ret;
0897:            }
0898:
0899:            @Override
0900:            public IoBuffer putMediumInt(int value) {
0901:                byte b1 = (byte) (value >> 16);
0902:                byte b2 = (byte) (value >> 8);
0903:                byte b3 = (byte) value;
0904:
0905:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0906:                    put(b1).put(b2).put(b3);
0907:                } else {
0908:                    put(b3).put(b2).put(b1);
0909:                }
0910:
0911:                return this ;
0912:            }
0913:
0914:            @Override
0915:            public IoBuffer putMediumInt(int index, int value) {
0916:                byte b1 = (byte) (value >> 16);
0917:                byte b2 = (byte) (value >> 8);
0918:                byte b3 = (byte) value;
0919:
0920:                if (ByteOrder.BIG_ENDIAN.equals(order())) {
0921:                    put(index, b1).put(index + 1, b2).put(index + 2, b3);
0922:                } else {
0923:                    put(index, b3).put(index + 1, b2).put(index + 2, b1);
0924:                }
0925:
0926:                return this ;
0927:            }
0928:
0929:            @Override
0930:            public long getUnsignedInt(int index) {
0931:                return getInt(index) & 0xffffffffL;
0932:            }
0933:
0934:            @Override
0935:            public InputStream asInputStream() {
0936:                return new InputStream() {
0937:                    @Override
0938:                    public int available() {
0939:                        return AbstractIoBuffer.this .remaining();
0940:                    }
0941:
0942:                    @Override
0943:                    public synchronized void mark(int readlimit) {
0944:                        AbstractIoBuffer.this .mark();
0945:                    }
0946:
0947:                    @Override
0948:                    public boolean markSupported() {
0949:                        return true;
0950:                    }
0951:
0952:                    @Override
0953:                    public int read() {
0954:                        if (AbstractIoBuffer.this .hasRemaining()) {
0955:                            return AbstractIoBuffer.this .get() & 0xff;
0956:                        } else {
0957:                            return -1;
0958:                        }
0959:                    }
0960:
0961:                    @Override
0962:                    public int read(byte[] b, int off, int len) {
0963:                        int remaining = AbstractIoBuffer.this .remaining();
0964:                        if (remaining > 0) {
0965:                            int readBytes = Math.min(remaining, len);
0966:                            AbstractIoBuffer.this .get(b, off, readBytes);
0967:                            return readBytes;
0968:                        } else {
0969:                            return -1;
0970:                        }
0971:                    }
0972:
0973:                    @Override
0974:                    public synchronized void reset() {
0975:                        AbstractIoBuffer.this .reset();
0976:                    }
0977:
0978:                    @Override
0979:                    public long skip(long n) {
0980:                        int bytes;
0981:                        if (n > Integer.MAX_VALUE) {
0982:                            bytes = AbstractIoBuffer.this .remaining();
0983:                        } else {
0984:                            bytes = Math.min(AbstractIoBuffer.this .remaining(),
0985:                                    (int) n);
0986:                        }
0987:                        AbstractIoBuffer.this .skip(bytes);
0988:                        return bytes;
0989:                    }
0990:                };
0991:            }
0992:
0993:            @Override
0994:            public OutputStream asOutputStream() {
0995:                return new OutputStream() {
0996:                    @Override
0997:                    public void write(byte[] b, int off, int len) {
0998:                        AbstractIoBuffer.this .put(b, off, len);
0999:                    }
1000:
1001:                    @Override
1002:                    public void write(int b) {
1003:                        AbstractIoBuffer.this .put((byte) b);
1004:                    }
1005:                };
1006:            }
1007:
1008:            @Override
1009:            public String getHexDump() {
1010:                return this .getHexDump(Integer.MAX_VALUE);
1011:            }
1012:
1013:            @Override
1014:            public String getHexDump(int lengthLimit) {
1015:                return IoBufferHexDumper.getHexdump(this , lengthLimit);
1016:            }
1017:
1018:            @Override
1019:            public String getString(CharsetDecoder decoder)
1020:                    throws CharacterCodingException {
1021:                if (!hasRemaining()) {
1022:                    return "";
1023:                }
1024:
1025:                boolean utf16 = decoder.charset().name().startsWith("UTF-16");
1026:
1027:                int oldPos = position();
1028:                int oldLimit = limit();
1029:                int end = -1;
1030:                int newPos;
1031:
1032:                if (!utf16) {
1033:                    end = indexOf((byte) 0x00);
1034:                    if (end < 0) {
1035:                        newPos = end = oldLimit;
1036:                    } else {
1037:                        newPos = end + 1;
1038:                    }
1039:                } else {
1040:                    int i = oldPos;
1041:                    for (;;) {
1042:                        boolean wasZero = get(i) == 0;
1043:                        i++;
1044:
1045:                        if (i >= oldLimit) {
1046:                            break;
1047:                        }
1048:
1049:                        if (get(i) != 0) {
1050:                            i++;
1051:                            if (i >= oldLimit) {
1052:                                break;
1053:                            } else {
1054:                                continue;
1055:                            }
1056:                        }
1057:
1058:                        if (wasZero) {
1059:                            end = i - 1;
1060:                            break;
1061:                        }
1062:                    }
1063:
1064:                    if (end < 0) {
1065:                        newPos = end = oldPos
1066:                                + (oldLimit - oldPos & 0xFFFFFFFE);
1067:                    } else {
1068:                        if (end + 2 <= oldLimit) {
1069:                            newPos = end + 2;
1070:                        } else {
1071:                            newPos = end;
1072:                        }
1073:                    }
1074:                }
1075:
1076:                if (oldPos == end) {
1077:                    position(newPos);
1078:                    return "";
1079:                }
1080:
1081:                limit(end);
1082:                decoder.reset();
1083:
1084:                int expectedLength = (int) (remaining() * decoder
1085:                        .averageCharsPerByte()) + 1;
1086:                CharBuffer out = CharBuffer.allocate(expectedLength);
1087:                for (;;) {
1088:                    CoderResult cr;
1089:                    if (hasRemaining()) {
1090:                        cr = decoder.decode(buf(), out, true);
1091:                    } else {
1092:                        cr = decoder.flush(out);
1093:                    }
1094:
1095:                    if (cr.isUnderflow()) {
1096:                        break;
1097:                    }
1098:
1099:                    if (cr.isOverflow()) {
1100:                        CharBuffer o = CharBuffer.allocate(out.capacity()
1101:                                + expectedLength);
1102:                        out.flip();
1103:                        o.put(out);
1104:                        out = o;
1105:                        continue;
1106:                    }
1107:
1108:                    if (cr.isError()) {
1109:                        // Revert the buffer back to the previous state.
1110:                        limit(oldLimit);
1111:                        position(oldPos);
1112:                        cr.throwException();
1113:                    }
1114:                }
1115:
1116:                limit(oldLimit);
1117:                position(newPos);
1118:                return out.flip().toString();
1119:            }
1120:
1121:            @Override
1122:            public String getString(int fieldSize, CharsetDecoder decoder)
1123:                    throws CharacterCodingException {
1124:                checkFieldSize(fieldSize);
1125:
1126:                if (fieldSize == 0) {
1127:                    return "";
1128:                }
1129:
1130:                if (!hasRemaining()) {
1131:                    return "";
1132:                }
1133:
1134:                boolean utf16 = decoder.charset().name().startsWith("UTF-16");
1135:
1136:                if (utf16 && (fieldSize & 1) != 0) {
1137:                    throw new IllegalArgumentException("fieldSize is not even.");
1138:                }
1139:
1140:                int oldPos = position();
1141:                int oldLimit = limit();
1142:                int end = oldPos + fieldSize;
1143:
1144:                if (oldLimit < end) {
1145:                    throw new BufferUnderflowException();
1146:                }
1147:
1148:                int i;
1149:
1150:                if (!utf16) {
1151:                    for (i = oldPos; i < end; i++) {
1152:                        if (get(i) == 0) {
1153:                            break;
1154:                        }
1155:                    }
1156:
1157:                    if (i == end) {
1158:                        limit(end);
1159:                    } else {
1160:                        limit(i);
1161:                    }
1162:                } else {
1163:                    for (i = oldPos; i < end; i += 2) {
1164:                        if (get(i) == 0 && get(i + 1) == 0) {
1165:                            break;
1166:                        }
1167:                    }
1168:
1169:                    if (i == end) {
1170:                        limit(end);
1171:                    } else {
1172:                        limit(i);
1173:                    }
1174:                }
1175:
1176:                if (!hasRemaining()) {
1177:                    limit(oldLimit);
1178:                    position(end);
1179:                    return "";
1180:                }
1181:                decoder.reset();
1182:
1183:                int expectedLength = (int) (remaining() * decoder
1184:                        .averageCharsPerByte()) + 1;
1185:                CharBuffer out = CharBuffer.allocate(expectedLength);
1186:                for (;;) {
1187:                    CoderResult cr;
1188:                    if (hasRemaining()) {
1189:                        cr = decoder.decode(buf(), out, true);
1190:                    } else {
1191:                        cr = decoder.flush(out);
1192:                    }
1193:
1194:                    if (cr.isUnderflow()) {
1195:                        break;
1196:                    }
1197:
1198:                    if (cr.isOverflow()) {
1199:                        CharBuffer o = CharBuffer.allocate(out.capacity()
1200:                                + expectedLength);
1201:                        out.flip();
1202:                        o.put(out);
1203:                        out = o;
1204:                        continue;
1205:                    }
1206:
1207:                    if (cr.isError()) {
1208:                        // Revert the buffer back to the previous state.
1209:                        limit(oldLimit);
1210:                        position(oldPos);
1211:                        cr.throwException();
1212:                    }
1213:                }
1214:
1215:                limit(oldLimit);
1216:                position(end);
1217:                return out.flip().toString();
1218:            }
1219:
1220:            @Override
1221:            public IoBuffer putString(CharSequence val, CharsetEncoder encoder)
1222:                    throws CharacterCodingException {
1223:                if (val.length() == 0) {
1224:                    return this ;
1225:                }
1226:
1227:                CharBuffer in = CharBuffer.wrap(val);
1228:                encoder.reset();
1229:
1230:                int expandedState = 0;
1231:
1232:                for (;;) {
1233:                    CoderResult cr;
1234:                    if (in.hasRemaining()) {
1235:                        cr = encoder.encode(in, buf(), true);
1236:                    } else {
1237:                        cr = encoder.flush(buf());
1238:                    }
1239:
1240:                    if (cr.isUnderflow()) {
1241:                        break;
1242:                    }
1243:                    if (cr.isOverflow()) {
1244:                        if (isAutoExpand()) {
1245:                            switch (expandedState) {
1246:                            case 0:
1247:                                autoExpand((int) Math.ceil(in.remaining()
1248:                                        * encoder.averageBytesPerChar()));
1249:                                expandedState++;
1250:                                break;
1251:                            case 1:
1252:                                autoExpand((int) Math.ceil(in.remaining()
1253:                                        * encoder.maxBytesPerChar()));
1254:                                expandedState++;
1255:                                break;
1256:                            default:
1257:                                throw new RuntimeException("Expanded by "
1258:                                        + (int) Math.ceil(in.remaining()
1259:                                                * encoder.maxBytesPerChar())
1260:                                        + " but that wasn't enough for '" + val
1261:                                        + "'");
1262:                            }
1263:                            continue;
1264:                        }
1265:                    } else {
1266:                        expandedState = 0;
1267:                    }
1268:                    cr.throwException();
1269:                }
1270:                return this ;
1271:            }
1272:
1273:            @Override
1274:            public IoBuffer putString(CharSequence val, int fieldSize,
1275:                    CharsetEncoder encoder) throws CharacterCodingException {
1276:                checkFieldSize(fieldSize);
1277:
1278:                if (fieldSize == 0) {
1279:                    return this ;
1280:                }
1281:
1282:                autoExpand(fieldSize);
1283:
1284:                boolean utf16 = encoder.charset().name().startsWith("UTF-16");
1285:
1286:                if (utf16 && (fieldSize & 1) != 0) {
1287:                    throw new IllegalArgumentException("fieldSize is not even.");
1288:                }
1289:
1290:                int oldLimit = limit();
1291:                int end = position() + fieldSize;
1292:
1293:                if (oldLimit < end) {
1294:                    throw new BufferOverflowException();
1295:                }
1296:
1297:                if (val.length() == 0) {
1298:                    if (!utf16) {
1299:                        put((byte) 0x00);
1300:                    } else {
1301:                        put((byte) 0x00);
1302:                        put((byte) 0x00);
1303:                    }
1304:                    position(end);
1305:                    return this ;
1306:                }
1307:
1308:                CharBuffer in = CharBuffer.wrap(val);
1309:                limit(end);
1310:                encoder.reset();
1311:
1312:                for (;;) {
1313:                    CoderResult cr;
1314:                    if (in.hasRemaining()) {
1315:                        cr = encoder.encode(in, buf(), true);
1316:                    } else {
1317:                        cr = encoder.flush(buf());
1318:                    }
1319:
1320:                    if (cr.isUnderflow() || cr.isOverflow()) {
1321:                        break;
1322:                    }
1323:                    cr.throwException();
1324:                }
1325:
1326:                limit(oldLimit);
1327:
1328:                if (position() < end) {
1329:                    if (!utf16) {
1330:                        put((byte) 0x00);
1331:                    } else {
1332:                        put((byte) 0x00);
1333:                        put((byte) 0x00);
1334:                    }
1335:                }
1336:
1337:                position(end);
1338:                return this ;
1339:            }
1340:
1341:            @Override
1342:            public String getPrefixedString(CharsetDecoder decoder)
1343:                    throws CharacterCodingException {
1344:                return getPrefixedString(2, decoder);
1345:            }
1346:
1347:            /**
1348:             * Reads a string which has a length field before the actual
1349:             * encoded string, using the specified <code>decoder</code> and returns it.
1350:             *
1351:             * @param prefixLength the length of the length field (1, 2, or 4)
1352:             * @param decoder the decoder to use for decoding the string
1353:             * @return the prefixed string
1354:             * @throws CharacterCodingException when decoding fails
1355:             * @throws BufferUnderflowException when there is not enough data available
1356:             */
1357:            @Override
1358:            public String getPrefixedString(int prefixLength,
1359:                    CharsetDecoder decoder) throws CharacterCodingException {
1360:                if (!prefixedDataAvailable(prefixLength)) {
1361:                    throw new BufferUnderflowException();
1362:                }
1363:
1364:                int fieldSize = 0;
1365:
1366:                switch (prefixLength) {
1367:                case 1:
1368:                    fieldSize = getUnsigned();
1369:                    break;
1370:                case 2:
1371:                    fieldSize = getUnsignedShort();
1372:                    break;
1373:                case 4:
1374:                    fieldSize = getInt();
1375:                    break;
1376:                }
1377:
1378:                if (fieldSize == 0) {
1379:                    return "";
1380:                }
1381:
1382:                boolean utf16 = decoder.charset().name().startsWith("UTF-16");
1383:
1384:                if (utf16 && (fieldSize & 1) != 0) {
1385:                    throw new BufferDataException(
1386:                            "fieldSize is not even for a UTF-16 string.");
1387:                }
1388:
1389:                int oldLimit = limit();
1390:                int end = position() + fieldSize;
1391:
1392:                if (oldLimit < end) {
1393:                    throw new BufferUnderflowException();
1394:                }
1395:
1396:                limit(end);
1397:                decoder.reset();
1398:
1399:                int expectedLength = (int) (remaining() * decoder
1400:                        .averageCharsPerByte()) + 1;
1401:                CharBuffer out = CharBuffer.allocate(expectedLength);
1402:                for (;;) {
1403:                    CoderResult cr;
1404:                    if (hasRemaining()) {
1405:                        cr = decoder.decode(buf(), out, true);
1406:                    } else {
1407:                        cr = decoder.flush(out);
1408:                    }
1409:
1410:                    if (cr.isUnderflow()) {
1411:                        break;
1412:                    }
1413:
1414:                    if (cr.isOverflow()) {
1415:                        CharBuffer o = CharBuffer.allocate(out.capacity()
1416:                                + expectedLength);
1417:                        out.flip();
1418:                        o.put(out);
1419:                        out = o;
1420:                        continue;
1421:                    }
1422:
1423:                    cr.throwException();
1424:                }
1425:
1426:                limit(oldLimit);
1427:                position(end);
1428:                return out.flip().toString();
1429:            }
1430:
1431:            @Override
1432:            public IoBuffer putPrefixedString(CharSequence in,
1433:                    CharsetEncoder encoder) throws CharacterCodingException {
1434:                return putPrefixedString(in, 2, 0, encoder);
1435:            }
1436:
1437:            @Override
1438:            public IoBuffer putPrefixedString(CharSequence in,
1439:                    int prefixLength, CharsetEncoder encoder)
1440:                    throws CharacterCodingException {
1441:                return putPrefixedString(in, prefixLength, 0, encoder);
1442:            }
1443:
1444:            @Override
1445:            public IoBuffer putPrefixedString(CharSequence in,
1446:                    int prefixLength, int padding, CharsetEncoder encoder)
1447:                    throws CharacterCodingException {
1448:                return putPrefixedString(in, prefixLength, padding, (byte) 0,
1449:                        encoder);
1450:            }
1451:
1452:            @Override
1453:            public IoBuffer putPrefixedString(CharSequence val,
1454:                    int prefixLength, int padding, byte padValue,
1455:                    CharsetEncoder encoder) throws CharacterCodingException {
1456:                int maxLength;
1457:                switch (prefixLength) {
1458:                case 1:
1459:                    maxLength = 255;
1460:                    break;
1461:                case 2:
1462:                    maxLength = 65535;
1463:                    break;
1464:                case 4:
1465:                    maxLength = Integer.MAX_VALUE;
1466:                    break;
1467:                default:
1468:                    throw new IllegalArgumentException("prefixLength: "
1469:                            + prefixLength);
1470:                }
1471:
1472:                if (val.length() > maxLength) {
1473:                    throw new IllegalArgumentException(
1474:                            "The specified string is too long.");
1475:                }
1476:                if (val.length() == 0) {
1477:                    switch (prefixLength) {
1478:                    case 1:
1479:                        put((byte) 0);
1480:                        break;
1481:                    case 2:
1482:                        putShort((short) 0);
1483:                        break;
1484:                    case 4:
1485:                        putInt(0);
1486:                        break;
1487:                    }
1488:                    return this ;
1489:                }
1490:
1491:                int padMask;
1492:                switch (padding) {
1493:                case 0:
1494:                case 1:
1495:                    padMask = 0;
1496:                    break;
1497:                case 2:
1498:                    padMask = 1;
1499:                    break;
1500:                case 4:
1501:                    padMask = 3;
1502:                    break;
1503:                default:
1504:                    throw new IllegalArgumentException("padding: " + padding);
1505:                }
1506:
1507:                CharBuffer in = CharBuffer.wrap(val);
1508:                int expectedLength = (int) (in.remaining() * encoder
1509:                        .averageBytesPerChar()) + 1;
1510:
1511:                skip(prefixLength); // make a room for the length field
1512:                int oldPos = position();
1513:                encoder.reset();
1514:
1515:                for (;;) {
1516:                    CoderResult cr;
1517:                    if (in.hasRemaining()) {
1518:                        cr = encoder.encode(in, buf(), true);
1519:                    } else {
1520:                        cr = encoder.flush(buf());
1521:                    }
1522:
1523:                    if (position() - oldPos > maxLength) {
1524:                        throw new IllegalArgumentException(
1525:                                "The specified string is too long.");
1526:                    }
1527:
1528:                    if (cr.isUnderflow()) {
1529:                        break;
1530:                    }
1531:                    if (cr.isOverflow() && isAutoExpand()) {
1532:                        autoExpand(expectedLength);
1533:                        continue;
1534:                    }
1535:                    cr.throwException();
1536:                }
1537:
1538:                // Write the length field
1539:                fill(padValue, padding - (position() - oldPos & padMask));
1540:                int length = position() - oldPos;
1541:                switch (prefixLength) {
1542:                case 1:
1543:                    put(oldPos - 1, (byte) length);
1544:                    break;
1545:                case 2:
1546:                    putShort(oldPos - 2, (short) length);
1547:                    break;
1548:                case 4:
1549:                    putInt(oldPos - 4, length);
1550:                    break;
1551:                }
1552:                return this ;
1553:            }
1554:
1555:            @Override
1556:            public Object getObject() throws ClassNotFoundException {
1557:                return getObject(Thread.currentThread().getContextClassLoader());
1558:            }
1559:
1560:            @Override
1561:            public Object getObject(final ClassLoader classLoader)
1562:                    throws ClassNotFoundException {
1563:                if (!prefixedDataAvailable(4)) {
1564:                    throw new BufferUnderflowException();
1565:                }
1566:
1567:                int length = getInt();
1568:                if (length <= 4) {
1569:                    throw new BufferDataException(
1570:                            "Object length should be greater than 4: " + length);
1571:                }
1572:
1573:                int oldLimit = limit();
1574:                limit(position() + length);
1575:                try {
1576:                    ObjectInputStream in = new ObjectInputStream(
1577:                            asInputStream()) {
1578:                        @Override
1579:                        protected ObjectStreamClass readClassDescriptor()
1580:                                throws IOException, ClassNotFoundException {
1581:                            int type = read();
1582:                            if (type < 0) {
1583:                                throw new EOFException();
1584:                            }
1585:                            switch (type) {
1586:                            case 0: // Primitive types
1587:                                return super .readClassDescriptor();
1588:                            case 1: // Non-primitive types
1589:                                String className = readUTF();
1590:                                Class<?> clazz = Class.forName(className, true,
1591:                                        classLoader);
1592:                                return ObjectStreamClass.lookup(clazz);
1593:                            default:
1594:                                throw new StreamCorruptedException(
1595:                                        "Unexpected class descriptor type: "
1596:                                                + type);
1597:                            }
1598:                        }
1599:
1600:                        @Override
1601:                        protected Class<?> resolveClass(ObjectStreamClass desc)
1602:                                throws IOException, ClassNotFoundException {
1603:                            String name = desc.getName();
1604:                            try {
1605:                                return Class.forName(name, false, classLoader);
1606:                            } catch (ClassNotFoundException ex) {
1607:                                return super .resolveClass(desc);
1608:                            }
1609:                        }
1610:                    };
1611:                    return in.readObject();
1612:                } catch (IOException e) {
1613:                    throw new BufferDataException(e);
1614:                } finally {
1615:                    limit(oldLimit);
1616:                }
1617:            }
1618:
1619:            @Override
1620:            public IoBuffer putObject(Object o) {
1621:                int oldPos = position();
1622:                skip(4); // Make a room for the length field.
1623:                try {
1624:                    ObjectOutputStream out = new ObjectOutputStream(
1625:                            asOutputStream()) {
1626:                        @Override
1627:                        protected void writeClassDescriptor(
1628:                                ObjectStreamClass desc) throws IOException {
1629:                            String className = desc.getName();
1630:                            if (primitiveTypeNames.contains(className)) {
1631:                                write(0);
1632:                                super .writeClassDescriptor(desc);
1633:                            } else {
1634:                                write(1);
1635:                                writeUTF(desc.getName());
1636:                            }
1637:                        }
1638:                    };
1639:                    out.writeObject(o);
1640:                    out.flush();
1641:                } catch (IOException e) {
1642:                    throw new BufferDataException(e);
1643:                }
1644:
1645:                // Fill the length field
1646:                int newPos = position();
1647:                position(oldPos);
1648:                putInt(newPos - oldPos - 4);
1649:                position(newPos);
1650:                return this ;
1651:            }
1652:
1653:            @Override
1654:            public boolean prefixedDataAvailable(int prefixLength) {
1655:                return prefixedDataAvailable(prefixLength, Integer.MAX_VALUE);
1656:            }
1657:
1658:            @Override
1659:            public boolean prefixedDataAvailable(int prefixLength,
1660:                    int maxDataLength) {
1661:                if (remaining() < prefixLength) {
1662:                    return false;
1663:                }
1664:
1665:                int dataLength;
1666:                switch (prefixLength) {
1667:                case 1:
1668:                    dataLength = getUnsigned(position());
1669:                    break;
1670:                case 2:
1671:                    dataLength = getUnsignedShort(position());
1672:                    break;
1673:                case 4:
1674:                    dataLength = getInt(position());
1675:                    break;
1676:                default:
1677:                    throw new IllegalArgumentException("prefixLength: "
1678:                            + prefixLength);
1679:                }
1680:
1681:                if (dataLength < 0 || dataLength > maxDataLength) {
1682:                    throw new BufferDataException("dataLength: " + dataLength);
1683:                }
1684:
1685:                return remaining() - prefixLength >= dataLength;
1686:            }
1687:
1688:            @Override
1689:            public int indexOf(byte b) {
1690:                if (hasArray()) {
1691:                    int arrayOffset = arrayOffset();
1692:                    int beginPos = arrayOffset + position();
1693:                    int limit = arrayOffset + limit();
1694:                    byte[] array = array();
1695:
1696:                    for (int i = beginPos; i < limit; i++) {
1697:                        if (array[i] == b) {
1698:                            return i - arrayOffset;
1699:                        }
1700:                    }
1701:                } else {
1702:                    int beginPos = position();
1703:                    int limit = limit();
1704:
1705:                    for (int i = beginPos; i < limit; i++) {
1706:                        if (get(i) == b) {
1707:                            return i;
1708:                        }
1709:                    }
1710:                }
1711:
1712:                return -1;
1713:            }
1714:
1715:            @Override
1716:            public IoBuffer skip(int size) {
1717:                autoExpand(size);
1718:                return position(position() + size);
1719:            }
1720:
1721:            @Override
1722:            public IoBuffer fill(byte value, int size) {
1723:                autoExpand(size);
1724:                int q = size >>> 3;
1725:                int r = size & 7;
1726:
1727:                if (q > 0) {
1728:                    int intValue = value | value << 8 | value << 16
1729:                            | value << 24;
1730:                    long longValue = intValue;
1731:                    longValue <<= 32;
1732:                    longValue |= intValue;
1733:
1734:                    for (int i = q; i > 0; i--) {
1735:                        putLong(longValue);
1736:                    }
1737:                }
1738:
1739:                q = r >>> 2;
1740:                r = r & 3;
1741:
1742:                if (q > 0) {
1743:                    int intValue = value | value << 8 | value << 16
1744:                            | value << 24;
1745:                    putInt(intValue);
1746:                }
1747:
1748:                q = r >> 1;
1749:                r = r & 1;
1750:
1751:                if (q > 0) {
1752:                    short shortValue = (short) (value | value << 8);
1753:                    putShort(shortValue);
1754:                }
1755:
1756:                if (r > 0) {
1757:                    put(value);
1758:                }
1759:
1760:                return this ;
1761:            }
1762:
1763:            @Override
1764:            public IoBuffer fillAndReset(byte value, int size) {
1765:                autoExpand(size);
1766:                int pos = position();
1767:                try {
1768:                    fill(value, size);
1769:                } finally {
1770:                    position(pos);
1771:                }
1772:                return this ;
1773:            }
1774:
1775:            @Override
1776:            public IoBuffer fill(int size) {
1777:                autoExpand(size);
1778:                int q = size >>> 3;
1779:                int r = size & 7;
1780:
1781:                for (int i = q; i > 0; i--) {
1782:                    putLong(0L);
1783:                }
1784:
1785:                q = r >>> 2;
1786:                r = r & 3;
1787:
1788:                if (q > 0) {
1789:                    putInt(0);
1790:                }
1791:
1792:                q = r >> 1;
1793:                r = r & 1;
1794:
1795:                if (q > 0) {
1796:                    putShort((short) 0);
1797:                }
1798:
1799:                if (r > 0) {
1800:                    put((byte) 0);
1801:                }
1802:
1803:                return this ;
1804:            }
1805:
1806:            @Override
1807:            public IoBuffer fillAndReset(int size) {
1808:                autoExpand(size);
1809:                int pos = position();
1810:                try {
1811:                    fill(size);
1812:                } finally {
1813:                    position(pos);
1814:                }
1815:
1816:                return this ;
1817:            }
1818:
1819:            private static final long BYTE_MASK = 0xFFL;
1820:            private static final long SHORT_MASK = 0xFFFFL;
1821:            private static final long INT_MASK = 0xFFFFFFFFL;
1822:
1823:            @Override
1824:            public <E extends Enum<E>> E getEnum(Class<E> enumClass) {
1825:                return toEnum(enumClass, get());
1826:            }
1827:
1828:            @Override
1829:            public <E extends Enum<E>> E getEnum(int index, Class<E> enumClass) {
1830:                return toEnum(enumClass, get(index));
1831:            }
1832:
1833:            @Override
1834:            public <E extends Enum<E>> E getEnumShort(Class<E> enumClass) {
1835:                return toEnum(enumClass, getShort());
1836:            }
1837:
1838:            @Override
1839:            public <E extends Enum<E>> E getEnumShort(int index,
1840:                    Class<E> enumClass) {
1841:                return toEnum(enumClass, getShort(index));
1842:            }
1843:
1844:            @Override
1845:            public <E extends Enum<E>> E getEnumInt(Class<E> enumClass) {
1846:                return toEnum(enumClass, getInt());
1847:            }
1848:
1849:            @Override
1850:            public <E extends Enum<E>> E getEnumInt(int index,
1851:                    Class<E> enumClass) {
1852:                return toEnum(enumClass, getInt(index));
1853:            }
1854:
1855:            @Override
1856:            public IoBuffer putEnum(Enum<?> e) {
1857:                if (e.ordinal() > Byte.MAX_VALUE) {
1858:                    throw new IllegalArgumentException(
1859:                            enumConversionErrorMessage(e, "byte"));
1860:                }
1861:                return put((byte) e.ordinal());
1862:            }
1863:
1864:            @Override
1865:            public IoBuffer putEnum(int index, Enum<?> e) {
1866:                if (e.ordinal() > Byte.MAX_VALUE) {
1867:                    throw new IllegalArgumentException(
1868:                            enumConversionErrorMessage(e, "byte"));
1869:                }
1870:                return put(index, (byte) e.ordinal());
1871:            }
1872:
1873:            @Override
1874:            public IoBuffer putEnumShort(Enum<?> e) {
1875:                if (e.ordinal() > Short.MAX_VALUE) {
1876:                    throw new IllegalArgumentException(
1877:                            enumConversionErrorMessage(e, "short"));
1878:                }
1879:                return putShort((short) e.ordinal());
1880:            }
1881:
1882:            @Override
1883:            public IoBuffer putEnumShort(int index, Enum<?> e) {
1884:                if (e.ordinal() > Short.MAX_VALUE) {
1885:                    throw new IllegalArgumentException(
1886:                            enumConversionErrorMessage(e, "short"));
1887:                }
1888:                return putShort(index, (short) e.ordinal());
1889:            }
1890:
1891:            @Override
1892:            public IoBuffer putEnumInt(Enum<?> e) {
1893:                return putInt(e.ordinal());
1894:            }
1895:
1896:            @Override
1897:            public IoBuffer putEnumInt(int index, Enum<?> e) {
1898:                return putInt(index, e.ordinal());
1899:            }
1900:
1901:            private <E> E toEnum(Class<E> enumClass, int i) {
1902:                E[] enumConstants = enumClass.getEnumConstants();
1903:                if (i > enumConstants.length) {
1904:                    throw new IndexOutOfBoundsException(
1905:                            String
1906:                                    .format(
1907:                                            "%d is too large of an ordinal to convert to the enum %s",
1908:                                            i, enumClass.getName()));
1909:                }
1910:                return enumConstants[i];
1911:            }
1912:
1913:            private String enumConversionErrorMessage(Enum<?> e, String type) {
1914:                return String.format(
1915:                        "%s.%s has an ordinal value too large for a %s", e
1916:                                .getClass().getName(), e.name(), type);
1917:            }
1918:
1919:            @Override
1920:            public <E extends Enum<E>> EnumSet<E> getEnumSet(Class<E> enumClass) {
1921:                return toEnumSet(enumClass, get() & BYTE_MASK);
1922:            }
1923:
1924:            @Override
1925:            public <E extends Enum<E>> EnumSet<E> getEnumSet(int index,
1926:                    Class<E> enumClass) {
1927:                return toEnumSet(enumClass, get(index) & BYTE_MASK);
1928:            }
1929:
1930:            @Override
1931:            public <E extends Enum<E>> EnumSet<E> getEnumSetShort(
1932:                    Class<E> enumClass) {
1933:                return toEnumSet(enumClass, getShort() & SHORT_MASK);
1934:            }
1935:
1936:            @Override
1937:            public <E extends Enum<E>> EnumSet<E> getEnumSetShort(int index,
1938:                    Class<E> enumClass) {
1939:                return toEnumSet(enumClass, getShort(index) & SHORT_MASK);
1940:            }
1941:
1942:            @Override
1943:            public <E extends Enum<E>> EnumSet<E> getEnumSetInt(
1944:                    Class<E> enumClass) {
1945:                return toEnumSet(enumClass, getInt() & INT_MASK);
1946:            }
1947:
1948:            @Override
1949:            public <E extends Enum<E>> EnumSet<E> getEnumSetInt(int index,
1950:                    Class<E> enumClass) {
1951:                return toEnumSet(enumClass, getInt(index) & INT_MASK);
1952:            }
1953:
1954:            @Override
1955:            public <E extends Enum<E>> EnumSet<E> getEnumSetLong(
1956:                    Class<E> enumClass) {
1957:                return toEnumSet(enumClass, getLong());
1958:            }
1959:
1960:            @Override
1961:            public <E extends Enum<E>> EnumSet<E> getEnumSetLong(int index,
1962:                    Class<E> enumClass) {
1963:                return toEnumSet(enumClass, getLong(index));
1964:            }
1965:
1966:            private <E extends Enum<E>> EnumSet<E> toEnumSet(Class<E> clazz,
1967:                    long vector) {
1968:                EnumSet<E> set = EnumSet.noneOf(clazz);
1969:                long mask = 1;
1970:                for (E e : clazz.getEnumConstants()) {
1971:                    if ((mask & vector) == mask) {
1972:                        set.add(e);
1973:                    }
1974:                    mask <<= 1;
1975:                }
1976:                return set;
1977:            }
1978:
1979:            @Override
1980:            public <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set) {
1981:                long vector = toLong(set);
1982:                if ((vector & ~BYTE_MASK) != 0) {
1983:                    throw new IllegalArgumentException(
1984:                            "The enum set is too large to fit in a byte: "
1985:                                    + set);
1986:                }
1987:                return put((byte) vector);
1988:            }
1989:
1990:            @Override
1991:            public <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set) {
1992:                long vector = toLong(set);
1993:                if ((vector & ~BYTE_MASK) != 0) {
1994:                    throw new IllegalArgumentException(
1995:                            "The enum set is too large to fit in a byte: "
1996:                                    + set);
1997:                }
1998:                return put(index, (byte) vector);
1999:            }
2000:
2001:            @Override
2002:            public <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set) {
2003:                long vector = toLong(set);
2004:                if ((vector & ~SHORT_MASK) != 0) {
2005:                    throw new IllegalArgumentException(
2006:                            "The enum set is too large to fit in a short: "
2007:                                    + set);
2008:                }
2009:                return putShort((short) vector);
2010:            }
2011:
2012:            @Override
2013:            public <E extends Enum<E>> IoBuffer putEnumSetShort(int index,
2014:                    Set<E> set) {
2015:                long vector = toLong(set);
2016:                if ((vector & ~SHORT_MASK) != 0) {
2017:                    throw new IllegalArgumentException(
2018:                            "The enum set is too large to fit in a short: "
2019:                                    + set);
2020:                }
2021:                return putShort(index, (short) vector);
2022:            }
2023:
2024:            @Override
2025:            public <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set) {
2026:                long vector = toLong(set);
2027:                if ((vector & ~INT_MASK) != 0) {
2028:                    throw new IllegalArgumentException(
2029:                            "The enum set is too large to fit in an int: "
2030:                                    + set);
2031:                }
2032:                return putInt((int) vector);
2033:            }
2034:
2035:            @Override
2036:            public <E extends Enum<E>> IoBuffer putEnumSetInt(int index,
2037:                    Set<E> set) {
2038:                long vector = toLong(set);
2039:                if ((vector & ~INT_MASK) != 0) {
2040:                    throw new IllegalArgumentException(
2041:                            "The enum set is too large to fit in an int: "
2042:                                    + set);
2043:                }
2044:                return putInt(index, (int) vector);
2045:            }
2046:
2047:            @Override
2048:            public <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set) {
2049:                return putLong(toLong(set));
2050:            }
2051:
2052:            @Override
2053:            public <E extends Enum<E>> IoBuffer putEnumSetLong(int index,
2054:                    Set<E> set) {
2055:                return putLong(index, toLong(set));
2056:            }
2057:
2058:            private <E extends Enum<E>> long toLong(Set<E> set) {
2059:                long vector = 0;
2060:                for (E e : set) {
2061:                    if (e.ordinal() >= Long.SIZE) {
2062:                        throw new IllegalArgumentException(
2063:                                "The enum set is too large to fit in a bit vector: "
2064:                                        + set);
2065:                    }
2066:                    vector |= 1L << e.ordinal();
2067:                }
2068:                return vector;
2069:            }
2070:
2071:            /**
2072:             * This method forwards the call to {@link #expand(int)} only when
2073:             * <tt>autoExpand</tt> property is <tt>true</tt>.
2074:             */
2075:            private IoBuffer autoExpand(int expectedRemaining) {
2076:                if (isAutoExpand()) {
2077:                    expand(expectedRemaining);
2078:                }
2079:                return this ;
2080:            }
2081:
2082:            /**
2083:             * This method forwards the call to {@link #expand(int)} only when
2084:             * <tt>autoExpand</tt> property is <tt>true</tt>.
2085:             */
2086:            private IoBuffer autoExpand(int pos, int expectedRemaining) {
2087:                if (isAutoExpand()) {
2088:                    expand(pos, expectedRemaining);
2089:                }
2090:                return this ;
2091:            }
2092:
2093:            private static void checkFieldSize(int fieldSize) {
2094:                if (fieldSize < 0) {
2095:                    throw new IllegalArgumentException(
2096:                            "fieldSize cannot be negative: " + fieldSize);
2097:                }
2098:            }
2099:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.