Skip to content

Instantly share code, notes, and snippets.

@volgar1x
Created September 1, 2013 14:10
Show Gist options
  • Save volgar1x/6404681 to your computer and use it in GitHub Desktop.
Save volgar1x/6404681 to your computer and use it in GitHub Desktop.
package backend
import (
"fmt"
"github.com/Blackrush/gofus/protocol"
"io"
"math"
"time"
)
func put(out io.Writer, arg interface{}) {
switch value := arg.(type) {
case []byte:
out.Write(value)
case byte:
out.Write([]byte{value})
case int8:
put(out, byte(value))
case int16:
out.Write([]byte{
byte(value >> 8),
byte(value & 0xff),
})
case uint16:
out.Write([]byte{
byte(value >> 8),
byte(value & 0xff),
})
case int32:
out.Write([]byte{
byte(value >> 24),
byte(value >> 16 & 0xff),
byte(value >> 8 & 0xff),
byte(value & 0xff),
})
case uint32:
out.Write([]byte{
byte(value >> 24),
byte(value >> 16 & 0xff),
byte(value >> 8 & 0xff),
byte(value & 0xff),
})
case int64:
out.Write([]byte{
byte(value >> 56),
byte(value >> 48 & 0xff),
byte(value >> 40 & 0xff),
byte(value >> 32 & 0xff),
byte(value >> 24 & 0xff),
byte(value >> 16 & 0xff),
byte(value >> 8 & 0xff),
byte(value & 0xff),
})
case uint64:
out.Write([]byte{
byte(value >> 56),
byte(value >> 48 & 0xff),
byte(value >> 40 & 0xff),
byte(value >> 32 & 0xff),
byte(value >> 24 & 0xff),
byte(value >> 16 & 0xff),
byte(value >> 8 & 0xff),
byte(value & 0xff),
})
case float32:
put(out, math.Float32bits(value))
case float64:
put(out, math.Float64bits(value))
case string:
put(out, uint32(len(value)))
put(out, []byte(value))
case bool:
if value {
put(out, byte(1))
} else {
put(out, byte(0))
}
case protocol.Serializer:
value.Serialize(out)
case time.Time:
put(out, value.UnixNano())
default:
panic(fmt.Sprintf("can't convert %T to bytes"))
}
}
func read(in io.Reader, arg interface{}) {
switch value := arg.(type) {
case []byte:
in.Read(value)
case *byte:
tmp := []byte{0}
in.Read(tmp)
*value = tmp[0]
case *int8:
tmp := []byte{0}
in.Read(tmp)
*value = int8(tmp[0])
case *int16:
tmp := []byte{0, 0}
in.Read(tmp)
*value = int16(tmp[0])<<8 | int16(tmp[1])
case *uint16:
tmp := []byte{0, 0}
in.Read(tmp)
*value = uint16(tmp[0])<<8 | uint16(tmp[1])
case *int32:
tmp := []byte{0, 0, 0, 0}
in.Read(tmp)
*value = int32(tmp[0])<<24 | int32(tmp[1])<<16 | int32(tmp[2])<<8 | int32(tmp[3])
case *uint32:
tmp := []byte{0, 0, 0, 0}
in.Read(tmp)
*value = uint32(tmp[0])<<24 | uint32(tmp[1])<<16 | uint32(tmp[2])<<8 | uint32(tmp[3])
case *int64:
tmp := []byte{0, 0, 0, 0, 0, 0, 0, 0}
in.Read(tmp)
*value = int64(tmp[0])<<56 | int64(tmp[1])<<48 | int64(tmp[2])<<40 | int64(tmp[3])<<32 | int64(tmp[4])<<24 | int64(tmp[5])<<16 | int64(tmp[6])<<8 | int64(tmp[7])
case *uint64:
tmp := []byte{0, 0, 0, 0, 0, 0, 0, 0}
in.Read(tmp)
*value = uint64(tmp[0])<<56 | uint64(tmp[1])<<48 | uint64(tmp[2])<<40 | uint64(tmp[3])<<32 | uint64(tmp[4])<<24 | uint64(tmp[5])<<16 | uint64(tmp[6])<<8 | uint64(tmp[7])
case *float32:
var tmp uint32
read(in, &tmp)
*value = math.Float32frombits(tmp)
case *float64:
var tmp uint64
read(in, &tmp)
*value = math.Float64frombits(tmp)
case *string:
var tmp uint32
read(in, &tmp)
tmp2 := make([]byte, tmp)
in.Read(tmp2)
*value = string(tmp2)
case *bool:
tmp := []byte{0}
in.Read(tmp)
*value = tmp[0] == 1
case protocol.Deserializer:
value.Deserialize(in)
case *time.Time:
var tmp int64
read(in, &tmp)
*value = time.Unix(0, tmp)
default:
panic(fmt.Sprintf("can't convert %T to bytes"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment