ProtobufBinaryTypes.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. // ProtobufRuntime/Sources/Protobuf/ProtobufBinaryTypes.swift - Per-type binary coding
  2. //
  3. // This source file is part of the Swift.org open source project
  4. //
  5. // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See http://swift.org/LICENSE.txt for license information
  9. // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  10. //
  11. // -----------------------------------------------------------------------------
  12. ///
  13. /// Extensions to the proto types defined in ProtobufTypes.swift to provide
  14. /// type-specific binary coding and decoding.
  15. ///
  16. // -----------------------------------------------------------------------------
  17. import Swift
  18. import Foundation
  19. public protocol ProtobufBinaryCodableType: ProtobufTypePropertiesBase {
  20. static func protobufWireType() -> Int
  21. /// Write out the protobuf value only.
  22. static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: BaseType) throws
  23. static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool
  24. static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool
  25. static func setFromProtobufFixed4(fixed4: [UInt8], value: inout BaseType?) throws -> Bool
  26. static func setFromProtobufFixed4(fixed4: [UInt8], value: inout [BaseType]) throws -> Bool
  27. static func setFromProtobufFixed8(fixed8: [UInt8], value: inout BaseType?) throws -> Bool
  28. static func setFromProtobufFixed8(fixed8: [UInt8], value: inout [BaseType]) throws -> Bool
  29. static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout BaseType?) throws -> Bool
  30. static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool
  31. static func setFromProtobufBinaryDecoder(decoder: inout ProtobufBinaryDecoder, value: inout [BaseType]) throws -> Bool
  32. // Special interface for decoding a value of this type as a map value.
  33. static func decodeProtobufMapValue(decoder: inout ProtobufFieldDecoder, value: inout BaseType?) throws
  34. }
  35. /// Extension defines default handling for mismatched wire types.
  36. /// TODO: Examine how C++ proto2 treats wire type mismatches -- if
  37. /// it treats them as unknown fields, consider changing the following
  38. /// to 'return false' to match.
  39. public extension ProtobufBinaryCodableType {
  40. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  41. throw ProtobufDecodingError.schemaMismatch
  42. }
  43. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  44. throw ProtobufDecodingError.schemaMismatch
  45. }
  46. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout BaseType?) throws -> Bool {
  47. throw ProtobufDecodingError.schemaMismatch
  48. }
  49. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout [BaseType]) throws -> Bool {
  50. throw ProtobufDecodingError.schemaMismatch
  51. }
  52. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout BaseType?) throws -> Bool {
  53. throw ProtobufDecodingError.schemaMismatch
  54. }
  55. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout [BaseType]) throws -> Bool {
  56. throw ProtobufDecodingError.schemaMismatch
  57. }
  58. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout BaseType?) throws -> Bool {
  59. throw ProtobufDecodingError.schemaMismatch
  60. }
  61. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  62. throw ProtobufDecodingError.schemaMismatch
  63. }
  64. public static func setFromProtobufBinaryDecoder(decoder: inout ProtobufBinaryDecoder, value: inout [BaseType]) throws -> Bool {
  65. throw ProtobufDecodingError.schemaMismatch
  66. }
  67. }
  68. public extension ProtobufTypeProperties {
  69. public static func decodeProtobufMapValue(decoder: inout ProtobufFieldDecoder, value: inout BaseType?) throws {
  70. let handled = try decoder.decodeOptionalField(fieldType: Self.self, value: &value)
  71. assert(handled)
  72. }
  73. }
  74. public protocol ProtobufBinaryCodableMapKeyType: ProtobufTypePropertiesBase {
  75. /// Basic protobuf encoding hooks.
  76. static func protobufWireType() -> Int
  77. /// Write out the protobuf value only.
  78. static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: BaseType)
  79. }
  80. ///
  81. /// Float traits
  82. ///
  83. public extension ProtobufFloat {
  84. public static func protobufWireType() -> Int { return 5 }
  85. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Float) {
  86. encoder.putFloatValue(value: value)
  87. }
  88. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout BaseType?) throws -> Bool {
  89. assert(fixed4.count == 4)
  90. var i: Float = 0
  91. withUnsafeMutablePointer(to: &i) { ip -> Void in
  92. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  93. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  94. dest.initialize(from: src, count: 4)
  95. }
  96. }
  97. value = i
  98. return true
  99. }
  100. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout [BaseType]) throws -> Bool {
  101. assert(fixed4.count == 4)
  102. var i: Float = 0
  103. withUnsafeMutablePointer(to: &i) { ip -> Void in
  104. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  105. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  106. dest.initialize(from: src, count: 4)
  107. }
  108. }
  109. value.append(i)
  110. return true
  111. }
  112. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  113. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  114. while let t = try decoder.decodeFloat() {
  115. value.append(t)
  116. }
  117. return true
  118. }
  119. }
  120. ///
  121. /// Double traits
  122. ///
  123. public extension ProtobufDouble {
  124. public static func protobufWireType() -> Int { return 1 }
  125. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Double) {
  126. encoder.putDoubleValue(value: value)
  127. }
  128. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout BaseType?) throws -> Bool {
  129. assert(fixed8.count == 8)
  130. var i: Double = 0
  131. withUnsafeMutablePointer(to: &i) { ip -> Void in
  132. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  133. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  134. dest.initialize(from: src, count: 8)
  135. }
  136. }
  137. value = i
  138. return true
  139. }
  140. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout [BaseType]) throws -> Bool {
  141. assert(fixed8.count == 8)
  142. var i: Double = 0
  143. withUnsafeMutablePointer(to: &i) { ip -> Void in
  144. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  145. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  146. dest.initialize(from: src, count: 8)
  147. }
  148. }
  149. value.append(i)
  150. return true
  151. }
  152. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  153. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  154. while let t = try decoder.decodeDouble() {
  155. value.append(t)
  156. }
  157. return true
  158. }
  159. }
  160. ///
  161. /// Int32 traits
  162. ///
  163. public extension ProtobufInt32 {
  164. public static func protobufWireType() -> Int { return 0 }
  165. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int32) {
  166. encoder.putVarInt(value: Int64(value))
  167. }
  168. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  169. value = Int32(truncatingBitPattern: varint)
  170. return true
  171. }
  172. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  173. value.append(Int32(truncatingBitPattern: varint))
  174. return true
  175. }
  176. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  177. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  178. while let t = try decoder.decodeInt32() {
  179. value.append(t)
  180. }
  181. return true
  182. }
  183. }
  184. ///
  185. /// Int64 traits
  186. ///
  187. public extension ProtobufInt64 {
  188. public static func protobufWireType() -> Int { return 0 }
  189. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int64) {
  190. encoder.putVarInt(value: value)
  191. }
  192. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  193. value = Int64(bitPattern: varint)
  194. return true
  195. }
  196. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  197. value.append(Int64(bitPattern: varint))
  198. return true
  199. }
  200. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  201. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  202. while let t = try decoder.decodeInt64() {
  203. value.append(t)
  204. }
  205. return true
  206. }
  207. }
  208. ///
  209. /// UInt32 traits
  210. ///
  211. public extension ProtobufUInt32 {
  212. public static func protobufWireType() -> Int { return 0 }
  213. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: UInt32) {
  214. encoder.putVarInt(value: UInt64(value))
  215. }
  216. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  217. value = UInt32(truncatingBitPattern: varint)
  218. return true
  219. }
  220. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  221. value.append(UInt32(truncatingBitPattern: varint))
  222. return true
  223. }
  224. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  225. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  226. while let t = try decoder.decodeUInt32() {
  227. value.append(t)
  228. }
  229. return true
  230. }
  231. }
  232. ///
  233. /// UInt64 traits
  234. ///
  235. public extension ProtobufUInt64 {
  236. public static func protobufWireType() -> Int { return 0 }
  237. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: UInt64) {
  238. encoder.putVarInt(value: value)
  239. }
  240. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  241. value = varint
  242. return true
  243. }
  244. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  245. value.append(varint)
  246. return true
  247. }
  248. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  249. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  250. while let t = try decoder.decodeUInt64() {
  251. value.append(t)
  252. }
  253. return true
  254. }
  255. }
  256. ///
  257. /// SInt32 traits
  258. ///
  259. public extension ProtobufSInt32 {
  260. public static func protobufWireType() -> Int { return 0 }
  261. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int32) {
  262. encoder.putZigZagVarInt(value: Int64(value))
  263. }
  264. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  265. let t = UInt32(truncatingBitPattern: varint)
  266. let n = Int32(bitPattern: (t >> 1))
  267. value = n ^ -Int32(bitPattern: t & 1)
  268. return true
  269. }
  270. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  271. let t = UInt32(truncatingBitPattern: varint)
  272. let n = Int32(bitPattern: (t >> 1))
  273. value.append(n ^ -Int32(bitPattern: t & 1))
  274. return true
  275. }
  276. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  277. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  278. while let t = try decoder.decodeSInt32() {
  279. value.append(t)
  280. }
  281. return true
  282. }
  283. }
  284. ///
  285. /// SInt64 traits
  286. ///
  287. public extension ProtobufSInt64 {
  288. public static func protobufWireType() -> Int { return 0 }
  289. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int64) {
  290. encoder.putZigZagVarInt(value: value)
  291. }
  292. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  293. let n = Int64(bitPattern: (varint >> 1))
  294. value = n ^ -Int64(bitPattern: varint & 1)
  295. return true
  296. }
  297. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  298. let n = Int64(bitPattern: (varint >> 1))
  299. value.append(n ^ -Int64(bitPattern: varint & 1))
  300. return true
  301. }
  302. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  303. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  304. while let t = try decoder.decodeSInt64() {
  305. value.append(t)
  306. }
  307. return true
  308. }
  309. }
  310. ///
  311. /// Fixed32 traits
  312. ///
  313. public extension ProtobufFixed32 {
  314. public static func protobufWireType() -> Int { return 5 }
  315. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: UInt32) {
  316. encoder.putFixedUInt32(value: value)
  317. }
  318. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout BaseType?) throws -> Bool {
  319. assert(fixed4.count == 4)
  320. var i: UInt32 = 0
  321. withUnsafeMutablePointer(to: &i) { ip -> Void in
  322. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  323. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  324. dest.initialize(from: src, count: 4)
  325. }
  326. }
  327. value = i
  328. return true
  329. }
  330. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout [BaseType]) throws -> Bool {
  331. assert(fixed4.count == 4)
  332. var i: UInt32 = 0
  333. withUnsafeMutablePointer(to: &i) { ip -> Void in
  334. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  335. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  336. dest.initialize(from: src, count: 4)
  337. }
  338. }
  339. value.append(i)
  340. return true
  341. }
  342. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  343. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  344. while let t = try decoder.decodeFixed32() {
  345. value.append(t)
  346. }
  347. return true
  348. }
  349. }
  350. ///
  351. /// Fixed64 traits
  352. ///
  353. public extension ProtobufFixed64 {
  354. public static func protobufWireType() -> Int { return 1 }
  355. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: UInt64) {
  356. encoder.putFixedUInt64(value: value.littleEndian)
  357. }
  358. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout BaseType?) throws -> Bool {
  359. assert(fixed8.count == 8)
  360. var i: UInt64 = 0
  361. withUnsafeMutablePointer(to: &i) { ip -> Void in
  362. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  363. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  364. dest.initialize(from: src, count: 8)
  365. }
  366. }
  367. value = i
  368. return true
  369. }
  370. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout [BaseType]) throws -> Bool {
  371. assert(fixed8.count == 8)
  372. var i: UInt64 = 0
  373. withUnsafeMutablePointer(to: &i) { ip -> Void in
  374. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  375. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  376. dest.initialize(from: src, count: 8)
  377. }
  378. }
  379. value.append(i)
  380. return true
  381. }
  382. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  383. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  384. while let t = try decoder.decodeFixed64() {
  385. value.append(t)
  386. }
  387. return true
  388. }
  389. }
  390. ///
  391. /// SFixed32 traits
  392. ///
  393. public extension ProtobufSFixed32 {
  394. public static func protobufWireType() -> Int { return 5 }
  395. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int32) {
  396. encoder.putFixedUInt32(value: UInt32(bitPattern: value))
  397. }
  398. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout BaseType?) throws -> Bool {
  399. assert(fixed4.count == 4)
  400. var i: Int32 = 0
  401. withUnsafeMutablePointer(to: &i) { ip -> Void in
  402. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  403. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  404. dest.initialize(from: src, count: 4)
  405. }
  406. }
  407. value = i
  408. return true
  409. }
  410. public static func setFromProtobufFixed4(fixed4: [UInt8], value: inout [BaseType]) throws -> Bool {
  411. assert(fixed4.count == 4)
  412. var i: Int32 = 0
  413. withUnsafeMutablePointer(to: &i) { ip -> Void in
  414. ip.withMemoryRebound(to: UInt8.self, capacity: 4) { dest -> () in
  415. let src = UnsafeMutablePointer<UInt8>(mutating: fixed4)
  416. dest.initialize(from: src, count: 4)
  417. }
  418. }
  419. value.append(i)
  420. return true
  421. }
  422. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  423. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  424. while let t = try decoder.decodeSFixed32() {
  425. value.append(t)
  426. }
  427. return true
  428. }
  429. }
  430. ///
  431. /// SFixed64 traits
  432. ///
  433. public extension ProtobufSFixed64 {
  434. public static func protobufWireType() -> Int { return 1 }
  435. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Int64) {
  436. encoder.putFixedUInt64(value: UInt64(bitPattern: value.littleEndian))
  437. }
  438. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout BaseType?) throws -> Bool {
  439. assert(fixed8.count == 8)
  440. var i: Int64 = 0
  441. withUnsafeMutablePointer(to: &i) { ip -> Void in
  442. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  443. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  444. dest.initialize(from: src, count: 8)
  445. }
  446. }
  447. value = i
  448. return true
  449. }
  450. public static func setFromProtobufFixed8(fixed8: [UInt8], value: inout [BaseType]) throws -> Bool {
  451. assert(fixed8.count == 8)
  452. var i: Int64 = 0
  453. withUnsafeMutablePointer(to: &i) { ip -> Void in
  454. ip.withMemoryRebound(to: UInt8.self, capacity: 8) { dest -> () in
  455. let src = UnsafeMutablePointer<UInt8>(mutating: fixed8)
  456. dest.initialize(from: src, count: 8)
  457. }
  458. }
  459. value.append(i)
  460. return true
  461. }
  462. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  463. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  464. while let t = try decoder.decodeSFixed64() {
  465. value.append(t)
  466. }
  467. return true
  468. }
  469. }
  470. ///
  471. /// Bool traits
  472. ///
  473. public extension ProtobufBool {
  474. public static func protobufWireType() -> Int { return 0 }
  475. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Bool) {
  476. encoder.putBoolValue(value: value)
  477. }
  478. public static func setFromProtobufVarint(varint: UInt64, value: inout BaseType?) throws -> Bool {
  479. value = (varint != 0)
  480. return true
  481. }
  482. public static func setFromProtobufVarint(varint: UInt64, value: inout [BaseType]) throws -> Bool {
  483. value.append(varint != 0)
  484. return true
  485. }
  486. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [BaseType]) throws -> Bool {
  487. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  488. while let t = try decoder.decodeBool() {
  489. value.append(t)
  490. }
  491. return true
  492. }
  493. }
  494. ///
  495. /// String traits
  496. ///
  497. private func bufferToString(buffer: UnsafeBufferPointer<UInt8>) -> String? {
  498. var s = ""
  499. var bytes = buffer.makeIterator()
  500. var utf8Decoder = UTF8()
  501. while true {
  502. switch utf8Decoder.decode(&bytes) {
  503. case .scalarValue(let scalar): s.append(String(scalar))
  504. case .emptyInput: return s
  505. case .error: return nil
  506. }
  507. }
  508. }
  509. public extension ProtobufString {
  510. public static func protobufWireType() -> Int { return 2 }
  511. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: String) {
  512. encoder.putStringValue(value: value)
  513. }
  514. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout String?) throws -> Bool {
  515. if let s = bufferToString(buffer: buffer) {
  516. value = s
  517. return true
  518. }
  519. throw ProtobufDecodingError.invalidUTF8
  520. }
  521. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [String]) throws -> Bool {
  522. if let s = bufferToString(buffer: buffer) {
  523. value.append(s)
  524. return true
  525. }
  526. throw ProtobufDecodingError.invalidUTF8
  527. }
  528. }
  529. ///
  530. /// Bytes traits
  531. ///
  532. public extension ProtobufBytes {
  533. public static func protobufWireType() -> Int { return 2 }
  534. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: [UInt8]) {
  535. encoder.putBytesValue(value: value)
  536. }
  537. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [UInt8]?) throws -> Bool {
  538. value = [UInt8](buffer)
  539. return true
  540. }
  541. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [[UInt8]]) throws -> Bool {
  542. value.append([UInt8](buffer))
  543. return true
  544. }
  545. }
  546. //
  547. // Enum traits
  548. //
  549. extension ProtobufEnum where RawValue == Int {
  550. public static func protobufWireType() -> Int { return 0 }
  551. public static func decodeOptionalField(decoder: inout ProtobufFieldDecoder, value: inout BaseType?) throws -> Bool {
  552. return try decoder.decodeOptionalField(fieldType: Self.self, value: &value)
  553. }
  554. public static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Self) {
  555. encoder.putVarInt(value: value.rawValue)
  556. }
  557. public static func setFromProtobufVarint(varint: UInt64, value: inout Self?) throws -> Bool {
  558. if let v = Self(rawValue: Int(Int32(truncatingBitPattern: varint))) {
  559. value = v
  560. return true
  561. } else {
  562. return false
  563. }
  564. }
  565. public static func setFromProtobufVarint(varint: UInt64, value: inout [Self]) throws -> Bool {
  566. if let v = Self(rawValue: Int(Int32(truncatingBitPattern: varint))) {
  567. value.append(v)
  568. return true
  569. } else {
  570. return false
  571. }
  572. }
  573. public static func setFromProtobufBuffer(buffer: UnsafeBufferPointer<UInt8>, value: inout [Self]) throws -> Bool {
  574. var decoder = ProtobufBinaryDecoder(protobufPointer: buffer)
  575. while let t = try decoder.decodeInt32() {
  576. if let e = Self(rawValue:Int(t)) {
  577. value.append(e)
  578. }
  579. }
  580. return true
  581. }
  582. }
  583. ///
  584. /// Messages
  585. ///
  586. public protocol ProtobufBinaryMessageBase: ProtobufMessageBase {
  587. // Serialize to protobuf
  588. func serializeProtobuf() throws -> [UInt8]
  589. // Decode from protobuf
  590. #if !os(Linux)
  591. init(protobuf: Data) throws
  592. init(protobuf: Data, extensions: ProtobufExtensionSet?) throws
  593. #endif
  594. init(protobuf: [UInt8]) throws
  595. init(protobuf: [UInt8], extensions: ProtobufExtensionSet?) throws
  596. init(protobufBuffer: UnsafeBufferPointer<UInt8>) throws
  597. init(protobufBuffer: UnsafeBufferPointer<UInt8>, extensions: ProtobufExtensionSet?) throws
  598. }
  599. public extension ProtobufBinaryMessageBase {
  600. func serializeProtobuf() throws -> [UInt8] {
  601. return try ProtobufBinaryEncodingVisitor(message: self).buffer
  602. }
  603. static func protobufWireType() -> Int {return 2}
  604. static func serializeProtobufValue(encoder: inout ProtobufBinaryEncoder, value: Self) throws {
  605. let t = try value.serializeProtobuf()
  606. encoder.putBytesValue(value: t)
  607. }
  608. }
  609. public extension ProtobufMessage {
  610. static func decodeProtobufMapValue(decoder: inout ProtobufFieldDecoder, value: inout Self?) throws {
  611. let handled = try decoder.decodeOptionalMessageField(fieldType: Self.self, value: &value)
  612. assert(handled)
  613. }
  614. #if !os(Linux)
  615. init(protobuf: Data) throws {
  616. try self.init(protobuf: protobuf, extensions: nil)
  617. }
  618. init(protobuf: Data, extensions: ProtobufExtensionSet? = nil) throws {
  619. try self.init(protobuf: [UInt8](protobuf), extensions: extensions)
  620. }
  621. #endif
  622. init(protobuf: [UInt8]) throws {
  623. try self.init(protobuf: protobuf, extensions: nil)
  624. }
  625. init(protobuf: [UInt8], extensions: ProtobufExtensionSet? = nil) throws {
  626. self.init()
  627. try protobuf.withUnsafeBufferPointer { (bp) in
  628. var protobufDecoder = ProtobufBinaryDecoder(protobufPointer: bp, extensions: extensions)
  629. try protobufDecoder.decodeFullObject(message: &self)
  630. }
  631. }
  632. init(protobufBuffer: UnsafeBufferPointer<UInt8>) throws {
  633. try self.init(protobufBuffer: protobufBuffer, extensions: nil)
  634. }
  635. init(protobufBuffer: UnsafeBufferPointer<UInt8>, extensions: ProtobufExtensionSet? = nil) throws {
  636. self.init()
  637. var protobufDecoder = ProtobufBinaryDecoder(protobufPointer: protobufBuffer, extensions: extensions)
  638. try protobufDecoder.decodeFullObject(message: &self)
  639. }
  640. }
  641. ///
  642. /// Groups
  643. ///
  644. // TODO: Does something belong here?
  645. ///
  646. /// Maps
  647. ///
  648. public extension ProtobufMap {
  649. }