blob: 68cfe4aaa25b16a280d26ac0969ba5f04f075d14 [file] [log] [blame]
Jens Geyer0e87c462013-06-18 22:25:07 +02001/*
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
20package thrift
21
Jens Geyer3ea26be2015-07-10 00:23:39 +020022import (
John Boiles57852792018-01-05 14:37:05 -080023 "context"
Jens Geyer3ea26be2015-07-10 00:23:39 +020024 "errors"
Jens Geyer5f723cd2017-01-10 21:57:48 +010025 "fmt"
Jens Geyer3ea26be2015-07-10 00:23:39 +020026)
27
Jens Geyer0e87c462013-06-18 22:25:07 +020028const (
29 VERSION_MASK = 0xffff0000
30 VERSION_1 = 0x80010000
31)
32
33type TProtocol interface {
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -070034 WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error
35 WriteMessageEnd(ctx context.Context) error
36 WriteStructBegin(ctx context.Context, name string) error
37 WriteStructEnd(ctx context.Context) error
38 WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error
39 WriteFieldEnd(ctx context.Context) error
40 WriteFieldStop(ctx context.Context) error
41 WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error
42 WriteMapEnd(ctx context.Context) error
43 WriteListBegin(ctx context.Context, elemType TType, size int) error
44 WriteListEnd(ctx context.Context) error
45 WriteSetBegin(ctx context.Context, elemType TType, size int) error
46 WriteSetEnd(ctx context.Context) error
47 WriteBool(ctx context.Context, value bool) error
48 WriteByte(ctx context.Context, value int8) error
49 WriteI16(ctx context.Context, value int16) error
50 WriteI32(ctx context.Context, value int32) error
51 WriteI64(ctx context.Context, value int64) error
52 WriteDouble(ctx context.Context, value float64) error
53 WriteString(ctx context.Context, value string) error
54 WriteBinary(ctx context.Context, value []byte) error
Yuxuan 'fishy' Wang19c13b42022-10-12 14:13:15 -070055 WriteUUID(ctx context.Context, value Tuuid) error
Jens Geyer0e87c462013-06-18 22:25:07 +020056
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -070057 ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error)
58 ReadMessageEnd(ctx context.Context) error
59 ReadStructBegin(ctx context.Context) (name string, err error)
60 ReadStructEnd(ctx context.Context) error
61 ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error)
62 ReadFieldEnd(ctx context.Context) error
63 ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error)
64 ReadMapEnd(ctx context.Context) error
65 ReadListBegin(ctx context.Context) (elemType TType, size int, err error)
66 ReadListEnd(ctx context.Context) error
67 ReadSetBegin(ctx context.Context) (elemType TType, size int, err error)
68 ReadSetEnd(ctx context.Context) error
69 ReadBool(ctx context.Context) (value bool, err error)
70 ReadByte(ctx context.Context) (value int8, err error)
71 ReadI16(ctx context.Context) (value int16, err error)
72 ReadI32(ctx context.Context) (value int32, err error)
73 ReadI64(ctx context.Context) (value int64, err error)
74 ReadDouble(ctx context.Context) (value float64, err error)
75 ReadString(ctx context.Context) (value string, err error)
76 ReadBinary(ctx context.Context) (value []byte, err error)
Yuxuan 'fishy' Wang19c13b42022-10-12 14:13:15 -070077 ReadUUID(ctx context.Context) (value Tuuid, err error)
Jens Geyer0e87c462013-06-18 22:25:07 +020078
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -070079 Skip(ctx context.Context, fieldType TType) (err error)
John Boiles57852792018-01-05 14:37:05 -080080 Flush(ctx context.Context) (err error)
Jens Geyer0e87c462013-06-18 22:25:07 +020081
82 Transport() TTransport
83}
84
85// The maximum recursive depth the skip() function will traverse
Jens Geyer3ea26be2015-07-10 00:23:39 +020086const DEFAULT_RECURSION_DEPTH = 64
Jens Geyer0e87c462013-06-18 22:25:07 +020087
88// Skips over the next data element from the provided input TProtocol object.
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -070089func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) {
90 return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH)
Jens Geyer0e87c462013-06-18 22:25:07 +020091}
92
93// Skips over the next data element from the provided input TProtocol object.
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -070094func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) {
D. Can Celasun8da0e722017-06-02 14:33:32 +020095
96 if maxDepth <= 0 {
97 return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded"))
Jens Geyer3ea26be2015-07-10 00:23:39 +020098 }
99
Jens Geyer0e87c462013-06-18 22:25:07 +0200100 switch fieldType {
Jens Geyer0e87c462013-06-18 22:25:07 +0200101 case BOOL:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700102 _, err = self.ReadBool(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200103 return
104 case BYTE:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700105 _, err = self.ReadByte(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200106 return
107 case I16:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700108 _, err = self.ReadI16(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200109 return
110 case I32:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700111 _, err = self.ReadI32(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200112 return
113 case I64:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700114 _, err = self.ReadI64(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200115 return
116 case DOUBLE:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700117 _, err = self.ReadDouble(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200118 return
119 case STRING:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700120 _, err = self.ReadString(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200121 return
Yuxuan 'fishy' Wang19c13b42022-10-12 14:13:15 -0700122 case UUID:
123 _, err = self.ReadUUID(ctx)
124 return
Jens Geyer0e87c462013-06-18 22:25:07 +0200125 case STRUCT:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700126 if _, err = self.ReadStructBegin(ctx); err != nil {
Jens Geyer0e87c462013-06-18 22:25:07 +0200127 return err
128 }
129 for {
Philippe Antoine62beb672021-03-15 09:26:39 +0100130 _, typeId, _, err := self.ReadFieldBegin(ctx)
131 if err != nil {
132 return err
133 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200134 if typeId == STOP {
135 break
136 }
Philippe Antoine62beb672021-03-15 09:26:39 +0100137 err = Skip(ctx, self, typeId, maxDepth-1)
Jens Geyer3ea26be2015-07-10 00:23:39 +0200138 if err != nil {
139 return err
140 }
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700141 self.ReadFieldEnd(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200142 }
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700143 return self.ReadStructEnd(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200144 case MAP:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700145 keyType, valueType, size, err := self.ReadMapBegin(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200146 if err != nil {
147 return err
148 }
Yuxuan 'fishy' Wang91565d42024-08-14 09:01:15 -0700149 for range size {
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700150 err := Skip(ctx, self, keyType, maxDepth-1)
Jens Geyer3ea26be2015-07-10 00:23:39 +0200151 if err != nil {
152 return err
153 }
郑桐0f760532021-10-09 16:01:28 +0800154
155 err = Skip(ctx, self, valueType, maxDepth-1)
156 if err != nil {
157 return err
158 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200159 }
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700160 return self.ReadMapEnd(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200161 case SET:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700162 elemType, size, err := self.ReadSetBegin(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200163 if err != nil {
164 return err
165 }
Yuxuan 'fishy' Wang91565d42024-08-14 09:01:15 -0700166 for range size {
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700167 err := Skip(ctx, self, elemType, maxDepth-1)
Jens Geyer3ea26be2015-07-10 00:23:39 +0200168 if err != nil {
169 return err
170 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200171 }
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700172 return self.ReadSetEnd(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200173 case LIST:
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700174 elemType, size, err := self.ReadListBegin(ctx)
Jens Geyer0e87c462013-06-18 22:25:07 +0200175 if err != nil {
176 return err
177 }
Yuxuan 'fishy' Wang91565d42024-08-14 09:01:15 -0700178 for range size {
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700179 err := Skip(ctx, self, elemType, maxDepth-1)
Jens Geyer3ea26be2015-07-10 00:23:39 +0200180 if err != nil {
181 return err
182 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200183 }
Yuxuan 'fishy' Wange79f7642020-06-12 22:22:35 -0700184 return self.ReadListEnd(ctx)
Jens Geyer5f723cd2017-01-10 21:57:48 +0100185 default:
Yuxuan 'fishy' Wang17373a32021-08-26 11:04:27 -0700186 return NewTProtocolExceptionWithType(INVALID_DATA, fmt.Errorf("Unknown data type %d", fieldType))
Jens Geyer0e87c462013-06-18 22:25:07 +0200187 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200188}