first init
This commit is contained in:
209
encoding.go
Normal file
209
encoding.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package modbus
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
)
|
||||
|
||||
func uint16ToBytes(endianness Endianness, in uint16) (out []byte) {
|
||||
out = make([]byte, 2)
|
||||
switch endianness {
|
||||
case BIG_ENDIAN: binary.BigEndian.PutUint16(out, in)
|
||||
case LITTLE_ENDIAN: binary.LittleEndian.PutUint16(out, in)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func uint16sToBytes(endianness Endianness, in []uint16) (out []byte) {
|
||||
for i := range in {
|
||||
out = append(out, uint16ToBytes(endianness, in[i])...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToUint16(endianness Endianness, in []byte) (out uint16) {
|
||||
switch endianness {
|
||||
case BIG_ENDIAN: out = binary.BigEndian.Uint16(in)
|
||||
case LITTLE_ENDIAN: out = binary.LittleEndian.Uint16(in)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToUint16s(endianness Endianness, in []byte) (out []uint16) {
|
||||
for i := 0; i < len(in); i += 2 {
|
||||
out = append(out, bytesToUint16(endianness, in[i:i+2]))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToUint32s(endianness Endianness, wordOrder WordOrder, in []byte) (out []uint32) {
|
||||
var u32 uint32
|
||||
|
||||
for i := 0; i < len(in); i += 4 {
|
||||
switch endianness {
|
||||
case BIG_ENDIAN:
|
||||
if wordOrder == HIGH_WORD_FIRST {
|
||||
u32 = binary.BigEndian.Uint32(in[i:i+4])
|
||||
} else {
|
||||
u32 = binary.BigEndian.Uint32(
|
||||
[]byte{in[i+2], in[i+3], in[i+0], in[i+1]})
|
||||
}
|
||||
case LITTLE_ENDIAN:
|
||||
if wordOrder == LOW_WORD_FIRST {
|
||||
u32 = binary.LittleEndian.Uint32(in[i:i+4])
|
||||
} else {
|
||||
u32 = binary.LittleEndian.Uint32(
|
||||
[]byte{in[i+2], in[i+3], in[i+0], in[i+1]})
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, u32)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func uint32ToBytes(endianness Endianness, wordOrder WordOrder, in uint32) (out []byte) {
|
||||
out = make([]byte, 4)
|
||||
|
||||
switch endianness {
|
||||
case BIG_ENDIAN:
|
||||
binary.BigEndian.PutUint32(out, in)
|
||||
|
||||
// swap words if needed
|
||||
if wordOrder == LOW_WORD_FIRST {
|
||||
out[0], out[1], out[2], out[3] = out[2], out[3], out[0], out[1]
|
||||
}
|
||||
case LITTLE_ENDIAN:
|
||||
binary.LittleEndian.PutUint32(out, in)
|
||||
|
||||
// swap words if needed
|
||||
if wordOrder == HIGH_WORD_FIRST {
|
||||
out[0], out[1], out[2], out[3] = out[2], out[3], out[0], out[1]
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToFloat32s(endianness Endianness, wordOrder WordOrder, in []byte) (out []float32) {
|
||||
var u32s []uint32
|
||||
|
||||
u32s = bytesToUint32s(endianness, wordOrder, in)
|
||||
|
||||
for _, u32 := range u32s {
|
||||
out = append(out, math.Float32frombits(u32))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func float32ToBytes(endianness Endianness, wordOrder WordOrder, in float32) (out []byte) {
|
||||
out = uint32ToBytes(endianness, wordOrder, math.Float32bits(in))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToUint64s(endianness Endianness, wordOrder WordOrder, in []byte) (out []uint64) {
|
||||
var u64 uint64
|
||||
|
||||
for i := 0; i < len(in); i += 8 {
|
||||
switch endianness {
|
||||
case BIG_ENDIAN:
|
||||
if wordOrder == HIGH_WORD_FIRST {
|
||||
u64 = binary.BigEndian.Uint64(in[i:i+8])
|
||||
} else {
|
||||
u64 = binary.BigEndian.Uint64(
|
||||
[]byte{in[i+6], in[i+7], in[i+4], in[i+5],
|
||||
in[i+2], in[i+3], in[i+0], in[i+1]})
|
||||
}
|
||||
case LITTLE_ENDIAN:
|
||||
if wordOrder == LOW_WORD_FIRST {
|
||||
u64 = binary.LittleEndian.Uint64(in[i:i+8])
|
||||
} else {
|
||||
u64 = binary.LittleEndian.Uint64(
|
||||
[]byte{in[i+6], in[i+7], in[i+4], in[i+5],
|
||||
in[i+2], in[i+3], in[i+0], in[i+1]})
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, u64)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func uint64ToBytes(endianness Endianness, wordOrder WordOrder, in uint64) (out []byte) {
|
||||
out = make([]byte, 8)
|
||||
|
||||
switch endianness {
|
||||
case BIG_ENDIAN:
|
||||
binary.BigEndian.PutUint64(out, in)
|
||||
|
||||
// swap words if needed
|
||||
if wordOrder == LOW_WORD_FIRST {
|
||||
out[0], out[1], out[2], out[3],out[4], out[5], out[6], out[7] =
|
||||
out[6], out[7], out[4], out[5], out[2], out[3], out[0], out[1]
|
||||
}
|
||||
case LITTLE_ENDIAN:
|
||||
binary.LittleEndian.PutUint64(out, in)
|
||||
|
||||
// swap words if needed
|
||||
if wordOrder == HIGH_WORD_FIRST {
|
||||
out[0], out[1], out[2], out[3],out[4], out[5], out[6], out[7] =
|
||||
out[6], out[7], out[4], out[5], out[2], out[3], out[0], out[1]
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bytesToFloat64s(endianness Endianness, wordOrder WordOrder, in []byte) (out []float64) {
|
||||
var u64s []uint64
|
||||
|
||||
u64s = bytesToUint64s(endianness, wordOrder, in)
|
||||
|
||||
for _, u64 := range u64s {
|
||||
out = append(out, math.Float64frombits(u64))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func float64ToBytes(endianness Endianness, wordOrder WordOrder, in float64) (out []byte) {
|
||||
out = uint64ToBytes(endianness, wordOrder, math.Float64bits(in))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func encodeBools(in []bool) (out []byte) {
|
||||
var byteCount uint
|
||||
var i uint
|
||||
|
||||
byteCount = uint(len(in)) / 8
|
||||
if len(in) % 8 != 0 {
|
||||
byteCount++
|
||||
}
|
||||
|
||||
out = make([]byte, byteCount)
|
||||
for i = 0; i < uint(len(in)); i++ {
|
||||
if in[i] {
|
||||
out[i/8] |= (0x01 << (i % 8))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func decodeBools(quantity uint16, in []byte) (out []bool) {
|
||||
var i uint
|
||||
for i = 0; i < uint(quantity); i++ {
|
||||
out = append(out, (((in[i/8] >> (i % 8)) & 0x01) == 0x01))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user