xref: /aosp_15_r20/external/flatbuffers/swift/Sources/FlatBuffers/Root.swift (revision 890232f25432b36107d06881e0a25aaa6b473652)
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