1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,134 @@
# Binary Serializer Plugin
The `binary` data format serializer serializes metrics into binary protocols using
user-specified configurations.
## Configuration
```toml
[[outputs.socket_writer]]
address = "tcp://127.0.0.1:54000"
metric_batch_size = 1
## Data format to consume.
## Each data format has its own unique set of configuration options, read
## more about them here:
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
data_format = "binary"
## Specify the endianness of the data.
## Available values are "little" (little-endian), "big" (big-endian) and "host",
## where "host" means the same endianness as the machine running Telegraf.
# endianness = "host"
## Definition of the message format and the serialized data.
## Please note that you need to define all elements of the data in the
## correct order.
## An entry can have the following properties:
## read_from -- Source of the data.
## Can be "field", "tag", "time" or "name".
## If omitted "field" is assumed.
## name -- Name of the element (e.g. field or tag).
## Can be omitted for "time" and "name".
## data_format -- Target data-type of the entry. Can be "int8/16/32/64", "uint8/16/32/64",
## "float32/64", "string".
## In case of time, this can be any of "unix" (default), "unix_ms", "unix_us",
## "unix_ns".
## If original field type is different from the target type, the field will be converted
## If loss of precision is possible, warning will be logged.
## string_length -- Length of the string in bytes. Only used for "string" type.
## string_terminator -- Terminator for strings. Only used for "string" type.
## Valid values are "null", "0x00", "00", "0x01", etc.
## If original string length is greater than "string_length" the string will
## be truncated to have length of the `string + terminator = string_length`.
## If original string length is smaller than "string_length" the string
## will be padded with terminator to have length of "string_length". (e.g. "abcd\0\0\0\0\0")
## Defaults to "null" for strings.
entries = [
{ read_from = "field", name = "addr_3", data_format="int16" },
{ read_from = "field", name = "addr_2", data_format="int16" },
{ read_from = "field", name = "addr_4_5", data_format="int32" },
{ read_from = "field", name = "addr_6_7", data_format="float32" },
{ read_from = "field", name = "addr_16_20", data_format="string", string_terminator = "null", string_length = 11 },
{ read_from = "field", name = "addr_3_sc", data_format="float64" }
]
```
### General options and remarks
#### Value conversion
The plugin will try to convert the value of the field to the target data type. If the conversion is not possible without precision loss value is converted and warning is logged.
Conversions are allowed between all supported data types.
### Examples
In the following example, we read some registers from a Modbus device and serialize them into a binary protocol.
```toml
# Retrieve data from MODBUS slave devices
[[inputs.modbus]]
name = "device"
slave_id = 1
timeout = "1s"
controller = "tcp://127.0.0.1:5020"
configuration_type = "register"
holding_registers = [
{ name = "addr_2", byte_order = "AB", data_type="UINT16", scale=1.0, address = [2] },
{ name = "addr_3", byte_order = "AB", data_type="UINT16", scale=1.0, address = [3] },
{ name = "addr_4_5", byte_order = "ABCD", data_type="UINT32", scale=1.0, address = [4,5] },
{ name = "addr_6_7", byte_order = "ABCD", data_type="FLOAT32-IEEE", scale=1.0, address = [6,7] },
{ name = "addr_16_20", byte_order = "ABCD", data_type="STRING", address = [16,17,18,19,20] },
{ name = "addr_3_sc", byte_order = "AB", data_type="UFIXED", scale=0.1, address = [3] }
]
[[outputs.socket_writer]]
address = "tcp://127.0.0.1:54000"
metric_batch_size = 1
data_format = "binary"
endianness = "little"
entries = [
{ read_from = "field", name = "addr_3", data_format="int16" },
{ read_from = "field", name = "addr_2", data_format="int16" },
{ read_from = "field", name = "addr_4_5", data_format="int32" },
{ read_from = "field", name = "addr_6_7", data_format="float32" },
{ read_from = "field", name = "addr_16_20", data_format="string", string_terminator = "null", string_length = 11 },
{ read_from = "field", name = "addr_3_sc", data_format="float64" },
{ read_from = "time", data_format="int32", time_format="unix" },
{ read_from = "name", data_format="string", string_terminator = "null", string_length = 20 }
]
```
On the receiving side, we expect the following message structure:
```cpp
#pragma pack(push, 1)
struct test_struct
{
short addr_3;
short addr_2;
int addr_4_5;
float addr_6_7;
char addr_16_20[11];
double addr_3_sc;
int time;
char metric_name[20];
};
#pragma pack(pop)
```
Produced message:
```text
69420700296a0900c395d343415f425f435f445f455f006766666666909a407c0082656d6f646275730000000000000000000000000000
```
| addr_3 | addr_2 | addr_4_5 | addr_6_7 | addr_16_20 | addr_3_sc | time | metric_name |
|--------|--------|----------|-------------------|------------------------|--------------------|------------|--------------------------------------------|
| 0x6942 | 0700 | 296a0900 | c395d343 | 415f425f435f445f455f00 | 6766666666909a40 | 0x7c008265 | 0x6d6f646275730000000000000000000000000000 |
| 17001 | 7 | 617001 | 423.1700134277344 | A_B_C_D_E_ | 1700.1000000000001 | 1703018620 | modbus |

