...

Source file src/github.com/jackc/pgtype/varbit.go

Documentation: github.com/jackc/pgtype

     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 // Number of bits
    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  // Scan implements the database/sql Scanner interface.
   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  // Value implements the database/sql/driver Valuer interface.
   131  func (src Varbit) Value() (driver.Value, error) {
   132  	return EncodeValueText(src)
   133  }
   134  

View as plain text