first few types implemented

This commit is contained in:
David Vennik
2023-09-13 11:37:39 +01:00
parent fe323179e8
commit bfe176c5a9
4 changed files with 107 additions and 10 deletions

View File

@@ -18,6 +18,8 @@ func New() *S { return &S{b: make([]byte, Len)} }
// //
// The remaining bytes, if any, are returned for further processing. // The remaining bytes, if any, are returned for further processing.
func NewFrom(b []byte) (s *S, rem []byte) { func NewFrom(b []byte) (s *S, rem []byte) {
// If the bytes are less than Len the input is invalid and nil will be
// returned.
if len(b) < Len { if len(b) < Len {
return return
} }
@@ -50,14 +52,20 @@ func (s *S) Write(by []byte) (out []byte) {
func (s *S) Len() int { return len(s.b) } func (s *S) Len() int { return len(s.b) }
func (s *S) Get() (v interface{}) { func (s *S) Get() (v interface{}) {
if len(s.b) >= Len {
val := int32(binary.BigEndian.Uint32(s.b)) val := int32(binary.BigEndian.Uint32(s.b))
return &val return &val
} }
return
}
func (s *S) Put(bits interface{}) interface{} { func (s *S) Put(v interface{}) interface{} {
if len(s.b) < Len {
s.b = make([]byte, Len)
}
var tv *int32 var tv *int32
var ok bool var ok bool
if tv, ok = bits.(*int32); ok { if tv, ok = v.(*int32); ok {
binary.BigEndian.PutUint32(s.b[:Len], uint32(*tv)) binary.BigEndian.PutUint32(s.b[:Len], uint32(*tv))
} }
return s return s

View File

@@ -0,0 +1,82 @@
package magic
const Len = 4
type Bytes struct {
bytes []byte
}
// New allocates bytes to store a new magic.Bytes in. Note that this allocates
// memory.
func New() *Bytes { return &Bytes{bytes: make([]byte, Len)} }
// NewFrom creates a 32-bit integer from raw bytes, if the slice is at least Len
// bytes long. This can be used to snip out an encoded segment which should
// return a value from a call to Get.
//
// The remaining bytes, if any, are returned for further processing.
func NewFrom(b []byte) (s *Bytes, rem []byte) {
if len(b) < Len {
return
}
// This slices the input, meaning no copy is required, only allocating the
// slice pointer.
s = &Bytes{bytes: b[:Len]}
if len(b) > Len {
rem = b[Len:]
}
return
}
func (m Bytes) Len() (l int) { return len(m.bytes) }
func (m Bytes) Read() (o []byte) {
if len(m.bytes) >= Len {
o = m.bytes[:Len]
}
return
}
func (m Bytes) Write(b []byte) (o []byte) {
if len(b) >= Len {
m.bytes = b[:3]
// If there is more, return the excess.
if len(b) > Len {
o = b[Len:]
}
}
return
}
func (m Bytes) Get() (v interface{}) {
if len(m.bytes) >= Len {
val := string(m.bytes[:Len])
v = &val
}
return
}
func (m Bytes) Put(v interface{}) (o interface{}) {
var tv *string
var ok bool
if tv, ok = v.(*string); ok {
bytes := []byte(*tv)
if len(bytes) == Len {
m.bytes = bytes
}
}
return
}
// Assert takes an interface and if it is a duration.Time, returns the time.Time
// value. If it is not the expected type, nil is returned.
func Assert(v interface{}) (t *string) {
var tv *Bytes
var ok bool
if tv, ok = v.(*Bytes); ok {
tt := tv.Get()
// If this fails the return is nil, indicating failure.
t, _ = tt.(*string)
}
return
}

View File

@@ -0,0 +1 @@
package magic

View File

@@ -19,14 +19,14 @@ type Splice interface {
// Len returns the number of bytes used to encode the Splice. This returns // Len returns the number of bytes used to encode the Splice. This returns
// zero if no value has been encoded yet. // zero if no value has been encoded yet.
Len() int Len() (l int)
// Read returns the wire/storage form of the data. // Read returns the wire/storage form of the data.
Read() []byte Read() (o []byte)
// Write stores the decoded data from the head of the slice and returns the // Write stores the decoded data from the head of the slice and returns the
// remainder. If the input bytes are not long enough, abort and return nil. // remainder. If the input bytes are not long enough, abort and return nil.
Write(b []byte) []byte Write(b []byte) (o []byte)
} }
// Accessor is a generic interface, for decoding and encoding runtime forms of // Accessor is a generic interface, for decoding and encoding runtime forms of
@@ -34,11 +34,17 @@ type Splice interface {
// above. // above.
type Accessor interface { type Accessor interface {
// Get returns the decoded value wrapped in an interface{}. // Get returns the decoded value as a pointer wrapped in an interface{}.
Get() (v interface{}) Get() (v interface{})
// Put // Put inserts a pointer to a value that is expected to be the underlying
Put(v interface{}) interface{} // type.
Put(v interface{}) (o interface{})
}
type SpliceAccessor interface {
Splice
Accessor
} }
type Serializers []Splice type Serializers []Splice