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;
        }
Exemple #3
0
        public static PdlFile ParsePdlFile(LfdReader reader)
        {
            PdlFile pdlFile = new PdlFile();

            ParsePdlFile(pdlFile, reader);
            return(pdlFile);
        }
Exemple #4
0
        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));
        }
Exemple #5
0
        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));
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
                }
            }
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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]));
        }
Exemple #12
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("}");
        }