]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / swift / Sources / TBinaryProtocol.swift
CommitLineData
f67539c2
TL
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
20import Foundation
21
22public struct TBinaryProtocolVersion {
23 static let version1 = Int32(bitPattern: 0x80010000)
24 static let versionMask = Int32(bitPattern: 0xffff0000)
25}
26
27public class TBinaryProtocol: TProtocol {
28 public var messageSizeLimit: UInt32 = 0
29
30 public var transport: TTransport
31
32 // class level properties for setting global config (useful for server in lieu of Factory design)
33 public static var strictRead: Bool = false
34 public static var strictWrite: Bool = true
35
36 private var strictRead: Bool
37 private var strictWrite: Bool
38
39 var currentMessageName: String?
40 var currentFieldName: String?
41
42
43 public convenience init(transport: TTransport, strictRead: Bool, strictWrite: Bool) {
44 self.init(on: transport)
45 self.strictRead = strictRead
46 self.strictWrite = strictWrite
47 }
48
49 public required init(on transport: TTransport) {
50 self.transport = transport
51 self.strictWrite = TBinaryProtocol.strictWrite
52 self.strictRead = TBinaryProtocol.strictRead
53 }
54
55 func readStringBody(_ size: Int) throws -> String {
56
57 var data = Data()
58 try ProtocolTransportTry(error: TProtocolError(message: "Transport read failed")) {
59 data = try self.transport.readAll(size: size)
60 }
61
62 return String(data: data, encoding: String.Encoding.utf8) ?? ""
63 }
64
65 /// Mark: - TProtocol
66
67 public func readMessageBegin() throws -> (String, TMessageType, Int32) {
68 let size: Int32 = try read()
69 var messageName = ""
70 var type = TMessageType.exception
71
72 if size < 0 {
73 let version = size & TBinaryProtocolVersion.versionMask
74 if version != TBinaryProtocolVersion.version1 {
75 throw TProtocolError(error: .badVersion(expected: "\(TBinaryProtocolVersion.version1)",
76 got: "\(version)"))
77 }
78 type = TMessageType(rawValue: Int32(size) & 0x00FF) ?? type
79 messageName = try read()
80 } else {
81 if strictRead {
82 let errorMessage = "Missing message version, old client? Message Name: \(currentMessageName ?? "")"
83 throw TProtocolError(error: .invalidData,
84 message: errorMessage)
85 }
86 if messageSizeLimit > 0 && size > Int32(messageSizeLimit) {
87 throw TProtocolError(error: .sizeLimit(limit: Int(messageSizeLimit), got: Int(size)))
88 }
89
90 messageName = try readStringBody(Int(size))
91 type = TMessageType(rawValue: Int32(try read() as UInt8)) ?? type
92 }
93
94 let seqID: Int32 = try read()
95 return (messageName, type, seqID)
96 }
97
98 public func readMessageEnd() throws {
99 return
100 }
101
102 public func readStructBegin() throws -> String {
103 return ""
104 }
105
106 public func readStructEnd() throws {
107 return
108 }
109
110 public func readFieldBegin() throws -> (String, TType, Int32) {
111
112 let fieldType = TType(rawValue: Int32(try read() as UInt8)) ?? TType.stop
113 var fieldID: Int32 = 0
114
115 if fieldType != .stop {
116 fieldID = Int32(try read() as Int16)
117 }
118
119 return ("", fieldType, fieldID)
120 }
121
122 public func readFieldEnd() throws {
123 return
124 }
125
126 public func readMapBegin() throws -> (TType, TType, Int32) {
127 var raw = Int32(try read() as UInt8)
128 guard let keyType = TType(rawValue: raw) else {
129 throw TProtocolError(message: "Unknown value for keyType TType: \(raw)")
130 }
131
132 raw = Int32(try read() as UInt8)
133 guard let valueType = TType(rawValue: raw) else {
134 throw TProtocolError(message: "Unknown value for valueType TType: \(raw)")
135 }
136 let size: Int32 = try read()
137
138 return (keyType, valueType, size)
139 }
140
141 public func readMapEnd() throws {
142 return
143 }
144
145 public func readSetBegin() throws -> (TType, Int32) {
146 let raw = Int32(try read() as UInt8)
147 guard let elementType = TType(rawValue: raw) else {
148 throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
149 }
150
151 let size: Int32 = try read()
152
153 return (elementType, size)
154 }
155
156 public func readSetEnd() throws {
157 return
158 }
159
160 public func readListBegin() throws -> (TType, Int32) {
161 let raw = Int32(try read() as UInt8)
162 guard let elementType = TType(rawValue: raw) else {
163 throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
164 }
165 let size: Int32 = try read()
166
167 return (elementType, size)
168 }
169
170 public func readListEnd() throws {
171 return
172 }
173
174 public func read() throws -> String {
175 let data: Data = try read()
176 guard let str = String.init(data: data, encoding: .utf8) else {
177 throw TProtocolError(error: .invalidData, message: "Couldn't encode UTF-8 from data read")
178 }
179 return str
180 }
181
182 public func read() throws -> Bool {
183 return (try read() as UInt8) == 1
184 }
185
186 public func read() throws -> UInt8 {
187 var buff = Data()
188 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
189 buff = try self.transport.readAll(size: 1)
190 }
191 return buff[0]
192 }
193
194 public func read() throws -> Int16 {
195 var buff = Data()
196 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
197 buff = try self.transport.readAll(size: 2)
198 }
199 var ret = Int16(buff[0] & 0xff) << 8
200 ret |= Int16(buff[1] & 0xff)
201 return ret
202 }
203
204 public func read() throws -> Int32 {
205 var buff = Data()
206 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
207 buff = try self.transport.readAll(size: 4)
208 }
209 var ret = Int32(buff[0] & 0xff) << 24
210 ret |= Int32(buff[1] & 0xff) << 16
211 ret |= Int32(buff[2] & 0xff) << 8
212 ret |= Int32(buff[3] & 0xff)
213
214 return ret
215 }
216
217 public func read() throws -> Int64 {
218 var buff = Data()
219 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
220 buff = try self.transport.readAll(size: 8)
221 }
222 var ret = Int64(buff[0] & 0xff) << 56
223 ret |= Int64(buff[1] & 0xff) << 48
224 ret |= Int64(buff[2] & 0xff) << 40
225 ret |= Int64(buff[3] & 0xff) << 32
226 ret |= Int64(buff[4] & 0xff) << 24
227 ret |= Int64(buff[5] & 0xff) << 16
228 ret |= Int64(buff[6] & 0xff) << 8
229 ret |= Int64(buff[7] & 0xff)
230
231 return ret
232 }
233
234 public func read() throws -> Double {
235 let val = try read() as Int64
236 return Double(bitPattern: UInt64(bitPattern: val))
237 }
238
239 public func read() throws -> Data {
240 let size = Int(try read() as Int32)
241 var data = Data()
242 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
243 data = try self.transport.readAll(size: size)
244 }
245
246 return data
247 }
248
249 // Write methods
250
251 public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws {
252 if strictWrite {
253 let version = TBinaryProtocolVersion.version1 | Int32(messageType.rawValue)
254 try write(version)
255 try write(name)
256 try write(sequenceID)
257 } else {
258 try write(name)
259 try write(UInt8(messageType.rawValue))
260 try write(sequenceID)
261 }
262 currentMessageName = name
263 }
264
265 public func writeMessageEnd() throws {
266 currentMessageName = nil
267 }
268
269 public func writeStructBegin(name: String) throws {
270 return
271 }
272
273 public func writeStructEnd() throws {
274 return
275 }
276
277 public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws {
278 try write(UInt8(fieldType.rawValue))
279 try write(Int16(fieldID))
280 }
281
282 public func writeFieldStop() throws {
283 try write(UInt8(TType.stop.rawValue))
284 }
285
286 public func writeFieldEnd() throws {
287 return
288 }
289
290 public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
291 try write(UInt8(keyType.rawValue))
292 try write(UInt8(valueType.rawValue))
293 try write(size)
294 }
295
296 public func writeMapEnd() throws {
297 return
298 }
299
300 public func writeSetBegin(elementType: TType, size: Int32) throws {
301 try write(UInt8(elementType.rawValue))
302 try write(size)
303 }
304
305 public func writeSetEnd() throws {
306 return
307 }
308
309 public func writeListBegin(elementType: TType, size: Int32) throws {
310 try write(UInt8(elementType.rawValue))
311 try write(size)
312 }
313
314 public func writeListEnd() throws {
315 return
316 }
317
318 public func write(_ value: String) throws {
319 try write(value.data(using: .utf8)!)
320 }
321
322 public func write(_ value: Bool) throws {
323 let byteVal: UInt8 = value ? 1 : 0
324 try write(byteVal)
325 }
326
327 public func write(_ value: UInt8) throws {
328 let buff = Data([value])
329
330 try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
331 try self.transport.write(data: buff)
332 }
333 }
334
335 public func write(_ value: Int16) throws {
336 var buff = Data()
337 buff.append(Data([UInt8(0xff & (value >> 8))]))
338 buff.append(Data([UInt8(0xff & (value))]))
339 try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
340 try self.transport.write(data: buff)
341 }
342 }
343
344 public func write(_ value: Int32) throws {
345 var buff = Data()
346 buff.append(Data([UInt8(0xff & (value >> 24))]))
347 buff.append(Data([UInt8(0xff & (value >> 16))]))
348 buff.append(Data([UInt8(0xff & (value >> 8))]))
349 buff.append(Data([UInt8(0xff & (value))]))
350
351 try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
352 try self.transport.write(data: buff)
353 }
354 }
355
356 public func write(_ value: Int64) throws {
357 var buff = Data()
358 buff.append(Data([UInt8(0xff & (value >> 56))]))
359 buff.append(Data([UInt8(0xff & (value >> 48))]))
360 buff.append(Data([UInt8(0xff & (value >> 40))]))
361 buff.append(Data([UInt8(0xff & (value >> 32))]))
362 buff.append(Data([UInt8(0xff & (value >> 24))]))
363 buff.append(Data([UInt8(0xff & (value >> 16))]))
364 buff.append(Data([UInt8(0xff & (value >> 8))]))
365 buff.append(Data([UInt8(0xff & (value))]))
366
367 try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
368 try self.transport.write(data: buff)
369 }
370 }
371
372 public func write(_ value: Double) throws {
373 // Notably unsafe, since Double and Int64 are the same size, this should work fine
374 try self.write(Int64(bitPattern: value.bitPattern))
375 }
376
377 public func write(_ data: Data) throws {
378 try write(Int32(data.count))
379
380 try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
381 try self.transport.write(data: data)
382 }
383 }
384}