blob: 0c593dcb44e11aa6771933eb1576e4ab70b345cf [file] [log] [blame]
James Kuszmaul8e62b022022-03-22 09:33:25 -07001/*
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
Austin Schuh2dd86a92022-09-14 21:19:23 -070017#if !os(WASI)
James Kuszmaul8e62b022022-03-22 09:33:25 -070018import Foundation
Austin Schuh2dd86a92022-09-14 21:19:23 -070019#else
20import SwiftOverlayShims
21#endif
James Kuszmaul8e62b022022-03-22 09:33:25 -070022
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:)``
33public func getPrefixedSizeCheckedRoot<T: FlatBufferObject & Verifiable>(
34 byteBuffer: inout ByteBuffer,
Austin Schuh2dd86a92022-09-14 21:19:23 -070035 fileId: String? = nil,
James Kuszmaul8e62b022022-03-22 09:33:25 -070036 options: VerifierOptions = .init()) throws -> T
37{
38 byteBuffer.skipPrefix()
Austin Schuh2dd86a92022-09-14 21:19:23 -070039 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:)``
55public 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)
James Kuszmaul8e62b022022-03-22 09:33:25 -070068}
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:)``
77public 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.
95public func getCheckedRoot<T: FlatBufferObject & Verifiable>(
96 byteBuffer: inout ByteBuffer,
Austin Schuh2dd86a92022-09-14 21:19:23 -070097 fileId: String? = nil,
James Kuszmaul8e62b022022-03-22 09:33:25 -070098 options: VerifierOptions = .init()) throws -> T
99{
100 var verifier = try Verifier(buffer: &byteBuffer, options: options)
Austin Schuh2dd86a92022-09-14 21:19:23 -0700101 if let fileId = fileId {
102 try verifier.verify(id: fileId)
103 }
James Kuszmaul8e62b022022-03-22 09:33:25 -0700104 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
114public 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}