Skip to content

Commit

Permalink
Stream File and Code Movement
Browse files Browse the repository at this point in the history
- Moved WriteAt/ReadExactAt/ReadSingle to Strilbrary
- Removed ReadNullTerminatedData
- Removed non-maxLength-variant of ReadNullterminatedString
- Moved PickleStream from WC3.Replay to Library and renamed to Stream Extensions
- Moved ReadNullTerminatedString and WriteNullTerminatedString to Stream Extensions
- Folded the Library/Streams folder into Library
  • Loading branch information
Strilanc committed Feb 10, 2010
1 parent 57de5af commit 4392304
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 321 deletions.
80 changes: 0 additions & 80 deletions Library/Common.vb
Expand Up @@ -293,86 +293,6 @@ Public Module PoorlyCategorizedFunctions
Return arg
End Function

<Extension()>
<ContractVerification(False)>
Public Sub WriteAt(ByVal stream As IRandomWritableStream, ByVal position As Long, ByVal data As IReadableList(Of Byte))
Contract.Requires(stream IsNot Nothing)
Contract.Requires(data IsNot Nothing)
Contract.Requires(position >= 0)
Contract.Requires(position <= stream.Length)
Contract.Ensures(stream.Position = position + data.Count)
stream.Position = position
stream.Write(data)
End Sub

<Extension()>
<ContractVerification(False)>
Public Function ReadExactAt(ByVal stream As IRandomReadableStream, ByVal position As Long, ByVal exactCount As Integer) As IReadableList(Of Byte)
Contract.Requires(stream IsNot Nothing)
Contract.Requires(position >= 0)
Contract.Requires(exactCount > 0)
Contract.Requires(position + exactCount <= stream.Length)
Contract.Ensures(Contract.Result(Of IReadableList(Of Byte))() IsNot Nothing)
Contract.Ensures(Contract.Result(Of IReadableList(Of Byte))().Count = exactCount)
Contract.Ensures(stream.Position = position + exactCount)
stream.Position = position
Return stream.ReadExact(exactCount)
End Function
<Extension()>
Public Sub WriteNullTerminatedString(ByVal bw As IWritableStream, ByVal data As String)
Contract.Requires(bw IsNot Nothing)
Contract.Requires(data IsNot Nothing)
bw.Write(data.ToAscBytes(True).AsReadableList)
End Sub
<Extension()>
<ContractVerification(False)>
Public Function ReadNullTerminatedData(ByVal reader As IReadableStream) As IReadableList(Of Byte)
Contract.Requires(reader IsNot Nothing)
Contract.Ensures(Contract.Result(Of IReadableList(Of Byte))() IsNot Nothing)
Dim result = New List(Of Byte)
Do
Dim b = reader.ReadByte()
If b = 0 Then Exit Do
result.Add(b)
Loop
Return result.AsReadableList
End Function
<Extension()>
Public Function ReadNullTerminatedString(ByVal reader As IReadableStream) As String
Contract.Requires(reader IsNot Nothing)
Contract.Ensures(Contract.Result(Of String)() IsNot Nothing)
Return reader.ReadNullTerminatedData.ParseChrString(nullTerminated:=False)
End Function
'verification disabled due to stupid verifier (1.2.30118.5)
<ContractVerification(False)>
<Extension()>
Public Function ReadNullTerminatedString(ByVal reader As IReadableStream,
ByVal maxLength As Integer) As String
Contract.Requires(reader IsNot Nothing)
Contract.Requires(maxLength >= 0)
Contract.Ensures(Contract.Result(Of String)() IsNot Nothing)
Contract.Ensures(Contract.Result(Of String)().Length <= maxLength)

Dim data = New List(Of Byte)(capacity:=maxLength)
Do
Contract.Assert(data.Count <= maxLength)
Dim b = reader.ReadByte()
If b = 0 Then
Return data.ParseChrString(nullTerminated:=False)
ElseIf data.Count < maxLength Then
data.Add(b)
Else
Throw New IO.InvalidDataException("Null-terminated string exceeded maximum length.")
End If
Loop
End Function

<Extension()>
Public Function ReadSingle(ByVal stream As IReadableStream) As Single
Contract.Requires(stream IsNot Nothing)
Return BitConverter.ToSingle(stream.ReadExact(4).ToArray, 0)
End Function

