aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/BufferedReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.World/BufferedReader.cpp')
-rw-r--r--Minecraft.World/BufferedReader.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/Minecraft.World/BufferedReader.cpp b/Minecraft.World/BufferedReader.cpp
new file mode 100644
index 00000000..80345ad0
--- /dev/null
+++ b/Minecraft.World/BufferedReader.cpp
@@ -0,0 +1,173 @@
+#include "stdafx.h"
+
+#include "BufferedReader.h"
+
+//Creates a buffering character-input stream that uses a default-sized input buffer.
+//Parameters:
+//in - A Reader
+BufferedReader::BufferedReader( Reader *in ) : reader( in ), readMark( 0 ), bufferedMark( 0 ), eofReached( false )
+{
+ bufferSize = 64;
+ buffer = new wchar_t[bufferSize];
+ memset( buffer,0,sizeof(wchar_t)*bufferSize);
+ bufferMore();
+}
+
+BufferedReader::~BufferedReader()
+{
+ delete[] buffer;
+}
+
+void BufferedReader::bufferMore()
+{
+ // Don't buffer more unless we are going to read at least twice as much as what is already left
+ if( bufferedMark - readMark > (BUFFER_MORE_AMOUNT / 2) )
+ return;
+
+ if( bufferSize < (bufferedMark + BUFFER_MORE_AMOUNT) )
+ {
+ // Enlarge the buffer
+ wchar_t *temp = new wchar_t[bufferSize * 2];
+ memset( temp,0,sizeof(wchar_t)*bufferSize*2);
+ std::copy( buffer, buffer+bufferSize, temp );
+
+ delete[] buffer;
+ buffer = temp;
+ bufferSize = bufferSize * 2;
+ }
+
+ int value = 0;
+ unsigned int newCharsBuffered = 0;
+ while( newCharsBuffered < BUFFER_MORE_AMOUNT && (value = reader->read() ) != -1 )
+ {
+ buffer[bufferedMark++] = value;
+ newCharsBuffered++;
+ }
+}
+
+//Closes the stream and releases any system resources associated with it. Once the stream has been closed,
+//further read(), ready(), mark(), reset(), or skip() invocations will throw an IOException. Closing a previously closed stream has no effect.
+void BufferedReader::close()
+{
+ reader->close();
+}
+
+//Reads a single character.
+//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
+int BufferedReader::read()
+{
+ // We should have buffered at least as much as we have read
+ assert( bufferedMark >= readMark );
+
+ if( bufferedMark == readMark )
+ {
+ int value = reader->read();
+ if( value == -1 )
+ return -1;
+
+ buffer[bufferedMark++] = value;
+
+ bufferMore();
+ }
+
+ return buffer[readMark++];
+}
+
+//Reads characters into a portion of an array.
+//This method implements the general contract of the corresponding read method of the Reader 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:
+//
+//The specified number of characters have been read,
+//The read method of the underlying stream returns -1, indicating end-of-file, or
+//The ready method of the underlying stream returns false, indicating that further input requests would block.
+//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.
+//
+//Parameters:
+//cbuf - Destination buffer
+//off - Offset at which to start storing characters
+//len - Maximum number of characters to read
+//Returns:
+//The number of characters read, or -1 if the end of the stream has been reached
+int BufferedReader::read(wchar_t cbuf[], unsigned int off, unsigned int len)
+{
+ if( bufferSize < (bufferedMark + len) )
+ {
+ // Enlarge the buffer
+ wchar_t *temp = new wchar_t[bufferSize * 2];
+ memset( temp,0,sizeof(wchar_t)*bufferSize*2);
+ std::copy( buffer, buffer+bufferSize, temp );
+
+ delete[] buffer;
+ buffer = temp;
+ bufferSize = bufferSize * 2;
+ }
+
+ unsigned int charsRead = 0;
+ while( charsRead < len && readMark <= bufferedMark )
+ {
+ cbuf[off + charsRead] = buffer[ readMark++ ];
+ charsRead++;
+ }
+
+ int value = 0;
+ while( charsRead < len && (value = reader->read() ) != -1 )
+ {
+ buffer[bufferedMark++] = value;
+ cbuf[off+charsRead] = value;
+ charsRead++;
+ readMark++;
+ }
+
+ bufferMore();
+
+ return charsRead;
+}
+
+//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.
+//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
+wstring BufferedReader::readLine()
+{
+ wstring output = L"";
+ bool newLineCharFound = false;
+
+ while( readMark < bufferedMark )
+ {
+ wchar_t value = buffer[readMark++];
+
+ if( !newLineCharFound )
+ {
+ if( ( value == '\n') || ( value == '\r') )
+ {
+ newLineCharFound = true;
+ }
+ else
+ {
+ output.push_back(value);
+ }
+ }
+ else
+ {
+ if( ( value != '\n') && ( value != '\r') )
+ {
+ readMark--; // Move back the read mark on char so we get this char again next time
+ break;
+ }
+ }
+
+ // This will only actually read more from the stream if we have less than half of the amount that
+ // will be added left to read
+ bufferMore();
+ }
+ return output;
+} \ No newline at end of file