View file

@ -0,0 +1,108 @@
package binary
import (
"encoding/binary"
"fmt"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/serializers"
)
type Serializer struct {
Entries []*Entry `toml:"entries"`
Endianness string `toml:"endianness"`
converter binary.ByteOrder
}
func (s *Serializer) Init() error {
switch s.Endianness {
case "big":
s.converter = binary.BigEndian
case "little":
s.converter = binary.LittleEndian
case "", "host":
s.Endianness = "host"
s.converter = internal.HostEndianness
default:
return fmt.Errorf("invalid endianness %q", s.Endianness)
}
for i, entry := range s.Entries {
if err := entry.fillDefaults(); err != nil {
return fmt.Errorf("entry %d check failed: %w", i, err)
}
}
return nil
}
func (s *Serializer) Serialize(metric telegraf.Metric) ([]byte, error) {
serialized := make([]byte, 0)
for _, entry := range s.Entries {
switch entry.ReadFrom {
case "field":
field, found := metric.GetField(entry.Name)
if !found {
return nil, fmt.Errorf("field %s not found", entry.Name)
}
entryBytes, err := entry.serializeValue(field, s.converter)
if err != nil {
return nil, err
}
serialized = append(serialized, entryBytes...)
case "tag":
tag, found := metric.GetTag(entry.Name)
if !found {
return nil, fmt.Errorf("tag %s not found", entry.Name)
}
entryBytes, err := entry.serializeValue(tag, s.converter)
if err != nil {
return nil, err
}
serialized = append(serialized, entryBytes...)
case "time":
entryBytes, err := entry.serializeValue(metric.Time(), s.converter)
if err != nil {
return nil, err
}
serialized = append(serialized, entryBytes...)
case "name":
entryBytes, err := entry.serializeValue(metric.Name(), s.converter)
if err != nil {
return nil, err
}
serialized = append(serialized, entryBytes...)
}
}
return serialized, nil
}
func (s *Serializer) SerializeBatch(metrics []telegraf.Metric) ([]byte, error) {
serialized := make([]byte, 0)
for _, metric := range metrics {
m, err := s.Serialize(metric)
if err != nil {
return nil, err
}
serialized = append(serialized, m...)
}
return serialized, nil
}
func init() {
serializers.Add("binary",
func() telegraf.Serializer {
return &Serializer{}
},
)
}

View file

