Compare commits

..

4 Commits

Author SHA1 Message Date
Derek Bailey
c92e78a9f8 FlatBuffers Version 22.9.29 (#7557) 2022-09-29 22:12:07 -07:00
Björn Harrtell
d243b904cc [TS] Make strict compliant and improve typings (#7549)
* [TS] Make strict compliant and improve typings

* clang-format

* Code gen harmonize

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-29 15:03:35 -07:00
Raphael Taylor-Davies
374f8fb5fb Rust soundness fixes (#7518)
* Rust soundness fixes

* Second pass

* Make init_from_table unsafe

* Remove SafeSliceAccess

* Clippy

* Remove create_vector_of_strings

* More clippy

* Remove deprecated root type accessors

* More soundness fixes

* Fix EndianScalar for bool

* Add TriviallyTransmutable

* Add debug assertions

* Review comments

* Review feedback
2022-09-29 09:58:49 -04:00
mustiikhalil
dadbff5714 Moves swift package to root of repository so it can be used directly … (#7548)
* Moves swift package to root of repository so it can be used directly from the main repo

Fixing paths for swift directory

* Update swift readme
2022-09-27 14:32:05 -07:00
277 changed files with 3146 additions and 2495 deletions

View File

@@ -4,6 +4,10 @@ All major or breaking changes will be documented in this file, as well as any
new features that should be highlighted. Minor fixes or improvements are not new features that should be highlighted. Minor fixes or improvements are not
necessarily listed. necessarily listed.
## 22.9.29 (Sept 29 2022)
* Rust soundness fixes to avoid the crate from bing labelled unsafe (#7518).
## 22.9.24 (Sept 24 2022) ## 22.9.24 (Sept 24 2022)
* 20 Major releases in a row? Nope, we switched to a new * 20 Major releases in a row? Nope, we switched to a new

View File

@@ -1,6 +1,6 @@
set(VERSION_MAJOR 22) set(VERSION_MAJOR 22)
set(VERSION_MINOR 9) set(VERSION_MINOR 9)
set(VERSION_PATCH 24) set(VERSION_PATCH 29)
set(VERSION_COMMIT 0) set(VERSION_COMMIT 0)
find_program(GIT git) find_program(GIT git)

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'FlatBuffers' s.name = 'FlatBuffers'
s.version = '22.9.24' s.version = '22.9.29'
s.summary = 'FlatBuffers: Memory Efficient Serialization Library' s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
s.description = "FlatBuffers is a cross platform serialization library architected for s.description = "FlatBuffers is a cross platform serialization library architected for
@@ -11,11 +11,11 @@ Pod::Spec.new do |s|
s.homepage = 'https://github.com/google/flatbuffers' s.homepage = 'https://github.com/google/flatbuffers'
s.license = { :type => 'Apache2.0', :file => 'LICENSE' } s.license = { :type => 'Apache2.0', :file => 'LICENSE' }
s.author = { 'mustii' => 'mustii@mmk.one' } s.author = { 'mustii' => 'mustii@mmk.one' }
s.source = { :git => 'https://github.com/mustiikhalil/flatbuffers.git', :tag => s.version.to_s, :submodules => true } s.source = { :git => 'https://github.com/google/flatbuffers.git', :tag => s.version.to_s, :submodules => true }
s.ios.deployment_target = '11.0' s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14' s.osx.deployment_target = '10.14'
s.swift_version = '5.0' s.swift_version = '5.0'
s.source_files = 'Sources/Flatbuffers/*.swift' s.source_files = 'swift/Sources/Flatbuffers/*.swift'
end end

View File

@@ -32,5 +32,6 @@ let package = Package(
.target( .target(
name: "FlatBuffers", name: "FlatBuffers",
dependencies: [], dependencies: [],
path: "swift/Sources",
exclude: ["Documentation.docc/Resources/code/swift"]), exclude: ["Documentation.docc/Resources/code/swift"]),
]) ])

View File

@@ -31,6 +31,7 @@ let package = Package(
targets: [ targets: [
.target( .target(
name: "FlatBuffers", name: "FlatBuffers",
dependencies: []), dependencies: [],
path: "swift/Sources")
]) ])

View File

@@ -36,7 +36,7 @@ class Animal : Table() {
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal()) fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal { fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -1,5 +1,5 @@
name: flat_buffers name: flat_buffers
version: 22.9.24 version: 22.9.29
description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team. description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
homepage: https://github.com/google/flatbuffers homepage: https://github.com/google/flatbuffers
documentation: https://google.github.io/flatbuffers/index.html documentation: https://google.github.io/flatbuffers/index.html

View File

@@ -6,7 +6,7 @@ import FlatBuffers
public struct models_HelloReply: FlatBufferObject, Verifiable { public struct models_HelloReply: FlatBufferObject, Verifiable {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
public var __buffer: ByteBuffer! { return _accessor.bb } public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table private var _accessor: Table
@@ -55,7 +55,7 @@ extension models_HelloReply: Encodable {
public struct models_HelloRequest: FlatBufferObject, Verifiable { public struct models_HelloRequest: FlatBufferObject, Verifiable {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
public var __buffer: ByteBuffer! { return _accessor.bb } public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table private var _accessor: Table

View File

@@ -140,7 +140,7 @@
#define FLATBUFFERS_VERSION_MAJOR 22 #define FLATBUFFERS_VERSION_MAJOR 22
#define FLATBUFFERS_VERSION_MINOR 9 #define FLATBUFFERS_VERSION_MINOR 9
#define FLATBUFFERS_VERSION_REVISION 24 #define FLATBUFFERS_VERSION_REVISION 29
#define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers { namespace flatbuffers {

View File

@@ -10,7 +10,7 @@
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 && static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 && FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 24, FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
namespace reflection { namespace reflection {

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.google.flatbuffers</groupId> <groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId> <artifactId>flatbuffers-java</artifactId>
<version>22.9.24</version> <version>22.9.29</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>FlatBuffers Java API</name> <name>FlatBuffers Java API</name>
<description> <description>

View File

@@ -46,7 +46,7 @@ public class Constants {
Changes to the Java implementation need to be sure to change Changes to the Java implementation need to be sure to change
the version here and in the code generator on every possible the version here and in the code generator on every possible
incompatible change */ incompatible change */
public static void FLATBUFFERS_22_9_24() {} public static void FLATBUFFERS_22_9_29() {}
} }
/// @endcond /// @endcond

View File

@@ -32,6 +32,6 @@ namespace Google.FlatBuffers
Changes to the C# implementation need to be sure to change Changes to the C# implementation need to be sure to change
the version here and in the code generator on every possible the version here and in the code generator on every possible
incompatible change */ incompatible change */
public static void FLATBUFFERS_22_9_24() {} public static void FLATBUFFERS_22_9_29() {}
} }
} }

View File

@@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;net46</TargetFrameworks> <TargetFrameworks>netstandard2.1;netstandard2.0;net46</TargetFrameworks>
<Description>A cross-platform memory efficient serialization library</Description> <Description>A cross-platform memory efficient serialization library</Description>
<PackageVersion>22.9.24</PackageVersion> <PackageVersion>22.9.29</PackageVersion>
<Authors>Google LLC</Authors> <Authors>Google LLC</Authors>
<PackageProjectUrl>https://github.com/google/flatbuffers</PackageProjectUrl> <PackageProjectUrl>https://github.com/google/flatbuffers</PackageProjectUrl>
<RepositoryUrl>https://github.com/google/flatbuffers</RepositoryUrl> <RepositoryUrl>https://github.com/google/flatbuffers</RepositoryUrl>

View File

@@ -1,6 +1,6 @@
{ {
"name": "flatbuffers", "name": "flatbuffers",
"version": "22.9.24", "version": "22.9.29",
"description": "Memory Efficient Serialization Library", "description": "Memory Efficient Serialization Library",
"files": [ "files": [
"js/**/*.js", "js/**/*.js",
@@ -17,6 +17,7 @@
}, },
"scripts": { "scripts": {
"test": "npm run compile && cd tests/ts && python3 ./TypeScriptTest.py", "test": "npm run compile && cd tests/ts && python3 ./TypeScriptTest.py",
"lint": "eslint ts",
"compile": "tsc && tsc -p tsconfig.mjs.json && rollup -c", "compile": "tsc && tsc -p tsconfig.mjs.json && rollup -c",
"prepublishOnly": "npm install --only=dev && npm run compile" "prepublishOnly": "npm install --only=dev && npm run compile"
}, },

View File

@@ -14,4 +14,4 @@
# Placeholder, to be updated during the release process # Placeholder, to be updated during the release process
# by the setup.py # by the setup.py
__version__ = u"22.9.24" __version__ = u"22.9.29"

View File

@@ -17,7 +17,6 @@ no_std = ["core2", "thiserror_core2"]
serialize = ["serde"] serialize = ["serde"]
[dependencies] [dependencies]
smallvec = "1.6.1"
bitflags = "1.2.1" bitflags = "1.2.1"
serde = { version = "1.0", optional = true } serde = { version = "1.0", optional = true }
thiserror = { version = "1.0.30", optional = true } thiserror = { version = "1.0.30", optional = true }

View File

@@ -37,14 +37,18 @@ where
#[allow(clippy::len_without_is_empty)] #[allow(clippy::len_without_is_empty)]
#[allow(clippy::from_over_into)] // TODO(caspern): Go from From to Into. #[allow(clippy::from_over_into)] // TODO(caspern): Go from From to Into.
impl<'a, T: 'a, const N: usize> Array<'a, T, N> { impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
/// # Safety
///
/// buf must be a contiguous array of `T`
///
/// # Panics
///
/// Panics if `buf.len()` is not `size_of::<T>() * N`
#[inline(always)] #[inline(always)]
pub fn new(buf: &'a [u8]) -> Self { pub unsafe fn new(buf: &'a [u8]) -> Self {
assert!(size_of::<T>() * N == buf.len()); assert_eq!(size_of::<T>() * N, buf.len());
Array { Array(buf, PhantomData)
0: buf,
1: PhantomData,
}
} }
#[inline(always)] #[inline(always)]
@@ -61,34 +65,39 @@ impl<'a, T: Follow<'a> + 'a, const N: usize> Array<'a, T, N> {
pub fn get(&self, idx: usize) -> T::Inner { pub fn get(&self, idx: usize) -> T::Inner {
assert!(idx < N); assert!(idx < N);
let sz = size_of::<T>(); let sz = size_of::<T>();
T::follow(self.0, sz * idx) // Safety:
// self.0 was valid for length `N` on construction and have verified `idx < N`
unsafe { T::follow(self.0, sz * idx) }
} }
#[inline(always)] #[inline(always)]
pub fn iter(&self) -> VectorIter<'a, T> { pub fn iter(&self) -> VectorIter<'a, T> {
VectorIter::from_slice(self.0, self.len()) // Safety:
// self.0 was valid for length N on construction
unsafe { VectorIter::from_slice(self.0, self.len()) }
} }
} }
impl<'a, T: Follow<'a> + Debug, const N: usize> Into<[T::Inner; N]> for Array<'a, T, N> { impl<'a, T: Follow<'a> + Debug, const N: usize> From<Array<'a, T, N>> for [T::Inner; N] {
#[inline(always)] fn from(array: Array<'a, T, N>) -> Self {
fn into(self) -> [T::Inner; N] { array_init(|i| array.get(i))
array_init(|i| self.get(i))
} }
} }
// TODO(caspern): Implement some future safe version of SafeSliceAccess.
/// Implement Follow for all possible Arrays that have Follow-able elements. /// Implement Follow for all possible Arrays that have Follow-able elements.
impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> { impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
type Inner = Array<'a, T, N>; type Inner = Array<'a, T, N>;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Array::new(&buf[loc..loc + N * size_of::<T>()]) Array::new(&buf[loc..loc + N * size_of::<T>()])
} }
} }
pub fn emplace_scalar_array<T: EndianScalar, const N: usize>( /// Place an array of EndianScalar into the provided mutable byte slice. Performs
/// endian conversion, if necessary.
/// # Safety
/// Caller must ensure `s.len() >= size_of::<[T; N]>()`
pub unsafe fn emplace_scalar_array<T: EndianScalar, const N: usize>(
buf: &mut [u8], buf: &mut [u8],
loc: usize, loc: usize,
src: &[T; N], src: &[T; N],
@@ -96,14 +105,12 @@ pub fn emplace_scalar_array<T: EndianScalar, const N: usize>(
let mut buf_ptr = buf[loc..].as_mut_ptr(); let mut buf_ptr = buf[loc..].as_mut_ptr();
for item in src.iter() { for item in src.iter() {
let item_le = item.to_little_endian(); let item_le = item.to_little_endian();
unsafe { core::ptr::copy_nonoverlapping(
core::ptr::copy_nonoverlapping( &item_le as *const T::Scalar as *const u8,
&item_le as *const T as *const u8, buf_ptr,
buf_ptr, size_of::<T::Scalar>(),
size_of::<T>(), );
); buf_ptr = buf_ptr.add(size_of::<T::Scalar>());
buf_ptr = buf_ptr.add(size_of::<T>());
}
} }
} }
@@ -124,6 +131,8 @@ where
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit(); let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
let mut ptr_i = array.as_mut_ptr() as *mut T; let mut ptr_i = array.as_mut_ptr() as *mut T;
// Safety:
// array is aligned by T, and has length N
unsafe { unsafe {
for i in 0..N { for i in 0..N {
let value_i = initializer(i); let value_i = initializer(i);
@@ -134,7 +143,7 @@ where
} }
} }
#[cfg(feature="serialize")] #[cfg(feature = "serialize")]
impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N> impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N>
where where
T: 'a + Follow<'a>, T: 'a + Follow<'a>,

View File

@@ -14,26 +14,22 @@
* limitations under the License. * limitations under the License.
*/ */
extern crate smallvec; #[cfg(feature = "no_std")]
use alloc::{vec, vec::Vec};
use core::cmp::max; use core::cmp::max;
use core::iter::{DoubleEndedIterator, ExactSizeIterator}; use core::iter::{DoubleEndedIterator, ExactSizeIterator};
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ptr::write_bytes; use core::ptr::write_bytes;
use core::slice::from_raw_parts;
#[cfg(feature = "no_std")]
use alloc::{vec, vec::Vec};
use crate::endian_scalar::{emplace_scalar, read_scalar_at}; use crate::endian_scalar::emplace_scalar;
use crate::primitives::*; use crate::primitives::*;
use crate::push::{Push, PushAlignment}; use crate::push::{Push, PushAlignment};
use crate::read_scalar;
use crate::table::Table; use crate::table::Table;
use crate::vector::{SafeSliceAccess, Vector}; use crate::vector::Vector;
use crate::vtable::{field_index_to_field_offset, VTable}; use crate::vtable::{field_index_to_field_offset, VTable};
use crate::vtable_writer::VTableWriter; use crate::vtable_writer::VTableWriter;
pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct FieldLoc { struct FieldLoc {
off: UOffsetT, off: UOffsetT,
@@ -121,6 +117,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
{ {
let to_clear = self.owned_buf.len() - self.head; let to_clear = self.owned_buf.len() - self.head;
let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr(); let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
// Safety:
// Verified ptr is valid for `to_clear` above
unsafe { unsafe {
write_bytes(ptr, 0, to_clear); write_bytes(ptr, 0, to_clear);
} }
@@ -153,7 +151,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
self.make_space(sz); self.make_space(sz);
{ {
let (dst, rest) = (&mut self.owned_buf[self.head..]).split_at_mut(sz); let (dst, rest) = (&mut self.owned_buf[self.head..]).split_at_mut(sz);
x.push(dst, rest); // Safety:
// Called make_space above
unsafe { x.push(dst, rest.len()) };
} }
WIPOffset::new(self.used_space() as UOffsetT) WIPOffset::new(self.used_space() as UOffsetT)
} }
@@ -309,73 +309,32 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
WIPOffset::new(self.used_space() as UOffsetT) WIPOffset::new(self.used_space() as UOffsetT)
} }
/// Create a vector by memcpy'ing. This is much faster than calling
/// `create_vector`, but the underlying type must be represented as
/// little-endian on the host machine. This property is encoded in the
/// type system through the SafeSliceAccess trait. The following types are
/// always safe, on any platform: bool, u8, i8, and any
/// FlatBuffers-generated struct.
#[inline]
pub fn create_vector_direct<'a: 'b, 'b, T: SafeSliceAccess + Push + Sized + 'b>(
&'a mut self,
items: &'b [T],
) -> WIPOffset<Vector<'fbb, T>> {
self.assert_not_nested(
"create_vector_direct can not be called when a table or vector is under construction",
);
let elem_size = T::size();
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
let bytes = {
let ptr = items.as_ptr() as *const T as *const u8;
unsafe { from_raw_parts(ptr, items.len() * elem_size) }
};
self.push_bytes_unprefixed(bytes);
self.push(items.len() as UOffsetT);
WIPOffset::new(self.used_space() as UOffsetT)
}
/// Create a vector of strings.
///
/// Speed-sensitive users may wish to reduce memory usage by creating the
/// vector manually: use `start_vector`, `push`, and `end_vector`.
#[inline]
pub fn create_vector_of_strings<'a, 'b>(
&'a mut self,
xs: &'b [&'b str],
) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction");
// internally, smallvec can be a stack-allocated or heap-allocated vector:
// if xs.len() > N_SMALLVEC_STRING_VECTOR_CAPACITY then it will overflow to the heap.
let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> =
smallvec::SmallVec::with_capacity(xs.len());
unsafe {
offsets.set_len(xs.len());
}
// note that this happens in reverse, because the buffer is built back-to-front:
for (i, &s) in xs.iter().enumerate().rev() {
let o = self.create_string(s);
offsets[i] = o;
}
self.create_vector(&offsets[..])
}
/// Create a vector of Push-able objects. /// Create a vector of Push-able objects.
/// ///
/// Speed-sensitive users may wish to reduce memory usage by creating the /// Speed-sensitive users may wish to reduce memory usage by creating the
/// vector manually: use `start_vector`, `push`, and `end_vector`. /// vector manually: use `start_vector`, `push`, and `end_vector`.
#[inline] #[inline]
pub fn create_vector<'a: 'b, 'b, T: Push + Copy + 'b>( pub fn create_vector<'a: 'b, 'b, T: Push + 'b>(
&'a mut self, &'a mut self,
items: &'b [T], items: &'b [T],
) -> WIPOffset<Vector<'fbb, T::Output>> { ) -> WIPOffset<Vector<'fbb, T::Output>> {
let elem_size = T::size(); let elem_size = T::size();
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET)); let slice_size = items.len() * elem_size;
for i in (0..items.len()).rev() { self.align(slice_size, T::alignment().max_of(SIZE_UOFFSET));
self.push(items[i]); self.ensure_capacity(slice_size + UOffsetT::size());
self.head -= slice_size;
let mut written_len = self.owned_buf.len() - self.head;
let buf = &mut self.owned_buf[self.head..self.head + slice_size];
for (item, out) in items.iter().zip(buf.chunks_exact_mut(elem_size)) {
written_len -= elem_size;
// Safety:
// Called ensure_capacity and aligned to T above
unsafe { item.push(out, written_len) };
} }
WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value()) WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value())
} }
@@ -384,17 +343,18 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// Speed-sensitive users may wish to reduce memory usage by creating the /// Speed-sensitive users may wish to reduce memory usage by creating the
/// vector manually: use `start_vector`, `push`, and `end_vector`. /// vector manually: use `start_vector`, `push`, and `end_vector`.
#[inline] #[inline]
pub fn create_vector_from_iter<T: Push + Copy>( pub fn create_vector_from_iter<T: Push>(
&mut self, &mut self,
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator, items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
) -> WIPOffset<Vector<'fbb, T::Output>> { ) -> WIPOffset<Vector<'fbb, T::Output>> {
let elem_size = T::size(); let elem_size = T::size();
let len = items.len(); self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
self.align(len * elem_size, T::alignment().max_of(SIZE_UOFFSET)); let mut actual = 0;
for item in items.rev() { for item in items.rev() {
self.push(item); self.push(item);
actual += 1;
} }
WIPOffset::new(self.push::<UOffsetT>(len as UOffsetT).value()) WIPOffset::new(self.push::<UOffsetT>(actual).value())
} }
/// Set whether default values are stored. /// Set whether default values are stored.
@@ -443,7 +403,15 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
assert_msg_name: &'static str, assert_msg_name: &'static str,
) { ) {
let idx = self.used_space() - tab_revloc.value() as usize; let idx = self.used_space() - tab_revloc.value() as usize;
let tab = Table::new(&self.owned_buf[self.head..], idx);
// Safety:
// The value of TableFinishedWIPOffset is the offset from the end of owned_buf
// to an SOffsetT pointing to a valid VTable
//
// `self.owned_buf.len() = self.used_space() + self.head`
// `self.owned_buf.len() - tab_revloc = self.used_space() - tab_revloc + self.head`
// `self.owned_buf.len() - tab_revloc = idx + self.head`
let tab = unsafe { Table::new(&self.owned_buf[self.head..], idx) };
let o = tab.vtable().get(slot_byte_loc) as usize; let o = tab.vtable().get(slot_byte_loc) as usize;
assert!(o != 0, "missing required field {}", assert_msg_name); assert!(o != 0, "missing required field {}", assert_msg_name);
} }
@@ -560,11 +528,15 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
} }
} }
let new_vt_bytes = &self.owned_buf[vt_start_pos..vt_end_pos]; let new_vt_bytes = &self.owned_buf[vt_start_pos..vt_end_pos];
let found = self.written_vtable_revpos.binary_search_by(|old_vtable_revpos: &UOffsetT| { let found = self
let old_vtable_pos = self.owned_buf.len() - *old_vtable_revpos as usize; .written_vtable_revpos
let old_vtable = VTable::init(&self.owned_buf, old_vtable_pos); .binary_search_by(|old_vtable_revpos: &UOffsetT| {
new_vt_bytes.cmp(old_vtable.as_bytes()) let old_vtable_pos = self.owned_buf.len() - *old_vtable_revpos as usize;
}); // Safety:
// Already written vtables are valid by construction
let old_vtable = unsafe { VTable::init(&self.owned_buf, old_vtable_pos) };
new_vt_bytes.cmp(old_vtable.as_bytes())
});
let final_vtable_revpos = match found { let final_vtable_revpos = match found {
Ok(i) => { Ok(i) => {
// The new vtable is a duplicate so clear it. // The new vtable is a duplicate so clear it.
@@ -581,12 +553,22 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
}; };
// Write signed offset from table to its vtable. // Write signed offset from table to its vtable.
let table_pos = self.owned_buf.len() - object_revloc_to_vtable.value() as usize; let table_pos = self.owned_buf.len() - object_revloc_to_vtable.value() as usize;
let tmp_soffset_to_vt = unsafe { read_scalar_at::<UOffsetT>(&self.owned_buf, table_pos) }; if cfg!(debug_assertions) {
debug_assert_eq!(tmp_soffset_to_vt, 0xF0F0_F0F0); // Safety:
// Verified slice length
let tmp_soffset_to_vt = unsafe {
read_scalar::<UOffsetT>(&self.owned_buf[table_pos..table_pos + SIZE_UOFFSET])
};
assert_eq!(tmp_soffset_to_vt, 0xF0F0_F0F0);
}
let buf = &mut self.owned_buf[table_pos..table_pos + SIZE_SOFFSET];
// Safety:
// Verified length of buf above
unsafe { unsafe {
emplace_scalar::<SOffsetT>( emplace_scalar::<SOffsetT>(
&mut self.owned_buf[table_pos..table_pos + SIZE_SOFFSET], buf,
final_vtable_revpos as SOffsetT - object_revloc_to_vtable.value() as SOffsetT final_vtable_revpos as SOffsetT - object_revloc_to_vtable.value() as SOffsetT,
); );
} }
@@ -624,6 +606,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
// finally, zero out the old end data. // finally, zero out the old end data.
{ {
let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr(); let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
// Safety:
// ptr is byte aligned and of length middle
unsafe { unsafe {
write_bytes(ptr, 0, middle); write_bytes(ptr, 0, middle);
} }

View File

@@ -17,6 +17,24 @@
use core::mem::size_of; use core::mem::size_of;
mod private {
/// Types that are trivially transmutable are those where any combination of bits
/// represents a valid value of that type
///
/// For example integral types are TriviallyTransmutable as all bit patterns are valid,
/// however, `bool` is not trivially transmutable as only `0` and `1` are valid
pub trait TriviallyTransmutable {}
impl TriviallyTransmutable for i8 {}
impl TriviallyTransmutable for i16 {}
impl TriviallyTransmutable for i32 {}
impl TriviallyTransmutable for i64 {}
impl TriviallyTransmutable for u8 {}
impl TriviallyTransmutable for u16 {}
impl TriviallyTransmutable for u32 {}
impl TriviallyTransmutable for u64 {}
}
/// Trait for values that must be stored in little-endian byte order, but /// Trait for values that must be stored in little-endian byte order, but
/// might be represented in memory as big-endian. Every type that implements /// might be represented in memory as big-endian. Every type that implements
/// EndianScalar is a valid FlatBuffers scalar value. /// EndianScalar is a valid FlatBuffers scalar value.
@@ -28,144 +46,118 @@ use core::mem::size_of;
/// "too much". For example, num-traits provides i128 support, but that is an /// "too much". For example, num-traits provides i128 support, but that is an
/// invalid FlatBuffers type. /// invalid FlatBuffers type.
pub trait EndianScalar: Sized + PartialEq + Copy + Clone { pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
fn to_little_endian(self) -> Self; type Scalar: private::TriviallyTransmutable;
fn from_little_endian(self) -> Self;
}
/// Macro for implementing a no-op endian conversion. This is used for types fn to_little_endian(self) -> Self::Scalar;
/// that are one byte wide.
macro_rules! impl_endian_scalar_noop { fn from_little_endian(v: Self::Scalar) -> Self;
($ty:ident) => {
impl EndianScalar for $ty {
#[inline]
fn to_little_endian(self) -> Self {
self
}
#[inline]
fn from_little_endian(self) -> Self {
self
}
}
};
} }
/// Macro for implementing an endian conversion using the stdlib `to_le` and /// Macro for implementing an endian conversion using the stdlib `to_le` and
/// `from_le` functions. This is used for integer types. It is not used for /// `from_le` functions. This is used for integer types. It is not used for
/// floats, because the `to_le` and `from_le` are not implemented for them in /// floats, because the `to_le` and `from_le` are not implemented for them in
/// the stdlib. /// the stdlib.
macro_rules! impl_endian_scalar_stdlib_le_conversion { macro_rules! impl_endian_scalar {
($ty:ident) => { ($ty:ident) => {
impl EndianScalar for $ty { impl EndianScalar for $ty {
type Scalar = Self;
#[inline] #[inline]
fn to_little_endian(self) -> Self { fn to_little_endian(self) -> Self::Scalar {
Self::to_le(self) Self::to_le(self)
} }
#[inline] #[inline]
fn from_little_endian(self) -> Self { fn from_little_endian(v: Self::Scalar) -> Self {
Self::from_le(self) Self::from_le(v)
} }
} }
}; };
} }
impl_endian_scalar_noop!(bool); impl_endian_scalar!(u8);
impl_endian_scalar_noop!(u8); impl_endian_scalar!(i8);
impl_endian_scalar_noop!(i8); impl_endian_scalar!(u16);
impl_endian_scalar!(u32);
impl_endian_scalar!(u64);
impl_endian_scalar!(i16);
impl_endian_scalar!(i32);
impl_endian_scalar!(i64);
impl_endian_scalar_stdlib_le_conversion!(u16); impl EndianScalar for bool {
impl_endian_scalar_stdlib_le_conversion!(u32); type Scalar = u8;
impl_endian_scalar_stdlib_le_conversion!(u64);
impl_endian_scalar_stdlib_le_conversion!(i16); fn to_little_endian(self) -> Self::Scalar {
impl_endian_scalar_stdlib_le_conversion!(i32); self as u8
impl_endian_scalar_stdlib_le_conversion!(i64); }
fn from_little_endian(v: Self::Scalar) -> Self {
v != 0
}
}
impl EndianScalar for f32 { impl EndianScalar for f32 {
type Scalar = u32;
/// Convert f32 from host endian-ness to little-endian. /// Convert f32 from host endian-ness to little-endian.
#[inline] #[inline]
fn to_little_endian(self) -> Self { fn to_little_endian(self) -> u32 {
#[cfg(target_endian = "little")] // Floats and Ints have the same endianness on all supported platforms.
{ // <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
self self.to_bits().to_le()
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f32(self)
}
} }
/// Convert f32 from little-endian to host endian-ness. /// Convert f32 from little-endian to host endian-ness.
#[inline] #[inline]
fn from_little_endian(self) -> Self { fn from_little_endian(v: u32) -> Self {
#[cfg(target_endian = "little")] // Floats and Ints have the same endianness on all supported platforms.
{ // <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
self f32::from_bits(u32::from_le(v))
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f32(self)
}
} }
} }
impl EndianScalar for f64 { impl EndianScalar for f64 {
type Scalar = u64;
/// Convert f64 from host endian-ness to little-endian. /// Convert f64 from host endian-ness to little-endian.
#[inline] #[inline]
fn to_little_endian(self) -> Self { fn to_little_endian(self) -> u64 {
#[cfg(target_endian = "little")] // Floats and Ints have the same endianness on all supported platforms.
{ // <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
self self.to_bits().to_le()
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f64(self)
}
} }
/// Convert f64 from little-endian to host endian-ness. /// Convert f64 from little-endian to host endian-ness.
#[inline] #[inline]
fn from_little_endian(self) -> Self { fn from_little_endian(v: u64) -> Self {
#[cfg(target_endian = "little")] // Floats and Ints have the same endianness on all supported platforms.
{ // <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
self f64::from_bits(u64::from_le(v))
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f64(self)
}
} }
} }
/// Swaps the bytes of an f32.
#[allow(dead_code)]
#[inline]
pub fn byte_swap_f32(x: f32) -> f32 {
f32::from_bits(x.to_bits().swap_bytes())
}
/// Swaps the bytes of an f64.
#[allow(dead_code)]
#[inline]
pub fn byte_swap_f64(x: f64) -> f64 {
f64::from_bits(x.to_bits().swap_bytes())
}
/// Place an EndianScalar into the provided mutable byte slice. Performs /// Place an EndianScalar into the provided mutable byte slice. Performs
/// endian conversion, if necessary. /// endian conversion, if necessary.
/// # Safety /// # Safety
/// Caller must ensure `s.len() > size_of::<T>()` /// Caller must ensure `s.len() >= size_of::<T>()`
/// and `x` does not overlap with `s`.
#[inline] #[inline]
pub unsafe fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) { pub unsafe fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
let size = size_of::<T::Scalar>();
debug_assert!(
s.len() >= size,
"insufficient capacity for emplace_scalar, needed {} got {}",
size,
s.len()
);
let x_le = x.to_little_endian(); let x_le = x.to_little_endian();
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
&x_le as *const T as *const u8, &x_le as *const T::Scalar as *const u8,
s.as_mut_ptr() as *mut u8, s.as_mut_ptr() as *mut u8,
size_of::<T>(), size,
); );
} }
/// Read an EndianScalar from the provided byte slice at the specified location. /// Read an EndianScalar from the provided byte slice at the specified location.
/// Performs endian conversion, if necessary. /// Performs endian conversion, if necessary.
/// # Safety /// # Safety
/// Caller must ensure `s.len() > loc + size_of::<T>()`. /// Caller must ensure `s.len() >= loc + size_of::<T>()`.
#[inline] #[inline]
pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T { pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
read_scalar(&s[loc..]) read_scalar(&s[loc..])
@@ -177,8 +169,20 @@ pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
/// Caller must ensure `s.len() > size_of::<T>()`. /// Caller must ensure `s.len() > size_of::<T>()`.
#[inline] #[inline]
pub unsafe fn read_scalar<T: EndianScalar>(s: &[u8]) -> T { pub unsafe fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
let mut mem = core::mem::MaybeUninit::<T>::uninit(); let size = size_of::<T::Scalar>();
debug_assert!(
s.len() >= size,
"insufficient capacity for emplace_scalar, needed {} got {}",
size,
s.len()
);
let mut mem = core::mem::MaybeUninit::<T::Scalar>::uninit();
// Since [u8] has alignment 1, we copy it into T which may have higher alignment. // Since [u8] has alignment 1, we copy it into T which may have higher alignment.
core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size_of::<T>()); core::ptr::copy_nonoverlapping(
mem.assume_init().from_little_endian() s.as_ptr(),
mem.as_mut_ptr() as *mut u8,
size,
);
T::from_little_endian(mem.assume_init())
} }

