Skip to content

Commit 993517e

Browse files
committed
ReadBuffer implementation (DNET-748, pull#65).
1 parent 786881b commit 993517e

4 files changed

Lines changed: 83 additions & 11 deletions

File tree

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/XdrStream.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
using System.Net;
2424
using System.Text;
2525
using System.Globalization;
26-
using System.Linq;
2726
using FirebirdSql.Data.Common;
2827
using System.Collections.Generic;
2928

@@ -79,7 +78,7 @@ private static byte[] Pad
7978

8079
private long _position;
8180
private List<byte> _outputBuffer;
82-
private List<byte> _inputBuffer;
81+
private ReadBuffer _inputBuffer;
8382
private Ionic.Zlib.ZlibCodec _deflate;
8483
private Ionic.Zlib.ZlibCodec _inflate;
8584
private byte[] _compressionBuffer;
@@ -142,7 +141,7 @@ public XdrStream(Stream innerStream, Charset charset, bool compression, bool own
142141

143142
_position = 0;
144143
_outputBuffer = new List<byte>(PreferredBufferSize);
145-
_inputBuffer = new List<byte>(PreferredBufferSize);
144+
_inputBuffer = new ReadBuffer(PreferredBufferSize);
146145
if (_compression)
147146
{
148147
_deflate = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Compress);
@@ -224,7 +223,7 @@ public override int Read(byte[] buffer, int offset, int count)
224223
CheckDisposed();
225224
EnsureReadable();
226225

227-
if (_inputBuffer.Count < count)
226+
if (_inputBuffer.Length < count)
228227
{
229228
var readBuffer = new byte[PreferredBufferSize];
230229
var read = _innerStream.Read(readBuffer, 0, readBuffer.Length);
@@ -246,14 +245,12 @@ public override int Read(byte[] buffer, int offset, int count)
246245
readBuffer = _compressionBuffer;
247246
read = _inflate.NextOut;
248247
}
249-
_inputBuffer.AddRange(readBuffer.Take(read));
248+
_inputBuffer.AddRange(readBuffer, read);
250249
}
251250
}
252-
var data = _inputBuffer.Take(count).ToArray();
253-
_inputBuffer.RemoveRange(0, data.Length);
254-
Array.Copy(data, 0, buffer, offset, data.Length);
255-
_position += data.Length;
256-
return data.Length;
251+
var dataLength = _inputBuffer.ReadInto(ref buffer, offset, count);
252+
_position += dataLength;
253+
return dataLength;
257254
}
258255

259256
public override void WriteByte(byte value)
@@ -269,7 +266,7 @@ public override void Write(byte[] buffer, int offset, int count)
269266
CheckDisposed();
270267
EnsureWritable();
271268

272-
_outputBuffer.AddRange(buffer.Skip(offset).Take(count));
269+
_outputBuffer.AddRange(new ArraySegment<byte>(buffer, offset, count));
273270
}
274271

275272
public byte[] ToArray()
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Firebird ADO.NET Data provider for .NET and Mono
3+
*
4+
* The contents of this file are subject to the Initial
5+
* Developer's Public License Version 1.0 (the "License");
6+
* you may not use this file except in compliance with the
7+
* License. You may obtain a copy of the License at
8+
* http://www.firebirdsql.org/index.php?op=doc&id=idpl
9+
*
10+
* Software distributed under the License is distributed on
11+
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
12+
* express or implied. See the License for the specific
13+
* language governing rights and limitations under the License.
14+
*
15+
* Copyright (c) 2017 Gerdus van Zyl
16+
* Copyright (c) 2017 Jiri Cincura (jiri@cincura.net)
17+
* All Rights Reserved.
18+
*/
19+
20+
using System;
21+
22+
namespace FirebirdSql.Data.Common
23+
{
24+
class ReadBuffer
25+
{
26+
byte[] _buffer;
27+
int _readPosition;
28+
int _writePosition;
29+
int _length;
30+
31+
public int Length => _length;
32+
33+
public ReadBuffer(int bufferSize)
34+
{
35+
_buffer = new byte[bufferSize];
36+
_readPosition = 0;
37+
_writePosition = 0;
38+
_length = 0;
39+
}
40+
41+
public void AddRange(byte[] source, int count)
42+
{
43+
if ((_length + count) >= _buffer.Length)
44+
{
45+
var newBuffer = new byte[_buffer.Length * 2];
46+
Array.Copy(_buffer, newBuffer, _buffer.Length);
47+
_buffer = newBuffer;
48+
}
49+
for (var i = 0; i < count; i++)
50+
{
51+
if (_writePosition == _buffer.Length)
52+
_writePosition = 0;
53+
_buffer[_writePosition] = source[i];
54+
_writePosition++;
55+
}
56+
_length += count;
57+
}
58+
59+
public int ReadInto(ref byte[] destination, int offset, int count)
60+
{
61+
count = Math.Min(count, Length);
62+
for (var i = 0; i < count; i++)
63+
{
64+
if (_readPosition == _buffer.Length)
65+
_readPosition = 0;
66+
destination[offset + i] = _buffer[_readPosition];
67+
_readPosition++;
68+
}
69+
_length -= count;
70+
return count;
71+
}
72+
}
73+
}

Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient_NET40.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<Compile Include="Common\IscErrorMessages.cs" />
8181
<Compile Include="Common\Marshal2.cs" />
8282
<Compile Include="Common\PageSizeHelper.cs" />
83+
<Compile Include="Common\ReadBuffer.cs" />
8384
<Compile Include="Common\SqlStateMapping.cs" />
8485
<Compile Include="Common\TimeoutHelper.cs" />
8586
<Compile Include="Common\TraceHelper.cs" />

Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient_NET45.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<Compile Include="Common\IscErrorMessages.cs" />
8181
<Compile Include="Common\Marshal2.cs" />
8282
<Compile Include="Common\PageSizeHelper.cs" />
83+
<Compile Include="Common\ReadBuffer.cs" />
8384
<Compile Include="Common\SqlStateMapping.cs" />
8485
<Compile Include="Common\TimeoutHelper.cs" />
8586
<Compile Include="Common\TraceHelper.cs" />

0 commit comments

Comments
 (0)