Source Code Cross Referenced for ReadStream.java in  » EJB-Server-resin-3.1.5 » util » com » caucho » vfs » 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 » EJB Server resin 3.1.5 » util » com.caucho.vfs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *   Free SoftwareFoundation, Inc.
0023:         *   59 Temple Place, Suite 330
0024:         *   Boston, MA 02111-1307  USA
0025:         *
0026:         * @author Scott Ferguson
0027:         */
0028:
0029:        package com.caucho.vfs;
0030:
0031:        import com.caucho.util.Alarm;
0032:        import com.caucho.util.CharBuffer;
0033:
0034:        import java.io.IOException;
0035:        import java.io.InputStream;
0036:        import java.io.OutputStream;
0037:        import java.io.Reader;
0038:        import java.io.UnsupportedEncodingException;
0039:        import java.io.Writer;
0040:        import java.util.Iterator;
0041:        import java.util.logging.Level;
0042:        import java.util.logging.Logger;
0043:
0044:        /**
0045:         * A fast bufferered input stream supporting both character
0046:         * and byte data.  The underlying stream sources are provided by StreamImpl
0047:         * classes, so all streams have the same API regardless of the underlying
0048:         * implementation.
0049:         *
0050:         * <p>Dynamic streams, like tcp and http 
0051:         * will properly flush writes before reading input.  And random access
0052:         * streams, like RandomAccessFile, can use the same API as normal streams.
0053:         *
0054:         * <p>Most applications will use the Path routines to create their own streams.
0055:         * Specialized applications, like servers, need the capability of recycling
0056:         * streams.
0057:         */
0058:        public final class ReadStream extends InputStream implements 
0059:                LockableStream {
0060:            public static int ZERO_COPY_SIZE = 1024;
0061:
0062:            private TempBuffer _tempRead;
0063:            private byte[] _readBuffer;
0064:            private int _readOffset;
0065:            private int _readLength;
0066:
0067:            private WriteStream _sibling;
0068:
0069:            private StreamImpl _source;
0070:            private long _position;
0071:
0072:            private long _readTime;
0073:
0074:            private Reader _readEncoding;
0075:            private String _readEncodingName;
0076:            private int _specialEncoding;
0077:
0078:            private boolean _disableClose;
0079:            private boolean _isDisableCloseSource;
0080:            private boolean _reuseBuffer;
0081:            private Reader _reader;
0082:
0083:            /**
0084:             * Creates an uninitialized stream. Use <code>init</code> to initialize.
0085:             */
0086:            public ReadStream() {
0087:            }
0088:
0089:            /**
0090:             * Creates a stream and initializes with a specified source.
0091:             *
0092:             * @param source Underlying source for the stream.
0093:             */
0094:            public ReadStream(StreamImpl source) {
0095:                init(source, null);
0096:            }
0097:
0098:            /**
0099:             * Creates a stream and initializes with a specified source.
0100:             *
0101:             * @param source Underlying source for the stream.
0102:             * @param sibling Sibling write stream.
0103:             */
0104:            public ReadStream(StreamImpl source, WriteStream sibling) {
0105:                init(source, sibling);
0106:            }
0107:
0108:            /**
0109:             * Initializes the stream with a given source.
0110:             *
0111:             * @param source Underlying source for the stream.
0112:             * @param sibling Sibling write stream
0113:             */
0114:            public void init(StreamImpl source, WriteStream sibling) {
0115:                _disableClose = false;
0116:                _isDisableCloseSource = false;
0117:                _readTime = 0;
0118:
0119:                if (_source != null && _source != source) {
0120:                    close();
0121:                }
0122:
0123:                if (source == null)
0124:                    throw new IllegalArgumentException();
0125:
0126:                _source = source;
0127:                _sibling = sibling;
0128:
0129:                if (source.canRead()) {
0130:                    if (_tempRead == null) {
0131:                        _tempRead = TempBuffer.allocate();
0132:                        _readBuffer = _tempRead._buf;
0133:                    }
0134:                }
0135:                _readOffset = 0;
0136:                _readLength = 0;
0137:
0138:                _readEncoding = null;
0139:                _readEncodingName = "ISO-8859-1";
0140:            }
0141:
0142:            public void setSibling(WriteStream sibling) {
0143:                _sibling = sibling;
0144:            }
0145:
0146:            public WriteStream getSibling() {
0147:                return _sibling;
0148:            }
0149:
0150:            /**
0151:             * Returns the underlying source for the stream.
0152:             *
0153:             * @return the source
0154:             */
0155:            public StreamImpl getSource() {
0156:                return _source;
0157:            }
0158:
0159:            public void setReuseBuffer(boolean reuse) {
0160:                _reuseBuffer = reuse;
0161:            }
0162:
0163:            /**
0164:             * Pushes a filter on the top of the stream stack.
0165:             *
0166:             * @param filter the filter to be added.
0167:             */
0168:            public void pushFilter(StreamFilter filter) {
0169:                filter.init(_source);
0170:                _source = filter;
0171:            }
0172:
0173:            public byte[] getBuffer() {
0174:                return _readBuffer;
0175:            }
0176:
0177:            public int getOffset() {
0178:                return _readOffset;
0179:            }
0180:
0181:            public int getLength() {
0182:                return _readLength;
0183:            }
0184:
0185:            public void setOffset(int offset) {
0186:                _readOffset = offset;
0187:            }
0188:
0189:            /**
0190:             * Returns the read position.
0191:             */
0192:            public long getPosition() {
0193:                return _position - (_readLength - _readOffset);
0194:            }
0195:
0196:            /**
0197:             * Returns the last read-time.
0198:             */
0199:            public long getReadTime() {
0200:                return _readTime;
0201:            }
0202:
0203:            /**
0204:             * Returns the sets current read position.
0205:             */
0206:            public boolean setPosition(long pos) throws IOException {
0207:                // Allow seeks to be reflected in the char Reader.
0208:                if (_readEncoding != null)
0209:                    _readEncoding = Encoding.getReadEncoding(this ,
0210:                            _readEncodingName);
0211:
0212:                if (pos < 0) {
0213:                    // Return error on seek to negative stream position
0214:
0215:                    return false;
0216:                } else if (pos < getPosition()) {
0217:                    // Seek backwards in the stream
0218:
0219:                    _position = pos;
0220:                    _readLength = _readOffset = 0;
0221:
0222:                    if (_source != null) {
0223:                        _source.seekStart(pos);
0224:
0225:                        return true;
0226:                    } else
0227:                        return false;
0228:                } else {
0229:                    // Seek forward in the stream, skip any buffered bytes
0230:
0231:                    long n = pos - getPosition();
0232:
0233:                    return skip(n) == n;
0234:                }
0235:            }
0236:
0237:            /**
0238:             * Returns true if the stream allows reading.
0239:             */
0240:            public boolean canRead() {
0241:                return _source.canRead();
0242:            }
0243:
0244:            /**
0245:             * Clears the read buffer.
0246:             */
0247:            public void clearRead() {
0248:                _readOffset = 0;
0249:                _readLength = 0;
0250:            }
0251:
0252:            /**
0253:             * Returns an estimate of the available bytes.  If a read would not block,
0254:             * it will always return greater than 0.
0255:             */
0256:            public int getAvailable() throws IOException {
0257:                if (_readOffset < _readLength) {
0258:                    return _readLength - _readOffset;
0259:                }
0260:
0261:                if (_sibling != null)
0262:                    _sibling.flush();
0263:
0264:                return _source.getAvailable();
0265:            }
0266:
0267:            /**
0268:             * Returns true if data in the buffer is available.
0269:             */
0270:            public int getBufferAvailable() throws IOException {
0271:                return _readLength - _readOffset;
0272:            }
0273:
0274:            /**
0275:             * Compatibility with InputStream.
0276:             */
0277:            @Override
0278:            public int available() throws IOException {
0279:                return getAvailable();
0280:            }
0281:
0282:            /**
0283:             * Returns the next byte or -1 if at the end of file.
0284:             */
0285:            public final int read() throws IOException {
0286:                if (_readLength <= _readOffset) {
0287:                    if (!readBuffer())
0288:                        return -1;
0289:                }
0290:
0291:                return _readBuffer[_readOffset++] & 0xff;
0292:            }
0293:
0294:            /**
0295:             * Unreads the last byte.
0296:             */
0297:            public final void unread() {
0298:                if (_readOffset <= 0)
0299:                    throw new RuntimeException();
0300:
0301:                _readOffset--;
0302:            }
0303:
0304:            /**
0305:             * Waits for data to be available.
0306:             */
0307:            public final boolean waitForRead() throws IOException {
0308:                if (_readLength <= _readOffset) {
0309:                    if (!readBuffer())
0310:                        return false;
0311:                }
0312:
0313:                return true;
0314:            }
0315:
0316:            /**
0317:             * Skips the next <code>n</code> bytes.
0318:             *
0319:             * @param n bytes to skip.
0320:             *
0321:             * @return number of bytes skipped.
0322:             */
0323:            @Override
0324:            public long skip(long n) throws IOException {
0325:                long buffered = getBufferAvailable();
0326:
0327:                if (n < buffered) {
0328:                    _readOffset += n;
0329:                    return n;
0330:                }
0331:
0332:                _readLength = 0;
0333:                _readOffset = 0;
0334:
0335:                if (_source.hasSkip()) {
0336:                    if (_sibling != null)
0337:                        _sibling.flush();
0338:
0339:                    long skipped = _source.skip(n - buffered);
0340:
0341:                    if (skipped < 0)
0342:                        return buffered;
0343:                    else {
0344:                        _position += skipped + buffered;
0345:                        return skipped + buffered;
0346:                    }
0347:                }
0348:
0349:                while (_readLength < (_readOffset + n - buffered)) {
0350:                    buffered += getBufferAvailable();
0351:                    _readOffset = 0;
0352:                    _readLength = 0;
0353:
0354:                    if (!readBuffer())
0355:                        return buffered;
0356:                }
0357:
0358:                _readOffset += (int) (n - buffered);
0359:
0360:                return n;
0361:            }
0362:
0363:            /**
0364:             * Reads into a byte array.  <code>read</code> may return less than
0365:             * the maximum bytes even if more bytes are available to read.
0366:             *
0367:             * @param buf byte array
0368:             * @param offset offset into the byte array to start reading
0369:             * @param length maximum byte allowed to read.
0370:             *
0371:             * @return number of bytes read or -1 on end of file.
0372:             */
0373:            @Override
0374:            public final int read(byte[] buf, int offset, int length)
0375:                    throws IOException {
0376:                int readOffset = _readOffset;
0377:                int readLength = _readLength;
0378:
0379:                if (readLength <= readOffset) {
0380:                    if (ZERO_COPY_SIZE <= length) {
0381:                        if (_sibling != null)
0382:                            _sibling.flush();
0383:
0384:                        int len = _source.read(buf, offset, length);
0385:
0386:                        if (len > 0) {
0387:                            _position += len;
0388:                            _readTime = Alarm.getCurrentTime();
0389:                        }
0390:
0391:                        return len;
0392:                    }
0393:
0394:                    if (!readBuffer())
0395:                        return -1;
0396:
0397:                    readOffset = _readOffset;
0398:                    readLength = _readLength;
0399:                }
0400:
0401:                int sublen = readLength - readOffset;
0402:                if (length < sublen)
0403:                    sublen = length;
0404:
0405:                System.arraycopy(_readBuffer, readOffset, buf, offset, sublen);
0406:
0407:                _readOffset = readOffset + sublen;
0408:
0409:                return sublen;
0410:            }
0411:
0412:            /**
0413:             * Reads into a byte array.  <code>readAll</code> will always read
0414:             * <code>length</code> bytes, blocking if necessary, until the end of
0415:             * file is reached.
0416:             *
0417:             * @param buf byte array
0418:             * @param offset offset into the byte array to start reading
0419:             * @param length maximum byte allowed to read.
0420:             *
0421:             * @return number of bytes read or -1 on end of file.
0422:             */
0423:            public int readAll(byte[] buf, int offset, int length)
0424:                    throws IOException {
0425:                int readLength = 0;
0426:
0427:                while (length > 0) {
0428:                    int sublen = read(buf, offset, length);
0429:
0430:                    if (sublen < 0)
0431:                        return readLength == 0 ? -1 : readLength;
0432:
0433:                    offset += sublen;
0434:                    readLength += sublen;
0435:                    length -= sublen;
0436:                }
0437:
0438:                return readLength == 0 ? -1 : readLength;
0439:            }
0440:
0441:            /*
0442:             * Reader methods
0443:             */
0444:
0445:            /**
0446:             * Sets the current read encoding.  The encoding can either be a
0447:             * Java encoding name or a mime encoding.
0448:             *
0449:             * @param encoding name of the read encoding
0450:             */
0451:            public void setEncoding(String encoding)
0452:                    throws UnsupportedEncodingException {
0453:                String mimeName = Encoding.getMimeName(encoding);
0454:
0455:                if (mimeName != null && mimeName.equals(_readEncodingName))
0456:                    return;
0457:
0458:                _readEncoding = Encoding.getReadEncoding(this , encoding);
0459:                _readEncodingName = mimeName;
0460:            }
0461:
0462:            /**
0463:             * Returns the mime-encoding currently read.
0464:             */
0465:            public String getEncoding() {
0466:                return _readEncodingName;
0467:            }
0468:
0469:            /**
0470:             * Reads a character from the stream, returning -1 on end of file.
0471:             */
0472:            public final int readChar() throws IOException {
0473:                if (_readEncoding != null) {
0474:                    int ch = _readEncoding.read();
0475:                    return ch;
0476:                }
0477:
0478:                if (_readLength <= _readOffset) {
0479:                    if (!readBuffer())
0480:                        return -1;
0481:                }
0482:
0483:                return _readBuffer[_readOffset++] & 0xff;
0484:            }
0485:
0486:            /**
0487:             * Reads into a character buffer from the stream.  Like the byte
0488:             * array version, read may return less characters even though more
0489:             * characters are available.
0490:             *
0491:             * @param buf character buffer to fill
0492:             * @param offset starting offset into the character buffer
0493:             * @param length maximum number of characters to read
0494:             * @return number of characters read or -1 on end of file.
0495:             */
0496:            public final int read(char[] buf, int offset, int length)
0497:                    throws IOException {
0498:                if (_readEncoding != null)
0499:                    return _readEncoding.read(buf, offset, length);
0500:
0501:                byte[] readBuffer = _readBuffer;
0502:                if (readBuffer == null)
0503:                    return -1;
0504:
0505:                int readOffset = _readOffset;
0506:                int readLength = _readLength;
0507:
0508:                int sublen = readLength - readOffset;
0509:
0510:                if (sublen <= 0) {
0511:                    if (!readBuffer()) {
0512:                        return -1;
0513:                    }
0514:                    readLength = _readLength;
0515:                    readOffset = _readOffset;
0516:                    sublen = readLength - readOffset;
0517:                }
0518:
0519:                if (length < sublen)
0520:                    sublen = length;
0521:
0522:                for (int i = 0; i < sublen; i++)
0523:                    buf[offset + i] = (char) (readBuffer[readOffset + i] & 0xff);
0524:
0525:                _readOffset = readOffset + sublen;
0526:
0527:                return sublen;
0528:            }
0529:
0530:            /**
0531:             * Reads into a character buffer from the stream.  <code>length</code>
0532:             * characters will always be read until the end of file is reached.
0533:             *
0534:             * @param buf character buffer to fill
0535:             * @param offset starting offset into the character buffer
0536:             * @param length maximum number of characters to read
0537:             * @return number of characters read or -1 on end of file.
0538:             */
0539:            public int readAll(char[] buf, int offset, int length)
0540:                    throws IOException {
0541:                int readLength = 0;
0542:
0543:                while (length > 0) {
0544:                    int sublen = read(buf, offset, length);
0545:
0546:                    if (sublen <= 0)
0547:                        return readLength > 0 ? readLength : -1;
0548:
0549:                    offset += sublen;
0550:                    readLength += sublen;
0551:                    length -= sublen;
0552:                }
0553:
0554:                return readLength;
0555:            }
0556:
0557:            /**
0558:             * Reads characters from the stream, appending to the character buffer.
0559:             *
0560:             * @param buf character buffer to fill
0561:             * @param length maximum number of characters to read
0562:             * @return number of characters read or -1 on end of file.
0563:             */
0564:            public int read(CharBuffer buf, int length) throws IOException {
0565:                int len = buf.getLength();
0566:
0567:                buf.setLength(len + length);
0568:                int readLength = read(buf.getBuffer(), len, length);
0569:                if (readLength < 0)
0570:                    buf.setLength(len);
0571:                else if (readLength < length)
0572:                    buf.setLength(len + readLength);
0573:
0574:                return length;
0575:            }
0576:
0577:            /**
0578:             * Reads characters from the stream, appending to the character buffer.
0579:             * <code>length</code> characters will always be read until the end of
0580:             * file.
0581:             *
0582:             * @param buf character buffer to fill
0583:             * @param length maximum number of characters to read
0584:             * @return number of characters read or -1 on end of file.
0585:             */
0586:            public int readAll(CharBuffer buf, int length) throws IOException {
0587:                int len = buf.getLength();
0588:
0589:                buf.setLength(len + length);
0590:                int readLength = readAll(buf.getBuffer(), len, length);
0591:                if (readLength < 0)
0592:                    buf.setLength(len);
0593:                else if (readLength < length)
0594:                    buf.setLength(len + readLength);
0595:
0596:                return length;
0597:            }
0598:
0599:            /**
0600:             * Reads a line from the stream, returning a string.
0601:             */
0602:            public final String readln() throws IOException {
0603:                return readLine();
0604:            }
0605:
0606:            /**
0607:             * Reads a line, returning a string.
0608:             */
0609:            public String readLine() throws IOException {
0610:                CharBuffer cb = new CharBuffer();
0611:
0612:                if (readLine(cb, true))
0613:                    return cb.toString();
0614:                else if (cb.length() == 0)
0615:                    return null;
0616:                else
0617:                    return cb.toString();
0618:            }
0619:
0620:            /**
0621:             * Reads a line, returning a string.
0622:             */
0623:            public String readLineNoChop() throws IOException {
0624:                CharBuffer cb = new CharBuffer();
0625:
0626:                if (readLine(cb, false))
0627:                    return cb.toString();
0628:                else if (cb.length() == 0)
0629:                    return null;
0630:                else
0631:                    return cb.toString();
0632:            }
0633:
0634:            /**
0635:             * Fills the buffer with the next line from the input stream.
0636:             *
0637:             * @return true on success, false on end of file.
0638:             */
0639:            public final boolean readln(CharBuffer cb) throws IOException {
0640:                return readLine(cb, true);
0641:            }
0642:
0643:            /**
0644:             * Reads a line into the character buffer.  \r\n is converted to \n.
0645:             *
0646:             * @param buf character buffer to fill
0647:             * @return false on end of file
0648:             */
0649:            public final boolean readLine(CharBuffer cb) throws IOException {
0650:                return readLine(cb, true);
0651:            }
0652:
0653:            /**
0654:             * Reads a line into the character buffer.  \r\n is converted to \n.
0655:             *
0656:             * @param buf character buffer to fill
0657:             * @return false on end of file
0658:             */
0659:            public final boolean readLine(CharBuffer cb, boolean isChop)
0660:                    throws IOException {
0661:                if (_readEncoding != null)
0662:                    return readlnEncoded(cb, isChop);
0663:
0664:                int capacity = cb.getCapacity();
0665:                int offset = cb.getLength();
0666:                char[] buf = cb.getBuffer();
0667:
0668:                byte[] readBuffer = _readBuffer;
0669:
0670:                while (true) {
0671:                    int readOffset = _readOffset;
0672:
0673:                    int sublen = _readLength - readOffset;
0674:                    if (capacity - offset < sublen)
0675:                        sublen = capacity - offset;
0676:
0677:                    for (; sublen > 0; sublen--) {
0678:                        int ch = readBuffer[readOffset++] & 0xff;
0679:
0680:                        if (ch != '\n') {
0681:                            buf[offset++] = (char) ch;
0682:                        } else if (isChop) {
0683:                            if (offset > 0 && buf[offset - 1] == '\r')
0684:                                cb.setLength(offset - 1);
0685:                            else
0686:                                cb.setLength(offset);
0687:
0688:                            _readOffset = readOffset;
0689:
0690:                            return true;
0691:                        } else {
0692:                            buf[offset++] = (char) '\n';
0693:
0694:                            cb.setLength(offset);
0695:
0696:                            _readOffset = readOffset;
0697:
0698:                            return true;
0699:                        }
0700:                    }
0701:
0702:                    _readOffset = readOffset;
0703:
0704:                    if (_readLength <= readOffset) {
0705:                        if (!readBuffer()) {
0706:                            cb.setLength(offset);
0707:                            return offset > 0;
0708:                        }
0709:                    }
0710:
0711:                    if (capacity <= offset) {
0712:                        cb.setLength(offset + 1);
0713:                        capacity = cb.getCapacity();
0714:                        buf = cb.getBuffer();
0715:                    }
0716:                }
0717:            }
0718:
0719:            /**
0720:             * Reads a line into the character buffer.  \r\n is converted to \n.
0721:             *
0722:             * @param buf character buffer to fill.
0723:             * @param length number of characters to fill.
0724:             *
0725:             * @return -1 on end of file or the number of characters read.
0726:             */
0727:            public final int readLine(char[] buf, int length)
0728:                    throws IOException {
0729:                return readLine(buf, length, true);
0730:            }
0731:
0732:            /**
0733:             * Reads a line into the character buffer.  \r\n is converted to \n.
0734:             *
0735:             * @param buf character buffer to fill.
0736:             * @param length number of characters to fill.
0737:             *
0738:             * @return -1 on end of file or the number of characters read.
0739:             */
0740:            public final int readLine(char[] buf, int length, boolean isChop)
0741:                    throws IOException {
0742:                byte[] readBuffer = _readBuffer;
0743:
0744:                int offset = 0;
0745:
0746:                while (true) {
0747:                    int readOffset = _readOffset;
0748:
0749:                    int sublen = _readLength - readOffset;
0750:                    if (sublen < length)
0751:                        sublen = length;
0752:
0753:                    for (; sublen > 0; sublen--) {
0754:                        int ch = readBuffer[readOffset++] & 0xff;
0755:
0756:                        if (ch != '\n') {
0757:                        } else if (isChop) {
0758:                            _readOffset = readOffset;
0759:
0760:                            if (offset > 0 && buf[offset - 1] == '\r')
0761:                                return offset - 1;
0762:                            else
0763:                                return offset;
0764:                        } else {
0765:                            buf[offset++] = (char) ch;
0766:
0767:                            _readOffset = readOffset;
0768:
0769:                            return offset + 1;
0770:                        }
0771:
0772:                        buf[offset++] = (char) ch;
0773:                    }
0774:                    _readOffset = readOffset;
0775:
0776:                    if (readOffset <= _readLength) {
0777:                        if (!readBuffer()) {
0778:                            return offset;
0779:                        }
0780:                    }
0781:
0782:                    if (length <= offset)
0783:                        return length + 1;
0784:                }
0785:            }
0786:
0787:            private boolean readlnEncoded(CharBuffer cb, boolean isChop)
0788:                    throws IOException {
0789:                while (true) {
0790:                    int ch = readChar();
0791:
0792:                    if (ch < 0)
0793:                        return cb.length() > 0;
0794:
0795:                    if (ch != '\n') {
0796:                    } else if (isChop) {
0797:                        if (cb.length() > 0 && cb.getLastChar() == '\r')
0798:                            cb.setLength(cb.getLength() - 1);
0799:
0800:                        return true;
0801:                    } else {
0802:                        cb.append('\n');
0803:
0804:                        return true;
0805:                    }
0806:
0807:                    cb.append((char) ch);
0808:                }
0809:            }
0810:
0811:            /**
0812:             * Copies this stream to the output stream.
0813:             *
0814:             * @param os destination stream.
0815:             */
0816:            public void writeToStream(OutputStream os) throws IOException {
0817:                if (_readLength <= _readOffset) {
0818:                    readBuffer();
0819:                }
0820:
0821:                while (_readOffset < _readLength) {
0822:                    os.write(_readBuffer, _readOffset, _readLength
0823:                            - _readOffset);
0824:
0825:                    readBuffer();
0826:                }
0827:            }
0828:
0829:            /**
0830:             * Writes <code>len<code> bytes to the output stream from this stream.
0831:             *
0832:             * @param os destination stream.
0833:             * @param len bytes to write.
0834:             */
0835:            public void writeToStream(OutputStream os, int len)
0836:                    throws IOException {
0837:                while (len > 0) {
0838:                    if (_readLength <= _readOffset) {
0839:                        if (!readBuffer())
0840:                            return;
0841:                    }
0842:
0843:                    int sublen = _readLength - _readOffset;
0844:                    if (len < sublen)
0845:                        sublen = len;
0846:
0847:                    os.write(_readBuffer, _readOffset, sublen);
0848:                    _readOffset += sublen;
0849:                    len -= sublen;
0850:                }
0851:            }
0852:
0853:            /**
0854:             * Copies this stream to the output stream.
0855:             *
0856:             * @param out destination writer
0857:             */
0858:            public void writeToWriter(Writer out) throws IOException {
0859:                int ch;
0860:                while ((ch = readChar()) >= 0)
0861:                    out.write((char) ch);
0862:            }
0863:
0864:            /**
0865:             * Fills the buffer from the underlying stream.
0866:             */
0867:            public int fillBuffer() throws IOException {
0868:                if (!readBuffer())
0869:                    return -1;
0870:                else
0871:                    return _readLength;
0872:            }
0873:
0874:            /**
0875:             * Fills the buffer with a non-blocking read.
0876:             */
0877:            public boolean readNonBlock() throws IOException {
0878:                if (_readOffset < _readLength)
0879:                    return true;
0880:
0881:                if (_readBuffer == null) {
0882:                    _readOffset = 0;
0883:                    _readLength = 0;
0884:                    return false;
0885:                }
0886:
0887:                if (_sibling != null)
0888:                    _sibling.flush();
0889:
0890:                _readOffset = 0;
0891:                _readLength = _source.readNonBlock(_readBuffer, 0,
0892:                        _readBuffer.length);
0893:
0894:                // Setting to 0 is needed to avoid int to long conversion errors with AIX
0895:                if (_readLength > 0) {
0896:                    _position += _readLength;
0897:                    _readTime = Alarm.getCurrentTime();
0898:
0899:                    return true;
0900:                } else {
0901:                    _readLength = 0;
0902:                    return false;
0903:                }
0904:            }
0905:
0906:            /**
0907:             * Fills the buffer with a non-blocking read.
0908:             */
0909:            public boolean fillWithTimeout(long timeout) throws IOException {
0910:                if (_readOffset < _readLength)
0911:                    return true;
0912:
0913:                if (_readBuffer == null) {
0914:                    _readOffset = 0;
0915:                    _readLength = 0;
0916:                    return false;
0917:                }
0918:
0919:                if (_sibling != null)
0920:                    _sibling.flush();
0921:
0922:                _readOffset = 0;
0923:                _readLength = _source.readTimeout(_readBuffer, 0,
0924:                        _readBuffer.length, timeout);
0925:
0926:                // Setting to 0 is needed to avoid int to long conversion errors with AIX
0927:                if (_readLength > 0) {
0928:                    _position += _readLength;
0929:                    _readTime = Alarm.getCurrentTime();
0930:                    return true;
0931:                } else {
0932:                    _readLength = 0;
0933:                    return false;
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Fills the read buffer, flushing the write buffer.
0939:             *
0940:             * @return false on end of file and true if there's more data.
0941:             */
0942:            private boolean readBuffer() throws IOException {
0943:                if (_readBuffer == null) {
0944:                    _readOffset = 0;
0945:                    _readLength = 0;
0946:                    return false;
0947:                }
0948:
0949:                if (_sibling != null)
0950:                    _sibling.flush();
0951:
0952:                _readOffset = 0;
0953:                _readLength = _source.read(_readBuffer, 0, _readBuffer.length);
0954:
0955:                // Setting to 0 is needed to avoid int to long conversion errors with AIX
0956:                if (_readLength > 0) {
0957:                    _position += _readLength;
0958:                    _readTime = Alarm.getCurrentTime();
0959:                    return true;
0960:                } else {
0961:                    _readLength = 0;
0962:                    return false;
0963:                }
0964:            }
0965:
0966:            private boolean readBuffer(int off) throws IOException {
0967:                if (_readBuffer == null)
0968:                    return false;
0969:
0970:                if (_sibling != null)
0971:                    _sibling.flush();
0972:
0973:                _readOffset = 0;
0974:                _readLength = _source.read(_readBuffer, off, _readBuffer.length
0975:                        - off);
0976:
0977:                // Setting to 0 is needed to avoid int to long conversion errors with AIX
0978:                if (_readLength > 0) {
0979:                    _position += _readLength;
0980:                    _readTime = Alarm.getCurrentTime();
0981:                    return true;
0982:                } else {
0983:                    _readLength = 0;
0984:                    return false;
0985:                }
0986:            }
0987:
0988:            /**
0989:             * Disables close.  Sometimes an application will pass a stream
0990:             * to a client that may close the stream at an inappropriate time.
0991:             * Setting disable close gives the calling routine control over closing
0992:             * the stream.
0993:             */
0994:            public void setDisableClose(boolean disableClose) {
0995:                _disableClose = disableClose;
0996:            }
0997:
0998:            /**
0999:             * Disables closing of the underlying source.
1000:             */
1001:            public void setDisableCloseSource(boolean disableClose) {
1002:                _isDisableCloseSource = disableClose;
1003:            }
1004:
1005:            /**
1006:             * Close the stream.
1007:             */
1008:            @Override
1009:            public final void close() {
1010:                try {
1011:                    if (_disableClose)
1012:                        return;
1013:
1014:                    if (!_reuseBuffer) {
1015:                        if (_tempRead != null) {
1016:                            TempBuffer.free(_tempRead);
1017:                            _tempRead = null;
1018:                        }
1019:                        _readBuffer = null;
1020:                    }
1021:
1022:                    if (_readEncoding != null) {
1023:                        Reader reader = _readEncoding;
1024:                        _readEncoding = null;
1025:                        reader.close();
1026:                    }
1027:
1028:                    if (_source != null && !_isDisableCloseSource) {
1029:                        StreamImpl s = _source;
1030:                        _source = null;
1031:                        s.close();
1032:                    }
1033:                } catch (IOException e) {
1034:                    log().log(Level.FINE, e.toString(), e);
1035:                }
1036:            }
1037:
1038:            /**
1039:             * Returns a named attribute.  For example, an HTTP stream
1040:             * may use this to return header values.
1041:             */
1042:            public Object getAttribute(String name) throws IOException {
1043:                if (_sibling != null)
1044:                    _sibling.flush();
1045:
1046:                return _source.getAttribute(name);
1047:            }
1048:
1049:            /**
1050:             * Lists all named attributes.
1051:             */
1052:            public Iterator getAttributeNames() throws IOException {
1053:                if (_sibling != null)
1054:                    _sibling.flush();
1055:
1056:                return _source.getAttributeNames();
1057:            }
1058:
1059:            /**
1060:             * Sets a named attribute.  For example, an HTTP stream
1061:             * may use this to set header values.
1062:             */
1063:            public void setAttribute(String name, Object value)
1064:                    throws IOException {
1065:                _source.setAttribute(name, value);
1066:            }
1067:
1068:            /**
1069:             * Removes a named attribute.
1070:             */
1071:            public void removeAttribute(String name) throws IOException {
1072:                _source.removeAttribute(name);
1073:            }
1074:
1075:            /**
1076:             * Returns the Path which opened this stream.
1077:             */
1078:            public Path getPath() {
1079:                return _source == null ? null : _source.getPath();
1080:            }
1081:
1082:            /**
1083:             * Returns the user path which opened this stream.
1084:             *
1085:             * <p>Parsing routines typically use this for error reporting.
1086:             */
1087:            public String getUserPath() {
1088:                if (_source == null || _source.getPath() == null)
1089:                    return "stream";
1090:                else
1091:                    return _source.getPath().getUserPath();
1092:            }
1093:
1094:            /**
1095:             * Returns the user path which opened this stream.
1096:             *
1097:             * <p>Parsing routines typically use this for error reporting.
1098:             */
1099:            public String getURL() {
1100:                if (_source == null || _source.getPath() == null)
1101:                    return "stream:";
1102:                else
1103:                    return _source.getPath().getURL();
1104:            }
1105:
1106:            /**
1107:             * Sets a path name associated with the stream.
1108:             */
1109:            public void setPath(Path path) {
1110:                _source.setPath(path);
1111:            }
1112:
1113:            /**
1114:             * Returns a Reader reading to this stream.
1115:             */
1116:            public Reader getReader() {
1117:                if (_reader == null)
1118:                    _reader = new StreamReader();
1119:
1120:                return _reader;
1121:            }
1122:
1123:            private static Logger log() {
1124:                return Logger.getLogger(ReadStream.class.getName());
1125:            }
1126:
1127:            /**
1128:             * Returns a printable representation of the read stream.
1129:             */
1130:            public String toString() {
1131:                return "ReadStream[" + _source + "]";
1132:            }
1133:
1134:            public boolean lock(boolean shared, boolean block) {
1135:                if (!(_source instanceof  LockableStream))
1136:                    return true;
1137:
1138:                LockableStream ls = (LockableStream) _source;
1139:                return ls.lock(shared, block);
1140:            }
1141:
1142:            public boolean unlock() {
1143:                if (!(_source instanceof  LockableStream))
1144:                    return true;
1145:
1146:                LockableStream ls = (LockableStream) _source;
1147:                return ls.unlock();
1148:            }
1149:
1150:            public class StreamReader extends Reader {
1151:                public final int read() throws IOException {
1152:                    return ReadStream.this .readChar();
1153:                }
1154:
1155:                public final int read(char[] cbuf, int off, int len)
1156:                        throws IOException {
1157:                    return ReadStream.this .read(cbuf, off, len);
1158:                }
1159:
1160:                public boolean ready() throws IOException {
1161:                    return ReadStream.this .available() > 0;
1162:                }
1163:
1164:                public final void close() throws IOException {
1165:                }
1166:
1167:                public ReadStream getStream() {
1168:                    return ReadStream.this;
1169:                }
1170:            }
1171:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.