...

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

Documentation: github.com/jackc/pgtype

     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 Box struct {
    15  	P      [2]Vec2
    16  	Status Status
    17  }
    18  
    19  func (dst *Box) Set(src interface{}) error {
    20  	return fmt.Errorf("cannot convert %v to Box", src)
    21  }
    22  
    23  func (dst Box) 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 *Box) AssignTo(dst interface{}) error {
    35  	return fmt.Errorf("cannot assign %v to %T", src, dst)
    36  }
    37  
    38  func (dst *Box) DecodeText(ci *ConnInfo, src []byte) error {
    39  	if src == nil {
    40  		*dst = Box{Status: Null}
    41  		return nil
    42  	}
    43  
    44  	if len(src) < 11 {
    45  		return fmt.Errorf("invalid length for Box: %v", len(src))
    46  	}
    47  
    48  	str := string(src[1:])
    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)-1]
    75  
    76  	y2, err := strconv.ParseFloat(str, 64)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	*dst = Box{P: [2]Vec2{{x1, y1}, {x2, y2}}, Status: Present}
    82  	return nil
    83  }
    84  
    85  func (dst *Box) DecodeBinary(ci *ConnInfo, src []byte) error {
    86  	if src == nil {
    87  		*dst = Box{Status: Null}
    88  		return nil
    89  	}
    90  
    91  	if len(src) != 32 {
    92  		return fmt.Errorf("invalid length for Box: %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 = Box{
   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 Box) 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  	return buf, nil
   125  }
   126  
   127  func (src Box) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
   128  	switch src.Status {
   129  	case Null:
   130  		return nil, nil
   131  	case Undefined:
   132  		return nil, errUndefined
   133  	}
   134  
   135  	buf = pgio.AppendUint64(buf, math.Float64bits(src.P[0].X))
   136  	buf = pgio.AppendUint64(buf, math.Float64bits(src.P[0].Y))
   137  	buf = pgio.AppendUint64(buf, math.Float64bits(src.P[1].X))
   138  	buf = pgio.AppendUint64(buf, math.Float64bits(src.P[1].Y))
   139  
   140  	return buf, nil
   141  }
   142  
   143  // Scan implements the database/sql Scanner interface.
   144  func (dst *Box) Scan(src interface{}) error {
   145  	if src == nil {
   146  		*dst = Box{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  // Value implements the database/sql/driver Valuer interface.
   163  func (src Box) Value() (driver.Value, error) {
   164  	return EncodeValueText(src)
   165  }
   166  

View as plain text