public NamedObjectDefinition(PdlFile pdlFile, String name, String nameLowerInvariant, NamedObjectDefinition objectDefinedIn) : base(pdlFile) { this.name = name; this.nameLowerInvariant = nameLowerInvariant; this.globalReferenceNameLowerInvariant = (objectDefinedIn == null) ? nameLowerInvariant : (objectDefinedIn.globalReferenceNameLowerInvariant + "." + nameLowerInvariant); this.objectDefinedIn = objectDefinedIn; //this.fields = new List<ObjectDefinitionField>(); //this.firstOptionalFieldIndex = -1; //this.calculatedFixedSerializationLength = false; // // Add definition to pdl file and parent object // pdlFile.AddObjectDefinition(this); if (objectDefinedIn != null) { objectDefinedIn.AddObjectDefinition(this); } }
public ObjectDefinition(PdlFile pdlFile /*, NamedObjectDefinition objectDefinedIn*/) { //this.objectDefinedIn = objectDefinedIn; this.fields = new List <ObjectDefinitionField>(); this.calculatedFixedSerializationLength = false; }
public static PdlFile ParsePdlFile(LfdReader reader) { PdlFile pdlFile = new PdlFile(); ParsePdlFile(pdlFile, reader); return(pdlFile); }
static SwitchTypeReference ParseSwitch(PdlFile pdlFile, LfdReader reader, LfdLine switchLine, NamedObjectDefinition containingNamedObject, out LfdLine nextLine) { List <Case> cases = new List <Case>(); String switchFieldString = switchLine.fields[0]; Debug("Entering Switch Definition '{0}'", switchFieldString); nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == switchLine) { Boolean isCase = nextLine.id.Equals("case", StringComparison.OrdinalIgnoreCase); if (!isCase && !nextLine.id.Equals("default", StringComparison.OrdinalIgnoreCase)) { throw new FormatException(String.Format("Expected 'Case' or 'Default' but got '{0}'", nextLine)); } VerifyFieldCount(nextLine, isCase ? 1 : 0); LfdLine currentCaseLine = nextLine; String currentCaseValueString = isCase ? nextLine.fields[0] : null; ObjectDefinition currentCaseObjectDefinition = new ObjectDefinition(pdlFile); nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == currentCaseLine) { ParseObjectFieldLine(pdlFile, reader, containingNamedObject, currentCaseObjectDefinition, nextLine, out nextLine); } currentCaseObjectDefinition.CalculateFixedSerializationLength(); cases.Add(new Case(currentCaseValueString, currentCaseObjectDefinition)); } return(new SwitchTypeReference(switchFieldString, cases)); }
static IfTypeReference ParseIf(PdlFile pdlFile, LfdReader reader, LfdLine ifLine, NamedObjectDefinition containingNamedObject, out LfdLine nextLine) { Case trueCase, falseCase = null; String conditionString = ifLine.fields[0]; Debug("Entering If Definition '{0}'", conditionString); ObjectDefinition trueCaseObjectDefinition = new ObjectDefinition(pdlFile); nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == ifLine) { ParseObjectFieldLine(pdlFile, reader, containingNamedObject, trueCaseObjectDefinition, nextLine, out nextLine); } trueCaseObjectDefinition.CalculateFixedSerializationLength(); trueCase = new Case(conditionString, trueCaseObjectDefinition); if (nextLine != null && nextLine.id.Equals("else", StringComparison.OrdinalIgnoreCase)) { LfdLine falseCaseLine = nextLine; ObjectDefinition falseCaseObjectDefinition = new ObjectDefinition(pdlFile); nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == falseCaseLine) { ParseObjectFieldLine(pdlFile, reader, containingNamedObject, falseCaseObjectDefinition, nextLine, out nextLine); } falseCaseObjectDefinition.CalculateFixedSerializationLength(); falseCase = new Case(conditionString, falseCaseObjectDefinition); } return(new IfTypeReference(conditionString, trueCase, falseCase)); }
static NamedObjectDefinition ParseObjectDefinition(PdlFile pdlFile, LfdReader reader, LfdLine objectDefinitionLine, NamedObjectDefinition currentObjectDefinition, String objectDefinitionName, out LfdLine nextLine) { NamedObjectDefinition objectDefinition = new NamedObjectDefinition(pdlFile, objectDefinitionName, objectDefinitionName.ToLowerInvariant(), currentObjectDefinition); Debug("Entering Object Definition '{0}'", objectDefinition.name); nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == objectDefinitionLine) { ParseObjectFieldLine(pdlFile, reader, objectDefinition, objectDefinition, nextLine, out nextLine); } objectDefinition.CalculateFixedSerializationLength(); return(objectDefinition); }
static void ParseEnumOrFlagsDefinition(PdlFile pdlFile, LfdReader reader, NamedObjectDefinition currentObjectDefinition, LfdLine enumDefinitionLine, out LfdLine nextLine, Boolean isFlagsDefinition) { String enumOrFlagsString = isFlagsDefinition ? "Flags" : "Enum"; VerifyFieldCount(enumDefinitionLine, 2); String underlyingIntegerTypeString = enumDefinitionLine.fields[0]; PdlType underlyingIntegerType = PdlTypeExtensions.ParseIntegerType(underlyingIntegerTypeString); EnumOrFlagsDefinition definition; try { definition = new EnumOrFlagsDefinition(pdlFile, isFlagsDefinition, currentObjectDefinition, underlyingIntegerType, enumDefinitionLine.fields[1]); } catch (FormatException e) { throw new ParseException(enumDefinitionLine, e.Message); } Debug(" Entering {0} '{1}' (IntegerType={2})", enumOrFlagsString, enumDefinitionLine.id, definition.underlyingIntegerType); // // Read enum values // nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null && nextLine.parent == enumDefinitionLine) { LfdLine enumValueLine = nextLine; VerifyFieldCount(enumValueLine, 1); Debug(" {0} {1} {2}", enumOrFlagsString, enumValueLine.id, enumValueLine.fields[0]); if (isFlagsDefinition) { definition.Add(new FlagsValueDefinition(enumValueLine.fields[0], Byte.Parse(enumValueLine.id))); } else { definition.Add(new EnumValueDefinition(enumValueLine.id, enumValueLine.fields[0])); } nextLine = reader.ReadLineIgnoreComments(); } Debug(" Exiting {0} '{1}'", enumOrFlagsString, definition.typeName); }
public static void ParsePdlFile(PdlFile pdlFile, LfdReader reader) { LfdLine nextLine = reader.ReadLineIgnoreComments(); while (nextLine != null) { if (nextLine.id.Equals("enum", StringComparison.OrdinalIgnoreCase)) { ParseEnumOrFlagsDefinition(pdlFile, reader, null, nextLine, out nextLine, false); } else if (nextLine.id.Equals("flags", StringComparison.OrdinalIgnoreCase)) { ParseEnumOrFlagsDefinition(pdlFile, reader, null, nextLine, out nextLine, true); } else { LfdLine currentCommandLine = nextLine; VerifyFieldCount(currentCommandLine, 0); NamedObjectDefinition objectDefinition = ParseObjectDefinition(pdlFile, reader, currentCommandLine, null, currentCommandLine.id, out nextLine); } } }
public EnumOrFlagsDefinition(PdlFile pdlFile, Boolean isFlagsDefinition, NamedObjectDefinition objectDefinedIn, PdlType underlyingIntegerType, String typeName) { this.isFlagsDefinition = isFlagsDefinition; this.isGlobalType = (objectDefinedIn == null); this.underlyingIntegerType = underlyingIntegerType; this.byteCount = underlyingIntegerType.IntegerTypeByteCount(); this.typeName = typeName; this.typeNameLowerInvariantCase = typeName.ToLowerInvariant(); this.globalReferenceNameLowerInvariant = (objectDefinedIn == null) ? typeNameLowerInvariantCase : (objectDefinedIn.globalReferenceNameLowerInvariant + "." + typeNameLowerInvariantCase); // // Add the definition to the static flags or enum definitions list // if (isFlagsDefinition) { enumValues = null; flagValues = new List <FlagsValueDefinition>(); } else { enumValues = new List <EnumValueDefinition>(); flagValues = null; } // // Add the defintion to the object and the pdl file // if (objectDefinedIn != null) { objectDefinedIn.AddEnumOrFlagDefinition(this); } pdlFile.AddEnumOrFlagsDefinition(this); }
public Boolean Execute() { // // Check Options // if (buildEngine == null) { throw new ArgumentNullException("BuildEngine"); } if (inputFiles == null || inputFiles.Length <= 0) { LogError("Missing InputFiles"); return(TaskFailed); } if (String.IsNullOrEmpty(outputFile)) { LogError("Missing OutputFile"); return(TaskFailed); } if (String.IsNullOrEmpty(@namespace)) { LogError("Missing Namespace"); return(TaskFailed); } // // Check that input files exist // Int32 missingInputFileCount = 0; for (int i = 0; i < inputFiles.Length; i++) { String inputFile = inputFiles[i]; if (!File.Exists(inputFiles[i])) { missingInputFileCount++; LogError("Missing InputFile '{0}'", inputFile); } } if (missingInputFileCount > 0) { LogError("{0} of the input files {1} missing", missingInputFileCount, (missingInputFileCount == 1) ? "is" : "are"); return(TaskFailed); } // // Load the input files // InputFileObject[] inputFileObjects = new InputFileObject[inputFiles.Length]; Byte[] fileBuffer = new Byte[1024]; Sha1Builder inputShaBuilder = new Sha1Builder(); StringBuilder builder = new StringBuilder(); for (int i = 0; i < inputFileObjects.Length; i++) { inputFileObjects[i] = new InputFileObject(inputFiles[i], fileBuffer, builder, inputShaBuilder, Encoding.UTF8); } Sha1 inputHash = inputShaBuilder.Finish(false); String inputHashString = inputHash.ToString(); if (forceCodeGeneration) { Log(MessageImportance.High, "Skipping the InputHash check because ForceCodeGeneration is set to true"); } else { // // Try to get the saved hash from output file // Sha1 savedInputHash; String savedInputHashString = TryGetSavedInputHash(outputFile, out savedInputHash); if (savedInputHashString != null) { if (inputHash.Equals(savedInputHash)) { Log(MessageImportance.Normal, "Input hash matches saved input hash, no code generation done"); return(TaskSucceeded); } } } // // Parse Pdl Files // PdlFile pdlFile = new PdlFile(); for (int i = 0; i < inputFileObjects.Length; i++) { InputFileObject inputFileObject = inputFileObjects[i]; PdlFileParser.ParsePdlFile(pdlFile, new LfdReader(new StringReader(inputFileObject.contents))); } // // Generate the code // StringBuilder outputStringBuilder = new StringBuilder(); using (StringWriter outputStringWriter = new StringWriter(outputStringBuilder)) { // Save the hash first outputStringWriter.WriteLine("// {0}{1}", PdlFile.InputShaPrefix, inputHashString); PdlCodeGenerator.GenerateCode(outputStringWriter, pdlFile, @namespace, generateStructs); } String outputContents = outputStringBuilder.ToString(); FileExtensions.SaveStringToFile(outputFile, FileMode.Create, outputContents); return(TaskSucceeded); }
public static void ParseObjectFieldLine(PdlFile pdlFile, LfdReader reader, NamedObjectDefinition containingNamedObject, IFieldContainer containingObject, LfdLine fieldLine, out LfdLine nextLine) { // // Check if it is only a definition (enum or flag) // if (fieldLine.id.Equals("enum", StringComparison.OrdinalIgnoreCase)) { ParseEnumOrFlagsDefinition(pdlFile, reader, containingNamedObject, fieldLine, out nextLine, false); return; } if (fieldLine.id.Equals("flags", StringComparison.OrdinalIgnoreCase)) { ParseEnumOrFlagsDefinition(pdlFile, reader, containingNamedObject, fieldLine, out nextLine, true); return; } String typeString = fieldLine.id; // // The rest of the fields can have arrayParse the Array Size Type // PdlArrayType arrayType; int indexOfOpenBracket = typeString.IndexOf('['); if (indexOfOpenBracket < 0) { arrayType = null; } else { String arraySizeTypeString = typeString.Substring(indexOfOpenBracket + 1); typeString = typeString.Remove(indexOfOpenBracket); int indexOfCloseBracket = arraySizeTypeString.IndexOf(']'); if (indexOfCloseBracket < 0) { throw new ParseException(fieldLine, "Found an opening bracket '[' without a closing bracket"); } if (indexOfCloseBracket != arraySizeTypeString.Length - 1) { throw new ParseException(fieldLine, "The array size type '{0}' had a closing bracket, but the closing bracket was not the last character", arraySizeTypeString); } arraySizeTypeString = arraySizeTypeString.Remove(indexOfCloseBracket); arrayType = PdlArrayType.Parse(fieldLine, arraySizeTypeString); } // // Parse object inline definition // if (typeString.Equals("object", StringComparison.OrdinalIgnoreCase)) { VerifyFieldCount(fieldLine, 1); String objectDefinitionAndFieldName = fieldLine.fields[0]; NamedObjectDefinition fieldObjectDefinition = ParseObjectDefinition(pdlFile, reader, fieldLine, containingNamedObject, objectDefinitionAndFieldName, out nextLine); containingObject.AddField(new ObjectDefinitionField( new ObjectTypeReference(objectDefinitionAndFieldName, fieldObjectDefinition, arrayType), objectDefinitionAndFieldName)); return; } // // Check if it is a serializer // if (fieldLine.id.Equals("serializer", StringComparison.OrdinalIgnoreCase)) { VerifyFieldCount(fieldLine, 2); String serializerLengthTypeString = fieldLine.fields[0]; String serializerFieldName = fieldLine.fields[1]; PdlArrayType serializerLengthType = PdlArrayType.Parse(fieldLine, serializerLengthTypeString); containingObject.AddField(new ObjectDefinitionField(new SerializerTypeReference(serializerLengthType, arrayType), serializerFieldName)); nextLine = reader.ReadLineIgnoreComments(); return; } // // Check if it is an 'if' type // if (typeString.Equals("if", StringComparison.OrdinalIgnoreCase)) { VerifyFieldCount(fieldLine, 1); IfTypeReference ifType = ParseIf(pdlFile, reader, fieldLine, containingNamedObject, out nextLine); containingObject.AddField(new ObjectDefinitionField(ifType, null)); return; } // // Check if it is a switch type // if (typeString.Equals("switch", StringComparison.OrdinalIgnoreCase)) { VerifyFieldCount(fieldLine, 1); SwitchTypeReference switchType = ParseSwitch(pdlFile, reader, fieldLine, containingNamedObject, out nextLine); containingObject.AddField(new ObjectDefinitionField(switchType, null)); return; } // // The field is only one line, so read the next line now for the caller // nextLine = reader.ReadLineIgnoreComments(); EnumOrFlagsDefinition enumDefinition = pdlFile.TryGetEnumOrFlagsDefinition(containingNamedObject, typeString); if (enumDefinition != null) { VerifyFieldCount(fieldLine, 1); containingObject.AddField(new ObjectDefinitionField(new EnumOrFlagsTypeReference(typeString, enumDefinition, arrayType), fieldLine.fields[0])); return; } // Check if it is an object type NamedObjectDefinition objectDefinition = pdlFile.TryGetObjectDefinition(containingNamedObject, typeString); if (objectDefinition != null) { if (fieldLine.fields == null || fieldLine.fields.Length <= 0) { // // Add each field from the object definition to the current object definition // List <ObjectDefinitionField> objectDefinitionFields = objectDefinition.Fields; for (int i = 0; i < objectDefinitionFields.Count; i++) { ObjectDefinitionField fieldDefinition = objectDefinitionFields[i]; containingObject.AddField(fieldDefinition); } } else if (fieldLine.fields.Length == 1) { containingObject.AddField(new ObjectDefinitionField( new ObjectTypeReference(typeString, objectDefinition, arrayType), fieldLine.fields[0])); } else { throw new ParseException(fieldLine, "Expected line to have 0 or 1 fields but had {0}", fieldLine.fields.Length); } return; } // // Check if it a string type // if (typeString.Equals("ascii", StringComparison.OrdinalIgnoreCase)) { VerifyFieldCount(fieldLine, 1); containingObject.AddField(new ObjectDefinitionField( new AsciiTypeReference(typeString, arrayType), fieldLine.fields[0])); return; } // // It must be an integer type // VerifyFieldCount(fieldLine, 1); PdlType type; try { type = (PdlType)Enum.Parse(typeof(PdlType), typeString, true); } catch (ArgumentException) { throw new FormatException(String.Format("Unknown Pdl Type '{0}'", typeString)); } if (!type.IsIntegerType()) { throw new InvalidOperationException(String.Format("Unhandled PDL type '{0}'", type)); } containingObject.AddField(new ObjectDefinitionField(new IntegerTypeReference(type, arrayType), fieldLine.fields[0])); }
public static void GenerateCode(TextWriter writer, PdlFile pdlFile, String @namespace, Boolean generateStructs) { String commandObject = generateStructs ? "struct" : "class"; // // Write Code Generation Information // writer.WriteLine("//"); writer.WriteLine("// This file was autogenerated using the PdlCodeGenerator"); writer.WriteLine("// GenerationDateTime : {0}", DateTime.Now); writer.WriteLine("//"); writer.WriteLine("using System;"); writer.WriteLine("using System.Text;"); writer.WriteLine(); writer.WriteLine("using More;"); writer.WriteLine(); writer.WriteLine("namespace {0}", @namespace); writer.WriteLine("{"); // // Print global enum definitions // foreach (EnumOrFlagsDefinition enumOrFlagsDefinition in pdlFile.EnumOrFlagsDefinitions) { if (enumOrFlagsDefinition.isGlobalType) { GenerateEnumDefinition(@namespace, writer, 1, enumOrFlagsDefinition); } } // // Print class definitions // foreach (NamedObjectDefinition objectDefinition in pdlFile.ObjectDefinitions) { List <ObjectDefinitionField> objectDefinitionFields = objectDefinition.Fields; UInt32 fixedSerializationLength = objectDefinition.FixedSerializationLength; UInt32 tabs; writer.WriteLine(" public {0} {1}", commandObject, objectDefinition.name); writer.WriteLine(" {"); if (fixedSerializationLength != UInt32.MaxValue) { writer.WriteLine(" public const UInt32 FixedSerializationLength = {0};", fixedSerializationLength); writer.WriteLine(); } /* * // * // Print static reflector * // * writer.WriteLine(" static IReflector reflector = null;"); * writer.WriteLine(" public static IReflector Reflector"); * writer.WriteLine(" {"); * writer.WriteLine(" get"); * writer.WriteLine(" {"); * writer.WriteLine(" if(reflector == null)"); * writer.WriteLine(" {"); * writer.WriteLine(" reflector = new Reflectors(new IReflector[] {"); * tabs = 6; * for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) * { * ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; * PdlType type = field.typeReference.type; * if(type == PdlType.Object) * { * generator.GenerateReflectorConstructor(writer, tabs, objectDefinition.name, field.name, field.typeReference.AsObjectTypeReference); * } * else if(type == PdlType.Enum || type == PdlType.Flags) * { * generator.GenerateReflectorConstructor(writer, tabs, objectDefinition.name, field.name, field.typeReference.AsEnumOrFlagsTypeReference); * } * else if (type == PdlType.Serializer) * { * generator.GenerateReflectorConstructor(writer, tabs, objectDefinition.name, field.name, field.typeReference.AsSerializerTypeReference); * } * else * { * generator.GenerateReflectorConstructor(writer, tabs, objectDefinition.name, field.name, field.typeReference.AsIntegerTypeReference); * } * } * writer.WriteLine(" });"); * writer.WriteLine(" }"); * writer.WriteLine(" return reflector;"); * writer.WriteLine(" }"); * writer.WriteLine(" }"); * writer.WriteLine(); */ // // Print static instance serializer // writer.WriteLine(" static InstanceSerializer serializer = null;"); writer.WriteLine(" public static InstanceSerializer Serializer"); writer.WriteLine(" {"); writer.WriteLine(" get"); writer.WriteLine(" {"); writer.WriteLine(" if(serializer == null) serializer = new InstanceSerializer();"); writer.WriteLine(" return serializer;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(); writer.WriteLine(" public class InstanceSerializer : {0}InstanceSerializer<{1}>", (fixedSerializationLength == UInt32.MaxValue) ? "I" : "FixedLength", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" public InstanceSerializer() {}"); if (fixedSerializationLength != UInt32.MaxValue) { // // FixedSerializationLength Method // writer.WriteLine(" public override UInt32 FixedSerializationLength() {{ return {0}.FixedSerializationLength; }}", objectDefinition.name); // // FixedLengthSerialize Method // writer.WriteLine(" public override void FixedLengthSerialize(Byte[] bytes, UInt32 offset, {0} instance)", objectDefinition.name); writer.WriteLine(" {"); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; if (typeReference.arrayType == null) { writer.WriteLine(" {0};", typeReference.ElementSerializeExpression("bytes", "offset", "instance." + field.name)); writer.WriteLine(" offset += {0};", typeReference.FixedElementSerializationLength); } else { UInt32 fixedArraySize = typeReference.arrayType.GetFixedArraySize(); if (typeReference.type == PdlType.Byte || typeReference.type == PdlType.SByte) { writer.WriteLine(" Array.Copy(instance.{0}, 0, bytes, offset, {1});", field.name, fixedArraySize); writer.WriteLine(" offset += {0};", fixedArraySize); } else { writer.WriteLine(" for(int i = 0; i < {0}; i++)", fixedArraySize); writer.WriteLine(" {"); writer.WriteLine(" {0};", typeReference.ElementSerializeExpression("bytes", "offset", "instance." + field.name + "[i]")); writer.WriteLine(" offset += {0};", typeReference.FixedElementSerializationLength); writer.WriteLine(" }"); } } } writer.WriteLine(" }"); // // FixedLengthDeserialize Method // writer.WriteLine(" public override {0} FixedLengthDeserialize(Byte[] bytes, UInt32 offset)", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" return new {0} (", objectDefinition.name); UInt32 offset = 0; for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; if (typeReference.arrayType == null) { writer.Write(" {0}", typeReference.ElementFixedLengthDeserializeExpression("bytes", "offset + " + offset.ToString())); offset += typeReference.FixedElementSerializationLength; } else { UInt32 fixedArraySize = typeReference.arrayType.GetFixedArraySize(); writer.Write(" {0}", typeReference.ElementDeserializeArrayExpression("bytes", "offset + " + offset, fixedArraySize.ToString())); offset += typeReference.FixedElementSerializationLength * fixedArraySize; } if (fieldIndex < objectDefinitionFields.Count - 1) { writer.Write(','); } writer.WriteLine(" // {0}", field.name); } writer.WriteLine(" );"); writer.WriteLine(" }"); } else { // // SerializationLength Method // writer.WriteLine(" public UInt32 SerializationLength({0} instance)", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" UInt32 dynamicLengthPart = 0;"); UInt32 fixedSerializationLengthPart = 0; for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; UInt32 fieldFixedElementSerializationLength = typeReference.FixedElementSerializationLength; if (fieldFixedElementSerializationLength != UInt32.MaxValue) { if (typeReference.arrayType == null) { fixedSerializationLengthPart += fieldFixedElementSerializationLength; } else { if (typeReference.arrayType.type == PdlArraySizeTypeEnum.Fixed) { fixedSerializationLengthPart += fieldFixedElementSerializationLength * typeReference.arrayType.GetFixedArraySize(); } else { fixedSerializationLengthPart += typeReference.arrayType.GetArraySizeByteCount(); writer.WriteLine(" if(instance.{0} != null) dynamicLengthPart += (UInt32)instance.{0}.Length * {1};", field.name, fieldFixedElementSerializationLength); } } } else { if (typeReference.arrayType == null) { writer.WriteLine(" dynamicLengthPart += {0};", typeReference.ElementDynamicSerializationLengthExpression("instance." + field.name)); } else { String serializationLengthExpression = typeReference.ElementDynamicSerializationLengthExpression("instance." + field.name + "[i]"); if (typeReference.arrayType.type == PdlArraySizeTypeEnum.Fixed) { writer.WriteLine(" for(int i = 0; i < {0}; i++)", typeReference.arrayType.GetFixedArraySize()); writer.WriteLine(" {"); writer.WriteLine(" dynamicLengthPart += {0};", serializationLengthExpression); writer.WriteLine(" }"); } else { fixedSerializationLengthPart += typeReference.arrayType.GetArraySizeByteCount(); writer.WriteLine(" if(instance.{0} != null)", field.name); writer.WriteLine(" {"); writer.WriteLine(" for(int i = 0; i < instance.{0}.Length; i++)", field.name); writer.WriteLine(" {"); writer.WriteLine(" dynamicLengthPart += {0};", serializationLengthExpression); writer.WriteLine(" }"); writer.WriteLine(" }"); } } } } writer.WriteLine(" return {0} + dynamicLengthPart;", fixedSerializationLengthPart); writer.WriteLine(" }"); // // Serialize Method // writer.WriteLine(" public UInt32 Serialize(Byte[] bytes, UInt32 offset, {0} instance)", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" UInt32 arrayLength;"); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; UInt32 fieldFixedElementSerializationLength = typeReference.FixedElementSerializationLength; if (typeReference.arrayType == null) { String serializeExpression = typeReference.ElementSerializeExpression("bytes", "offset", "instance." + field.name); if (fieldFixedElementSerializationLength == UInt32.MaxValue) { writer.WriteLine(" offset = {0};", serializeExpression); } else { writer.WriteLine(" {0};", serializeExpression); writer.WriteLine(" offset += {0};", fieldFixedElementSerializationLength); } } else { String arrayLengthString; if (typeReference.arrayType.type == PdlArraySizeTypeEnum.Fixed) { arrayLengthString = typeReference.arrayType.GetFixedArraySize().ToString(); } else { arrayLengthString = "arrayLength"; writer.WriteLine(" arrayLength = (instance.{0} == null) ? 0 : (UInt32)instance.{0}.Length;", field.name); writer.WriteLine(" {0};", typeReference.arrayType.LengthSerializeExpression("bytes", "offset", String.Format("({0})arrayLength", typeReference.arrayType.type))); writer.WriteLine(" offset += {0};", typeReference.arrayType.GetArraySizeByteCount()); } writer.WriteLine(" for(UInt32 i = 0; i < {0}; i++)", arrayLengthString); writer.WriteLine(" {"); String elementInstanceString = String.Format("instance.{0}[{1}i]", field.name, (field.typeReference.type == PdlType.Ascii) ? "(Int32)" : ""); String serializeExpression = typeReference.ElementSerializeExpression("bytes", "offset", elementInstanceString); if (fieldFixedElementSerializationLength == UInt32.MaxValue) { writer.WriteLine(" offset = {0};", serializeExpression); } else { writer.WriteLine(" {0};", serializeExpression); writer.WriteLine(" offset += {0};", fieldFixedElementSerializationLength); } writer.WriteLine(" }"); } } writer.WriteLine(" return offset;"); writer.WriteLine(" }"); // // Deserialize Method // writer.WriteLine(" public UInt32 Deserialize(Byte[] bytes, UInt32 offset, UInt32 offsetLimit, out {0} outInstance)", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" UInt32 arrayLength;"); writer.WriteLine(" {0} instance = new {0}();", objectDefinition.name); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; UInt32 fieldFixedElementSerializationLength = typeReference.FixedElementSerializationLength; if (typeReference.arrayType == null) { if (fieldFixedElementSerializationLength == UInt32.MaxValue) { //String deserializeExpression = typeReference.ElementDeserializeExpression("bytes", "offset"); writer.WriteLine(" // not implemented; //instance.{0};", field.name); } else { writer.WriteLine(" instance.{0} = {1};", field.name, typeReference.ElementFixedLengthDeserializeExpression("bytes", "offset")); writer.WriteLine(" offset += {0};", fieldFixedElementSerializationLength); } } else { String arrayLengthString; if (typeReference.arrayType.type == PdlArraySizeTypeEnum.Fixed) { arrayLengthString = typeReference.arrayType.GetFixedArraySize().ToString(); } else { arrayLengthString = "arrayLength"; writer.WriteLine(" {0};", typeReference.arrayType.LengthDeserializeExpression("bytes", "offset", "arrayLength")); writer.WriteLine(" offset += {0};", typeReference.arrayType.GetArraySizeByteCount()); } if (fieldFixedElementSerializationLength == UInt32.MaxValue) { writer.WriteLine("// Dynamic Length Element Arrays are not yet implemented"); } else { writer.WriteLine(" instance.{0} = {1};", field.name, typeReference.ElementDeserializeArrayExpression("bytes", "offset", arrayLengthString)); writer.WriteLine(" offset += {0} * {1};", fieldFixedElementSerializationLength, arrayLengthString); } } } writer.WriteLine(" outInstance = instance;"); writer.WriteLine(" return offset;"); writer.WriteLine(" }"); } // // DataString Method // writer.WriteLine(" public{0} void DataString({1} instance, StringBuilder builder)", (fixedSerializationLength == UInt32.MaxValue) ? "" : " override", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" builder.Append(\"{0}:{{\");", objectDefinition.name); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { if (fieldIndex > 0) { writer.WriteLine(" builder.Append(',');"); } ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; if (typeReference.arrayType == null) { writer.WriteLine(" {0};", typeReference.ElementDataStringExpression("builder", "instance." + field.name, false)); } else { writer.WriteLine(" // Arrays inside dynamic length objects not implemented"); } } writer.WriteLine(" builder.Append(\"}\");"); writer.WriteLine(" }"); // // DataString Method // writer.WriteLine(" public{0} void DataSmallString({1} instance, StringBuilder builder)", (fixedSerializationLength == UInt32.MaxValue) ? "" : " override", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" builder.Append(\"{0}:{{\");", objectDefinition.name); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { if (fieldIndex > 0) { writer.WriteLine(" builder.Append(',');"); } ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; if (typeReference.arrayType == null) { writer.WriteLine(" {0};", typeReference.ElementDataStringExpression("builder", "instance." + field.name, true)); } else { writer.WriteLine(" // Arrays inside dynamic length objects not implemented"); } } writer.WriteLine(" builder.Append(\"}\");"); writer.WriteLine(" }"); writer.WriteLine(" }"); // End Of Serializer Class // // Print Enum definitinos // if (objectDefinition.enumOrFlagDefinitions != null) { writer.WriteLine(); foreach (EnumOrFlagsDefinition enumOrFlagsDefinition in objectDefinition.enumOrFlagDefinitions) { GenerateEnumDefinition(@namespace, writer, 2, enumOrFlagsDefinition); } } // // Print fields // writer.WriteLine(); tabs = 2; for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; TypeReference typeReference = field.typeReference; writer.WriteLine(tabs * 4, "public {0} {1};", typeReference.CodeTypeString(), field.name); } // // Print No-Parameter Constructor // if (!generateStructs) { writer.WriteLine(" public {0}() {{ }}", objectDefinition.name); } // // Print Parameter Constructor // writer.Write(" public {0}(", objectDefinition.name); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; if (fieldIndex > 0) { writer.Write(", "); } writer.Write("{0} {1}", field.typeReference.CodeTypeString(), field.name); } writer.WriteLine(")"); writer.WriteLine(" {"); for (int fieldIndex = 0; fieldIndex < objectDefinitionFields.Count; fieldIndex++) { ObjectDefinitionField field = objectDefinitionFields[fieldIndex]; writer.WriteLine(" this.{0} = {0};", field.name); } writer.WriteLine(" }"); // // Print Deserialization Constructor // /* * writer.WriteLine(); * writer.WriteLine(" // Deserialization constructor"); * writer.WriteLine(" public {0}(Byte[] array, UInt32 offset, UInt32 offsetLimit)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" UInt32 newOffset = Reflector.Deserialize(this, array, offset, offsetLimit);"); * writer.WriteLine(" if(newOffset != offsetLimit) throw new FormatException(String.Format("); * writer.WriteLine(" \"Expected packet '{0}' to be {{1}} bytes but was {{2}} bytes\", offsetLimit - offset, newOffset - offset));", objectDefinition.name); * writer.WriteLine(" }"); * writer.WriteLine(" public {0}(Byte[] array, UInt32 offset, UInt32 offsetLimit, out UInt32 newOffset)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" newOffset = Reflector.Deserialize(this, array, offset, offsetLimit);"); * writer.WriteLine(" }"); */ /* * // * // Print Deserializer Method * // * if (fixedSerializationLength >= 0) * { * writer.WriteLine(" public override {0} Deserialize(Byte[] array, UInt32 offset)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" return new {0}(array, offset, offset + FixedSerializationLength);", objectDefinition.name); * writer.WriteLine(" }"); * } * else * { * writer.WriteLine(" public override UInt32 Deserialize(Byte[] array, UInt32 offset, UInt32 offsetLimit, out {0} outInstance)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" UInt32 newOffset;"); * writer.WriteLine(" outInstance = new {0}(array, offset, offsetLimit, out newOffset);", objectDefinition.name); * writer.WriteLine(" return newOffset;"); * writer.WriteLine(" }"); * } */ // // Print Serialization Methods // /* * if (fixedSerializationLength >= 0) * { * writer.WriteLine(" public const UInt32 FixedSerializationLength = {0};", fixedSerializationLength); * writer.WriteLine(" public static void FixedLengthSerialize(Byte[] array, UInt32 offset, {0} instance)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" UInt32 serializationLength = Reflector.Serialize(instance, array, offset) - FixedSerializationLength;"); * writer.WriteLine(" if(offset != serializationLength) throw new InvalidOperationException(String.Format("); * writer.WriteLine(" \"Expected serialization length to be {0} but was {1}\","); * writer.WriteLine(" FixedSerializationLength, serializationLength));"); * writer.WriteLine(" }"); * } * else * { * writer.WriteLine(" public static UInt32 SerializationLength({0} obj)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" return Reflector.SerializationLength(obj);"); * writer.WriteLine(" }"); * writer.WriteLine(" public static UInt32 DynamicLengthSerialize(Byte[] array, UInt32 offset, {0} instance)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" return Reflector.Serialize(instance, array, offset);"); * writer.WriteLine(" }"); * } * writer.WriteLine(" public static void DataString({0} instance, StringBuilder builder)", objectDefinition.name); * writer.WriteLine(" {"); * writer.WriteLine(" Reflector.DataString(instance, builder);"); * writer.WriteLine(" }"); */ // // Print serializer adapater factory method // if (fixedSerializationLength == UInt32.MaxValue) { writer.WriteLine(" public InstanceSerializerAdapter<{0}> CreateSerializerAdapater()", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" return new InstanceSerializerAdapter<{0}>(Serializer, this);", objectDefinition.name); writer.WriteLine(" }"); } else { writer.WriteLine(" public FixedLengthInstanceSerializerAdapter<{0}> CreateSerializerAdapater()", objectDefinition.name); writer.WriteLine(" {"); writer.WriteLine(" return new FixedLengthInstanceSerializerAdapter<{0}>(Serializer, this);", objectDefinition.name); writer.WriteLine(" }"); } writer.WriteLine(" }"); } writer.WriteLine("}"); }