@ -0,0 +1,121 @@
package binary
import (
"encoding/hex"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/metric"
)
func TestMetricSerialization(t *testing.T) {
m := metric.New(
"modbus",
map[string]string{
"tag_1": "ABC",
"tag_2": "1.63",
},
map[string]interface{}{
"addr_2": 7,
"addr_3": 17001,
"addr_4_5": 617001,
"addr_6_7": 423.1700134277344,
"addr_16_20": "A_B_C_D_E_",
"addr_3_sc": 1700.1000000000001,
},
time.Unix(1703018620, 0),
)
tests := []struct {
name string
entries []*Entry
expected map[string]string
}{
{
name: "complex metric serialization",
entries: []*Entry{
{
ReadFrom: "field",
Name: "addr_3",
DataFormat: "int16",
},
{
ReadFrom: "field",
Name: "addr_2",
DataFormat: "int16",
},
{
ReadFrom: "field",
Name: "addr_4_5",
DataFormat: "int32",
},
{
ReadFrom: "field",
Name: "addr_6_7",
DataFormat: "float32",
},
{
ReadFrom: "field",
Name: "addr_16_20",
DataFormat: "string",
StringTerminator: "null",
StringLength: 11,
},
{
ReadFrom: "field",
Name: "addr_3_sc",
DataFormat: "float64",
},
{
ReadFrom: "time",
DataFormat: "int32",
TimeFormat: "unix",
},
{
ReadFrom: "name",
DataFormat: "string",
StringTerminator: "null",
StringLength: 20,
},
{
ReadFrom: "tag",
Name: "tag_1",
DataFormat: "string",
StringLength: 4,
},
{
ReadFrom: "tag",
Name: "tag_2",
DataFormat: "float32",
},
},
expected: map[string]string{
"little": "69420700296a0900c395d343415f425f435f445f455f006766666666909a407c" +
"0082656d6f64627573000000000000000000000000000041424300d7a3d03f",
"big": "4269000700096a2943d395c3415f425f435f445f455f00409a90666666666765" +
"82007c6d6f646275730000000000000000000000000000414243003fd0a3d7",
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
for endianness, expected := range tc.expected {
serializer := &Serializer{
Entries: tc.entries,
Endianness: endianness,
}
require.NoError(t, serializer.Init())
serialized, err := serializer.Serialize(m)
actual := hex.EncodeToString(serialized)
require.NoError(t, err)
require.Equal(t, expected, actual)
}
})
}
}

View file

@ -0,0 +1,133 @@
package binary
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"strings"
"time"
)
type converterFunc func(value interface{}, order binary.ByteOrder) ([]byte, error)
type Entry struct {
ReadFrom string `toml:"read_from"` // field, tag, time, name
Name string `toml:"name"` // name of entry
DataFormat string `toml:"data_format"` // int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, string
StringTerminator string `toml:"string_terminator"` // for string metrics: null, 0x00, 00, ....
StringLength uint64 `toml:"string_length"` // for string only, target size
TimeFormat string `toml:"time_format"` // for time metrics: unix, unix_ms, unix_us, unix_ns
converter converterFunc
termination byte
}
func (e *Entry) fillDefaults() error {
// Normalize
e.ReadFrom = strings.ToLower(e.ReadFrom)
// Check input constraints
switch e.ReadFrom {
case "":
e.ReadFrom = "field"
fallthrough
case "field", "tag":
if e.Name == "" {
return errors.New("missing name")
}
case "time":
switch e.TimeFormat {
case "":
e.TimeFormat = "unix"
case "unix", "unix_ms", "unix_us", "unix_ns":
default:
return errors.New("invalid time format")
}
case "name":
if e.DataFormat == "" {
e.DataFormat = "string"
} else if e.DataFormat != "string" {
return errors.New("name data format has to be string")
}
default:
return fmt.Errorf("unknown assignment %q", e.ReadFrom)
}
// Check data format
switch e.DataFormat {
case "":
return errors.New("missing data format")
case "float64":
e.converter = convertToFloat64
case "float32":
e.converter = convertToFloat32
case "uint64":
e.converter = convertToUint64
case "uint32":
e.converter = convertToUint32
case "uint16":
e.converter = convertToUint16
case "uint8":
e.converter = convertToUint8
case "int64":
e.converter = convertToInt64
case "int32":
e.converter = convertToInt32
case "int16":
e.converter = convertToInt16
case "int8":
e.converter = convertToInt8
case "string":
switch e.StringTerminator {
case "", "null":
e.termination = 0x00
default:
e.StringTerminator = strings.TrimPrefix(e.StringTerminator, "0x")
termination, err := hex.DecodeString(e.StringTerminator)
if err != nil {
return fmt.Errorf("decoding terminator failed for %q: %w", e.Name, err)
}
if len(termination) != 1 {
return fmt.Errorf("terminator must be a single byte, got %q", e.StringTerminator)
}
e.termination = termination[0]
}
if e.StringLength < 1 {
return errors.New("string length must be at least 1")
}
e.converter = e.convertToString
default:
return fmt.Errorf("invalid data format %q for field %q", e.ReadFrom, e.DataFormat)
}
return nil
}
func (e *Entry) serializeValue(value interface{}, order binary.ByteOrder) ([]byte, error) {
// Handle normal fields, tags, etc
if e.ReadFrom != "time" {
return e.converter(value, order)
}
// We need to serialize the time, make sure we actually do get a time and
// convert it to the correct timestamp (with scale) first.
t, ok := value.(time.Time)
if !ok {
return nil, fmt.Errorf("time expected but got %T", value)
}
var timestamp int64
switch e.TimeFormat {
case "unix":
timestamp = t.Unix()
case "unix_ms":
timestamp = t.UnixMilli()
case "unix_us":
timestamp = t.UnixMicro()
case "unix_ns":
timestamp = t.UnixNano()
}
return e.converter(timestamp, order)
}

