private void ReadToc(Stream st)
        {
            XmlTextReader xmlReader = new XmlTextReader (st);
            ArrayList nodeL = new ArrayList ();
            ArrayList pathList = new ArrayList ();
            XarArchiveEntry ce = null;

            while (xmlReader.Read ())
            {
                string nodeName = "";
                switch (xmlReader.NodeType)
                {
                case XmlNodeType.Element:

                    if (!xmlReader.IsEmptyElement)
                    {
                        nodeL.Add (xmlReader.Name);
                    }

                    nodeName = xmlReader.Name;
                    Hashtable attributes = ReadAttributes(xmlReader);
                    if (nodeName.Equals ("file")) {
                        ce = new XarArchiveEntry ();
                        ce.Id = long.Parse((string) attributes["id"]);
                        entryList.Add(ce);
                    }
                    else if (nodeName.Equals("encoding")){
                        if ("application/x-gzip".Equals(attributes["style"])){
                            ce.Encoding = XarEncoding.Gzip;
                        }
                        else if ("application/x-bzip2".Equals(attributes["style"])){
                            ce.Encoding = XarEncoding.Bzip2;
                        }
                        else if("application/octet-stream".Equals(attributes["style"])){
                            ce.Encoding = XarEncoding.None;
                        }
                        else {
                            throw new IOException ("Unsupported file encoding " + attributes["style"]);
                        }
                    }
                    else if (nodeName.Equals("archived-checksum")){
                        if ("SHA1".Equals (attributes["style"])) {
                            ce.HashAlgorithmArchived = XarHashAlgorithm.Sha1;
                        } else if ("MD5".Equals (attributes["style"])) {
                            ce.HashAlgorithmArchived = XarHashAlgorithm.Md5;
                        }
                        else {
                            throw new IOException ("Unsupported archived checksum " + attributes["style"]);
                        }
                    }
                    else if (nodeName.Equals ("extracted-checksum")) {
                        if ("SHA1".Equals (attributes["style"])) {
                            ce.HashAlgorithmExtracted = XarHashAlgorithm.Sha1;
                        } else if ("MD5".Equals (attributes["style"])) {
                            ce.HashAlgorithmExtracted = XarHashAlgorithm.Md5;
                        } else {
                            throw new IOException ("Unsupported extracted checksum " + attributes["style"]);
                        }
                    }
                    break;
                case XmlNodeType.EndElement:

                    nodeL.RemoveAt (nodeL.Count - 1);
                    if (xmlReader.Name.Equals("file")){
                        pathList.RemoveAt(pathList.Count -1);
                    }

                    break;
                case XmlNodeType.Text:
                    nodeName = (string)nodeL[nodeL.Count-1];
                    string val = xmlReader.Value;
                    if (nodeName.Equals("length")){
                        ce.Length = long.Parse(val);
                    }
                    else if (nodeName.Equals("offset")){
                        if (!"checksum".Equals(nodeL[nodeL.Count-2])){
                            ce.Offset = long.Parse(val);
                        }
                        else {
                            this.tocHashOffset = long.Parse(val);
                        }
                    }
                    else if (nodeName.Equals ("size")) {
                        if (!"checksum".Equals(nodeL[nodeL.Count-2])){
                            ce.Size = long.Parse(val);
                        }
                        else {
                            this.tocHashSize = long.Parse (val);
                        }
                    }
                    else if (nodeName.Equals ("archived-checksum")) {
                        ce.ArchivedChecksum = val;
                    }
                    else if (nodeName.Equals ("extracted-checksum")) {
                        ce.ExtractedChecksum = val;
                    }
                    else if (nodeName.Equals ("group")) {
                        ce.Group = val;
                    }
                    else if (nodeName.Equals ("gid")) {
                        ce.Gid = Int32.Parse(val);
                    }
                    else if (nodeName.Equals ("user")) {
                        ce.User = val;
                    }
                    else if (nodeName.Equals ("uid")) {
                        ce.Uid = Int32.Parse(val);
                    }
                    else if (nodeName.Equals ("")) {

                    }
                    else if (nodeName.Equals ("type")) {
                        if ("directory".Equals(val)){
                            ce.IsDirectory = true;
                        }
                        else if ("file".Equals(val) || "script".Equals(val)) {
                            ce.IsDirectory = false;
                        }
                        else {
                            throw new IOException("Unsupported file type " + val);
                        }
                    }
                    else if (nodeName.Equals ("name")) {
                        StringBuilder sb = new StringBuilder();
                        foreach (string s in pathList)
                        {
                            sb.Append(s);
                            sb.Append(Path.DirectorySeparatorChar);
                        }
                        sb.Append(val);
                        pathList.Add(val);
                        ce.Name = sb.ToString();
                    }
                    break;
                default:

                    break;

                }
            }
            st.Close();
        }
        public XarArchiveEntry GetNextXarEntry()
        {
            if (dataStream != null) {
                while (this.Read (tmpBuffer) > 0) {
                }
                dataStream.Close ();
            }
            dataStream = null;

            if (entryCursor >= entryList.Count) {
                return null;
            }
            this.currentEntry = (XarArchiveEntry)entryList[entryCursor++];
            if (this.currentEntry.IsDirectory) {
                return this.currentEntry;
            }

            Stream s = new SizeLimiterStream (this.inputStream, this.currentEntry.Length);
            if (this.currentEntry.ArchivedChecksum != null) {
                switch (this.currentEntry.HashAlgorithmArchived) {
                case XarHashAlgorithm.Md5:
                    s = new HashStream (s, MD5.Create (), this.currentEntry.ArchivedChecksum);
                    break;
                case XarHashAlgorithm.Sha1:
                    s = new HashStream (s, SHA1.Create (), this.currentEntry.ArchivedChecksum);
                    break;
                default:
                    break;
                }

            }
            switch (this.currentEntry.Encoding) {
            case XarEncoding.None:
                dataStream = s;
                break;
            case XarEncoding.Gzip:
                dataStream = new InflaterInputStream (s, new Inflater (false));
                break;
            case XarEncoding.Bzip2:
                dataStream = new BZip2InputStream (s);
                break;
            default:
                break;
            }
            if (this.currentEntry.ExtractedChecksum != null) {
                switch (this.currentEntry.HashAlgorithmExtracted) {
                case XarHashAlgorithm.Md5:
                    dataStream = new HashStream (dataStream, MD5.Create (), this.currentEntry.ExtractedChecksum);
                    break;
                case XarHashAlgorithm.Sha1:
                    dataStream = new HashStream (dataStream, SHA1.Create (), this.currentEntry.ExtractedChecksum);
                    break;
                default:
                    break;
                }
            }

            return this.currentEntry;
        }