1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/binary"
6 "fmt"
7 "math"
8 "strconv"
9 "strings"
10
11 "github.com/jackc/pgio"
12 )
13
14 type Lseg struct {
15 P [2]Vec2
16 Status Status
17 }
18
19 func (dst *Lseg) Set(src interface{}) error {
20 return fmt.Errorf("cannot convert %v to Lseg", src)
21 }
22
23 func (dst Lseg) Get() interface{} {
24 switch dst.Status {
25 case Present:
26 return dst
27 case Null:
28 return nil
29 default:
30 return dst.Status
31 }
32 }
33
34 func (src *Lseg) AssignTo(dst interface{}) error {
35 return fmt.Errorf("cannot assign %v to %T", src, dst)
36 }
37
38 func (dst *Lseg) DecodeText(ci *ConnInfo, src []byte) error {
39 if src == nil {
40 *dst = Lseg{Status: Null}
41 return nil
42 }
43
44 if len(src) < 11 {
45 return fmt.Errorf("invalid length for Lseg: %v", len(src))
46 }
47
48 str := string(src[2:])
49
50 var end int
51 end = strings.IndexByte(str, ',')
52
53 x1, err := strconv.ParseFloat(str[:end], 64)
54 if err != nil {
55 return err
56 }
57
58 str = str[end+1:]
59 end = strings.IndexByte(str, ')')
60
61 y1, err := strconv.ParseFloat(str[:end], 64)
62 if err != nil {
63 return err
64 }
65
66 str = str[end+3:]
67 end = strings.IndexByte(str, ',')
68
69 x2, err := strconv.ParseFloat(str[:end], 64)
70 if err != nil {
71 return err
72 }
73
74 str = str[end+1 : len(str)-2]
75
76 y2, err := strconv.ParseFloat(str, 64)
77 if err != nil {
78 return err
79 }
80
81 *dst = Lseg{P: [2]Vec2{{x1, y1}, {x2, y2}}, Status: Present}
82 return nil
83 }
84
85 func (dst *Lseg) DecodeBinary(ci *ConnInfo, src []byte) error {
86 if src == nil {
87 *dst = Lseg{Status: Null}
88 return nil
89 }
90
91 if len(src) != 32 {
92 return fmt.Errorf("invalid length for Lseg: %v", len(src))
93 }
94
95 x1 := binary.BigEndian.Uint64(src)
96 y1 := binary.BigEndian.Uint64(src[8:])
97 x2 := binary.BigEndian.Uint64(src[16:])
98 y2 := binary.BigEndian.Uint64(src[24:])
99
100 *dst = Lseg{
101 P: [2]Vec2{
102 {math.Float64frombits(x1), math.Float64frombits(y1)},
103 {math.Float64frombits(x2), math.Float64frombits(y2)},
104 },
105 Status: Present,
106 }
107 return nil
108 }
109
110 func (src Lseg) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
111 switch src.Status {
112 case Null:
113 return nil, nil
114 case Undefined:
115 return nil, errUndefined
116 }
117
118 buf = append(buf, fmt.Sprintf(`[(%s,%s),(%s,%s)]`,
119 strconv.FormatFloat(src.P[0].X, 'f', -1, 64),
120 strconv.FormatFloat(src.P[0].Y, 'f', -1, 64),
121 strconv.FormatFloat(src.P[1].X, 'f', -1, 64),
122 strconv.FormatFloat(src.P[1].Y, 'f', -1, 64),
123 )...)
124
125 return buf, nil
126 }
127
128 func (src Lseg) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
129 switch src.Status {
130 case Null:
131 return nil, nil
132 case Undefined:
133 return nil, errUndefined
134 }
135
136 buf = pgio.AppendUint64(buf, math.Float64bits(src.P[0].X))
137 buf = pgio.AppendUint64(buf, math.Float64bits(src.P[0].Y))
138 buf = pgio.AppendUint64(buf, math.Float64bits(src.P[1].X))
139 buf = pgio.AppendUint64(buf, math.Float64bits(src.P[1].Y))
140 return buf, nil
141 }
142
143
144 func (dst *Lseg) Scan(src interface{}) error {
145 if src == nil {
146 *dst = Lseg{Status: Null}
147 return nil
148 }
149
150 switch src := src.(type) {
151 case string:
152 return dst.DecodeText(nil, []byte(src))
153 case []byte:
154 srcCopy := make([]byte, len(src))
155 copy(srcCopy, src)
156 return dst.DecodeText(nil, srcCopy)
157 }
158
159 return fmt.Errorf("cannot scan %T", src)
160 }
161
162
163 func (src Lseg) Value() (driver.Value, error) {
164 return EncodeValueText(src)
165 }
166
View as plain text