-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathresponse.go
106 lines (89 loc) · 2.41 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package zagent
import (
"bufio"
"encoding/binary"
"io"
"io/ioutil"
"strconv"
"strings"
)
// Response is the response from the zabbix agent.
// Response.Data is generally what most people care
// about. See the wire format here:
// https://www.zabbix.com/documentation/2.2/manual/appendix/items/activepassive
type Response struct {
Header []byte // This should always be: ZBXD\x01
DataLength uint64 // The size of the response
Data []byte // The results of the query
}
// Returns true if the key is supported, false if it wasn't.
func (r *Response) Supported() bool {
return !strings.Contains(r.String(), NotSupported)
}
// Convenience wrapper to return Response.Data as a string.
func (r *Response) String() string {
return string(r.Data)
}
// Convenience wrapper to return Response.Data as a bool.
func (r *Response) Bool() (bool, error) {
return strconv.ParseBool(r.String())
}
// Convenience wrapper to return Response.Data as an int.
func (r *Response) Int() (int, error) {
return strconv.Atoi(r.String())
}
// Convenience wrapper to return Response.Data as an int64.
func (r *Response) Int64() (int64, error) {
return strconv.ParseInt(r.String(), 10, 64)
}
// Convenience wrapper to return Response.Data as an float64.
func (r *Response) Float64() (float64, error) {
return strconv.ParseFloat(r.String(), 64)
}
/*
Convert Response.Data to the most appropriate type. Useful when
you want a concrete type but don't know it ahead of time.
*/
func (r *Response) Interface() interface{} {
// Attempt int64
i, err := strconv.ParseInt(r.String(), 10, 64)
if err == nil {
return i
}
// Attempt float64
f, err := strconv.ParseFloat(r.String(), 64)
if err == nil {
return f
}
// Attempt bool
b, err := strconv.ParseBool(r.String())
if err == nil {
return b
}
return r.String()
}
// Create a new Response type
func newResponse() *Response {
return &Response{
// Header is always 5 bytes
Header: make([]byte, 5),
}
}
func ParseResponse(rd io.Reader) (*Response, error) {
res := newResponse()
dataLength := make([]byte, 8)
reader := bufio.NewReader(rd)
reader.Read(res.Header)
reader.Read(dataLength)
res.Data, _ = ioutil.ReadAll(reader)
// Convert dataLength from binary to uint
var bytesRead int
res.DataLength, bytesRead = binary.Uvarint(dataLength)
if bytesRead <= 0 {
if bytesRead == 0 {
return nil, DataLengthBufferTooSmall
}
return nil, DataLengthOverflow
}
return res, nil
}