Пример #1
0
        /* resolve a particular object from the archive */
        public bool ResolveObject(string objPath, ref ChmUnitInfo ui)
        {
            /*
             * XXX: implement caching scheme for dir pages
             */

            Int32 curPage;

            /* buffer to hold whatever page we're looking at */
            /* RWE 6/12/2003 */
            byte[] page_buf = new byte[_h.block_len];

            /* starting page */
            curPage = _h.index_root;

            /* until we have either returned or given up */
            while (curPage != -1)
            {
                /* try to fetch the index page */
                if (Storage.FetchBytes(ref _h, ref page_buf,
                                       (UInt64)_h.dir_offset + (UInt64)curPage * _h.block_len,
                                       _h.block_len) != _h.block_len)
                {
                    return(false);
                }

                /* now, if it is a leaf node: */
                if (ASCIIEncoding.UTF8.GetString(page_buf, 0, 4).CompareTo(Pmgl.CHM_PMGL_MARKER) == 0)
                {
                    /* scan block */
                    long pEntry = Pmgl.FindInPmgl(page_buf, _h.block_len, objPath);
                    if (pEntry < 0)
                    {
                        return(false);
                    }

                    /* parse entry and return */
                    uint os = (uint)pEntry;
                    Pmgl.ParsePgmlEntry(page_buf, ref os, ref ui);
                    return(true);
                }

                /* else, if it is a branch node: */
                else if (ASCIIEncoding.UTF8.GetString(page_buf, 0, 4).CompareTo(Pmgi.CHM_PMGI_MARKER) == 0)
                {
                    curPage = Pmgi.FindInPmgi(page_buf, _h.block_len, objPath);
                }

                /* else, we are confused.  give up. */
                else
                {
                    return(false);
                }
            }

            /* didn't find anything.  fail. */
            return(false);
        }
Пример #2
0
        /* enumerate the objects in the .chm archive */
        public bool Enumerate(EnumerateLevel what, ChmEnumerator e, object context)
        {
            Int32 curPage;

            /* buffer to hold whatever page we're looking at */
            /* RWE 6/12/2003 */
            byte[]        page_buf = new byte[_h.block_len];
            chmPmglHeader header   = new chmPmglHeader();
            uint          end;
            uint          cur;
            uint          lenRemain;
            UInt64        ui_path_len;

            /* the current ui */
            ChmUnitInfo ui          = new ChmUnitInfo();
            int         type_bits   = ((int)what & 0x7);
            int         filter_bits = ((int)what & 0xF8);

            /* starting page */
            curPage = _h.index_head;

            /* until we have either returned or given up */
            while (curPage != -1)
            {
                /* try to fetch the index page */
                if (Storage.FetchBytes(ref _h,
                                       ref page_buf,
                                       (UInt64)_h.dir_offset + (UInt64)curPage * _h.block_len,
                                       _h.block_len) != _h.block_len)
                {
                    return(false);
                }

                /* figure out start and end for this page */
                cur       = 0;
                lenRemain = Pmgl.CHM_PMGL_LEN;
                if (!Pmgl.UnmarshalPmglHeader(ref page_buf, ref cur, ref lenRemain, ref header))
                {
                    return(false);
                }
                end = _h.block_len - (header.free_space);

                /* loop over this page */
                while (cur < end)
                {
                    ui.flags = 0;

                    if (!Pmgl.ParsePgmlEntry(page_buf, ref cur, ref ui))
                    {
                        return(false);
                    }

                    /* get the length of the path */
                    ui_path_len = (ulong)ui.path.Length;

                    /* check for DIRS */
                    if (ui.path.EndsWith("/"))
                    {
                        ui.flags |= (int)EnumerateLevel.Directories;
                    }

                    /* check for FILES */
                    if (!ui.path.EndsWith("/"))
                    {
                        ui.flags |= (int)EnumerateLevel.Files;
                    }

                    /* check for NORMAL vs. META */
                    if (ui.path.StartsWith("/"))
                    {
                        /* check for NORMAL vs. SPECIAL */
                        if (ui.path.Length > 1 && (ui.path[1] == '#' || ui.path[1] == '$'))
                        {
                            ui.flags |= (int)EnumerateLevel.Special;
                        }
                        else
                        {
                            ui.flags |= (int)EnumerateLevel.Normal;
                        }
                    }
                    else
                    {
                        ui.flags |= (int)EnumerateLevel.Meta;
                    }

                    if (!Convert.ToBoolean(type_bits & ui.flags))
                    {
                        continue;
                    }

                    if (filter_bits != 0 && (filter_bits & ui.flags) == 0)
                    {
                        continue;
                    }

                    /* call the enumerator */
                    EnumerateStatus status = e(this, ui, context);
                    switch (status)
                    {
                    case EnumerateStatus.Failure:
                        return(false);

                    case EnumerateStatus.Continue:
                        break;

                    case EnumerateStatus.Success:
                        return(true);

                    default:
                        break;
                    }
                }

                /* advance to next page */
                curPage = header.block_next;
            }

            return(true);
        }