• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google Inc. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import XCTest
18 @testable import FlatBuffers
19 
20 final class FlatBuffersUnionTests: XCTestCase {
21 
testCreateMonstornull22   func testCreateMonstor() {
23 
24     var b = FlatBufferBuilder(initialSize: 20)
25     let dmg: Int16 = 5
26     let str = "Axe"
27     let axe = b.create(string: str)
28     let weapon = Weapon.createWeapon(builder: &b, offset: axe, dmg: dmg)
29     let weapons = b.createVector(ofOffsets: [weapon])
30     let root = LocalMonster.createMonster(
31       builder: &b,
32       offset: weapons,
33       equipment: .Weapon,
34       equippedOffset: weapon.o)
35     b.finish(offset: root)
36     let buffer = b.sizedByteArray
37     XCTAssertEqual(buffer, [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0])
38     let monster = LocalMonster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
39     XCTAssertEqual(monster.weapon(at: 0)?.dmg, dmg)
40     XCTAssertEqual(monster.weapon(at: 0)?.name, str)
41     XCTAssertEqual(monster.weapon(at: 0)?.nameVector, [65, 120, 101])
42     let p: Weapon? = monster.equiped()
43     XCTAssertEqual(p?.dmg, dmg)
44     XCTAssertEqual(p?.name, str)
45     XCTAssertEqual(p?.nameVector, [65, 120, 101])
46   }
47 
testEndTableFinishnull48   func testEndTableFinish() {
49     var builder = FlatBufferBuilder(initialSize: 20)
50     let sword = builder.create(string: "Sword")
51     let axe = builder.create(string: "Axe")
52     let weaponOne = Weapon.createWeapon(builder: &builder, offset: sword, dmg: 3)
53     let weaponTwo = Weapon.createWeapon(builder: &builder, offset: axe, dmg: 5)
54     let name = builder.create(string: "Orc")
55     let inventory: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
56     let inv = builder.createVector(inventory, size: 10)
57     let weapons = builder.createVector(ofOffsets: [weaponOne, weaponTwo])
58     let path = builder.createVector(ofStructs: [
59       Vec(x: 4.0, y: 5.0, z: 6.0),
60       Vec(x: 1.0, y: 2.0, z: 3.0),
61     ])
62     let orc = FinalMonster.createMonster(
63       builder: &builder,
64       position: Vec(x: 1, y: 2, z: 3),
65       hp: 300,
66       name: name,
67       inventory: inv,
68       color: .red,
69       weapons: weapons,
70       equipment: .Weapon,
71       equippedOffset: weaponTwo,
72       path: path)
73     builder.finish(offset: orc)
74     XCTAssertEqual(builder.sizedByteArray, [32, 0, 0, 0, 0, 0, 26, 0, 48, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15, 0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 76, 0, 0, 0, 0, 0, 44, 1, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 52, 0, 0, 0, 28, 0, 0, 0, 10, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 3, 0, 0, 0, 79, 114, 99, 0, 244, 255, 255, 255, 0, 0, 5, 0, 24, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 3, 0, 12, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0, 5, 0, 0, 0, 83, 119, 111, 114, 100, 0, 0, 0])
75   }
76 
testEnumVectornull77   func testEnumVector() {
78     let vectorOfEnums: [ColorsNameSpace.RGB] = [.blue, .green]
79 
80     var builder = FlatBufferBuilder(initialSize: 1)
81     let off = builder.createVector(vectorOfEnums)
82     let start = ColorsNameSpace.Monster.startMonster(&builder)
83     ColorsNameSpace.Monster.add(colors: off, &builder)
84     let end = ColorsNameSpace.Monster.endMonster(&builder, start: start)
85     builder.finish(offset: end)
86     XCTAssertEqual(builder.sizedByteArray, [12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0])
87     let monster = ColorsNameSpace.Monster.getRootAsMonster(bb: builder.buffer)
88     XCTAssertEqual(monster.colorsCount, 2)
89     XCTAssertEqual(monster.colors(at: 0), .blue)
90     XCTAssertEqual(monster.colors(at: 1), .green)
91   }
92 
testUnionVectornull93   func testUnionVector() {
94     var fb = FlatBufferBuilder()
95 
96     let swordDmg: Int32 = 8
97     let attackStart = Attacker.startAttacker(&fb)
98     Attacker.add(swordAttackDamage: swordDmg, &fb)
99     let attack = Attacker.endAttacker(&fb, start: attackStart)
100 
101     let characterType: [Character] = [.belle, .mulan, .bookfan]
102 
103     let characters = [
104       fb.create(struct: BookReader(booksRead: 7)),
105       attack,
106       fb.create(struct: BookReader(booksRead: 2)),
107     ]
108     let types = fb.createVector(characterType)
109     let characterVector = fb.createVector(ofOffsets: characters)
110     let end = Movie.createMovie(
111       &fb,
112       charactersTypeVectorOffset: types,
113       charactersVectorOffset: characterVector)
114     Movie.finish(&fb, end: end)
115 
116     var movie = Movie.getRootAsMovie(bb: fb.buffer)
117     XCTAssertEqual(movie.charactersTypeCount, Int32(characterType.count))
118     XCTAssertEqual(movie.charactersCount, Int32(characters.count))
119 
120     for i in 0..<movie.charactersTypeCount {
121       XCTAssertEqual(movie.charactersType(at: i), characterType[Int(i)])
122     }
123 
124     XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
125     XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
126     XCTAssertEqual(movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead, 2)
127 
128     var objc: MovieT? = movie.unpack()
129     XCTAssertEqual(movie.charactersTypeCount, Int32(objc?.characters.count ?? 0))
130     XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, (objc?.characters[0]?.value as? BookReader)?.booksRead)
131     fb.clear()
132     let newMovie = Movie.pack(&fb, obj: &objc)
133     fb.finish(offset: newMovie)
134 
135     let packedMovie = Movie.getRootAsMovie(bb: fb.buffer)
136 
137     XCTAssertEqual(packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead)
138     XCTAssertEqual(packedMovie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage)
139     XCTAssertEqual(packedMovie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead, movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead)
140   }
141 
testStringUnionnull142   func testStringUnion() {
143     let string = "Awesome \\\\t\t\nstring!"
144     var fb = FlatBufferBuilder()
145     let stringOffset = fb.create(string: string)
146     let characterType: [Character] = [.bookfan, .other]
147 
148     let characters = [
149       fb.create(struct: BookReader(booksRead: 7)),
150       stringOffset,
151     ]
152     let types = fb.createVector(characterType)
153     let characterVector = fb.createVector(ofOffsets: characters)
154 
155     let end = Movie.createMovie(
156       &fb,
157       mainCharacterType: .other,
158       mainCharacterOffset: Offset(offset: stringOffset.o),
159       charactersTypeVectorOffset: types,
160       charactersVectorOffset: characterVector)
161     Movie.finish(&fb, end: end)
162 
163     var movie = Movie.getRootAsMovie(bb: fb.sizedBuffer)
164     XCTAssertEqual(movie.mainCharacter(type: String.self), string)
165     XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
166     XCTAssertEqual(movie.characters(at: 1, type: String.self), string)
167 
168     var objc: MovieT? = movie.unpack()
169     XCTAssertEqual(objc?.mainCharacter?.value as? String, string)
170     XCTAssertEqual((objc?.characters[0]?.value as? BookReader)?.booksRead, 7)
171     XCTAssertEqual(objc?.characters[1]?.value as? String, string)
172     fb.clear()
173     let newMovie = Movie.pack(&fb, obj: &objc)
174     fb.finish(offset: newMovie)
175 
176     let packedMovie = Movie.getRootAsMovie(bb: fb.buffer)
177     XCTAssertEqual(packedMovie.mainCharacter(type: String.self), string)
178     XCTAssertEqual(packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
179     XCTAssertEqual(packedMovie.characters(at: 1, type: String.self), string)
180   }
181 }
182 
183 public enum ColorsNameSpace {
184 
185   enum RGB: Int32, Enum {
186     typealias T = Int32
187     static var byteSize: Int { MemoryLayout<Int32>.size }
188     var value: Int32 { rawValue }
189     case red = 0, green = 1, blue = 2
190   }
191 
192   struct Monster: FlatBufferObject {
193     var __buffer: ByteBuffer! { _accessor.bb }
194 
195     private var _accessor: Table
getRootAsMonsternull196     static func getRootAsMonster(bb: ByteBuffer) -> Monster { Monster(Table(
197       bb: bb,
198       position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
199 
200     init(_ t: Table) { _accessor = t }
201     init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
202 
203     public var colorsCount: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.vector(count: o) }
colorsnull204     public func colors(at index: Int32) -> ColorsNameSpace.RGB? { let o = _accessor.offset(4); return o == 0 ? ColorsNameSpace.RGB(rawValue: 0)! : ColorsNameSpace.RGB(rawValue: _accessor.directRead(
205       of: Int32.self,
206       offset: _accessor.vector(at: o) + index * 4)) }
startMonsternull207     static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
addnull208     static func add(colors: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(
209       offset: colors,
210       at: 4)  }
endMonsternull211     static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
212   }
213 }
214 
215 
216 enum Equipment: Byte { case none, Weapon }
217 
218 enum Color3: Int8 { case red = 0, green, blue }
219 
220 struct FinalMonster {
221 
222   @inlinable
223   static func createMonster(
224     builder: inout FlatBufferBuilder,
225     position: Vec,
226     hp: Int16,
227     name: Offset,
228     inventory: Offset,
229     color: Color3,
230     weapons: Offset,
231     equipment: Equipment = .none,
232     equippedOffset: Offset,
233     path: Offset) -> Offset
234   {
235     let start = builder.startTable(with: 11)
236     builder.create(struct: position, position: 4)
237     builder.add(element: hp, def: 100, at: 8)
238     builder.add(offset: name, at: 10)
239     builder.add(offset: inventory, at: 14)
240     builder.add(element: color.rawValue, def: Color3.green.rawValue, at: 16)
241     builder.add(offset: weapons, at: 18)
242     builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 20)
243     builder.add(offset: equippedOffset, at: 22)
244     builder.add(offset: path, at: 24)
245     return Offset(offset: builder.endTable(at: start))
246   }
247 }
248 
249 struct LocalMonster {
250 
251   private var __t: Table
252 
253   init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o) }
254   init(_ t: Table) { __t = t }
255 
weaponnull256   func weapon(at index: Int32) -> Weapon? { let o = __t.offset(4); return o == 0 ? nil : Weapon.assign(
257     __t.indirect(__t.vector(at: o) + (index * 4)),
258     __t.bb) }
259 
equiped<T: FlatBufferObject>null260   func equiped<T: FlatBufferObject>() -> T? {
261     let o = __t.offset(8); return o == 0 ? nil : __t.union(o)
262   }
263 
getRootAsMonsternull264   static func getRootAsMonster(bb: ByteBuffer) -> LocalMonster {
265     LocalMonster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
266   }
267 
268   @inlinable
269   static func createMonster(
270     builder: inout FlatBufferBuilder,
271     offset: Offset,
272     equipment: Equipment = .none,
273     equippedOffset: UOffset) -> Offset
274   {
275     let start = builder.startTable(with: 3)
276     builder.add(element: equippedOffset, def: 0, at: 8)
277     builder.add(offset: offset, at: 4)
278     builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 6)
279     return Offset(offset: builder.endTable(at: start))
280   }
281 }
282 
283 struct Weapon: FlatBufferObject {
284 
285   var __buffer: ByteBuffer! { __t.bb }
286 
287   static let offsets: (name: VOffset, dmg: VOffset) = (4, 6)
288   private var __t: Table
289 
290   init(_ t: Table) { __t = t }
291   init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o)}
292 
293   var dmg: Int16 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int16.self, at: o) }
294   var nameVector: [UInt8]? { __t.getVector(at: 4) }
295   var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
296 
assignnull297   static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { Weapon(Table(bb: bb, position: i)) }
298 
299   @inlinable
300   static func createWeapon(
301     builder: inout FlatBufferBuilder,
302     offset: Offset,
303     dmg: Int16) -> Offset
304   {
305     let _start = builder.startTable(with: 2)
306     Weapon.add(builder: &builder, name: offset)
307     Weapon.add(builder: &builder, dmg: dmg)
308     return Weapon.end(builder: &builder, startOffset: _start)
309   }
310 
311   @inlinable
endnull312   static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset {
313     Offset(offset: builder.endTable(at: startOffset))
314   }
315 
316   @inlinable
addnull317   static func add(builder: inout FlatBufferBuilder, name: Offset) {
318     builder.add(offset: name, at: Weapon.offsets.name)
319   }
320 
321   @inlinable
addnull322   static func add(builder: inout FlatBufferBuilder, dmg: Int16) {
323     builder.add(element: dmg, def: 0, at: Weapon.offsets.dmg)
324   }
325 }
326