Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 85 additions & 29 deletions src/absil/bytes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ type ByteMemory () =
type ByteArrayMemory(bytes: byte[], offset, length) =
inherit ByteMemory()

let checkCount count =
if count < 0 then
raise (ArgumentOutOfRangeException("count", "Count is less than zero."))

do
if length < 0 || length > bytes.Length then
raise (ArgumentOutOfRangeException("length"))
Expand All @@ -80,7 +84,11 @@ type ByteArrayMemory(bytes: byte[], offset, length) =
override _.Length = length

override _.ReadBytes(pos, count) =
Array.sub bytes (offset + pos) count
checkCount count
if count > 0 then
Array.sub bytes (offset + pos) count
else
Array.empty

override _.ReadInt32 pos =
let finalOffset = offset + pos
Expand All @@ -96,25 +104,45 @@ type ByteArrayMemory(bytes: byte[], offset, length) =
((uint16 bytes.[finalOffset + 1]) <<< 8)

override _.ReadUtf8String(pos, count) =
System.Text.Encoding.UTF8.GetString(bytes, offset + pos, count)
checkCount count
if count > 0 then
System.Text.Encoding.UTF8.GetString(bytes, offset + pos, count)
else
String.Empty

override _.Slice(pos, count) =
ByteArrayMemory(bytes, offset + pos, count) :> ByteMemory
checkCount count
if count > 0 then
ByteArrayMemory(bytes, offset + pos, count) :> ByteMemory
else
ByteArrayMemory(Array.empty, 0, 0) :> ByteMemory

override _.CopyTo stream =
stream.Write(bytes, offset, length)
if length > 0 then
stream.Write(bytes, offset, length)

override _.Copy(srcOffset, dest, destOffset, count) =
Array.blit bytes (offset + srcOffset) dest destOffset count
checkCount count
if count > 0 then
Array.blit bytes (offset + srcOffset) dest destOffset count

override _.ToArray() =
Array.sub bytes offset length
if length > 0 then
Array.sub bytes offset length
else
Array.empty

override _.AsStream() =
new MemoryStream(bytes, offset, length) :> Stream
if length > 0 then
new MemoryStream(bytes, offset, length) :> Stream
else
new MemoryStream([||], 0, 0, false) :> Stream

override _.AsReadOnlyStream() =
new MemoryStream(bytes, offset, length, false) :> Stream
if length > 0 then
new MemoryStream(bytes, offset, length, false) :> Stream
else
new MemoryStream([||], 0, 0, false) :> Stream

[<Sealed>]
type SafeUnmanagedMemoryStream =
Expand Down Expand Up @@ -149,6 +177,10 @@ type RawByteMemory(addr: nativeptr<byte>, length: int, holder: obj) =
if i < 0 || i >= length then
raise (ArgumentOutOfRangeException("i"))

let checkCount count =
if count < 0 then
raise (ArgumentOutOfRangeException("count", "Count is less than zero."))

do
if length < 0 then
raise (ArgumentOutOfRangeException("length"))
Expand All @@ -165,16 +197,24 @@ type RawByteMemory(addr: nativeptr<byte>, length: int, holder: obj) =
override _.Length = length

override _.ReadUtf8String(pos, count) =
check pos
check (pos + count - 1)
System.Text.Encoding.UTF8.GetString(NativePtr.add addr pos, count)
checkCount count
if count > 0 then
check pos
check (pos + count - 1)
System.Text.Encoding.UTF8.GetString(NativePtr.add addr pos, count)
else
String.Empty

override _.ReadBytes(pos, count) =
check pos
check (pos + count - 1)
let res = Bytes.zeroCreate count
Marshal.Copy(NativePtr.toNativeInt addr + nativeint pos, res, 0, count)
res
override _.ReadBytes(pos, count) =
checkCount count
if count > 0 then
check pos
check (pos + count - 1)
let res = Bytes.zeroCreate count
Marshal.Copy(NativePtr.toNativeInt addr + nativeint pos, res, 0, count)
res
else
Array.empty

override _.ReadInt32 pos =
check pos
Expand All @@ -187,28 +227,44 @@ type RawByteMemory(addr: nativeptr<byte>, length: int, holder: obj) =
uint16(Marshal.ReadInt16(NativePtr.toNativeInt addr + nativeint pos))

override _.Slice(pos, count) =
check pos
check (pos + count - 1)
RawByteMemory(NativePtr.add addr pos, count, holder) :> ByteMemory
checkCount count
if count > 0 then
check pos
check (pos + count - 1)
RawByteMemory(NativePtr.add addr pos, count, holder) :> ByteMemory
else
ByteArrayMemory(Array.empty, 0, 0) :> ByteMemory

override x.CopyTo stream =
use stream2 = x.AsStream()
stream2.CopyTo stream
if length > 0 then
use stream2 = x.AsStream()
stream2.CopyTo stream

override _.Copy(srcOffset, dest, destOffset, count) =
check srcOffset
Marshal.Copy(NativePtr.toNativeInt addr + nativeint srcOffset, dest, destOffset, count)
checkCount count
if count > 0 then
check srcOffset
Marshal.Copy(NativePtr.toNativeInt addr + nativeint srcOffset, dest, destOffset, count)

override _.ToArray() =
let res = Array.zeroCreate<byte> length
Marshal.Copy(NativePtr.toNativeInt addr, res, 0, res.Length)
res
if length > 0 then
let res = Array.zeroCreate<byte> length
Marshal.Copy(NativePtr.toNativeInt addr, res, 0, res.Length)
res
else
Array.empty

override _.AsStream() =
new SafeUnmanagedMemoryStream(addr, int64 length, holder) :> Stream
if length > 0 then
new SafeUnmanagedMemoryStream(addr, int64 length, holder) :> Stream
else
new MemoryStream([||], 0, 0, false) :> Stream

override _.AsReadOnlyStream() =
new SafeUnmanagedMemoryStream(addr, int64 length, int64 length, FileAccess.Read, holder) :> Stream
if length > 0 then
new SafeUnmanagedMemoryStream(addr, int64 length, int64 length, FileAccess.Read, holder) :> Stream
else
new MemoryStream([||], 0, 0, false) :> Stream

[<Struct;NoEquality;NoComparison>]
type ReadOnlyByteMemory(bytes: ByteMemory) =
Expand Down