View File

@@ -29,7 +29,11 @@ use core::marker::PhantomData;
/// continue traversing the FlatBuffer. /// continue traversing the FlatBuffer.
pub trait Follow<'buf> { pub trait Follow<'buf> {
type Inner; type Inner;
fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner; /// # Safety
///
/// `buf[loc..]` must contain a valid value of `Self` and anything it
/// transitively refers to by offset must also be valid
unsafe fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner;
} }
/// FollowStart wraps a Follow impl in a struct type. This can make certain /// FollowStart wraps a Follow impl in a struct type. This can make certain
@@ -39,17 +43,21 @@ pub struct FollowStart<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> FollowStart<T> { impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
#[inline] #[inline]
pub fn new() -> Self { pub fn new() -> Self {
Self { 0: PhantomData } Self(PhantomData)
} }
/// # Safety
///
/// `buf[loc..]` must contain a valid value of `T`
#[inline] #[inline]
pub fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner { pub unsafe fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner {
T::follow(buf, loc) T::follow(buf, loc)
} }
} }
impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> { impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc) T::follow(buf, loc)
} }
} }

View File

@@ -45,6 +45,8 @@ where
{ {
let mut v = Verifier::new(opts, data); let mut v = Verifier::new(opts, data);
<ForwardsUOffset<T>>::run_verifier(&mut v, 0)?; <ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
// Safety:
// Run verifier above
Ok(unsafe { root_unchecked::<T>(data) }) Ok(unsafe { root_unchecked::<T>(data) })
} }
@@ -75,6 +77,8 @@ where
{ {
let mut v = Verifier::new(opts, data); let mut v = Verifier::new(opts, data);
<SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?; <SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
// Safety:
// Run verifier above
Ok(unsafe { size_prefixed_root_unchecked::<T>(data) }) Ok(unsafe { size_prefixed_root_unchecked::<T>(data) })
} }

