blob: b4e5dbe73b3a10d243fbebff97eadb508b33c683 [file] [log] [blame]
Chris Simpsona9b6c702018-04-08 07:11:37 -04001/*
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
20import Foundation
Chris Simpsona9b6c702018-04-08 07:11:37 -040021
22public enum TMessageType: Int32 {
23 case call = 1
24 case reply = 2
25 case exception = 3
26 case oneway = 4
27}
28
29public enum TType: Int32 {
30 case stop = 0
31 case void = 1
32 case bool = 2
33 case i8 = 3
34 case double = 4
35 case i16 = 6
36 case i32 = 8
37 case i64 = 10
38 case string = 11
39 case `struct` = 12
40 case map = 13
41 case set = 14
42 case list = 15
43 case utf8 = 16
44 case utf16 = 17
45}
46
47public protocol TProtocol {
48 var transport: TTransport { get set }
49 init(on transport: TTransport)
50 // Reading Methods
51
52 func readMessageBegin() throws -> (String, TMessageType, Int32)
53 func readMessageEnd() throws
54 func readStructBegin() throws -> String
55 func readStructEnd() throws
56 func readFieldBegin() throws -> (String, TType, Int32)
57 func readFieldEnd() throws
58 func readMapBegin() throws -> (TType, TType, Int32)
59 func readMapEnd() throws
60 func readSetBegin() throws -> (TType, Int32)
61 func readSetEnd() throws
62 func readListBegin() throws -> (TType, Int32)
63 func readListEnd() throws
64
65 func read() throws -> String
66 func read() throws -> Bool
67 func read() throws -> UInt8
68 func read() throws -> Int16
69 func read() throws -> Int32
70 func read() throws -> Int64
71 func read() throws -> Double
72 func read() throws -> Data
73
74 // Writing methods
75
76 func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws
77 func writeMessageEnd() throws
78 func writeStructBegin(name: String) throws
79 func writeStructEnd() throws
80 func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws
81 func writeFieldStop() throws
82 func writeFieldEnd() throws
83 func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws
84 func writeMapEnd() throws
85 func writeSetBegin(elementType: TType, size: Int32) throws
86 func writeSetEnd() throws
87 func writeListBegin(elementType: TType, size: Int32) throws
88 func writeListEnd() throws
89
90 func write(_ value: String) throws
91 func write(_ value: Bool) throws
92 func write(_ value: UInt8) throws
93 func write(_ value: Int16) throws
94 func write(_ value: Int32) throws
95 func write(_ value: Int64) throws
96 func write(_ value: Double) throws
97 func write(_ value: Data) throws
98}
99
100public extension TProtocol {
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800101 func writeFieldValue(_ value: TSerializable, name: String, type: TType, id: Int32) throws {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400102 try writeFieldBegin(name: name, type: type, fieldID: id)
103 try value.write(to: self)
104 try writeFieldEnd()
105 }
106
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800107 func validateValue(_ value: Any?, named name: String) throws {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400108 if value == nil {
109 throw TProtocolError(error: .unknown, message: "Missing required value for field: \(name)")
110 }
111 }
112
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800113 func readResultMessageBegin() throws {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400114 let (_, type, _) = try readMessageBegin();
115 if type == .exception {
116 let x = try readException()
117 throw x
118 }
119 return
120 }
121
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800122 func readException() throws -> TApplicationError {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400123 return try TApplicationError.read(from: self)
124 }
125
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800126 func writeException(messageName name: String, sequenceID: Int32, ex: TApplicationError) throws {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400127 try writeMessageBegin(name: name, type: .exception, sequenceID: sequenceID)
128 try ex.write(to: self)
129 try writeMessageEnd()
130 }
131
Antoine Cœur08a6eb62019-07-08 18:42:09 +0800132 func skip(type: TType) throws {
Chris Simpsona9b6c702018-04-08 07:11:37 -0400133 switch type {
134 case .bool: _ = try read() as Bool
135 case .i8: _ = try read() as UInt8
136 case .i16: _ = try read() as Int16
137 case .i32: _ = try read() as Int32
138 case .i64: _ = try read() as Int64
139 case .double: _ = try read() as Double
140 case .string: _ = try read() as String
141
142 case .struct:
143 _ = try readStructBegin()
144 while true {
145 let (_, fieldType, _) = try readFieldBegin()
146 if fieldType == .stop {
147 break
148 }
149 try skip(type: fieldType)
150 try readFieldEnd()
151 }
152 try readStructEnd()
153
154
155 case .map:
156 let (keyType, valueType, size) = try readMapBegin()
157 for _ in 0..<size {
158 try skip(type: keyType)
159 try skip(type: valueType)
160 }
161 try readMapEnd()
162
163
164 case .set:
165 let (elemType, size) = try readSetBegin()
166 for _ in 0..<size {
167 try skip(type: elemType)
168 }
169 try readSetEnd()
170
171 case .list:
172 let (elemType, size) = try readListBegin()
173 for _ in 0..<size {
174 try skip(type: elemType)
175 }
176 try readListEnd()
James E. King IIIdbc1f8d2019-02-14 16:46:38 -0500177
Chris Simpsona9b6c702018-04-08 07:11:37 -0400178 default:
James E. King IIIdbc1f8d2019-02-14 16:46:38 -0500179 throw TProtocolError(error: .invalidData, message: "Invalid data")
Chris Simpsona9b6c702018-04-08 07:11:37 -0400180 }
181 }
182}