mspack_rb 0.1.5 → 0.1.6
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.
- checksums.yaml +4 -4
- data/.gitignore +5 -1
- data/README.md +12 -2
- data/ext/mspack_native/chm_decompressor.c +130 -50
- data/ext/mspack_native/chm_decompressor.h +1 -5
- data/ext/mspack_native/chm_decompressor_file.c +52 -0
- data/ext/mspack_native/chm_decompressor_file.h +8 -0
- data/ext/mspack_native/chm_decompressor_header.c +34 -0
- data/ext/mspack_native/chm_decompressor_header.h +8 -0
- data/ext/mspack_native/mspack_native.c +7 -0
- data/ext/mspack_native/mspack_native.h +3 -0
- data/lib/mspack/chm_decompressor.rb +0 -1
- data/lib/mspack/version.rb +1 -1
- data/lib/mspack.rb +4 -0
- data/mspack.gemspec +9 -5
- metadata +20 -3
- data/lib/mspack_native.bundle +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f9c40d23c5867b56e2fa1b1960fd31309cfa799
|
4
|
+
data.tar.gz: 642ae95857d11d712c584a11b2f20ba0b2daeca3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 508fd382485b88754746f25ff1bae5006a68306c5ced69a141e52c053470a2c89d6014cb8999f2ea7a261f5e9a535eb4cf5fffd40b46322ef013ca0bc7199f68
|
7
|
+
data.tar.gz: 64dd35882e4fa5fbfa80c147ad422ec30d83caf27d89df1ea130ec743d2e2bb02889b64287b9855375ebbda35851bf155f095b66b8dae948a10beb83b6ad564b
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,14 +2,24 @@
|
|
2
2
|
|
3
3
|
### A simple Ruby native extension gem wrapper for [libmspack](https://www.cabextract.org.uk/libmspack/)
|
4
4
|
|
5
|
-
Requires libmspack to be installed, and currently, only
|
6
|
-
|
5
|
+
Requires libmspack to be installed, and currently, only CHM extraction has been
|
6
|
+
implemented.
|
7
7
|
|
8
8
|
The gem is available over at [https://rubygems.org/gems/mspack_rb](https://rubygems.org/gems/mspack_rb).
|
9
9
|
|
10
10
|
### Usage:
|
11
11
|
require 'mspack'
|
12
12
|
|
13
|
+
# Extract all files to disk
|
13
14
|
dcom = Mspack::ChmDecompressor.new
|
14
15
|
header = dcom.open('path/to/a/chm/file')
|
15
16
|
header.each_file { |file| dcom.extract(file, out_path) }
|
17
|
+
dcom.close(header)
|
18
|
+
|
19
|
+
# Extract a specific file by name
|
20
|
+
fast_open_header = dcom.fast_open('path/to/a/chm/file')
|
21
|
+
file = dcom.fast_find(fast_open_header, '/index.html')
|
22
|
+
dcom.extract(file) unless file.nil?
|
23
|
+
|
24
|
+
# check last error
|
25
|
+
p 'w00t' if dcom.last_error == :ok
|
@@ -1,35 +1,109 @@
|
|
1
1
|
#include "chm_decompressor.h"
|
2
|
+
#include "mspack_native.h"
|
3
|
+
#include "chm_decompressor_header.h"
|
4
|
+
#include "chm_decompressor_file.h"
|
2
5
|
|
3
6
|
#include <mspack.h>
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
+
/*
|
9
|
+
* utility methods
|
10
|
+
*/
|
11
|
+
|
12
|
+
static inline VALUE _error_code_sym(int code) {
|
13
|
+
const char *str;
|
14
|
+
|
15
|
+
switch (code) {
|
16
|
+
case MSPACK_ERR_OK:
|
17
|
+
str = "ok";
|
18
|
+
break;
|
19
|
+
case MSPACK_ERR_ARGS:
|
20
|
+
str = "args";
|
21
|
+
break;
|
22
|
+
case MSPACK_ERR_OPEN:
|
23
|
+
str = "open";
|
24
|
+
break;
|
25
|
+
case MSPACK_ERR_READ:
|
26
|
+
str = "read";
|
27
|
+
break;
|
28
|
+
case MSPACK_ERR_WRITE:
|
29
|
+
str = "write";
|
30
|
+
break;
|
31
|
+
case MSPACK_ERR_SEEK:
|
32
|
+
str = "seek";
|
33
|
+
break;
|
34
|
+
case MSPACK_ERR_NOMEMORY:
|
35
|
+
str = "no_memory";
|
36
|
+
break;
|
37
|
+
case MSPACK_ERR_SIGNATURE:
|
38
|
+
str = "signature";
|
39
|
+
break;
|
40
|
+
case MSPACK_ERR_DATAFORMAT:
|
41
|
+
str = "data_format";
|
42
|
+
break;
|
43
|
+
case MSPACK_ERR_CHECKSUM:
|
44
|
+
str = "checksum";
|
45
|
+
break;
|
46
|
+
case MSPACK_ERR_CRUNCH:
|
47
|
+
str = "crunch";
|
48
|
+
break;
|
49
|
+
case MSPACK_ERR_DECRUNCH:
|
50
|
+
str = "decrunch";
|
51
|
+
break;
|
52
|
+
default:
|
53
|
+
str = "unknown";
|
54
|
+
}
|
8
55
|
|
9
|
-
|
10
|
-
mspack_destroy_chm_decompressor(decom);
|
56
|
+
return ID2SYM(rb_intern(str));
|
11
57
|
}
|
12
58
|
|
13
|
-
VALUE
|
14
|
-
|
15
|
-
return Data_Wrap_Struct(self, NULL, chmd_deallocate, decom);
|
16
|
-
}
|
59
|
+
static inline VALUE _open(VALUE self, VALUE path, int fast_bool) {
|
60
|
+
Check_Type(path, T_STRING);
|
17
61
|
|
18
|
-
VALUE chmd_open(VALUE self, VALUE path) {
|
19
62
|
struct mschm_decompressor *decom;
|
20
63
|
Data_Get_Struct(self, struct mschm_decompressor, decom);
|
21
|
-
|
64
|
+
|
65
|
+
struct mschmd_header *header;
|
66
|
+
|
67
|
+
if (fast_bool) {
|
68
|
+
header = decom->fast_open(decom, StringValueCStr(path));
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
header = decom->open(decom, StringValueCStr(path));
|
72
|
+
}
|
22
73
|
|
23
74
|
if (!header) {
|
24
75
|
return Qnil;
|
25
76
|
}
|
26
77
|
|
27
|
-
VALUE headerObj =
|
28
|
-
|
29
|
-
|
78
|
+
VALUE headerObj = Data_Wrap_Struct(ChmDHeader, NULL, NULL, header);
|
79
|
+
VALUE is_fast_open = fast_bool ? Qtrue : Qfalse;
|
80
|
+
rb_iv_set(headerObj, "is_fast_open", is_fast_open);
|
81
|
+
|
82
|
+
return headerObj;
|
83
|
+
}
|
84
|
+
|
85
|
+
/*
|
86
|
+
* decompressor
|
87
|
+
*/
|
88
|
+
|
89
|
+
void chmd_deallocate(void *decom) {
|
90
|
+
mspack_destroy_chm_decompressor(decom);
|
91
|
+
}
|
92
|
+
|
93
|
+
VALUE chmd_allocate(VALUE self) {
|
94
|
+
struct mschm_decompressor *decom = mspack_create_chm_decompressor(NULL);
|
95
|
+
return Data_Wrap_Struct(self, NULL, chmd_deallocate, decom);
|
96
|
+
}
|
97
|
+
|
98
|
+
VALUE chmd_open(VALUE self, VALUE path) {
|
99
|
+
return _open(self, path, 0);
|
30
100
|
}
|
31
101
|
|
32
102
|
VALUE chmd_close(VALUE self, VALUE header) {
|
103
|
+
if (!CLASS_OF(header) == ChmDHeader) {
|
104
|
+
rb_raise(rb_eTypeError, "Parameter must be a CHM decompression header");
|
105
|
+
}
|
106
|
+
|
33
107
|
struct mschm_decompressor *decom;
|
34
108
|
Data_Get_Struct(self, struct mschm_decompressor, decom);
|
35
109
|
|
@@ -41,50 +115,61 @@ VALUE chmd_close(VALUE self, VALUE header) {
|
|
41
115
|
}
|
42
116
|
|
43
117
|
VALUE chmd_extract_to_path(VALUE self, VALUE file, VALUE outputPath) {
|
118
|
+
if (!CLASS_OF(file) == ChmDFile) {
|
119
|
+
rb_raise(rb_eTypeError, "First parameter must be a CHM decompression file");
|
120
|
+
}
|
121
|
+
|
122
|
+
Check_Type(outputPath, T_STRING);
|
123
|
+
|
44
124
|
struct mschm_decompressor *decom;
|
45
125
|
Data_Get_Struct(self, struct mschm_decompressor, decom);
|
46
126
|
|
47
127
|
struct mschmd_file *filePtr;
|
48
128
|
Data_Get_Struct(file, struct mschmd_file, filePtr);
|
49
|
-
|
50
129
|
const char *pathStr = StringValueCStr(outputPath);
|
51
|
-
return decom->extract(decom, filePtr, pathStr) == MSPACK_ERR_OK ?
|
52
|
-
Qtrue : Qfalse;
|
53
|
-
}
|
54
130
|
|
55
|
-
|
56
|
-
|
57
|
-
Data_Get_Struct(self, struct mschmd_header, header);
|
58
|
-
return rb_str_new2(header->filename);
|
131
|
+
int result = decom->extract(decom, filePtr, pathStr);
|
132
|
+
return result == MSPACK_ERR_OK ? Qtrue : Qfalse;
|
59
133
|
}
|
60
134
|
|
61
|
-
VALUE
|
62
|
-
struct
|
63
|
-
Data_Get_Struct(self, struct
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
return Data_Wrap_Struct(ChmDFile, NULL, NULL, header->files);
|
135
|
+
VALUE chmd_last_error(VALUE self) {
|
136
|
+
struct mschm_decompressor *decom;
|
137
|
+
Data_Get_Struct(self, struct mschm_decompressor, decom);
|
138
|
+
|
139
|
+
int error = decom->last_error(decom);
|
140
|
+
return _error_code_sym(error);
|
68
141
|
}
|
69
142
|
|
70
|
-
VALUE
|
71
|
-
|
72
|
-
Data_Get_Struct(self, struct mschmd_file, file);
|
73
|
-
return rb_str_new2(file->filename);
|
143
|
+
VALUE chmd_fast_open(VALUE self, VALUE path) {
|
144
|
+
return _open(self, path, 1);
|
74
145
|
}
|
75
146
|
|
76
|
-
VALUE
|
77
|
-
struct
|
78
|
-
Data_Get_Struct(self, struct
|
79
|
-
|
147
|
+
VALUE chmd_fast_find(VALUE self, VALUE header, VALUE filename) {
|
148
|
+
struct mschm_decompressor *decom;
|
149
|
+
Data_Get_Struct(self, struct mschm_decompressor, decom);
|
150
|
+
|
151
|
+
struct mschmd_header *headerPtr;
|
152
|
+
Data_Get_Struct(header, struct mschmd_header, headerPtr);
|
153
|
+
|
154
|
+
const char *filenameStr = StringValueCStr(filename);
|
80
155
|
|
81
|
-
|
156
|
+
int structSize = sizeof(struct mschmd_file);
|
157
|
+
struct mschmd_file *file = malloc(structSize);
|
158
|
+
|
159
|
+
int result =
|
160
|
+
decom->fast_find(decom, headerPtr, filenameStr, file, structSize);
|
161
|
+
|
162
|
+
if (result != MSPACK_ERR_OK || file->length == 0) {
|
163
|
+
free(file);
|
82
164
|
return Qnil;
|
83
|
-
}
|
165
|
+
}
|
84
166
|
|
85
|
-
|
86
|
-
|
87
|
-
|
167
|
+
file->filename = malloc(sizeof(char) * strlen(filenameStr) + 1);
|
168
|
+
strcpy(file->filename, filenameStr);
|
169
|
+
|
170
|
+
VALUE fileObj = Data_Wrap_Struct(ChmDFile, NULL, NULL, file);
|
171
|
+
rb_iv_set(fileObj, "is_fast_find", Qtrue);
|
172
|
+
return fileObj;
|
88
173
|
}
|
89
174
|
|
90
175
|
void Init_chm_decompressor() {
|
@@ -93,12 +178,7 @@ void Init_chm_decompressor() {
|
|
93
178
|
rb_define_method(ChmDecom, "open", chmd_open, 1);
|
94
179
|
rb_define_method(ChmDecom, "close", chmd_close, 1);
|
95
180
|
rb_define_method(ChmDecom, "extract_to_path", chmd_extract_to_path, 2);
|
96
|
-
|
97
|
-
|
98
|
-
rb_define_method(
|
99
|
-
rb_define_method(ChmDHeader, "files", chmd_header_files, 0);
|
100
|
-
|
101
|
-
ChmDFile = rb_define_class_under(ChmDecom, "File", rb_cObject);
|
102
|
-
rb_define_method(ChmDFile, "filename", chmd_file_filename, 0);
|
103
|
-
rb_define_method(ChmDFile, "next", chmd_file_next, 0);
|
181
|
+
rb_define_method(ChmDecom, "last_error", chmd_last_error, 0);
|
182
|
+
rb_define_method(ChmDecom, "fast_open", chmd_fast_open, 1);
|
183
|
+
rb_define_method(ChmDecom, "fast_find", chmd_fast_find, 2);
|
104
184
|
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#include "chm_decompressor_file.h"
|
2
|
+
#include "mspack_native.h"
|
3
|
+
|
4
|
+
#include <mspack.h>
|
5
|
+
|
6
|
+
void chmd_file_free(void *ptr) {
|
7
|
+
struct mschmd_file *file = (struct mschmd_file *)ptr;
|
8
|
+
|
9
|
+
if (file->length == 0) { // only free if it was created in fast_find
|
10
|
+
//if (file->filename) {
|
11
|
+
// free(file->filename);
|
12
|
+
//}
|
13
|
+
|
14
|
+
free(file);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
VALUE chmd_file_filename(VALUE self) {
|
19
|
+
struct mschmd_file *file;
|
20
|
+
Data_Get_Struct(self, struct mschmd_file, file);
|
21
|
+
|
22
|
+
if (!file->filename) {
|
23
|
+
return Qnil;
|
24
|
+
}
|
25
|
+
|
26
|
+
return rb_str_new2(file->filename);
|
27
|
+
}
|
28
|
+
|
29
|
+
VALUE chmd_file_next(VALUE self) {
|
30
|
+
struct mschmd_file *file;
|
31
|
+
Data_Get_Struct(self, struct mschmd_file, file);
|
32
|
+
struct mschmd_file *next = file->next;
|
33
|
+
|
34
|
+
if (!next) {
|
35
|
+
return Qnil;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE nextObj = Data_Wrap_Struct(ChmDFile, NULL, chmd_file_free, next);
|
39
|
+
rb_iv_set(nextObj, "is_fast_find", Qfalse);
|
40
|
+
return nextObj;
|
41
|
+
}
|
42
|
+
|
43
|
+
VALUE chmd_file_is_fast_find(VALUE self) {
|
44
|
+
return rb_iv_get(self, "is_fast_find");
|
45
|
+
}
|
46
|
+
|
47
|
+
void Init_chm_decompressor_file() {
|
48
|
+
ChmDFile = rb_define_class_under(ChmDecom, "File", rb_cObject);
|
49
|
+
rb_define_method(ChmDFile, "filename", chmd_file_filename, 0);
|
50
|
+
rb_define_method(ChmDFile, "next", chmd_file_next, 0);
|
51
|
+
rb_define_method(ChmDFile, "fast_find?", chmd_file_is_fast_find, 0);
|
52
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#include "chm_decompressor_header.h"
|
2
|
+
#include "mspack_native.h"
|
3
|
+
|
4
|
+
#include <mspack.h>
|
5
|
+
|
6
|
+
VALUE chmd_header_filename(VALUE self) {
|
7
|
+
struct mschmd_header *header;
|
8
|
+
Data_Get_Struct(self, struct mschmd_header, header);
|
9
|
+
return rb_str_new2(header->filename);
|
10
|
+
}
|
11
|
+
|
12
|
+
VALUE chmd_header_files(VALUE self) {
|
13
|
+
struct mschmd_header *header;
|
14
|
+
Data_Get_Struct(self, struct mschmd_header, header);
|
15
|
+
|
16
|
+
if (!header->files) {
|
17
|
+
return Qnil;
|
18
|
+
}
|
19
|
+
|
20
|
+
VALUE file = Data_Wrap_Struct(ChmDFile, NULL, NULL, header->files);
|
21
|
+
rb_iv_set(file, "is_fast_find", Qfalse);
|
22
|
+
return file;
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE chmd_header_is_fast_open(VALUE self) {
|
26
|
+
return rb_iv_get(self, "is_fast_open");
|
27
|
+
}
|
28
|
+
|
29
|
+
void Init_chm_decompressor_header() {
|
30
|
+
ChmDHeader = rb_define_class_under(ChmDecom, "Header", rb_cObject);
|
31
|
+
rb_define_method(ChmDHeader, "filename", chmd_header_filename, 0);
|
32
|
+
rb_define_method(ChmDHeader, "files", chmd_header_files, 0);
|
33
|
+
rb_define_method(ChmDHeader, "fast_open?", chmd_header_is_fast_open, 0);
|
34
|
+
}
|
@@ -1,9 +1,14 @@
|
|
1
1
|
#include "mspack_native.h"
|
2
2
|
#include "chm_decompressor.h"
|
3
|
+
#include "chm_decompressor_file.h"
|
4
|
+
#include "chm_decompressor_header.h"
|
3
5
|
|
4
6
|
#include <mspack.h>
|
5
7
|
|
6
8
|
VALUE Mspack = Qnil;
|
9
|
+
VALUE ChmDecom = Qnil;
|
10
|
+
VALUE ChmDHeader = Qnil;
|
11
|
+
VALUE ChmDFile = Qnil;
|
7
12
|
|
8
13
|
VALUE mspack_test() {
|
9
14
|
int result;
|
@@ -16,4 +21,6 @@ void Init_mspack_native() {
|
|
16
21
|
rb_define_singleton_method(Mspack, "test", mspack_test, 0);
|
17
22
|
|
18
23
|
Init_chm_decompressor();
|
24
|
+
Init_chm_decompressor_header();
|
25
|
+
Init_chm_decompressor_file();
|
19
26
|
}
|
data/lib/mspack/version.rb
CHANGED
data/lib/mspack.rb
CHANGED
@@ -12,6 +12,10 @@ module Mspack
|
|
12
12
|
# Raises an error if the final, expanded path is outside of dir.
|
13
13
|
# Returns the expanded file path.
|
14
14
|
def self.ensure_path(filename, dir)
|
15
|
+
unless filename.is_a?(String) && dir.is_a?(String)
|
16
|
+
raise TypeError, 'both parameters must be strings'
|
17
|
+
end
|
18
|
+
|
15
19
|
raise PathError, "#{dir} is not a directory" unless ::File.directory?(dir)
|
16
20
|
raise PathError, "#{dir} is not writable" unless ::File.writable?(dir)
|
17
21
|
|
data/mspack.gemspec
CHANGED
@@ -23,9 +23,13 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
spec.extensions << 'ext/mspack_native/extconf.rb'
|
25
25
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rake-compiler', '~> 1.0'
|
30
|
+
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
spec.add_development_dependency 'guard-rspec','~> 4.7'
|
33
|
+
|
34
|
+
spec.add_development_dependency 'byebug'
|
31
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mspack_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: A ruby gem wrapper for libmspack
|
84
98
|
email:
|
85
99
|
- 8enwilliams@gmail.com
|
@@ -99,13 +113,16 @@ files:
|
|
99
113
|
- bin/setup
|
100
114
|
- ext/mspack_native/chm_decompressor.c
|
101
115
|
- ext/mspack_native/chm_decompressor.h
|
116
|
+
- ext/mspack_native/chm_decompressor_file.c
|
117
|
+
- ext/mspack_native/chm_decompressor_file.h
|
118
|
+
- ext/mspack_native/chm_decompressor_header.c
|
119
|
+
- ext/mspack_native/chm_decompressor_header.h
|
102
120
|
- ext/mspack_native/extconf.rb
|
103
121
|
- ext/mspack_native/mspack_native.c
|
104
122
|
- ext/mspack_native/mspack_native.h
|
105
123
|
- lib/mspack.rb
|
106
124
|
- lib/mspack/chm_decompressor.rb
|
107
125
|
- lib/mspack/version.rb
|
108
|
-
- lib/mspack_native.bundle
|
109
126
|
- mspack.gemspec
|
110
127
|
homepage: https://github.com/benjineering/mspack_rb
|
111
128
|
licenses:
|
data/lib/mspack_native.bundle
DELETED
Binary file
|