1*890232f2SAndroid Build Coastguard Worker /*
2*890232f2SAndroid Build Coastguard Worker * Copyright 2021 Google Inc. All rights reserved.
3*890232f2SAndroid Build Coastguard Worker *
4*890232f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*890232f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*890232f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*890232f2SAndroid Build Coastguard Worker *
8*890232f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*890232f2SAndroid Build Coastguard Worker *
10*890232f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*890232f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*890232f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*890232f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*890232f2SAndroid Build Coastguard Worker * limitations under the License.
15*890232f2SAndroid Build Coastguard Worker */
16*890232f2SAndroid Build Coastguard Worker
17*890232f2SAndroid Build Coastguard Worker #if !os(WASI)
18*890232f2SAndroid Build Coastguard Worker import Foundation
19*890232f2SAndroid Build Coastguard Worker #else
20*890232f2SAndroid Build Coastguard Worker import SwiftOverlayShims
21*890232f2SAndroid Build Coastguard Worker #endif
22*890232f2SAndroid Build Coastguard Worker
23*890232f2SAndroid Build Coastguard Worker /// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
24*890232f2SAndroid Build Coastguard Worker /// And would verify that the buffer passed is a valid `Flatbuffers` Object.
25*890232f2SAndroid Build Coastguard Worker /// - Parameters:
26*890232f2SAndroid Build Coastguard Worker /// - byteBuffer: Buffer that needs to be checked and read
27*890232f2SAndroid Build Coastguard Worker /// - options: Verifier options
28*890232f2SAndroid Build Coastguard Worker /// - Throws: FlatbuffersErrors
29*890232f2SAndroid Build Coastguard Worker /// - Returns: Returns a valid, checked Flatbuffers object
30*890232f2SAndroid Build Coastguard Worker ///
31*890232f2SAndroid Build Coastguard Worker /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
32*890232f2SAndroid Build Coastguard Worker /// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
33*890232f2SAndroid Build Coastguard Worker public func getPrefixedSizeCheckedRoot<T: FlatBufferObject & Verifiable>(
34*890232f2SAndroid Build Coastguard Worker byteBuffer: inout ByteBuffer,
35*890232f2SAndroid Build Coastguard Worker fileId: String? = nil,
36*890232f2SAndroid Build Coastguard Worker options: VerifierOptions = .init()) throws -> T
37*890232f2SAndroid Build Coastguard Worker {
38*890232f2SAndroid Build Coastguard Worker byteBuffer.skipPrefix()
39*890232f2SAndroid Build Coastguard Worker return try getCheckedRoot(
40*890232f2SAndroid Build Coastguard Worker byteBuffer: &byteBuffer,
41*890232f2SAndroid Build Coastguard Worker fileId: fileId,
42*890232f2SAndroid Build Coastguard Worker options: options)
43*890232f2SAndroid Build Coastguard Worker }
44*890232f2SAndroid Build Coastguard Worker
45*890232f2SAndroid Build Coastguard Worker /// Takes in a prefixed sized buffer, where we check if the sized buffer is equal to prefix size.
46*890232f2SAndroid Build Coastguard Worker /// And would verify that the buffer passed is a valid `Flatbuffers` Object.
47*890232f2SAndroid Build Coastguard Worker /// - Parameters:
48*890232f2SAndroid Build Coastguard Worker /// - byteBuffer: Buffer that needs to be checked and read
49*890232f2SAndroid Build Coastguard Worker /// - options: Verifier options
50*890232f2SAndroid Build Coastguard Worker /// - Throws: FlatbuffersErrors
51*890232f2SAndroid Build Coastguard Worker /// - Returns: Returns a valid, checked Flatbuffers object
52*890232f2SAndroid Build Coastguard Worker ///
53*890232f2SAndroid Build Coastguard Worker /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
54*890232f2SAndroid Build Coastguard Worker /// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
55*890232f2SAndroid Build Coastguard Worker public func getCheckedPrefixedSizeRoot<T: FlatBufferObject & Verifiable>(
56*890232f2SAndroid Build Coastguard Worker byteBuffer: inout ByteBuffer,
57*890232f2SAndroid Build Coastguard Worker fileId: String? = nil,
58*890232f2SAndroid Build Coastguard Worker options: VerifierOptions = .init()) throws -> T
59*890232f2SAndroid Build Coastguard Worker {
60*890232f2SAndroid Build Coastguard Worker let prefix = byteBuffer.skipPrefix()
61*890232f2SAndroid Build Coastguard Worker if prefix != byteBuffer.size {
62*890232f2SAndroid Build Coastguard Worker throw FlatbuffersErrors.prefixedSizeNotEqualToBufferSize
63*890232f2SAndroid Build Coastguard Worker }
64*890232f2SAndroid Build Coastguard Worker return try getCheckedRoot(
65*890232f2SAndroid Build Coastguard Worker byteBuffer: &byteBuffer,
66*890232f2SAndroid Build Coastguard Worker fileId: fileId,
67*890232f2SAndroid Build Coastguard Worker options: options)
68*890232f2SAndroid Build Coastguard Worker }
69*890232f2SAndroid Build Coastguard Worker
70*890232f2SAndroid Build Coastguard Worker /// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
71*890232f2SAndroid Build Coastguard Worker /// Returns a `NON-Checked` flatbuffers object
72*890232f2SAndroid Build Coastguard Worker /// - Parameter byteBuffer: Buffer that contains data
73*890232f2SAndroid Build Coastguard Worker /// - Returns: Returns a Flatbuffers object
74*890232f2SAndroid Build Coastguard Worker ///
75*890232f2SAndroid Build Coastguard Worker /// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
76*890232f2SAndroid Build Coastguard Worker /// the ``ByteBuffer`` and then calls ``getRoot(byteBuffer:)``
getPrefixedSizeRoot<T: FlatBufferObject>null77*890232f2SAndroid Build Coastguard Worker public func getPrefixedSizeRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer)
78*890232f2SAndroid Build Coastguard Worker -> T
79*890232f2SAndroid Build Coastguard Worker {
80*890232f2SAndroid Build Coastguard Worker byteBuffer.skipPrefix()
81*890232f2SAndroid Build Coastguard Worker return getRoot(byteBuffer: &byteBuffer)
82*890232f2SAndroid Build Coastguard Worker
83*890232f2SAndroid Build Coastguard Worker }
84*890232f2SAndroid Build Coastguard Worker
85*890232f2SAndroid Build Coastguard Worker /// Verifies that the buffer passed is a valid `Flatbuffers` Object.
86*890232f2SAndroid Build Coastguard Worker /// - Parameters:
87*890232f2SAndroid Build Coastguard Worker /// - byteBuffer: Buffer that needs to be checked and read
88*890232f2SAndroid Build Coastguard Worker /// - options: Verifier options
89*890232f2SAndroid Build Coastguard Worker /// - Throws: FlatbuffersErrors
90*890232f2SAndroid Build Coastguard Worker /// - Returns: Returns a valid, checked Flatbuffers object
91*890232f2SAndroid Build Coastguard Worker ///
92*890232f2SAndroid Build Coastguard Worker /// ``getCheckedRoot(byteBuffer:options:)`` Takes in a ``ByteBuffer`` and verifies
93*890232f2SAndroid Build Coastguard Worker /// that by creating a ``Verifier`` and checkes if all the `Bytes` and correctly aligned
94*890232f2SAndroid Build Coastguard Worker /// and within the ``ByteBuffer`` range.
95*890232f2SAndroid Build Coastguard Worker public func getCheckedRoot<T: FlatBufferObject & Verifiable>(
96*890232f2SAndroid Build Coastguard Worker byteBuffer: inout ByteBuffer,
97*890232f2SAndroid Build Coastguard Worker fileId: String? = nil,
98*890232f2SAndroid Build Coastguard Worker options: VerifierOptions = .init()) throws -> T
99*890232f2SAndroid Build Coastguard Worker {
100*890232f2SAndroid Build Coastguard Worker var verifier = try Verifier(buffer: &byteBuffer, options: options)
101*890232f2SAndroid Build Coastguard Worker if let fileId = fileId {
102*890232f2SAndroid Build Coastguard Worker try verifier.verify(id: fileId)
103*890232f2SAndroid Build Coastguard Worker }
104*890232f2SAndroid Build Coastguard Worker try ForwardOffset<T>.verify(&verifier, at: 0, of: T.self)
105*890232f2SAndroid Build Coastguard Worker return T.init(
106*890232f2SAndroid Build Coastguard Worker byteBuffer,
107*890232f2SAndroid Build Coastguard Worker o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
108*890232f2SAndroid Build Coastguard Worker Int32(byteBuffer.reader))
109*890232f2SAndroid Build Coastguard Worker }
110*890232f2SAndroid Build Coastguard Worker
111*890232f2SAndroid Build Coastguard Worker /// Returns a `NON-Checked` flatbuffers object
112*890232f2SAndroid Build Coastguard Worker /// - Parameter byteBuffer: Buffer that contains data
113*890232f2SAndroid Build Coastguard Worker /// - Returns: Returns a Flatbuffers object
getRoot<T: FlatBufferObject>null114*890232f2SAndroid Build Coastguard Worker public func getRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer) -> T {
115*890232f2SAndroid Build Coastguard Worker T.init(
116*890232f2SAndroid Build Coastguard Worker byteBuffer,
117*890232f2SAndroid Build Coastguard Worker o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
118*890232f2SAndroid Build Coastguard Worker Int32(byteBuffer.reader))
119*890232f2SAndroid Build Coastguard Worker }
120