Exemplo n.º 1
0
 public Parser(IBinaryStream file)
 {
     m_file         = file;
     m_is_bigendian = 0x2a004d4d == m_file.Signature;
     if (m_is_bigendian)
     {
         ReadUInt16 = () => Binary.BigEndian(m_file.ReadUInt16());
         ReadUInt32 = () => Binary.BigEndian(m_file.ReadUInt32());
         ReadUInt64 = () => Binary.BigEndian(m_file.ReadUInt64());
     }
     else
     {
         ReadUInt16 = () => m_file.ReadUInt16();
         ReadUInt32 = () => m_file.ReadUInt32();
         ReadUInt64 = () => m_file.ReadUInt64();
     }
     m_first_ifd = file.ReadHeader(8).ToUInt32(4);
 }
Exemplo n.º 2
0
        public List <Entry> Deserialize()
        {
            m_index.Position = 8;
            int count = Binary.BigEndian(m_index.ReadInt32());

            m_name_list = new string[count];
            for (int i = 0; i < count; ++i)
            {
                int length = m_index.ReadUInt8();
                m_name_list[i] = m_index.ReadCString(length, Encoding.UTF8);
            }

            count = Binary.BigEndian(m_index.ReadInt32());
            m_dir = new List <Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                m_index.ReadUInt16();
                ushort flags  = Binary.BigEndian(m_index.ReadUInt16());
                uint   offset = Binary.BigEndian(m_index.ReadUInt32());
                uint   size   = Binary.BigEndian(m_index.ReadUInt32());
                var    entry  = new SxEntry {
                    Flags        = flags,
                    Offset       = (long)offset << 4,
                        Size     = size,
                        IsPacked = 0 != (flags & 0x03),
                };
                if (!entry.CheckPlacement(m_max_offset))
                {
                    return(null);
                }
                m_dir.Add(entry);
            }

            count = Binary.BigEndian(m_index.ReadUInt16());
            for (int i = 0; i < count; ++i)
            {
                m_index.ReadUInt32();
                m_index.ReadUInt32();
                m_index.ReadUInt32();
                Binary.BigEndian(m_index.ReadUInt32()); // archive body length
                m_index.ReadUInt64();
                m_index.Seek(16, SeekOrigin.Current);   // MD5 sum
            }

            count = Binary.BigEndian(m_index.ReadUInt16());
            if (count > 0)
            {
                m_index.Seek(count * 24, SeekOrigin.Current);
            }
            DeserializeTree();
            return(m_dir);
        }
Exemplo n.º 3
0
        internal static object ReadField(this IBinaryStream input, FieldInfo field)
        {
            var field_type = field.FieldType;
            var type_code  = Type.GetTypeCode(field_type);

            switch (type_code)
            {
            case TypeCode.SByte:    return(input.ReadInt8());

            case TypeCode.Byte:     return(input.ReadUInt8());

            case TypeCode.Int16:    return(input.ReadInt16());

            case TypeCode.UInt16:   return(input.ReadUInt16());

            case TypeCode.Int32:    return(input.ReadInt32());

            case TypeCode.UInt32:   return(input.ReadUInt32());

            case TypeCode.Int64:    return(input.ReadInt64());

            case TypeCode.UInt64:   return(input.ReadUInt64());

            case TypeCode.Char:     return((char)input.ReadInt16());

            case TypeCode.String:
                var cstring_attr = field.GetCustomAttribute <CStringAttribute>();
                if (cstring_attr != null)
                {
                    var encoding = cstring_attr.Encoding ?? Encodings.cp932;
                    if (cstring_attr.IsLengthDefined)
                    {
                        return(input.ReadCString(cstring_attr.Length, encoding));
                    }
                    else
                    {
                        return(input.ReadCString(encoding));
                    }
                }
                throw new FormatException("Serialization method for string field is not defined.");

            case TypeCode.Object:
                object val = Activator.CreateInstance(field_type);
                ReadStruct(input, field_type, ref val);  // FIXME check object graph for cycles
                return(val);

            default:
                throw new NotSupportedException("Not supported serialization type.");
            }
        }
Exemplo n.º 4
0
        internal IEnumerable <ArcDatEntry> ReadIndex(IBinaryStream input, int count, Scheme scheme, uint key = 0)
        {
            int skipped  = 0;
            var file_map = ReadFilenameMap(scheme);

            for (int i = 0; i < count; ++i)
            {
                var hash  = input.ReadUInt64();
                var entry = new ArcDatEntry
                {
                    Hash         = hash,
                    Flags        = input.ReadByte() ^ (byte)hash,
                    Offset       = input.ReadUInt32() ^ (uint)hash ^ key,
                    Size         = input.ReadUInt32() ^ (uint)hash,
                    UnpackedSize = input.ReadUInt32() ^ (uint)hash,
                };
                entry.IsPacked = 0 != (entry.Flags & 2);
                byte[] raw_name = null;
                if (file_map.TryGetValue(hash, out raw_name))
                {
                    entry.Name    = Encodings.cp932.GetString(raw_name);
                    entry.Type    = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                    entry.RawName = raw_name;
                }
                if (0 == (entry.Flags & 2))
                {
                    if (null == raw_name)
                    {
//                      System.Diagnostics.Trace.WriteLine ("Unknown hash", hash.ToString ("X16"));
                        ++skipped;
                        continue;
                    }
                    entry.Offset       ^= raw_name[raw_name.Length >> 1];
                    entry.Size         ^= raw_name[raw_name.Length >> 2];
                    entry.UnpackedSize ^= raw_name[raw_name.Length >> 3];
                }
                if (string.IsNullOrEmpty(entry.Name))
                {
                    entry.Name = hash.ToString("X16");
                }
                yield return(entry);
            }
            if (skipped != 0)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Missing {0} names", skipped), "[noncolor]");
            }
        }