CMakeScripts/**
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
-
src/idl_parser.cpp
src/idl_gen_cpp.cpp
src/idl_gen_java.cpp
+ src/idl_gen_csharp.cpp
src/idl_gen_go.cpp
src/idl_gen_text.cpp
src/flatc.cpp
<ClInclude Include="..\..\include\flatbuffers\flatbuffers.h" />
<ClInclude Include="..\..\include\flatbuffers\idl.h" />
<ClInclude Include="..\..\include\flatbuffers\util.h" />
+ <ClCompile Include="..\..\src\idl_gen_csharp.cpp" />
<ClCompile Include="..\..\src\idl_gen_go.cpp">
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
</ClCompile>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>..\..\tests</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- <LocalDebuggerCommandArguments>-j -c -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
+ <LocalDebuggerCommandArguments>-j -c -n -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- <LocalDebuggerCommandArguments>-j -c -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
+ <LocalDebuggerCommandArguments>-j -c -n -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-j -c -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
const std::string &file_name,
const GeneratorOptions &opts);
+// Generate C# files from the definitions in the Parser object.
+// See idl_gen_csharp.cpp.
+extern bool GenerateCSharp(const Parser &parser,
+ const std::string &path,
+ const std::string &file_name,
+ const GeneratorOptions &opts);
+
+
} // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Linq;
+
+namespace FlatBuffers
+{
+ /// <summary>
+ /// Class to mimick Java's ByteBuffer which is used heavily in Flatbuffers
+ /// </summary>
+ public class ByteBuffer
+ {
+ private readonly byte[] _buffer;
+
+ public int Length { get { return _buffer.Length; } }
+
+ public byte[] Data { get { return _buffer; } }
+
+ public ByteBuffer(byte[] buffer)
+ {
+ _buffer = buffer;
+ }
+
+ protected void WriteLittleEndian(int offset, byte[] data)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ data = data.Reverse().ToArray();
+ }
+ Buffer.BlockCopy(data, 0, _buffer, offset, data.Length);
+ }
+
+ protected byte[] ReadLittleEndian(int offset, int count)
+ {
+ AssertOffsetAndLength(offset, count);
+ var tmp = new byte[count];
+ Buffer.BlockCopy(_buffer, offset, tmp, 0, count);
+ return (BitConverter.IsLittleEndian)
+ ? tmp
+ : tmp.Reverse().ToArray();
+ }
+
+ private void AssertOffsetAndLength(int offset, int length)
+ {
+ if (offset < 0 ||
+ offset >= _buffer.Length ||
+ offset + length > _buffer.Length)
+ throw new ArgumentOutOfRangeException();
+ }
+
+ public void PutByte(int offset, byte value)
+ {
+ AssertOffsetAndLength(offset, sizeof(byte));
+ _buffer[offset] = value;
+ }
+
+ public void PutShort(int offset, short value)
+ {
+ AssertOffsetAndLength(offset, sizeof(short));
+ WriteLittleEndian(offset, BitConverter.GetBytes(value));
+ }
+
+ public void PutInt(int offset, int value)
+ {
+ AssertOffsetAndLength(offset, sizeof(int));
+ WriteLittleEndian(offset, BitConverter.GetBytes(value));
+ }
+
+ public void PutLong(int offset, long value)
+ {
+ AssertOffsetAndLength(offset, sizeof(long));
+ WriteLittleEndian(offset, BitConverter.GetBytes(value));
+ }
+
+ public void PutFloat(int offset, float value)
+ {
+ AssertOffsetAndLength(offset, sizeof(float));
+ WriteLittleEndian(offset, BitConverter.GetBytes(value));
+ }
+
+ public void PutDouble(int offset, double value)
+ {
+ AssertOffsetAndLength(offset, sizeof(double));
+ WriteLittleEndian(offset, BitConverter.GetBytes(value));
+ }
+
+ public byte Get(int index)
+ {
+ AssertOffsetAndLength(index, sizeof(byte));
+ return _buffer[index];
+ }
+
+ public short GetShort(int index)
+ {
+ var tmp = ReadLittleEndian(index, sizeof(short));
+ var value = BitConverter.ToInt16(tmp, 0);
+ return value;
+ }
+
+ public int GetInt(int index)
+ {
+ var tmp = ReadLittleEndian(index, sizeof(int));
+ var value = BitConverter.ToInt32(tmp, 0);
+ return value;
+ }
+
+ public long GetLong(int index)
+ {
+ var tmp = ReadLittleEndian(index, sizeof(long));
+ var value = BitConverter.ToInt64(tmp, 0);
+ return value;
+ }
+
+ public float GetFloat(int index)
+ {
+ var tmp = ReadLittleEndian(index, sizeof(float));
+ var value = BitConverter.ToSingle(tmp, 0);
+ return value;
+ }
+
+ public double GetDouble(int index)
+ {
+ var tmp = ReadLittleEndian(index, sizeof(double));
+ var value = BitConverter.ToDouble(tmp, 0);
+ return value;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Text;
+
+namespace FlatBuffers
+{
+ /// <summary>
+ /// Responsible for building up and accessing a flatbuffer formatted byte
+ /// array (via ByteBuffer)
+ /// </summary>
+ public class FlatBufferBuilder
+ {
+ private int _space;
+ private ByteBuffer _bb;
+ private int _minAlign = 1;
+
+ // The vtable for the current table, null otherwise.
+ private int[] _vtable;
+ // Starting offset of the current struct/table.
+ private int _objectStart;
+ // List of offsets of all vtables.
+ private int[] _vtables = new int[16];
+ // Number of entries in `vtables` in use.
+ private int _numVtables = 0;
+ // For the current vector being built.
+ private int _vectorNumElems = 0;
+
+ public FlatBufferBuilder(int initialSize)
+ {
+ if (initialSize <= 0)
+ throw new ArgumentOutOfRangeException("initialSize",
+ initialSize, "Must be greater than zero");
+ _space = initialSize;
+ _bb = new ByteBuffer(new byte[initialSize]);
+ }
+
+
+ public int Offset { get { return _bb.Length - _space; } }
+
+ public void Pad(int size)
+ {
+ for (var i = 0; i < size; i++)
+ {
+ _bb.PutByte(--_space, 0);
+ }
+ }
+
+ // Doubles the size of the ByteBuffer, and copies the old data towards
+ // the end of the new buffer (since we build the buffer backwards).
+ void GrowBuffer()
+ {
+ var oldBuf = _bb.Data;
+ var oldBufSize = oldBuf.Length;
+ if ((oldBufSize & 0xC0000000) != 0)
+ throw new Exception(
+ "FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
+
+ var newBufSize = oldBufSize << 1;
+ var newBuf = new byte[newBufSize];
+
+ Buffer.BlockCopy(oldBuf, 0, newBuf, newBufSize - oldBufSize,
+ oldBufSize);
+
+ _bb = new ByteBuffer(newBuf);
+ }
+
+ // Prepare to write an element of `size` after `additional_bytes`
+ // have been written, e.g. if you write a string, you need to align
+ // such the int length field is aligned to SIZEOF_INT, and the string
+ // data follows it directly.
+ // If all you need to do is align, `additional_bytes` will be 0.
+ public void Prep(int size, int additionalBytes)
+ {
+ // Track the biggest thing we've ever aligned to.
+ if (size > _minAlign)
+ _minAlign = size;
+ // Find the amount of alignment needed such that `size` is properly
+ // aligned after `additional_bytes`
+ var alignSize =
+ ((~((int)_bb.Length - _space + additionalBytes)) + 1) &
+ (size - 1);
+ // Reallocate the buffer if needed.
+ while (_space < alignSize + size + additionalBytes)
+ {
+ var oldBufSize = (int)_bb.Length;
+ GrowBuffer();
+ _space += (int)_bb.Length - oldBufSize;
+
+ }
+ Pad(alignSize);
+ }
+
+ public void PutByte(byte x)
+ {
+ _bb.PutByte(_space -= sizeof(byte), x);
+ }
+
+ public void PutShort(short x)
+ {
+ _bb.PutShort(_space -= sizeof(short), x);
+ }
+
+ public void PutInt32(int x)
+ {
+ _bb.PutInt(_space -= sizeof(int), x);
+ }
+
+ public void PutInt64(long x)
+ {
+ _bb.PutLong(_space -= sizeof(long), x);
+ }
+
+ public void PutFloat(float x)
+ {
+ _bb.PutFloat(_space -= sizeof(float), x);
+ }
+
+ public void PutDouble(double x)
+ {
+ _bb.PutDouble(_space -= sizeof(double), x);
+ }
+
+ // Adds a scalar to the buffer, properly aligned, and the buffer grown
+ // if needed.
+ public void AddByte(byte x) { Prep(sizeof(byte), 0); PutByte(x); }
+ public void AddShort(short x) { Prep(sizeof(short), 0); PutShort(x); }
+ public void AddInt(int x) { Prep(sizeof(int), 0); PutInt32(x); }
+ public void AddLong(long x) { Prep(sizeof(long), 0); PutInt64(x); }
+ public void AddFloat(float x) { Prep(sizeof(float), 0); PutFloat(x); }
+ public void AddDouble(double x) { Prep(sizeof(double), 0);
+ PutDouble(x); }
+
+
+
+ // Adds on offset, relative to where it will be written.
+ public void AddOffset(int off)
+ {
+ Prep(sizeof(int), 0); // Ensure alignment is already done.
+ if (off > Offset)
+ throw new ArgumentException();
+
+ off = Offset - off + sizeof(int);
+ PutInt32(off);
+ }
+
+ public void StartVector(int elemSize, int count, int alignment)
+ {
+ NotNested();
+ _vectorNumElems = count;
+ Prep(sizeof(int), elemSize * count);
+ Prep(alignment, elemSize * count); // Just in case alignment > int.
+ }
+
+ public int EndVector()
+ {
+ PutInt32(_vectorNumElems);
+ return Offset;
+ }
+
+ public void Nested(int obj)
+ {
+ // Structs are always stored inline, so need to be created right
+ // where they are used. You'll get this assert if you created it
+ // elsewhere.
+ if (obj != Offset)
+ throw new Exception(
+ "FlatBuffers: struct must be serialized inline.");
+ }
+
+ public void NotNested()
+ {
+ // You should not be creating any other objects or strings/vectors
+ // while an object is being constructed
+ if (_vtable != null)
+ throw new Exception(
+ "FlatBuffers: object serialization must not be nested.");
+ }
+
+ public void StartObject(int numfields)
+ {
+ NotNested();
+ _vtable = new int[numfields];
+ _objectStart = Offset;
+ }
+
+
+ // Set the current vtable at `voffset` to the current location in the
+ // buffer.
+ public void Slot(int voffset)
+ {
+ _vtable[voffset] = Offset;
+ }
+
+ // Add a scalar to a table at `o` into its vtable, with value `x` and default `d`
+ public void AddByte(int o, byte x, int d) { if (x != d) { AddByte(x); Slot(o); } }
+ public void AddShort(int o, short x, int d) { if (x != d) { AddShort(x); Slot(o); } }
+ public void AddInt(int o, int x, int d) { if (x != d) { AddInt(x); Slot(o); } }
+ public void AddLong(int o, long x, long d) { if (x != d) { AddLong(x); Slot(o); } }
+ public void AddFloat(int o, float x, double d) { if (x != d) { AddFloat(x); Slot(o); } }
+ public void AddDouble(int o, double x, double d) { if (x != d) { AddDouble(x); Slot(o); } }
+ public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
+
+ public int CreateString(string s)
+ {
+ NotNested();
+ byte[] utf8 = Encoding.UTF8.GetBytes(s);
+ AddByte((byte)0);
+ StartVector(1, utf8.Length, 1);
+ Buffer.BlockCopy(utf8, 0, _bb.Data, _space -= utf8.Length,
+ utf8.Length);
+ return EndVector();
+ }
+
+ // Structs are stored inline, so nothing additional is being added.
+ // `d` is always 0.
+ public void AddStruct(int voffset, int x, int d)
+ {
+ if (x != d)
+ {
+ Nested(x);
+ Slot(voffset);
+ }
+ }
+
+ public int EndObject()
+ {
+
+ if (_vtable == null)
+ throw new InvalidOperationException(
+ "Flatbuffers: calling endObject without a startObject");
+
+ AddInt((int)0);
+ var vtableloc = Offset;
+ // Write out the current vtable.
+ for (int i = _vtable.Length - 1; i >= 0 ; i--) {
+ // Offset relative to the start of the table.
+ short off = (short)(_vtable[i] != 0
+ ? vtableloc - _vtable[i]
+ : 0);
+ AddShort(off);
+ }
+
+ const int standardFields = 2; // The fields below:
+ AddShort((short)(vtableloc - _objectStart));
+ AddShort((short)((_vtable.Length + standardFields) *
+ sizeof(short)));
+
+ // Search for an existing vtable that matches the current one.
+ int existingVtable = 0;
+
+ for (int i = 0; i < _numVtables; i++) {
+ int vt1 = _bb.Length - _vtables[i];
+ int vt2 = _space;
+ short len = _bb.GetShort(vt1);
+ if (len == _bb.GetShort(vt2)) {
+ for (int j = sizeof(short); j < len; j += sizeof(short)) {
+ if (_bb.GetShort(vt1 + j) != _bb.GetShort(vt2 + j)) {
+ goto endLoop;
+ }
+ }
+ existingVtable = _vtables[i];
+ break;
+ }
+
+ endLoop: { }
+ }
+
+ if (existingVtable != 0) {
+ // Found a match:
+ // Remove the current vtable.
+ _space = _bb.Length - vtableloc;
+ // Point table to existing vtable.
+ _bb.PutInt(_space, existingVtable - vtableloc);
+ } else {
+ // No match:
+ // Add the location of the current vtable to the list of
+ // vtables.
+ if (_numVtables == _vtables.Length)
+ {
+ // Arrays.CopyOf(vtables num_vtables * 2);
+ var newvtables = new int[ _numVtables * 2];
+ Array.Copy(_vtables, newvtables, _vtables.Length);
+
+ _vtables = newvtables;
+ };
+ _vtables[_numVtables++] = Offset;
+ // Point table to current vtable.
+ _bb.PutInt(_bb.Length - vtableloc, Offset - vtableloc);
+ }
+
+ _vtable = null;
+ return vtableloc;
+ }
+
+ public void Finish(int rootTable)
+ {
+ Prep(_minAlign, sizeof(int));
+ AddOffset(rootTable);
+ }
+
+ public ByteBuffer Data { get { return _bb; }}
+
+ // The FlatBuffer data doesn't start at offset 0 in the ByteBuffer:
+ public int DataStart { get { return _space; } }
+
+
+ // Utility function for copying a byte array that starts at 0.
+ public byte[] SizedByteArray()
+ {
+ var newArray = new byte[_bb.Data.Length];
+ Buffer.BlockCopy(_bb.Data, DataStart, newArray, 0,
+ _bb.Data.Length);
+ return newArray;
+ }
+
+ public void Finish(int rootTable, string fileIdentifier)
+ {
+ Prep(_minAlign, sizeof(int) +
+ FlatBufferConstants.FileIdentifierLength);
+ if (fileIdentifier.Length !=
+ FlatBufferConstants.FileIdentifierLength)
+ throw new ArgumentException(
+ "FlatBuffers: file identifier must be length " +
+ FlatBufferConstants.FileIdentifierLength,
+ "fileIdentifier");
+ for (int i = FlatBufferConstants.FileIdentifierLength - 1; i >= 0;
+ i--)
+ {
+ AddByte((byte)fileIdentifier[i]);
+ }
+ AddOffset(rootTable);
+ }
+
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers
+{
+ public static class FlatBufferConstants
+ {
+ public const int FileIdentifierLength = 4;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <metadata>
+ <id>FlatBuffers</id>
+ <version>1.0.0-alpha00003</version>
+ <authors>Google Inc</authors>
+ <description>A .NET port of Google Inc's FlatBuffers project.</description>
+ <language>en-US</language>
+ <projectUrl>https://github.com/evolutional/flatbuffers</projectUrl>
+ <licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
+ </metadata>
+</package>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{28C00774-1E73-4A75-AD8F-844CD21A064D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>FlatBuffers</RootNamespace>
+ <AssemblyName>FlatBuffers</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ByteBuffer.cs" />
+ <Compile Include="FlatBufferBuilder.cs" />
+ <Compile Include="FlatBufferConstants.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Struct.cs" />
+ <Compile Include="Table.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="FlatBuffers.1.0.0.nuspec" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
--- /dev/null
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FlatBuffers")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FlatBuffers")]
+[assembly: AssemblyCopyright("Copyright © 2014 Google Inc")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("91c32e64-ef20-47df-9c9f-cec9207bc6df")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace FlatBuffers
+{
+ /// <summary>
+ /// All structs in the generated code derive from this class, and add their own accessors.
+ /// </summary>
+ public abstract class Struct
+ {
+ protected int bb_pos;
+ protected ByteBuffer bb;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Text;
+
+namespace FlatBuffers
+{
+ /// <summary>
+ /// All tables in the generated code derive from this class, and add their own accessors.
+ /// </summary>
+ public abstract class Table
+ {
+ protected int bb_pos;
+ protected ByteBuffer bb;
+
+ // Look up a field in the vtable, return an offset into the object, or 0 if the field is not
+ // present.
+ protected int __offset(int vtableOffset)
+ {
+ int vtable = bb_pos - bb.GetInt(bb_pos);
+ return vtableOffset < bb.GetShort(vtable) ? bb.GetShort(vtable + vtableOffset) : 0;
+ }
+
+ // Retrieve the relative offset stored at "offset"
+ protected int __indirect(int offset)
+ {
+ return offset + bb.GetInt(offset);
+ }
+
+ // Create a .NET String from UTF-8 data stored inside the flatbuffer.
+ protected string __string(int offset)
+ {
+ offset += bb.GetInt(offset);
+ var len = bb.GetInt(offset);
+ var startPos = offset + sizeof(int);
+ return Encoding.UTF8.GetString(bb.Data, startPos , len);
+ }
+
+ // Get the length of a vector whose offset is stored at "offset" in this object.
+ protected int __vector_len(int offset)
+ {
+ offset += bb_pos;
+ offset += bb.GetInt(offset);
+ return bb.GetInt(offset);
+ }
+
+ // Get the start of data of a vector whose offset is stored at "offset" in this object.
+ protected int __vector(int offset)
+ {
+ offset += bb_pos;
+ return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length
+ }
+
+ // Initialize any Table-derived type to point to the union at the given offset.
+ protected Table __union(Table t, int offset)
+ {
+ offset += bb_pos;
+ t.bb_pos = offset + bb.GetInt(offset);
+ t.bb = bb;
+ return t;
+ }
+
+ protected static bool __has_identifier(ByteBuffer bb, int offset, string ident)
+ {
+ if (ident.Length != FlatBufferConstants.FileIdentifierLength)
+ throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
+
+ for (var i = 0; i < FlatBufferConstants.FileIdentifierLength; i++)
+ {
+ if (ident[i] != (char)bb.Get(offset + sizeof(int) + i)) return false;
+ }
+
+ return true;
+ }
+
+
+ }
+}
"Generate Go files for tables/structs" },
{ flatbuffers::GenerateJava, "j", "Java",
"Generate Java classes for tables/structs" },
+ { flatbuffers::GenerateCSharp, "n", "C#",
+ "Generate C# classes for tables/structs" }
};
const char *program_name = NULL;
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+namespace csharp {
+
+static std::string GenTypeBasic(const Type &type) {
+ static const char *ctypename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE) #JTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ return ctypename[type.base_type];
+}
+
+static std::string GenTypeGet(const Type &type);
+
+static std::string GenTypePointer(const Type &type) {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING:
+ return "string";
+ case BASE_TYPE_VECTOR:
+ return GenTypeGet(type.VectorType());
+ case BASE_TYPE_STRUCT:
+ return type.struct_def->name;
+ case BASE_TYPE_UNION:
+ // fall through
+ default:
+ return "Table";
+ }
+}
+
+static std::string GenTypeGet(const Type &type) {
+ return IsScalar(type.base_type)
+ ? GenTypeBasic(type)
+ : GenTypePointer(type);
+}
+
+static void GenComment(const std::string &dc,
+ std::string *code_ptr,
+ const char *prefix = "") {
+ std::string &code = *code_ptr;
+ if (dc.length()) {
+ code += std::string(prefix) + "/*" + dc + "*/\n";
+ }
+}
+
+
+static void GenEnum(EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ if (enum_def.generated) return;
+
+ // Generate enum definitions of the form:
+ // public static int Name = value;
+ // We use ints rather than the C# Enum feature, because we want them
+ // to map directly to how they're used in C/C++ and file formats.
+ GenComment(enum_def.doc_comment, code_ptr);
+ code += "public class " + enum_def.name + "\n{\n";
+ for (auto it = enum_def.vals.vec.begin();
+ it != enum_def.vals.vec.end();
+ ++it) {
+ auto &ev = **it;
+ GenComment(ev.doc_comment, code_ptr, " ");
+ code += " public static " + GenTypeBasic(enum_def.underlying_type);
+ code += " " + ev.name + " = ";
+ code += NumToString(ev.value) + ";\n";
+ }
+ code += "};\n\n";
+}
+
+// Returns the function name that is able to read a value of the given type.
+static std::string GenGetter(const Type &type) {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "__string";
+ case BASE_TYPE_STRUCT: return "__struct";
+ case BASE_TYPE_UNION: return "__union";
+ case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+ default:
+ return "bb.Get" + (SizeOf(type.base_type) > 1
+ ? MakeCamel(GenTypeGet(type))
+ : "");
+ }
+}
+
+// Returns the method name for use with add/put calls.
+static std::string GenMethod(const FieldDef &field) {
+ return IsScalar(field.value.type.base_type)
+ ? MakeCamel(GenTypeBasic(field.value.type))
+ : (IsStruct(field.value.type) ? "Struct" : "Offset");
+}
+
+// Recursively generate arguments for a constructor, to deal with nested
+// structs.
+static void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix) {
+ std::string &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end();
+ ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure names
+ // don't clash, and to make it obvious these arguments are constructing
+ // a nested struct, prefix the name with the struct name.
+ GenStructArgs(*field.value.type.struct_def, code_ptr,
+ (field.value.type.struct_def->name + "_").c_str());
+ } else {
+ code += ", " + GenTypeBasic(field.value.type) + " " + nameprefix;
+ code += MakeCamel(field.name, true);
+ }
+ }
+}
+
+// Recusively generate struct construction statements of the form:
+// builder.PutType(name);
+// and insert manual padding.
+static void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix) {
+ std::string &code = *code_ptr;
+ code += " builder.Prep(" + NumToString(struct_def.minalign) + ", ";
+ code += NumToString(struct_def.bytesize) + ");\n";
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend();
+ ++it) {
+ auto &field = **it;
+ if (field.padding)
+ code += " builder.Pad(" + NumToString(field.padding) + ");\n";
+ if (IsStruct(field.value.type)) {
+ GenStructBody(*field.value.type.struct_def, code_ptr,
+ (field.value.type.struct_def->name + "_").c_str());
+ } else {
+ code += " builder.Put" + GenMethod(field) + "(";
+ code += nameprefix + MakeCamel(field.name, true) + ");\n";
+ }
+ }
+}
+
+static void GenStruct(const Parser &parser, StructDef &struct_def,
+ std::string *code_ptr) {
+ if (struct_def.generated) return;
+ std::string &code = *code_ptr;
+
+ // Generate a struct accessor class, with methods of the form:
+ // public type Name() { return bb.GetType(i + offset); }
+ // or for tables of the form:
+ // public type Name() {
+ // int o = __offset(offset); return o != 0 ? bb.GetType(o + i) : default;
+ // }
+ GenComment(struct_def.doc_comment, code_ptr);
+ code += "public class " + struct_def.name + " : ";
+ code += struct_def.fixed ? "Struct" : "Table";
+ code += " {\n";
+ if (!struct_def.fixed) {
+ // Generate a special accessor for the table that when used as the root
+ // of a FlatBuffer
+ code += " public static " + struct_def.name + " GetRootAs";
+ code += struct_def.name;
+ code += "(ByteBuffer _bb, int offset) { ";
+ // Endian handled by .NET ByteBuffer impl
+ code += "return (new " + struct_def.name;
+ code += "()).__init(_bb.GetInt(offset) + offset, _bb); }\n";
+ if (parser.root_struct_def == &struct_def) {
+ if (parser.file_identifier_.length()) {
+ // Check if a buffer has the identifier.
+ code += " public static bool " + struct_def.name;
+ code += "BufferHasIdentifier(ByteBuffer _bb, int offset) { return ";
+ code += "__has_identifier(_bb, offset, \"" + parser.file_identifier_;
+ code += "\"); }\n";
+ }
+ }
+ }
+ // Generate the __init method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ code += " public " + struct_def.name;
+ code += " __init(int _i, ByteBuffer _bb) ";
+ code += "{ bb_pos = _i; bb = _bb; return this; }\n\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end();
+ ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ GenComment(field.doc_comment, code_ptr, " ");
+ std::string type_name = GenTypeGet(field.value.type);
+ std::string method_start = " public " + type_name + " " +
+ MakeCamel(field.name, true);
+ // Generate the accessors that don't do object reuse.
+ if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ // Calls the accessor that takes an accessor object with a new object.
+ code += method_start + "() { return " + MakeCamel(field.name, true);
+ code += "(new ";
+ code += type_name + "()); }\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_STRUCT) {
+ // Accessors for vectors of structs also take accessor objects, this
+ // generates a variant without that argument.
+ code += method_start + "(int j) { return " + MakeCamel(field.name, true);
+ code += "(new ";
+ code += type_name + "(), j); }\n";
+ }
+ std::string getter = GenGetter(field.value.type);
+ code += method_start + "(";
+ // Most field accessors need to retrieve and test the field offset first,
+ // this is the prefix code for that:
+ auto offset_prefix = ") { int o = __offset(" +
+ NumToString(field.value.offset) +
+ "); return o != 0 ? ";
+ if (IsScalar(field.value.type.base_type)) {
+ if (struct_def.fixed) {
+ code += ") { return " + getter;
+ code += "(bb_pos + " + NumToString(field.value.offset) + ")";
+ } else {
+ code += offset_prefix + getter;
+ code += "(o + bb_pos) : (";
+ code += type_name;
+ code += ")" + field.value.constant;
+ }
+ } else {
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT:
+ code += type_name + " obj";
+ if (struct_def.fixed) {
+ code += ") { return obj.__init(bb_pos + ";
+ code += NumToString(field.value.offset) + ", bb)";
+ } else {
+ code += offset_prefix;
+ code += "obj.__init(";
+ code += field.value.type.struct_def->fixed
+ ? "o + bb_pos"
+ : "__indirect(o + bb_pos)";
+ code += ", bb) : null";
+ }
+ break;
+ case BASE_TYPE_STRING:
+ code += offset_prefix + getter +"(o + bb_pos) : null";
+ break;
+ case BASE_TYPE_VECTOR: {
+ auto vectortype = field.value.type.VectorType();
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ code += type_name + " obj, ";
+ getter = "obj.__init";
+ }
+ code += "int j" + offset_prefix + getter +"(";
+ auto index = "__vector(o) + j * " +
+ NumToString(InlineSize(vectortype));
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ code += vectortype.struct_def->fixed
+ ? index
+ : "__indirect(" + index + ")";
+ code += ", bb";
+ } else {
+ code += index;
+ }
+ code += ") : ";
+ code += IsScalar(field.value.type.element) ? "(" + type_name + ")0" : "null";
+ break;
+ }
+ case BASE_TYPE_UNION:
+ code += type_name + " obj" + offset_prefix + getter;
+ code += "(obj, o) : null";
+ break;
+ default:
+ assert(0);
+ }
+ }
+ code += "; }\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += " public int " + MakeCamel(field.name, true) + "Length(";
+ code += offset_prefix;
+ code += "__vector_len(o) : 0; }\n";
+ }
+ }
+ code += "\n";
+ if (struct_def.fixed) {
+ // create a struct constructor function
+ code += " public static int Create" + struct_def.name;
+ code += "(FlatBufferBuilder builder";
+ GenStructArgs(struct_def, code_ptr, "");
+ code += ") {\n";
+ GenStructBody(struct_def, code_ptr, "");
+ code += " return builder.Offset;\n }\n";
+ } else {
+ // Create a set of static methods that allow table construction,
+ // of the form:
+ // public static void AddName(FlatBufferBuilder builder, short name)
+ // { builder.AddShort(id, name, default); }
+ code += " public static void Start" + struct_def.name;
+ code += "(FlatBufferBuilder builder) { builder.StartObject(";
+ code += NumToString(struct_def.fields.vec.size()) + "); }\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end();
+ ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ code += " public static void Add" + MakeCamel(field.name);
+ code += "(FlatBufferBuilder builder, " + GenTypeBasic(field.value.type);
+ auto argname = MakeCamel(field.name, false);
+ if (!IsScalar(field.value.type.base_type)) argname += "Offset";
+ code += " " + argname + ") { builder.Add";
+ code += GenMethod(field) + "(";
+ code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
+ code += argname + ", " + field.value.constant;
+ code += "); }\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += " public static void Start" + MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, int numElems) ";
+ code += "{ builder.StartVector(";
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ code += NumToString(elem_size);
+ code += ", numElems, " + NumToString(alignment);
+ code += "); }\n";
+ }
+ }
+ code += " public static int End" + struct_def.name;
+ code += "(FlatBufferBuilder builder) { return builder.EndObject(); }\n";
+ if (parser.root_struct_def == &struct_def) {
+ code += " public static void Finish" + struct_def.name;
+ code += "Buffer(FlatBufferBuilder builder, int offset) { ";
+ code += "builder.Finish(offset";
+ if (parser.file_identifier_.length())
+ code += ", \"" + parser.file_identifier_ + "\"";
+ code += "); }\n";
+ }
+ }
+ code += "};\n\n";
+}
+
+// Save out the generated code for a single Java class while adding
+// declaration boilerplate.
+static bool SaveClass(const Parser &parser, const Definition &def,
+ const std::string &classcode, const std::string &path) {
+ if (!classcode.length()) return true;
+
+ std::string namespace_csharp;
+ std::string namespace_dir = path;
+ auto &namespaces = parser.namespaces_.back()->components;
+ for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+ if (namespace_csharp.length()) {
+ namespace_csharp += ".";
+ namespace_dir += kPathSeparator;
+ }
+ namespace_csharp += *it;
+ namespace_dir += *it;
+ }
+ EnsureDirExists(namespace_dir);
+
+ std::string code = "// automatically generated, do not modify\n\n";
+ code += "namespace " + namespace_csharp + "\n{\n\n";
+// Other usings
+ code += "using FlatBuffers;\n\n";
+ code += classcode;
+ code += "\n}\n";
+ auto filename = namespace_dir + kPathSeparator + def.name + ".cs";
+ return SaveFile(filename.c_str(), code, false);
+}
+
+} // namespace csharp
+
+bool GenerateCSharp(const Parser &parser,
+ const std::string &path,
+ const std::string & /*file_name*/,
+ const GeneratorOptions & /*opts*/) {
+ using namespace csharp;
+
+ for (auto it = parser.enums_.vec.begin();
+ it != parser.enums_.vec.end(); ++it) {
+ std::string enumcode;
+ GenEnum(**it, &enumcode);
+ if (!SaveClass(parser, **it, enumcode, path))
+ return false;
+ }
+
+ for (auto it = parser.structs_.vec.begin();
+ it != parser.structs_.vec.end(); ++it) {
+ std::string declcode;
+ GenStruct(parser, **it, &declcode);
+ if (!SaveClass(parser, **it, declcode, path))
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace flatbuffers
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers.Test
+{
+
+ public class AssertFailedException : Exception
+ {
+ private readonly object _expected;
+ private readonly object _actual;
+
+ public AssertFailedException(object expected, object actual)
+ {
+ _expected = expected;
+ _actual = actual;
+ }
+
+ public override string Message
+ {
+ get { return string.Format("Expected {0} but saw {1}", _expected, _actual); }
+ }
+ }
+
+ public class AssertUnexpectedThrowException : Exception
+ {
+ private readonly object _expected;
+
+ public AssertUnexpectedThrowException(object expected)
+ {
+ _expected = expected;
+ }
+
+ public override string Message
+ {
+ get { return string.Format("Expected exception of type {0}", _expected); }
+ }
+ }
+
+ public static class Assert
+ {
+ public static void AreEqual<T>(T expected, T actual)
+ {
+ if (!expected.Equals(actual))
+ {
+ throw new AssertFailedException(expected, actual);
+ }
+ }
+
+ public static void IsTrue(bool value)
+ {
+ if (!value)
+ {
+ throw new AssertFailedException(true, value);
+ }
+ }
+
+ public static void Throws<T>(Action action) where T : Exception
+ {
+ var caught = false;
+ try
+ {
+ action();
+ }
+ catch (T ex)
+ {
+ caught = true;
+ }
+
+ if (!caught)
+ {
+ throw new AssertUnexpectedThrowException(typeof (T));
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+ public class ByteBufferTests
+ {
+
+ public void ByteBuffer_Length_MatchesBufferLength()
+ {
+ var buffer = new byte[1000];
+ var uut = new ByteBuffer(buffer);
+ Assert.AreEqual(buffer.Length, uut.Length);
+ }
+
+ public void ByteBuffer_PutBytePopulatesBufferAtZeroOffset()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ uut.PutByte(0, (byte)99);
+
+ Assert.AreEqual((byte)99, buffer[0]);
+ }
+
+ public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
+ }
+
+ public void ByteBuffer_PutShortPopulatesBufferCorrectly()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ uut.PutShort(0, (short)1);
+
+ // Ensure Endianness was written correctly
+ Assert.AreEqual((byte)1, buffer[0]);
+ Assert.AreEqual((byte)0, buffer[1]);
+ }
+
+ public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
+ }
+
+ public void ByteBuffer_PutShortChecksLength()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(0, 99));
+ }
+
+ public void ByteBuffer_PutShortChecksLengthAndOffset()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
+ }
+
+ public void ByteBuffer_PutIntPopulatesBufferCorrectly()
+ {
+ var buffer = new byte[4];
+ var uut = new ByteBuffer(buffer);
+ uut.PutInt(0, 0x0A0B0C0D);
+
+ // Ensure Endianness was written correctly
+ Assert.AreEqual(0x0D, buffer[0]);
+ Assert.AreEqual(0x0C, buffer[1]);
+ Assert.AreEqual(0x0B, buffer[2]);
+ Assert.AreEqual(0x0A, buffer[3]);
+ }
+
+ public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
+ {
+ var buffer = new byte[4];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+ }
+
+ public void ByteBuffer_PutIntChecksLength()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(0, 0x0A0B0C0D));
+ }
+
+ public void ByteBuffer_PutIntChecksLengthAndOffset()
+ {
+ var buffer = new byte[4];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+ }
+
+ public void ByteBuffer_PutLongPopulatesBufferCorrectly()
+ {
+ var buffer = new byte[8];
+ var uut = new ByteBuffer(buffer);
+ uut.PutLong(0, 0x010203040A0B0C0D);
+
+ // Ensure Endianness was written correctly
+ Assert.AreEqual(0x0D, buffer[0]);
+ Assert.AreEqual(0x0C, buffer[1]);
+ Assert.AreEqual(0x0B, buffer[2]);
+ Assert.AreEqual(0x0A, buffer[3]);
+ Assert.AreEqual(0x04, buffer[4]);
+ Assert.AreEqual(0x03, buffer[5]);
+ Assert.AreEqual(0x02, buffer[6]);
+ Assert.AreEqual(0x01, buffer[7]);
+ }
+
+ public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
+ {
+ var buffer = new byte[8];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+ }
+
+ public void ByteBuffer_PutLongChecksLength()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(0, 0x010203040A0B0C0D));
+ }
+
+ public void ByteBuffer_PutLongChecksLengthAndOffset()
+ {
+ var buffer = new byte[8];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+ }
+
+ public void ByteBuffer_GetByteReturnsCorrectData()
+ {
+ var buffer = new byte[1];
+ buffer[0] = 99;
+ var uut = new ByteBuffer(buffer);
+ Assert.AreEqual((byte)99, uut.Get(0));
+ }
+
+ public void ByteBuffer_GetByteChecksOffset()
+ {
+ var buffer = new byte[1];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
+ }
+
+ public void ByteBuffer_GetShortReturnsCorrectData()
+ {
+ var buffer = new byte[2];
+ buffer[0] = 1;
+ buffer[1] = 0;
+ var uut = new ByteBuffer(buffer);
+ Assert.AreEqual(1, uut.GetShort(0));
+ }
+
+ public void ByteBuffer_GetShortChecksOffset()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(2));
+ }
+
+ public void ByteBuffer_GetShortChecksLength()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
+ }
+
+ public void ByteBuffer_GetIntReturnsCorrectData()
+ {
+ var buffer = new byte[4];
+ buffer[0] = 0x0D;
+ buffer[1] = 0x0C;
+ buffer[2] = 0x0B;
+ buffer[3] = 0x0A;
+ var uut = new ByteBuffer(buffer);
+ Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
+ }
+
+ public void ByteBuffer_GetIntChecksOffset()
+ {
+ var buffer = new byte[4];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(4));
+ }
+
+ public void ByteBuffer_GetIntChecksLength()
+ {
+ var buffer = new byte[2];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
+ }
+
+ public void ByteBuffer_GetLongReturnsCorrectData()
+ {
+ var buffer = new byte[8];
+ buffer[0] = 0x0D;
+ buffer[1] = 0x0C;
+ buffer[2] = 0x0B;
+ buffer[3] = 0x0A;
+ buffer[4] = 0x04;
+ buffer[5] = 0x03;
+ buffer[6] = 0x02;
+ buffer[7] = 0x01;
+ var uut = new ByteBuffer(buffer);
+ Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
+ }
+
+ public void ByteBuffer_GetLongChecksOffset()
+ {
+ var buffer = new byte[8];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(8));
+ }
+
+ public void ByteBuffer_GetLongChecksLength()
+ {
+ var buffer = new byte[7];
+ var uut = new ByteBuffer(buffer);
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{9DB0B5E7-757E-4BD1-A5F6-279390331254}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>FlatBuffers.Test</RootNamespace>
+ <AssemblyName>FlatBuffers.Test</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <StartupObject />
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\MyGame\Example\Any.cs">
+ <Link>MyGame\Example\Any.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\Color.cs">
+ <Link>MyGame\Example\Color.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\Monster.cs">
+ <Link>MyGame\Example\Monster.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\Test.cs">
+ <Link>MyGame\Example\Test.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\Vec3.cs">
+ <Link>MyGame\Example\Vec3.cs</Link>
+ </Compile>
+ <Compile Include="Assert.cs" />
+ <Compile Include="ByteBufferTests.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="FlatBuffersExampleTests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\net\FlatBuffers\FlatBuffers.csproj">
+ <Project>{28C00774-1E73-4A75-AD8F-844CD21A064D}</Project>
+ <Name>FlatBuffers</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="..\monsterdata_test.bin">
+ <Link>Resources\monsterdata_test.bin</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.IO;
+using MyGame.Example;
+
+namespace FlatBuffers.Test
+{
+ public class FlatBuffersExampleTests
+ {
+ public void RunTests()
+ {
+ CanCreateNewFlatBufferFromScratch();
+ CanReadCppGeneratedWireFile();
+ }
+
+ public void CanCreateNewFlatBufferFromScratch()
+ {
+ // Second, let's create a FlatBuffer from scratch in C#, and test it also.
+ // We use an initial size of 1 to exercise the reallocation algorithm,
+ // normally a size larger than the typical FlatBuffer you generate would be
+ // better for performance.
+ var fbb = new FlatBufferBuilder(1);
+
+ // We set up the same values as monsterdata.json:
+
+ var str = fbb.CreateString("MyMonster");
+ var test1 = fbb.CreateString("test1");
+ var test2 = fbb.CreateString("test2");
+
+
+ Monster.StartInventoryVector(fbb, 5);
+ for (int i = 4; i >= 0; i--)
+ {
+ fbb.AddByte((byte)i);
+ }
+ var inv = fbb.EndVector();
+
+ Monster.StartMonster(fbb);
+ Monster.AddHp(fbb, (short)20);
+ var mon2 = Monster.EndMonster(fbb);
+
+ Monster.StartTest4Vector(fbb, 2);
+ MyGame.Example.Test.CreateTest(fbb, (short)10, (byte)20);
+ MyGame.Example.Test.CreateTest(fbb, (short)30, (byte)40);
+ var test4 = fbb.EndVector();
+
+ Monster.StartTestarrayofstringVector(fbb, 2);
+ fbb.AddOffset(test2);
+ fbb.AddOffset(test1);
+ var testArrayOfString = fbb.EndVector();
+
+
+ Monster.StartMonster(fbb);
+ Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+ (byte)4, (short)5, (byte)6));
+ Monster.AddHp(fbb, (short)80);
+ Monster.AddName(fbb, str);
+ Monster.AddInventory(fbb, inv);
+ Monster.AddTestType(fbb, (byte)1);
+ Monster.AddTest(fbb, mon2);
+ Monster.AddTest4(fbb, test4);
+ Monster.AddTestarrayofstring(fbb, testArrayOfString);
+ var mon = Monster.EndMonster(fbb);
+
+ fbb.Finish(mon);
+
+ // Dump to output directory so we can inspect later, if needed
+ using (var ms= new MemoryStream(fbb.Data.Data, fbb.DataStart, fbb.Offset))
+ {
+ var data = ms.ToArray();
+ File.WriteAllBytes(@"Resources/monsterdata_cstest.bin",data);
+ }
+
+ // Now assert the buffer
+ TestBuffer(fbb.Data, fbb.DataStart);
+ }
+
+ private void TestBuffer(ByteBuffer bb, int start)
+ {
+ var monster = Monster.GetRootAsMonster(bb, start);
+
+ Assert.AreEqual(80, monster.Hp());
+ Assert.AreEqual(150, monster.Mana());
+ Assert.AreEqual("MyMonster", monster.Name());
+
+ var pos = monster.Pos();
+ Assert.AreEqual(1.0f, pos.X());
+ Assert.AreEqual(2.0f, pos.Y());
+ Assert.AreEqual(3.0f, pos.Z());
+
+ Assert.AreEqual(3.0f, pos.Test1());
+ Assert.AreEqual((byte)4, pos.Test2());
+ var t = pos.Test3();
+ Assert.AreEqual((short)5, t.A());
+ Assert.AreEqual((byte)6, t.B());
+
+ Assert.AreEqual((byte)Any.Monster, monster.TestType());
+
+ var monster2 = new Monster();
+ Assert.IsTrue(monster.Test(monster2) != null);
+ Assert.AreEqual(20, monster2.Hp());
+
+
+ Assert.AreEqual(5, monster.InventoryLength());
+ var invsum = 0;
+ for (var i = 0; i < monster.InventoryLength(); i++)
+ {
+ invsum += monster.Inventory(i);
+ }
+ Assert.AreEqual(10, invsum);
+
+ var test0 = monster.Test4(0);
+ var test1 = monster.Test4(1);
+ Assert.AreEqual(2, monster.Test4Length());
+
+ Assert.AreEqual(100, test0.A() + test0.B() + test1.A() + test1.B());
+
+
+ Assert.AreEqual(2, monster.TestarrayofstringLength());
+ Assert.AreEqual("test1", monster.Testarrayofstring(0));
+ Assert.AreEqual("test2", monster.Testarrayofstring(1));
+ }
+
+ public void CanReadCppGeneratedWireFile()
+ {
+ var data = File.ReadAllBytes(@"Resources/monsterdata_test.bin");
+ var bb = new ByteBuffer(data);
+ TestBuffer(bb, 0);
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace FlatBuffers.Test
+{
+ static class Program
+ {
+ public static int Main(string[] args)
+ {
+ var tests = new FlatBuffersExampleTests();
+ try
+ {
+ tests.RunTests();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("FlatBuffersExampleTests FAILED - {0}", ex.GetBaseException());
+ return -1;
+ }
+
+ // Run ByteBuffers Tests
+ var testClass = new ByteBufferTests();
+
+ var methods = testClass.GetType().GetMethods(BindingFlags.Public |
+ BindingFlags.Instance)
+ .Where(m => m.Name.StartsWith("ByteBuffer_"));
+ foreach (var method in methods)
+ {
+ try
+ {
+ method.Invoke(testClass, new object[] { });
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("ByteBufferTests FAILED when invoking {0} with error {1}",
+ method.Name, ex.GetBaseException());
+ return -1;
+ }
+
+ }
+
+ return 0;
+ }
+ }
+}
--- /dev/null
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FlatBuffers.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FlatBuffers.Test")]
+[assembly: AssemblyCopyright("Copyright © 2014 Google Inc")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a1d58a51-3e74-4ae9-aac7-5a399c9eed1a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null
+// automatically generated, do not modify
+
+namespace MyGame.Example
+{
+
+using FlatBuffers;
+
+public class Any
+{
+ public static byte NONE = 0;
+ public static byte Monster = 1;
+};
+
+
+}
--- /dev/null
+// automatically generated, do not modify
+
+namespace MyGame.Example
+{
+
+using FlatBuffers;
+
+public class Color
+{
+ public static byte Red = 1;
+ public static byte Green = 2;
+ public static byte Blue = 8;
+};
+
+
+}
--- /dev/null
+// automatically generated, do not modify\r
+\r
+namespace MyGame.Example\r
+{\r
+\r
+using FlatBuffers;\r
+\r
+public class Monster : Table {\r
+ public static Monster GetRootAsMonster(ByteBuffer _bb, int offset) { return (new Monster()).__init(_bb.GetInt(offset) + offset, _bb); }\r
+ public static bool MonsterBufferHasIdentifier(ByteBuffer _bb, int offset) { return __has_identifier(_bb, offset, "MONS"); }\r
+ public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }\r
+\r
+ public Vec3 Pos() { return Pos(new Vec3()); }\r
+ public Vec3 Pos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }\r
+ public short Mana() { int o = __offset(6); return o != 0 ? bb.GetShort(o + bb_pos) : (short)150; }\r
+ public short Hp() { int o = __offset(8); return o != 0 ? bb.GetShort(o + bb_pos) : (short)100; }\r
+ public string Name() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }\r
+ public byte Inventory(int j) { int o = __offset(14); return o != 0 ? bb.Get(__vector(o) + j * 1) : (byte)0; }\r
+ public int InventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }\r
+ public byte Color() { int o = __offset(16); return o != 0 ? bb.Get(o + bb_pos) : (byte)8; }\r
+ public byte TestType() { int o = __offset(18); return o != 0 ? bb.Get(o + bb_pos) : (byte)0; }\r
+ public Table Test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }\r
+ public Test Test4(int j) { return Test4(new Test(), j); }\r
+ public Test Test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__init(__vector(o) + j * 4, bb) : null; }\r
+ public int Test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }\r
+ public string Testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }\r
+ public int TestarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }\r
+ /* an example documentation comment: this will end up in the generated code\r multiline too\r*/\r
+ public Monster Testarrayoftables(int j) { return Testarrayoftables(new Monster(), j); }\r
+ public Monster Testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }\r
+ public int TestarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }\r
+ public Monster Enemy() { return Enemy(new Monster()); }\r
+ public Monster Enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }\r
+ public byte Testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.Get(__vector(o) + j * 1) : (byte)0; }\r
+ public int TestnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }\r
+ public Monster Testempty() { return Testempty(new Monster()); }\r
+ public Monster Testempty(Monster obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }\r
+\r
+ public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(15); }\r
+ public static void AddPos(FlatBufferBuilder builder, int posOffset) { builder.AddStruct(0, posOffset, 0); }\r
+ public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }\r
+ public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }\r
+ public static void AddName(FlatBufferBuilder builder, int nameOffset) { builder.AddOffset(3, nameOffset, 0); }\r
+ public static void AddInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.AddOffset(5, inventoryOffset, 0); }\r
+ public static void StartInventoryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }\r
+ public static void AddColor(FlatBufferBuilder builder, byte color) { builder.AddByte(6, color, 8); }\r
+ public static void AddTestType(FlatBufferBuilder builder, byte testType) { builder.AddByte(7, testType, 0); }\r
+ public static void AddTest(FlatBufferBuilder builder, int testOffset) { builder.AddOffset(8, testOffset, 0); }\r
+ public static void AddTest4(FlatBufferBuilder builder, int test4Offset) { builder.AddOffset(9, test4Offset, 0); }\r
+ public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }\r
+ public static void AddTestarrayofstring(FlatBufferBuilder builder, int testarrayofstringOffset) { builder.AddOffset(10, testarrayofstringOffset, 0); }\r
+ public static void StartTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }\r
+ public static void AddTestarrayoftables(FlatBufferBuilder builder, int testarrayoftablesOffset) { builder.AddOffset(11, testarrayoftablesOffset, 0); }\r
+ public static void StartTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }\r
+ public static void AddEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.AddOffset(12, enemyOffset, 0); }\r
+ public static void AddTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.AddOffset(13, testnestedflatbufferOffset, 0); }\r
+ public static void StartTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }\r
+ public static void AddTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.AddOffset(14, testemptyOffset, 0); }\r
+ public static int EndMonster(FlatBufferBuilder builder) { return builder.EndObject(); }\r
+ public static void FinishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.Finish(offset, "MONS"); }\r
+};\r
+\r
+\r
+}\r
--- /dev/null
+// automatically generated, do not modify
+
+namespace MyGame.Example
+{
+
+using FlatBuffers;
+
+public class Test : Struct {
+ public Test __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public short A() { return bb.GetShort(bb_pos + 0); }
+ public byte B() { return bb.Get(bb_pos + 2); }
+
+ public static int CreateTest(FlatBufferBuilder builder, short A, byte B) {
+ builder.Prep(2, 4);
+ builder.Pad(1);
+ builder.PutByte(B);
+ builder.PutShort(A);
+ return builder.Offset;
+ }
+};
+
+
+}
--- /dev/null
+// automatically generated, do not modify
+
+namespace MyGame.Example
+{
+
+using FlatBuffers;
+
+public class Vec3 : Struct {
+ public Vec3 __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public float X() { return bb.GetFloat(bb_pos + 0); }
+ public float Y() { return bb.GetFloat(bb_pos + 4); }
+ public float Z() { return bb.GetFloat(bb_pos + 8); }
+ public double Test1() { return bb.GetDouble(bb_pos + 16); }
+ public byte Test2() { return bb.Get(bb_pos + 24); }
+ public Test Test3() { return Test3(new Test()); }
+ public Test Test3(Test obj) { return obj.__init(bb_pos + 26, bb); }
+
+ public static int CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, byte Test2, short Test_A, byte Test_B) {
+ builder.Prep(16, 32);
+ builder.Pad(2);
+ builder.Prep(2, 4);
+ builder.Pad(1);
+ builder.PutByte(Test_B);
+ builder.PutShort(Test_A);
+ builder.Pad(1);
+ builder.PutByte(Test2);
+ builder.PutDouble(Test1);
+ builder.Pad(4);
+ builder.PutFloat(Z);
+ builder.PutFloat(Y);
+ builder.PutFloat(X);
+ return builder.Offset;
+ }
+};
+
+
+}