コード例 #1
0
        private void SaveContainer(InputFile inFile, OutputFile outFile, ContainerAtom container)
        {
            if (container.HeaderLength == 8)
            {
                outFile.WriteUInt32((UInt32)container.TotalLength);
                outFile.WriteChars(container.Type.ToCharArray());
            }
            else
            {
                outFile.WriteUInt32(1);
                outFile.WriteChars(container.Type.ToCharArray());
                outFile.WriteUInt64(container.TotalLength);
            }

            foreach (var obj in container.Children)
            {
                if (obj is ContainerAtom)
                {
                    SaveContainer(inFile, outFile, (ContainerAtom)obj);
                }
                else
                {
                    SaveAtom(inFile, outFile, (LeafAtom)obj);
                }
            }
        }
コード例 #2
0
        public ArrayList ParseFile(InputFile file)
        {
            ArrayList atoms    = new ArrayList();
            UInt64    position = 0;

            while (position < file.Length)
            {
                string type = GetAtomType(file, position);
                Atom   atom = null;

                if (IsContainer(type))
                {
                    atom = new ContainerAtom(type);
                    ParseContainer(file, position, (ContainerAtom)atom);
                }
                else if (IsAtom(type))
                {
                    atom = new LeafAtom(type);
                    ParseAtom(file, position, atom);
                }
                else
                {
                    throw new Exception("Invalid atom at pos 0x" + position.ToString("X16"));
                }

                atoms.Add(atom);
                position += atom.TotalLength;
            }

            return(atoms);
        }
コード例 #3
0
        private void ParseContainer(InputFile file, ulong position, ContainerAtom container)
        {
            ParseAtom(file, position, container);

            ArrayList atoms  = new ArrayList();
            UInt64    offset = container.HeaderLength;

            while (offset < container.TotalLength)
            {
                string type = GetAtomType(file, position + offset);
                Atom   atom = null;

                if (IsContainer(type))
                {
                    atom = new ContainerAtom(type);
                    ParseContainer(file, position + offset, (ContainerAtom)atom);
                }
                else
                {
                    atom = new LeafAtom(type);
                    ParseAtom(file, position + offset, atom);
                }

                container.Children.Add(atom);
                offset += atom.TotalLength;
            }
        }
コード例 #4
0
 private void BuildTree(TreeNode root, ArrayList atoms)
 {
     foreach (var obj in atoms)
     {
         if (obj is ContainerAtom)
         {
             ContainerAtom container = (ContainerAtom)obj;
             TreeNode      node      = new TreeNode(container + " C:" + container.Children.Count);
             BuildTree(node, ((ContainerAtom)obj).Children);
             root.Nodes.Add(node);
         }
         else
         {
             LeafAtom leaf = (LeafAtom)obj;
             TreeNode node = new TreeNode(leaf + "");
             root.Nodes.Add(node);
         }
     }
 }
コード例 #5
0
        private Atom FindAtom(ArrayList atoms, string name)
        {
            foreach (var obj in atoms)
            {
                if (((Atom)obj).Type == name)
                {
                    return((Atom)obj);
                }

                if (obj is ContainerAtom)
                {
                    ContainerAtom container = (ContainerAtom)obj;
                    Atom          sub       = FindAtom(((ContainerAtom)obj).Children, name);

                    if (sub != null)
                    {
                        return(sub);
                    }
                }
            }

            return(null);
        }
コード例 #6
0
        private UInt64 CalculateSizes(ArrayList atoms, UInt64 outFileOffset, bool absolute)
        {
            UInt64 totalSize = 0;

            string tabs = "";

            for (int pos = 0; pos < TreeDepth; pos++)
            {
                tabs += "  ";
            }

            foreach (var obj in atoms)
            {
                if (obj is ContainerAtom)
                {
                    ContainerAtom container = (ContainerAtom)obj;

                    if (absolute)
                    {
                        Log(tabs + "  [" + container.Type + "] size: 0x" + container.TotalLength.ToString("X8") + " bytes");
                    }

                    /* run first with absolute file offset set to zero, as it is not clear yet if we have 8 or 16 byte header */
                    UInt64 containerSize = CalculateSizes(container.Children, 0, false);

                    if ((containerSize + 8) > 0xFFFFFFFF)
                    {
                        container.HeaderLength = 16;
                    }
                    else
                    {
                        container.HeaderLength = 8;
                    }
                    container.TotalLength      = container.HeaderLength + containerSize;
                    container.HeaderFileOffset = outFileOffset + totalSize;

                    /* run again with the real absolute file offset */
                    if (absolute)
                    {
                        TreeDepth++;
                        CalculateSizes(container.Children, container.PayloadFileOffset, true);
                        TreeDepth--;
                    }

                    /* now we are done with that container */
                    totalSize += container.TotalLength;
                }
                else
                {
                    LeafAtom leaf        = (LeafAtom)obj;
                    UInt64   contentSize = leaf.PayloadLength;

                    /* replace content with our patched? */
                    if (leaf.PayloadData != null)
                    {
                        contentSize = (UInt64)leaf.PayloadData.Length;
                        if (absolute)
                        {
                            Log(tabs + "      [" + leaf.Type + "] Replacing data (0x" + leaf.OriginalPayloadLength.ToString("X8") + " bytes) with 0x" + contentSize.ToString("X8") + " bytes");
                        }
                    }

                    if ((contentSize + 8) > 0xFFFFFFFF)
                    {
                        leaf.HeaderLength = 16;
                    }
                    else
                    {
                        leaf.HeaderLength = 8;
                    }

                    leaf.TotalLength      = leaf.HeaderLength + contentSize;
                    leaf.HeaderFileOffset = outFileOffset + totalSize;

                    totalSize += leaf.TotalLength;

                    if (absolute)
                    {
                        Log(tabs + "      [" + leaf.Type + "] size: 0x" + leaf.TotalLength.ToString("X8") + " pos: 0x" + leaf.HeaderFileOffset.ToString("X8"));
                    }
                }
            }

            return(totalSize);
        }