ffi-chm 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +2 -0
- data/lib/ffi-chm.rb +1 -1
- data/lib/ffi-chm/chm_file.rb +3 -3
- data/lib/ffi-chm/chm_file/aux.rb +103 -3
- data/lib/ffi-chm/com8ble.rb +3 -0
- data/lib/ffi-chm/struct.rb +6 -0
- data/lib/ffi-chm/struct/encint.rb +11 -0
- data/lib/ffi-chm/struct/fulltext_index.rb +84 -0
- data/lib/ffi-chm/struct/fulltext_index/index.rb +16 -0
- data/lib/ffi-chm/struct/fulltext_index/index/index_record.rb +11 -0
- data/lib/ffi-chm/struct/fulltext_index/leaf.rb +17 -0
- data/lib/ffi-chm/struct/fulltext_index/leaf/leaf_record.rb +16 -0
- data/lib/ffi-chm/struct/hhx_document.rb +1 -1
- data/lib/ffi-chm/struct/sr.rb +30 -0
- data/lib/ffi-chm/struct/system.rb +11 -8
- data/lib/ffi-chm/struct/system/{record.rb → system_record.rb} +1 -1
- data/lib/ffi-chm/struct/topics.rb +27 -0
- data/lib/ffi-chm/struct/topics/topics_record.rb +24 -0
- data/lib/ffi-chm/struct/url_string.rb +7 -0
- data/lib/ffi-chm/struct/url_table.rb +6 -0
- data/lib/ffi-chm/struct/url_table/url_table_block.rb +8 -0
- data/lib/ffi-chm/struct/url_table/url_table_record.rb +9 -0
- data/lib/ffi-chm/struct/wlc.rb +16 -0
- data/test/test_sr.rb +54 -0
- metadata +28 -12
data/README.txt
CHANGED
@@ -10,6 +10,7 @@ Ruby bindings for the libchm via FFI.
|
|
10
10
|
|
11
11
|
* Provides basic access to the CHM files.
|
12
12
|
* Some functionalities to access to internal structure.
|
13
|
+
* Fulltext search.
|
13
14
|
* Currently developed on MRI 1.8.7 / 1.9.2
|
14
15
|
|
15
16
|
== SYNOPSIS:
|
@@ -25,6 +26,7 @@ Ruby bindings for the libchm via FFI.
|
|
25
26
|
* Ruby
|
26
27
|
* libffi
|
27
28
|
* libchm
|
29
|
+
* Nokogiri >= 1.5.0
|
28
30
|
|
29
31
|
== INSTALL:
|
30
32
|
|
data/lib/ffi-chm.rb
CHANGED
data/lib/ffi-chm/chm_file.rb
CHANGED
@@ -47,6 +47,7 @@ module FFI::Chm
|
|
47
47
|
if UnitInfo === ui
|
48
48
|
buf = FFI::Buffer.new ui[:length]
|
49
49
|
API.chm_retrieve_object @h, ui, buf, 0, ui[:length]
|
50
|
+
# use read_string for JRuby
|
50
51
|
buf.read_bytes buf.size
|
51
52
|
else
|
52
53
|
retrieve_object resolve_object(ui)
|
@@ -55,13 +56,12 @@ module FFI::Chm
|
|
55
56
|
raise RetrieveError, ui
|
56
57
|
end
|
57
58
|
|
58
|
-
require 'enumerator'
|
59
59
|
def enumerate(*what, &block)
|
60
60
|
if block_given?
|
61
61
|
API.chm_enumerate @h, to_flags(what), enum_func(&block), nil
|
62
62
|
self
|
63
63
|
else
|
64
|
-
|
64
|
+
Com8ble::Enumerator.new self, :enumerate, to_flags(what)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -70,7 +70,7 @@ module FFI::Chm
|
|
70
70
|
API.chm_enumerate_dir @h, prefix, to_flags(what), enum_func(&block), nil
|
71
71
|
self
|
72
72
|
else
|
73
|
-
|
73
|
+
Com8ble::Enumerator.new self, :enumerate_dir, prefix, to_flags(what)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
data/lib/ffi-chm/chm_file/aux.rb
CHANGED
@@ -4,8 +4,16 @@ require 'ffi-chm/com8ble'
|
|
4
4
|
module FFI::Chm::ChmFile::Aux
|
5
5
|
include FFI::Chm
|
6
6
|
|
7
|
+
# /#SYSTEM
|
7
8
|
def system
|
8
|
-
@system ||= Struct::System.new.read
|
9
|
+
@system ||= Struct::System.new.read retrieve_object("/#SYSTEM")
|
10
|
+
end
|
11
|
+
|
12
|
+
# /#TOPICS
|
13
|
+
def topics
|
14
|
+
@topics ||= Struct::Topics.new.read retrieve_object("/#TOPICS")
|
15
|
+
@topics.set_context self
|
16
|
+
@topics
|
9
17
|
end
|
10
18
|
|
11
19
|
def encoding
|
@@ -18,7 +26,7 @@ module FFI::Chm::ChmFile::Aux
|
|
18
26
|
|
19
27
|
def contents(cache=true)
|
20
28
|
return @contents if @contents
|
21
|
-
xml =
|
29
|
+
xml = retrieve_object("/#{self.system.record(6).data.compiled_file}.hhc").com8ble.force_encoding(encoding).encode("UTF-8")
|
22
30
|
doc = Struct::HHXDocument.new(Struct::HHC::Entry)
|
23
31
|
Nokogiri::HTML::SAX::Parser.new(doc).parse(xml)
|
24
32
|
|
@@ -29,11 +37,103 @@ module FFI::Chm::ChmFile::Aux
|
|
29
37
|
|
30
38
|
def index(cache=true)
|
31
39
|
return @index if @index
|
32
|
-
xml =
|
40
|
+
xml = retrieve_object("/#{self.system.record(6).data.compiled_file}.hhk").com8ble.force_encoding(encoding).encode("UTF-8")
|
33
41
|
doc = Struct::HHXDocument.new(Struct::HHK::Entry)
|
34
42
|
Nokogiri::HTML::SAX::Parser.new(doc).parse(xml)
|
35
43
|
doc.root.flatten.tap do |v|
|
36
44
|
@index = v if cache
|
37
45
|
end
|
38
46
|
end
|
47
|
+
|
48
|
+
# /$FIftiMain
|
49
|
+
def fulltext_index
|
50
|
+
@fulltext_index ||= Struct::FulltextIndex.new.read retrieve_object("/$FIftiMain")
|
51
|
+
end
|
52
|
+
|
53
|
+
# /#STRINGS
|
54
|
+
def string(offset)
|
55
|
+
@string ||= {}
|
56
|
+
if @string.has_key? offset
|
57
|
+
@string[offset]
|
58
|
+
else
|
59
|
+
io = StringIO.new raw_strings
|
60
|
+
io.seek offset
|
61
|
+
@string[offset] = BinData::Stringz.new.read(io).to_s.com8ble.force_encoding(encoding).encode("UTF-8")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# /#URLTBL
|
66
|
+
def url_table(offset)
|
67
|
+
io = StringIO.new raw_urltbl
|
68
|
+
io.seek offset
|
69
|
+
Struct::URLTable::URLTableRecord.new.read(io)
|
70
|
+
end
|
71
|
+
|
72
|
+
# /#URLSTR
|
73
|
+
def url_string(offset)
|
74
|
+
io = StringIO.new raw_urlstr
|
75
|
+
io.seek offset
|
76
|
+
FFI::Chm::Struct::URLString.new.read io
|
77
|
+
end
|
78
|
+
|
79
|
+
def fulltext_search(pattern, options={}, &block)
|
80
|
+
pattern = pattern.com8ble.force_encoding('UTF-8').encode(self.encoding).force_encoding("ASCII-8BIT")
|
81
|
+
context =
|
82
|
+
case options[:context]
|
83
|
+
when :title
|
84
|
+
0
|
85
|
+
when :body
|
86
|
+
1
|
87
|
+
end
|
88
|
+
|
89
|
+
case fulltext_index.depth.to_i
|
90
|
+
when 1
|
91
|
+
search_inner_prefix fulltext_index.root.to_a, pattern, context, &block
|
92
|
+
when 2
|
93
|
+
search_inner_prefix fulltext_index.root.records, pattern, context, &block
|
94
|
+
else
|
95
|
+
raise "Index tree is too deep(#{fulltext_index.depth})."
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
def raw_strings
|
101
|
+
@strings ||= retrieve_object("/#STRINGS").freeze
|
102
|
+
end
|
103
|
+
|
104
|
+
def raw_urltbl
|
105
|
+
@urltbl ||= retrieve_object("/#URLTBL").freeze
|
106
|
+
end
|
107
|
+
|
108
|
+
def raw_urlstr
|
109
|
+
@urlstr ||= retrieve_object("/#URLSTR").freeze
|
110
|
+
end
|
111
|
+
|
112
|
+
def search_inner_prefix(records, pattern, context, &block)
|
113
|
+
word = ""
|
114
|
+
records.each do |r|
|
115
|
+
word = word[0, r.position] + r.word
|
116
|
+
len = pattern.length
|
117
|
+
#len = [pattern.length, word.length].min
|
118
|
+
comp = word[0, len] <=> pattern[0, len]
|
119
|
+
|
120
|
+
case r
|
121
|
+
when Struct::FulltextIndex::Leaf::LeafRecord
|
122
|
+
case comp
|
123
|
+
when -1
|
124
|
+
next
|
125
|
+
when 1
|
126
|
+
break
|
127
|
+
else
|
128
|
+
next if context && context == r.context
|
129
|
+
#block.call fulltext_index.wlcs(r) if context == r.context
|
130
|
+
block.call r
|
131
|
+
end
|
132
|
+
when Struct::FulltextIndex::Index::IndexRecord
|
133
|
+
next if comp == -1
|
134
|
+
search_inner_prefix(fulltext_index.leaf(r.offset_of_leaf).records, pattern, context, &block)
|
135
|
+
break if comp == 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
39
139
|
end
|
data/lib/ffi-chm/com8ble.rb
CHANGED
data/lib/ffi-chm/struct.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
require 'bindata'
|
2
2
|
|
3
3
|
module FFI::Chm::Struct
|
4
|
+
autoload :FulltextIndex, 'ffi-chm/struct/fulltext_index'
|
5
|
+
autoload :Topics, 'ffi-chm/struct/topics'
|
4
6
|
autoload :System, 'ffi-chm/struct/system'
|
5
7
|
autoload :HHK, 'ffi-chm/struct/hhk/entry'
|
6
8
|
autoload :HHC, 'ffi-chm/struct/hhc/entry'
|
7
9
|
autoload :HHXDocument, 'ffi-chm/struct/hhx_document'
|
10
|
+
autoload :URLTable, 'ffi-chm/struct/url_table'
|
11
|
+
autoload :URLString, 'ffi-chm/struct/url_string'
|
12
|
+
autoload :SR, 'ffi-chm/struct/sr'
|
13
|
+
autoload :WLC, 'ffi-chm/struct/wlc'
|
8
14
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class FFI::Chm::Struct::FulltextIndex < BinData::Record
|
2
|
+
endian :little
|
3
|
+
|
4
|
+
hide :unknown1, :unknown2, :unknown3, :unknown4, :unknown5, :unknown6, :unknown7, :unknown8, :unknown9, :unknown10, :rest
|
5
|
+
hide :document_scale, :code_count_scale, :location_code_scale
|
6
|
+
|
7
|
+
uint32 :unknown1
|
8
|
+
uint32 :num_files
|
9
|
+
uint32 :offset_to_root
|
10
|
+
uint32 :unknown2, :check_value => 0
|
11
|
+
uint32 :num_nodes
|
12
|
+
uint32 :unknown3, :check_value => :offset_to_root
|
13
|
+
uint16 :depth
|
14
|
+
uint32 :unknown4
|
15
|
+
uint8 :document_scale
|
16
|
+
uint8 :document_root
|
17
|
+
uint8 :code_count_scale
|
18
|
+
uint8 :code_count_root
|
19
|
+
uint8 :location_code_scale
|
20
|
+
uint8 :location_code_root
|
21
|
+
string :unknown5, :read_length => 10
|
22
|
+
uint32 :node_size
|
23
|
+
uint32 :unknown6
|
24
|
+
uint32 :word_index_of_last_duplicate
|
25
|
+
uint32 :char_index_of_last_duplicate
|
26
|
+
uint32 :longest_word
|
27
|
+
uint32 :num_words
|
28
|
+
uint32 :num_unique_words
|
29
|
+
uint32 :length_of_words1
|
30
|
+
uint32 :length_of_words2
|
31
|
+
uint32 :length_of_unique_words
|
32
|
+
uint32 :length_of_null_bytes
|
33
|
+
uint32 :unknown7
|
34
|
+
uint32 :unknown8
|
35
|
+
string :unknown9, :read_length => 24
|
36
|
+
|
37
|
+
# http://en.wikipedia.org/wiki/Windows_code_page
|
38
|
+
uint32 :codepage
|
39
|
+
|
40
|
+
# http://msdn.microsoft.com/en-us/library/0h88fahh.aspx
|
41
|
+
uint32 :lcid
|
42
|
+
string :unknown10, :read_length => 894
|
43
|
+
|
44
|
+
rest :rest
|
45
|
+
|
46
|
+
require 'ffi-chm/struct/fulltext_index/leaf'
|
47
|
+
require 'ffi-chm/struct/fulltext_index/index'
|
48
|
+
|
49
|
+
def nodedata(offset, size=node_size)
|
50
|
+
rest[offset - 1024, size]
|
51
|
+
end
|
52
|
+
|
53
|
+
def leaf(offset)
|
54
|
+
FFI::Chm::Struct::FulltextIndex::Leaf.new.read(self.nodedata(offset))
|
55
|
+
end
|
56
|
+
|
57
|
+
def single_leaf?
|
58
|
+
self.depth == 1
|
59
|
+
end
|
60
|
+
|
61
|
+
def root
|
62
|
+
@root ||= (single_leaf? ? Leaf : Index).new.read(self.nodedata(self.offset_to_root))
|
63
|
+
end
|
64
|
+
|
65
|
+
def wlc_params
|
66
|
+
{
|
67
|
+
:document_root => self.document_root,
|
68
|
+
:code_count_root => self.code_count_root,
|
69
|
+
:location_code_root => self.location_code_root
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def wlcs(leaf)
|
74
|
+
@wlcs ||= {}
|
75
|
+
if @wlcs.has_key? leaf.offset_of_wlcs
|
76
|
+
@wlcs[leaf.offset_of_wlcs]
|
77
|
+
else
|
78
|
+
data = BinData::IO.new self.nodedata(leaf.offset_of_wlcs, leaf.length_of_wlcs)
|
79
|
+
@wlcs[leaf.offset_of_wlcs] = leaf.num_wlcs.times.map do
|
80
|
+
FFI::Chm::Struct::WLC.new(self.wlc_params).read(data)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class FFI::Chm::Struct::FulltextIndex::Index < BinData::Record
|
2
|
+
endian :little
|
3
|
+
|
4
|
+
uint16 :freespace
|
5
|
+
|
6
|
+
count_bytes_remaining :bytes_remaining
|
7
|
+
string :rawdata, :read_length => lambda {bytes_remaining - freespace}
|
8
|
+
|
9
|
+
hide :rawdata
|
10
|
+
|
11
|
+
require 'ffi-chm/struct/fulltext_index/index/index_record'
|
12
|
+
|
13
|
+
def records
|
14
|
+
@records ||= BinData::Array.new(:type => :index_record, :read_until => :eof).read self.rawdata
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class FFI::Chm::Struct::FulltextIndex::Index::IndexRecord < BinData::Record
|
2
|
+
endian :little
|
3
|
+
|
4
|
+
uint8 :length_of_word
|
5
|
+
uint8 :position
|
6
|
+
string :word, :read_length => lambda {length_of_word - 1}
|
7
|
+
uint32 :offset_of_leaf
|
8
|
+
uint16 :unknown, :check_value => 0
|
9
|
+
|
10
|
+
hide :length_of_word, :unknown
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class FFI::Chm::Struct::FulltextIndex::Leaf < BinData::Record
|
2
|
+
endian :little
|
3
|
+
|
4
|
+
uint32 :offset_to_next
|
5
|
+
uint16 :unknown, :check_value => 0
|
6
|
+
uint16 :freespace
|
7
|
+
|
8
|
+
hide :rawdata
|
9
|
+
count_bytes_remaining :bytes_remaining
|
10
|
+
string :rawdata, :read_length => lambda {bytes_remaining - freespace}
|
11
|
+
|
12
|
+
require 'ffi-chm/struct/fulltext_index/leaf/leaf_record'
|
13
|
+
|
14
|
+
def records
|
15
|
+
@records ||= BinData::Array.new(:type => :leaf_record, :read_until => :eof).read self.rawdata
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class FFI::Chm::Struct::FulltextIndex::Leaf::LeafRecord < BinData::Record
|
2
|
+
require 'ffi-chm/struct/encint'
|
3
|
+
|
4
|
+
endian :little
|
5
|
+
|
6
|
+
uint8 :length_of_word
|
7
|
+
uint8 :position
|
8
|
+
string :word, :read_length => lambda {length_of_word - 1}
|
9
|
+
uint8 :context # 0: body, 1: title
|
10
|
+
encint :num_wlcs
|
11
|
+
uint32 :offset_of_wlcs
|
12
|
+
uint16 :unknown, :check_value => 0
|
13
|
+
encint :length_of_wlcs
|
14
|
+
|
15
|
+
hide :length_of_word, :unknown
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class FFI::Chm::Struct::SR < BinData::Primitive
|
2
|
+
# s = 2
|
3
|
+
mandatory_parameter :r
|
4
|
+
|
5
|
+
array :prefix, :type => :bit1, :read_until => lambda { element.zero? }
|
6
|
+
array :bits, :type => :bit1, :initial_length => :num_bits
|
7
|
+
|
8
|
+
def num_bits
|
9
|
+
eval_parameter(:r) + [0, prefix.size - 2].max
|
10
|
+
end
|
11
|
+
|
12
|
+
def get
|
13
|
+
size = prefix.size
|
14
|
+
ret = bits.inject(0){|r, v| r << 1 | v}
|
15
|
+
ret += 2 << (eval_parameter(:r) + size - 3) if size > 1
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
module Shortcut
|
20
|
+
def prefix
|
21
|
+
@struct[:prefix]
|
22
|
+
end
|
23
|
+
|
24
|
+
def bits
|
25
|
+
@struct[:bits]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
include Shortcut
|
30
|
+
end
|
@@ -1,23 +1,26 @@
|
|
1
1
|
class FFI::Chm::Struct::System < BinData::Record
|
2
|
-
|
2
|
+
class NoRecordError < StandardError;end
|
3
|
+
|
4
|
+
require 'ffi-chm/struct/system/system_record'
|
3
5
|
|
4
6
|
endian :little
|
5
7
|
|
6
8
|
uint32 :version
|
7
|
-
array :records, :type => :
|
9
|
+
array :records, :type => :system_record, :read_until => :eof
|
8
10
|
|
9
11
|
|
10
12
|
def record(code)
|
11
13
|
@memo ||= Hash[*records.map{|v|[v.code.to_i, v]}.flatten]
|
14
|
+
raise NoRecordError, "/#SYSTEM has no record code:#{code}" unless @memo.has_key? code
|
12
15
|
@memo[code]
|
13
16
|
end
|
14
17
|
|
18
|
+
LCID2ENCODING = {
|
19
|
+
1041 => "CP932", # SJIS
|
20
|
+
2052 => "CP936" # GB2313
|
21
|
+
}
|
22
|
+
|
15
23
|
def encoding
|
16
|
-
|
17
|
-
when 1041
|
18
|
-
"CP932"
|
19
|
-
else
|
20
|
-
"UTF-8"
|
21
|
-
end
|
24
|
+
LCID2ENCODING[self.record(4).data.lcid.to_i] || "CP1252" # ANSI
|
22
25
|
end
|
23
26
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class FFI::Chm::Struct::Topics < BinData::Record
|
2
|
+
require 'ffi-chm/struct/topics/topics_record'
|
3
|
+
|
4
|
+
rest :rawdata
|
5
|
+
|
6
|
+
def records
|
7
|
+
Com8ble::Enumerator.new self, :each_record
|
8
|
+
end
|
9
|
+
|
10
|
+
def each_record
|
11
|
+
(rawdata.size >> 4).times do |i|
|
12
|
+
yield record(i)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def record(index)
|
17
|
+
io = StringIO.new rawdata
|
18
|
+
io.seek index << 4
|
19
|
+
r = TopicsRecord.new.read io
|
20
|
+
r.set_context @chm
|
21
|
+
r
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_context(chm)# :nodoc:
|
25
|
+
@chm = chm
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class FFI::Chm::Struct::Topics::TopicsRecord < BinData::Record
|
2
|
+
endian :little
|
3
|
+
|
4
|
+
uint32 :offset_in_tocidx
|
5
|
+
uint32 :offset_in_strings
|
6
|
+
uint32 :offset_in_urltbl
|
7
|
+
uint16 :in_contents # 2: not in contents, 6: in contents
|
8
|
+
uint16 :unknown
|
9
|
+
|
10
|
+
hide :unknown
|
11
|
+
|
12
|
+
def title
|
13
|
+
@chm.string(offset_in_strings) rescue nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def local
|
17
|
+
table = @chm.url_table(offset_in_urltbl)
|
18
|
+
@chm.url_string(table.offset_in_urlstr).local
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_context(chm)# :nodoc:
|
22
|
+
@chm = chm
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class FFI::Chm::Struct::WLC < BinData::Record
|
2
|
+
require 'ffi-chm/struct/sr'
|
3
|
+
|
4
|
+
mandatory_parameter :document_root, :code_count_root, :location_code_root
|
5
|
+
|
6
|
+
sr :document_index, :r => :document_root
|
7
|
+
sr :code_count, :r => :code_count_root
|
8
|
+
|
9
|
+
array :locations, :initial_length => :code_count do
|
10
|
+
sr :location_code, :r => :location_code_root
|
11
|
+
end
|
12
|
+
|
13
|
+
hide :code_count
|
14
|
+
|
15
|
+
resume_byte_alignment
|
16
|
+
end
|
data/test/test_sr.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "ffi-chm"
|
3
|
+
|
4
|
+
class TestSR < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@testset = [
|
7
|
+
[2, 3, '011----'],
|
8
|
+
[2, 4, '1000----'],
|
9
|
+
[3, 0, '0000----'],
|
10
|
+
[3, 1, '0001----'],
|
11
|
+
[3, 2, '0010----'],
|
12
|
+
[3, 7, '0111----'],
|
13
|
+
[3, 8, '10000---'],
|
14
|
+
[3, 9, '10001---'],
|
15
|
+
[3, 10, '10010---'],
|
16
|
+
[3, 15, '10111---'],
|
17
|
+
[3, 16, '1100000-'],
|
18
|
+
[3, 17, '1100001-'],
|
19
|
+
[3, 18, '1100010-'],
|
20
|
+
[3, 30, '1101110-'],
|
21
|
+
[3, 31, '1101111-'],
|
22
|
+
[3, 32, '111000000-------'],
|
23
|
+
[3, 33, '111000001-------'],
|
24
|
+
[3, 34, '111000010-------'],
|
25
|
+
[3, 62, '111011110-------'],
|
26
|
+
[3, 63, '111011111-------'],
|
27
|
+
[3, 64, '11110000000-----'],
|
28
|
+
[5, 31, '011111----------'],
|
29
|
+
[5, 63, '1011111----------'],
|
30
|
+
[5, 512, '111110000000000-']
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_sr
|
35
|
+
@testset.each{|set|set.last.gsub!('-', '0')}
|
36
|
+
@testset.each do |r, expect, bits|
|
37
|
+
sr = FFI::Chm::Struct::SR.new(:r => r).read [bits].pack("B*")
|
38
|
+
assert_equal expect, sr.get
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_sr_byte_aligned
|
43
|
+
@testset.each{|set|set.last.delete!('-')}
|
44
|
+
|
45
|
+
rs, expects, bits = @testset.transpose
|
46
|
+
bits = bits.join
|
47
|
+
bits += "0" * bits.size % 8
|
48
|
+
wlcs = BinData::IO.new [bits].pack("B*")
|
49
|
+
|
50
|
+
values = rs.map{|r| FFI::Chm::Struct::SR.new(:r => r).read(wlcs)}
|
51
|
+
|
52
|
+
assert_equal expects, values
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-chm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-09-09 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
16
|
-
requirement: &
|
16
|
+
requirement: &70226425573140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70226425573140
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bindata
|
27
|
-
requirement: &
|
27
|
+
requirement: &70226425572700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,21 +32,21 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70226425572700
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: nokogiri
|
38
|
-
requirement: &
|
38
|
+
requirement: &70226425572120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
version: 1.5.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70226425572120
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: hoe
|
49
|
-
requirement: &
|
49
|
+
requirement: &70226425571580 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '2.10'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70226425571580
|
58
58
|
description: Ruby bindings for the libchm via FFI.
|
59
59
|
email:
|
60
60
|
- nanki@dotswitch.net
|
@@ -69,17 +69,32 @@ files:
|
|
69
69
|
- lib/ffi-chm/chm_file.rb
|
70
70
|
- lib/ffi-chm/com8ble.rb
|
71
71
|
- lib/ffi-chm/const.rb
|
72
|
+
- lib/ffi-chm/struct/encint.rb
|
73
|
+
- lib/ffi-chm/struct/fulltext_index/index/index_record.rb
|
74
|
+
- lib/ffi-chm/struct/fulltext_index/index.rb
|
75
|
+
- lib/ffi-chm/struct/fulltext_index/leaf/leaf_record.rb
|
76
|
+
- lib/ffi-chm/struct/fulltext_index/leaf.rb
|
77
|
+
- lib/ffi-chm/struct/fulltext_index.rb
|
72
78
|
- lib/ffi-chm/struct/hhc/entry.rb
|
73
79
|
- lib/ffi-chm/struct/hhk/entry.rb
|
74
80
|
- lib/ffi-chm/struct/hhx_document.rb
|
81
|
+
- lib/ffi-chm/struct/sr.rb
|
75
82
|
- lib/ffi-chm/struct/system/code3.rb
|
76
83
|
- lib/ffi-chm/struct/system/code4.rb
|
77
84
|
- lib/ffi-chm/struct/system/code6.rb
|
78
|
-
- lib/ffi-chm/struct/system/
|
85
|
+
- lib/ffi-chm/struct/system/system_record.rb
|
79
86
|
- lib/ffi-chm/struct/system.rb
|
87
|
+
- lib/ffi-chm/struct/topics/topics_record.rb
|
88
|
+
- lib/ffi-chm/struct/topics.rb
|
89
|
+
- lib/ffi-chm/struct/url_string.rb
|
90
|
+
- lib/ffi-chm/struct/url_table/url_table_block.rb
|
91
|
+
- lib/ffi-chm/struct/url_table/url_table_record.rb
|
92
|
+
- lib/ffi-chm/struct/url_table.rb
|
93
|
+
- lib/ffi-chm/struct/wlc.rb
|
80
94
|
- lib/ffi-chm/struct.rb
|
81
95
|
- lib/ffi-chm/unit_info.rb
|
82
96
|
- lib/ffi-chm.rb
|
97
|
+
- test/test_sr.rb
|
83
98
|
- test/test_ffi_chm.rb
|
84
99
|
- .gemtest
|
85
100
|
homepage: http://github.com/nanki/ffi-chm
|
@@ -110,3 +125,4 @@ specification_version: 3
|
|
110
125
|
summary: Ruby bindings for the libchm via FFI.
|
111
126
|
test_files:
|
112
127
|
- test/test_ffi_chm.rb
|
128
|
+
- test/test_sr.rb
|