...
1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/binary"
6 "fmt"
7
8 "github.com/jackc/pgio"
9 )
10
11 type Varbit struct {
12 Bytes []byte
13 Len int32
14 Status Status
15 }
16
17 func (dst *Varbit) Set(src interface{}) error {
18 return fmt.Errorf("cannot convert %v to Varbit", src)
19 }
20
21 func (dst Varbit) Get() interface{} {
22 switch dst.Status {
23 case Present:
24 return dst
25 case Null:
26 return nil
27 default:
28 return dst.Status
29 }
30 }
31
32 func (src *Varbit) AssignTo(dst interface{}) error {
33 return fmt.Errorf("cannot assign %v to %T", src, dst)
34 }
35
36 func (dst *Varbit) DecodeText(ci *ConnInfo, src []byte) error {
37 if src == nil {
38 *dst = Varbit{Status: Null}
39 return nil
40 }
41
42 bitLen := len(src)
43 byteLen := bitLen / 8
44 if bitLen%8 > 0 {
45 byteLen++
46 }
47 buf := make([]byte, byteLen)
48
49 for i, b := range src {
50 if b == '1' {
51 byteIdx := i / 8
52 bitIdx := uint(i % 8)
53 buf[byteIdx] = buf[byteIdx] | (128 >> bitIdx)
54 }
55 }
56
57 *dst = Varbit{Bytes: buf, Len: int32(bitLen), Status: Present}
58 return nil
59 }
60
61 func (dst *Varbit) DecodeBinary(ci *ConnInfo, src []byte) error {
62 if src == nil {
63 *dst = Varbit{Status: Null}
64 return nil
65 }
66
67 if len(src) < 4 {
68 return fmt.Errorf("invalid length for varbit: %v", len(src))
69 }
70
71 bitLen := int32(binary.BigEndian.Uint32(src))
72 rp := 4
73
74 *dst = Varbit{Bytes: src[rp:], Len: bitLen, Status: Present}
75 return nil
76 }
77
78 func (src Varbit) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
79 switch src.Status {
80 case Null:
81 return nil, nil
82 case Undefined:
83 return nil, errUndefined
84 }
85
86 for i := int32(0); i < src.Len; i++ {
87 byteIdx := i / 8
88 bitMask := byte(128 >> byte(i%8))
89 char := byte('0')
90 if src.Bytes[byteIdx]&bitMask > 0 {
91 char = '1'
92 }
93 buf = append(buf, char)
94 }
95
96 return buf, nil
97 }
98
99 func (src Varbit) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
100 switch src.Status {
101 case Null:
102 return nil, nil
103 case Undefined:
104 return nil, errUndefined
105 }
106
107 buf = pgio.AppendInt32(buf, src.Len)
108 return append(buf, src.Bytes...), nil
109 }
110
111
112 func (dst *Varbit) Scan(src interface{}) error {
113 if src == nil {
114 *dst = Varbit{Status: Null}
115 return nil
116 }
117
118 switch src := src.(type) {
119 case string:
120 return dst.DecodeText(nil, []byte(src))
121 case []byte:
122 srcCopy := make([]byte, len(src))
123 copy(srcCopy, src)
124 return dst.DecodeText(nil, srcCopy)
125 }
126
127 return fmt.Errorf("cannot scan %T", src)
128 }
129
130
131 func (src Varbit) Value() (driver.Value, error) {
132 return EncodeValueText(src)
133 }
134
View as plain text