View file

@ -0,0 +1,305 @@
package binary
import (
"encoding/binary"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/internal"
)
func TestSerialization(t *testing.T) {
tests := []struct {
name string
entry *Entry
input interface{}
expected map[binary.ByteOrder][]byte
overflow bool
}{
{
name: "positive int serialization",
entry: &Entry{Name: "test", DataFormat: "int32"},
input: 1,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x00, 0x00, 0x00, 0x01},
binary.LittleEndian: {0x01, 0x00, 0x00, 0x00},
},
},
{
name: "negative int serialization",
entry: &Entry{Name: "test", DataFormat: "int32"},
input: -1,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0xff, 0xff, 0xff, 0xff},
binary.LittleEndian: {0xff, 0xff, 0xff, 0xff},
},
},
{
name: "negative int serialization | uint32 representation",
entry: &Entry{Name: "test", DataFormat: "uint32"},
input: -1,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0xff, 0xff, 0xff, 0xff},
binary.LittleEndian: {0xff, 0xff, 0xff, 0xff},
},
overflow: true,
},
{
name: "uint to int serialization",
entry: &Entry{Name: "test", DataFormat: "uint8"},
input: uint(1),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x01},
binary.LittleEndian: {0x01},
},
},
{
name: "string serialization",
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 4},
input: "test",
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x74, 0x65, 0x73, 0x00},
binary.LittleEndian: {0x74, 0x65, 0x73, 0x00},
},
},
{
name: "string serialization with terminator",
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "null"},
input: "test",
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x74, 0x65, 0x73, 0x74, 0x00},
binary.LittleEndian: {0x74, 0x65, 0x73, 0x74, 0x00},
},
},
{
name: "string serialization with hex terminator",
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "0x01"},
input: "test",
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x74, 0x65, 0x73, 0x74, 0x01},
binary.LittleEndian: {0x74, 0x65, 0x73, 0x74, 0x01},
},
},
{
name: "time serialization",
entry: &Entry{ReadFrom: "time", DataFormat: "uint64"},
input: time.Date(2024, time.January, 6, 19, 44, 10, 0, time.UTC),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x00, 0x00, 0x00, 0x00, 0x65, 0x99, 0xad, 0x8a},
binary.LittleEndian: {0x8a, 0xad, 0x99, 0x65, 0x00, 0x00, 0x00, 0x00},
},
},
{
name: "float32 serialization",
entry: &Entry{Name: "test", DataFormat: "float32"},
input: float32(3.1415),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x40, 0x49, 0x0e, 0x56},
binary.LittleEndian: {0x56, 0x0e, 0x49, 0x40},
},
},
{
name: "float32 serialization | float64 representation",
entry: &Entry{Name: "test", DataFormat: "float64"},
input: float32(3.1415),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x40, 0x09, 0x21, 0xCA, 0xC0, 0x00, 0x00, 0x00},
binary.LittleEndian: {0x00, 0x00, 0x00, 0xC0, 0xCA, 0x21, 0x09, 0x40},
},
},
{
name: "float64 serialization",
entry: &Entry{Name: "test", DataFormat: "float64"},
input: 3.1415,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x40, 0x09, 0x21, 0xCA, 0xC0, 0x83, 0x12, 0x6F},
binary.LittleEndian: {0x6F, 0x12, 0x83, 0xC0, 0xCA, 0x21, 0x09, 0x40},
},
},
{
name: "float64 serialization | float32 representation",
entry: &Entry{Name: "test", DataFormat: "float32"},
input: 3.1415,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x40, 0x49, 0x0e, 0x56},
binary.LittleEndian: {0x56, 0x0e, 0x49, 0x40},
},
},
{
name: "float64 serialization | int64 representation",
entry: &Entry{Name: "test", DataFormat: "int64"},
input: 3.1415,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
binary.LittleEndian: {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
},
{
name: "float64 serialization | uint8 representation",
entry: &Entry{Name: "test", DataFormat: "uint8"},
input: 3.1415,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x03}, binary.LittleEndian: {0x03},
},
},
{
name: "uint serialization | float32 representation",
entry: &Entry{Name: "test", DataFormat: "float32"},
input: uint(1),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x3f, 0x80, 0x00, 0x00},
binary.LittleEndian: {0x00, 0x00, 0x80, 0x3f},
},
},
{
name: "uint serialization | float64 representation",
entry: &Entry{Name: "test", DataFormat: "float64"},
input: uint(1),
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
binary.LittleEndian: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f},
},
},
{
name: "int serialization | float32 representation",
entry: &Entry{Name: "test", DataFormat: "float32"},
input: -101,
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0xc2, 0xca, 0x00, 0x00},
binary.LittleEndian: {0x00, 0x00, 0xca, 0xc2},
},
},
{
name: "string serialization | float32 representation",
entry: &Entry{Name: "test", DataFormat: "float32"},
input: "-101.25",
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0xc2, 0xca, 0x80, 0x00},
binary.LittleEndian: {0x00, 0x80, 0xca, 0xc2},
},
},
{
name: "string serialization | int32 representation",
entry: &Entry{Name: "test", DataFormat: "int32"},
input: "1",
expected: map[binary.ByteOrder][]byte{
binary.BigEndian: {0x00, 0x00, 0x00, 0x01},
binary.LittleEndian: {0x01, 0x00, 0x00, 0x00},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
require.NoError(t, tc.entry.fillDefaults())
for endianness, expected := range tc.expected {
value, err := tc.entry.serializeValue(tc.input, endianness)
if tc.overflow {
require.ErrorIs(t, err, internal.ErrOutOfRange)
} else {
require.NoError(t, err)
}
require.Equal(t, expected, value)
}
})
}
}
func TestNoNameSerialization(t *testing.T) {
e := &Entry{}
require.ErrorContains(t, e.fillDefaults(), "missing name")
}
func BenchmarkSerialization(b *testing.B) {
entries := []struct {
entry *Entry
input interface{}
}{
{
entry: &Entry{Name: "test", DataFormat: "int32"},
input: 1,
},
{
entry: &Entry{Name: "test", DataFormat: "int32"},
input: -1,
},
{
entry: &Entry{Name: "test", DataFormat: "uint8"},
input: uint(1),
},
{
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 4},
input: "test",
},
{
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "null"},
input: "test",
},
{
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "0x01"},
input: "test",
},
{
entry: &Entry{ReadFrom: "time", DataFormat: "uint64"},
input: time.Date(2024, time.January, 6, 19, 44, 10, 0, time.UTC),
},
{
entry: &Entry{Name: "test", DataFormat: "float32"},
input: float32(3.1415),
},
{
entry: &Entry{Name: "test", DataFormat: "float64"},
input: float32(3.1415),
},
{
entry: &Entry{Name: "test", DataFormat: "float64"},
input: 3.1415,
},
{
entry: &Entry{Name: "test", DataFormat: "float32"},
input: 3.1415,
},
{
entry: &Entry{Name: "test", DataFormat: "int64"},
input: 3.1415,
},
{
entry: &Entry{Name: "test", DataFormat: "uint8"},
input: 3.1415,
},
{
entry: &Entry{Name: "test", DataFormat: "float32"},
input: uint(1),
},
{
entry: &Entry{Name: "test", DataFormat: "float64"},
input: uint(1),
},
{
entry: &Entry{Name: "test", DataFormat: "float32"},
input: -101,
},
{
entry: &Entry{Name: "test", DataFormat: "float32"},
input: "-101.25",
},
{
entry: &Entry{Name: "test", DataFormat: "int32"},
input: "1",
},
}
for _, tc := range entries {
require.NoError(b, tc.entry.fillDefaults())
}
for i := 0; i < b.N; i++ {
for _, tc := range entries {
_, err := tc.entry.serializeValue(tc.input, binary.BigEndian)
require.NoError(b, err)
}
}
}