View File

@@ -48,14 +48,12 @@ mod vtable_writer;
pub use crate::array::{array_init, emplace_scalar_array, Array}; pub use crate::array::{array_init, emplace_scalar_array, Array};
pub use crate::builder::FlatBufferBuilder; pub use crate::builder::FlatBufferBuilder;
pub use crate::endian_scalar::{ pub use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at, EndianScalar};
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
};
pub use crate::follow::{Follow, FollowStart}; pub use crate::follow::{Follow, FollowStart};
pub use crate::primitives::*; pub use crate::primitives::*;
pub use crate::push::Push; pub use crate::push::Push;
pub use crate::table::{buffer_has_identifier, Table}; pub use crate::table::{buffer_has_identifier, Table};
pub use crate::vector::{follow_cast_ref, SafeSliceAccess, Vector, VectorIter}; pub use crate::vector::{follow_cast_ref, Vector, VectorIter};
pub use crate::verifier::{ pub use crate::verifier::{
ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier, ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier,
VerifierOptions, VerifierOptions,
@@ -64,6 +62,4 @@ pub use crate::vtable::field_index_to_field_offset;
pub use bitflags; pub use bitflags;
pub use get_root::*; pub use get_root::*;
// TODO(rw): Unify `create_vector` and `create_vector_direct` by using
// `Into<Vector<...>>`.
// TODO(rw): Split fill ops in builder into fill_small, fill_big like in C++. // TODO(rw): Split fill ops in builder into fill_small, fill_big like in C++.

View File

@@ -112,10 +112,7 @@ impl<'a, T: 'a> WIPOffset<T> {
/// Create a new WIPOffset. /// Create a new WIPOffset.
#[inline] #[inline]
pub fn new(o: UOffsetT) -> WIPOffset<T> { pub fn new(o: UOffsetT) -> WIPOffset<T> {
WIPOffset { WIPOffset(o, PhantomData)
0: o,
1: PhantomData,
}
} }
/// Return a wrapped value that brings its meaning as a union WIPOffset /// Return a wrapped value that brings its meaning as a union WIPOffset
@@ -135,11 +132,9 @@ impl<T> Push for WIPOffset<T> {
type Output = ForwardsUOffset<T>; type Output = ForwardsUOffset<T>;
#[inline(always)] #[inline(always)]
fn push(&self, dst: &mut [u8], rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
let n = (SIZE_UOFFSET + rest.len() - self.value() as usize) as UOffsetT; let n = (SIZE_UOFFSET + written_len - self.value() as usize) as UOffsetT;
unsafe { emplace_scalar::<UOffsetT>(dst, n);
emplace_scalar::<UOffsetT>(dst, n);
}
} }
} }
@@ -147,8 +142,8 @@ impl<T> Push for ForwardsUOffset<T> {
type Output = Self; type Output = Self;
#[inline(always)] #[inline(always)]
fn push(&self, dst: &mut [u8], rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, rest); self.value().push(dst, written_len);
} }
} }
@@ -179,9 +174,9 @@ impl<T> ForwardsUOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> { impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_UOFFSET]; let slice = &buf[loc..loc + SIZE_UOFFSET];
let off = unsafe { read_scalar::<u32>(slice) as usize }; let off = read_scalar::<u32>(slice) as usize;
T::follow(buf, loc + off) T::follow(buf, loc + off)
} }
} }
@@ -200,9 +195,9 @@ impl<T> ForwardsVOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> { impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_VOFFSET]; let slice = &buf[loc..loc + SIZE_VOFFSET];
let off = unsafe { read_scalar::<VOffsetT>(slice) as usize }; let off = read_scalar::<VOffsetT>(slice) as usize;
T::follow(buf, loc + off) T::follow(buf, loc + off)
} }
} }
@@ -211,8 +206,8 @@ impl<T> Push for ForwardsVOffset<T> {
type Output = Self; type Output = Self;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, rest); self.value().push(dst, written_len);
} }
} }
@@ -230,9 +225,9 @@ impl<T> BackwardsSOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> { impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let slice = &buf[loc..loc + SIZE_SOFFSET]; let slice = &buf[loc..loc + SIZE_SOFFSET];
let off = unsafe { read_scalar::<SOffsetT>(slice) }; let off = read_scalar::<SOffsetT>(slice);
T::follow(buf, (loc as SOffsetT - off) as usize) T::follow(buf, (loc as SOffsetT - off) as usize)
} }
} }
@@ -241,8 +236,8 @@ impl<T> Push for BackwardsSOffset<T> {
type Output = Self; type Output = Self;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, rest); self.value().push(dst, written_len);
} }
} }
@@ -252,7 +247,7 @@ pub struct SkipSizePrefix<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> { impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_SIZEPREFIX) T::follow(buf, loc + SIZE_SIZEPREFIX)
} }
} }
@@ -263,7 +258,7 @@ pub struct SkipRootOffset<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> { impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + SIZE_UOFFSET) T::follow(buf, loc + SIZE_UOFFSET)
} }
} }
@@ -274,7 +269,7 @@ pub struct FileIdentifier;
impl<'a> Follow<'a> for FileIdentifier { impl<'a> Follow<'a> for FileIdentifier {
type Inner = &'a [u8]; type Inner = &'a [u8];
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
&buf[loc..loc + FILE_IDENTIFIER_LENGTH] &buf[loc..loc + FILE_IDENTIFIER_LENGTH]
} }
} }
@@ -286,7 +281,7 @@ pub struct SkipFileIdentifier<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> { impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
type Inner = T::Inner; type Inner = T::Inner;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc + FILE_IDENTIFIER_LENGTH) T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
} }
} }
@@ -294,8 +289,8 @@ impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
impl<'a> Follow<'a> for bool { impl<'a> Follow<'a> for bool {
type Inner = bool; type Inner = bool;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe { read_scalar_at::<u8>(buf, loc) != 0 } read_scalar_at::<u8>(buf, loc) != 0
} }
} }
@@ -309,8 +304,8 @@ macro_rules! impl_follow_for_endian_scalar {
impl<'a> Follow<'a> for $ty { impl<'a> Follow<'a> for $ty {
type Inner = $ty; type Inner = $ty;
#[inline(always)] #[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe { read_scalar_at::<$ty>(buf, loc) } read_scalar_at::<$ty>(buf, loc)
} }
} }
}; };

View File

@@ -24,7 +24,11 @@ use crate::endian_scalar::emplace_scalar;
/// types. /// types.
pub trait Push: Sized { pub trait Push: Sized {
type Output; type Output;
fn push(&self, dst: &mut [u8], _rest: &[u8]);
/// # Safety
///
/// dst is aligned to [`Self::alignment`] and has length greater than or equal to [`Self::size`]
unsafe fn push(&self, dst: &mut [u8], written_len: usize);
#[inline] #[inline]
fn size() -> usize { fn size() -> usize {
size_of::<Self::Output>() size_of::<Self::Output>()
@@ -35,13 +39,29 @@ pub trait Push: Sized {
} }
} }
impl<'a, T: Push> Push for &'a T {
type Output = T::Output;
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
T::push(self, dst, written_len)
}
fn size() -> usize {
T::size()
}
fn alignment() -> PushAlignment {
T::alignment()
}
}
/// Ensure Push alignment calculations are typesafe (because this helps reduce /// Ensure Push alignment calculations are typesafe (because this helps reduce
/// implementation issues when using FlatBufferBuilder::align). /// implementation issues when using FlatBufferBuilder::align).
pub struct PushAlignment(usize); pub struct PushAlignment(usize);
impl PushAlignment { impl PushAlignment {
#[inline] #[inline]
pub fn new(x: usize) -> Self { pub fn new(x: usize) -> Self {
PushAlignment { 0: x } PushAlignment(x)
} }
#[inline] #[inline]
pub fn value(&self) -> usize { pub fn value(&self) -> usize {
@@ -60,10 +80,8 @@ macro_rules! impl_push_for_endian_scalar {
type Output = $ty; type Output = $ty;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
unsafe { emplace_scalar::<$ty>(dst, *self);
emplace_scalar::<$ty>(dst, *self);
}
} }
} }
}; };

View File

@@ -18,23 +18,36 @@ use crate::follow::Follow;
use crate::primitives::*; use crate::primitives::*;
use crate::vtable::VTable; use crate::vtable::VTable;
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Table<'a> { pub struct Table<'a> {
pub buf: &'a [u8], buf: &'a [u8],
pub loc: usize, loc: usize,
} }
impl<'a> Table<'a> { impl<'a> Table<'a> {
/// # Safety
///
/// `buf` must contain a `soffset_t` at `loc`, which points to a valid vtable
#[inline] #[inline]
pub fn new(buf: &'a [u8], loc: usize) -> Self { pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
Table { buf, loc } Table { buf, loc }
} }
#[inline] #[inline]
pub fn vtable(&self) -> VTable<'a> { pub fn vtable(&self) -> VTable<'a> {
<BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc) // Safety:
// Table::new is created with a valid buf and location
unsafe { <BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc) }
} }
/// Retrieves the value at the provided `slot_byte_loc` returning `default`
/// if no value present
///
/// # Safety
///
/// The value of the corresponding slot must have type T
#[inline] #[inline]
pub fn get<T: Follow<'a> + 'a>( pub unsafe fn get<T: Follow<'a> + 'a>(
&self, &self,
slot_byte_loc: VOffsetT, slot_byte_loc: VOffsetT,
default: Option<T::Inner>, default: Option<T::Inner>,
@@ -50,19 +63,26 @@ impl<'a> Table<'a> {
impl<'a> Follow<'a> for Table<'a> { impl<'a> Follow<'a> for Table<'a> {
type Inner = Table<'a>; type Inner = Table<'a>;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Table { buf, loc } Table { buf, loc }
} }
} }
/// Returns true if data contains a prefix of `ident`
#[inline] #[inline]
pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool { pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH); assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
let got = if size_prefixed { let got = if size_prefixed {
<SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0) assert!(data.len() >= SIZE_SIZEPREFIX + SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
// Safety:
// Verified data has sufficient bytes
unsafe { <SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0) }
} else { } else {
<SkipRootOffset<FileIdentifier>>::follow(data, 0) assert!(data.len() >= SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
// Safety:
// Verified data has sufficient bytes
unsafe { <SkipRootOffset<FileIdentifier>>::follow(data, 0) }
}; };
ident.as_bytes() == got ident.as_bytes() == got

