public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?passedLength, string passedLengthAccessor, DataType data = null) { using (var args = new ArgsWrapper(fg, $"partial void {(typeGen.Name == null ? typeGen.GetFieldData().RecordType?.ToString() : typeGen.Name)}CustomParse")) { args.Add($"{nameof(OverlayStream)} stream"); args.Add($"int offset"); } }
public override async Task GenerateCopyIn( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor frameAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationMaskAccessor) { var fieldData = typeGen.GetFieldData(); if (fieldData.HasTrigger) { fg.AppendLine($"{frameAccessor}.Position += {frameAccessor}.{nameof(MutagenBinaryReadStream.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(RecordHeaderConstants.HeaderLength)};"); } bool hasCustom = false; List <string> extraArgs = new List <string>(); extraArgs.Add($"frame: {frameAccessor}{(fieldData.HasTrigger ? ".SpawnWithLength(contentLength)" : "")}"); foreach (var writeParam in this.AdditionalCopyInParams) { var get = writeParam( objGen: objGen, typeGen: typeGen); if (get.Failed) { continue; } extraArgs.Add(get.Value); hasCustom = true; } if (CustomRead != null) { if (CustomRead(fg, objGen, typeGen, frameAccessor, itemAccessor)) { return; } } if (PreferDirectTranslation && !hasCustom) { fg.AppendLine($"{itemAccessor} = {frameAccessor}.Read{typeName}();"); } else { TranslationGeneration.WrapParseCall( new TranslationWrapParseArgs() { FG = fg, TypeGen = typeGen, TranslatorLine = $"{this.Namespace}{this.Typename(typeGen)}BinaryTranslation.Instance", MaskAccessor = errorMaskAccessor, ItemAccessor = itemAccessor, TranslationMaskAccessor = null, AsyncMode = AsyncMode.Off, IndexAccessor = typeGen.HasIndex ? typeGen.IndexEnumInt : null, ExtraArgs = extraArgs.ToArray(), SkipErrorMask = !this.DoErrorMasks }); } }
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(PluginBinaryOverlay)}.{nameof(PluginBinaryOverlay.LockExtractMemory)}({accessor}, {positionStr}, {lenStr})"); } else { return($"{accessor}.Slice({positionStr})"); } } string recConverter = $"default({nameof(TypedParseParams)})"; 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 is GroupType) { fg.AppendLine($"private List<{GetLocationObjectString(objGen)}>? _{typeGen.Name}Locations;"); 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}"); fg.Append($" => _{typeGen.Name}Locations != null ? "); fg.Append( $"{this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(_data, _{typeGen.Name}Locations, _package"); if (!recConverter.StartsWith("default(")) { fg.Append($", {recConverter}"); } fg.Append($") "); fg.Append($": default;"); } } else 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;"); } if (data.OverflowRecordType.HasValue) { fg.AppendLine($"private int? _{typeGen.Name}LengthOverride;"); } 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{(data.OverflowRecordType.HasValue ? $", new {nameof(TypedParseParams)}(_{typeGen.Name}LengthOverride, null)" : null)}"); 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 <int?> ExpectedLength(ObjectGeneration objGen, TypeGeneration typeGen) { var data = typeGen.GetFieldData(); if (data.Length.HasValue) { return(data.Length); } LoquiType loqui = typeGen as LoquiType; if (loqui.TargetObjectGeneration == null) { return(null); } var sum = 0; foreach (var item in loqui.TargetObjectGeneration.IterateFields(includeBaseClass: true)) { if (item.Nullable) { return(null); } if (!this.Module.TryGetTypeGeneration(item.GetType(), out var gen)) { continue; } var len = await gen.ExpectedLength(loqui.TargetObjectGeneration, item); if (len == null) { return(null); } sum += len.Value; } if (loqui.TargetObjectGeneration.Abstract) { int?absSum = null; foreach (var inheritingObj in await loqui.TargetObjectGeneration.InheritingObjects()) { int objectSum = 0; foreach (var item in inheritingObj.IterateFields(includeBaseClass: true)) { if (item.Nullable) { return(null); } if (!this.Module.TryGetTypeGeneration(item.GetType(), out var gen)) { continue; } var len = await gen.ExpectedLength(inheritingObj, item); if (len == null) { return(null); } objectSum += len.Value; } if (absSum == null) { absSum = objectSum; } else if (absSum.Value != objectSum) { // Inheriting objects don't agree on their length, so we can't expect a certain length return(null); } } if (absSum == null) { return(null); } sum += absSum.Value; } return(sum); }
public override async Task GenerateWrite(FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor writerAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationAccessor, Accessor converterAccessor) { fg.AppendLine($"using (HeaderExport.Subrecord(writer, RecordTypes.{typeGen.GetFieldData().RecordType.Value})) {{ }}"); }
public override async Task GenerateWrite( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor writerAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationMask, Accessor converterAccessor) { var dict = typeGen as DictType; var subData = dict.ValueTypeGen.GetFieldData(); var data = typeGen.GetFieldData(); if (data.MarkerType.HasValue) { fg.AppendLine($"using (HeaderExport.ExportHeader(writer, {objGen.RegistrationName}.{data.MarkerType.Value.Type}_HEADER, ObjectType.Subrecord)) {{ }}"); } var binaryType = GetDictType(dict); if (!this.Module.TryGetTypeGeneration(dict.ValueTypeGen.GetType(), out var valTransl)) { throw new ArgumentException("Unsupported type generator: " + dict.ValueTypeGen); } if (dict.Mode == DictMode.KeyedValue || binaryType == DictBinaryType.EnumMap) { var term = binaryType == DictBinaryType.EnumMap ? "Dict" : "List"; using (var args = new ArgsWrapper(fg, $"{this.NamespacePrefix}{term}BinaryTranslation<{dict.ValueTypeGen.TypeName(getter: true)}>.Instance.Write")) { args.Add($"writer: {writerAccessor}"); args.Add($"items: {itemAccessor}{(binaryType == DictBinaryType.EnumMap ? null : ".Items")}"); if (binaryType == DictBinaryType.Trigger) { args.Add($"recordType: {objGen.RecordTypeHeaderName(data.RecordType.Value)}"); } if (valTransl.AllowDirectWrite(objGen, typeGen)) { args.Add($"transl: {valTransl.GetTranslatorInstance(dict.ValueTypeGen, getter: true)}.Write"); } else { args.Add((gen) => { gen.AppendLine($"transl: (MutagenWriter r, {dict.ValueTypeGen.TypeName(getter: true)} dictSubItem) =>"); using (new BraceWrapper(gen)) { LoquiType targetLoqui = dict.ValueTypeGen as LoquiType; valTransl.GenerateWrite( fg: gen, objGen: objGen, typeGen: targetLoqui, itemAccessor: new Accessor("dictSubItem"), writerAccessor: "r", translationAccessor: "dictTranslMask", errorMaskAccessor: null, converterAccessor: null); } }); } } } else { throw new NotImplementedException(); } }
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(); } var gendered = typeGen as GenderedType; this.Module.TryGetTypeGeneration(gendered.SubTypeGeneration.GetType(), out var subBin); var typeName = $"{gendered.SubTypeGeneration.TypeName(getter: true, needsCovariance: true)}{gendered.SubTypeGeneration.NullChar}"; if (data.HasTrigger && !gendered.ItemNullable) { var subLen = (await subBin.ExpectedLength(objGen, gendered.SubTypeGeneration)).Value; if (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); } fg.AppendLine($"public IGenderedItemGetter<{gendered.SubTypeGeneration.TypeName(getter: true, needsCovariance: true)}>{(typeGen.Nullable ? "?" : null)} {typeGen.Name}"); using (new BraceWrapper(fg)) { fg.AppendLine("get"); using (new BraceWrapper(fg)) { var subTypeDefault = gendered.SubTypeGeneration.GetDefault(getter: true); fg.AppendLine($"if (!_{typeGen.Name}Location.HasValue) return {(typeGen.Nullable ? "default" : $"new GenderedItem<{typeName}>({subTypeDefault}, {subTypeDefault})")};"); fg.AppendLine($"var data = HeaderTranslation.ExtractSubrecordMemory(_data, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)});"); using (var args = new ArgsWrapper(fg, $"return new GenderedItem<{gendered.SubTypeGeneration.TypeName(getter: true, needsCovariance: true)}>")) { args.Add($"{subBin.GenerateForTypicalWrapper(objGen, gendered.SubTypeGeneration, "data", "_package")}"); args.Add($"{subBin.GenerateForTypicalWrapper(objGen, gendered.SubTypeGeneration, $"data.Slice({subLen})", "_package")}"); } } } }
public override async Task GenerateCopyIn( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor readerAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationAccessor) { GenderedType gender = typeGen as GenderedType; var data = typeGen.GetFieldData(); if (!this.Module.TryGetTypeGeneration(gender.SubTypeGeneration.GetType(), out var subTransl)) { throw new ArgumentException("Unsupported type generator: " + gender.SubTypeGeneration); } if (data.RecordType.HasValue) { fg.AppendLine($"{readerAccessor}.Position += {readerAccessor}.{nameof(MutagenBinaryReadStream.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(RecordHeaderConstants.HeaderLength)};"); } else if (data.MarkerType.HasValue && !gender.MarkerPerGender) { fg.AppendLine($"{readerAccessor}.Position += {readerAccessor}.{nameof(MutagenBinaryReadStream.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(RecordHeaderConstants.HeaderLength)} + contentLength; // Skip marker"); } bool notNull = gender.ItemNullable && !gender.SubTypeGeneration.IsNullable; using (var args = new ArgsWrapper(fg, $"{itemAccessor} = {this.Namespace}GenderedItemBinaryTranslation.Parse{(gender.MarkerPerGender ? "MarkerPerItem" : null)}<{gender.SubTypeGeneration.TypeName(getter: false, needsCovariance: true)}>")) { args.AddPassArg($"frame"); if (gender.MaleMarker.HasValue) { args.Add($"maleMarker: {objGen.RecordTypeHeaderName(gender.MaleMarker.Value)}"); args.Add($"femaleMarker: {objGen.RecordTypeHeaderName(gender.FemaleMarker.Value)}"); } if (data.MarkerType.HasValue && gender.MarkerPerGender) { args.Add($"marker: {objGen.RecordTypeHeaderName(data.MarkerType.Value)}"); } var subData = gender.SubTypeGeneration.GetFieldData(); if (subData.RecordType.HasValue && !(gender.SubTypeGeneration is LoquiType)) { args.Add($"contentMarker: {objGen.RecordTypeHeaderName(subData.RecordType.Value)}"); } LoquiType loqui = gender.SubTypeGeneration as LoquiType; if (loqui != null) { if (subData?.RecordTypeConverter != null && subData.RecordTypeConverter.FromConversions.Count > 0) { args.Add($"recordTypeConverter: {objGen.RegistrationName}.{typeGen.Name}Converter"); } } if (gender.FemaleConversions != null) { args.Add($"femaleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}FemaleConverter"); } if (gender.MaleConversions != null) { args.Add($"maleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}MaleConverter"); } bool needsRecordConv = gender.SubTypeGeneration.NeedsRecordConverter(); if (subTransl.AllowDirectParse(objGen, gender.SubTypeGeneration, false)) { if (loqui != null) { args.Add($"transl: {loqui.ObjectTypeName}{loqui.GenericTypes(getter: false)}.TryCreateFromBinary"); } else { args.Add($"transl: {subTransl.GetTranslatorInstance(gender.SubTypeGeneration, getter: false)}.Parse"); if (gender.ItemNullable) { args.Add($"skipMarker: false"); } } } else { args.Add(gen => { gen.AppendLine($"transl: (MutagenFrame r, out {gender.SubTypeGeneration.TypeName(getter: false, needsCovariance: true)} genSubItem{(needsRecordConv ? $", {nameof(RecordTypeConverter)}? conv" : null)}) =>"); using (new BraceWrapper(gen)) { subTransl.GenerateCopyInRet( fg: gen, objGen: objGen, targetGen: gender.SubTypeGeneration, typeGen: gender.SubTypeGeneration, readerAccessor: "r", translationAccessor: null, retAccessor: "return ", outItemAccessor: new Accessor("genSubItem"), asyncMode: AsyncMode.Off, errorMaskAccessor: "listErrMask", converterAccessor: "conv", inline: false); } if (gender.ItemNullable) { args.Add($"skipMarker: false"); } }); } if (notNull) { args.Add($"fallback: {gender.SubTypeGeneration.GetDefault(getter: false)}"); } } }
public override async Task GenerateWrite( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor writerAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationAccessor, Accessor converterAccessor) { GenderedType gendered = typeGen as GenderedType; var gen = this.Module.GetTypeGeneration(gendered.SubTypeGeneration.GetType()); var data = typeGen.GetFieldData(); if (!this.Module.TryGetTypeGeneration(gendered.SubTypeGeneration.GetType(), out var subTransl)) { throw new ArgumentException("Unsupported type generator: " + gendered.SubTypeGeneration); } var allowDirectWrite = subTransl.AllowDirectWrite(objGen, gendered.SubTypeGeneration); bool needsMasters = gendered.SubTypeGeneration is FormLinkType || gendered.SubTypeGeneration is LoquiType; var typeName = gendered.SubTypeGeneration.TypeName(getter: true, needsCovariance: true); var loqui = gendered.SubTypeGeneration as LoquiType; if (loqui != null) { typeName = loqui.TypeNameInternal(getter: true, internalInterface: true); } using (var args = new ArgsWrapper(fg, $"GenderedItemBinaryTranslation.Write{(gendered.MarkerPerGender ? "MarkerPerItem" : null)}")) { args.Add($"writer: {writerAccessor}"); args.Add($"item: {itemAccessor}"); if (data.RecordType.HasValue) { args.Add($"recordType: {objGen.RecordTypeHeaderName(data.RecordType.Value)}"); } else if (data.MarkerType.HasValue) { args.Add($"markerType: {objGen.RecordTypeHeaderName(data.MarkerType.Value)}"); } if (gendered.MaleMarker.HasValue) { args.Add($"maleMarker: {objGen.RecordTypeHeaderName(gendered.MaleMarker.Value)}"); } if (gendered.FemaleMarker.HasValue) { args.Add($"femaleMarker: {objGen.RecordTypeHeaderName(gendered.FemaleMarker.Value)}"); } if (gendered.MaleMarker.HasValue && loqui != null) { args.Add("markerWrap: false"); } if (gendered.FemaleConversions != null) { args.Add($"femaleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}FemaleConverter"); } if (gendered.MaleConversions != null) { args.Add($"maleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}MaleConverter"); } if (allowDirectWrite) { args.Add($"transl: {subTransl.GetTranslatorInstance(gendered.SubTypeGeneration, getter: true)}.Write{(gendered.SubTypeGeneration.Nullable ? "Nullable" : string.Empty)}"); } else { args.Add((gen) => { var listTranslMask = this.MaskModule.GetMaskModule(gendered.SubTypeGeneration.GetType()).GetTranslationMaskTypeStr(gendered.SubTypeGeneration); gen.AppendLine($"transl: (MutagenWriter subWriter, {typeName}{gendered.SubTypeGeneration.NullChar} subItem{(needsMasters ? $", {nameof(RecordTypeConverter)}? conv" : null)}) =>"); using (new BraceWrapper(gen)) { subTransl.GenerateWrite( fg: gen, objGen: objGen, typeGen: gendered.SubTypeGeneration, writerAccessor: "subWriter", translationAccessor: "subTranslMask", itemAccessor: new Accessor($"subItem"), errorMaskAccessor: null, converterAccessor: needsMasters ? "conv" : 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 GenerateWrite( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor writerAccessor, Accessor itemAccessor, Accessor errorMaskAccessor, Accessor translationMaskAccessor, Accessor converterAccessor) { var data = typeGen.CustomData[Constants.DataKey] as MutagenFieldData; if (CustomWrite != null) { if (CustomWrite(fg, objGen, typeGen, writerAccessor, itemAccessor)) { return; } } if (data.HasTrigger || !PreferDirectTranslation) { using (var args = new ArgsWrapper(fg, $"{this.NamespacePrefix}{this.GetTranslatorInstance(typeGen, getter: true)}.Write{(typeGen.Nullable ? "Nullable" : null)}")) { args.Add($"writer: {writerAccessor}"); args.Add($"item: {ItemWriteAccess(typeGen, itemAccessor)}"); if (this.DoErrorMasks) { if (typeGen.HasIndex) { args.Add($"fieldIndex: (int){typeGen.IndexEnumName}"); } args.Add($"errorMask: {errorMaskAccessor}"); } if (data.RecordType.HasValue && data.HandleTrigger) { args.Add($"header: translationParams.ConvertToCustom({objGen.RecordTypeHeaderName(data.RecordType.Value)})"); } foreach (var writeParam in this.AdditionalWriteParams) { var get = writeParam( objGen: objGen, typeGen: typeGen); if (get.Failed) { continue; } args.Add(get.Value); } } } else if (typeGen.GetFieldData().Length > 1) { fg.AppendLine($"{writerAccessor}.Write({itemAccessor}, length: {typeGen.GetFieldData().Length});"); } else { fg.AppendLine($"{writerAccessor}.Write({itemAccessor});"); } }
public override async Task <int?> ExpectedLength(ObjectGeneration objGen, TypeGeneration typeGen) { return(typeGen.GetFieldData().Length ?? this._ExpectedLength); }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType = null) { passedLengthAccessor ??= "0x0"; 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.Nullable ? "?" : 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.Nullable) { 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 if (data.IsAfterBreak) { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {dataAccessor}.Length <= {passedLengthAccessor} ? default : {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor}{(expectedLen != null ? $", 0x{expectedLen.Value:X}" : null)})", "_package")};"); } else { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor}{(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)};"); } } }