'''<summary>Determines the SHA-1 hash of a sequence of bytes.</summary>
<Extension()> <Pure()>
Public Function SHA1(ByVal data As IEnumerable(Of Byte)) As IReadableList(Of Byte)
Expand Down
File renamed without changes.
142 changes: 142 additions & 0 deletions Library/Stream Extensions.vb
@@ -0,0 +1,142 @@
Imports Tinker.Pickling

Public Module StreamExtensions
<Extension()>
Public Sub WriteNullTerminatedString(ByVal bw As IWritableStream, ByVal data As String)
Contract.Requires(bw IsNot Nothing)
Contract.Requires(data IsNot Nothing)
bw.Write(data.ToAscBytes(True).AsReadableList)
End Sub
'verification disabled due to stupid verifier (1.2.30118.5)
<ContractVerification(False)>
<Extension()>
Public Function ReadNullTerminatedString(ByVal reader As IReadableStream,
ByVal maxLength As Integer) As String
Contract.Requires(reader IsNot Nothing)
Contract.Requires(maxLength >= 0)
Contract.Ensures(Contract.Result(Of String)() IsNot Nothing)
Contract.Ensures(Contract.Result(Of String)().Length <= maxLength)

Dim data = New List(Of Byte)(capacity:=maxLength)
Do
Contract.Assert(data.Count <= maxLength)
Dim b = reader.ReadByte()
If b = 0 Then
Return data.ParseChrString(nullTerminated:=False)
ElseIf data.Count < maxLength Then
data.Add(b)
Else
Throw New IO.InvalidDataException("Null-terminated string exceeded maximum length.")
End If
Loop
End Function

<DebuggerDisplay("{ToString}")>
Private Class StreamAsList
Inherits FutureDisposable
Implements IReadableList(Of Byte)

Private ReadOnly _stream As IRandomReadableStream
Private ReadOnly _offset As Long
Private ReadOnly _takeOwnershipofStream As Boolean

<ContractInvariantMethod()> Private Sub ObjectInvariant()
Contract.Invariant(_stream IsNot Nothing)
Contract.Invariant(_offset >= 0)
Contract.Invariant(_offset <= _stream.Length)
End Sub

Public Sub New(ByVal stream As IRandomReadableStream,
ByVal offset As Long,
ByVal takeOwnershipOfStream As Boolean)
Contract.Requires(stream IsNot Nothing)
Contract.Requires(offset >= 0)
Contract.Requires(offset <= stream.Length)
Me._stream = stream
Me._offset = offset
Me._takeOwnershipofStream = takeOwnershipOfStream
End Sub

<ContractVerification(False)>
Public Function Contains(ByVal item As Byte) As Boolean Implements IReadableCollection(Of Byte).Contains
Return (From e In Me Where item = e).Any
End Function

Public ReadOnly Property Count As Integer Implements IReadableCollection(Of Byte).Count
Get
Return CInt(_stream.Length - _offset)
End Get
End Property

<ContractVerification(False)>
Public Function IndexOf(ByVal item As Byte) As Integer Implements IReadableList(Of Byte).IndexOf
Return (From i In Enumerable.Range(0, Count)
Where Me(i) = item
Select i + 1
).FirstOrDefault - 1
End Function
Default Public ReadOnly Property Item(ByVal index As Integer) As Byte Implements IReadableList(Of Byte).Item
<ContractVerification(False)>
Get
If Me.FutureDisposed.State <> FutureState.Unknown Then Throw New ObjectDisposedException(Me.GetType.FullName)
Return _stream.ReadExactAt(position:=_offset + index, exactCount:=1)(0)
End Get
End Property

Public Function GetEnumerator() As IEnumerator(Of Byte) Implements IEnumerable(Of Byte).GetEnumerator
Return (From i In Enumerable.Range(0, Count)
Select Item(i)).GetEnumerator
End Function
Private Function GetEnumeratorObj() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return GetEnumerator()
End Function

Public Overrides Function ToString() As String
If Me.Count > 10 Then
Return "[{0}, ...".Frmt(Me.Take(10).StringJoin(", "))
Else
Return "[{0}]".Frmt(Me.StringJoin(", "))
End If
End Function

Protected Overrides Function PerformDispose(ByVal finalizing As Boolean) As IFuture
If _takeOwnershipofStream Then _stream.Dispose()
Return MyBase.PerformDispose(finalizing)
End Function
End Class

<Extension()>
<ContractVerification(False)>
Public Function ReadPickle(Of T)(ByVal stream As IRandomReadableStream, ByVal jar As IParseJar(Of T)) As IPickle(Of T)
Contract.Requires(stream IsNot Nothing)
Contract.Requires(jar IsNot Nothing)
Contract.Ensures(Contract.Result(Of IPickle(Of T))() IsNot Nothing)
Contract.Ensures(stream.Position = Contract.OldValue(stream.Position) + Contract.Result(Of IPickle(Of T)).Data.Count)
Try
Dim oldPosition = stream.Position
Using view = New StreamAsList(stream, oldPosition, takeOwnershipOfStream:=False)
'[first parse: learn needed data]
Dim result = jar.Parse(view)
'[second parse: work with copied data, to avoid accessing the disposed StreamAsList later]
result = jar.Parse(result.Data.ToArray.AsReadableList)
'Place position after used data, as if it had been read normally
stream.Position = oldPosition + result.Data.Count
Return result
End Using
Catch ex As PicklingException
Throw New IO.InvalidDataException(ex.Message, ex)
End Try
End Function

<Extension()>
<ContractVerification(False)>
Public Function WritePickle(Of T)(ByVal stream As IWritableStream, ByVal jar As IPackJar(Of T), ByVal value As T) As IPickle(Of T)
Contract.Requires(stream IsNot Nothing)
Contract.Requires(jar IsNot Nothing)
Contract.Requires(value IsNot Nothing)
Contract.Ensures(Contract.Result(Of IPickle(Of T))() IsNot Nothing)
Dim result = jar.Pack(value)
stream.Write(result.Data)
Return result
End Function
End Module
110 changes: 0 additions & 110 deletions Library/Streams/BottleneckedWriteStream.vb

This file was deleted.

File renamed without changes.
4 changes: 2 additions & 2 deletions Tinker.vbproj
Expand Up @@ -351,8 +351,8 @@
<Compile Include="Pickling\Pickling Interfaces.vb" />
<Compile Include="Pickling\ManualSwitchJar.vb" />
<Compile Include="Pickling\Numeric Jars.vb" />
<Compile Include="Library\Streams\PacketStream.vb" />
<Compile Include="Library\Streams\ThrottledWriteStream.vb" />
<Compile Include="Library\PacketStream.vb" />
<Compile Include="Library\ThrottledWriteStream.vb" />
<Compile Include="Plugins\Plugin Socket.vb" />
<Compile Include="CKL\CKL Server.vb" />
<Compile Include="Warcraft3\Protocol\WC3 Protocol.vb" />
Expand Down

0 comments on commit 4392304

Please sign in to comment.