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 #if !os(WASI)
18 import Foundation
19 #else
20 import SwiftOverlayShims
21 #endif
22
23 /// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
24 /// And would verify that the buffer passed is a valid `Flatbuffers` Object.
25 /// - Parameters:
26 /// - byteBuffer: Buffer that needs to be checked and read
27 /// - options: Verifier options
28 /// - Throws: FlatbuffersErrors
29 /// - Returns: Returns a valid, checked Flatbuffers object
30 ///
31 /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
32 /// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
33 public func getPrefixedSizeCheckedRoot<T: FlatBufferObject & Verifiable>(
34 byteBuffer: inout ByteBuffer,
35 fileId: String? = nil,
36 options: VerifierOptions = .init()) throws -> T
37 {
38 byteBuffer.skipPrefix()
39 return try getCheckedRoot(
40 byteBuffer: &byteBuffer,
41 fileId: fileId,
42 options: options)
43 }
44
45 /// Takes in a prefixed sized buffer, where we check if the sized buffer is equal to prefix size.
46 /// And would verify that the buffer passed is a valid `Flatbuffers` Object.
47 /// - Parameters:
48 /// - byteBuffer: Buffer that needs to be checked and read
49 /// - options: Verifier options
50 /// - Throws: FlatbuffersErrors
51 /// - Returns: Returns a valid, checked Flatbuffers object
52 ///
53 /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
54 /// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
55 public func getCheckedPrefixedSizeRoot<T: FlatBufferObject & Verifiable>(
56 byteBuffer: inout ByteBuffer,
57 fileId: String? = nil,
58 options: VerifierOptions = .init()) throws -> T
59 {
60 let prefix = byteBuffer.skipPrefix()
61 if prefix != byteBuffer.size {
62 throw FlatbuffersErrors.prefixedSizeNotEqualToBufferSize
63 }
64 return try getCheckedRoot(
65 byteBuffer: &byteBuffer,
66 fileId: fileId,
67 options: options)
68 }
69
70 /// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
71 /// Returns a `NON-Checked` flatbuffers object
72 /// - Parameter byteBuffer: Buffer that contains data
73 /// - Returns: Returns a Flatbuffers object
74 ///
75 /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
76 /// the ``ByteBuffer`` and then calls ``getRoot(byteBuffer:)``
getPrefixedSizeRoot<T: FlatBufferObject>null77 public func getPrefixedSizeRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer)
78 -> T
79 {
80 byteBuffer.skipPrefix()
81 return getRoot(byteBuffer: &byteBuffer)
82
83 }
84
85 /// Verifies that the buffer passed is a valid `Flatbuffers` Object.
86 /// - Parameters:
87 /// - byteBuffer: Buffer that needs to be checked and read
88 /// - options: Verifier options
89 /// - Throws: FlatbuffersErrors
90 /// - Returns: Returns a valid, checked Flatbuffers object
91 ///
92 /// ``getCheckedRoot(byteBuffer:options:)`` Takes in a ``ByteBuffer`` and verifies
93 /// that by creating a ``Verifier`` and checkes if all the `Bytes` and correctly aligned
94 /// and within the ``ByteBuffer`` range.
95 public func getCheckedRoot<T: FlatBufferObject & Verifiable>(
96 byteBuffer: inout ByteBuffer,
97 fileId: String? = nil,
98 options: VerifierOptions = .init()) throws -> T
99 {
100 var verifier = try Verifier(buffer: &byteBuffer, options: options)
101 if let fileId = fileId {
102 try verifier.verify(id: fileId)
103 }
104 try ForwardOffset<T>.verify(&verifier, at: 0, of: T.self)
105 return T.init(
106 byteBuffer,
107 o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
108 Int32(byteBuffer.reader))
109 }
110
111 /// Returns a `NON-Checked` flatbuffers object
112 /// - Parameter byteBuffer: Buffer that contains data
113 /// - Returns: Returns a Flatbuffers object
getRoot<T: FlatBufferObject>null114 public func getRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer) -> T {
115 T.init(
116 byteBuffer,
117 o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
118 Int32(byteBuffer.reader))
119 }
120