internal void EmitFCSToForeign(CodeFormatter cppFile, MemberSpec foreignDestObject) { cppFile.BeginCase(FCSType.Name + "::" + enumValue); cppFile.FormatLine("{0}{2}{1} = true;", foreignDestObject.Name, boolMemberName, foreignDestObject.Type.GetDereferencingOperator()); cppFile.EndCase(); }
internal void EmitForeignToFCS(CodeFormatter cppFile, MemberSpec foreignSourceObject, MemberSpec fcsDestObject, string fcsMemberName) { cppFile.FormatLine("if ({1}{2}{0})", boolMemberName, foreignSourceObject.Name, foreignSourceObject.Type.GetDereferencingOperator() ); cppFile.WriteLine("{"); cppFile.FormatLine("{0}{1}{2} = {3}::{4};", fcsDestObject.Name, fcsDestObject.Type.GetDereferencingOperator(), fcsMemberName, FCSType.Name, enumValue); cppFile.WriteLine("}"); }
private void AddForeignToFCSConvert(CodeFormatter cppFile) { MemberSpec dest = new MemberSpec(FCSType, "destination"); MemberSpec source = new MemberSpec(ForeignType, "source"); BeginMethod(cppFile, dest.Type, "Convert", source); OutputSwitch(cppFile, ForeignValues, FCSValues, FCSDefault, ForeignTypePrefix(), FCSType.Name+"::"); cppFile.WriteLine("}"); }
public override void EmitForeignToFCS(CodeFormatter cppFile, MemberSpec fcsDestObject, MemberSpec foreignSourceObject) { foreach (EnumToBoolMapping etbm in mappings) { etbm.EmitForeignToFCS(cppFile, foreignSourceObject, fcsDestObject, FCSSpec.Name); } }
public EnumToMultiMemberMapping(XmlElement element, TypeSpec parentFCSType, TypeSpec parentForeignType) { if (element.GetAttribute("FCSMember").Length > 0) FCSSpec = new MemberSpec(element.GetAttribute("FCSMember"), TypeSpec.TypeSpecCategories.FCSType); else FCSSpec = new MemberSpec(parentFCSType, ""); foreach (XmlNode subNode in element.SelectNodes(".//x:ValueToForeignBoolMember", GenerationContext.NamespaceManager)) { mappings.Add(new EnumToBoolMapping(subNode as XmlElement, FCSSpec.Type)); } }
public override void EmitFCSToForeign(CodeFormatter cppFile, MemberSpec foreignDestObject, MemberSpec fcsSourceObject) { foreach (EnumToBoolMapping etbm in mappings) { etbm.EmitSetToFalse(cppFile, foreignDestObject); } cppFile.FormatLine("switch ({1}{2}{0})", FCSSpec.Name, fcsSourceObject.Name, fcsSourceObject.Type.GetDereferencingOperator()); cppFile.WriteLine("{"); foreach (EnumToBoolMapping etbm in mappings) { etbm.EmitFCSToForeign(cppFile, foreignDestObject); } cppFile.WriteLine("}"); }
public MemberMapping(XmlElement element, TypeSpec parentFCSType, TypeSpec parentForeignType) { if (element.GetAttribute("FCSMember").Length > 0) FCSSpec = new MemberSpec(element.GetAttribute("FCSMember"), TypeSpec.TypeSpecCategories.FCSType); else FCSSpec = new MemberSpec(parentFCSType, ""); if (element.GetAttribute("ForeignMember").Length > 0) ForeignSpec = new MemberSpec(element.GetAttribute("ForeignMember"), TypeSpec.TypeSpecCategories.ForeignType); else ForeignSpec = new MemberSpec(parentForeignType, ""); Invert = XmlUtils.GetOptionalAttribute(element, "Invert") == "yes"; MissingValue = XmlUtils.GetOptionalAttribute(element, "MissingValue"); StringConvert = XmlUtils.GetOptionalAttribute(element, "StringConvert") == "yes"; Converter = XmlUtils.GetOptionalAttribute(element, "Converter"); UseManagedConstructor = XmlUtils.GetOptionalAttribute(element, "UseManagedConstructor") == "yes"; Collection = XmlUtils.GetOptionalAttribute(element, "Collection") == "yes"; ForeignScaling = 1; string scale = XmlUtils.GetOptionalAttribute(element, "ForeignScaleFactor"); if (!string.IsNullOrEmpty(scale)) ForeignScaling = int.Parse(scale); }
private void EmitSimpleConvertToString(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string source = BuildBit(sourceObject, sourceMember); string dest = BuildBit(destObject, destMember); switch (sourceMember.Type.Name) { case "String": m_currentFile.FormatLine("{0} = {1};", dest, source); return; case "CWideString": m_currentFile.FormatLine("{0} = gcnew String({1}.GetData());", dest, source); return; case "RTFPCData": m_currentFile.FormatLine("{0} = gcnew String({1}{2}GetContent().GetData());", dest, source, sourceMember.Type.GetDereferencingOperator()); return; case "int": m_currentFile.FormatLine("{0} = {1}.ToString();", dest, source); return; default: throw new InvalidOperationException("No explicit handling of that string type conversion"); } }
private void EmitSimpleConvertFromString(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string source = BuildBit(sourceObject, sourceMember); string dest = BuildBit(destObject, destMember); if (sourceMember.Type.Name == "int") source = source + ".ToString()"; switch (destMember.Type.Name) { case "String": m_currentFile.FormatLine("{0} = {1};", dest, source); return; case "CWideString": m_currentFile.WriteLine("{"); m_currentFile.FormatLine("pin_ptr<const wchar_t> pStr = PtrToStringChars({0});", source); m_currentFile.FormatLine("{0} = pStr;", dest); m_currentFile.WriteLine("}"); return; case "CQuickBuildString": m_currentFile.WriteLine("{"); m_currentFile.FormatLine("pin_ptr<const wchar_t> pStr = PtrToStringChars({0});", source); m_currentFile.FormatLine("{0} = CStdStringA(pStr);", dest); m_currentFile.WriteLine("}"); return; case "int": if (sourceMember.Type.Name != "String") { m_currentFile.WriteLine("{"); source += sourceMember.Type.GetDereferencingOperator(); source += sourceMember.Type.Name == "RTFPCData" ? "GetContent().GetData()" : "GetData()"; m_currentFile.FormatLine("String^ tempStr = gcnew System::String({0});", source); m_currentFile.FormatLine("{0} = Int32::Parse(tempStr);", dest); m_currentFile.WriteLine("}"); } else { m_currentFile.FormatLine("{0} = Int32::Parse({1});", dest, source); } return; // Need to revisit if we have more than 1 of these in the converter because of the explicit cwsNeedRef variable case "RTFPCData": m_currentFile.FormatLine("if ({0} != nullptr)", source); m_currentFile.WriteLine("{"); m_currentFile.FormatLine("pin_ptr<const wchar_t> pStr = PtrToStringChars({0});", source); //"CWideString cwsNeedRef =(const wchar_t*)(Runtime::InteropServices::Marshal::StringToHGlobalUni({0})).ToPointer();", //source); if (destMember.Type.GetDereferencingOperator() == "->") { m_currentFile.FormatLine("if ({0} == NULL)", dest); m_currentFile.WriteLine("{"); m_currentFile.FormatLine("{0} = new RTFPCData();", dest); m_currentFile.WriteLine("}"); } m_currentFile.FormatLine("{0}{1}SetContent(pStr);", dest, destMember.Type.GetDereferencingOperator()); m_currentFile.WriteLine("}"); return; default: throw new InvalidOperationException("No explicit handling of that string type conversion"); } }
private void EmitBuildFromThis(BaseClassMapping converter, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string dest = BuildBit(destObject, destMember); switch (destMember.Type.Modifier) { case TypeSpec.Modifiers.managedReference: m_currentFile.FormatLine("_ASSERT({0} == nullptr);", dest); m_currentFile.FormatLine("{0} = {2}::Construct({1});", dest, sourceObject.Name, converter); break; case TypeSpec.Modifiers.pointer: m_currentFile.FormatLine("_ASSERT({0} == NULL);", dest); m_currentFile.FormatLine("{0} = {2}::Construct({1}, destination->GetFileContext());", dest, sourceObject.Name, converter); break; case TypeSpec.Modifiers.reference: throw new NotImplementedException(); case TypeSpec.Modifiers.value: m_currentFile.FormatLine("{2}::Populate({0}, {1});", dest, sourceObject.Name, converter); break; } }
private void EmitPopulateThis(BaseClassMapping converter, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string source = BuildBit(sourceObject, sourceMember); m_currentFile.FormatLine("{0}::Populate({1}, {2});", converter, destObject.Name, source); }
private void EmitComplexConvert(BaseClassMapping converter, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string source = BuildBit(sourceObject, sourceMember); if (converter.ForeignType != null && sourceMember.Type.Name == converter.ForeignType.Name) { if ((sourceMember.Type.Modifier == TypeSpec.Modifiers.value) && (converter.ForeignType.Modifier == TypeSpec.Modifiers.pointer)) source = "&" + source; } string dest = BuildBit(destObject, destMember); if (converter.ForeignType != null && destMember.Type.Name == converter.ForeignType.Name) { if ((destMember.Type.Modifier == TypeSpec.Modifiers.value) && (converter.ForeignType.Modifier == TypeSpec.Modifiers.pointer)) dest = "&" + dest; } if (converter is EnumerationMapping || converter is ManualMapping) { m_currentFile.FormatLine("{0} = {2}::Convert({1});", dest, source, converter); return; } switch (destMember.Type.Modifier) { case TypeSpec.Modifiers.managedReference: m_currentFile.FormatLine("_ASSERT({0} == nullptr);", dest); m_currentFile.FormatLine("{0} = {2}::Construct({1});", dest, source, converter); break; case TypeSpec.Modifiers.pointer: m_currentFile.FormatLine("_ASSERT({0} == NULL);", dest); m_currentFile.FormatLine("{0} = {2}::Construct({1},destination->GetFileContext());", dest, source, converter); break; case TypeSpec.Modifiers.reference: throw new NotImplementedException(); case TypeSpec.Modifiers.value: m_currentFile.FormatLine("{2}::Populate({0}, {1});", dest, source, converter); break; } }
internal void EmitSetToFalse(CodeFormatter cppFile, MemberSpec foreignDestObject) { cppFile.FormatLine("{0}{2}{1} = false;", foreignDestObject.Name, boolMemberName, foreignDestObject.Type.GetDereferencingOperator()); }
private void AddForeignToFCSPopulate(CodeFormatter cppFile) { MemberSpec dest = new MemberSpec(FCSType, "destination"); MemberSpec source = new MemberSpec(ForeignType, "source"); BeginMethod(cppFile, TypeSpec.Void, "Populate", dest, source); if (ForeignType.Modifier == TypeSpec.Modifiers.pointer) { cppFile.WriteLine("if (source == NULL)"); cppFile.IncreaseIndent(); cppFile.WriteLine("return;"); cppFile.DecreaseIndent(); } foreach (MemberMapping mm in MemberMappings) { mm.EmitForeignToFCS(cppFile, dest, source); } cppFile.WriteLine("}"); }
private void AddFCSToForeignPopulate(CodeFormatter cppFile) { MemberSpec dest = new MemberSpec(ForeignType, "destination"); MemberSpec source = new MemberSpec(FCSType, "source"); BeginMethod(cppFile, TypeSpec.Void, "Populate", dest, source); foreach (MemberMapping mm in MemberMappings) { mm.EmitFCSToForeign(cppFile, dest, source); } cppFile.WriteLine("}"); }
private void EmitSimpleConvert(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { if ((destMember.Type.Modifier == TypeSpec.Modifiers.optional) ^ (sourceMember.Type.Modifier == TypeSpec.Modifiers.optional)) throw new InvalidOperationException("Not supporting optional <-> non-optional mappings (yet)"); if (sourceMember.Type.Name == "String" || StringConvert) { if (ForeignScaling != 1) throw new NotSupportedException("can't do scaling on string converts"); EmitSimpleConvertFromString(destObject, destMember, sourceObject, sourceMember); return; } if (destMember.Type.Name == "String" || StringConvert) { if (ForeignScaling != 1) throw new NotSupportedException("can't do scaling on string converts"); EmitSimpleConvertToString(destObject, destMember, sourceObject, sourceMember); return; } if (destMember.Type.Modifier == TypeSpec.Modifiers.optional) { EmitOptionalValueConvert(destObject, destMember, sourceObject, sourceMember); } else { if (Invert && (destMember.Type.Name != "bool" || sourceMember.Type.Name != "bool")) throw new NotSupportedException("Can't do inverts on non-boolean types"); if (ForeignScaling != 1 && !destMember.Type.Name.Contains("int")) throw new NotSupportedException("can't do scaling on non integer"); if (ForeignScaling != 1) { if (destObject.Type.Modifier == TypeSpec.Modifiers.managedReference) { FormatNoConverterAssign("{0} = {3}{1}/" + ForeignScaling.ToString() + ";", destObject, destMember, sourceObject, sourceMember); } else if (sourceObject.Type.Modifier == TypeSpec.Modifiers.managedReference) { FormatNoConverterAssign("{0} = {3}{1}*" + ForeignScaling.ToString() + ";", destObject, destMember, sourceObject, sourceMember); } else throw new Exception("Can't work out which is the managed side when applying scale factor"); } else { FormatNoConverterAssign("{0} = {3}{1};", destObject, destMember, sourceObject, sourceMember); } } }
private void FormatNoConverterAssign(string format, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { m_currentFile.FormatLine(format, BuildBit(destObject, destMember), BuildBit(sourceObject, sourceMember), destMember.Type.Name, Invert ? "!" : "", string.IsNullOrEmpty(MissingValue) ? "-1" : MissingValue); }
private void FormatIfConverterAssign(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { m_currentFile.FormatLine("if(!{0}.IsDefault())\n", BuildBit(sourceObject, sourceMember)); m_currentFile.IncreaseIndent(); m_currentFile.FormatLine("{0} = {1};", BuildBit(destObject, destMember), BuildBit(sourceObject, sourceMember)); m_currentFile.DecreaseIndent(); }
private static string BuildBit(MemberSpec theObject, MemberSpec theMember) { StringBuilder bld = new StringBuilder(); bld.AppendFormat("{0}{1}{2}", theObject.Name, theObject.Type.GetDereferencingOperator(), theMember.Name); return bld.ToString(); }
public virtual void EmitFCSToForeign(CodeFormatter cppFile, MemberSpec foreignDestObject, MemberSpec fcsSourceObject) { BaseClassMapping converter = GetConverter(); m_currentFile = cppFile; EmitConversion(converter, foreignDestObject, ForeignSpec, fcsSourceObject, FCSSpec); }
private void EmitOptionalBoolSignedCharValueConvert(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { if (!(destMember.Type.Name == "bool" && sourceMember.Type.Name == "signed char") && !(destMember.Type.Name == "signed char" && sourceMember.Type.Name == "bool")) { throw new NotImplementedException("no idea how to cope with bool <-> non-signed char"); } string source = BuildBit(sourceObject, sourceMember); string dest = BuildBit(destObject, destMember); if (destMember.Type.Category == TypeSpec.TypeSpecCategories.ForeignType) { FormatNoConverterAssign("{0} = {1}.IsDefault() ? -1 : ({3}{1} ? 1 : 0);", destObject, destMember, sourceObject, sourceMember); } else { FormatNoConverterAssign("{0} = OptionalValue<{2}>({3}({1} == 1), {1} == -1);", destObject, destMember, sourceObject, sourceMember); } }
private void EmitConversion(BaseClassMapping converter, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { if (converter == null) { EmitSimpleConvert(destObject, destMember, sourceObject, sourceMember); } else { if (ForeignScaling != 1) throw new NotSupportedException("can't do scaling on complex converts"); if (Invert) throw new NotSupportedException("Can't do complex converts and invert them"); if (string.IsNullOrEmpty(destMember.Name)) { EmitPopulateThis(converter, destObject, destMember, sourceObject, sourceMember); } else if (string.IsNullOrEmpty(sourceMember.Name)) { EmitBuildFromThis(converter, destObject, destMember, sourceObject, sourceMember); } else if (Collection) { if (destMember.Type.Modifier == TypeSpec.Modifiers.pointer) { m_currentFile.FormatLine("for (int i=0; i<{0}->Count; i++)", BuildBit(sourceObject, sourceMember)); } else { m_currentFile.FormatLine("for (unsigned int i=0; i<{0}.size(); i++)", BuildBit(sourceObject, sourceMember)); } m_currentFile.WriteLine("{"); EmitListComplexConvert(converter, destObject, destMember, sourceObject, sourceMember); m_currentFile.WriteLine("}"); } else { EmitComplexConvert(converter, destObject, destMember, sourceObject, sourceMember); } } }
private void EmitListComplexConvert(BaseClassMapping converter, MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { string source = BuildBit(sourceObject, sourceMember); string dest = BuildBit(destObject, destMember); if (converter is EnumerationMapping || converter is ManualMapping) { throw new Exception("not handled yet"); } switch (destMember.Type.Modifier) { case TypeSpec.Modifiers.managedReference: m_currentFile.FormatLine("{0}->Add({2}::Construct({1}[i]));", dest, source, converter); break; case TypeSpec.Modifiers.pointer: m_currentFile.FormatLine("{0}.push_back({2}::Construct({1}[i], destination->GetFileContext()));", dest, source, converter); break; case TypeSpec.Modifiers.reference: throw new NotImplementedException(); case TypeSpec.Modifiers.value: throw new NotImplementedException(); } }
private void EmitOptionalValueConvert(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { if (destMember.Type.Name == "bool" && sourceMember.Type.Name == "bool") { EmitOptionalBoolValueConvert(destObject, destMember, sourceObject, sourceMember); return; } else if ((destMember.Type.Name == "bool" && sourceMember.Type.Name == "signed char") || (destMember.Type.Name == "signed char" && sourceMember.Type.Name == "bool")) { EmitOptionalBoolSignedCharValueConvert(destObject, destMember, sourceObject, sourceMember); return; } if (Invert) throw new NotSupportedException("Can't do inverts on non-boolean types"); if (ForeignScaling != 1) { if (!destMember.Type.Name.Contains("int")) throw new NotSupportedException("can't do scaling on non integer"); if (destMember.Type.Category == TypeSpec.TypeSpecCategories.FCSType) { FormatNoConverterAssign("{0} = OptionalValue<{2}>({1} / " + ForeignScaling.ToString() + ", {1} == {4});", destObject, destMember, sourceObject, sourceMember); } else { FormatNoConverterAssign("{0} = {1}.IsDefault() ? {4} : {1} * " + ForeignScaling.ToString() + ";", destObject, destMember, sourceObject, sourceMember); } } else { if (destMember.Type.Category == TypeSpec.TypeSpecCategories.ForeignType) { FormatNoConverterAssign("{0} = {1}.IsDefault() ? {4} : {1};", destObject, destMember, sourceObject, sourceMember); } else { FormatNoConverterAssign("{0} = OptionalValue<{2}>({1}, {1} == {4});", destObject, destMember, sourceObject, sourceMember); } } }
private void AddFCSToForeignConstruct(CodeFormatter cppFile) { MemberSpec source = new MemberSpec(FCSType, "source"); MemberSpec context = new MemberSpec(new TypeSpec("RTFFileContext", TypeSpec.TypeSpecCategories.ForeignType) { Modifier = TypeSpec.Modifiers.pointer }, "pContext"); BeginMethod(cppFile, ForeignType, "Construct", source, context); if (ForeignType.Modifier == TypeSpec.Modifiers.pointer && FCSType.Modifier == TypeSpec.Modifiers.managedReference) { cppFile.WriteLine("if (source == nullptr)"); cppFile.IncreaseIndent(); cppFile.WriteLine("return NULL;"); cppFile.DecreaseIndent(); } ConstructResult(cppFile, ForeignType); cppFile.FormatLine("Populate(result, source);"); cppFile.WriteLine("return result;"); cppFile.WriteLine("}"); }
private void EmitOptionalBoolValueConvert(MemberSpec destObject, MemberSpec destMember, MemberSpec sourceObject, MemberSpec sourceMember) { if (destMember.Type.Name != "bool" && sourceMember.Type.Name != "bool") { throw new NotImplementedException("no idea how to cope with bool <-> non-bool"); } string source = BuildBit(sourceObject, sourceMember); string dest = BuildBit(destObject, destMember); if (destMember.Type.Category == TypeSpec.TypeSpecCategories.ForeignType) { // FormatNoConverterAssign("if(!{1}.IsDefault())\n\t\\t{0} = {1};", destObject, destMember, sourceObject, sourceMember); FormatIfConverterAssign(destObject, destMember, sourceObject, sourceMember); } else { FormatNoConverterAssign("{0} = OptionalValue<{2}>({3}{1});", destObject, destMember, sourceObject, sourceMember); } }
private void AddForeignToFCSConstruct(CodeFormatter cppFile) { MemberSpec source = new MemberSpec(ForeignType, "source"); BeginMethod(cppFile, FCSType, "Construct", source); if (ForeignType.Modifier == TypeSpec.Modifiers.pointer && FCSType.Modifier == TypeSpec.Modifiers.managedReference) { cppFile.WriteLine("if (source == NULL)"); cppFile.IncreaseIndent(); cppFile.WriteLine("return nullptr;"); cppFile.DecreaseIndent(); } if (UseManagedCtor) { ConstructResultWithParams(cppFile, FCSType); } else { ConstructResult(cppFile, FCSType); cppFile.FormatLine("Populate(result, source);"); } cppFile.WriteLine("return result;"); cppFile.WriteLine("}"); }