Class: Cabriolet::HLP::WinHelp::BTreeBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/cabriolet/hlp/winhelp/btree_builder.rb

Overview

B+ tree builder for WinHelp 4.x directory format

Builds B+ tree directory structure for WinHelp 4.x files. The directory maps filenames to file offsets using a B+ tree with fixed-size pages.

Constant Summary collapse

DEFAULT_PAGE_SIZE =

Default page size for WinHelp 4.x directory (1KB for catalog/directory)

0x0400
PAGE_TYPE_LEAF =

Page types

0
PAGE_TYPE_INDEX =
1
BTREE_MAGIC =

B+ tree magic number

0x293B
FLAGS_MAGIC_BIT =

Flags for B+ tree header Bit 0x0002 is always 1 Bit 0x0400 is 1 for catalog/directory

0x0002
FLAGS_CATALOG_BIT =
0x0400

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(page_size: DEFAULT_PAGE_SIZE, structure: "FFz") ⇒ BTreeBuilder

Initialize B+ tree builder

Parameters:

  • page_size (Integer) (defaults to: DEFAULT_PAGE_SIZE)

    Page size in bytes (default: 1KB)

  • structure (String) (defaults to: "FFz")

    Structure string describing data format



37
38
39
40
41
# File 'lib/cabriolet/hlp/winhelp/btree_builder.rb', line 37

def initialize(page_size: DEFAULT_PAGE_SIZE, structure: "FFz")
  @page_size = page_size
  @structure = structure
  @entries = []
end

Instance Attribute Details

#page_sizeObject (readonly)

Returns the value of attribute page_size.



31
32
33
# File 'lib/cabriolet/hlp/winhelp/btree_builder.rb', line 31

def page_size
  @page_size
end

#structureObject (readonly)

Returns the value of attribute structure.



31
32
33
# File 'lib/cabriolet/hlp/winhelp/btree_builder.rb', line 31

def structure
  @structure
end

Instance Method Details

#add_entry(filename, offset, size) ⇒ Object

Add a file entry to the B+ tree

Parameters:

  • filename (String)

    Internal filename (e.g., "|SYSTEM")

  • offset (Integer)

    File offset in help file

  • size (Integer)

    File size in bytes



48
49
50
# File 'lib/cabriolet/hlp/winhelp/btree_builder.rb', line 48

def add_entry(filename, offset, size)
  @entries << { filename: filename, offset: offset, size: size }
end

#buildHash

Build B+ tree structure

Returns:

  • (Hash)

    Hash containing :header, :pages



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/cabriolet/hlp/winhelp/btree_builder.rb', line 55

def build
  return build_empty if @entries.empty?

  # Sort entries by filename
  sorted_entries = @entries.sort_by { |e| e[:filename] }

  # Build leaf pages
  leaf_pages = build_leaf_pages(sorted_entries)

  # Build index pages if needed
  if leaf_pages.size > 1
    index_pages = build_index_pages(leaf_pages)
    root_page = index_pages.first[:page_num]
    n_levels = 2
  else
    index_pages = []
    root_page = leaf_pages.first[:page_num]
    n_levels = 1
  end

  # Build B+ tree header
  header = build_header(
    total_pages: leaf_pages.size + index_pages.size,
    root_page: root_page,
    n_levels: n_levels,
    total_entries: @entries.size,
  )

  # Combine all pages
  all_pages = index_pages + leaf_pages

  { header: header, pages: all_pages }
end