public async Task GenerateForCustomFlagWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLenAccessor, DataType dataType = null) { var fieldData = typeGen.GetFieldData(); var gen = this.Module.GetTypeGeneration(typeGen.GetType()); string loc; if (fieldData.HasTrigger) { using (var args = new ArgsWrapper(fg, $"partial void {typeGen.Name}CustomParse")) { args.Add($"{nameof(OverlayStream)} stream"); args.Add($"long finalPos"); args.Add($"int offset"); } if (typeGen.Nullable && !typeGen.CanBeNullable(getter: true)) { fg.AppendLine($"public bool {typeGen.Name}_IsSet => Get{typeGen.Name}IsSetCustom();"); } loc = $"_{typeGen.Name}Location.Value"; } else if (dataType != null) { loc = $"_{typeGen.Name}Location"; DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLenAccessor); } else { loc = passedLenAccessor; } using (var args = new ArgsWrapper(fg, $"public {typeGen.OverrideStr}{typeGen.TypeName(getter: true)}{(typeGen.IsNullable ? "?" : null)} {typeGen.Name} => Get{typeGen.Name}Custom")) { if (!fieldData.HasTrigger && dataType == null) { args.Add($"location: {loc ?? "0x0"}"); } } if (!fieldData.HasTrigger) { currentPosition += fieldData.Length ?? await gen.ExpectedLength(objGen, typeGen); } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int? currentPosition, string passedLengthAccessor, DataType dataType) { var eType = typeGen as EnumType; var data = typeGen.GetFieldData(); var nullable = typeGen.Nullable && eType.NullableFallbackInt == null; switch (data.BinaryOverlayFallback) { case BinaryGenerationType.Normal: break; case BinaryGenerationType.NoGeneration: return; case BinaryGenerationType.Custom: await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields( fg, objGen, typeGen, dataAccessor, currentPosition, passedLengthAccessor, dataType); return; default: throw new NotImplementedException(); } if (dataType == null && data.HasVersioning && !typeGen.Nullable) { fg.AppendLine($"private bool _{typeGen.Name}_IsSet => {VersioningModule.GetVersionIfCheck(data, "_package.FormVersion!.FormVersion!.Value")};"); } if (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); } var posStr = dataType == null ? passedLengthAccessor : $"_{typeGen.Name}Location"; string slice; if (data.RecordType.HasValue) { slice = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location!.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; } else { slice = $"{dataAccessor}.Span.Slice({posStr ?? "0x0"}, 0x{eType.ByteLength:X})"; } var getType = GenerateForTypicalWrapper(objGen, typeGen, slice, "_package"); if (dataType != null) { DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); } bool isSetCheck = dataType != null || data.HasVersioning; if (eType.NullableFallbackInt != null) { fg.AppendLine($"public {eType.TypeName(getter: true)}? {eType.Name}"); using (new BraceWrapper(fg)) { fg.AppendLine("get"); using (new BraceWrapper(fg)) { fg.AppendLine($"var val = {getType};"); fg.AppendLine($"if (((int)val) == {eType.NullableFallbackInt}) return null;"); fg.AppendLine("return val;"); } } } else if (data.HasTrigger) { if (typeGen.CanBeNullable(getter: true)) { fg.AppendLine($"public {eType.TypeName(getter: true)}{(nullable ? "?" : null)} {eType.Name} => _{typeGen.Name}Location.HasValue ? {getType} : default({eType.TypeName(getter: true)}{(nullable ? "?" : null)});"); } else { fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => {getType};"); } } else { if (!isSetCheck) { fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => {getType};"); } else { fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => _{typeGen.Name}_IsSet ? {getType} : default;"); } } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType) { LoquiType loqui = typeGen as LoquiType; var data = typeGen.GetFieldData(); switch (data.BinaryOverlayFallback) { case BinaryGenerationType.Normal: break; case BinaryGenerationType.NoGeneration: return; case BinaryGenerationType.Custom: await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields( fg, objGen, typeGen, dataAccessor, currentPosition, passedLengthAccessor, dataType); return; default: throw new NotImplementedException(); } string DataAccessor(Accessor accessor, string positionStr, string lenStr) { if (objGen.GetObjectType() == ObjectType.Mod) { return($"{nameof(BinaryOverlay)}.{nameof(BinaryOverlay.LockExtractMemory)}({accessor}, {positionStr}, {lenStr})"); } else { return($"{accessor}.Slice({positionStr})"); } } string recConverter = $"default({nameof(RecordTypeConverter)})"; if (loqui.GetFieldData()?.RecordTypeConverter != null && loqui.GetFieldData().RecordTypeConverter.FromConversions.Count > 0) { recConverter = $"{objGen.RegistrationName}.{loqui.Name}Converter"; } var isRequiredRecord = !loqui.Nullable && data.HasTrigger; if (dataType == null) { if (loqui.GetFieldData()?.HasTrigger ?? false) { if (loqui.TargetObjectGeneration.IsTypelessStruct()) { if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name};"); } else if (loqui.Nullable) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)}? {typeGen.Name} {{ get; private set; }}"); } } else { var severalSubTypes = data.GenerationTypes .Select(i => i.Value) .WhereCastable <TypeGeneration, LoquiType>() .Where(loqui => !loqui?.TargetObjectGeneration?.Abstract ?? true) .CountGreaterThan(1); if (severalSubTypes) { fg.AppendLine($"private {nameof(RecordType)} _{typeGen.Name}Type;"); } fg.AppendLine($"private {GetLocationObjectString(objGen)}? _{typeGen.Name}Location;"); using (new LineWrapper(fg)) { if (loqui.IsNullable) { fg.Append($"public "); } else { fg.Append($"private "); } fg.Append($"{loqui.Interface(getter: true, internalInterface: true)}{(typeGen.CanBeNullable(getter: true) ? "?" : null)} "); if (!loqui.IsNullable || isRequiredRecord) { fg.Append("_"); } fg.Append($"{typeGen.Name}"); if (!severalSubTypes) { fg.Append($" => _{typeGen.Name}Location.HasValue ? "); fg.Append($"{this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location!.Value.Min", $"_{typeGen.Name}Location!.Value.Max")}, _package), _package"); if (!recConverter.StartsWith("default(")) { fg.Append($", {recConverter}"); } fg.Append($") "); fg.Append($": default;"); } } if (severalSubTypes) { using (new BraceWrapper(fg)) { fg.AppendLine("get"); using (new BraceWrapper(fg)) { fg.AppendLine($"if (!_{typeGen.Name}Location.HasValue) return default;"); fg.AppendLine($"switch (_{typeGen.Name}Type.TypeInt)"); using (new BraceWrapper(fg)) { foreach (var gen in data.GenerationTypes) { if (!(gen.Value is LoquiType subLoq)) { continue; } if (subLoq?.TargetObjectGeneration?.Abstract ?? false) { continue; } foreach (var trigger in gen.Key) { fg.AppendLine($"case 0x{trigger.TypeInt.ToString("X")}: // {trigger.Type}"); } using (new DepthWrapper(fg)) using (new LineWrapper(fg)) { fg.Append($"return {this.Module.BinaryOverlayClassName(subLoq)}.{subLoq.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{subLoq.Name}Location!.Value.Min", $"_{subLoq.Name}Location!.Value.Max")}, _package), _package"); if (!loqui.Singleton) { fg.Append($", {recConverter}"); } fg.Append($");"); } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { fg.AppendLine("throw new ArgumentException();"); } } } } } } } else { if (!loqui.Singleton) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({dataAccessor}.Slice({passedLengthAccessor ?? "0x0"}), _package), _package, {recConverter});"); } else { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)} _{typeGen.Name} {{ get; private set; }}"); } } } else { isRequiredRecord = true; DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name} => _{typeGen.Name}_IsSet ? {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location", null)}, _package), _package) : default;"); } if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => _{typeGen.Name} ?? new {loqui.DirectTypeName}({(loqui.ThisConstruction ? "this" : null)});"); } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType) { var data = typeGen.GetFieldData(); switch (data.BinaryOverlayFallback) { case BinaryGenerationType.Normal: break; case BinaryGenerationType.NoGeneration: return; case BinaryGenerationType.Custom: await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields( fg, objGen, typeGen, dataAccessor, currentPosition, passedLengthAccessor, dataType); return; default: throw new NotImplementedException(); } if (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); if (typeGen.CanBeNullable(getter: true)) { dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}{(typeGen.Nullable ? "?" : null)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {dataAccessor}[0] : default(Byte{(typeGen.Nullable ? "?" : null)});"); } else { fg.AppendLine($"public bool {typeGen.Name}_IsSet => _{typeGen.Name}Location.HasValue;"); if (dataType != null) { throw new ArgumentException(); } dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {dataAccessor}[0] : default(Byte{(typeGen.Nullable ? "?" : null)});"); } } else { if (dataType == null) { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {dataAccessor}.Span[{passedLengthAccessor ?? "0x0"}];"); } else { DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}_IsSet ? {dataAccessor}.Span[_{typeGen.Name}Location] : default;"); } } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType = null) { var data = typeGen.GetFieldData(); switch (data.BinaryOverlayFallback) { case BinaryGenerationType.Normal: break; case BinaryGenerationType.NoGeneration: return; case BinaryGenerationType.Custom: await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields( fg, objGen, typeGen, dataAccessor, currentPosition, passedLengthAccessor, dataType); return; default: throw new NotImplementedException(); } if (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); } if (data.RecordType.HasValue) { if (dataType != null) { throw new ArgumentException(); } dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}{(typeGen.HasBeenSet ? "?" : null)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {GenerateForTypicalWrapper(objGen, typeGen, dataAccessor, "_package")} : {typeGen.GetDefault(getter: true)};"); } else { var expectedLen = await this.ExpectedLength(objGen, typeGen); if (this.CustomWrapper != null) { if (CustomWrapper(fg, objGen, typeGen, dataAccessor, passedLengthAccessor)) { return; } } if (dataType == null) { if (typeGen.HasBeenSet) { if (!typeGen.CanBeNullable(getter: true)) { throw new NotImplementedException(); //fg.AppendLine($"public bool {typeGen.Name}_IsSet => {dataAccessor}.Length >= {(currentPosition + this.ExpectedLength(objGen, typeGen).Value)};"); //fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Span.Slice({currentPosition}, {this.ExpectedLength(objGen, typeGen).Value})", "_package")};"); } else { string passed = int.TryParse(passedLengthAccessor.TrimStart("0x"), System.Globalization.NumberStyles.HexNumber, null, out var passedInt) ? (passedInt + expectedLen.Value).ToString() : $"({passedLengthAccessor} + {expectedLen.Value})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}? {typeGen.Name} => {dataAccessor}.Length >= {passed} ? {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor}{(expectedLen != null ? $", 0x{expectedLen.Value:X}" : null)})", "_package")} : {typeGen.GetDefault(getter: true)};"); } } else { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor ?? "0x0"}{(expectedLen != null ? $", 0x{expectedLen.Value:X}" : null)})", "_package")};"); } } else { DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}_IsSet ? {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice(_{typeGen.Name}Location{(expectedLen.HasValue ? $", {expectedLen.Value}" : null)})", "_package")} : {typeGen.GetDefault(getter: true)};"); } } }
protected virtual string ItemWriteAccess(TypeGeneration typeGen, Accessor itemAccessor) { return($"{itemAccessor.Access}{(typeGen.Nullable && typeGen.CanBeNullable(true) && CanBeNotNullable ? ".Value" : null)}"); }