/* 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); }
/* 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); }