int m_encoding_max_byte;
byte[] m_buffer;
+
+ Decoder decoder;
+ char [] charBuffer;
+
+ //
+ // 128 chars should cover most strings in one grab.
+ //
+ const int MaxBufferSize = 128;
+
private bool m_disposed = false;
m_stream = input;
m_encoding = encoding;
- m_encoding_max_byte = m_encoding.GetMaxByteCount(1);
+ decoder = encoding.GetDecoder ();
m_buffer = new byte [32];
}
m_buffer = null;
m_encoding = null;
m_stream = null;
+ charBuffer = null;
}
void IDisposable.Dispose()
if (pos!=count) {
byte[] new_buffer=new byte[pos];
- Buffer.BlockCopy (buf, 0, new_buffer, 0, pos);
+ Buffer.BlockCopyInternal (buf, 0, new_buffer, 0, pos);
return(new_buffer);
}
throw new ArgumentOutOfRangeException("count is less than 0");
}
+ if (count == 0)
+ return new char [0];
+
char[] full = new char[count];
int chars = Read(full, 0, count);
* not chars
*/
int len = Read7BitEncodedInt();
+
+ if (len < 0)
+ throw new IOException ("Invalid binary file (string len < 0)");
- FillBuffer(len);
+ if (len == 0)
+ return String.Empty;
+
- char[] str = m_encoding.GetChars(m_buffer, 0, len);
+ if (charBuffer == null)
+ charBuffer = new char [MaxBufferSize];
+
+ //
+ // We read the string here in small chunks. Also, we
+ // Attempt to optimize the common case of short strings.
+ //
+ StringBuilder sb = null;
+ do {
+ int readLen = (len > MaxBufferSize)
+ ? MaxBufferSize
+ : len;
+
+ FillBuffer (readLen);
+
+ int cch = decoder.GetChars (m_buffer, 0, readLen, charBuffer, 0);
+
+ if (sb == null && readLen == len) // ok, we got out the easy way, dont bother with the sb
+ return new String (charBuffer, 0, cch);
+
+ if (sb == null)
+ // Len is a fairly good estimate of the number of chars in a string
+ // Most of the time 1 byte == 1 char
+ sb = new StringBuilder (len);
+
+ sb.Append (charBuffer, 0, cch);
+ len -= readLen;
+ } while (len > 0);
- return(new String(str));
+ return sb.ToString();
}
public virtual float ReadSingle() {
{
if(m_buffer.Length <= length) {
byte[] new_buffer=new byte[length];
- Buffer.BlockCopy (m_buffer, 0, new_buffer, 0, m_buffer.Length);
+ Buffer.BlockCopyInternal (m_buffer, 0, new_buffer, 0, m_buffer.Length);
m_buffer=new_buffer;
}
}