예제 #1
0
        public void ParseListsChunks(ContainerVisitor visitor, BinaryReader reader, long offset, long stopAt, StructInstance parent)
        {
            while (offset < stopAt)
            {
                reader.BaseStream.Seek(offset, SeekOrigin.Begin);

                string id = Util.ReadFourCC(reader);
                int size = reader.ReadInt32();
                if (size % 2 != 0)
                {
                    size++;
                }

                StructInstance inst = null;

                if (id == "LIST") // 'LIST' listSize listType listData
                {
                    string listType = Util.ReadFourCC(reader);

                    // a LIST instance is needed to maintain a list of sub LISTs and CHUNKs.
                    StructElement listDef = _chunkDefs["LIST"];
                    inst = GetChunkInstance(reader, listDef, 0, parent);

                    if (listType != "movi")
                    {
                        visitor.BeginVisitNode(
                            string.Format("LIST ({0})", listType), string.Empty);

                        ParseListsChunks(visitor, reader, reader.BaseStream.Position, offset + size + 8, inst);
                    }
                    else
                    {
                        visitor.BeginVisitNode(
                            string.Format("LIST ({0})", listType), "Content in this list is skipped.");
                    }

                    offset += size + 8;
                }
                else // ckID ckSize ckData
                {
                    StructElement chunkDef = _chunkDefs[id];
                    inst = GetChunkInstance(reader, chunkDef, size, parent);

                    visitor.BeginVisitNode(id, GetChunkDescription(reader, id, size, inst));

                    offset += size + 8;
                }

                if (parent != null)
                {
                    // link CHUNK to its parent LIST
                    parent[id] = inst;
                }

                visitor.EndVisitNode();
            }
        }
예제 #2
0
        public void ParseAtoms(ContainerVisitor visitor, BinaryReader reader, long offset, long stopAt, StructInstance parent)
        {
            while (offset < stopAt)
            {
                reader.BaseStream.Seek(offset, SeekOrigin.Begin);

                uint atomSize = Util.EndianFlip32(reader.ReadUInt32());
                string atomType = Util.ReadFourCC(reader);

                if (_atomDefs.ContainsKey(atomType))
                {
                    StructElement atomDef = _atomDefs[atomType];

                    StructInstance inst = GetAtomInstance(reader, atomDef, atomSize, parent);
                    string desc = GetAtomDesc(atomDef, atomSize, inst);
                    visitor.BeginVisitNode(atomType, desc);

                    // If it is a container atom
                    if (atomDef != null && atomDef.Elements == null)
                    {
                        // parse children atoms recursively
                        ParseAtoms(visitor, reader, reader.BaseStream.Position, offset + atomSize, inst);
                    }

                    if (parent != null)
                    {
                        parent[atomType] = inst;
                    }

                    visitor.EndVisitNode();
                }

                // now set offset to next atom (or end-of-file) in special case
                // (atomSize = 0 means atom goes to EOF)
                if (atomSize == 0)
                {
                    offset = reader.BaseStream.Length;
                }
                else
                {
                    offset += atomSize;
                }

                // if a 'udta' container atom, then jump ahead 4 to work around
                // Apple's QT 1.0 workaround
                // @see http://developer.apple.com/technotes/qt/qt_03.html
                if (atomType == "udta")
                {
                    offset += 4;
                }
            }
        }
예제 #3
0
        public virtual string GetChunkDescription(BinaryReader reader, string id, int chunkSize, StructInstance inst)
        {
            StructElement chunkDef = _chunkDefs[id];

            StringBuilder sb = new StringBuilder();

            if (chunkDef != null && chunkDef.Description != string.Empty)
            {
                sb.Append(chunkDef.Description);
                sb.Append("\r\n\r\n");
            }
            sb.AppendFormat("Chunk size = {0}\r\n\r\n", chunkSize);

            if (inst != null)
            {
                sb.Append(FileSchema.DumpInstance(inst, string.Empty));
            }

            return sb.ToString();
        }
예제 #4
0
        private StructInstance GetChunkInstance(BinaryReader reader, StructElement chunkDef, int chunkSize, StructInstance parent)
        {
            StructInstance inst = null;

            if (chunkDef != null)
            {
                int size = chunkDef.Size;
                if (size != 0)
                {
                    inst = chunkDef.Parse(parent, reader.BaseStream, reader.BaseStream.Position + chunkSize) as StructInstance;
                }
                else
                {
                    inst = chunkDef.Parse(parent, null, 0) as StructInstance;
                }
            }

            return inst;
        }
예제 #5
0
        private StructInstance GetAtomInstance(BinaryReader reader, StructElement atomDef, uint atomSize, StructInstance parent)
        {
            StructInstance inst = null;

            if (atomDef != null)
            {
                int size = atomDef.Size;
                if (size != 0)
                {
                    inst = atomDef.Parse(parent, reader.BaseStream, reader.BaseStream.Position + atomSize - 8) as StructInstance;
                }
                else
                {
                    inst = atomDef.Parse(parent, null, 0) as StructInstance;
                }
            }

            return inst;
        }
예제 #6
0
        private string GetAtomDesc(StructElement atomDef, uint atomSize, StructInstance inst)
        {
            StringBuilder sb = new StringBuilder();

            if (atomDef != null && atomDef.Description != string.Empty)
            {
                sb.Append(atomDef.Description);
                sb.Append("\r\n\r\n");
            }
            sb.AppendFormat("Atom size = {0}\r\n\r\n", atomSize);

            if (inst != null)
            {
                sb.Append(FileSchema.DumpInstance(inst, string.Empty));
            }

            return sb.ToString();
        }
예제 #7
0
        /// <summary>
        /// Create an instance by specified byte array and start position.
        /// </summary>
        public override object Parse(ElementInstance parent, Stream stream, long stopAt)
        {
            StructInstance inst = new StructInstance(parent, Elements);
            if (Elements != null)
            {
                foreach (Element elem in Elements)
                {
                    if (elem.EvalCondition(inst))
                    {
                        if (stream.Position >= stopAt)
                        {
                            break;	// don't read beyond boundary.
                        }

                        object elemInst = elem.Parse(inst, stream, stopAt);
                        // Elements that don't have a name will not be added directly
                        if (elem.Name != null && elem.Name != string.Empty)
                        {
                            inst[elem.Name] = elemInst;
                        }
                    }
                }
            }
            return inst;
        }