83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
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
|
|
}
|