Example #1
0
            /// <summary>
            /// Decodes the ARZ file.
            /// </summary>
            /// <param name="inReader">input BinaryReader</param>
            /// <param name="baseOffset">Offset in the file.</param>
            /// <param name="arzFile">ArzFile instance which we are operating.</param>
            public void Decode(BinaryReader inReader, int baseOffset, ArzFile arzFile)
            {
                // Record Entry Format
                // 0x0000 int32 stringEntryID (dbr filename)
                // 0x0004 int32 string length
                // 0x0008 string (record type)
                // 0x00?? int32 offset
                // 0x00?? int32 length in bytes
                // 0x00?? int32 timestamp?
                // 0x00?? int32 timestamp?
                this.idStringIndex = inReader.ReadInt32();
                this.RecordType    = TQData.ReadCString(inReader);
                this.offset        = inReader.ReadInt32() + baseOffset;

                // Compressed size
                // We throw it away and just advance the offset in the file.
                inReader.ReadInt32();

                // Crap1 - timestamp?
                // We throw it away and just advance the offset in the file.
                inReader.ReadInt32();

                // Crap2 - timestamp?
                // We throw it away and just advance the offset in the file.
                inReader.ReadInt32();

                // Get the ID string
                this.ID = arzFile.Getstring(this.idStringIndex);
            }
Example #2
0
            /// <summary>
            /// Decompresses the ARZ file into an array of bytes.
            /// </summary>
            /// <param name="arzFile">ArzFile which we are decompressing.</param>
            /// <returns>Returns a byte array containing the raw data.</returns>
            private byte[] DecompressBytes(ArzFile arzFile)
            {
                if (arzFile == null)
                {
                    throw new ArgumentNullException("arzFile", "arzFile is null.");
                }

                // Read in the compressed data and decompress it, storing the results in a memorystream
                using (FileStream arzStream = new FileStream(arzFile.fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    arzStream.Seek(this.offset, SeekOrigin.Begin);

                    // Ignore the zlib compression method.
                    arzStream.ReadByte();

                    // Ignore the zlib compression flags.
                    arzStream.ReadByte();

                    // Create a deflate stream.
                    using (DeflateStream deflate = new DeflateStream(arzStream, CompressionMode.Decompress))
                    {
                        // Create a memorystream to hold the decompressed data
                        using (MemoryStream outStream = new MemoryStream())
                        {
                            // Now decompress
                            byte[] buffer = new byte[1024];
                            int    len;
                            while ((len = deflate.Read(buffer, 0, 1024)) > 0)
                            {
                                outStream.Write(buffer, 0, len);
                            }

                            // Return the decompressed data
                            return(outStream.ToArray());
                        }
                    }
                }
            }
Example #3
0
            /// <summary>
            /// Decompresses an individual record.
            /// </summary>
            /// <param name="arzFile">ARZ file which we are decompressing.</param>
            /// <returns>decompressed DBRecord.</returns>
            public DBRecordCollection Decompress(ArzFile arzFile)
            {
                // record variables have this format:
                // 0x00 int16 specifies data type:
                //      0x0000 = int - data will be an int32
                //      0x0001 = float - data will be a Single
                //      0x0002 = string - data will be an int32 that is index into string table
                //      0x0003 = bool - data will be an int32
                // 0x02 int16 specifies number of values (usually 1, but sometimes more (for arrays)
                // 0x04 int32 key string ID (the id into the string table for this variable name
                // 0x08 data value
                byte[] data = this.DecompressBytes(arzFile);

                int numberOfDWords = data.Length / 4;

                if (data.Length % 4 != 0)
                {
                    // Turn on debugging so we can log the exception.
                    if (!TQDebug.DebugEnabled)
                    {
                        TQDebug.DebugEnabled = true;
                    }

                    TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName));
                    TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, data Length = {1} which is not a multiple of 4", this.ID, (int)data.Length));
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, data Length = {1} which is not a multiple of 4", this.ID, (int)data.Length));
                }

                DBRecordCollection record = new DBRecordCollection(this.ID, this.RecordType);

                // Create a memory stream to read the binary data
                using (BinaryReader inReader = new BinaryReader(new MemoryStream(data, false)))
                {
                    int i = 0;
                    while (i < numberOfDWords)
                    {
                        short  dataType     = inReader.ReadInt16();
                        short  valCount     = inReader.ReadInt16();
                        int    variableID   = inReader.ReadInt32();
                        string variableName = arzFile.Getstring(variableID);

                        if (variableName == null)
                        {
                            // Turn on debugging so we can log the exception.
                            if (!TQDebug.DebugEnabled)
                            {
                                TQDebug.DebugEnabled = true;
                            }

                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName));
                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable is NULL", this.ID));
                            throw new ArgumentNullException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable is NULL", this.ID));
                        }

                        if (dataType < 0 || dataType > 3)
                        {
                            // Turn on debugging so we can log the exception.
                            if (!TQDebug.DebugEnabled)
                            {
                                TQDebug.DebugEnabled = true;
                            }

                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName));
                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad dataType {2}", this.ID, variableName, dataType));
                            throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad dataType {2}", this.ID, variableName, dataType));
                        }

                        Variable v = new Variable(variableName, (VariableDataType)dataType, valCount);

                        if (valCount < 1)
                        {
                            // Turn on debugging so we can log the exception.
                            if (!TQDebug.DebugEnabled)
                            {
                                TQDebug.DebugEnabled = true;
                            }

                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName));
                            TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad valCount {2}", this.ID, variableName, valCount));
                            throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad valCount {2}", this.ID, variableName, valCount));
                        }

                        // increment our dword count
                        i += 2 + valCount;

                        for (int j = 0; j < valCount; ++j)
                        {
                            switch (v.DataType)
                            {
                            case VariableDataType.Integer:
                            case VariableDataType.Boolean:
                            {
                                int val = inReader.ReadInt32();
                                v[j] = val;
                                break;
                            }

                            case VariableDataType.Float:
                            {
                                float val = inReader.ReadSingle();
                                v[j] = val;
                                break;
                            }

                            case VariableDataType.StringVar:
                            {
                                int    id  = inReader.ReadInt32();
                                string val = arzFile.Getstring(id);
                                if (val == null)
                                {
                                    val = string.Empty;
                                }
                                else
                                {
                                    val = val.Trim();
                                }

                                v[j] = val;
                                break;
                            }

                            default:
                            {
                                int val = inReader.ReadInt32();
                                v[j] = val;
                                break;
                            }
                            }
                        }

                        record.Set(v);
                    }
                }

                return(record);
            }