1 /* 2 * Copyright 2014 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 using System; 18 using System.Text; 19 20 namespace FlatBuffers 21 { 22 /// <summary> 23 /// All tables in the generated code derive from this struct, and add their own accessors. 24 /// </summary> 25 public struct Table 26 { 27 public int bb_pos; 28 public ByteBuffer bb; 29 30 public ByteBuffer ByteBuffer { get { return bb; } } 31 32 // Look up a field in the vtable, return an offset into the object, or 0 if the field is not 33 // present. __offsetFlatBuffers.Table34 public int __offset(int vtableOffset) 35 { 36 int vtable = bb_pos - bb.GetInt(bb_pos); 37 return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0; 38 } 39 __offsetFlatBuffers.Table40 public static int __offset(int vtableOffset, int offset, ByteBuffer bb) 41 { 42 int vtable = bb.Length - offset; 43 return (int)bb.GetShort(vtable + vtableOffset - bb.GetInt(vtable)) + vtable; 44 } 45 46 // Retrieve the relative offset stored at "offset" __indirectFlatBuffers.Table47 public int __indirect(int offset) 48 { 49 return offset + bb.GetInt(offset); 50 } 51 __indirectFlatBuffers.Table52 public static int __indirect(int offset, ByteBuffer bb) 53 { 54 return offset + bb.GetInt(offset); 55 } 56 57 // Create a .NET String from UTF-8 data stored inside the flatbuffer. __stringFlatBuffers.Table58 public string __string(int offset) 59 { 60 offset += bb.GetInt(offset); 61 var len = bb.GetInt(offset); 62 var startPos = offset + sizeof(int); 63 return bb.GetStringUTF8(startPos, len); 64 } 65 66 // Get the length of a vector whose offset is stored at "offset" in this object. __vector_lenFlatBuffers.Table67 public int __vector_len(int offset) 68 { 69 offset += bb_pos; 70 offset += bb.GetInt(offset); 71 return bb.GetInt(offset); 72 } 73 74 // Get the start of data of a vector whose offset is stored at "offset" in this object. __vectorFlatBuffers.Table75 public int __vector(int offset) 76 { 77 offset += bb_pos; 78 return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length 79 } 80 81 #if ENABLE_SPAN_T 82 // Get the data of a vector whoses offset is stored at "offset" in this object as an 83 // Spant<byte>. If the vector is not present in the ByteBuffer, 84 // then an empty span will be returned. __vector_as_spanFlatBuffers.Table85 public Span<byte> __vector_as_span(int offset) 86 { 87 var o = this.__offset(offset); 88 if (0 == o) 89 { 90 return new Span<byte>(); 91 } 92 93 var pos = this.__vector(o); 94 var len = this.__vector_len(o); 95 return bb.ToSpan(pos, len); 96 } 97 #else 98 // Get the data of a vector whoses offset is stored at "offset" in this object as an 99 // ArraySegment<byte>. If the vector is not present in the ByteBuffer, 100 // then a null value will be returned. __vector_as_arraysegmentFlatBuffers.Table101 public ArraySegment<byte>? __vector_as_arraysegment(int offset) 102 { 103 var o = this.__offset(offset); 104 if (0 == o) 105 { 106 return null; 107 } 108 109 var pos = this.__vector(o); 110 var len = this.__vector_len(o); 111 return bb.ToArraySegment(pos, len); 112 } 113 #endif 114 115 // Get the data of a vector whoses offset is stored at "offset" in this object as an 116 // T[]. If the vector is not present in the ByteBuffer, then a null value will be 117 // returned. 118 public T[] __vector_as_array<T>(int offset) 119 where T : struct 120 { 121 if(!BitConverter.IsLittleEndian) 122 { 123 throw new NotSupportedException("Getting typed arrays on a Big Endian " + 124 "system is not support"); 125 } 126 127 var o = this.__offset(offset); 128 if (0 == o) 129 { 130 return null; 131 } 132 133 var pos = this.__vector(o); 134 var len = this.__vector_len(o); 135 return bb.ToArray<T>(pos, len); 136 } 137 138 // Initialize any Table-derived type to point to the union at the given offset. 139 public T __union<T>(int offset) where T : struct, IFlatbufferObject 140 { 141 offset += bb_pos; 142 T t = new T(); 143 t.__init(offset + bb.GetInt(offset), bb); 144 return t; 145 } 146 __has_identifier(ByteBuffer bb, string ident)147 public static bool __has_identifier(ByteBuffer bb, string ident) 148 { 149 if (ident.Length != FlatBufferConstants.FileIdentifierLength) 150 throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident"); 151 152 for (var i = 0; i < FlatBufferConstants.FileIdentifierLength; i++) 153 { 154 if (ident[i] != (char)bb.Get(bb.Position + sizeof(int) + i)) return false; 155 } 156 157 return true; 158 } 159 160 // Compare strings in the ByteBuffer. CompareStrings(int offset_1, int offset_2, ByteBuffer bb)161 public static int CompareStrings(int offset_1, int offset_2, ByteBuffer bb) 162 { 163 offset_1 += bb.GetInt(offset_1); 164 offset_2 += bb.GetInt(offset_2); 165 var len_1 = bb.GetInt(offset_1); 166 var len_2 = bb.GetInt(offset_2); 167 var startPos_1 = offset_1 + sizeof(int); 168 var startPos_2 = offset_2 + sizeof(int); 169 var len = Math.Min(len_1, len_2); 170 for(int i = 0; i < len; i++) { 171 byte b1 = bb.Get(i + startPos_1); 172 byte b2 = bb.Get(i + startPos_2); 173 if (b1 != b2) 174 return b1 - b2; 175 } 176 return len_1 - len_2; 177 } 178 179 // Compare string from the ByteBuffer with the string object CompareStrings(int offset_1, byte[] key, ByteBuffer bb)180 public static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb) 181 { 182 offset_1 += bb.GetInt(offset_1); 183 var len_1 = bb.GetInt(offset_1); 184 var len_2 = key.Length; 185 var startPos_1 = offset_1 + sizeof(int); 186 var len = Math.Min(len_1, len_2); 187 for (int i = 0; i < len; i++) { 188 byte b = bb.Get(i + startPos_1); 189 if (b != key[i]) 190 return b - key[i]; 191 } 192 return len_1 - len_2; 193 } 194 } 195 } 196