View file

@ -0,0 +1,110 @@
package binary
import (
"encoding/binary"
"math"
"github.com/influxdata/telegraf/internal"
)
func (e *Entry) convertToString(value interface{}, _ binary.ByteOrder) ([]byte, error) {
v, err := internal.ToString(value)
if err != nil {
return nil, err
}
buf := []byte(v)
// If string is longer than target length, truncate it and append terminator.
// Thus, there is one less place for the data so that the terminator can be placed.
if len(buf) >= int(e.StringLength) {
dataLength := int(e.StringLength) - 1
return append(buf[:dataLength], e.termination), nil
}
for i := len(buf); i < int(e.StringLength); i++ {
buf = append(buf, e.termination)
}
return buf, nil
}
func convertToUint64(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 8)
v, err := internal.ToUint64(value)
order.PutUint64(buf, v)
return buf, err
}
func convertToUint32(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 4)
v, err := internal.ToUint32(value)
order.PutUint32(buf, v)
return buf, err
}
func convertToUint16(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 2)
v, err := internal.ToUint16(value)
order.PutUint16(buf, v)
return buf, err
}
func convertToUint8(value interface{}, _ binary.ByteOrder) ([]byte, error) {
v, err := internal.ToUint8(value)
return []byte{v}, err
}
func convertToInt64(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 8)
v, err := internal.ToInt64(value)
order.PutUint64(buf, uint64(v))
return buf, err
}
func convertToInt32(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 4)
v, err := internal.ToInt32(value)
order.PutUint32(buf, uint32(v))
return buf, err
}
func convertToInt16(value interface{}, order binary.ByteOrder) ([]byte, error) {
buf := make([]byte, 2)
v, err := internal.ToInt16(value)
order.PutUint16(buf, uint16(v))
return buf, err
}
func convertToInt8(value interface{}, _ binary.ByteOrder) ([]byte, error) {
v, err := internal.ToInt8(value)
return []byte{uint8(v)}, err
}
func convertToFloat64(value interface{}, order binary.ByteOrder) ([]byte, error) {
v, err := internal.ToFloat64(value)
if err != nil {
return nil, err
}
buf := make([]byte, 8)
x := math.Float64bits(v)
order.PutUint64(buf, x)
return buf, nil
}
func convertToFloat32(value interface{}, order binary.ByteOrder) ([]byte, error) {
v, err := internal.ToFloat32(value)
if err != nil {
return nil, err
}
buf := make([]byte, 4)
x := math.Float32bits(v)
order.PutUint32(buf, x)
return buf, nil
}