Changed Lucene.Net.Analysis.Common.Analysis.Util.BufferedCharFilter to to the implementation from the Apache Harmony project
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/f3ac940c Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/f3ac940c Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/f3ac940c Branch: refs/heads/master Commit: f3ac940c97d0e7ccdda707df11365fda4c89c197 Parents: b6b1d87 Author: Shad Storhaug <[email protected]> Authored: Thu Apr 27 12:54:48 2017 +0700 Committer: Shad Storhaug <[email protected]> Committed: Fri Apr 28 13:31:27 2017 +0700 ---------------------------------------------------------------------- LICENSE.txt | 22 + .../Analysis/CharFilter/MappingCharFilter.cs | 2 +- .../Analysis/Util/BufferedCharFilter.cs | 752 +++++++++-------- .../JavaCompatibility/SystemTypesHelpers.cs | 2 +- .../Analysis/Util/TestBufferedCharFilter.cs | 816 +++++++++++++++++++ .../Lucene.Net.Tests.Analysis.Common.csproj | 6 +- 6 files changed, 1266 insertions(+), 334 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/LICENSE.txt ---------------------------------------------------------------------- diff --git a/LICENSE.txt b/LICENSE.txt index 88346fd..617d392 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -758,6 +758,28 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +============================= + +Some code in +src/Lucene.Net.Analysis.Common/Util/BufferedCharFilter.cs +src/Lucene.Net.Tests.Analysis.Common/Util/TestBufferedCharFilter.cs +was sourced from the Apache Harmony project, which falls under the +following license: + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. ============================= http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs index 08ac354..de79d64 100644 --- a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs +++ b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs @@ -58,7 +58,7 @@ namespace Lucene.Net.Analysis.CharFilters { //LUCENENET support to reset the reader. _input = GetBufferedReader(@in); - _input.Mark(BufferedCharFilter.defaultCharBufferSize); + _input.Mark(BufferedCharFilter.DEFAULT_CHAR_BUFFER_SIZE); buffer.Reset(_input); //buffer.Reset(@in); http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs index e1461a7..c475772 100644 --- a/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs +++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs @@ -1,27 +1,4 @@ -/* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ +// This class was sourced from the Apache Harmony project's BufferedReader using Lucene.Net.Analysis.CharFilters; using System; @@ -31,38 +8,66 @@ using System.Threading.Tasks; namespace Lucene.Net.Analysis.Util { + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /// <summary> /// LUCENENET specific class to mimic Java's BufferedReader (that is, a reader that is seekable) /// so it supports Mark() and Reset() (which are part of the Java Reader class), but also /// provide the Correct() method of BaseCharFilter. - /// - /// At some point we might be able to make some readers accept streams (that are seekable) - /// so this functionality can be .NET-ified. /// </summary> public class BufferedCharFilter : BaseCharFilter { - private TextReader @in; - - private char[] cb; - private int nChars, nextChar; - - private static readonly int INVALIDATED = -2; - private static readonly int UNMARKED = -1; - private int markedChar = UNMARKED; - private int readAheadLimit = 0; /* Valid only when markedChar > 0 */ + public const int DEFAULT_CHAR_BUFFER_SIZE = 8192; /// <summary> - /// If the next character is a line feed, skip it + /// The object used to synchronize access to the reader. /// </summary> - private bool skipLF = false; + protected object m_lock = new object(); + + private TextReader @in; /// <summary> - /// The skipLF flag when the mark was set + /// The characters that can be read and refilled in bulk. We maintain three + /// indices into this buffer: + /// <code> + /// { X X X X X X X X X X X X - - } + /// ^ ^ ^ + /// | | | + /// mark pos end + /// </code> + /// Pos points to the next readable character.End is one greater than the + /// last readable character.When<c> pos == end</c>, the buffer is empty and + /// must be <see cref="FillBuf()"/> before characters can be read. + /// + /// <para/> Mark is the value pos will be set to on calls to + /// <see cref="Reset()"/>. Its value is in the range <c>[0...pos]</c>. If the mark is <c>-1</c>, the + /// buffer cannot be reset. + /// + /// <para/> MarkLimit limits the distance between the mark and the pos.When this + /// limit is exceeded, <see cref="Reset()"/> is permitted (but not required) to + /// throw an exception. For shorter distances, <see cref="Reset()"/> shall not throw + /// (unless the reader is closed). /// </summary> - private bool markedSkipLF = false; - - internal static int defaultCharBufferSize = 8192; - private static int defaultExpectedLineLength = 80; + private char[] buf; + private int pos; + private int end; + private int mark = -1; + private int markLimit = -1; #if !NETSTANDARD /// <summary> @@ -72,406 +77,497 @@ namespace Lucene.Net.Analysis.Util #endif /// <summary> - /// Creates a buffering character-input stream that uses an input buffer of the specified size. + /// Creates a buffering character-input stream that uses a default-sized input buffer. /// </summary> /// <param name="in">A TextReader</param> - /// <param name="sz">Input-buffer size</param> - public BufferedCharFilter(TextReader @in, int sz) + public BufferedCharFilter(TextReader @in) : base(@in) { - if (sz <= 0) - throw new ArgumentOutOfRangeException("Buffer size <= 0"); this.@in = @in; - cb = new char[sz]; - nextChar = nChars = 0; + buf = new char[DEFAULT_CHAR_BUFFER_SIZE]; } /// <summary> - /// Creates a buffering character-input stream that uses a default-sized input buffer. + /// Creates a buffering character-input stream that uses an input buffer of the specified size. /// </summary> /// <param name="in">A TextReader</param> - public BufferedCharFilter(TextReader @in) - : this(@in, defaultCharBufferSize) + /// <param name="size">Input-buffer size</param> + public BufferedCharFilter(TextReader @in, int size) + : base(@in) { + if (size <= 0) + { + throw new ArgumentOutOfRangeException("Buffer size <= 0"); + } + this.@in = @in; + buf = new char[size]; } /// <summary> - /// Checks to make sure that the stream has not been closed + /// Disposes this reader. This implementation closes the buffered source reader + /// and releases the buffer. Nothing is done if this reader has already been + /// disposed. /// </summary> - private void EnsureOpen() + /// <param name="disposing"></param> + /// <exception cref="IOException">if an error occurs while closing this reader.</exception> + protected override void Dispose(bool disposing) { - if (@in == null) - throw new IOException("Stream closed"); + if (disposing) + { +#if !NETSTANDARD + this.isDisposing = true; +#endif + lock (m_lock) + { + if (!IsClosed) + { + @in.Dispose(); + @in = null; + buf = null; + } + } +#if !NETSTANDARD + this.isDisposing = false; +#endif + } } /// <summary> - /// Fills the input buffer, taking the mark into account if it is valid. + /// Populates the buffer with data. It is an error to call this method when + /// the buffer still contains data; ie. if <c>pos < end</c>. /// </summary> - private void Fill() + /// <returns> + /// the number of bytes read into the buffer, or -1 if the end of the + /// source stream has been reached. + /// </returns> + private int FillBuf() { - int dst; - if (markedChar <= UNMARKED) - { - /* No mark */ - dst = 0; - } - else + // assert(pos == end); + + if (mark == -1 || (pos - mark >= markLimit)) { - /* Marked */ - int delta = nextChar - markedChar; - if (delta >= readAheadLimit) + /* mark isn't set or has exceeded its limit. use the whole buffer */ + int result = @in.Read(buf, 0, buf.Length); + if (result > 0) { - /* Gone past read-ahead limit: Invalidate mark */ - markedChar = INVALIDATED; - readAheadLimit = 0; - dst = 0; + mark = -1; + pos = 0; + end = result; } - else + // LUCENENET specific: convert result to -1 to mimic java's reader + return result == 0 ? -1 : result; + } + + if (mark == 0 && markLimit > buf.Length) + { + /* the only way to make room when mark=0 is by growing the buffer */ + int newLength = buf.Length * 2; + if (newLength > markLimit) { - if (readAheadLimit <= cb.Length) - { - /* Shuffle in the current buffer */ - System.Array.Copy(cb, markedChar, cb, 0, delta); - markedChar = 0; - dst = delta; - } - else - { - /* Reallocate buffer to accommodate read-ahead limit */ - char[] ncb = new char[readAheadLimit]; - System.Array.Copy(cb, markedChar, ncb, 0, delta); - cb = ncb; - markedChar = 0; - dst = delta; - } - nextChar = nChars = delta; + newLength = markLimit; } + char[] newbuf = new char[newLength]; + System.Array.Copy(buf, 0, newbuf, 0, buf.Length); + buf = newbuf; + } + else if (mark > 0) + { + /* make room by shifting the buffered data to left mark positions */ + System.Array.Copy(buf, mark, buf, 0, buf.Length - mark); + pos -= mark; + end -= mark; + mark = 0; } - int n = @in.Read(cb, dst, cb.Length - dst); - // LUCENENET: .NET readers always return 0 when they are finished - // so there is nothing to do here but remove this loop. - //do - //{ - // n = @in.Read(cb, dst, cb.Length - dst); - //} while (n == 0); - if (n > 0) + /* Set the new position and mark position */ + int count = @in.Read(buf, pos, buf.Length - pos); + if (count > 0) { - nChars = dst + n; - nextChar = dst; + end += count; } + // LUCENENET specific: convert result to -1 to mimic java's reader + return count == 0 ? -1 : count; } /// <summary> - /// Reads a single character. + /// Checks to make sure that the stream has not been closed /// </summary> - /// <returns>The character read, as an integer in the range 0 to 65535 (0x00-0xffff), or -1 if the end of the stream has been reached</returns> - /// <exception cref="IOException">If an I/O error occurs</exception> - public override int Read() + private void EnsureOpen() { - lock (this) + if (IsClosed) + { + throw new IOException("Reader already closed"); + } + } + + /// <summary> + /// Indicates whether or not this reader is closed. + /// </summary> + private bool IsClosed + { + get { return buf == null; } + } + + /// <summary> + /// Sets a mark position in this reader. The parameter <paramref name="markLimit"/> + /// indicates how many characters can be read before the mark is invalidated. + /// Calling <see cref="Reset()"/> will reposition the reader back to the marked + /// position if <see cref="markLimit"/> has not been surpassed. + /// </summary> + /// <param name="markLimit"> + /// the number of characters that can be read before the mark is + /// invalidated. + /// </param> + /// <exception cref="ArgumentOutOfRangeException">if <c>markLimit < 0</c></exception> + /// <exception cref="IOException">if an error occurs while setting a mark in this reader.</exception> + public override void Mark(int markLimit) + { + if (markLimit < 0) + { + throw new ArgumentOutOfRangeException("Read-ahead limit < 0"); + } + lock (m_lock) { EnsureOpen(); - for (;;) - { - if (nextChar >= nChars) - { - Fill(); - if (nextChar >= nChars) - return -1; - } - if (skipLF) - { - skipLF = false; - if (cb[nextChar] == '\n') - { - nextChar++; - continue; - } - } - return cb[nextChar++]; - } + this.markLimit = markLimit; + mark = pos; } } /// <summary> - /// Reads characters into a portion of an array. - /// This method implements the general contract of the corresponding read method of the TextReader class. - /// As an additional convenience, it attempts to read as many characters as possible by repeatedly - /// invoking the read method of the underlying stream.This iterated read continues until one of the - /// following conditions becomes true: - /// - /// <list type="bullet"> - /// <item>The specified number of characters have been read,</item> - /// <item>The read method of the underlying stream returns -1, indicating end-of-file, or</item> - /// <item>The ready method of the underlying stream returns false, indicating that further input requests would block.</item> - /// </list> - /// If the first read on the underlying stream returns -1 to indicate end-of-file then this method returns -1. - /// Otherwise this method returns the number of characters actually read. - /// Subclasses of this class are encouraged, but not required, to attempt to read as many characters - /// as possible in the same fashion. Ordinarily this method takes characters from this stream's character - /// buffer, filling it from the underlying stream as necessary. If, however, the buffer is empty, the mark - /// is not valid, and the requested length is at least as large as the buffer, then this method will read - /// characters directly from the underlying stream into the given array. Thus redundant BufferedReaders - /// will not copy data unnecessarily. + /// Indicates whether this reader supports the <see cref="Mark(int)"/> and + /// <see cref="Reset()"/> methods. This implementation returns <c>true</c>. /// </summary> - /// <param name="buffer">Destination buffer</param> - /// <param name="index">Offset at which to start storing characters</param> - /// <param name="count">Maximum number of characters to read</param> - /// <returns></returns> - public override int Read(char[] buffer, int index, int count) + /// <seealso cref="Mark(int)"/> + /// <seealso cref="Reset()"/> + public override bool IsMarkSupported { - if (nextChar >= nChars) + get { - /* If the requested length is at least as large as the buffer, and - if there is no mark/reset activity, and if line feeds are not - being skipped, do not bother to copy the characters into the - local buffer. In this way buffered streams will cascade - harmlessly. */ - if (count >= cb.Length && markedChar <= UNMARKED && !skipLF) - { - return @in.Read(buffer, index, count); - } - Fill(); + return true; } - if (nextChar >= nChars) return -1; - if (skipLF) + } + + + /// <summary> + /// Reads a single character from this reader and returns it with the two + /// higher-order bytes set to 0. If possible, <see cref="BufferedCharFilter"/> returns a + /// character from the buffer. If there are no characters available in the + /// buffer, it fills the buffer and then returns a character. It returns -1 + /// if there are no more characters in the source reader. + /// </summary> + /// <returns>The character read or -1 if the end of the source reader has been reached.</returns> + /// <exception cref="IOException">If this reader is disposed or some other I/O error occurs.</exception> + public override int Read() + { + lock (m_lock) { - skipLF = false; - if (cb[nextChar] == '\n') + EnsureOpen(); + /* Are there buffered characters available? */ + if (pos < end || FillBuf() != -1) { - nextChar++; - if (nextChar >= nChars) - Fill(); - if (nextChar >= nChars) - return -1; + return buf[pos++]; } + return -1; } - int n = Math.Min(count, nChars - nextChar); - System.Array.Copy(cb, nextChar, buffer, index, n); - nextChar += n; - return n; } /// <summary> - /// Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return - /// ('\r'), or a carriage return followed immediately by a linefeed. + /// Reads at most <paramref name="length"/> characters from this reader and stores them + /// at <paramref name="offset"/> in the character array <paramref name="buffer"/>. Returns the + /// number of characters actually read or -1 if the end of the source reader + /// has been reached. If all the buffered characters have been used, a mark + /// has not been set and the requested number of characters is larger than + /// this readers buffer size, BufferedReader bypasses the buffer and simply + /// places the results directly into <paramref name="buffer"/>. /// </summary> - /// <returns>A String containing the contents of the line, not including any line-termination characters, - /// or null if the end of the stream has been reached</returns> - /// <exception cref="IOException">If an I/O error occurs</exception> - public override string ReadLine() + /// <param name="buffer">the character array to store the characters read.</param> + /// <param name="offset">the initial position in <paramref name="buffer"/> to store the bytes read from this reader.</param> + /// <param name="length">the maximum number of characters to read, must be non-negative.</param> + /// <returns>number of characters read or -1 if the end of the source reader has been reached.</returns> + /// <exception cref="ArgumentOutOfRangeException"> + /// if <c>offset < 0</c> or <c>length < 0</c>, or if + /// <c>offset + length</c> is greater than the size of + /// <paramref name="buffer"/>. + /// </exception> + /// <exception cref="IOException">if this reader is disposed or some other I/O error occurs.</exception> + public override int Read(char[] buffer, int offset, int length) { - StringBuilder s = null; - int startChar; - - lock (this) + lock(m_lock) { EnsureOpen(); - bool omitLF = skipLF; - - for (;;) + if (offset < 0 || offset > buffer.Length - length || length < 0) + { + throw new ArgumentOutOfRangeException(); + } + int outstanding = length; + while (outstanding > 0) { - if (nextChar >= nChars) + + /* + * If there are bytes in the buffer, grab those first. + */ + int available = end - pos; + if (available > 0) { - Fill(); + int count2 = available >= outstanding ? outstanding : available; + System.Array.Copy(buf, pos, buffer, offset, count2); + pos += count2; + offset += count2; + outstanding -= count2; } - if (nextChar >= nChars) - { /* EOF */ - if (s != null && s.Length > 0) - return s.ToString(); - else - return null; + + /* + * Before attempting to read from the underlying stream, make + * sure we really, really want to. We won't bother if we're + * done, or if we've already got some bytes and reading from the + * underlying stream would block. + */ + if (outstanding == 0 /*|| (outstanding < length && [email protected]())*/) { + break; } - bool eol = false; - char c = (char)0; - int i; - /* Skip a leftover '\n', if necessary */ - if (omitLF && (cb[nextChar] == '\n')) - nextChar++; - skipLF = false; - omitLF = false; + // assert(pos == end); - for (i = nextChar; i < nChars; i++) + /* + * If we're unmarked and the requested size is greater than our + * buffer, read the bytes directly into the caller's buffer. We + * don't read into smaller buffers because that could result in + * a many reads. + */ + if ((mark == -1 || (pos - mark >= markLimit)) + && outstanding >= buf.Length) { - c = cb[i]; - if ((c == '\n') || (c == '\r')) + int count3 = @in.Read(buffer, offset, outstanding); + if (count3 > 0) { - eol = true; - break; + offset += count3; + outstanding -= count3; + mark = -1; } + + break; // assume the source stream gave us all that it could } - startChar = nextChar; - nextChar = i; - if (eol) + if (FillBuf() == -1) { - string str; - if (s == null) - { - str = new string(cb, startChar, i - startChar); - } - else - { - s.Append(cb, startChar, i - startChar); - str = s.ToString(); - } - nextChar++; - if (c == '\r') - { - skipLF = true; - } - return str; + break; // source is exhausted } - - if (s == null) - s = new StringBuilder(defaultExpectedLineLength); - s.Append(cb, startChar, i - startChar); } + + int count = length - outstanding; + return (count > 0 || count == length) ? count : 0 /*-1*/; } } - public override long Skip(int n) + /// <summary> + /// Peeks at the next input character, refilling the buffer if necessary. If + /// this character is a newline character ("\n"), it is discarded. + /// </summary> + private void ChompNewline() { - if (n < 0L) + if ((pos != end || FillBuf() != -1) + && buf[pos] == '\n') { - throw new ArgumentOutOfRangeException("skip value is negative"); + pos++; } - lock (this) + } + + /// <summary> + /// Returns the next line of text available from this reader. A line is + /// represented by zero or more characters followed by <c>'\n'</c>, + /// <c>'\r'</c>, <c>"\r\n"</c> or the end of the reader. The string does + /// not include the newline sequence. + /// </summary> + /// <returns>The contents of the line or <c>null</c> if no characters were + /// read before the end of the reader has been reached.</returns> + /// <exception cref="IOException">if this reader is disposed or some other I/O error occurs.</exception> + public override string ReadLine() + { + lock(m_lock) { EnsureOpen(); - int r = n; - while (r > 0) + /* has the underlying stream been exhausted? */ + if (pos == end && FillBuf() == -1) { - if (nextChar >= nChars) - Fill(); - if (nextChar >= nChars) /* EOF */ - break; - if (skipLF) + return null; + } + for (int charPos = pos; charPos < end; charPos++) + { + char ch = buf[charPos]; + if (ch > '\r') { - skipLF = false; - if (cb[nextChar] == '\n') - { - nextChar++; - } + continue; } - int d = nChars - nextChar; - if (r <= d) + if (ch == '\n') { - nextChar += r; - r = 0; - break; + string res = new string(buf, pos, charPos - pos); + pos = charPos + 1; + return res; } - else + else if (ch == '\r') { - r -= d; - nextChar = nChars; + string res = new string(buf, pos, charPos - pos); + pos = charPos + 1; + if (((pos < end) || (FillBuf() != -1)) + && (buf[pos] == '\n')) + { + pos++; + } + return res; } } - return n - r; - } - } - /// <summary> - /// Tells whether this stream is ready to be read. A buffered character stream is ready if the buffer is not empty, or if the underlying character stream is ready. - /// </summary> - /// <returns></returns> - public override bool Ready() - { - lock (this) - { - EnsureOpen(); + char eol = '\0'; + StringBuilder result = new StringBuilder(80); + /* Typical Line Length */ - // If newline needs to be skipped and the next char to be read - // is a newline character, then just skip it right away. - if (skipLF) + result.Append(buf, pos, end - pos); + while (true) { - // Note that in.ready() will return true if and only if the next - // read on the stream will not block. - if (nextChar >= nChars /* && @in.Ready() */) + pos = end; + + /* Are there buffered characters available? */ + if (eol == '\n') + { + return result.ToString(); + } + // attempt to fill buffer + if (FillBuf() == -1) + { + // characters or null. + return result.Length > 0 || eol != '\0' + ? result.ToString() + : null; + } + for (int charPos = pos; charPos < end; charPos++) + { + char c = buf[charPos]; + if (eol == '\0') + { + if ((c == '\n' || c == '\r')) + { + eol = c; + } + } + else if (eol == '\r' && c == '\n') + { + if (charPos > pos) + { + result.Append(buf, pos, charPos - pos - 1); + } + pos = charPos + 1; + return result.ToString(); + } + else + { + if (charPos > pos) + { + result.Append(buf, pos, charPos - pos - 1); + } + pos = charPos; + return result.ToString(); + } + } + if (eol == '\0') { - Fill(); + result.Append(buf, pos, end - pos); } - if (nextChar < nChars) + else { - if (cb[nextChar] == '\n') - nextChar++; - skipLF = false; + result.Append(buf, pos, end - pos - 1); } } - return (nextChar < nChars) /* || @in.Ready() */; } } /// <summary> - /// Tells whether this stream supports the mark() operation, which it does. + /// Indicates whether this reader is ready to be read without blocking. /// </summary> - public override bool IsMarkSupported + /// <returns> + /// <c>true</c> if this reader will not block when <see cref="Read"/> is + /// called, <c>false</c> if unknown or blocking will occur. + /// </returns> + public override bool Ready() { - get + lock (m_lock) { - return true; + EnsureOpen(); + return ((end - pos) > 0) /*|| in.ready()*/; } } /// <summary> - /// Marks the present position in the stream. Subsequent calls to reset() will attempt to reposition the stream to this point. + /// Resets this reader's position to the last <see cref="Mark(int)"/> location. + /// Invocations of <see cref="Read()"/> and <see cref="Skip(int)"/> will occur from this new + /// location. /// </summary> - /// <param name="readAheadLimit">Limit on the number of characters that may be read while still preserving the mark. An attempt - /// to reset the stream after reading characters up to this limit or beyond may fail. A limit value larger than the size of the - /// input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be - /// used with care.</param> - public override void Mark(int readAheadLimit) + /// <exception cref="IOException">If this reader is disposed or no mark has been set.</exception> + /// <seealso cref="Mark(int)"/> + /// <seealso cref="IsMarkSupported"/> + public override void Reset() { - if (readAheadLimit < 0) - { - throw new ArgumentOutOfRangeException("Read-ahead limit < 0"); - } - lock (this) + lock (m_lock) { EnsureOpen(); - this.readAheadLimit = readAheadLimit; - markedChar = nextChar; - markedSkipLF = skipLF; + if (mark < 0) + { + throw new IOException("Reader not marked"); + } + pos = mark; } } /// <summary> - /// Resets the stream to the most recent mark. + /// Skips <paramref name="amount"/> characters in this reader. Subsequent + /// <see cref="Read()"/>s will not return these characters unless <see cref="Reset()"/> + /// is used. Skipping characters may invalidate a mark if <see cref="markLimit"/> + /// is surpassed. /// </summary> - /// <exception cref="IOException">If the stream has never been marked, or if the mark has been invalidated</exception> - public override void Reset() + /// <param name="amount">the maximum number of characters to skip.</param> + /// <returns>the number of characters actually skipped.</returns> + /// <exception cref="ArgumentOutOfRangeException">if <c>amount < 0</c>.</exception> + /// <exception cref="IOException">If this reader is disposed or some other I/O error occurs.</exception> + /// <seealso cref="Mark(int)"/> + /// <seealso cref="IsMarkSupported"/> + /// <seealso cref="Reset()"/> + public override long Skip(int amount) { - lock (this) + if (amount < 0L) { - EnsureOpen(); - if (markedChar < 0) - throw new IOException((markedChar == INVALIDATED) ? "Mark invalid" : "Stream not marked"); - nextChar = markedChar; - skipLF = markedSkipLF; + throw new ArgumentOutOfRangeException("skip value is negative"); } - } - - protected override void Dispose(bool disposing) - { - if (disposing) + lock (m_lock) { -#if !NETSTANDARD - this.isDisposing = true; -#endif - lock (this) + EnsureOpen(); + if (amount < 1) + { + return 0; + } + if (end - pos >= amount) + { + pos += amount; + return amount; + } + + int read = end - pos; + pos = end; + while (read < amount) { - if (@in != null) + if (FillBuf() == -1) { - @in.Dispose(); - @in = null; + return read; } - cb = null; + if (end - pos >= amount - read) + { + pos += amount - read; + return amount; + } + // Couldn't get all the characters, skip what we read + read += (end - pos); + pos = end; } -#if !NETSTANDARD - this.isDisposing = false; -#endif + return amount; } } @@ -511,8 +607,11 @@ namespace Lucene.Net.Analysis.Util { throw new NotImplementedException(); } - #if !NETSTANDARD + public override object InitializeLifetimeService() + { + throw new NotImplementedException(); + } public override void Close() { @@ -521,12 +620,7 @@ namespace Lucene.Net.Analysis.Util throw new NotSupportedException("Close() is not supported. Call Dispose() instead."); } } - - public override object InitializeLifetimeService() - { - throw new NotImplementedException(); - } #endif -#endregion + #endregion } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs b/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs index 9fd0444..c0f2462 100644 --- a/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs +++ b/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs @@ -282,7 +282,7 @@ namespace Lucene.Net public static int read(this TextReader reader, char[] buffer) { - int bytesRead = reader.Read(buffer, 0, buffer.Length - 1); + int bytesRead = reader.Read(buffer, 0, buffer.Length); // Convert the .NET 0 based bytes to the Java -1 behavior when reading is done. return bytesRead == 0 ? -1 : bytesRead; } http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestBufferedCharFilter.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestBufferedCharFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestBufferedCharFilter.cs new file mode 100644 index 0000000..887a7df --- /dev/null +++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestBufferedCharFilter.cs @@ -0,0 +1,816 @@ +// This class was sourced from the Apache Harmony project + +using Lucene.Net.Attributes; +using Lucene.Net.Util; +using NUnit.Framework; +using System; +using System.IO; + +namespace Lucene.Net.Analysis.Util +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + public class TestBufferedCharFilter : LuceneTestCase + { + BufferedCharFilter br; + + String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_Class NotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTes t_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_j ava_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n"; + + /** + * The spec says that BufferedReader.readLine() considers only "\r", "\n" + * and "\r\n" to be line separators. We must not permit additional separator + * characters. + */ + [Test, LuceneNetSpecific] + public void Test_ReadLine_IgnoresEbcdic85Characters() + { + assertLines("A\u0085B", "A\u0085B"); + } + + [Test, LuceneNetSpecific] + public void Test_ReadLine_Separators() + { + assertLines("A\nB\nC", "A", "B", "C"); + assertLines("A\rB\rC", "A", "B", "C"); + assertLines("A\r\nB\r\nC", "A", "B", "C"); + assertLines("A\n\rB\n\rC", "A", "", "B", "", "C"); + assertLines("A\n\nB\n\nC", "A", "", "B", "", "C"); + assertLines("A\r\rB\r\rC", "A", "", "B", "", "C"); + assertLines("A\n\n", "A", ""); + assertLines("A\n\r", "A", ""); + assertLines("A\r\r", "A", ""); + assertLines("A\r\n", "A"); + assertLines("A\r\n\r\n", "A", ""); + } + + private void assertLines(string @in, params string[] lines) + { + BufferedCharFilter bufferedReader + = new BufferedCharFilter(new StringReader(@in)); + foreach (String line in lines) + { + assertEquals(line, bufferedReader.ReadLine()); + } + assertNull(bufferedReader.ReadLine()); + } + + /** + * @tests java.io.BufferedReader#BufferedReader(java.io.Reader) + */ + [Test, LuceneNetSpecific] + public void Test_ConstructorLjava_io_Reader() + { + // Test for method java.io.BufferedReader(java.io.Reader) + assertTrue("Used in tests", true); + } + + /** + * @tests java.io.BufferedReader#BufferedReader(java.io.Reader, int) + */ + [Test, LuceneNetSpecific] + public void Test_ConstructorLjava_io_ReaderI() + { + // Test for method java.io.BufferedReader(java.io.Reader, int) + assertTrue("Used in tests", true); + } + + /** + * @tests java.io.BufferedReader#close() + */ + [Test, LuceneNetSpecific] + public void Test_Close() + { + // Test for method void java.io.BufferedReader.close() + try + { + br = new BufferedCharFilter(new StringReader(testString)); + br.Dispose(); + br.Read(); + fail("Read on closed stream"); + } + catch (IOException x) + { + return; + } + } + + /** + * @tests java.io.BufferedReader#mark(int) + */ + [Test, LuceneNetSpecific] + public void Test_MarkI() + { + // Test for method void java.io.BufferedReader.mark(int) + char[] buf = null; + br = new BufferedCharFilter(new StringReader(testString)); + br.Skip(500); + br.Mark(1000); + br.Skip(250); + br.Reset(); + buf = new char[testString.Length]; + br.Read(buf, 0, 500); + + assertTrue("Failed to set mark properly", testString.Substring(500, + 1000 - 500).equals(new string(buf, 0, 500))); + + try + { + br = new BufferedCharFilter(new StringReader(testString), 800); + br.Skip(500); + br.Mark(250); + br.Read(buf, 0, 1000); + br.Reset(); + + fail("Failed to invalidate mark properly"); + } + catch (IOException x) + { + // Expected + } + + char[] chars = new char[256]; + for (int i = 0; i < 256; i++) + chars[i] = (char)i; + BufferedCharFilter @in = new BufferedCharFilter(new StringReader(new String( + chars)), 12); + + @in.Skip(6); + @in.Mark(14); + @in.Read(new char[14], 0, 14); + @in.Reset(); + + assertTrue("Wrong chars", @in.Read() == (char)6 + && @in.Read() == (char)7); + + @in = new BufferedCharFilter(new StringReader(new String(chars)), 12); + @in.Skip(6); + @in.Mark(8); + @in.Skip(7); + @in.Reset(); + + assertTrue("Wrong chars 2", @in.Read() == (char)6 + && @in.Read() == (char)7); + + BufferedCharFilter br2 = new BufferedCharFilter(new StringReader("01234"), 2); + br2.Mark(3); + char[] carray = new char[3]; + int result = br2.read(carray); + assertEquals(3, result); + assertEquals("Assert 0:", '0', carray[0]); + assertEquals("Assert 1:", '1', carray[1]); + assertEquals("Assert 2:", '2', carray[2]); + assertEquals("Assert 3:", '3', br2.Read()); + + br2 = new BufferedCharFilter(new StringReader("01234"), 2); + br2.Mark(3); + carray = new char[4]; + result = br2.read(carray); + assertEquals("Assert 4:", 4, result); + assertEquals("Assert 5:", '0', carray[0]); + assertEquals("Assert 6:", '1', carray[1]); + assertEquals("Assert 7:", '2', carray[2]); + assertEquals("Assert 8:", '3', carray[3]); + assertEquals("Assert 9:", '4', br2.Read()); + assertEquals("Assert 10:", -1, br2.Read()); + + BufferedCharFilter reader = new BufferedCharFilter(new StringReader("01234")); + reader.Mark(int.MaxValue); + reader.Read(); + reader.Dispose(); + } + + /** + * @tests java.io.BufferedReader#markSupported() + */ + [Test, LuceneNetSpecific] + public void Test_IsMarkSupported() + { + // Test for method boolean java.io.BufferedReader.markSupported() + br = new BufferedCharFilter(new StringReader(testString)); + assertTrue("markSupported returned false", br.IsMarkSupported); + } + + /** + * @tests java.io.BufferedReader#read() + */ + [Test, LuceneNetSpecific] + public void Test_Read() + { + // Test for method int java.io.BufferedReader.read() + try + { + br = new BufferedCharFilter(new StringReader(testString)); + int r = br.Read(); + assertTrue("Char read improperly", testString[0] == r); + br = new BufferedCharFilter(new StringReader(new String( + new char[] { '\u8765' }))); + assertTrue("Wrong double byte character", br.Read() == '\u8765'); + } + catch (IOException e) + { + fail("Exception during read test"); + } + + char[] chars = new char[256]; + for (int i = 0; i < 256; i++) + chars[i] = (char)i; + BufferedCharFilter @in = new BufferedCharFilter(new StringReader(new String( + chars)), 12); + try + { + + assertEquals("Wrong initial char", 0, @in.Read()); // Fill the + // buffer + char[] buf = new char[14]; + @in.Read(buf, 0, 14); // Read greater than the buffer + + assertTrue("Wrong block read data", new String(buf) + .equals(new String(chars, 1, 14))); + + assertEquals("Wrong chars", 15, @in.Read()); // Check next byte + } + catch (IOException e) + { + + fail("Exception during read test 2:" + e); + } + + // regression test for HARMONY-841 + assertTrue(new BufferedCharFilter(new StringReader(new string(new char[5], 1, 0)), 2).Read() == -1); + } + + private class ReaderAnonymousInnerClassHelper : TextReader + { + private const int SIZE = 2; + private int size = SIZE, pos = 0; + + private readonly char[] contents = new char[SIZE]; + + public override int Read() + { + if (pos >= size) + throw new IOException("Read past end of data"); + return contents[pos++]; + } + + public override int Read(char[] buf, int off, int len) + { + if (pos >= size) + throw new IOException("Read past end of data"); + int toRead = len; + if (toRead > (size - pos)) + toRead = size - pos; + System.Array.Copy(contents, pos, buf, off, toRead); + pos += toRead; + return toRead; + } + + public bool Ready() + { + return size - pos > 0; + } + +#if !NETSTANDARD + public override void Close() + { + } +#endif + + protected override void Dispose(bool disposing) + { + } + } + + /** + * @tests java.io.BufferedReader#read(char[], int, int) + */ + [Test, LuceneNetSpecific] + public void Test_ReadCII() + { + char[] ca = new char[2]; + BufferedCharFilter toRet = new BufferedCharFilter(new StreamReader( + new MemoryStream(new byte[0]))); + + /* Null buffer should throw NPE even when len == 0 */ + try + { + toRet.Read(null, 1, 0); + + fail("null buffer reading zero bytes should throw NPE"); + } + catch (NullReferenceException e) + { + //expected + } + + try + { + toRet.Dispose(); + } + catch (IOException e) + { + + fail("unexpected 1: " + e); + } + + try + { + toRet.Read(null, 1, 0); + + fail("null buffer reading zero bytes on closed stream should throw IOException"); + } + catch (IOException e) + { + //expected + } + + /* Closed reader should throw IOException reading zero bytes */ + try + { + toRet.Read(ca, 0, 0); + + fail("Reading zero bytes on a closed reader should not work"); + } + catch (IOException e) + { + // expected + } + + /* + * Closed reader should throw IOException in preference to index out of + * bounds + */ + try + { + // Read should throw IOException before + // ArrayIndexOutOfBoundException + toRet.Read(ca, 1, 5); + + fail("IOException should have been thrown"); + } + catch (IOException e) + { + // expected + } + + // Test to ensure that a drained stream returns 0 at EOF + toRet = new BufferedCharFilter(new StreamReader( + + new MemoryStream(new byte[2]))); + try + { + + assertEquals("Emptying the reader should return two bytes", 2, + toRet.Read(ca, 0, 2)); + + // LUCENENET specific: end of stream should be 0 in .NET + assertEquals("EOF on a reader should be 0", 0, toRet.Read(ca, 0, + 2)); + //assertEquals("EOF on a reader should be -1", -1, toRet.Read(ca, 0, + // 2)); + + assertEquals("Reading zero bytes at EOF should work", 0, toRet + .Read(ca, 0, 0)); + } + catch (IOException ex) + { + + fail("Unexpected IOException : " + ex.ToString()); + } + + // Test for method int java.io.BufferedReader.read(char [], int, int) + try + { + char[] buf = new char[testString.Length]; + br = new BufferedCharFilter(new StringReader(testString)); + br.Read(buf, 50, 500); + + assertTrue("Chars read improperly", new String(buf, 50, 500) + .equals(testString.Substring(0, 500 - 0))); + } + catch (IOException e) + { + + fail("Exception during read test"); + } + + BufferedCharFilter bufin = new BufferedCharFilter(new ReaderAnonymousInnerClassHelper()); + + //BufferedCharFilter bufin = new BufferedCharFilter(new Reader() { + // int size = 2, pos = 0; + + //char[] contents = new char[size]; + + //public int read() + //{ + // if (pos >= size) + // throw new IOException("Read past end of data"); + // return contents[pos++]; + // } + + // public int read(char[] buf, int off, int len) throws IOException + //{ + // if (pos >= size) + // throw new IOException("Read past end of data"); + //int toRead = len; + // if (toRead > (size - pos)) + // toRead = size - pos; + // System.arraycopy(contents, pos, buf, off, toRead); + // pos += toRead; + // return toRead; + // } + + // public boolean ready() throws IOException + //{ + // return size - pos > 0; + //} + + //public void close() + //{ + //} + // }); + try + { + bufin.Read(); + int result = bufin.Read(new char[2], 0, 2); + + assertTrue("Incorrect result: " + result, result == 1); + } + catch (IOException e) + { + + fail("Unexpected: " + e); + } + + //regression for HARMONY-831 + try + { + new BufferedCharFilter(new StringReader(""), 9).Read(new char[] { }, 7, 0); + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + } + + // Regression for HARMONY-54 + char[] ch = { }; + BufferedCharFilter reader = new BufferedCharFilter(new StringReader(new string(ch))); + try + { + // Check exception thrown when the reader is open. + reader.Read(null, 1, 0); + fail("Assert 0: NullPointerException expected"); + } + catch (NullReferenceException e) + { + // Expected + } + + // Now check IOException is thrown in preference to + // NullPointerexception when the reader is closed. + reader.Dispose(); + try + { + reader.Read(null, 1, 0); + fail("Assert 1: IOException expected"); + } + catch (IOException e) + { + // Expected + } + + try + { + // And check that the IOException is thrown before + // ArrayIndexOutOfBoundException + reader.Read(ch, 0, 42); + fail("Assert 2: IOException expected"); + } + catch (IOException e) + { + // expected + } + } + + /** + * @tests java.io.BufferedReader#read(char[], int, int) + */ + [Test, LuceneNetSpecific] + public void Test_Read_CII_Exception() + { + br = new BufferedCharFilter(new StringReader(testString)); + char[] nullCharArray = null; + char[] charArray = testString.toCharArray(); + + try + { + br.Read(nullCharArray, -1, -1); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + // expected + } + + try + { + br.Read(nullCharArray, -1, 0); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + // expected + } + + try + { + br.Read(nullCharArray, 0, -1); + + fail("should throw NullPointerException"); + } + catch (NullReferenceException e) + { + // expected + } + + try + { + br.Read(nullCharArray, 0, 0); + + fail("should throw NullPointerException"); + } + catch (NullReferenceException e) + { + // expected + } + + try + { + br.Read(nullCharArray, 0, 1); + + fail("should throw NullPointerException"); + } + catch (NullReferenceException e) + { + // expected + } + + try + { + br.Read(charArray, -1, -1); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + // expected + } + + try + { + br.Read(charArray, -1, 0); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + // expected + } + + br.Read(charArray, 0, 0); + br.Read(charArray, 0, charArray.Length); + br.Read(charArray, charArray.Length, 0); + + try + { + br.Read(charArray, charArray.Length + 1, 0); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + //expected + } + + try + { + br.Read(charArray, charArray.Length + 1, 1); + + fail("should throw IndexOutOfBoundsException"); + } + catch (ArgumentOutOfRangeException e) + { + //expected + } + + br.Dispose(); + + try + { + br.Read(nullCharArray, -1, -1); + + fail("should throw IOException"); + } + catch (IOException e) + { + // expected + } + + try + { + br.Read(charArray, -1, 0); + + fail("should throw IOException"); + } + catch (IOException e) + { + // expected + } + + try + { + br.Read(charArray, 0, -1); + + fail("should throw IOException"); + } + catch (IOException e) + { + // expected + } + } + /** + * @tests java.io.BufferedReader#readLine() + */ + [Test, LuceneNetSpecific] + public void Test_ReadLine() + { + // Test for method java.lang.String java.io.BufferedReader.readLine() + try + { + br = new BufferedCharFilter(new StringReader(testString)); + String r = br.ReadLine(); + assertEquals("readLine returned incorrect string", "Test_All_Tests", r + ); + } + catch (IOException e) + { + fail("Exception during readLine test"); + } + } + + /** + * @tests java.io.BufferedReader#ready() + */ + public void Test_Ready() + { + // Test for method boolean java.io.BufferedReader.ready() + try + { + br = new BufferedCharFilter(new StringReader(testString)); + assertTrue("ready returned false", br.Ready()); + } + catch (IOException e) + { + fail("Exception during ready test" + e.toString()); + } + } + + /** + * @tests java.io.BufferedReader#reset() + */ + public void Test_Reset() + { + // Test for method void java.io.BufferedReader.reset() + try + { + br = new BufferedCharFilter(new StringReader(testString)); + br.Skip(500); + br.Mark(900); + br.Skip(500); + br.Reset(); + char[] buf = new char[testString.Length]; + br.Read(buf, 0, 500); + assertTrue("Failed to reset properly", testString.Substring(500, + 1000 - 500).equals(new String(buf, 0, 500))); + } + catch (IOException e) + { + fail("Exception during reset test"); + } + try + { + br = new BufferedCharFilter(new StringReader(testString)); + br.Skip(500); + br.Reset(); + fail("Reset succeeded on unmarked stream"); + } + catch (IOException x) + { + return; + + } + } + + [Test, LuceneNetSpecific] + public void Test_Reset_IOException() + { + int[] + expected = new int[] { '1', '2', '3', '4', '5', '6', '7', '8', + '9', '0', -1 }; + br = new BufferedCharFilter(new StringReader("1234567890"), 9); + br.Mark(9); + for (int i = 0; i < 11; i++) + { + assertEquals(expected[i], br.Read()); + } + try + { + br.Reset(); + fail("should throw IOException"); + } + catch (IOException e) + { + // Expected + } + for (int i = 0; i < 11; i++) + { + assertEquals(-1, br.Read()); + } + + br = new BufferedCharFilter(new StringReader("1234567890")); + br.Mark(10); + for (int i = 0; i < 10; i++) + { + assertEquals(expected[i], br.Read()); + } + br.Reset(); + for (int i = 0; i < 11; i++) + { + assertEquals(expected[i], br.Read()); + } + } + + /** + * @tests java.io.BufferedReader#skip(long) + */ + [Test, LuceneNetSpecific] + public void Test_SkipJ() + { + // Test for method long java.io.BufferedReader.skip(long) + try + { + br = new BufferedCharFilter(new StringReader(testString)); + br.Skip(500); + char[] buf = new char[testString.Length]; + br.Read(buf, 0, 500); + assertTrue("Failed to set skip properly", testString.Substring(500, + 1000 - 500).equals(new String(buf, 0, 500))); + } + catch (IOException e) + { + fail("Exception during skip test"); + } + + } + + /** + * Sets up the fixture, for example, open a network connection. This method + * is called before a test is executed. + */ + public override void SetUp() + { + } + + /** + * Tears down the fixture, for example, close a network connection. This + * method is called after a test is executed. + */ + public override void TearDown() + { + try + { + br.Dispose(); + } + catch (Exception e) + { + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f3ac940c/src/Lucene.Net.Tests.Analysis.Common/Lucene.Net.Tests.Analysis.Common.csproj ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests.Analysis.Common/Lucene.Net.Tests.Analysis.Common.csproj b/src/Lucene.Net.Tests.Analysis.Common/Lucene.Net.Tests.Analysis.Common.csproj index 06ff0c5..0c6f911 100644 --- a/src/Lucene.Net.Tests.Analysis.Common/Lucene.Net.Tests.Analysis.Common.csproj +++ b/src/Lucene.Net.Tests.Analysis.Common/Lucene.Net.Tests.Analysis.Common.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,6 @@ under the License. --> - <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <PropertyGroup> @@ -322,6 +321,7 @@ <Compile Include="Analysis\Util\BaseTokenStreamFactoryTestCase.cs" /> <Compile Include="Analysis\Util\StringMockResourceLoader.cs" /> <Compile Include="Analysis\Util\TestAnalysisSPILoader.cs" /> + <Compile Include="Analysis\Util\TestBufferedCharFilter.cs" /> <Compile Include="Analysis\Util\TestCharacterUtils.cs" /> <Compile Include="Analysis\Util\TestCharArrayIterator.cs" /> <Compile Include="Analysis\Util\TestCharArrayMap.cs" /> @@ -487,4 +487,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> +</Project> \ No newline at end of file
