github.com/aavshr/aws-sdk-go@v1.41.3/private/protocol/eventstream/header_value.go (about) 1 package eventstream 2 3 import ( 4 "encoding/base64" 5 "encoding/binary" 6 "fmt" 7 "io" 8 "strconv" 9 "time" 10 ) 11 12 const maxHeaderValueLen = 1<<15 - 1 // 2^15-1 or 32KB - 1 13 14 // valueType is the EventStream header value type. 15 type valueType uint8 16 17 // Header value types 18 const ( 19 trueValueType valueType = iota 20 falseValueType 21 int8ValueType // Byte 22 int16ValueType // Short 23 int32ValueType // Integer 24 int64ValueType // Long 25 bytesValueType 26 stringValueType 27 timestampValueType 28 uuidValueType 29 ) 30 31 func (t valueType) String() string { 32 switch t { 33 case trueValueType: 34 return "bool" 35 case falseValueType: 36 return "bool" 37 case int8ValueType: 38 return "int8" 39 case int16ValueType: 40 return "int16" 41 case int32ValueType: 42 return "int32" 43 case int64ValueType: 44 return "int64" 45 case bytesValueType: 46 return "byte_array" 47 case stringValueType: 48 return "string" 49 case timestampValueType: 50 return "timestamp" 51 case uuidValueType: 52 return "uuid" 53 default: 54 return fmt.Sprintf("unknown value type %d", uint8(t)) 55 } 56 } 57 58 type rawValue struct { 59 Type valueType 60 Len uint16 // Only set for variable length slices 61 Value []byte // byte representation of value, BigEndian encoding. 62 } 63 64 func (r rawValue) encodeScalar(w io.Writer, v interface{}) error { 65 return binaryWriteFields(w, binary.BigEndian, 66 r.Type, 67 v, 68 ) 69 } 70 71 func (r rawValue) encodeFixedSlice(w io.Writer, v []byte) error { 72 binary.Write(w, binary.BigEndian, r.Type) 73 74 _, err := w.Write(v) 75 return err 76 } 77 78 func (r rawValue) encodeBytes(w io.Writer, v []byte) error { 79 if len(v) > maxHeaderValueLen { 80 return LengthError{ 81 Part: "header value", 82 Want: maxHeaderValueLen, Have: len(v), 83 Value: v, 84 } 85 } 86 r.Len = uint16(len(v)) 87 88 err := binaryWriteFields(w, binary.BigEndian, 89 r.Type, 90 r.Len, 91 ) 92 if err != nil { 93 return err 94 } 95 96 _, err = w.Write(v) 97 return err 98 } 99 100 func (r rawValue) encodeString(w io.Writer, v string) error { 101 if len(v) > maxHeaderValueLen { 102 return LengthError{ 103 Part: "header value", 104 Want: maxHeaderValueLen, Have: len(v), 105 Value: v, 106 } 107 } 108 r.Len = uint16(len(v)) 109 110 type stringWriter interface { 111 WriteString(string) (int, error) 112 } 113 114 err := binaryWriteFields(w, binary.BigEndian, 115 r.Type, 116 r.Len, 117 ) 118 if err != nil { 119 return err 120 } 121 122 if sw, ok := w.(stringWriter); ok { 123 _, err = sw.WriteString(v) 124 } else { 125 _, err = w.Write([]byte(v)) 126 } 127 128 return err 129 } 130 131 func decodeFixedBytesValue(r io.Reader, buf []byte) error { 132 _, err := io.ReadFull(r, buf) 133 return err 134 } 135 136 func decodeBytesValue(r io.Reader) ([]byte, error) { 137 var raw rawValue 138 var err error 139 raw.Len, err = decodeUint16(r) 140 if err != nil { 141 return nil, err 142 } 143 144 buf := make([]byte, raw.Len) 145 _, err = io.ReadFull(r, buf) 146 if err != nil { 147 return nil, err 148 } 149 150 return buf, nil 151 } 152 153 func decodeStringValue(r io.Reader) (string, error) { 154 v, err := decodeBytesValue(r) 155 return string(v), err 156 } 157 158 // Value represents the abstract header value. 159 type Value interface { 160 Get() interface{} 161 String() string 162 valueType() valueType 163 encode(io.Writer) error 164 } 165 166 // An BoolValue provides eventstream encoding, and representation 167 // of a Go bool value. 168 type BoolValue bool 169 170 // Get returns the underlying type 171 func (v BoolValue) Get() interface{} { 172 return bool(v) 173 } 174 175 // valueType returns the EventStream header value type value. 176 func (v BoolValue) valueType() valueType { 177 if v { 178 return trueValueType 179 } 180 return falseValueType 181 } 182 183 func (v BoolValue) String() string { 184 return strconv.FormatBool(bool(v)) 185 } 186 187 // encode encodes the BoolValue into an eventstream binary value 188 // representation. 189 func (v BoolValue) encode(w io.Writer) error { 190 return binary.Write(w, binary.BigEndian, v.valueType()) 191 } 192 193 // An Int8Value provides eventstream encoding, and representation of a Go 194 // int8 value. 195 type Int8Value int8 196 197 // Get returns the underlying value. 198 func (v Int8Value) Get() interface{} { 199 return int8(v) 200 } 201 202 // valueType returns the EventStream header value type value. 203 func (Int8Value) valueType() valueType { 204 return int8ValueType 205 } 206 207 func (v Int8Value) String() string { 208 return fmt.Sprintf("0x%02x", int8(v)) 209 } 210 211 // encode encodes the Int8Value into an eventstream binary value 212 // representation. 213 func (v Int8Value) encode(w io.Writer) error { 214 raw := rawValue{ 215 Type: v.valueType(), 216 } 217 218 return raw.encodeScalar(w, v) 219 } 220 221 func (v *Int8Value) decode(r io.Reader) error { 222 n, err := decodeUint8(r) 223 if err != nil { 224 return err 225 } 226 227 *v = Int8Value(n) 228 return nil 229 } 230 231 // An Int16Value provides eventstream encoding, and representation of a Go 232 // int16 value. 233 type Int16Value int16 234 235 // Get returns the underlying value. 236 func (v Int16Value) Get() interface{} { 237 return int16(v) 238 } 239 240 // valueType returns the EventStream header value type value. 241 func (Int16Value) valueType() valueType { 242 return int16ValueType 243 } 244 245 func (v Int16Value) String() string { 246 return fmt.Sprintf("0x%04x", int16(v)) 247 } 248 249 // encode encodes the Int16Value into an eventstream binary value 250 // representation. 251 func (v Int16Value) encode(w io.Writer) error { 252 raw := rawValue{ 253 Type: v.valueType(), 254 } 255 return raw.encodeScalar(w, v) 256 } 257 258 func (v *Int16Value) decode(r io.Reader) error { 259 n, err := decodeUint16(r) 260 if err != nil { 261 return err 262 } 263 264 *v = Int16Value(n) 265 return nil 266 } 267 268 // An Int32Value provides eventstream encoding, and representation of a Go 269 // int32 value. 270 type Int32Value int32 271 272 // Get returns the underlying value. 273 func (v Int32Value) Get() interface{} { 274 return int32(v) 275 } 276 277 // valueType returns the EventStream header value type value. 278 func (Int32Value) valueType() valueType { 279 return int32ValueType 280 } 281 282 func (v Int32Value) String() string { 283 return fmt.Sprintf("0x%08x", int32(v)) 284 } 285 286 // encode encodes the Int32Value into an eventstream binary value 287 // representation. 288 func (v Int32Value) encode(w io.Writer) error { 289 raw := rawValue{ 290 Type: v.valueType(), 291 } 292 return raw.encodeScalar(w, v) 293 } 294 295 func (v *Int32Value) decode(r io.Reader) error { 296 n, err := decodeUint32(r) 297 if err != nil { 298 return err 299 } 300 301 *v = Int32Value(n) 302 return nil 303 } 304 305 // An Int64Value provides eventstream encoding, and representation of a Go 306 // int64 value. 307 type Int64Value int64 308 309 // Get returns the underlying value. 310 func (v Int64Value) Get() interface{} { 311 return int64(v) 312 } 313 314 // valueType returns the EventStream header value type value. 315 func (Int64Value) valueType() valueType { 316 return int64ValueType 317 } 318 319 func (v Int64Value) String() string { 320 return fmt.Sprintf("0x%016x", int64(v)) 321 } 322 323 // encode encodes the Int64Value into an eventstream binary value 324 // representation. 325 func (v Int64Value) encode(w io.Writer) error { 326 raw := rawValue{ 327 Type: v.valueType(), 328 } 329 return raw.encodeScalar(w, v) 330 } 331 332 func (v *Int64Value) decode(r io.Reader) error { 333 n, err := decodeUint64(r) 334 if err != nil { 335 return err 336 } 337 338 *v = Int64Value(n) 339 return nil 340 } 341 342 // An BytesValue provides eventstream encoding, and representation of a Go 343 // byte slice. 344 type BytesValue []byte 345 346 // Get returns the underlying value. 347 func (v BytesValue) Get() interface{} { 348 return []byte(v) 349 } 350 351 // valueType returns the EventStream header value type value. 352 func (BytesValue) valueType() valueType { 353 return bytesValueType 354 } 355 356 func (v BytesValue) String() string { 357 return base64.StdEncoding.EncodeToString([]byte(v)) 358 } 359 360 // encode encodes the BytesValue into an eventstream binary value 361 // representation. 362 func (v BytesValue) encode(w io.Writer) error { 363 raw := rawValue{ 364 Type: v.valueType(), 365 } 366 367 return raw.encodeBytes(w, []byte(v)) 368 } 369 370 func (v *BytesValue) decode(r io.Reader) error { 371 buf, err := decodeBytesValue(r) 372 if err != nil { 373 return err 374 } 375 376 *v = BytesValue(buf) 377 return nil 378 } 379 380 // An StringValue provides eventstream encoding, and representation of a Go 381 // string. 382 type StringValue string 383 384 // Get returns the underlying value. 385 func (v StringValue) Get() interface{} { 386 return string(v) 387 } 388 389 // valueType returns the EventStream header value type value. 390 func (StringValue) valueType() valueType { 391 return stringValueType 392 } 393 394 func (v StringValue) String() string { 395 return string(v) 396 } 397 398 // encode encodes the StringValue into an eventstream binary value 399 // representation. 400 func (v StringValue) encode(w io.Writer) error { 401 raw := rawValue{ 402 Type: v.valueType(), 403 } 404 405 return raw.encodeString(w, string(v)) 406 } 407 408 func (v *StringValue) decode(r io.Reader) error { 409 s, err := decodeStringValue(r) 410 if err != nil { 411 return err 412 } 413 414 *v = StringValue(s) 415 return nil 416 } 417 418 // An TimestampValue provides eventstream encoding, and representation of a Go 419 // timestamp. 420 type TimestampValue time.Time 421 422 // Get returns the underlying value. 423 func (v TimestampValue) Get() interface{} { 424 return time.Time(v) 425 } 426 427 // valueType returns the EventStream header value type value. 428 func (TimestampValue) valueType() valueType { 429 return timestampValueType 430 } 431 432 func (v TimestampValue) epochMilli() int64 { 433 nano := time.Time(v).UnixNano() 434 msec := nano / int64(time.Millisecond) 435 return msec 436 } 437 438 func (v TimestampValue) String() string { 439 msec := v.epochMilli() 440 return strconv.FormatInt(msec, 10) 441 } 442 443 // encode encodes the TimestampValue into an eventstream binary value 444 // representation. 445 func (v TimestampValue) encode(w io.Writer) error { 446 raw := rawValue{ 447 Type: v.valueType(), 448 } 449 450 msec := v.epochMilli() 451 return raw.encodeScalar(w, msec) 452 } 453 454 func (v *TimestampValue) decode(r io.Reader) error { 455 n, err := decodeUint64(r) 456 if err != nil { 457 return err 458 } 459 460 *v = TimestampValue(timeFromEpochMilli(int64(n))) 461 return nil 462 } 463 464 // MarshalJSON implements the json.Marshaler interface 465 func (v TimestampValue) MarshalJSON() ([]byte, error) { 466 return []byte(v.String()), nil 467 } 468 469 func timeFromEpochMilli(t int64) time.Time { 470 secs := t / 1e3 471 msec := t % 1e3 472 return time.Unix(secs, msec*int64(time.Millisecond)).UTC() 473 } 474 475 // An UUIDValue provides eventstream encoding, and representation of a UUID 476 // value. 477 type UUIDValue [16]byte 478 479 // Get returns the underlying value. 480 func (v UUIDValue) Get() interface{} { 481 return v[:] 482 } 483 484 // valueType returns the EventStream header value type value. 485 func (UUIDValue) valueType() valueType { 486 return uuidValueType 487 } 488 489 func (v UUIDValue) String() string { 490 return fmt.Sprintf(`%X-%X-%X-%X-%X`, v[0:4], v[4:6], v[6:8], v[8:10], v[10:]) 491 } 492 493 // encode encodes the UUIDValue into an eventstream binary value 494 // representation. 495 func (v UUIDValue) encode(w io.Writer) error { 496 raw := rawValue{ 497 Type: v.valueType(), 498 } 499 500 return raw.encodeFixedSlice(w, v[:]) 501 } 502 503 func (v *UUIDValue) decode(r io.Reader) error { 504 tv := (*v)[:] 505 return decodeFixedBytesValue(r, tv) 506 }