View File

@@ -17,13 +17,10 @@
use core::fmt::{Debug, Formatter, Result}; use core::fmt::{Debug, Formatter, Result};
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator}; use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use core::marker::PhantomData; use core::marker::PhantomData;
use core::mem::size_of; use core::mem::{align_of, size_of};
use core::slice::from_raw_parts;
use core::str::from_utf8_unchecked; use core::str::from_utf8_unchecked;
use crate::endian_scalar::read_scalar_at; use crate::endian_scalar::read_scalar_at;
#[cfg(target_endian = "little")]
use crate::endian_scalar::EndianScalar;
use crate::follow::Follow; use crate::follow::Follow;
use crate::primitives::*; use crate::primitives::*;
@@ -55,6 +52,7 @@ where
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>` // and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
// can always be copied, no matter that `T` you have. // can always be copied, no matter that `T` you have.
impl<'a, T> Copy for Vector<'a, T> {} impl<'a, T> Copy for Vector<'a, T> {}
impl<'a, T> Clone for Vector<'a, T> { impl<'a, T> Clone for Vector<'a, T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self *self
@@ -62,32 +60,46 @@ impl<'a, T> Clone for Vector<'a, T> {
} }
impl<'a, T: 'a> Vector<'a, T> { impl<'a, T: 'a> Vector<'a, T> {
/// # Safety
///
/// `buf` contains a valid vector at `loc` consisting of
///
/// - UOffsetT element count
/// - Consecutive list of `T` elements
#[inline(always)] #[inline(always)]
pub fn new(buf: &'a [u8], loc: usize) -> Self { pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
Vector { Vector(buf, loc, PhantomData)
0: buf,
1: loc,
2: PhantomData,
}
} }
#[inline(always)] #[inline(always)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
// Safety:
// Valid vector at time of construction starting with UOffsetT element count
unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize } unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
} }
#[inline(always)] #[inline(always)]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
} }
#[inline(always)]
pub fn bytes(&self) -> &'a [u8] {
let sz = size_of::<T>();
let len = self.len();
&self.0[self.1 + SIZE_UOFFSET..self.1 + SIZE_UOFFSET + sz * len]
}
} }
impl<'a, T: Follow<'a> + 'a> Vector<'a, T> { impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
#[inline(always)] #[inline(always)]
pub fn get(&self, idx: usize) -> T::Inner { pub fn get(&self, idx: usize) -> T::Inner {
assert!(idx < self.len() as usize); assert!(idx < self.len());
let sz = size_of::<T>(); let sz = size_of::<T>();
debug_assert!(sz > 0); debug_assert!(sz > 0);
T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) // Safety:
// Valid vector at time of construction, verified that idx < element count
unsafe { T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) }
} }
#[inline(always)] #[inline(always)]
@@ -96,84 +108,40 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
} }
} }
pub trait SafeSliceAccess {} /// # Safety
impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> { ///
pub fn safe_slice(self) -> &'a [T] { /// `buf` must contain a value of T at `loc` and have alignment of 1
let buf = self.0; pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
let loc = self.1; assert_eq!(align_of::<T>(), 1);
let sz = size_of::<T>();
debug_assert!(sz > 0);
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
let ptr = data_buf.as_ptr() as *const T;
let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
s
}
}
impl SafeSliceAccess for u8 {}
impl SafeSliceAccess for i8 {}
impl SafeSliceAccess for bool {}
// TODO(caspern): Get rid of this. Conditional compliation is unnecessary complexity.
// Vectors of primitives just don't work on big endian machines!!!
#[cfg(target_endian = "little")]
mod le_safe_slice_impls {
impl super::SafeSliceAccess for u16 {}
impl super::SafeSliceAccess for u32 {}
impl super::SafeSliceAccess for u64 {}
impl super::SafeSliceAccess for i16 {}
impl super::SafeSliceAccess for i32 {}
impl super::SafeSliceAccess for i64 {}
impl super::SafeSliceAccess for f32 {}
impl super::SafeSliceAccess for f64 {}
}
#[cfg(target_endian = "little")]
pub use self::le_safe_slice_impls::*;
pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
let sz = size_of::<T>(); let sz = size_of::<T>();
let buf = &buf[loc..loc + sz]; let buf = &buf[loc..loc + sz];
let ptr = buf.as_ptr() as *const T; let ptr = buf.as_ptr() as *const T;
unsafe { &*ptr } // SAFETY
// buf contains a value at loc of type T and T has no alignment requirements
&*ptr
} }
impl<'a> Follow<'a> for &'a str { impl<'a> Follow<'a> for &'a str {
type Inner = &'a str; type Inner = &'a str;
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize; let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]; let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
unsafe { from_utf8_unchecked(slice) } from_utf8_unchecked(slice)
} }
} }
#[cfg(target_endian = "little")] impl<'a> Follow<'a> for &'a [u8] {
fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] { type Inner = &'a [u8];
let sz = size_of::<T>(); unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
debug_assert!(sz > 0); let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) as usize }; &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
let ptr = data_buf.as_ptr() as *const T;
let s: &[T] = unsafe { from_raw_parts(ptr, len) };
s
}
/// Implement direct slice access if the host is little-endian.
#[cfg(target_endian = "little")]
impl<'a, T: EndianScalar> Follow<'a> for &'a [T] {
type Inner = &'a [T];
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
follow_slice_helper::<T>(buf, loc)
} }
} }
/// Implement Follow for all possible Vectors that have Follow-able elements. /// Implement Follow for all possible Vectors that have Follow-able elements.
impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> { impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
type Inner = Vector<'a, T>; type Inner = Vector<'a, T>;
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Vector::new(buf, loc) Vector::new(buf, loc)
} }
} }
@@ -201,8 +169,14 @@ impl<'a, T: 'a> VectorIter<'a, T> {
} }
} }
/// Creates a new `VectorIter` from the provided slice
///
/// # Safety
///
/// buf must contain a contiguous sequence of `items_num` values of `T`
///
#[inline] #[inline]
pub fn from_slice(buf: &'a [u8], items_num: usize) -> Self { pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
VectorIter { VectorIter {
buf, buf,
loc: 0, loc: 0,
@@ -235,7 +209,10 @@ impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
if self.remaining == 0 { if self.remaining == 0 {
None None
} else { } else {
let result = T::follow(self.buf, self.loc); // Safety:
// VectorIter can only be created from a contiguous sequence of `items_num`
// And remaining is initialized to `items_num`
let result = unsafe { T::follow(self.buf, self.loc) };
self.loc += sz; self.loc += sz;
self.remaining -= 1; self.remaining -= 1;
Some(result) Some(result)
@@ -272,7 +249,10 @@ impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
None None
} else { } else {
self.remaining -= 1; self.remaining -= 1;
Some(T::follow(self.buf, self.loc + sz * self.remaining)) // Safety:
// VectorIter can only be created from a contiguous sequence of `items_num`
// And remaining is initialized to `items_num`
Some(unsafe { T::follow(self.buf, self.loc + sz * self.remaining) })
} }
} }
@@ -309,7 +289,7 @@ impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
} }
} }
#[cfg(feature="serialize")] #[cfg(feature = "serialize")]
impl<'a, T> serde::ser::Serialize for Vector<'a, T> impl<'a, T> serde::ser::Serialize for Vector<'a, T>
where where
T: 'a + Follow<'a>, T: 'a + Follow<'a>,

View File

@@ -1,14 +1,14 @@
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ops::Range; use core::ops::Range;
use core::option::Option; use core::option::Option;
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
#[cfg(feature="no_std")] #[cfg(not(feature = "no_std"))]
use thiserror_core2::Error;
#[cfg(not(feature="no_std"))]
use thiserror::Error; use thiserror::Error;
#[cfg(feature = "no_std")]
use thiserror_core2::Error;
/// Traces the location of data errors. Not populated for Dos detecting errors. /// Traces the location of data errors. Not populated for Dos detecting errors.
/// Useful for MissingRequiredField and Utf8Error in particular, though /// Useful for MissingRequiredField and Utf8Error in particular, though
@@ -28,8 +28,10 @@ pub enum ErrorTraceDetail {
position: usize, position: usize,
}, },
} }
#[derive(PartialEq, Eq, Default, Debug, Clone)] #[derive(PartialEq, Eq, Default, Debug, Clone)]
pub struct ErrorTrace(Vec<ErrorTraceDetail>); pub struct ErrorTrace(Vec<ErrorTraceDetail>);
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace { impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
#[inline] #[inline]
fn as_ref(&self) -> &[ErrorTraceDetail] { fn as_ref(&self) -> &[ErrorTraceDetail] {
@@ -63,7 +65,7 @@ pub enum InvalidFlatbuffer {
error_trace: ErrorTrace, error_trace: ErrorTrace,
}, },
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}", #[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
range.start, range.end)] range.start, range.end)]
MissingNullTerminator { MissingNullTerminator {
range: Range<usize>, range: Range<usize>,
error_trace: ErrorTrace, error_trace: ErrorTrace,
@@ -184,6 +186,7 @@ fn trace_field<T>(res: Result<T>, field_name: &'static str, position: usize) ->
}, },
) )
} }
/// Adds a TableField trace detail if `res` is a data error. /// Adds a TableField trace detail if `res` is a data error.
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> { fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
append_trace(res, ErrorTraceDetail::VectorElement { index, position }) append_trace(res, ErrorTraceDetail::VectorElement { index, position })
@@ -205,6 +208,7 @@ pub struct VerifierOptions {
// options to error un-recognized enums and unions? possible footgun. // options to error un-recognized enums and unions? possible footgun.
// Ignore nested flatbuffers, etc? // Ignore nested flatbuffers, etc?
} }
impl Default for VerifierOptions { impl Default for VerifierOptions {
fn default() -> Self { fn default() -> Self {
Self { Self {
@@ -226,6 +230,7 @@ pub struct Verifier<'opts, 'buf> {
num_tables: usize, num_tables: usize,
apparent_size: usize, apparent_size: usize,
} }
impl<'opts, 'buf> Verifier<'opts, 'buf> { impl<'opts, 'buf> Verifier<'opts, 'buf> {
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self { pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
Self { Self {
@@ -247,9 +252,12 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
/// memory since `buffer: &[u8]` has alignment 1. /// memory since `buffer: &[u8]` has alignment 1.
/// ///
/// ### WARNING /// ### WARNING
///
/// This does not work for flatbuffers-structs as they have alignment 1 according to /// This does not work for flatbuffers-structs as they have alignment 1 according to
/// `core::mem::align_of` but are meant to have higher alignment within a Flatbuffer w.r.t. /// `core::mem::align_of` but are meant to have higher alignment within a Flatbuffer w.r.t.
/// `buffer[0]`. TODO(caspern). /// `buffer[0]`. TODO(caspern).
///
/// Note this does not impact soundness as this crate does not assume alignment of structs
#[inline] #[inline]
fn is_aligned<T>(&self, pos: usize) -> Result<()> { fn is_aligned<T>(&self, pos: usize) -> Result<()> {
if pos % core::mem::align_of::<T>() == 0 { if pos % core::mem::align_of::<T>() == 0 {
@@ -307,9 +315,9 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
// signed offsets are subtracted. // signed offsets are subtracted.
let derefed = if offset > 0 { let derefed = if offset > 0 {
pos.checked_sub(offset.abs() as usize) pos.checked_sub(offset.unsigned_abs() as usize)
} else { } else {
pos.checked_add(offset.abs() as usize) pos.checked_add(offset.unsigned_abs() as usize)
}; };
if let Some(x) = derefed { if let Some(x) = derefed {
if x < self.buffer.len() { if x < self.buffer.len() {
@@ -372,6 +380,7 @@ pub struct TableVerifier<'ver, 'opts, 'buf> {
// Verifier struct which holds the surrounding state and options. // Verifier struct which holds the surrounding state and options.
verifier: &'ver mut Verifier<'opts, 'buf>, verifier: &'ver mut Verifier<'opts, 'buf>,
} }
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> { impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> { fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
let field = field as usize; let field = field as usize;
@@ -439,7 +448,9 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
} }
(Some(k), Some(v)) => { (Some(k), Some(v)) => {
trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?; trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?;
let discriminant = Key::follow(self.verifier.buffer, k); // Safety:
// Run verifier on `k` above
let discriminant = unsafe { Key::follow(self.verifier.buffer, k) };
trace_field( trace_field(
verify_union(discriminant, self.verifier, v), verify_union(discriminant, self.verifier, v),
val_field_name, val_field_name,
@@ -486,16 +497,27 @@ fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<core::ops::Ran
} }
pub trait SimpleToVerifyInSlice {} pub trait SimpleToVerifyInSlice {}
impl SimpleToVerifyInSlice for bool {} impl SimpleToVerifyInSlice for bool {}
impl SimpleToVerifyInSlice for i8 {} impl SimpleToVerifyInSlice for i8 {}
impl SimpleToVerifyInSlice for u8 {} impl SimpleToVerifyInSlice for u8 {}
impl SimpleToVerifyInSlice for i16 {} impl SimpleToVerifyInSlice for i16 {}
impl SimpleToVerifyInSlice for u16 {} impl SimpleToVerifyInSlice for u16 {}
impl SimpleToVerifyInSlice for i32 {} impl SimpleToVerifyInSlice for i32 {}
impl SimpleToVerifyInSlice for u32 {} impl SimpleToVerifyInSlice for u32 {}
impl SimpleToVerifyInSlice for f32 {} impl SimpleToVerifyInSlice for f32 {}
impl SimpleToVerifyInSlice for i64 {} impl SimpleToVerifyInSlice for i64 {}
impl SimpleToVerifyInSlice for u64 {} impl SimpleToVerifyInSlice for u64 {}
impl SimpleToVerifyInSlice for f64 {} impl SimpleToVerifyInSlice for f64 {}
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> { impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {

View File

@@ -33,24 +33,42 @@ impl<'a> PartialEq for VTable<'a> {
} }
impl<'a> VTable<'a> { impl<'a> VTable<'a> {
pub fn init(buf: &'a [u8], loc: usize) -> Self { /// SAFETY
/// `buf` must contain a valid vtable at `loc`
///
/// This consists of a number of `VOffsetT`
/// - size of vtable in bytes including size element
/// - size of object in bytes including the vtable offset
/// - n fields where n is the number of fields in the table's schema when the code was compiled
pub unsafe fn init(buf: &'a [u8], loc: usize) -> Self {
VTable { buf, loc } VTable { buf, loc }
} }
pub fn num_fields(&self) -> usize { pub fn num_fields(&self) -> usize {
(self.num_bytes() / SIZE_VOFFSET) - 2 (self.num_bytes() / SIZE_VOFFSET) - 2
} }
pub fn num_bytes(&self) -> usize { pub fn num_bytes(&self) -> usize {
// Safety:
// Valid VTable at time of construction
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc) as usize } unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc) as usize }
} }
pub fn object_inline_num_bytes(&self) -> usize { pub fn object_inline_num_bytes(&self) -> usize {
// Safety:
// Valid VTable at time of construction
let n = unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + SIZE_VOFFSET) }; let n = unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + SIZE_VOFFSET) };
n as usize n as usize
} }
pub fn get_field(&self, idx: usize) -> VOffsetT { pub fn get_field(&self, idx: usize) -> VOffsetT {
// TODO(rw): distinguish between None and 0? // TODO(rw): distinguish between None and 0?
if idx > self.num_fields() { if idx > self.num_fields() {
return 0; return 0;
} }
// Safety:
// Valid VTable at time of construction
unsafe { unsafe {
read_scalar_at::<VOffsetT>( read_scalar_at::<VOffsetT>(
self.buf, self.buf,
@@ -58,13 +76,17 @@ impl<'a> VTable<'a> {
) )
} }
} }
pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT { pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT {
// TODO(rw): distinguish between None and 0? // TODO(rw): distinguish between None and 0?
if byte_loc as usize >= self.num_bytes() { if byte_loc as usize + 2 > self.num_bytes() {
return 0; return 0;
} }
// Safety:
// byte_loc is within bounds of vtable, which was valid at time of construction
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + byte_loc as usize) } unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + byte_loc as usize) }
} }
pub fn as_bytes(&self) -> &[u8] { pub fn as_bytes(&self) -> &[u8] {
let len = self.num_bytes(); let len = self.num_bytes();
&self.buf[self.loc..self.loc + len] &self.buf[self.loc..self.loc + len]
@@ -87,7 +109,7 @@ pub fn field_offset_to_field_index(field_o: VOffsetT) -> VOffsetT {
impl<'a> Follow<'a> for VTable<'a> { impl<'a> Follow<'a> for VTable<'a> {
type Inner = VTable<'a>; type Inner = VTable<'a>;
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
VTable::init(buf, loc) VTable::init(buf, loc)
} }
} }

View File

@@ -40,8 +40,11 @@ impl<'a> VTableWriter<'a> {
/// to the provided value. /// to the provided value.
#[inline(always)] #[inline(always)]
pub fn write_vtable_byte_length(&mut self, n: VOffsetT) { pub fn write_vtable_byte_length(&mut self, n: VOffsetT) {
let buf = &mut self.buf[..SIZE_VOFFSET];
// Safety:
// Validated range above
unsafe { unsafe {
emplace_scalar::<VOffsetT>(&mut self.buf[..SIZE_VOFFSET], n); emplace_scalar::<VOffsetT>(buf, n);
} }
debug_assert_eq!(n as usize, self.buf.len()); debug_assert_eq!(n as usize, self.buf.len());
} }
@@ -49,8 +52,11 @@ impl<'a> VTableWriter<'a> {
/// Writes an object length (in bytes) into the vtable. /// Writes an object length (in bytes) into the vtable.
#[inline(always)] #[inline(always)]
pub fn write_object_inline_size(&mut self, n: VOffsetT) { pub fn write_object_inline_size(&mut self, n: VOffsetT) {
let buf = &mut self.buf[SIZE_VOFFSET..2 * SIZE_VOFFSET];
// Safety:
// Validated range above
unsafe { unsafe {
emplace_scalar::<VOffsetT>(&mut self.buf[SIZE_VOFFSET..2 * SIZE_VOFFSET], n); emplace_scalar::<VOffsetT>(buf, n);
} }
} }
@@ -61,8 +67,11 @@ impl<'a> VTableWriter<'a> {
#[inline(always)] #[inline(always)]
pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) { pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) {
let idx = vtable_offset as usize; let idx = vtable_offset as usize;
let buf = &mut self.buf[idx..idx + SIZE_VOFFSET];
// Safety:
// Validated range above
unsafe { unsafe {
emplace_scalar::<VOffsetT>(&mut self.buf[idx..idx + SIZE_VOFFSET], object_data_offset); emplace_scalar::<VOffsetT>(buf, object_data_offset);
} }
} }
@@ -73,6 +82,9 @@ impl<'a> VTableWriter<'a> {
// This is the closest thing to memset in Rust right now. // This is the closest thing to memset in Rust right now.
let len = self.buf.len(); let len = self.buf.len();
let p = self.buf.as_mut_ptr() as *mut u8; let p = self.buf.as_mut_ptr() as *mut u8;
// Safety:
// p is byte aligned and of length `len`
unsafe { unsafe {
write_bytes(p, 0, len); write_bytes(p, 0, len);
} }

View File

@@ -10,7 +10,7 @@
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 && static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 && FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 24, FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
namespace MyGame { namespace MyGame {

View File

@@ -31,7 +31,7 @@ public enum MyGame_Sample_Equipment: UInt8, Enum {
public struct MyGame_Sample_Vec3: NativeStruct { public struct MyGame_Sample_Vec3: NativeStruct {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
private var _x: Float32 private var _x: Float32
private var _y: Float32 private var _y: Float32
@@ -56,7 +56,7 @@ public struct MyGame_Sample_Vec3: NativeStruct {
public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject { public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
public var __buffer: ByteBuffer! { return _accessor.bb } public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Struct private var _accessor: Struct
@@ -72,7 +72,7 @@ public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
public struct MyGame_Sample_Monster: FlatBufferObject { public struct MyGame_Sample_Monster: FlatBufferObject {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
public var __buffer: ByteBuffer! { return _accessor.bb } public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table private var _accessor: Table
@@ -162,7 +162,7 @@ public struct MyGame_Sample_Monster: FlatBufferObject {
public struct MyGame_Sample_Weapon: FlatBufferObject { public struct MyGame_Sample_Weapon: FlatBufferObject {
static func validateVersion() { FlatBuffersVersion_22_9_24() } static func validateVersion() { FlatBuffersVersion_22_9_29() }
public var __buffer: ByteBuffer! { return _accessor.bb } public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table private var _accessor: Table

View File

@@ -59,10 +59,8 @@ impl core::fmt::Debug for Color {
impl<'a> flatbuffers::Follow<'a> for Color { impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let b = unsafe { let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
flatbuffers::read_scalar_at::<i8>(buf, loc)
};
Self(b) Self(b)
} }
} }
@@ -70,21 +68,21 @@ impl<'a> flatbuffers::Follow<'a> for Color {
impl flatbuffers::Push for Color { impl flatbuffers::Push for Color {
type Output = Color; type Output = Color;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
unsafe { flatbuffers::emplace_scalar::<i8>(dst, self.0); } flatbuffers::emplace_scalar::<i8>(dst, self.0);
} }
} }
impl flatbuffers::EndianScalar for Color { impl flatbuffers::EndianScalar for Color {
type Scalar = i8;
#[inline] #[inline]
fn to_little_endian(self) -> Self { fn to_little_endian(self) -> i8 {
let b = i8::to_le(self.0); self.0.to_le()
Self(b)
} }
#[inline] #[inline]
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn from_little_endian(self) -> Self { fn from_little_endian(v: i8) -> Self {
let b = i8::from_le(self.0); let b = i8::from_le(v);
Self(b) Self(b)
} }
} }

View File

@@ -55,10 +55,8 @@ impl core::fmt::Debug for Equipment {
impl<'a> flatbuffers::Follow<'a> for Equipment { impl<'a> flatbuffers::Follow<'a> for Equipment {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let b = unsafe { let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
flatbuffers::read_scalar_at::<u8>(buf, loc)
};
Self(b) Self(b)
} }
} }
@@ -66,21 +64,21 @@ impl<'a> flatbuffers::Follow<'a> for Equipment {
impl flatbuffers::Push for Equipment { impl flatbuffers::Push for Equipment {
type Output = Equipment; type Output = Equipment;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
unsafe { flatbuffers::emplace_scalar::<u8>(dst, self.0); } flatbuffers::emplace_scalar::<u8>(dst, self.0);
} }
} }
impl flatbuffers::EndianScalar for Equipment { impl flatbuffers::EndianScalar for Equipment {
type Scalar = u8;
#[inline] #[inline]
fn to_little_endian(self) -> Self { fn to_little_endian(self) -> u8 {
let b = u8::to_le(self.0); self.0.to_le()
Self(b)
} }
#[inline] #[inline]
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn from_little_endian(self) -> Self { fn from_little_endian(v: u8) -> Self {
let b = u8::from_le(self.0); let b = u8::from_le(v);
Self(b) Self(b)
} }
} }

View File

@@ -19,8 +19,8 @@ pub struct Monster<'a> {
impl<'a> flatbuffers::Follow<'a> for Monster<'a> { impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
type Inner = Monster<'a>; type Inner = Monster<'a>;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table { buf, loc } } Self { _tab: flatbuffers::Table::new(buf, loc) }
} }
} }
@@ -41,7 +41,7 @@ impl<'a> Monster<'a> {
} }
#[inline] #[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Monster { _tab: table } Monster { _tab: table }
} }
#[allow(unused_mut)] #[allow(unused_mut)]
@@ -73,7 +73,7 @@ impl<'a> Monster<'a> {
x.to_string() x.to_string()
}); });
let inventory = self.inventory().map(|x| { let inventory = self.inventory().map(|x| {
x.to_vec() x.into_iter().collect()
}); });
let color = self.color(); let color = self.color();
let weapons = self.weapons().map(|x| { let weapons = self.weapons().map(|x| {
@@ -106,49 +106,84 @@ impl<'a> Monster<'a> {
#[inline] #[inline]
pub fn pos(&self) -> Option<&'a Vec3> { pub fn pos(&self) -> Option<&'a Vec3> {
self._tab.get::<Vec3>(Monster::VT_POS, None) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<Vec3>(Monster::VT_POS, None)}
} }
#[inline] #[inline]
pub fn mana(&self) -> i16 { pub fn mana(&self) -> i16 {
self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap() // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()}
} }
#[inline] #[inline]
pub fn hp(&self) -> i16 { pub fn hp(&self) -> i16 {
self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap() // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()}
} }
#[inline] #[inline]
pub fn name(&self) -> Option<&'a str> { pub fn name(&self) -> Option<&'a str> {
self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)}
} }
#[inline] #[inline]
pub fn inventory(&self) -> Option<&'a [u8]> { pub fn inventory(&self) -> Option<flatbuffers::Vector<'a, u8>> {
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None).map(|v| v.safe_slice()) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None)}
} }
#[inline] #[inline]
pub fn color(&self) -> Color { pub fn color(&self) -> Color {
self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap() // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()}
} }
#[inline] #[inline]
pub fn weapons(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon<'a>>>> { pub fn weapons(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)}
} }
#[inline] #[inline]
pub fn equipped_type(&self) -> Equipment { pub fn equipped_type(&self) -> Equipment {
self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap() // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()}
} }
#[inline] #[inline]
pub fn equipped(&self) -> Option<flatbuffers::Table<'a>> { pub fn equipped(&self) -> Option<flatbuffers::Table<'a>> {
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)}
} }
#[inline] #[inline]
pub fn path(&self) -> Option<&'a [Vec3]> { pub fn path(&self) -> Option<flatbuffers::Vector<'a, Vec3>> {
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice()) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None)}
} }
#[inline] #[inline]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn equipped_as_weapon(&self) -> Option<Weapon<'a>> { pub fn equipped_as_weapon(&self) -> Option<Weapon<'a>> {
if self.equipped_type() == Equipment::Weapon { if self.equipped_type() == Equipment::Weapon {
self.equipped().map(Weapon::init_from_table) self.equipped().map(|t| {
// Safety:
// Created from a valid Table for this object
// Which contains a valid union in this slot
unsafe { Weapon::init_from_table(t) }
})
} else { } else {
None None
} }
@@ -365,18 +400,6 @@ impl MonsterT {
}) })
} }
} }
#[inline]
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
unsafe { flatbuffers::root_unchecked::<Monster<'a>>(buf) }
}
#[inline]
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
unsafe { flatbuffers::size_prefixed_root_unchecked::<Monster<'a>>(buf) }
}
#[inline] #[inline]
/// Verifies that a buffer of bytes contains a `Monster` /// Verifies that a buffer of bytes contains a `Monster`
/// and returns it. /// and returns it.

View File

@@ -29,39 +29,25 @@ impl core::fmt::Debug for Vec3 {
} }
impl flatbuffers::SimpleToVerifyInSlice for Vec3 {} impl flatbuffers::SimpleToVerifyInSlice for Vec3 {}
impl flatbuffers::SafeSliceAccess for Vec3 {}
impl<'a> flatbuffers::Follow<'a> for Vec3 { impl<'a> flatbuffers::Follow<'a> for Vec3 {
type Inner = &'a Vec3; type Inner = &'a Vec3;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
<&'a Vec3>::follow(buf, loc) <&'a Vec3>::follow(buf, loc)
} }
} }
impl<'a> flatbuffers::Follow<'a> for &'a Vec3 { impl<'a> flatbuffers::Follow<'a> for &'a Vec3 {
type Inner = &'a Vec3; type Inner = &'a Vec3;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::follow_cast_ref::<Vec3>(buf, loc) flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
} }
} }
impl<'b> flatbuffers::Push for Vec3 { impl<'b> flatbuffers::Push for Vec3 {
type Output = Vec3; type Output = Vec3;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
let src = unsafe { let src = ::core::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size());
::core::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size())
};
dst.copy_from_slice(src);
}
}
impl<'b> flatbuffers::Push for &'b Vec3 {
type Output = Vec3;
#[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
let src = unsafe {
::core::slice::from_raw_parts(*self as *const Vec3 as *const u8, Self::size())
};
dst.copy_from_slice(src); dst.copy_from_slice(src);
} }
} }
@@ -95,70 +81,88 @@ impl<'a> Vec3 {
} }
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
let mut mem = core::mem::MaybeUninit::<f32>::uninit(); let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
unsafe { // Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
EndianScalar::from_little_endian(unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
self.0[0..].as_ptr(), self.0[0..].as_ptr(),
mem.as_mut_ptr() as *mut u8, mem.as_mut_ptr() as *mut u8,
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
mem.assume_init() mem.assume_init()
}.from_little_endian() })
} }
pub fn set_x(&mut self, x: f32) { pub fn set_x(&mut self, x: f32) {
let x_le = x.to_little_endian(); let x_le = x.to_little_endian();
// Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
&x_le as *const f32 as *const u8, &x_le as *const _ as *const u8,
self.0[0..].as_mut_ptr(), self.0[0..].as_mut_ptr(),
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
} }
} }
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
let mut mem = core::mem::MaybeUninit::<f32>::uninit(); let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
unsafe { // Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
EndianScalar::from_little_endian(unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
self.0[4..].as_ptr(), self.0[4..].as_ptr(),
mem.as_mut_ptr() as *mut u8, mem.as_mut_ptr() as *mut u8,
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
mem.assume_init() mem.assume_init()
}.from_little_endian() })
} }
pub fn set_y(&mut self, x: f32) { pub fn set_y(&mut self, x: f32) {
let x_le = x.to_little_endian(); let x_le = x.to_little_endian();
// Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
&x_le as *const f32 as *const u8, &x_le as *const _ as *const u8,
self.0[4..].as_mut_ptr(), self.0[4..].as_mut_ptr(),
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
} }
} }
pub fn z(&self) -> f32 { pub fn z(&self) -> f32 {
let mut mem = core::mem::MaybeUninit::<f32>::uninit(); let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
unsafe { // Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
EndianScalar::from_little_endian(unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
self.0[8..].as_ptr(), self.0[8..].as_ptr(),
mem.as_mut_ptr() as *mut u8, mem.as_mut_ptr() as *mut u8,
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
mem.assume_init() mem.assume_init()
}.from_little_endian() })
} }
pub fn set_z(&mut self, x: f32) { pub fn set_z(&mut self, x: f32) {
let x_le = x.to_little_endian(); let x_le = x.to_little_endian();
// Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
&x_le as *const f32 as *const u8, &x_le as *const _ as *const u8,
self.0[8..].as_mut_ptr(), self.0[8..].as_mut_ptr(),
core::mem::size_of::<f32>(), core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
); );
} }
} }

View File

@@ -19,8 +19,8 @@ pub struct Weapon<'a> {
impl<'a> flatbuffers::Follow<'a> for Weapon<'a> { impl<'a> flatbuffers::Follow<'a> for Weapon<'a> {
type Inner = Weapon<'a>; type Inner = Weapon<'a>;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table { buf, loc } } Self { _tab: flatbuffers::Table::new(buf, loc) }
} }
} }
@@ -33,7 +33,7 @@ impl<'a> Weapon<'a> {
} }
#[inline] #[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Weapon { _tab: table } Weapon { _tab: table }
} }
#[allow(unused_mut)] #[allow(unused_mut)]
@@ -60,11 +60,17 @@ impl<'a> Weapon<'a> {
#[inline] #[inline]
pub fn name(&self) -> Option<&'a str> { pub fn name(&self) -> Option<&'a str> {
self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None) // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)}
} }
#[inline] #[inline]
pub fn damage(&self) -> i16 { pub fn damage(&self) -> i16 {
self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap() // Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()}
} }
} }

View File

@@ -122,10 +122,7 @@ fn main() {
// Get an element from the `inventory` FlatBuffer's `vector`. // Get an element from the `inventory` FlatBuffer's `vector`.
assert!(monster.inventory().is_some()); assert!(monster.inventory().is_some());
let inv = monster.inventory().unwrap(); let inv = monster.inventory().unwrap();
let third_item = inv.get(2);
// Note that this vector is returned as a slice, because direct access for
// this type, a u8 vector, is safe on all platforms:
let third_item = inv[2];
assert_eq!(third_item, 2); assert_eq!(third_item, 2);
// Get and test the `weapons` FlatBuffers's `vector`. // Get and test the `weapons` FlatBuffers's `vector`.

View File

@@ -655,7 +655,7 @@ class CSharpGenerator : public BaseGenerator {
// Force compile time error if not using the same version runtime. // Force compile time error if not using the same version runtime.
code += " public static void ValidateVersion() {"; code += " public static void ValidateVersion() {";
code += " FlatBufferConstants."; code += " FlatBufferConstants.";
code += "FLATBUFFERS_22_9_24(); "; code += "FLATBUFFERS_22_9_29(); ";
code += "}\n"; code += "}\n";
// Generate a special accessor for the table that when used as the root // Generate a special accessor for the table that when used as the root

View File

@@ -665,7 +665,7 @@ class JavaGenerator : public BaseGenerator {
// Force compile time error if not using the same version runtime. // Force compile time error if not using the same version runtime.
code += " public static void ValidateVersion() {"; code += " public static void ValidateVersion() {";
code += " Constants."; code += " Constants.";
code += "FLATBUFFERS_22_9_24(); "; code += "FLATBUFFERS_22_9_29(); ";
code += "}\n"; code += "}\n";
// Generate a special accessor for the table that when used as the root // Generate a special accessor for the table that when used as the root

View File

@@ -505,7 +505,7 @@ class KotlinGenerator : public BaseGenerator {
// runtime. // runtime.
GenerateFunOneLine( GenerateFunOneLine(
writer, "validateVersion", "", "", writer, "validateVersion", "", "",
[&]() { writer += "Constants.FLATBUFFERS_22_9_24()"; }, [&]() { writer += "Constants.FLATBUFFERS_22_9_29()"; },
options.gen_jvmstatic); options.gen_jvmstatic);
GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options); GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options);

View File

@@ -737,7 +737,6 @@ class RustGenerator : public BaseGenerator {
code_ += "pub use self::bitflags_{{ENUM_NAMESPACE}}::{{ENUM_TY}};"; code_ += "pub use self::bitflags_{{ENUM_NAMESPACE}}::{{ENUM_TY}};";
code_ += ""; code_ += "";
code_.SetValue("FROM_BASE", "unsafe { Self::from_bits_unchecked(b) }");
code_.SetValue("INTO_BASE", "self.bits()"); code_.SetValue("INTO_BASE", "self.bits()");
} else { } else {
// Normal, c-modelled enums. // Normal, c-modelled enums.
@@ -810,7 +809,6 @@ class RustGenerator : public BaseGenerator {
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_.SetValue("FROM_BASE", "Self(b)");
code_.SetValue("INTO_BASE", "self.0"); code_.SetValue("INTO_BASE", "self.0");
} }
@@ -839,35 +837,55 @@ class RustGenerator : public BaseGenerator {
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_TY}} {"; code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_TY}} {";
code_ += " type Inner = Self;"; code_ += " type Inner = Self;";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " let b = unsafe {"; code_ += " let b = flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc);";
code_ += " flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc)"; if (IsBitFlagsEnum(enum_def)) {
code_ += " };"; // Safety:
code_ += " {{FROM_BASE}}"; // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size.
// from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0
// https://github.com/bitflags/bitflags/issues/262
code_ += " // Safety:";
code_ += " // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size.";
code_ += " // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0";
code_ += " // https://github.com/bitflags/bitflags/issues/262";
code_ += " Self::from_bits_unchecked(b)";
} else {
code_ += " Self(b)";
}
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
code_ += "impl flatbuffers::Push for {{ENUM_TY}} {"; code_ += "impl flatbuffers::Push for {{ENUM_TY}} {";
code_ += " type Output = {{ENUM_TY}};"; code_ += " type Output = {{ENUM_TY}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {";
code_ += code_ += " flatbuffers::emplace_scalar::<{{BASE_TYPE}}>(dst, {{INTO_BASE}});";
" unsafe { flatbuffers::emplace_scalar::<{{BASE_TYPE}}>"
"(dst, {{INTO_BASE}}); }";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
code_ += "impl flatbuffers::EndianScalar for {{ENUM_TY}} {"; code_ += "impl flatbuffers::EndianScalar for {{ENUM_TY}} {";
code_ += " type Scalar = {{BASE_TYPE}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn to_little_endian(self) -> Self {"; code_ += " fn to_little_endian(self) -> {{BASE_TYPE}} {";
code_ += " let b = {{BASE_TYPE}}::to_le({{INTO_BASE}});"; code_ += " {{INTO_BASE}}.to_le()";
code_ += " {{FROM_BASE}}";
code_ += " }"; code_ += " }";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " #[allow(clippy::wrong_self_convention)]"; code_ += " #[allow(clippy::wrong_self_convention)]";
code_ += " fn from_little_endian(self) -> Self {"; code_ += " fn from_little_endian(v: {{BASE_TYPE}}) -> Self {";
code_ += " let b = {{BASE_TYPE}}::from_le({{INTO_BASE}});"; code_ += " let b = {{BASE_TYPE}}::from_le(v);";
code_ += " {{FROM_BASE}}"; if (IsBitFlagsEnum(enum_def)) {
// Safety:
// This is safe because we know bitflags is implemented with a repr transparent uint of the correct size.
// from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0
// https://github.com/bitflags/bitflags/issues/262
code_ += " // Safety:";
code_ += " // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size.";
code_ += " // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0";
code_ += " // https://github.com/bitflags/bitflags/issues/262";
code_ += " unsafe { Self::from_bits_unchecked(b) }";
} else {
code_ += " Self(b)";
}
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -1425,11 +1443,7 @@ class RustGenerator : public BaseGenerator {
case ftVectorOfBool: case ftVectorOfBool:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
const auto vector_type = return WrapOption("flatbuffers::Vector<" + lifetime + ", " + typname + ">");
IsOneByte(type.VectorType().base_type)
? "&" + lifetime + " [" + typname + "]"
: "flatbuffers::Vector<" + lifetime + ", " + typname + ">";
return WrapOption(vector_type);
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
@@ -1438,7 +1452,7 @@ class RustGenerator : public BaseGenerator {
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return WrapOption("&" + lifetime + " [" + typname + "]"); return WrapOption("flatbuffers::Vector<" + lifetime + ", " + typname + ">");
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
@@ -1556,19 +1570,8 @@ class RustGenerator : public BaseGenerator {
: "None"; : "None";
const std::string unwrap = field.IsOptional() ? "" : ".unwrap()"; const std::string unwrap = field.IsOptional() ? "" : ".unwrap()";
const auto t = GetFullType(field.value.type); return "unsafe { self._tab.get::<" + typname + ">({{STRUCT_TY}}::" + vt_offset +
", " + default_value + ")" + unwrap + "}";
// TODO(caspern): Shouldn't 1byte VectorOfEnumKey be slice too?
const std::string safe_slice =
(t == ftVectorOfStruct ||
((t == ftVectorOfBool || t == ftVectorOfFloat ||
t == ftVectorOfInteger) &&
IsOneByte(field.value.type.VectorType().base_type)))
? ".map(|v| v.safe_slice())"
: "";
return "self._tab.get::<" + typname + ">({{STRUCT_TY}}::" + vt_offset +
", " + default_value + ")" + safe_slice + unwrap;
} }
// Generates a fully-qualified name getter for use with --gen-name-strings // Generates a fully-qualified name getter for use with --gen-name-strings
@@ -1650,8 +1653,8 @@ class RustGenerator : public BaseGenerator {
code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_TY}}<'a> {"; code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_TY}}<'a> {";
code_ += " type Inner = {{STRUCT_TY}}<'a>;"; code_ += " type Inner = {{STRUCT_TY}}<'a>;";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " Self { _tab: flatbuffers::Table { buf, loc } }"; code_ += " Self { _tab: flatbuffers::Table::new(buf, loc) }";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -1672,7 +1675,7 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]"; code_ += " #[inline]";
code_ += code_ +=
" pub fn init_from_table(table: flatbuffers::Table<'a>) -> " " pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> "
"Self {"; "Self {";
code_ += " {{STRUCT_TY}} { _tab: table }"; code_ += " {{STRUCT_TY}} { _tab: table }";
code_ += " }"; code_ += " }";
@@ -1764,16 +1767,7 @@ class RustGenerator : public BaseGenerator {
break; break;
} }
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfBool: { case ftVectorOfBool:
if (IsOneByte(type.VectorType().base_type)) {
// 1 byte stuff is viewed w/ slice instead of flatbuffer::Vector
// and thus needs to be cloned out of the slice.
code_.SetValue("EXPR", "x.to_vec()");
break;
}
code_.SetValue("EXPR", "x.into_iter().collect()");
break;
}
case ftVectorOfFloat: case ftVectorOfFloat:
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
code_.SetValue("EXPR", "x.into_iter().collect()"); code_.SetValue("EXPR", "x.into_iter().collect()");
@@ -1840,6 +1834,9 @@ class RustGenerator : public BaseGenerator {
this->GenComment(field.doc_comment); this->GenComment(field.doc_comment);
code_ += "#[inline]"; code_ += "#[inline]";
code_ += "pub fn {{FIELD}}(&self) -> {{RETURN_TYPE}} {"; code_ += "pub fn {{FIELD}}(&self) -> {{RETURN_TYPE}} {";
code_ += " // Safety:";
code_ += " // Created from valid Table for this object";
code_ += " // which contains a valid value in this slot";
code_ += " " + GenTableAccessorFuncBody(field, "'a"); code_ += " " + GenTableAccessorFuncBody(field, "'a");
code_ += "}"; code_ += "}";
@@ -1864,16 +1861,22 @@ class RustGenerator : public BaseGenerator {
code_ += "{{NESTED}}<'a> {"; code_ += "{{NESTED}}<'a> {";
code_ += " let data = self.{{FIELD}}();"; code_ += " let data = self.{{FIELD}}();";
code_ += " use flatbuffers::Follow;"; code_ += " use flatbuffers::Follow;";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid flatbuffer in this slot";
code_ += code_ +=
" <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>" " unsafe { <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>"
"::follow(data, 0)"; "::follow(data.bytes(), 0) }";
} else { } else {
code_ += "Option<{{NESTED}}<'a>> {"; code_ += "Option<{{NESTED}}<'a>> {";
code_ += " self.{{FIELD}}().map(|data| {"; code_ += " self.{{FIELD}}().map(|data| {";
code_ += " use flatbuffers::Follow;"; code_ += " use flatbuffers::Follow;";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid flatbuffer in this slot";
code_ += code_ +=
" <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>" " unsafe { <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>"
"::follow(data, 0)"; "::follow(data.bytes(), 0) }";
code_ += " })"; code_ += " })";
} }
code_ += "}"; code_ += "}";
@@ -1909,11 +1912,17 @@ class RustGenerator : public BaseGenerator {
// as of April 10, 2020 // as of April 10, 2020
if (field.IsRequired()) { if (field.IsRequired()) {
code_ += " let u = self.{{FIELD}}();"; code_ += " let u = self.{{FIELD}}();";
code_ += " Some({{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))"; code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid union in this slot";
code_ += " Some(unsafe { {{U_ELEMENT_TABLE_TYPE}}::init_from_table(u) })";
} else { } else {
code_ += code_ +=" self.{{FIELD}}().map(|t| {";
" self.{{FIELD}}().map(" code_ += " // Safety:";
"{{U_ELEMENT_TABLE_TYPE}}::init_from_table)"; code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid union in this slot";
code_ += " unsafe { {{U_ELEMENT_TABLE_TYPE}}::init_from_table(t) }";
code_ += " })";
} }
code_ += " } else {"; code_ += " } else {";
code_ += " None"; code_ += " None";
@@ -2282,8 +2291,8 @@ class RustGenerator : public BaseGenerator {
MapNativeTableField( MapNativeTableField(
field, field,
"let w: Vec<_> = x.iter().map(|s| s.as_ref()).collect();" "let w: Vec<_> = x.iter().map(|s| _fbb.create_string(s)).collect();"
"_fbb.create_vector_of_strings(&w)"); "_fbb.create_vector(&w)");
return; return;
} }
case ftVectorOfTable: { case ftVectorOfTable: {
@@ -2374,32 +2383,6 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("STRUCT_FN", namer_.Function(struct_def)); code_.SetValue("STRUCT_FN", namer_.Function(struct_def));
code_.SetValue("STRUCT_CONST", namer_.Constant(struct_def.name)); code_.SetValue("STRUCT_CONST", namer_.Constant(struct_def.name));
// The root datatype accessors:
code_ += "#[inline]";
code_ +=
"#[deprecated(since=\"2.0.0\", "
"note=\"Deprecated in favor of `root_as...` methods.\")]";
code_ +=
"pub fn get_root_as_{{STRUCT_FN}}<'a>(buf: &'a [u8])"
" -> {{STRUCT_TY}}<'a> {";
code_ +=
" unsafe { flatbuffers::root_unchecked::<{{STRUCT_TY}}"
"<'a>>(buf) }";
code_ += "}";
code_ += "";
code_ += "#[inline]";
code_ +=
"#[deprecated(since=\"2.0.0\", "
"note=\"Deprecated in favor of `root_as...` methods.\")]";
code_ +=
"pub fn get_size_prefixed_root_as_{{STRUCT_FN}}"
"<'a>(buf: &'a [u8]) -> {{STRUCT_TY}}<'a> {";
code_ +=
" unsafe { flatbuffers::size_prefixed_root_unchecked::<{{STRUCT_TY}}"
"<'a>>(buf) }";
code_ += "}";
code_ += "";
// Default verifier root fns. // Default verifier root fns.
code_ += "#[inline]"; code_ += "#[inline]";
code_ += "/// Verifies that a buffer of bytes contains a `{{STRUCT_TY}}`"; code_ += "/// Verifies that a buffer of bytes contains a `{{STRUCT_TY}}`";
@@ -2641,43 +2624,25 @@ class RustGenerator : public BaseGenerator {
// Follow for the value type, Follow for the reference type, Push for the // Follow for the value type, Follow for the reference type, Push for the
// value type, and Push for the reference type. // value type, and Push for the reference type.
code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{STRUCT_TY}} {}"; code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{STRUCT_TY}} {}";
code_ += "impl flatbuffers::SafeSliceAccess for {{STRUCT_TY}} {}";
code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_TY}} {"; code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_TY}} {";
code_ += " type Inner = &'a {{STRUCT_TY}};"; code_ += " type Inner = &'a {{STRUCT_TY}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " <&'a {{STRUCT_TY}}>::follow(buf, loc)"; code_ += " <&'a {{STRUCT_TY}}>::follow(buf, loc)";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += "impl<'a> flatbuffers::Follow<'a> for &'a {{STRUCT_TY}} {"; code_ += "impl<'a> flatbuffers::Follow<'a> for &'a {{STRUCT_TY}} {";
code_ += " type Inner = &'a {{STRUCT_TY}};"; code_ += " type Inner = &'a {{STRUCT_TY}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " flatbuffers::follow_cast_ref::<{{STRUCT_TY}}>(buf, loc)"; code_ += " flatbuffers::follow_cast_ref::<{{STRUCT_TY}}>(buf, loc)";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += "impl<'b> flatbuffers::Push for {{STRUCT_TY}} {"; code_ += "impl<'b> flatbuffers::Push for {{STRUCT_TY}} {";
code_ += " type Output = {{STRUCT_TY}};"; code_ += " type Output = {{STRUCT_TY}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {";
code_ += " let src = unsafe {"; code_ += " let src = ::core::slice::from_raw_parts(self as *const {{STRUCT_TY}} as *const u8, Self::size());";
code_ +=
" ::core::slice::from_raw_parts("
"self as *const {{STRUCT_TY}} as *const u8, Self::size())";
code_ += " };";
code_ += " dst.copy_from_slice(src);";
code_ += " }";
code_ += "}";
code_ += "impl<'b> flatbuffers::Push for &'b {{STRUCT_TY}} {";
code_ += " type Output = {{STRUCT_TY}};";
code_ += "";
code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " let src = unsafe {";
code_ +=
" ::core::slice::from_raw_parts("
"*self as *const {{STRUCT_TY}} as *const u8, Self::size())";
code_ += " };";
code_ += " dst.copy_from_slice(src);"; code_ += " dst.copy_from_slice(src);";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
@@ -2754,6 +2719,9 @@ class RustGenerator : public BaseGenerator {
// Getter. // Getter.
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
code_ += "pub fn {{FIELD}}(&self) -> &{{FIELD_TYPE}} {"; code_ += "pub fn {{FIELD}}(&self) -> &{{FIELD_TYPE}} {";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid struct in this slot";
code_ += code_ +=
" unsafe {" " unsafe {"
" &*(self.0[{{FIELD_OFFSET}}..].as_ptr() as *const" " &*(self.0[{{FIELD_OFFSET}}..].as_ptr() as *const"
@@ -2765,20 +2733,26 @@ class RustGenerator : public BaseGenerator {
code_ += code_ +=
"pub fn {{FIELD}}(&'a self) -> " "pub fn {{FIELD}}(&'a self) -> "
"flatbuffers::Array<'a, {{ARRAY_ITEM}}, {{ARRAY_SIZE}}> {"; "flatbuffers::Array<'a, {{ARRAY_ITEM}}, {{ARRAY_SIZE}}> {";
code_ += " flatbuffers::Array::follow(&self.0, {{FIELD_OFFSET}})"; code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid array in this slot";
code_ += " unsafe { flatbuffers::Array::follow(&self.0, {{FIELD_OFFSET}}) }";
} else { } else {
code_ += "pub fn {{FIELD}}(&self) -> {{FIELD_TYPE}} {"; code_ += "pub fn {{FIELD}}(&self) -> {{FIELD_TYPE}} {";
code_ += code_ +=
" let mut mem = core::mem::MaybeUninit::" " let mut mem = core::mem::MaybeUninit::"
"<{{FIELD_TYPE}}>::uninit();"; "<<{{FIELD_TYPE}} as EndianScalar>::Scalar>::uninit();";
code_ += " unsafe {"; code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid value in this slot";
code_ += " EndianScalar::from_little_endian(unsafe {";
code_ += " core::ptr::copy_nonoverlapping("; code_ += " core::ptr::copy_nonoverlapping(";
code_ += " self.0[{{FIELD_OFFSET}}..].as_ptr(),"; code_ += " self.0[{{FIELD_OFFSET}}..].as_ptr(),";
code_ += " mem.as_mut_ptr() as *mut u8,"; code_ += " mem.as_mut_ptr() as *mut u8,";
code_ += " core::mem::size_of::<{{FIELD_TYPE}}>(),"; code_ += " core::mem::size_of::<<{{FIELD_TYPE}} as EndianScalar>::Scalar>(),";
code_ += " );"; code_ += " );";
code_ += " mem.assume_init()"; code_ += " mem.assume_init()";
code_ += " }.from_little_endian()"; code_ += " })";
} }
code_ += "}\n"; code_ += "}\n";
// Setter. // Setter.
@@ -2799,13 +2773,19 @@ class RustGenerator : public BaseGenerator {
code_ += code_ +=
"pub fn set_{{FIELD}}(&mut self, items: &{{FIELD_TYPE}}) " "pub fn set_{{FIELD}}(&mut self, items: &{{FIELD_TYPE}}) "
"{"; "{";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid array in this slot";
code_ += code_ +=
" flatbuffers::emplace_scalar_array(&mut self.0, " " unsafe { flatbuffers::emplace_scalar_array(&mut self.0, "
"{{FIELD_OFFSET}}, items);"; "{{FIELD_OFFSET}}, items) };";
} else { } else {
code_.SetValue("FIELD_SIZE", code_.SetValue("FIELD_SIZE",
NumToString(InlineSize(field.value.type))); NumToString(InlineSize(field.value.type)));
code_ += "pub fn set_{{FIELD}}(&mut self, x: &{{FIELD_TYPE}}) {"; code_ += "pub fn set_{{FIELD}}(&mut self, x: &{{FIELD_TYPE}}) {";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid array in this slot";
code_ += " unsafe {"; code_ += " unsafe {";
code_ += " core::ptr::copy("; code_ += " core::ptr::copy(";
code_ += " x.as_ptr() as *const u8,"; code_ += " x.as_ptr() as *const u8,";
@@ -2817,11 +2797,14 @@ class RustGenerator : public BaseGenerator {
} else { } else {
code_ += "pub fn set_{{FIELD}}(&mut self, x: {{FIELD_TYPE}}) {"; code_ += "pub fn set_{{FIELD}}(&mut self, x: {{FIELD_TYPE}}) {";
code_ += " let x_le = x.to_little_endian();"; code_ += " let x_le = x.to_little_endian();";
code_ += " // Safety:";
code_ += " // Created from a valid Table for this object";
code_ += " // Which contains a valid value in this slot";
code_ += " unsafe {"; code_ += " unsafe {";
code_ += " core::ptr::copy_nonoverlapping("; code_ += " core::ptr::copy_nonoverlapping(";
code_ += " &x_le as *const {{FIELD_TYPE}} as *const u8,"; code_ += " &x_le as *const _ as *const u8,";
code_ += " self.0[{{FIELD_OFFSET}}..].as_mut_ptr(),"; code_ += " self.0[{{FIELD_OFFSET}}..].as_mut_ptr(),";
code_ += " core::mem::size_of::<{{FIELD_TYPE}}>(),"; code_ += " core::mem::size_of::<<{{FIELD_TYPE}} as EndianScalar>::Scalar>(),";
code_ += " );"; code_ += " );";
code_ += " }"; code_ += " }";
} }

View File

@@ -1874,7 +1874,7 @@ class SwiftGenerator : public BaseGenerator {
} }
std::string ValidateFunc() { std::string ValidateFunc() {
return "static func validateVersion() { FlatBuffersVersion_22_9_24() }"; return "static func validateVersion() { FlatBuffersVersion_22_9_29() }";
} }
std::string GenType(const Type &type, std::string GenType(const Type &type,

View File

@@ -759,10 +759,10 @@ class TsGenerator : public BaseGenerator {
import.object_name = object_name; import.object_name = object_name;
import.bare_file_path = bare_file_path; import.bare_file_path = bare_file_path;
import.rel_file_path = rel_file_path; import.rel_file_path = rel_file_path;
import.import_statement = import.import_statement = "import { " + symbols_expression + " } from '" +
"import { " + symbols_expression + " } from '" + rel_file_path + ".js';"; rel_file_path + ".js';";
import.export_statement = import.export_statement = "export { " + symbols_expression + " } from '." +
"export { " + symbols_expression + " } from '." + bare_file_path + ".js';"; bare_file_path + ".js';";
import.dependency = &dependency; import.dependency = &dependency;
import.dependent = &dependent; import.dependent = &dependent;
@@ -903,7 +903,7 @@ class TsGenerator : public BaseGenerator {
const auto conversion_function = GenUnionConvFuncName(enum_def); const auto conversion_function = GenUnionConvFuncName(enum_def);
ret = "(() => {\n"; ret = "(() => {\n";
ret += " let temp = " + conversion_function + "(this." + ret += " const temp = " + conversion_function + "(this." +
namer_.Method(field_name, "Type") + "(), " + namer_.Method(field_name, "Type") + "(), " +
field_binded_method + ");\n"; field_binded_method + ");\n";
ret += " if(temp === null) { return null; }\n"; ret += " if(temp === null) { return null; }\n";
@@ -916,17 +916,17 @@ class TsGenerator : public BaseGenerator {
const auto conversion_function = GenUnionListConvFuncName(enum_def); const auto conversion_function = GenUnionListConvFuncName(enum_def);
ret = "(() => {\n"; ret = "(() => {\n";
ret += " let ret = [];\n"; ret += " const ret = [];\n";
ret += " for(let targetEnumIndex = 0; targetEnumIndex < this." + ret += " for(let targetEnumIndex = 0; targetEnumIndex < this." +
namer_.Method(field_name, "TypeLength") + "()" + namer_.Method(field_name, "TypeLength") + "()" +
"; " "; "
"++targetEnumIndex) {\n"; "++targetEnumIndex) {\n";
ret += " let targetEnum = this." + ret += " const targetEnum = this." +
namer_.Method(field_name, "Type") + "(targetEnumIndex);\n"; namer_.Method(field_name, "Type") + "(targetEnumIndex);\n";
ret += " if(targetEnum === null || " + enum_type + ret += " if(targetEnum === null || " + enum_type +
"[targetEnum!] === 'NONE') { " "[targetEnum!] === 'NONE') { "
"continue; }\n\n"; "continue; }\n\n";
ret += " let temp = " + conversion_function + "(targetEnum, " + ret += " const temp = " + conversion_function + "(targetEnum, " +
field_binded_method + ", targetEnumIndex);\n"; field_binded_method + ", targetEnumIndex);\n";
ret += " if(temp === null) { continue; }\n"; ret += " if(temp === null) { continue; }\n";
ret += union_has_string ? " if(typeof temp === 'string') { " ret += union_has_string ? " if(typeof temp === 'string') { "
@@ -1102,11 +1102,13 @@ class TsGenerator : public BaseGenerator {
switch (vectortype.base_type) { switch (vectortype.base_type) {
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
const auto &sd = *field.value.type.struct_def; const auto &sd = *field.value.type.struct_def;
field_type += GetTypeName(sd, /*object_api=*/true); const auto field_type_name =
; GetTypeName(sd, /*object_api=*/true);
field_type += field_type_name;
field_type += ")[]"; field_type += ")[]";
field_val = GenBBAccess() + ".createObjList(" + field_val = GenBBAccess() + ".createObjList<" + vectortypename +
", " + field_type_name + ">(" +
field_binded_method + ", this." + field_binded_method + ", this." +
namer_.Method(field, "Length") + "())"; namer_.Method(field, "Length") + "())";
@@ -1128,7 +1130,7 @@ class TsGenerator : public BaseGenerator {
case BASE_TYPE_STRING: { case BASE_TYPE_STRING: {
field_type += "string)[]"; field_type += "string)[]";
field_val = GenBBAccess() + ".createScalarList(" + field_val = GenBBAccess() + ".createScalarList<string>(" +
field_binded_method + ", this." + field_binded_method + ", this." +
namer_.Field(field, "Length") + "())"; namer_.Field(field, "Length") + "())";
field_offset_decl = field_offset_decl =
@@ -1162,9 +1164,9 @@ class TsGenerator : public BaseGenerator {
field_type += vectortypename; field_type += vectortypename;
} }
field_type += ")[]"; field_type += ")[]";
field_val = GenBBAccess() + ".createScalarList(" + field_val = GenBBAccess() + ".createScalarList<" +
field_binded_method + ", this." + vectortypename + ">(" + field_binded_method +
namer_.Method(field, "Length") + "())"; ", this." + namer_.Method(field, "Length") + "())";
field_offset_decl = field_offset_decl =
AddImport(imports, struct_def, struct_def).name + "." + AddImport(imports, struct_def, struct_def).name + "." +
@@ -1260,7 +1262,7 @@ class TsGenerator : public BaseGenerator {
obj_api_class = "\n"; obj_api_class = "\n";
obj_api_class += "export class "; obj_api_class += "export class ";
obj_api_class += GetTypeName(struct_def, /*object_api=*/true); obj_api_class += GetTypeName(struct_def, /*object_api=*/true);
obj_api_class += " {\n"; obj_api_class += " implements flatbuffers.IGeneratedObject {\n";
obj_api_class += constructor_func; obj_api_class += constructor_func;
obj_api_class += pack_func_prototype + pack_func_offset_decl + obj_api_class += pack_func_prototype + pack_func_offset_decl +
pack_func_create_call + "\n}"; pack_func_create_call + "\n}";
@@ -1298,12 +1300,17 @@ class TsGenerator : public BaseGenerator {
} }
const std::string object_name = GetTypeName(struct_def); const std::string object_name = GetTypeName(struct_def);
const std::string object_api_name = GetTypeName(struct_def, true);
// Emit constructor // Emit constructor
GenDocComment(struct_def.doc_comment, code_ptr); GenDocComment(struct_def.doc_comment, code_ptr);
code += "export class "; code += "export class ";
code += object_name; code += object_name;
code += " {\n"; if (parser.opts.generate_object_based_api)
code += " implements flatbuffers.IUnpackableObject<" + object_api_name +
"> {\n";
else
code += " {\n";
code += " bb: flatbuffers.ByteBuffer|null = null;\n"; code += " bb: flatbuffers.ByteBuffer|null = null;\n";
code += " bb_pos = 0;\n"; code += " bb_pos = 0;\n";

View File

@@ -1,15 +1,11 @@
FlatBuffers swift can be found in both SPM FlatBuffers swift can be found in both SPM
`.package(url: "https://github.com/mustiikhalil/flatbuffers.git", from: "X.Y.Z"),` `.package(url: "https://github.com/google/flatbuffers.git", from: "X.Y.Z"),`
and Cocoapods and Cocoapods
`pod 'FlatBuffers'` `pod 'FlatBuffers'`
### Notes
1- To report any error please use the main repository.
### Contribute ### Contribute
1- Always run `swift test --generate-linuxmain` whenever new test functions are added or removed 1- Always run `swift test --generate-linuxmain` whenever new test functions are added or removed

View File

@@ -119,4 +119,4 @@ extension UInt64: Scalar, Verifiable {
public typealias NumericValue = UInt64 public typealias NumericValue = UInt64
} }
public func FlatBuffersVersion_22_9_24() {} public func FlatBuffersVersion_22_9_29() {}

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class LongFloatEntry extends Table { public final class LongFloatEntry extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static LongFloatEntry getRootAsLongFloatEntry(ByteBuffer _bb) { return getRootAsLongFloatEntry(_bb, new LongFloatEntry()); } public static LongFloatEntry getRootAsLongFloatEntry(ByteBuffer _bb) { return getRootAsLongFloatEntry(_bb, new LongFloatEntry()); }
public static LongFloatEntry getRootAsLongFloatEntry(ByteBuffer _bb, LongFloatEntry obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static LongFloatEntry getRootAsLongFloatEntry(ByteBuffer _bb, LongFloatEntry obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -32,7 +32,7 @@ class LongFloatEntry : Table() {
return (val_1 - val_2).sign return (val_1 - val_2).sign
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsLongFloatEntry(_bb: ByteBuffer): LongFloatEntry = getRootAsLongFloatEntry(_bb, LongFloatEntry()) fun getRootAsLongFloatEntry(_bb: ByteBuffer): LongFloatEntry = getRootAsLongFloatEntry(_bb, LongFloatEntry())
fun getRootAsLongFloatEntry(_bb: ByteBuffer, obj: LongFloatEntry): LongFloatEntry { fun getRootAsLongFloatEntry(_bb: ByteBuffer, obj: LongFloatEntry): LongFloatEntry {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class LongFloatMap extends Table { public final class LongFloatMap extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static LongFloatMap getRootAsLongFloatMap(ByteBuffer _bb) { return getRootAsLongFloatMap(_bb, new LongFloatMap()); } public static LongFloatMap getRootAsLongFloatMap(ByteBuffer _bb) { return getRootAsLongFloatMap(_bb, new LongFloatMap()); }
public static LongFloatMap getRootAsLongFloatMap(ByteBuffer _bb, LongFloatMap obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static LongFloatMap getRootAsLongFloatMap(ByteBuffer _bb, LongFloatMap obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -46,7 +46,7 @@ class LongFloatMap : Table() {
} }
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsLongFloatMap(_bb: ByteBuffer): LongFloatMap = getRootAsLongFloatMap(_bb, LongFloatMap()) fun getRootAsLongFloatMap(_bb: ByteBuffer): LongFloatMap = getRootAsLongFloatMap(_bb, LongFloatMap())
fun getRootAsLongFloatMap(_bb: ByteBuffer, obj: LongFloatMap): LongFloatMap { fun getRootAsLongFloatMap(_bb: ByteBuffer, obj: LongFloatMap): LongFloatMap {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -13,7 +13,7 @@ public struct KeywordsInTable : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static KeywordsInTable GetRootAsKeywordsInTable(ByteBuffer _bb) { return GetRootAsKeywordsInTable(_bb, new KeywordsInTable()); } public static KeywordsInTable GetRootAsKeywordsInTable(ByteBuffer _bb) { return GetRootAsKeywordsInTable(_bb, new KeywordsInTable()); }
public static KeywordsInTable GetRootAsKeywordsInTable(ByteBuffer _bb, KeywordsInTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static KeywordsInTable GetRootAsKeywordsInTable(ByteBuffer _bb, KeywordsInTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct ArrayTable : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); } public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); }
public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); } public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class ArrayTable extends Table { public final class ArrayTable extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static ArrayTable getRootAsArrayTable(ByteBuffer _bb) { return getRootAsArrayTable(_bb, new ArrayTable()); } public static ArrayTable getRootAsArrayTable(ByteBuffer _bb) { return getRootAsArrayTable(_bb, new ArrayTable()); }
public static ArrayTable getRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static ArrayTable getRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "ARRT"); } public static boolean ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "ARRT"); }

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -14,7 +14,7 @@ public struct Monster : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); } public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); } public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }

View File

@@ -12,7 +12,7 @@ import com.google.flatbuffers.*;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Monster extends Table { public final class Monster extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); } public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); } public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }

View File

@@ -874,7 +874,7 @@ class Monster : Table() {
return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb) return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb)
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster()) fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster { fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct Referrable : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static Referrable GetRootAsReferrable(ByteBuffer _bb) { return GetRootAsReferrable(_bb, new Referrable()); } public static Referrable GetRootAsReferrable(ByteBuffer _bb) { return GetRootAsReferrable(_bb, new Referrable()); }
public static Referrable GetRootAsReferrable(ByteBuffer _bb, Referrable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Referrable GetRootAsReferrable(ByteBuffer _bb, Referrable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Referrable extends Table { public final class Referrable extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static Referrable getRootAsReferrable(ByteBuffer _bb) { return getRootAsReferrable(_bb, new Referrable()); } public static Referrable getRootAsReferrable(ByteBuffer _bb) { return getRootAsReferrable(_bb, new Referrable()); }
public static Referrable getRootAsReferrable(ByteBuffer _bb, Referrable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static Referrable getRootAsReferrable(ByteBuffer _bb, Referrable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -36,7 +36,7 @@ class Referrable : Table() {
return (val_1 - val_2).sign return (val_1 - val_2).sign
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsReferrable(_bb: ByteBuffer): Referrable = getRootAsReferrable(_bb, Referrable()) fun getRootAsReferrable(_bb: ByteBuffer): Referrable = getRootAsReferrable(_bb, Referrable())
fun getRootAsReferrable(_bb: ByteBuffer, obj: Referrable): Referrable { fun getRootAsReferrable(_bb: ByteBuffer, obj: Referrable): Referrable {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct Stat : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); } public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); }
public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Stat extends Table { public final class Stat extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); } public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -57,7 +57,7 @@ class Stat : Table() {
return (val_1 - val_2).sign return (val_1 - val_2).sign
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat()) fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat())
fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat { fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ internal partial struct TestSimpleTableWithEnum : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); } public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
final class TestSimpleTableWithEnum extends Table { final class TestSimpleTableWithEnum extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); } public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -31,7 +31,7 @@ class TestSimpleTableWithEnum : Table() {
} }
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer): TestSimpleTableWithEnum = getRootAsTestSimpleTableWithEnum(_bb, TestSimpleTableWithEnum()) fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer): TestSimpleTableWithEnum = getRootAsTestSimpleTableWithEnum(_bb, TestSimpleTableWithEnum())
fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer, obj: TestSimpleTableWithEnum): TestSimpleTableWithEnum { fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer, obj: TestSimpleTableWithEnum): TestSimpleTableWithEnum {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct TypeAliases : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb) { return GetRootAsTypeAliases(_bb, new TypeAliases()); } public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb) { return GetRootAsTypeAliases(_bb, new TypeAliases()); }
public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class TypeAliases extends Table { public final class TypeAliases extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); } public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); }
public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -203,7 +203,7 @@ class TypeAliases : Table() {
} }
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsTypeAliases(_bb: ByteBuffer): TypeAliases = getRootAsTypeAliases(_bb, TypeAliases()) fun getRootAsTypeAliases(_bb: ByteBuffer): TypeAliases = getRootAsTypeAliases(_bb, TypeAliases())
fun getRootAsTypeAliases(_bb: ByteBuffer, obj: TypeAliases): TypeAliases { fun getRootAsTypeAliases(_bb: ByteBuffer, obj: TypeAliases): TypeAliases {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct Monster : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); } public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Monster extends Table { public final class Monster extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); } public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -17,7 +17,7 @@ class Monster : Table() {
return this return this
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster()) fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster { fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct InParentNamespace : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb) { return GetRootAsInParentNamespace(_bb, new InParentNamespace()); } public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb) { return GetRootAsInParentNamespace(_bb, new InParentNamespace()); }
public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class InParentNamespace extends Table { public final class InParentNamespace extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb) { return getRootAsInParentNamespace(_bb, new InParentNamespace()); } public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb) { return getRootAsInParentNamespace(_bb, new InParentNamespace()); }
public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }

View File

@@ -17,7 +17,7 @@ class InParentNamespace : Table() {
return this return this
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsInParentNamespace(_bb: ByteBuffer): InParentNamespace = getRootAsInParentNamespace(_bb, InParentNamespace()) fun getRootAsInParentNamespace(_bb: ByteBuffer): InParentNamespace = getRootAsInParentNamespace(_bb, InParentNamespace())
fun getRootAsInParentNamespace(_bb: ByteBuffer, obj: InParentNamespace): InParentNamespace { fun getRootAsInParentNamespace(_bb: ByteBuffer, obj: InParentNamespace): InParentNamespace {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //monster_test.fbs Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -13,7 +13,7 @@ public struct MonsterExtra : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); } public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); } public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }

View File

@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class MonsterExtra extends Table { public final class MonsterExtra extends Table {
public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_24(); } public static void ValidateVersion() { Constants.FLATBUFFERS_22_9_29(); }
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); } public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONE"); } public static boolean MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONE"); }

View File

@@ -175,7 +175,7 @@ class MonsterExtra : Table() {
} }
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_22_9_24() fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
fun getRootAsMonsterExtra(_bb: ByteBuffer): MonsterExtra = getRootAsMonsterExtra(_bb, MonsterExtra()) fun getRootAsMonsterExtra(_bb: ByteBuffer): MonsterExtra = getRootAsMonsterExtra(_bb, MonsterExtra())
fun getRootAsMonsterExtra(_bb: ByteBuffer, obj: MonsterExtra): MonsterExtra { fun getRootAsMonsterExtra(_bb: ByteBuffer, obj: MonsterExtra): MonsterExtra {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //include_test/sub/include_test2.fbs Declared by : //include_test/sub/include_test2.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //include_test/sub/include_test2.fbs Declared by : //include_test/sub/include_test2.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //include_test/sub/include_test2.fbs Declared by : //include_test/sub/include_test2.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify. Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop. Or modify. I'm a message, not a cop.
flatc version: 22.9.24 flatc version: 22.9.29
Declared by : //include_test/include_test1.fbs Declared by : //include_test/include_test1.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs) Rooting type : MyGame.Example.Monster (//monster_test.fbs)

View File

@@ -10,7 +10,7 @@
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 && static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 && FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 24, FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
struct BadAlignmentSmall; struct BadAlignmentSmall;

Some files were not shown because too many files have changed in this diff Show More