public int GetMaxSize(T item) { if (object.ReferenceEquals(item, null)) { throw new InvalidDataException("The root table may not be null."); } // 4 + padding(4) + inner serializer size. We add the extra to account for the very first uoffset. return(sizeof(uint) + SerializationHelpers.GetMaxPadding(sizeof(uint)) + this.innerSerializer.GetMaxSize(item)); }
public int GetMaxSize(T item) { if (item is null) { throw new ArgumentNullException(nameof(item), "The root table may not be null."); } return(sizeof(uint) // uoffset to first table + SerializationHelpers.GetMaxPadding(sizeof(uint)) // alignment error + this.innerSerializer.GetMaxSize(item) // size of item + FileIdentifierSize); // file identifier. Not present on every table, but cheaper to add as constant // than to introduce an 'if'. }
private void ImplementTableGetMaxSizeMethod(TableTypeModel tableModel) { int vtableEntryCount = tableModel.MaxIndex + 1; // vtable length + table length + 2 * entryCount + padding to 2-byte alignment. int maxVtableSize = sizeof(ushort) * (2 + vtableEntryCount) + SerializationHelpers.GetMaxPadding(sizeof(ushort)); int maxTableSize = tableModel.NonPaddedMaxTableInlineSize + SerializationHelpers.GetMaxPadding(tableModel.Alignment); List <string> statements = new List <string>(); foreach (var kvp in tableModel.IndexToMemberMap) { int index = kvp.Key; var member = kvp.Value; if (member.ItemTypeModel.IsFixedSize) { // This should already be accounted for in table.NonPaddedMax size above. continue; } string variableName = $"index{index}Value"; statements.Add($"var {variableName} = item.{member.PropertyInfo.Name};"); string statement = $"runningSum += {this.InvokeGetMaxSizeMethod(member.ItemTypeModel, variableName)};"; string condition = $"if ({variableName} != null)"; if (member.ItemTypeModel is VectorTypeModel vectorModel && vectorModel.IsMemoryVector) { condition = string.Empty; } statement = $@" {condition} {{ {statement} }}"; statements.Add(statement); } string body = $@" int runningSum = {maxTableSize} + {maxVtableSize}; {string.Join("\r\n", statements)}; return runningSum; "; this.GenerateGetMaxSizeMethod(tableModel.ClrType, body); }
/// <summary> /// Gets the max size of the vector itself, not the uoffset_t as part of the containing table. /// </summary> private void ImplementVectorGetMaxSizeMethod(VectorTypeModel vectorModel) { var itemModel = vectorModel.ItemTypeModel; string body; // count of items + padding(uoffset_t); int fixedSize = sizeof(uint) + SerializationHelpers.GetMaxPadding(sizeof(uint)); string lengthProperty = $"item.{vectorModel.LengthPropertyName}"; // Constant size items. We can reduce these reasonably well. if (itemModel.IsFixedSize) { body = $"return {fixedSize} + {SerializationHelpers.GetMaxPadding(itemModel.Alignment)} + ({vectorModel.PaddedMemberInlineSize} * {lengthProperty});"; } else if (itemModel.SchemaType == FlatBufferSchemaType.Table || itemModel.SchemaType == FlatBufferSchemaType.String) { Debug.Assert(itemModel.Alignment == sizeof(uint)); Debug.Assert(itemModel.InlineSize == sizeof(uint)); body = $@" int length = {lengthProperty}; int runningSum = {fixedSize} + {SerializationHelpers.GetMaxPadding(itemModel.Alignment)} + ({vectorModel.PaddedMemberInlineSize} * length); for (int i = 0; i < length; ++i) {{ var itemTemp = item[i]; {CSharpHelpers.GetNonNullCheckInvocation(itemModel, "itemTemp")}; runningSum += {this.InvokeGetMaxSizeMethod(itemModel, "itemTemp")}; }} return runningSum;"; } else { throw new NotImplementedException("Vector.GetMaxSize is not implemented for schema type of " + itemModel.SchemaType); } this.GenerateGetMaxSizeMethod(vectorModel.ClrType, body); }