aboutsummaryrefslogtreecommitdiff
path: root/stream.go
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2019-06-28 15:41:55 -0400
committerDeterminant <ted.sybil@gmail.com>2019-06-28 15:41:55 -0400
commitea27f0de65f79d7ee56e964f6c966e7c43c66f86 (patch)
tree3a0b868b7c560311b21a5a653d034148817d84c2 /stream.go
parent82153433ebdbe775ac3d7b12668dd222192e8dce (diff)
...
Diffstat (limited to 'stream.go')
-rw-r--r--stream.go138
1 files changed, 104 insertions, 34 deletions
diff --git a/stream.go b/stream.go
index bbc7680..1cbe8ba 100644
--- a/stream.go
+++ b/stream.go
@@ -2,19 +2,45 @@ package salticidae
// #include <stdlib.h>
// #include "salticidae/stream.h"
+// uint16_t _salti_htole16(uint16_t x) { return htole16(x); }
+// uint32_t _salti_htole32(uint32_t x) { return htole32(x); }
+// uint64_t _salti_htole64(uint64_t x) { return htole64(x); }
+//
+// uint16_t _salti_letoh16(uint16_t x) { return le16toh(x); }
+// uint32_t _salti_letoh32(uint32_t x) { return le32toh(x); }
+// uint64_t _salti_letoh64(uint64_t x) { return le64toh(x); }
+//
+// uint16_t _salti_htobe16(uint16_t x) { return htobe16(x); }
+// uint32_t _salti_htobe32(uint32_t x) { return htobe32(x); }
+// uint64_t _salti_htobe64(uint64_t x) { return htobe64(x); }
+//
+// uint16_t _salti_betoh16(uint16_t x) { return be16toh(x); }
+// uint32_t _salti_betoh32(uint32_t x) { return be32toh(x); }
+// uint64_t _salti_betoh64(uint64_t x) { return be64toh(x); }
+//
import "C"
import "runtime"
-type byteArray struct {
- inner *C.bytearray_t
-}
+type CByteArray = *C.bytearray_t
+// The C pointer to a ByteArray object.
+type byteArray struct { inner CByteArray }
// Array of binary data.
type ByteArray = *byteArray
+func ByteArrayFromC(ptr CByteArray) ByteArray {
+ return &byteArray{ inner: ptr }
+}
+
+func byteArraySetFinalizer(res ByteArray) {
+ if res != nil {
+ runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
+ }
+}
+
// Create an empty byte array (with zero contained bytes).
func NewByteArray() ByteArray {
- res := &byteArray{ inner: C.bytearray_new() }
- runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
+ res := ByteArrayFromC(C.bytearray_new())
+ byteArraySetFinalizer(res)
return res
}
@@ -23,19 +49,39 @@ func (self ByteArray) free() { C.bytearray_free(self.inner) }
// Create a byte array by taking out all data from src. Notice this is a
// zero-copy operation that consumes and invalidates the data in src ("move"
// semantics) so that no more operation should be done to src after this
-// function call.
-func NewByteArrayMovedFromDataStream(src DataStream) ByteArray {
- res := &byteArray{ inner: C.bytearray_new_moved_from_datastream(src.inner) }
- runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
- return res
+// function call. Also notice unlike copying, the entire DataStream buffer is
+// moved (including the possibily consumed part).
+func NewByteArrayMovedFromDataStream(src DataStream) (res ByteArray) {
+ res = ByteArrayFromC(C.bytearray_new_moved_from_datastream(src.inner))
+ byteArraySetFinalizer(res)
+ return
+}
+
+// Create a byte array by copying the remaining data from src.
+func NewByteArrayCopiedFromDataStream(src DataStream) (res ByteArray) {
+ res = ByteArrayFromC(C.bytearray_new_copied_from_datastream(src.inner))
+ byteArraySetFinalizer(res)
+ return
}
-func NewByteArrayFromHex(hex string) ByteArray {
+func NewByteArrayFromHex(hex string) (res ByteArray) {
c_str := C.CString(hex)
- res := &byteArray{ inner: C.bytearray_new_from_hex(c_str) }
+ res = ByteArrayFromC(C.bytearray_new_from_hex(c_str))
C.free(rawptr_t(c_str))
- runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
- return res
+ byteArraySetFinalizer(res)
+ return
+}
+
+func NewByteArrayFromBytes(bytes []byte) (res ByteArray) {
+ size := len(bytes)
+ if size > 0 {
+ base := (*C.uint8_t)(&bytes[0])
+ res = ByteArrayFromC(C.bytearray_new_from_bytes(base, C.size_t(size)))
+ } else {
+ res = ByteArrayFromC(C.bytearray_new())
+ }
+ byteArraySetFinalizer(res)
+ return
}
// The C pointer to a DataStream object.
@@ -55,17 +101,17 @@ func DataStreamFromC(ptr CDataStream) DataStream {
}
}
-func dataStreamSetFinalizer(res DataStream) DataStream {
+func dataStreamSetFinalizer(res DataStream) {
if res != nil {
runtime.SetFinalizer(res, func(self DataStream) { self.free() })
}
- return res
}
// Create an empty DataStream.
func NewDataStream() DataStream {
res := DataStreamFromC(C.datastream_new())
- return dataStreamSetFinalizer(res)
+ dataStreamSetFinalizer(res)
+ return res
}
// Create a DataStream with data copied from bytes.
@@ -77,7 +123,8 @@ func NewDataStreamFromBytes(bytes []byte) (res DataStream) {
} else {
res = DataStreamFromC(C.datastream_new())
}
- return dataStreamSetFinalizer(res)
+ dataStreamSetFinalizer(res)
+ return
}
// Create a DataStream with content moved from a ByteArray.
@@ -100,9 +147,10 @@ func (self DataStream) attach(ptr rawptr_t, obj interface{}) { self.attached[uin
func (self DataStream) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) }
// Make a copy of the object.
-func (self DataStream) Copy() DataStream {
- res := DataStreamFromC(C.datastream_copy(self.inner))
- return dataStreamSetFinalizer(res)
+func (self DataStream) Copy() (res DataStream) {
+ res = DataStreamFromC(C.datastream_copy(self.inner))
+ dataStreamSetFinalizer(res)
+ return
}
// TODO: datastream_data
@@ -157,6 +205,23 @@ func (self DataStream) GetI32(succ *bool) int32 { return int32(C.datastream_get_
// Parse an int64 integer by consuming the stream (no byte order conversion).
func (self DataStream) GetI64(succ *bool) int64 { return int64(C.datastream_get_i64(self.inner, (*C.bool)(succ))) }
+func ToLittleEndianU16(x uint16) uint16 { return uint16(C._salti_htole16(C.uint16_t(x))); }
+func ToLittleEndianU32(x uint32) uint32 { return uint32(C._salti_htole32(C.uint32_t(x))); }
+func ToLittleEndianU64(x uint64) uint64 { return uint64(C._salti_htole64(C.uint64_t(x))); }
+
+func FromLittleEndianU16(x uint16) uint16 { return uint16(C._salti_letoh16(C.uint16_t(x))); }
+func FromLittleEndianU32(x uint32) uint32 { return uint32(C._salti_letoh32(C.uint32_t(x))); }
+func FromLittleEndianU64(x uint64) uint64 { return uint64(C._salti_letoh64(C.uint64_t(x))); }
+
+func ToBigEndianU16(x uint16) uint16 { return uint16(C._salti_htobe16(C.uint16_t(x))); }
+func ToBigEndianU32(x uint32) uint32 { return uint32(C._salti_htobe32(C.uint32_t(x))); }
+func ToBigEndianU64(x uint64) uint64 { return uint64(C._salti_htobe64(C.uint64_t(x))); }
+
+func FromBigEndianU16(x uint16) uint16 { return uint16(C._salti_betoh16(C.uint16_t(x))); }
+func FromBigEndianU32(x uint32) uint32 { return uint32(C._salti_betoh32(C.uint32_t(x))); }
+func FromBigEndianU64(x uint64) uint64 { return uint64(C._salti_betoh64(C.uint64_t(x))); }
+
+
// The handle returned by GetDataInPlace. The Go slice returned by Get() is
// valid only during the lifetime of the handle.
type dataStreamBytes struct {
@@ -182,30 +247,35 @@ func (self DataStream) GetDataInPlace(length int) DataStreamBytes {
return res
}
-type uint256 struct {
- inner *C.uint256_t
-}
-
+// The C pointer to a UInt256 object.
+type CUInt256 = *C.uint256_t
+type uint256 struct { inner CUInt256 }
// 256-bit integer.
type UInt256 = *uint256
-// Create a 256-bit integer.
-func NewUInt256() UInt256 {
- res := &uint256{ inner: C.uint256_new() }
- if res != nil {
- runtime.SetFinalizer(res, func(self UInt256) { self.free() })
- }
- return res
+func UInt256FromC(ptr CUInt256) UInt256 {
+ return &uint256{ inner: ptr }
}
-func NewUInt256FromByteArray(bytes ByteArray) UInt256 {
- res := &uint256{ inner: C.uint256_new_from_bytearray(bytes.inner) }
+func uint256SetFinalizer(res UInt256) {
if res != nil {
runtime.SetFinalizer(res, func(self UInt256) { self.free() })
}
+}
+
+// Create a 256-bit integer.
+func NewUInt256() UInt256 {
+ res := &uint256{ inner: C.uint256_new() }
+ uint256SetFinalizer(res)
return res
}
+func NewUInt256FromByteArray(bytes ByteArray) (res UInt256) {
+ res = &uint256{ inner: C.uint256_new_from_bytearray(bytes.inner) }
+ uint256SetFinalizer(res)
+ return
+}
+
func (self UInt256) free() { C.uint256_free(self.inner) }
func (self UInt256) IsNull() bool { return bool(C.uint256_is_null(self.inner)) }