Пример #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
        /* find an exact entry in PMGL; return NULL if we fail */
        public static long FindInPmgl(byte[] page_buf, UInt32 block_len, string objPath)
        {
            /* XXX: modify this to do a binary search using the nice index structure
             *      that is provided for us.
             */
            chmPmglHeader header = new chmPmglHeader();
            uint          hremain;
            uint          end;
            uint          cur;
            uint          temp;
            UInt64        strLen;

            char[] buffer = new char[Storage.CHM_MAX_PATHLEN];

            /* figure out where to start and end */
            cur     = 0;
            hremain = CHM_PMGL_LEN;
            if (!UnmarshalPmglHeader(ref page_buf, ref cur, ref hremain, ref header))
            {
                return(-1);
            }
            end = block_len - (header.free_space);

            /* now, scan progressively */
            while (cur < end)
            {
                /* grab the name */
                temp   = cur;
                strLen = Storage.ParseCWord(page_buf, ref cur);
                if (strLen > Storage.CHM_MAX_PATHLEN)
                {
                    return(-1);
                }
                if (!Storage.ParseUTF8(page_buf, ref cur, strLen, ref buffer))
                {
                    return(-1);
                }

                /* check if it is the right name */
                if (Pmgi.strcasecmp(new String(buffer), objPath) == 0)
                {
                    return((long)temp);
                }

                SkipPmglEntryData(page_buf, ref cur);
            }

            return(-1);
        }