/* 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; }
private static extern int chm_enumerate(IntPtr raw, ChmEnumerate what, ChmEnumerator e, IntPtr context);
/* 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); }