├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .jshintignore
├── .jshintrc
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin
└── lzmajs
├── binding.gyp
├── deps
├── .gitignore
├── .npmignore
├── xz-5.2.3-windows.7z
├── xz-5.2.3-windows.7z.sig
├── xz-5.2.3.tar.bz2
└── xz-5.2.3.tar.bz2.sig
├── index.js
├── liblzma-build.sh
├── liblzma-config.sh
├── package.json
├── src
├── filter-array.cpp
├── index-parser.cpp
├── index-parser.h
├── liblzma-functions.cpp
├── liblzma-node.hpp
├── lzma-stream.cpp
├── module.cpp
├── mt-options.cpp
└── util.cpp
└── test
├── compat.js
├── functions.js
├── hamlet.txt.2stream.xz
├── hamlet.txt.lzma
├── hamlet.txt.xz
├── helpers.js
├── internals.js
├── invalid.xz
├── parse-index.js
├── random
├── random-large
├── readme-examples.js
├── regression-1.js
├── regression-53.js
├── regression-7.js
└── stream.js
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | tags:
8 | - v[0-9]+.[0-9]+.[0-9]+*
9 | pull_request:
10 |
11 | jobs:
12 | test:
13 | runs-on: ${{ matrix.os }}
14 | strategy:
15 | matrix:
16 | os: [windows-latest, macOS-latest, ubuntu-latest]
17 | node-version: [12.x, 14.x, 16.x]
18 |
19 | steps:
20 | - name: Fix git checkout line endings
21 | run: git config --global core.autocrlf input
22 | - uses: actions/checkout@v2.3.4
23 | - name: Setup Node.js
24 | uses: actions/setup-node@v2.3.0
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - name: Windows Setup
28 | if: matrix.os == 'windows-latest'
29 | run: npm run prepare-win32
30 | - name: Install
31 | run: npm install
32 | - name: Lint
33 | run: npm run jshint
34 | - name: Test
35 | run: npm run test
36 |
37 | prebuild:
38 | needs: test
39 | runs-on: ${{ matrix.os }}-latest
40 | strategy:
41 | matrix:
42 | os: [windows, macOS, ubuntu]
43 | arch: [x64, arm64]
44 | exclude:
45 | - os: windows
46 | arch: arm64
47 | include:
48 | - os: windows
49 | arch: ia32
50 |
51 | steps:
52 | - name: Fix git checkout line endings
53 | run: git config --global core.autocrlf input
54 | - uses: actions/checkout@v2.3.4
55 | - name: Setup Node.js
56 | uses: actions/setup-node@v2.3.0
57 | with:
58 | node-version: 12.x
59 | - name: Windows Setup
60 | if: matrix.os == 'windows'
61 | run: npm run prepare-win32
62 | - name: Install
63 | run: npm install
64 | - name: Prebuild binaries
65 | run: npm run prebuild --v8_enable_pointer_compression=false --v8_enable_31bit_smis_on_64bit_arch=false $([[ $OSTYPE != darwin* ]] && echo --llvm_version=0.0 || true)
66 | shell: bash
67 | env:
68 | PREBUILD_ARCH: ${{ matrix.arch }}
69 | - name: Upload binaries as an artifact
70 | uses: actions/upload-artifact@v2.3.1
71 | with:
72 | name: prebuild-${{ matrix.os }}-${{ matrix.arch }}
73 | path: prebuilds
74 |
75 | publish:
76 | needs: prebuild
77 | runs-on: ubuntu-latest
78 | if: github.ref_type == 'tag'
79 |
80 | steps:
81 | - name: Fix git checkout line endings
82 | run: git config --global core.autocrlf input
83 | - uses: actions/checkout@v2.3.4
84 | - name: Setup Node.js
85 | uses: actions/setup-node@v2.3.0
86 | with:
87 | node-version: 12.x
88 | registry-url: 'https://registry.npmjs.org'
89 | - name: Install
90 | run: npm install
91 | - name: Download prebuild artifacts
92 | uses: actions/download-artifact@v2.1.0
93 | with:
94 | path: artifacts
95 | - name: Merge artifacts to prebuilds directory
96 | run: |
97 | mkdir prebuilds
98 | mv artifacts/*/* prebuilds/
99 | rm -r artifacts
100 | ls prebuilds
101 | - name: Publish to npm
102 | run: npm publish
103 | env:
104 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
105 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | binding*/
3 | node_modules/
4 | coverage/
5 | npm-debug.log
6 | core
7 | README.md.xz
8 | .nyc_output
9 | /.idea/
10 | prebuilds/
11 |
--------------------------------------------------------------------------------
/.jshintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | output.log
3 | templates-compiled.js
4 | errors.log
5 | errors-*.log
6 | errors.*.log
7 | out
8 | doc
9 | buildstamp.js
10 | core
11 | coverage
12 | npm-debug.log
13 | output.*.log
14 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "expr": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "newcap": true,
6 | "noarg": true,
7 | "sub": true,
8 | "undef": true,
9 | "unused": "vars",
10 | "boss": true,
11 | "eqnull": true,
12 | "node": true,
13 | "esnext": true,
14 | "globals": {
15 | "require": true,
16 | "exports": true,
17 | "console": true,
18 | "module": true,
19 | "gc": true,
20 |
21 | "it": true,
22 | "describe": true,
23 | "before": true,
24 | "beforeEach": true,
25 | "after": true,
26 | "afterEach": true
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | build/
2 | test/
3 | coverage/
4 | binding*/
5 | deps/xz-5.2.3-windows.7z
6 | npm-debug.log
7 | core
8 | README.md.xz
9 | .jshint*
10 | .travis*
11 | appveyor.yml
12 | .nyc-output
13 | .git
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog for lzma-native
2 |
3 | ## 8.0.6, Jan 18 2022
4 |
5 | * [[`5bdb4b047c`](https://github.com/addaleax/lzma-native/commit/5bdb4b047c)] - **ci**: use npm instead of yarn (Anna Henningsen)
6 | * [[`204dfca905`](https://github.com/addaleax/lzma-native/commit/204dfca905)] - *Revert* "*Revert* "**ci**: set llvm_version to 0.0 on non-macOS hosts for prebuilds"" (Anna Henningsen)
7 | * [[`8c324b2672`](https://github.com/addaleax/lzma-native/commit/8c324b2672)] - *Revert* "**ci**: set llvm_version to 0.0 on non-macOS hosts for prebuilds" (Anna Henningsen)
8 | * [[`4639d45d73`](https://github.com/addaleax/lzma-native/commit/4639d45d73)] - **ci**: set llvm_version to 0.0 on non-macOS hosts for prebuilds (Anna Henningsen)
9 | * [[`d5164b3ded`](https://github.com/addaleax/lzma-native/commit/d5164b3ded)] - **test**: bump mocha timeout (Anna Henningsen)
10 | * [[`0ddd17aed8`](https://github.com/addaleax/lzma-native/commit/0ddd17aed8)] - **build**: fix dyld load error on Apple Silicon (#128) (tylinux)
11 |
12 | ## 8.0.5, Jan 11 2022
13 |
14 | * [[`2ee1daa361`](https://github.com/addaleax/lzma-native/commit/2ee1daa361)] - fix(build): remove bash-isms (Anna Henningsen)
15 | * [[`da5832b0c4`](https://github.com/addaleax/lzma-native/commit/da5832b0c4)] - **ci**: replace Travis CI/AppVeyor with GitHub Actions, prebuild for macOS/arm64 (#126) (Mark Lee)
16 | * [[`8af909b058`](https://github.com/addaleax/lzma-native/commit/8af909b058)] - **build**: fix build on Apple Silicon (#123) (tylinux)
17 |
18 | ## 8.0.1, May 13 2021
19 |
20 | * [[`5b724c30c1`](https://github.com/addaleax/lzma-native/commit/5b724c30c1)] - More prebuild updates (Anna Henningsen)
21 | * [[`43f11c229b`](https://github.com/addaleax/lzma-native/commit/43f11c229b)] - Try switching to prebuildify (Anna Henningsen)
22 |
23 | ## 7.0.1, Mar 11 2021
24 |
25 | * [[`d9b0b90b66`](https://github.com/addaleax/lzma-native/commit/d9b0b90b66)] - Upgrade to @mapbox/node-pre-gyp (Luis Solorzano)
26 |
27 | ## 6.0.1, Apr 23 2020
28 |
29 | * [[`d90d2fc354`](https://github.com/addaleax/lzma-native/commit/d90d2fc354)] - **build**: fix package filename for N-API (Anna Henningsen)
30 |
31 | ## 6.0.0, Jan 1 2020
32 |
33 | * [[`f33038b345`](https://github.com/addaleax/lzma-native/commit/f33038b345)] - **ci**: update platform list (Anna Henningsen) [#72](https://github.com/addaleax/lzma-native/pull/72)
34 | * [[`66499a02b6`](https://github.com/addaleax/lzma-native/commit/66499a02b6)] - **build**: remove cflags.sh build step (Anna Henningsen) [#72](https://github.com/addaleax/lzma-native/pull/72)
35 | * [[`8bea0ff0cf`](https://github.com/addaleax/lzma-native/commit/8bea0ff0cf)] - **src**: convert to N-API (Anna Henningsen) [#72](https://github.com/addaleax/lzma-native/pull/72)
36 |
37 | ## 5.0.1, Dec 19 2019
38 |
39 | * [[`56ff7693a8`](https://github.com/addaleax/lzma-native/commit/56ff7693a8)] - **ci**: revert back to using gcc 4.9 (Anna Henningsen)
40 |
41 | ## 5.0.0, Nov 23 2019
42 |
43 | * [[`607c4f450c`](https://github.com/addaleax/lzma-native/commit/607c4f450c)] - **ci**: remove Node.js 6, 11 (Anna Henningsen) [#87](https://github.com/addaleax/lzma-native/pull/87)
44 |
45 | ## 4.0.6, Nov 22 2019
46 |
47 | * [[`6ebced9b57`](https://github.com/addaleax/lzma-native/commit/6ebced9b57)] - Fix compatibility with Node 13 (Christian Moritz) [#86](https://github.com/addaleax/lzma-native/pull/86)
48 |
49 | ## 4.0.5, May 24 2019
50 |
51 | * [[`dfd9098c85`](https://github.com/addaleax/lzma-native/commit/dfd9098c85)] - Ignore .git when publishing to npm (Juan Cruz Viotti) [#83](https://github.com/addaleax/lzma-native/pull/83)
52 |
53 | ## 4.0.4, May 23 2019
54 |
55 | * [[`0dc31e34de`](https://github.com/addaleax/lzma-native/commit/0dc31e34de)] - Enable compilation for Node 12 (Gergely Imreh) [#81](https://github.com/addaleax/lzma-native/pull/81)
56 |
57 | ## 4.0.3, Nov 14 2018
58 |
59 | * [[`d07d5f5571`](https://github.com/addaleax/lzma-native/commit/d07d5f5571)] - **ci**: update platform list with Node 11 (Anna Henningsen)
60 | * [[`8bbfb0a4d1`](https://github.com/addaleax/lzma-native/commit/8bbfb0a4d1)] - **ci**: fix Node 8 version at 8.10 (Anna Henningsen)
61 |
62 | ## 4.0.2, Oct 26 2018
63 |
64 | * [[`bb6bfe0988`](https://github.com/addaleax/lzma-native/commit/bb6bfe0988)] - **package**: update node-pre-gyp to 0.11.0 (webcarrot) [#68](https://github.com/addaleax/lzma-native/pull/68)
65 |
66 | ## 4.0.1, Jul 26 2018
67 |
68 | * [[`93b50cc2f7`](https://github.com/addaleax/lzma-native/commit/93b50cc2f7)] - **package**: fix rimraf invocation in install script (webcarrot) [#63](https://github.com/addaleax/lzma-native/pull/63)
69 |
70 | ## 4.0.0, Jul 26 2018
71 |
72 | There are no breaking changes to the API provided by this module.
73 |
74 | This drops pre-built binaries and testing for officially unsupported Node.js
75 | versions. Those versions have known security issues and should not be used
76 | anymore.
77 |
78 | This also updates node-pre-gyp to a more recent version. In the past,
79 | this has caused trouble for some users, so this considered
80 | is a semver-major change as well.
81 |
82 | * [[`b625b3e525`](https://github.com/addaleax/lzma-native/commit/b625b3e525)] - **package**: stop bundling dependencies (Anna Henningsen)
83 | * [[`98155a8179`](https://github.com/addaleax/lzma-native/commit/98155a8179)] - **ci**: drop unsupported Node.js versions (4, 5, 7, 9) (Anna Henningsen)
84 | * [[`d59574481f`](https://github.com/addaleax/lzma-native/commit/d59574481f)] - **package**: update bl to 2.0.1 (Anna Henningsen)
85 | * [[`f2c6e84d2c`](https://github.com/addaleax/lzma-native/commit/f2c6e84d2c)] - **package**: update node-pre-gyp to 0.10.3 (simlu) [#61](https://github.com/addaleax/lzma-native/pull/61)
86 |
87 | ## 3.0.8, May 12 2018
88 |
89 | * [[`8c18848609`](https://github.com/addaleax/lzma-native/commit/8c18848609)] - **ci**: add Node.js 10 to matrix (Anna Henningsen)
90 |
91 | ## 3.0.7, Mar 26 2018
92 |
93 | This likely fixed a regression related to node-pre-gyp.
94 |
95 | * [[`430a440276`](https://github.com/addaleax/lzma-native/commit/430a440276)] - **package**: pin node-pre-gyp to 0.6.39 (Anna Henningsen)
96 |
97 | ## 3.0.6, Mar 26 2018
98 |
99 | * [[`484c53577f`](https://github.com/addaleax/lzma-native/commit/484c53577f)] - **package**: update dependencies (Anna Henningsen)
100 | * [[`6513708704`](https://github.com/addaleax/lzma-native/commit/6513708704)] - **lib**: use `Buffer.*` instead of deprecated Buffer constructor (Anna Henningsen)
101 |
102 | ## 3.0.5, Feb 21 2018
103 |
104 | * [[`c03299db13`](https://github.com/addaleax/lzma-native/commit/c03299db13)] - **ci**: remove OS X from coverage (Anna Henningsen)
105 | * [[`5f640416e0`](https://github.com/addaleax/lzma-native/commit/5f640416e0)] - **lib**: fix issue with invalid input (Anna Henningsen)
106 |
107 | ## 3.0.4, Nov 27 2017
108 |
109 | * [[`669ee5098b`](https://github.com/addaleax/lzma-native/commit/669ee5098b)] - **package**: replace unavailable host to node-pre-gyp.addaleax.net (JianyingLi) [#48](https://github.com/addaleax/lzma-native/pull/48)
110 |
111 | ## 3.0.3, Nov 26 2017
112 |
113 | * [[`fcba77ebe0`](https://github.com/addaleax/lzma-native/commit/fcba77ebe0)] - **ci**: include Node 9 support (Anna Henningsen)
114 |
115 | ## 3.0.2, Nov 07 2017
116 |
117 | * [[`82b97dd94f`](https://github.com/addaleax/lzma-native/commit/82b97dd94f)] - **package**: update dependencies (Anna Henningsen)
118 |
119 | ## 3.0.1, Jul 04 2017
120 |
121 | * [[`9e2ee5129f`](https://github.com/addaleax/lzma-native/commit/9e2ee5129f)] - **ci**: fix CI on Windows (Anna Henningsen)
122 | * [[`8d75757031`](https://github.com/addaleax/lzma-native/commit/8d75757031)] - **lib**: fix race condition (Alexander Sagen) [#40](https://github.com/addaleax/lzma-native/pull/40)
123 |
124 | ## 3.0.0, Jun 26 2017
125 |
126 | This is unlikely to break anybody’s code, but removing the build files after install might qualify as semver-major.
127 |
128 | * [[`d5a252e3de`](https://github.com/addaleax/lzma-native/commit/d5a252e3de)] - **build**: rimraf build/ after install (Anna Henningsen)
129 | * [[`fd2165e2ae`](https://github.com/addaleax/lzma-native/commit/fd2165e2ae)] - **ci**: add electron prebuilts again (Anna Henningsen)
130 | * [[`039ac523d0`](https://github.com/addaleax/lzma-native/commit/039ac523d0)] - **lib**: explicit util.promisify() compat (Anna Henningsen)
131 |
132 | ## 2.0.4, Jun 25 2017
133 |
134 | * [[`0cc00000b3`](https://github.com/addaleax/lzma-native/commit/0cc00000b3)] - **ci**: fix macOS prebuild binaries (Anna Henningsen)
135 |
136 | ## 2.0.3, Jun 21 2017
137 |
138 | * [[`621628abac`](https://github.com/addaleax/lzma-native/commit/621628abac)] - **ci**: add Node 8 to CI matrix (Anna Henningsen)
139 |
140 | ## 2.0.2, May 18 2017
141 |
142 | * [[`39bd6a2dc0`](https://github.com/addaleax/lzma-native/commit/39bd6a2dc0)] - **package**: pin nan to 2.5.1 (Anna Henningsen)
143 |
144 | ## 2.0.1, March 24 2017
145 |
146 | * [[`c0491a0a07`](https://github.com/addaleax/lzma-native/commit/c0491a0a07)] - refactored binding.gyp (Refael Ackermann)
147 | * [[`70883635b7`](https://github.com/addaleax/lzma-native/commit/70883635b7)] - **ci**: skip artifact encryption setup for non-tag builds (Anna Henningsen)
148 |
149 | ## 2.0.0, March 19 2017
150 |
151 | Changes since 1.5.2
152 |
153 | Notable changes:
154 |
155 | * Dropped support for Node 0.10 and 0.12, which includes dropping `any-promise` and `util-extend` as dependencies.
156 | * A changed path for the prebuilt binaries, which now includes versioning information.
157 |
158 | * [[`83e0007061`](https://github.com/addaleax/lzma-native/commit/83e0007061)] - Bump version to 1.5.3
159 | * [[`8021673b5d`](https://github.com/addaleax/lzma-native/commit/8021673b5d)] - Silence warnings about deprecated `NewInstance` usage
160 | * [[`061933c4c7`](https://github.com/addaleax/lzma-native/commit/061933c4c7)] - **bin**: drop `commander` dependency
161 | * [[`d752f96be4`](https://github.com/addaleax/lzma-native/commit/d752f96be4)] - **ci**: don’t use -flto for now
162 | * [[`92188bee5e`](https://github.com/addaleax/lzma-native/commit/92188bee5e)] - **ci**: fix AppVeyor allocation failures
163 | * [[`b79fa969d4`](https://github.com/addaleax/lzma-native/commit/b79fa969d4)] - **ci**: fix AppVeyor indexparser failures
164 | * [[`5fcc17e54f`](https://github.com/addaleax/lzma-native/commit/5fcc17e54f)] - **ci**: fix Travis gcc CI failures
165 | * [[`3f5d2609bd`](https://github.com/addaleax/lzma-native/commit/3f5d2609bd)] - **ci**: drop Node v0.10/v0.12 support
166 | * [[`48e48ea25a`](https://github.com/addaleax/lzma-native/commit/48e48ea25a)] - **ci**: ci file housekeeping
167 | * [[`c2d06b5e09`](https://github.com/addaleax/lzma-native/commit/c2d06b5e09)] - **ci**: work around node-gyp build failures
168 | * [[`f94287f711`](https://github.com/addaleax/lzma-native/commit/f94287f711)] - **ci,test**: drop explicit nw.js testing
169 | * [[`c61355984f`](https://github.com/addaleax/lzma-native/commit/c61355984f)] - **deps**: update xz to 5.2.3
170 | * [[`b07f501e26`](https://github.com/addaleax/lzma-native/commit/b07f501e26)] - **doc**: leave blank lines around headings in README
171 | * [[`dea30f3f20`](https://github.com/addaleax/lzma-native/commit/dea30f3f20)] - **lib**: drop util-extend dependency
172 | * [[`0988b8d360`](https://github.com/addaleax/lzma-native/commit/0988b8d360)] - **lib**: refactor js-facing Stream into class
173 | * [[`18bbdfc220`](https://github.com/addaleax/lzma-native/commit/18bbdfc220)] - **lib**: always use ES6 promises
174 | * [[`f5030e027e`](https://github.com/addaleax/lzma-native/commit/f5030e027e)] - **lib**: fix unhandled Promise rejections
175 | * [[`6e887ca52c`](https://github.com/addaleax/lzma-native/commit/6e887ca52c)] - **meta**: package.json housekeeping
176 | * [[`e884b2e7c1`](https://github.com/addaleax/lzma-native/commit/e884b2e7c1)] - **prebuild**: add versioning to the binding file path
177 | * [[`e8660b3728`](https://github.com/addaleax/lzma-native/commit/e8660b3728)] - **src**: use Nan::MakeCallback() for calling into JS
178 | * [[`bd7ee7ce3f`](https://github.com/addaleax/lzma-native/commit/bd7ee7ce3f)] - **test**: use `fs.unlinkSync` for synchronous unlinking
179 |
180 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2016 Anna Henningsen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | lzma-native
2 | ===========
3 |
4 | [](https://npmjs.org/package/lzma-native)
5 | [](https://npmjs.org/package/lzma-native)
6 | [](https://travis-ci.org/addaleax/lzma-native?branch=master)
7 | [](https://ci.appveyor.com/project/addaleax/lzma-native)
8 | [](https://coveralls.io/r/addaleax/lzma-native?branch=master)
9 | [](https://david-dm.org/addaleax/lzma-native)
10 | [](https://david-dm.org/addaleax/lzma-native#info=devDependencies)
11 |
12 | Node.js interface to the native liblzma compression library (.xz file format, among others)
13 |
14 | This package provides interfaces for compression and decompression
15 | of `.xz` (and legacy `.lzma`) files, both stream-based and string-based.
16 |
17 |
18 |
19 | ## Example usage
20 |
21 |
22 |
23 | ### Installation
24 |
25 | Simply install `lzma-native` via npm:
26 | ```bash
27 | $ npm install --save lzma-native
28 | ```
29 |
30 | *Note*: As of version 1.0.0, this module provides pre-built binaries for multiple Node.js
31 | versions and all major OS using [node-pre-gyp](https://github.com/mapbox/node-pre-gyp),
32 | so for 99 % of users no compiler toolchain is necessary.
33 | Please [create an issue here](https://github.com/addaleax/lzma-native/issues/new)
34 | if you have any trouble installing this module.
35 |
36 | *Note*: `lzma-native@2.x` requires a Node version >= 4. If you want to support
37 | Node `0.10` or `0.12`, you can feel free to use `lzma-native@1.x`.
38 |
39 |
40 |
41 | ### For streams
42 |
43 | If you don’t have any fancy requirements, using this library is quite simple:
44 |
45 |
49 |
50 |
51 |
52 | ```js
53 | var lzma = require('lzma-native');
54 |
55 | var compressor = lzma.createCompressor();
56 | var input = fs.createReadStream('README.md');
57 | var output = fs.createWriteStream('README.md.xz');
58 |
59 | input.pipe(compressor).pipe(output);
60 | ```
61 |
62 | For decompression, you can simply use `lzma.createDecompressor()`.
63 |
64 | Both functions return a stream where you can pipe your
65 | input in and read your (de)compressed output from.
66 |
67 |
68 |
69 | ### For simple strings/Buffers
70 |
71 | If you want your input/output to be Buffers (strings will be accepted as input),
72 | this even gets a little simpler:
73 |
74 |
75 |
76 | ```js
77 | lzma.compress('Banana', function(result) {
78 | console.log(result); //
79 | });
80 | ```
81 |
82 | Again, replace `lzma.compress` with `lzma.decompress` and you’ll get the inverse transformation.
83 |
84 | `lzma.compress()` and `lzma.decompress()`
85 | will return promises and you don’t need to provide any kind of callback
86 | ([Example code](#api-q-compress-examle)).
87 |
88 |
89 |
90 | ## API
91 |
92 |
93 |
94 | ### Compatibility implementations
95 |
96 | Apart from the API described here, `lzma-native` implements the APIs of the following
97 | other LZMA libraries so you can use it nearly as a drop-in replacement:
98 |
99 | * [node-xz][node-xz] via `lzma.Compressor` and `lzma.Decompressor`
100 | * [LZMA-JS][LZMA-JS] via `lzma.LZMA().compress` and `lzma.LZMA().decompress`,
101 | though without actual support for progress functions and returning `Buffer` objects
102 | instead of integer arrays. (This produces output in the `.lzma` file format, *not* the `.xz` format!)
103 |
104 |
105 |
106 | ### Multi-threaded encoding
107 |
108 | Since version `1.5.0`, lzma-native supports liblzma’s built-in multi-threading
109 | encoding capabilities. To make use of them, set the `threads` option to
110 | an integer value: `lzma.createCompressor({ threads: n });`. You can use
111 | value of `0` to use the number of processor cores. This option is only
112 | available for the `easyEncoder` (the default) and `streamEncoder` encoders.
113 |
114 | Note that, by default, encoding will take place in Node’s libuv thread pool
115 | regardless of this option, and setting it when multiple encoders are running
116 | is likely to affect performance negatively.
117 |
118 |
119 |
120 | ### Reference
121 |
122 | [Encoding strings and Buffer objects](#api-encoding-buffers)
123 | * [`compress()`](#api-compress) – Compress strings and Buffers
124 | * [`decompress()`](#api-decompress) – Decompress strings and Buffers
125 | * [`LZMA().compress()`](#api-LZMA_compress) ([LZMA-JS][LZMA-JS] compatibility)
126 | * [`LZMA().decompress()`](#api-LZMA_decompress) ([LZMA-JS][LZMA-JS] compatibility)
127 |
128 | [Creating streams for encoding](#api-creating-streams)
129 | * [`createCompressor()`](#api-create-compressor) – Compress streams
130 | * [`createDecompressor()`](#api-create-decompressor) – Decompress streams
131 | * [`createStream()`](#api-create-stream) – (De-)Compression with advanced options
132 | * [`Compressor()`](#api-robey_compressor) ([node-xz][node-xz] compatibility)
133 | * [`Decompressor()`](#api-robey_decompressor) ([node-xz][node-xz] compatibility)
134 |
135 | [.xz file metadata](#api-parse-indexes)
136 | * [`isXZ()`](#api-isxz) – Test Buffer for `.xz` file format
137 | * [`parseFileIndex()`](#api-parse-file-index) – Read `.xz` file metadata
138 | * [`parseFileIndexFD()`](#api-parse-file-index-fd) – Read `.xz` metadata from a file descriptor
139 |
140 | [Miscellaneous functions](#api-functions)
141 | * [`crc32()`](#api-crc32) – Calculate CRC32 checksum
142 | * [`checkSize()`](#api-check-size) – Return required size for specific checksum type
143 | * [`easyDecoderMemusage()`](#api-easy-decoder-memusage) – Expected memory usage
144 | * [`easyEncoderMemusage()`](#api-easy-encoder-memusage) – Expected memory usage
145 | * [`rawDecoderMemusage()`](#api-raw-decoder-memusage) – Expected memory usage
146 | * [`rawEncoderMemusage()`](#api-raw-encoder-memusage) – Expected memory usage
147 | * [`versionString()`](#api-version-string) – Native library version string
148 | * [`versionNumber()`](#api-version-number) – Native library numerical version identifier
149 |
150 |
151 |
152 | ### Encoding strings and Buffer objects
153 |
154 |
155 |
156 |
157 | #### `lzma.compress()`, `lzma.decompress()`
158 |
159 | * `lzma.compress(string, [opt, ]on_finish)`
160 | * `lzma.decompress(string, [opt, ]on_finish)`
161 |
162 | Param | Type | Description
163 | ------------ | ---------------- | --------------
164 | `string` | Buffer / String | Any string or buffer to be (de)compressed (that can be passed to `stream.end(…)`)
165 | [`opt`] | Options / int | Optional. See [options](#api-options)
166 | `on_finish` | Callback | Will be invoked with the resulting Buffer as the first parameter when encoding is finished, and as `on_finish(null, err)` in case of an error.
167 |
168 | These methods will also return a promise that you can use directly.
169 |
170 | Example code:
171 |
172 |
173 | ```js
174 | lzma.compress('Bananas', 6, function(result) {
175 | lzma.decompress(result, function(decompressedResult) {
176 | assert.equal(decompressedResult.toString(), 'Bananas');
177 | });
178 | });
179 | ```
180 |
181 |
182 | Example code for promises:
183 |
184 |
185 | ```js
186 | lzma.compress('Bananas', 6).then(function(result) {
187 | return lzma.decompress(result);
188 | }).then(function(decompressedResult) {
189 | assert.equal(decompressedResult.toString(), 'Bananas');
190 | }).catch(function(err) {
191 | // ...
192 | });
193 | ```
194 |
195 |
196 |
197 |
198 | #### `lzma.LZMA().compress()`, `lzma.LZMA().decompress()`
199 |
200 | * `lzma.LZMA().compress(string, mode, on_finish[, on_progress])`
201 | * `lzma.LZMA().decompress(string, on_finish[, on_progress])`
202 |
203 | (Compatibility; See [LZMA-JS][LZMA-JS] for the original specs.)
204 |
205 | **Note that the result of compression is in the older LZMA1 format (`.lzma` files).**
206 | This is different from the more universally used LZMA2 format (`.xz` files) and you will
207 | have to take care of possible compatibility issues with systems expecting `.xz` files.
208 |
209 | Param | Type | Description
210 | ------------- | ----------------------- | --------------
211 | `string` | Buffer / String / Array | Any string, buffer, or array of integers or typed integers (e.g. `Uint8Array`)
212 | `mode` | int | [A number between 0 and 9](#api-options-preset), indicating compression level
213 | `on_finish` | Callback | Will be invoked with the resulting Buffer as the first parameter when encoding is finished, and as `on_finish(null, err)` in case of an error.
214 | `on_progress` | Callback | Indicates progress by passing a number in [0.0, 1.0]. Currently, this package only invokes the callback with 0.0 and 1.0.
215 |
216 | These methods will also return a promise that you can use directly.
217 |
218 | This does not work exactly as described in the original [LZMA-JS][LZMA-JS] specification:
219 | * The results are `Buffer` objects, not integer arrays. This just makes a lot
220 | more sense in a Node.js environment.
221 | * `on_progress` is currently only called with `0.0` and `1.0`.
222 |
223 | Example code:
224 |
225 |
226 | ```js
227 | lzma.LZMA().compress('Bananas', 4, function(result) {
228 | lzma.LZMA().decompress(result, function(decompressedResult) {
229 | assert.equal(decompressedResult.toString(), 'Bananas');
230 | });
231 | });
232 | ```
233 |
234 | For an example using promises, see [`compress()`](#api-q-compress-examle).
235 |
236 |
237 |
238 | ### Creating streams for encoding
239 |
240 |
241 |
242 |
243 | #### `lzma.createCompressor()`, `lzma.createDecompressor()`
244 |
245 | * `lzma.createCompressor([options])`
246 | * `lzma.createDecompressor([options])`
247 |
248 | Param | Type | Description
249 | ----------- | ---------------- | --------------
250 | [`options`] | Options / int | Optional. See [options](#api-options)
251 |
252 | Return a [duplex][duplex] stream, i.e. a both readable and writable stream.
253 | Input will be read, (de)compressed and written out. You can use this to pipe
254 | input through this stream, i.e. to mimick the `xz` command line util, you can write:
255 |
256 |
257 |
258 | ```js
259 | var compressor = lzma.createCompressor();
260 |
261 | process.stdin.pipe(compressor).pipe(process.stdout);
262 | ```
263 |
264 | The output of compression will be in LZMA2 format (`.xz` files), while decompression
265 | will accept either format via automatic detection.
266 |
267 |
268 |
269 |
270 | #### `lzma.Compressor()`, `lzma.Decompressor()`
271 |
272 | * `lzma.Compressor([preset], [options])`
273 | * `lzma.Decompressor([options])`
274 |
275 | (Compatibility; See [node-xz][node-xz] for the original specs.)
276 |
277 | These methods handle the `.xz` file format.
278 |
279 | Param | Type | Description
280 | ----------- | ---------------- | --------------
281 | [`preset`] | int | Optional. See [options.preset](#api-options-preset)
282 | [`options`] | Options | Optional. See [options](#api-options)
283 |
284 | Return a [duplex][duplex] stream, i.e. a both readable and writable stream.
285 | Input will be read, (de)compressed and written out. You can use this to pipe
286 | input through this stream, i.e. to mimick the `xz` command line util, you can write:
287 |
288 |
289 |
290 | ```js
291 | var compressor = lzma.Compressor();
292 |
293 | process.stdin.pipe(compressor).pipe(process.stdout);
294 | ```
295 |
296 |
297 |
298 | #### `lzma.createStream()`
299 |
300 | * `lzma.createStream(coder, options)`
301 |
302 | Param | Type | Description
303 | ----------- | ---------------- | --------------
304 | [`coder`] | string | Any of the [supported coder names](#api-coders), e.g. `"easyEncoder"` (default) or `"autoDecoder"`.
305 | [`options`] | Options / int | Optional. See [options](#api-options)
306 |
307 | Return a [duplex][duplex] stream for (de-)compression. You can use this to pipe
308 | input through this stream.
309 |
310 |
311 | The available coders are (the most interesting ones first):
312 |
313 | * `easyEncoder`
314 | Standard LZMA2 ([`.xz` file format](https://en.wikipedia.org/wiki/.xz)) encoder.
315 | Supports [`options.preset`](#api-options-preset) and [`options.check`](#api-options-check) options.
316 | * `autoDecoder`
317 | Standard LZMA1/2 (both `.xz` and `.lzma`) decoder with auto detection of file format.
318 | Supports [`options.memlimit`](#api-options-memlimit) and [`options.flags`](#api-options-flags) options.
319 | * `aloneEncoder`
320 | Encoder which only uses the legacy `.lzma` format.
321 | Supports the whole range of [LZMA options](#api-options-lzma).
322 |
323 | Less likely to be of interest to you, but also available:
324 |
325 | * `aloneDecoder`
326 | Decoder which only uses the legacy `.lzma` format.
327 | Supports the [`options.memlimit`](#api-options-memlimit) option.
328 | * `rawEncoder`
329 | Custom encoder corresponding to `lzma_raw_encoder` (See the native library docs for details).
330 | Supports the [`options.filters`](#api-options-filters) option.
331 | * `rawDecoder`
332 | Custom decoder corresponding to `lzma_raw_decoder` (See the native library docs for details).
333 | Supports the [`options.filters`](#api-options-filters) option.
334 | * `streamEncoder`
335 | Custom encoder corresponding to `lzma_stream_encoder` (See the native library docs for details).
336 | Supports [`options.filters`](#api-options-filters) and [`options.check`](#api-options-check) options.
337 | * `streamDecoder`
338 | Custom decoder corresponding to `lzma_stream_decoder` (See the native library docs for details).
339 | Supports [`options.memlimit`](#api-options-memlimit) and [`options.flags`](#api-options-flags) options.
340 |
341 |
342 |
343 | #### Options
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 | Option name | Type | Description
352 | ------------- | ---------- | -------------
353 | `check` | check | Any of `lzma.CHECK_CRC32`, `lzma.CHECK_CRC64`, `lzma.CHECK_NONE`, `lzma.CHECK_SHA256`
354 | `memlimit` | float | A memory limit for (de-)compression in bytes
355 | `preset` | int | A number from 0 to 9, 0 being the fastest and weakest compression, 9 the slowest and highest compression level. (Please also see the [xz(1) manpage][xz-manpage] for notes – don’t just blindly use 9!) You can also OR this with `lzma.PRESET_EXTREME` (the `-e` option to the `xz` command line utility).
356 | `flags` | int | A bitwise or of `lzma.LZMA_TELL_NO_CHECK`, `lzma.LZMA_TELL_UNSUPPORTED_CHECK`, `lzma.LZMA_TELL_ANY_CHECK`, `lzma.LZMA_CONCATENATED`
357 | `synchronous` | bool | If true, forces synchronous coding (i.e. no usage of threading)
358 | `bufsize` | int | The default size for allocated buffers
359 | `threads` | int | Set to an integer to use liblzma’s multi-threading support. 0 will choose the number of CPU cores.
360 | `blockSize` | int | Maximum uncompressed size of a block in multi-threading mode
361 | `timeout` | int | Timeout for a single encoding operation in multi-threading mode
362 |
363 |
364 |
365 | `options.filters` can, if the coder supports it, be an array of filter objects, each with the following properties:
366 |
367 | * `.id`
368 | Any of `lzma.FILTERS_MAX`, `lzma.FILTER_ARM`, `lzma.FILTER_ARMTHUMB`, `lzma.FILTER_IA64`,
369 | `lzma.FILTER_POWERPC`, `lzma.FILTER_SPARC`, `lzma.FILTER_X86` or
370 | `lzma.FILTER_DELTA`, `lzma.FILTER_LZMA1`, `lzma.FILTER_LZMA2`
371 |
372 | The delta filter supports the additional option `.dist` for a distance between bytes (see the [xz(1) manpage][xz-manpage]).
373 |
374 |
375 |
376 | The LZMA filter supports the additional options `.dict_size`, `.lp`, `.lc`, `pb`, `.mode`, `nice_len`, `.mf`, `.depth`
377 | and `.preset`. See the [xz(1) manpage][xz-manpage] for meaning of these parameters and additional information.
378 |
379 |
380 |
381 | ### Miscellaneous functions
382 |
383 |
384 |
385 | #### `lzma.crc32()`
386 |
387 | * `lzma.crc32(input[, encoding[, previous]])`
388 |
389 | Compute the CRC32 checksum of a Buffer or string.
390 |
391 | Param | Type | Description
392 | ------------ | ---------------- | --------------
393 | `input` | string / Buffer | Any string or Buffer.
394 | [`encoding`] | string | Optional. If `input` is a string, an encoding to use when converting into binary.
395 | [`previous`] | int | The result of a previous CRC32 calculation so that you can compute the checksum per each chunk
396 |
397 | Example usage:
398 |
399 |
400 | ```js
401 | lzma.crc32('Banana') // => 69690105
402 | ```
403 |
404 |
405 |
406 | #### `lzma.checkSize()`
407 |
408 | * `lzma.checkSize(check)`
409 |
410 | Return the byte size of a check sum.
411 |
412 | Param | Type | Description
413 | ------------ | ---------------- | --------------
414 | `check` | check | Any supported check constant.
415 |
416 | Example usage:
417 |
418 |
419 | ```js
420 | lzma.checkSize(lzma.CHECK_SHA256) // => 16
421 | lzma.checkSize(lzma.CHECK_CRC32) // => 4
422 | ```
423 |
424 |
425 |
426 | #### `lzma.easyDecoderMemusage()`
427 |
428 | * `lzma.easyDecoderMemusage(preset)`
429 |
430 | Returns the approximate memory usage when decoding using easyDecoder for a given preset.
431 |
432 | Param | Type | Description
433 | ------------ | ----------- | --------------
434 | `preset` | preset | A compression level from 0 to 9
435 |
436 | Example usage:
437 |
438 |
439 | ```js
440 | lzma.easyDecoderMemusage(6) // => 8454192
441 | ```
442 |
443 |
444 |
445 | #### `lzma.easyEncoderMemusage()`
446 |
447 | * `lzma.easyEncoderMemusage(preset)`
448 |
449 | Returns the approximate memory usage when encoding using easyEncoder for a given preset.
450 |
451 | Param | Type | Description
452 | ------------ | ----------- | --------------
453 | `preset` | preset | A compression level from 0 to 9
454 |
455 | Example usage:
456 |
457 |
458 | ```js
459 | lzma.easyEncoderMemusage(6) // => 97620499
460 | ```
461 |
462 |
463 |
464 | #### `lzma.rawDecoderMemusage()`
465 |
466 | * `lzma.rawDecoderMemusage(filters)`
467 |
468 | Returns the approximate memory usage when decoding using rawDecoder for a given filter list.
469 |
470 | Param | Type | Description
471 | ------------ | ----------- | --------------
472 | `filters` | array | An array of [filters](#api-options-filters)
473 |
474 |
475 |
476 | #### `lzma.rawEncoderMemusage()`
477 |
478 | * `lzma.rawEncoderMemusage(filters)`
479 |
480 | Returns the approximate memory usage when encoding using rawEncoder for a given filter list.
481 |
482 | Param | Type | Description
483 | ------------ | ----------- | --------------
484 | `filters` | array | An array of [filters](#api-options-filters)
485 |
486 |
487 |
488 | #### `lzma.versionString()`
489 |
490 | * `lzma.versionString()`
491 |
492 | Returns the version of the underlying C library.
493 |
494 | Example usage:
495 |
496 |
497 | ```js
498 | lzma.versionString() // => '5.2.3'
499 | ```
500 |
501 |
502 |
503 | #### `lzma.versionNumber()`
504 |
505 | * `lzma.versionNumber()`
506 |
507 | Returns the version of the underlying C library.
508 |
509 | Example usage:
510 |
511 |
512 | ```js
513 | lzma.versionNumber() // => 50020012
514 | ```
515 |
516 |
517 |
518 | ### .xz file metadata
519 |
520 |
521 |
522 | #### `lzma.isXZ()`
523 |
524 | * `lzma.isXZ(input)`
525 |
526 | Tells whether an input buffer is an XZ file (`.xz`, LZMA2 format) using the
527 | file format’s magic number. This is not a complete test, i.e. the data
528 | following the file header may still be invalid in some way.
529 |
530 | Param | Type | Description
531 | ------------ | ---------------- | --------------
532 | `input` | string / Buffer | Any string or Buffer (integer arrays accepted).
533 |
534 | Example usage:
535 |
536 |
537 | ```js
538 | lzma.isXZ(fs.readFileSync('test/hamlet.txt.xz')); // => true
539 | lzma.isXZ(fs.readFileSync('test/hamlet.txt.lzma')); // => false
540 | lzma.isXZ('Banana'); // => false
541 | ```
542 |
543 | (The magic number of XZ files is hex `fd 37 7a 58 5a 00` at position 0.)
544 |
545 |
546 |
547 | #### `lzma.parseFileIndex()`
548 |
549 | * `lzma.parseFileIndex(options[, callback])`
550 |
551 | Read `.xz` file metadata.
552 |
553 | `options.fileSize` needs to be an integer indicating the size of the file
554 | being inspected, e.g. obtained by `fs.stat()`.
555 |
556 | `options.read(count, offset, cb)` must be a function that reads `count` bytes
557 | from the underlying file, starting at position `offset`. If that is not
558 | possible, e.g. because the file does not have enough bytes, the file should
559 | be considered corrupt. On success, `cb` should be called with a `Buffer`
560 | containing the read data. `cb` can be invoked as `cb(err, buffer)`, in which
561 | case `err` will be passed along to the original `callback` argument when set.
562 |
563 | `callback` will be called with `err` and `info` as its arguments.
564 |
565 | If no `callback` is provided, `options.read()` must work synchronously and
566 | the file info will be returned from `lzma.parseFileIndex()`.
567 |
568 | Example usage:
569 |
570 |
571 | ```js
572 | fs.readFile('test/hamlet.txt.xz', function(err, content) {
573 | // handle error
574 |
575 | lzma.parseFileIndex({
576 | fileSize: content.length,
577 | read: function(count, offset, cb) {
578 | cb(content.slice(offset, offset + count));
579 | }
580 | }, function(err, info) {
581 | // handle error
582 |
583 | // do something with e.g. info.uncompressedSize
584 | });
585 | });
586 | ```
587 |
588 |
589 |
590 | #### `lzma.parseFileIndexFD()`
591 |
592 | * `lzma.parseFileIndexFD(fd, callback)`
593 |
594 | Read `.xz` metadata from a file descriptor.
595 |
596 | This is like [`parseFileIndex()`](#api-parse-file-index), but lets you
597 | pass an file descriptor in `fd`. The file will be inspected using
598 | `fs.stat()` and `fs.read()`. The file descriptor will not be opened or closed
599 | by this call.
600 |
601 | Example usage:
602 |
603 |
604 | ```js
605 | fs.open('test/hamlet.txt.xz', 'r', function(err, fd) {
606 | // handle error
607 |
608 | lzma.parseFileIndexFD(fd, function(err, info) {
609 | // handle error
610 |
611 | // do something with e.g. info.uncompressedSize
612 |
613 | fs.close(fd, function(err) { /* handle error */ });
614 | });
615 | });
616 | ```
617 |
618 | ## Installation
619 |
620 | This package includes the native C library, so there is no need to install it separately.
621 |
622 | ## Licensing
623 |
624 | The original C library package contains code under various licenses,
625 | with its core (liblzma) being public domain. See its contents for details.
626 | This wrapper is licensed under the MIT License.
627 |
628 | ## Related projects
629 |
630 | Other implementations of the LZMA algorithms for node.js and/or web clients include:
631 |
632 | * [lzma-purejs](https://github.com/cscott/lzma-purejs)
633 | * [LZMA-JS](https://github.com/nmrugg/LZMA-JS)
634 | * [node-xz](https://github.com/robey/node-xz) (native)
635 | * [node-liblzma](https://github.com/oorabona/node-liblzma) (native)
636 |
637 | Note that LZMA has been designed to have much faster decompression than
638 | compression, which is something you may want to take into account when
639 | choosing an compression algorithm for large files. Almost always, LZMA achieves
640 | higher compression ratios than other algorithms, though.
641 |
642 | ## Acknowledgements
643 |
644 | Initial development of this project was financially supported by [Tradity](https://tradity.de/).
645 |
646 | [node-xz]: https://github.com/robey/node-xz
647 | [LZMA-JS]: https://github.com/nmrugg/LZMA-JS
648 | [Q]: https://github.com/kriskowal/q
649 | [duplex]: https://nodejs.org/api/stream.html#stream_class_stream_duplex
650 | [xz-manpage]: https://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1&manpath=FreeBSD+8.3-RELEASE
651 |
--------------------------------------------------------------------------------
/bin/lzmajs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | var program = require('commander');
5 | var lzma = require('../');
6 | var fs = require('fs');
7 | var path = require('path');
8 |
9 | var argv = process.argv.slice(2);
10 | var positionalArgs = [];
11 |
12 | var level = undefined;
13 | var threads = undefined;
14 | var compress = true;
15 |
16 | for (var i = 0; i < argv.length; ++i) {
17 | if (argv[i][0] !== '-') {
18 | positionalArgs.push(argv[i]);
19 | continue;
20 | }
21 |
22 | if (!isNaN(+argv[i][1])) {
23 | level = +argv[i][1];
24 | continue;
25 | }
26 |
27 | switch (argv[i]) {
28 | case '-d':
29 | case '--decompress':
30 | compress = false;
31 | break;
32 | case '-z':
33 | case '--compress':
34 | compress = true;
35 | break;
36 | case '-t':
37 | case '--threads':
38 | if (!isNaN(+argv[i+1]))
39 | threads = +argv[++i];
40 | else
41 | threads = 0;
42 | break;
43 | default:
44 | case '-h':
45 | case '--help':
46 | usage();
47 | return;
48 | }
49 | }
50 |
51 | function usage() {
52 | process.stdout.write('Usage: \n' +
53 | ' ' + path.basename(process.argv[1]) +
54 | ' [-d|-z] [-t num] [-1|...|-9] [infile] [outfile]\n' +
55 | '\n' +
56 | ' -d, --decompress Decompress infile to outfile\n' +
57 | ' -z, --compress Compress infile to outfile\n' +
58 | ' -t n, --threads n Use n threads for compressing\n' +
59 | ' -1, ..., -9 Specifiy compression level\n' +
60 | ' -h, --help Display this text\n' +
61 | '\n' +
62 | ' defaults to stdin and defaults to stdout.\n');
63 | return;
64 | }
65 |
66 | var input = process.stdin, output = process.stdout;
67 |
68 | if (positionalArgs.length > 0) {
69 | input = fs.createReadStream(positionalArgs.shift());
70 | }
71 |
72 | if (positionalArgs.length > 0) {
73 | output = fs.createWriteStream(positionalArgs.shift());
74 | }
75 |
76 | var opts = {
77 | preset: level || lzma.PRESET_DEFAULT,
78 | threads: threads,
79 | };
80 |
81 | var encoder = lzma.createStream(compress ? 'easyEncoder' : 'autoDecoder', opts);
82 |
83 | input.pipe(encoder).pipe(output);
84 |
85 |
--------------------------------------------------------------------------------
/binding.gyp:
--------------------------------------------------------------------------------
1 | {
2 | "variables": {
3 | "dlldir%": "<(module_root_dir)/build/Release"
4 | },
5 | "targets": [
6 | {
7 | "target_name": "lzma_native",
8 | "sources": [
9 | "src/util.cpp",
10 | "src/liblzma-functions.cpp",
11 | "src/filter-array.cpp",
12 | "src/lzma-stream.cpp",
13 | "src/module.cpp",
14 | "src/mt-options.cpp",
15 | "src/index-parser.cpp"
16 | ],
17 | 'include_dirs': [" nul 2>&1 & copy "<(module_root_dir)/deps/<(arch_lib_path)/liblzma.dll" <(dlldir)/liblzma.dll']
93 | }
94 | ]
95 | } ],
96 | ]
97 | }
98 | ]
99 | }
100 |
--------------------------------------------------------------------------------
/deps/.gitignore:
--------------------------------------------------------------------------------
1 | bin_*/
2 | doc/
3 | include/
4 | *.dll
5 | *.a
6 |
--------------------------------------------------------------------------------
/deps/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/addaleax/lzma-native/287f5ae4daf8240f9d8f73a9908264bb1d325480/deps/.npmignore
--------------------------------------------------------------------------------
/deps/xz-5.2.3-windows.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/addaleax/lzma-native/287f5ae4daf8240f9d8f73a9908264bb1d325480/deps/xz-5.2.3-windows.7z
--------------------------------------------------------------------------------
/deps/xz-5.2.3-windows.7z.sig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/addaleax/lzma-native/287f5ae4daf8240f9d8f73a9908264bb1d325480/deps/xz-5.2.3-windows.7z.sig
--------------------------------------------------------------------------------
/deps/xz-5.2.3.tar.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/addaleax/lzma-native/287f5ae4daf8240f9d8f73a9908264bb1d325480/deps/xz-5.2.3.tar.bz2
--------------------------------------------------------------------------------
/deps/xz-5.2.3.tar.bz2.sig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/addaleax/lzma-native/287f5ae4daf8240f9d8f73a9908264bb1d325480/deps/xz-5.2.3.tar.bz2.sig
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | var stream = require('readable-stream');
5 | var assert = require('assert');
6 | var fs = require('fs');
7 | var util = require('util');
8 |
9 | var native = require('node-gyp-build')(__dirname);
10 |
11 | Object.assign(exports, native);
12 |
13 | // Please do not update this version except as part of a release commit.
14 | exports.version = '8.0.6';
15 |
16 | var Stream = exports.Stream;
17 |
18 | Stream.curAsyncStreamsCount = 0;
19 |
20 | Stream.prototype.getStream = function(options) {
21 | options = options || {};
22 |
23 | return new JSLzmaStream(this, options);
24 | };
25 |
26 | class JSLzmaStream extends stream.Transform {
27 | constructor(nativeStream, options) {
28 | super(options);
29 |
30 | this.nativeStream = nativeStream;
31 | this.synchronous = (options.synchronous || !native.asyncCodeAvailable) ? true : false;
32 | this.chunkCallbacks = [];
33 |
34 | this.totalIn_ = 0;
35 | this.totalOut_ = 0;
36 |
37 | this._writingLastChunk = false;
38 | this._isFinished = false;
39 |
40 | if (!this.synchronous) {
41 | Stream.curAsyncStreamsCount++;
42 |
43 | var oldCleanup = this.cleanup;
44 | var countedCleanup = false;
45 | this.cleanup = () => {
46 | if (countedCleanup === false) {
47 | Stream.curAsyncStreamsCount--;
48 | countedCleanup = true;
49 | }
50 | oldCleanup.call(this);
51 | };
52 | }
53 |
54 | // always clean up in case of error
55 | this.once('error-cleanup', this.cleanup);
56 |
57 | this.nativeStream.bufferHandler = (buf, processedChunks, err, totalIn, totalOut) => {
58 | if (totalIn !== null) {
59 | this.totalIn_ = totalIn;
60 | this.totalOut_ = totalOut;
61 | }
62 |
63 | setImmediate(() => {
64 | if (err) {
65 | this.push(null);
66 | this.emit('error-cleanup', err);
67 | this.emit('error', err);
68 | return;
69 | }
70 |
71 | if (totalIn !== null) {
72 | this.emit('progress', {
73 | totalIn: this.totalIn_,
74 | totalOut: this.totalOut_
75 | });
76 | }
77 |
78 | if (typeof processedChunks === 'number') {
79 | assert.ok(processedChunks <= this.chunkCallbacks.length);
80 |
81 | var chunkCallbacks = this.chunkCallbacks.splice(0, processedChunks);
82 |
83 | while (chunkCallbacks.length > 0)
84 | chunkCallbacks.shift().call(this);
85 | } else if (buf === null) {
86 | if (this._writingLastChunk) {
87 | this.push(null);
88 | } else {
89 | // There may be additional members in the file.
90 | // Reset and set _isFinished to tell `_flush()` that nothing
91 | // needs to be done.
92 | this._isFinished = true;
93 |
94 | if (this.nativeStream && this.nativeStream._restart) {
95 | this.nativeStream._restart();
96 | } else {
97 | this.push(null);
98 | }
99 | }
100 | } else {
101 | this.push(buf);
102 | }
103 | });
104 | };
105 |
106 | if (typeof options.bufsize !== 'undefined') {
107 | this.bufsize = options.bufsize;
108 | }
109 | }
110 |
111 | get bufsize() {
112 | return this.setBufsize(null);
113 | }
114 |
115 | set bufsize(n) {
116 | if (typeof n !== 'number' || n <= 0) {
117 | throw new TypeError('bufsize must be a positive number');
118 | }
119 |
120 | return this.setBufsize(n);
121 | }
122 |
123 | totalIn() {
124 | return this.totalIn_;
125 | }
126 |
127 | totalOut() {
128 | return this.totalOut_;
129 | }
130 |
131 | cleanup() {
132 | if (this.nativeStream) {
133 | this.nativeStream.resetUnderlying();
134 | }
135 |
136 | this.nativeStream = null;
137 | }
138 |
139 | _transform(chunk, encoding, callback) {
140 | if (!this.nativeStream) return;
141 | // Split the chunk at 'YZ'. This is used to have a clean boundary at the
142 | // end of each `.xz` file stream.
143 | var possibleEndIndex = bufferIndexOfYZ(chunk);
144 | if (possibleEndIndex !== -1) {
145 | possibleEndIndex += 2;
146 | if (possibleEndIndex !== chunk.length) {
147 | this._transform(chunk.slice(0, possibleEndIndex), encoding, () => {
148 | this._transform(chunk.slice(possibleEndIndex), encoding, callback);
149 | });
150 |
151 | return;
152 | }
153 | }
154 |
155 | if (this._isFinished && chunk) {
156 | chunk = skipLeadingZeroes(chunk);
157 |
158 | if (chunk.length > 0) {
159 | // Real data from a second stream member in the file!
160 | this._isFinished = false;
161 | }
162 | }
163 |
164 | if (chunk && chunk.length === 0) {
165 | return callback();
166 | }
167 |
168 | this.chunkCallbacks.push(callback);
169 |
170 | try {
171 | this.nativeStream.code(chunk, !this.synchronous);
172 | } catch (e) {
173 | this.emit('error-cleanup', e);
174 | this.emit('error', e);
175 | }
176 | }
177 |
178 | _writev(chunks, callback) {
179 | chunks = chunks.map(chunk => chunk.chunk);
180 | this._write(Buffer.concat(chunks), null, callback);
181 | }
182 |
183 | _flush(callback) {
184 | this._writingLastChunk = true;
185 |
186 | if (this._isFinished) {
187 | this.cleanup();
188 | callback(null);
189 | return;
190 | }
191 |
192 | this._transform(null, null, function() {
193 | this.cleanup();
194 | callback.apply(this, arguments);
195 | });
196 | }
197 | }
198 |
199 | // add all methods from the native Stream
200 | Object.getOwnPropertyNames(native.Stream.prototype).forEach(function(key) {
201 | if (typeof native.Stream.prototype[key] !== 'function' || key === 'constructor')
202 | return;
203 | JSLzmaStream.prototype[key] = function() {
204 | return this.nativeStream[key].apply(this.nativeStream, arguments);
205 | };
206 | });
207 |
208 | Stream.prototype.rawEncoder = function(options) {
209 | return this.rawEncoder_(options.filters || []);
210 | };
211 |
212 | Stream.prototype.rawDecoder = function(options) {
213 | return this.rawDecoder_(options.filters || []);
214 | };
215 |
216 | Stream.prototype.easyEncoder = function(options) {
217 | var preset = options.preset || exports.PRESET_DEFAULT;
218 | var check = options.check || exports.CHECK_CRC32;
219 |
220 | if (typeof options.threads !== 'undefined' && options.threads !== null) {
221 | return this.mtEncoder_(Object.assign({
222 | preset: preset,
223 | filters: null,
224 | check: check
225 | }, options));
226 | } else {
227 | return this.easyEncoder_(preset, check);
228 | }
229 | };
230 |
231 | Stream.prototype.streamEncoder = function(options) {
232 | var filters = options.filters || [];
233 | var check = options.check || exports.CHECK_CRC32;
234 |
235 | if (typeof options.threads !== 'undefined' && options.threads !== null) {
236 | return this.mtEncoder_(Object.assign({
237 | preset: null,
238 | filters: filters,
239 | check: check
240 | }, options));
241 | } else {
242 | return this.streamEncoder_(filters, check);
243 | }
244 | };
245 |
246 | Stream.prototype.streamDecoder = function(options) {
247 | this._initOptions = options;
248 | this._restart = function() {
249 | this.resetUnderlying();
250 | this.streamDecoder(this._initOptions);
251 | };
252 |
253 | return this.streamDecoder_(options.memlimit || null, options.flags || 0);
254 | };
255 |
256 | Stream.prototype.autoDecoder = function(options) {
257 | this._initOptions = options;
258 | this._restart = function() {
259 | this.resetUnderlying();
260 | this.autoDecoder(this._initOptions);
261 | };
262 |
263 | return this.autoDecoder_(options.memlimit || null, options.flags || 0);
264 | };
265 |
266 | Stream.prototype.aloneDecoder = function(options) {
267 | return this.aloneDecoder_(options.memlimit || null);
268 | };
269 |
270 | /* helper functions for easy creation of streams */
271 | var createStream =
272 | exports.createStream = function(coder, options) {
273 | if (['number', 'object'].indexOf(typeof coder) !== -1 && !options) {
274 | options = coder;
275 | coder = null;
276 | }
277 |
278 | if (parseInt(options) === parseInt(options))
279 | options = {preset: parseInt(options)};
280 |
281 | coder = coder || 'easyEncoder';
282 | options = options || {};
283 |
284 | var stream = new Stream();
285 | stream[coder](options);
286 |
287 | if (options.memlimit)
288 | stream.memlimitSet(options.memlimit);
289 |
290 | return stream.getStream(options);
291 | };
292 |
293 | exports.createCompressor = function(options) {
294 | return createStream('easyEncoder', options);
295 | };
296 |
297 | exports.createDecompressor = function(options) {
298 | return createStream('autoDecoder', options);
299 | };
300 |
301 | exports.crc32 = function(input, encoding, presetCRC32) {
302 | if (typeof encoding === 'number') {
303 | presetCRC32 = encoding;
304 | encoding = null;
305 | }
306 |
307 | if (typeof input === 'string')
308 | input = Buffer.from(input, encoding);
309 |
310 | return exports.crc32_(input, presetCRC32 || 0);
311 | };
312 |
313 | /* compatibility: node-xz (https://github.com/robey/node-xz) */
314 | exports.Compressor = function(preset, options) {
315 | options = Object.assign({}, options);
316 |
317 | if (preset)
318 | options.preset = preset;
319 |
320 | return createStream('easyEncoder', options);
321 | };
322 |
323 | exports.Decompressor = function(options) {
324 | return createStream('autoDecoder', options);
325 | };
326 |
327 | /* compatibility: LZMA-JS (https://github.com/nmrugg/LZMA-JS) */
328 | function singleStringCoding(stream, string, on_finish, on_progress) {
329 | on_progress = on_progress || function() {};
330 | on_finish = on_finish || function() {};
331 |
332 | // possibly our input is an array of byte integers
333 | // or a typed array
334 | if (!Buffer.isBuffer(string))
335 | string = Buffer.from(string);
336 |
337 | var deferred = {}, failed = false;
338 |
339 | stream.once('error', function(err) {
340 | failed = true;
341 | on_finish(null, err);
342 | });
343 |
344 | // emulate Promise.defer()
345 | deferred.promise = new Promise(function(resolve, reject) {
346 | deferred.resolve = resolve;
347 | deferred.reject = reject;
348 | });
349 |
350 | // Since using the Promise API is optional, generating unhandled
351 | // rejections is not okay.
352 | deferred.promise.catch(noop);
353 |
354 | stream.once('error', function(e) {
355 | deferred.reject(e);
356 | });
357 |
358 | var buffers = [];
359 |
360 | stream.on('data', function(b) {
361 | buffers.push(b);
362 | });
363 |
364 | stream.once('end', function() {
365 | var result = Buffer.concat(buffers);
366 |
367 | if (!failed) {
368 | on_progress(1.0);
369 | on_finish(result);
370 | }
371 |
372 | if (deferred)
373 | deferred.resolve(result);
374 | });
375 |
376 | on_progress(0.0);
377 |
378 | stream.end(string);
379 |
380 | if (deferred)
381 | return deferred.promise;
382 | }
383 |
384 | exports.LZMA = function() {
385 | return {
386 | compress: function(string, mode, on_finish, on_progress) {
387 | var opt = {};
388 |
389 | if (parseInt(mode) === parseInt(mode) && mode >= 1 && mode <= 9)
390 | opt.preset = parseInt(mode);
391 |
392 | var stream = createStream('aloneEncoder', opt);
393 |
394 | return singleStringCoding(stream, string, on_finish, on_progress);
395 | },
396 | decompress: function(byte_array, on_finish, on_progress) {
397 | var stream = createStream('autoDecoder');
398 |
399 | return singleStringCoding(stream, byte_array, on_finish, on_progress);
400 | },
401 | // dummy, we don’t use web workers
402 | worker: function() { return null; }
403 | };
404 | };
405 |
406 | exports.compress = function(string, opt, on_finish) {
407 | if (typeof opt === 'function') {
408 | on_finish = opt;
409 | opt = {};
410 | }
411 |
412 | var stream = createStream('easyEncoder', opt);
413 | return singleStringCoding(stream, string, on_finish);
414 | };
415 |
416 | exports.decompress = function(string, opt, on_finish) {
417 | if (typeof opt === 'function') {
418 | on_finish = opt;
419 | opt = {};
420 | }
421 |
422 | var stream = createStream('autoDecoder', opt);
423 | return singleStringCoding(stream, string, on_finish);
424 | };
425 |
426 | if (util.promisify) {
427 | exports.compress[util.promisify.custom] = exports.compress;
428 | exports.decompress[util.promisify.custom] = exports.decompress;
429 | }
430 |
431 | exports.isXZ = function(buf) {
432 | return buf && buf.length >= 6 &&
433 | buf[0] === 0xfd &&
434 | buf[1] === 0x37 &&
435 | buf[2] === 0x7a &&
436 | buf[3] === 0x58 &&
437 | buf[4] === 0x5a &&
438 | buf[5] === 0x00;
439 | };
440 |
441 | exports.parseFileIndex = function(options, callback) {
442 | if (typeof options !== 'object') {
443 | throw new TypeError('parseFileIndex needs an options object');
444 | }
445 |
446 | var p = new native.IndexParser();
447 |
448 | if (typeof options.fileSize !== 'number') {
449 | throw new TypeError('parseFileeIndex needs options.fileSize');
450 | }
451 |
452 | if (typeof options.read !== 'function') {
453 | throw new TypeError('parseFileIndex needs a read callback');
454 | }
455 |
456 | p.init(options.fileSize, options.memlimit || 0);
457 | p.read_cb = function(count, offset) {
458 | var inSameTick = true;
459 | var bytesRead = count;
460 |
461 | options.read(count, offset, function(err, buffer) {
462 | if (Buffer.isBuffer(err)) {
463 | buffer = err;
464 | err = null;
465 | }
466 |
467 | if (err) {
468 | if (typeof callback === 'undefined') {
469 | throw err;
470 | }
471 |
472 | return callback(err, null);
473 | }
474 |
475 | p.feed(buffer);
476 | bytesRead = buffer.length;
477 |
478 | if (inSameTick) {
479 | // The call to parse() is still on the call stack and will continue
480 | // seamlessly.
481 | return;
482 | }
483 |
484 | // Kick off parsing again.
485 | var info;
486 |
487 | try {
488 | info = p.parse();
489 | } catch (e) {
490 | return callback(e, null);
491 | }
492 |
493 | if (info !== true) {
494 | return callback(null, cleanupIndexInfo(info));
495 | }
496 | });
497 |
498 | inSameTick = false;
499 |
500 | return bytesRead;
501 | };
502 |
503 | var info;
504 | try {
505 | info = p.parse();
506 | } catch (e) {
507 | if (typeof callback !== 'undefined') {
508 | callback(e, null);
509 | return;
510 | }
511 |
512 | throw e;
513 | }
514 |
515 | if (info !== true) {
516 | info = cleanupIndexInfo(info);
517 | if (typeof callback !== 'undefined' && info !== true) {
518 | callback(null, info);
519 | }
520 |
521 | return info;
522 | }
523 | };
524 |
525 | exports.parseFileIndexFD = function(fd, callback) {
526 | return fs.fstat(fd, function(err, stats) {
527 | if (err) {
528 | return callback(err, null);
529 | }
530 |
531 | exports.parseFileIndex({
532 | fileSize: stats.size,
533 | read: function(count, offset, cb) {
534 | var buffer = Buffer.allocUnsafe(count);
535 |
536 | fs.read(fd, buffer, 0, count, offset, function(err, bytesRead, buffer) {
537 | if (err) {
538 | return cb(err, null);
539 | }
540 |
541 | if (bytesRead !== count) {
542 | return cb(new Error('Truncated file!'), null);
543 | }
544 |
545 | cb(null, buffer);
546 | });
547 | }
548 | }, callback);
549 | });
550 | };
551 |
552 | function cleanupIndexInfo(info) {
553 | var checkFlags = info.checks;
554 |
555 | info.checks = [];
556 | for (var i = 0; i < exports.CHECK_ID_MAX; i++) {
557 | if (checkFlags & (1 << i))
558 | info.checks.push(i);
559 | }
560 |
561 | return info;
562 | }
563 |
564 | function skipLeadingZeroes(buffer) {
565 | var i;
566 | for (i = 0; i < buffer.length; i++) {
567 | if (buffer[i] !== 0x00)
568 | break;
569 | }
570 |
571 | return buffer.slice(i);
572 | }
573 |
574 | function bufferIndexOfYZ(chunk) {
575 | if (!chunk) {
576 | return -1;
577 | }
578 |
579 | if (chunk.indexOf) {
580 | return chunk.indexOf('YZ');
581 | }
582 |
583 | var i;
584 | for (i = 0; i < chunk.length - 1; i++) {
585 | if (chunk[i] === 0x59 && chunk[i+1] === 0x5a) {
586 | return i;
587 | }
588 | }
589 |
590 | return -1;
591 | }
592 |
593 | function noop() {}
594 |
595 | })();
596 |
--------------------------------------------------------------------------------
/liblzma-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | case $(uname | tr '[:upper:]' '[:lower:]') in
5 | *bsd) alias make='gmake';;
6 | *)
7 | esac
8 |
9 | cd "$1/liblzma"
10 | make
11 | make install
12 |
--------------------------------------------------------------------------------
/liblzma-config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | SRC_TARBALL="$2"
5 | TARGET_DIR="$1/liblzma"
6 |
7 | mkdir -p "$TARGET_DIR"
8 | cd "$TARGET_DIR"
9 |
10 | tar xvjf "$SRC_TARBALL" >node_liblzma_config.log 2>&1
11 |
12 | export CFLAGS="-fPIC $CFLAGS"
13 |
14 | # Fix build on Apple Silicon
15 | if [ $(uname) = "Darwin" -a $(uname -m) = "arm64" ]; then
16 | XZ_SRC_DIR=$(ls | grep xz-*)
17 | sed -i '' 's/\tnone)/\tarm64-*)\n\t\tbasic_machine=$(echo $basic_machine | sed "s\/arm64\/aarch64\/")\n\t\t;;\n\t\tnone)/g' $XZ_SRC_DIR/build-aux/config.sub
18 | fi
19 |
20 | sh xz-*/configure --enable-static --disable-shared --disable-scripts --disable-lzmainfo \
21 | --disable-lzma-links --disable-lzmadec --disable-xzdec --disable-xz --disable-rpath \
22 | --prefix="$TARGET_DIR/build" CFLAGS="$CFLAGS" >>node_liblzma_config.log 2>&1
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lzma-native",
3 | "version": "8.0.6",
4 | "engines": {
5 | "node": ">=10.0.0"
6 | },
7 | "author": {
8 | "name": "Anna Henningsen",
9 | "email": "anna@addaleax.net"
10 | },
11 | "description": "Provides bindings to the native liblzma library (.xz file format, among others)",
12 | "main": "index",
13 | "bin": {
14 | "lzmajs": "bin/lzmajs"
15 | },
16 | "dependencies": {
17 | "node-addon-api": "^3.1.0",
18 | "node-gyp-build": "^4.2.1",
19 | "readable-stream": "^3.6.0"
20 | },
21 | "keywords": [
22 | "lzma",
23 | "compression",
24 | "crc32",
25 | "xz",
26 | "liblzma"
27 | ],
28 | "homepage": "https://github.com/addaleax/lzma-native",
29 | "license": "MIT",
30 | "repository": {
31 | "type": "git",
32 | "url": "https://github.com/addaleax/lzma-native.git"
33 | },
34 | "scripts": {
35 | "install": "node-gyp-build",
36 | "prebuild": "prebuildify --napi --electron-compat",
37 | "prepack": "[ $(ls prebuilds | wc -l) = '6' ] || (echo 'Some prebuilds are missing'; exit 1)",
38 | "test": "mocha --expose-gc -s 1000 -t 15000",
39 | "prepare": "npm run prepare-win32 || true",
40 | "prepare-win32": "cd deps && 7z x -y xz-5.2.3-windows.7z bin_i686/liblzma.dll bin_x86-64/liblzma.dll include doc/liblzma.def",
41 | "jshint": "jshint ."
42 | },
43 | "gypfile": true,
44 | "bugs": {
45 | "url": "https://github.com/addaleax/lzma-native/issues"
46 | },
47 | "devDependencies": {
48 | "bl": "^4.1.0",
49 | "jshint": "^2.12.0",
50 | "mocha": "^8.3.1",
51 | "prebuildify": "^5.0.0"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/filter-array.cpp:
--------------------------------------------------------------------------------
1 | #include "liblzma-node.hpp"
2 |
3 | namespace lzma {
4 |
5 | FilterArray::FilterArray(Value val) {
6 | Env env = val.Env();
7 | HandleScope handle_scope(env);
8 |
9 | if (!val.IsArray())
10 | throw TypeError::New(env, "Filter array expected");
11 | Array arr = val.As();
12 |
13 | size_t len = arr.Length();
14 |
15 | String id_ = String::New(env, "id");
16 | String options_ = String::New(env, "options");
17 |
18 | for (size_t i = 0; i < len; ++i) {
19 | Value entry_v = arr[i];
20 | if (!entry_v.IsObject() || !entry_v.As