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