public AppendBytes ( MutableString buffer, int count, bool preserveEndOfLines ) : int | ||
buffer | MutableString | |
count | int | |
preserveEndOfLines | bool | |
return | int |
public int AppendBytes(MutableString/*!*/ buffer, int count, bool preserveEndOfLines) {
ContractUtils.RequiresNotNull(buffer, "buffer");
ContractUtils.Requires(count >= 0, "count");
if (count == 0) {
return 0;
}
bool readAll = count == Int32.MaxValue;
buffer.SwitchToBytes();
int initialBufferSize = buffer.GetByteCount();
if (preserveEndOfLines) {
AppendRawBytes(buffer, count);
} else {
// allocate 3 more bytes at the end for a backstop and possible LF:
byte[] bytes = Utils.EmptyBytes;
int done = initialBufferSize;
bool eof;
do {
AppendRawBytes(buffer, readAll ? 1024 : count);
int end = buffer.GetByteCount();
int bytesRead = end - done;
if (bytesRead == 0) {
break;
}
eof = bytesRead < count;
buffer.EnsureCapacity(end + 3);
int byteCount;
bytes = buffer.GetByteArray(out byteCount);
if (bytes[end - 1] == CR && PeekByte(0) == LF) {
ReadByte();
bytes[end++] = LF;
}
// insert backstop:
bytes[end] = CR;
bytes[end + 1] = LF;
int last = IndexOfCrLf(bytes, done);
count -= last - done;
done = last;
while (last < end) {
int next = IndexOfCrLf(bytes, last + 2);
int chunk = next - last - 1;
Buffer.BlockCopy(bytes, last + 1, bytes, done, chunk);
done += chunk;
count -= chunk;
last = next;
}
buffer.Remove(done);
} while (readAll || count > 0 && !eof);
}
if (readAll) {
buffer.TrimExcess();
}
return buffer.GetByteCount() - initialBufferSize;
}
public void File_AppendBytes1() { string s; string crlf = "\r\n"; var stream = new TestStream(false, B( "ab\r\r\n" + "e" + (s = "fgh" + crlf + "ijkl" + crlf + "mnop" + crlf + crlf + crlf + crlf + "qrst") + crlf + "!" )); int s_crlf_count = 6; var io = new RubyBufferedStream(stream); Assert(io.PeekByte() == (byte)'a'); var buffer = MutableString.CreateBinary(B("foo:")); Assert(io.AppendBytes(buffer, 4, false) == 4); Assert(buffer.ToString() == "foo:ab\r\n"); buffer = MutableString.CreateBinary(); Assert(io.AppendBytes(buffer, 1, false) == 1); Assert(buffer.ToString() == "e"); buffer = MutableString.CreateMutable("x:", RubyEncoding.Binary); int c = s.Length - s_crlf_count - 2; Assert(io.AppendBytes(buffer, c, false) == c); Assert(buffer.ToString() == "x:" + s.Replace(crlf, "\n").Substring(0, c)); buffer = MutableString.CreateBinary(); Assert(io.AppendBytes(buffer, 10, false) == 4); Assert(buffer.ToString() == "st\n!"); buffer = MutableString.CreateBinary(); Assert(io.AppendBytes(buffer, 10, false) == 0); Assert(buffer.ToString() == ""); stream = new TestStream(false, B(s = "abcd" + crlf + "xyz" + crlf + "qqq;")); io = new RubyBufferedStream(stream); buffer = MutableString.CreateBinary(); Assert(io.AppendBytes(buffer, Int32.MaxValue, true) == s.Length); io.BaseStream.Seek(0, SeekOrigin.Begin); Assert(io.AppendBytes(buffer, Int32.MaxValue, false) == s.Length - 2); Assert(buffer.ToString() == s + s.Replace(crlf, "\n")); }