github.com/artyom/thrift@v0.0.0-20130902103359-388840a05deb/json_protocol.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package thrift 21 22 import ( 23 "encoding/base64" 24 "fmt" 25 ) 26 27 const ( 28 THRIFT_JSON_PROTOCOL_VERSION = 1 29 ) 30 31 // for references to _ParseContext see tsimplejson_protocol.go 32 33 // JSON protocol implementation for thrift. 34 // 35 // This protocol produces/consumes a simple output format 36 // suitable for parsing by scripting languages. It should not be 37 // confused with the full-featured TJSONProtocol. 38 // 39 type TJSONProtocol struct { 40 *TSimpleJSONProtocol 41 } 42 43 // Constructor 44 func NewTJSONProtocol(t TTransport) *TJSONProtocol { 45 v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} 46 v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) 47 v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) 48 return v 49 } 50 51 // Factory 52 type TJSONProtocolFactory struct{} 53 54 func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { 55 return NewTJSONProtocol(trans) 56 } 57 58 func NewTJSONProtocolFactory() *TJSONProtocolFactory { 59 return &TJSONProtocolFactory{} 60 } 61 62 func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { 63 if e := p.OutputListBegin(); e != nil { 64 return e 65 } 66 if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil { 67 return e 68 } 69 if e := p.WriteString(name); e != nil { 70 return e 71 } 72 if e := p.WriteByte(byte(typeId)); e != nil { 73 return e 74 } 75 if e := p.WriteI32(seqId); e != nil { 76 return e 77 } 78 return nil 79 } 80 81 func (p *TJSONProtocol) WriteMessageEnd() error { 82 return p.OutputListEnd() 83 } 84 85 func (p *TJSONProtocol) WriteStructBegin(name string) error { 86 if e := p.OutputObjectBegin(); e != nil { 87 return e 88 } 89 return nil 90 } 91 92 func (p *TJSONProtocol) WriteStructEnd() error { 93 return p.OutputObjectEnd() 94 } 95 96 func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { 97 if e := p.WriteI16(id); e != nil { 98 return e 99 } 100 if e := p.OutputObjectBegin(); e != nil { 101 return e 102 } 103 if e := p.WriteString(p.TypeIdToString(typeId)); e != nil { 104 return e 105 } 106 return nil 107 } 108 109 func (p *TJSONProtocol) WriteFieldEnd() error { 110 return p.OutputObjectEnd() 111 } 112 113 func (p *TJSONProtocol) WriteFieldStop() error { return nil } 114 115 func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { 116 if e := p.OutputListBegin(); e != nil { 117 return e 118 } 119 if e := p.WriteString(p.TypeIdToString(keyType)); e != nil { 120 return e 121 } 122 if e := p.WriteString(p.TypeIdToString(valueType)); e != nil { 123 return e 124 } 125 return p.WriteI64(int64(size)) 126 } 127 128 func (p *TJSONProtocol) WriteMapEnd() error { 129 return p.OutputListEnd() 130 } 131 132 func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error { 133 return p.OutputElemListBegin(elemType, size) 134 } 135 136 func (p *TJSONProtocol) WriteListEnd() error { 137 return p.OutputListEnd() 138 } 139 140 func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error { 141 return p.OutputElemListBegin(elemType, size) 142 } 143 144 func (p *TJSONProtocol) WriteSetEnd() error { 145 return p.OutputListEnd() 146 } 147 148 func (p *TJSONProtocol) WriteBool(b bool) error { 149 return p.OutputBool(b) 150 } 151 152 func (p *TJSONProtocol) WriteByte(b byte) error { 153 return p.WriteI32(int32(b)) 154 } 155 156 func (p *TJSONProtocol) WriteI16(v int16) error { 157 return p.WriteI32(int32(v)) 158 } 159 160 func (p *TJSONProtocol) WriteI32(v int32) error { 161 return p.OutputI64(int64(v)) 162 } 163 164 func (p *TJSONProtocol) WriteI64(v int64) error { 165 return p.OutputI64(int64(v)) 166 } 167 168 func (p *TJSONProtocol) WriteDouble(v float64) error { 169 return p.OutputF64(v) 170 } 171 172 func (p *TJSONProtocol) WriteString(v string) error { 173 return p.OutputString(v) 174 } 175 176 func (p *TJSONProtocol) WriteBinary(v []byte) error { 177 // JSON library only takes in a string, 178 // not an arbitrary byte array, to ensure bytes are transmitted 179 // efficiently we must convert this into a valid JSON string 180 // therefore we use base64 encoding to avoid excessive escaping/quoting 181 if e := p.OutputPreValue(); e != nil { 182 return e 183 } 184 p.writer.Write(JSON_QUOTE_BYTES) 185 writer := base64.NewEncoder(base64.StdEncoding, p.writer) 186 if _, e := writer.Write(v); e != nil { 187 return NewTProtocolException(e) 188 } 189 writer.Close() 190 p.writer.Write(JSON_QUOTE_BYTES) 191 return p.OutputPostValue() 192 } 193 194 // Reading methods. 195 196 func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { 197 if isNull, err := p.ParseListBegin(); isNull || err != nil { 198 return name, typeId, seqId, err 199 } 200 version, err := p.ReadI32() 201 if err != nil { 202 return name, typeId, seqId, err 203 } 204 if version != THRIFT_JSON_PROTOCOL_VERSION { 205 e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) 206 return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) 207 208 } 209 if name, err = p.ReadString(); err != nil { 210 return name, typeId, seqId, err 211 } 212 bTypeId, err := p.ReadByte() 213 typeId = TMessageType(bTypeId) 214 if err != nil { 215 return name, typeId, seqId, err 216 } 217 if seqId, err = p.ReadI32(); err != nil { 218 return name, typeId, seqId, err 219 } 220 return name, typeId, seqId, nil 221 } 222 223 func (p *TJSONProtocol) ReadMessageEnd() error { 224 err := p.ParseListEnd() 225 return err 226 } 227 228 func (p *TJSONProtocol) ReadStructBegin() (name string, err error) { 229 _, err = p.ParseObjectStart() 230 return "", err 231 } 232 233 func (p *TJSONProtocol) ReadStructEnd() error { 234 return p.ParseObjectEnd() 235 } 236 237 func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { 238 if p.reader.Buffered() < 1 { 239 return "", STOP, -1, nil 240 } 241 b, _ := p.reader.Peek(1) 242 if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { 243 return "", STOP, -1, nil 244 } 245 fieldId, err := p.ReadI16() 246 if err != nil { 247 return "", STOP, fieldId, err 248 } 249 if _, err = p.ParseObjectStart(); err != nil { 250 return "", STOP, fieldId, err 251 } 252 sType, err := p.ReadString() 253 fType := p.StringToTypeId(sType) 254 return "", fType, fieldId, err 255 } 256 257 func (p *TJSONProtocol) ReadFieldEnd() error { 258 return p.ParseObjectEnd() 259 } 260 261 func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { 262 if isNull, e := p.ParseListBegin(); isNull || e != nil { 263 return VOID, VOID, 0, e 264 } 265 266 // read keyType 267 sKeyType, e := p.ReadString() 268 keyType = p.StringToTypeId(sKeyType) 269 if e != nil { 270 return keyType, valueType, size, e 271 } 272 273 // read valueType 274 sValueType, e := p.ReadString() 275 valueType = p.StringToTypeId(sValueType) 276 if e != nil { 277 return keyType, valueType, size, e 278 } 279 280 // read size 281 iSize, err := p.ReadI64() 282 size = int(iSize) 283 return keyType, valueType, size, err 284 } 285 286 func (p *TJSONProtocol) ReadMapEnd() error { 287 return p.ParseListEnd() 288 } 289 290 func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { 291 return p.ParseElemListBegin() 292 } 293 294 func (p *TJSONProtocol) ReadListEnd() error { 295 return p.ParseListEnd() 296 } 297 298 func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { 299 return p.ParseElemListBegin() 300 } 301 302 func (p *TJSONProtocol) ReadSetEnd() error { 303 return p.ParseListEnd() 304 } 305 306 func (p *TJSONProtocol) ReadBool() (bool, error) { 307 var value bool 308 if err := p.ParsePreValue(); err != nil { 309 return value, err 310 } 311 b, _ := p.reader.Peek(len(JSON_FALSE)) 312 if len(b) > 0 { 313 switch b[0] { 314 case JSON_TRUE[0]: 315 if string(b[0:len(JSON_TRUE)]) == string(JSON_TRUE) { 316 p.reader.Read(b[0:len(JSON_TRUE)]) 317 value = true 318 } else { 319 e := fmt.Errorf("Expected \"true\" but found: %s", string(b)) 320 return value, NewTProtocolExceptionWithType(INVALID_DATA, e) 321 } 322 break 323 case JSON_FALSE[0]: 324 if string(b[0:len(JSON_FALSE)]) == string(JSON_FALSE) { 325 p.reader.Read(b[0:len(JSON_FALSE)]) 326 value = false 327 } else { 328 e := fmt.Errorf("Expected \"false\" but found: %s", string(b)) 329 return value, NewTProtocolExceptionWithType(INVALID_DATA, e) 330 } 331 break 332 case JSON_NULL[0]: 333 if string(b[0:len(JSON_NULL)]) == string(JSON_NULL) { 334 p.reader.Read(b[0:len(JSON_NULL)]) 335 value = false 336 } else { 337 e := fmt.Errorf("Expected \"null\" but found: %s", string(b)) 338 return value, NewTProtocolExceptionWithType(INVALID_DATA, e) 339 } 340 default: 341 e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b)) 342 return value, NewTProtocolExceptionWithType(INVALID_DATA, e) 343 } 344 } 345 return value, p.ParsePostValue() 346 } 347 348 func (p *TJSONProtocol) ReadByte() (byte, error) { 349 v, err := p.ReadI64() 350 return byte(v), err 351 } 352 353 func (p *TJSONProtocol) ReadI16() (int16, error) { 354 v, err := p.ReadI64() 355 return int16(v), err 356 } 357 358 func (p *TJSONProtocol) ReadI32() (int32, error) { 359 v, err := p.ReadI64() 360 return int32(v), err 361 } 362 363 func (p *TJSONProtocol) ReadI64() (int64, error) { 364 v, _, err := p.ParseI64() 365 return v, err 366 } 367 368 func (p *TJSONProtocol) ReadDouble() (float64, error) { 369 v, _, err := p.ParseF64() 370 return v, err 371 } 372 373 func (p *TJSONProtocol) ReadString() (string, error) { 374 var v string 375 if err := p.ParsePreValue(); err != nil { 376 return v, err 377 } 378 b, _ := p.reader.Peek(len(JSON_NULL)) 379 if len(b) > 0 && b[0] == JSON_QUOTE { 380 p.reader.ReadByte() 381 value, err := p.ParseStringBody() 382 v = value 383 if err != nil { 384 return v, err 385 } 386 } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) { 387 _, err := p.reader.Read(b[0:len(JSON_NULL)]) 388 if err != nil { 389 return v, NewTProtocolException(err) 390 } 391 } else { 392 e := fmt.Errorf("Expected a JSON string, found %s", string(b)) 393 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 394 } 395 return v, p.ParsePostValue() 396 } 397 398 func (p *TJSONProtocol) ReadBinary() ([]byte, error) { 399 var v []byte 400 if err := p.ParsePreValue(); err != nil { 401 return nil, err 402 } 403 b, _ := p.reader.Peek(len(JSON_NULL)) 404 if len(b) > 0 && b[0] == JSON_QUOTE { 405 p.reader.ReadByte() 406 value, err := p.ParseBase64EncodedBody() 407 v = value 408 if err != nil { 409 return v, err 410 } 411 } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) { 412 _, err := p.reader.Read(b[0:len(JSON_NULL)]) 413 if err != nil { 414 return v, NewTProtocolException(err) 415 } 416 } else { 417 e := fmt.Errorf("Expected a JSON string, found %s", string(b)) 418 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 419 } 420 return v, p.ParsePostValue() 421 } 422 423 func (p *TJSONProtocol) Flush() (err error) { 424 return NewTProtocolException(p.writer.Flush()) 425 } 426 427 func (p *TJSONProtocol) Skip(fieldType TType) (err error) { 428 return SkipDefaultDepth(p, fieldType) 429 } 430 431 func (p *TJSONProtocol) Transport() TTransport { 432 return p.trans 433 } 434 435 func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { 436 if e := p.OutputListBegin(); e != nil { 437 return e 438 } 439 if e := p.WriteString(p.TypeIdToString(elemType)); e != nil { 440 return e 441 } 442 if e := p.WriteI64(int64(size)); e != nil { 443 return e 444 } 445 return nil 446 } 447 448 449 func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { 450 if isNull, e := p.ParseListBegin(); isNull || e != nil { 451 return VOID, 0, e 452 } 453 sElemType, err := p.ReadString() 454 elemType = p.StringToTypeId(sElemType) 455 if err != nil { 456 return elemType, size, err 457 } 458 nSize, err2 := p.ReadI64() 459 size = int(nSize) 460 return elemType, size, err2 461 } 462 463 func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) { 464 if isNull, e := p.ParseListBegin(); isNull || e != nil { 465 return VOID, 0, e 466 } 467 sElemType, err := p.ReadString() 468 elemType = p.StringToTypeId(sElemType) 469 if err != nil { 470 return elemType, size, err 471 } 472 nSize, err2 := p.ReadI64() 473 size = int(nSize) 474 return elemType, size, err2 475 } 476 477 func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error { 478 if e := p.OutputListBegin(); e != nil { 479 return e 480 } 481 if e := p.OutputString(p.TypeIdToString(elemType)); e != nil { 482 return e 483 } 484 if e := p.OutputI64(int64(size)); e != nil { 485 return e 486 } 487 return nil 488 } 489 490 func (p *TJSONProtocol) TypeIdToString(fieldType TType) string { 491 switch byte(fieldType) { 492 case STOP: 493 return "stp" 494 case VOID: 495 return "v" 496 case BOOL: 497 return "tf" 498 case BYTE: 499 return "i8" 500 case DOUBLE: 501 return "dbl" 502 case I16: 503 return "i16" 504 case I32: 505 return "i32" 506 case I64: 507 return "i64" 508 case STRING: 509 return "str" 510 case STRUCT: 511 return "rec" 512 case MAP: 513 return "map" 514 case SET: 515 return "set" 516 case LIST: 517 return "lst" 518 case UTF16: 519 return "str" 520 } 521 return "" 522 } 523 524 func (p *TJSONProtocol) StringToTypeId(fieldType string) TType { 525 switch fieldType { 526 case "stp": 527 return TType(STOP) 528 case "v": 529 return TType(VOID) 530 case "tf": 531 return TType(BOOL) 532 case "i8": 533 return TType(BYTE) 534 case "dbl": 535 return TType(DOUBLE) 536 case "16": 537 return TType(I16) 538 case "i32": 539 return TType(I32) 540 case "i64": 541 return TType(I64) 542 case "str": 543 return TType(STRING) 544 case "rec": 545 return TType(STRUCT) 546 case "map": 547 return TType(MAP) 548 case "set": 549 return TType(SET) 550 case "lst": 551 return TType(LIST) 552 case "u16": 553 return TType(UTF16) 554 } 555 return TType(STOP) 556 }