{"id":13493115,"url":"https://github.com/OlehKulykov/PLzmaSDK","last_synced_at":"2025-03-28T11:31:36.155Z","repository":{"id":37696526,"uuid":"291093106","full_name":"OlehKulykov/PLzmaSDK","owner":"OlehKulykov","description":"PLzmaSDK is (Portable, Patched, Package, cross-P-latform) Lzma SDK.","archived":false,"fork":false,"pushed_at":"2024-04-02T15:14:01.000Z","size":8423,"stargazers_count":74,"open_issues_count":6,"forks_count":21,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-04-13T21:05:04.713Z","etag":null,"topics":["7zip","c","cocoapods","compress","compression","cpp","extract","js","lzma","lzma-sdk","lzma2","multi-volume","multi-volume-archives","plzmasdk","swift","tar","tarball","xz"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OlehKulykov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"patreon":"plzmasdk","open_collective":"plzmasdk"}},"created_at":"2020-08-28T16:22:03.000Z","updated_at":"2024-04-03T03:29:53.000Z","dependencies_parsed_at":"2024-01-22T20:15:07.562Z","dependency_job_id":"24bfdda1-52c2-4cc5-95d7-347b2da63f38","html_url":"https://github.com/OlehKulykov/PLzmaSDK","commit_stats":{"total_commits":122,"total_committers":7,"mean_commits":"17.428571428571427","dds":0.639344262295082,"last_synced_commit":"9f48b99d8aee09c98184e4610b40ee87487d1643"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlehKulykov%2FPLzmaSDK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlehKulykov%2FPLzmaSDK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlehKulykov%2FPLzmaSDK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlehKulykov%2FPLzmaSDK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OlehKulykov","download_url":"https://codeload.github.com/OlehKulykov/PLzmaSDK/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245615004,"owners_count":20644376,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["7zip","c","cocoapods","compress","compression","cpp","extract","js","lzma","lzma-sdk","lzma2","multi-volume","multi-volume-archives","plzmasdk","swift","tar","tarball","xz"],"created_at":"2024-07-31T19:01:12.343Z","updated_at":"2025-03-28T11:31:36.144Z","avatar_url":"https://github.com/OlehKulykov.png","language":"C","funding_links":["https://patreon.com/plzmasdk","https://opencollective.com/plzmasdk"],"categories":["C"],"sub_categories":[],"readme":"![platform](https://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Android%20%7C%20Windows%20%7C%20Linux%20%7C%20Unix-lightgrey.svg)\n![language](https://img.shields.io/badge/language-Swift%20%7C%20Objective%E2%80%93C%20%7C%20C%20%7C%20C++%20%7C%20JavaScript-brightgreen.svg)\n[![Cocoapods](https://img.shields.io/cocoapods/l/PLzmaSDK)](https://cocoapods.org/pods/PLzmaSDK)\n[![Cocoapods](https://img.shields.io/cocoapods/v/PLzmaSDK)](https://cocoapods.org/pods/PLzmaSDK)\n[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager)\n[![GitHub release](https://img.shields.io/github/release/OlehKulykov/PLzmaSDK.svg)](https://github.com/OlehKulykov/PLzmaSDK/releases)\n[![node-current](https://img.shields.io/node/v/plzmasdk)](https://www.npmjs.com/package/plzmasdk)\n[![Build Status](https://travis-ci.org/OlehKulykov/PLzmaSDK.svg?branch=master)](https://travis-ci.org/OlehKulykov/PLzmaSDK)\n[![Build status](https://ci.appveyor.com/api/projects/status/1mb5w6nlht1ar2p8/branch/master?svg=true)](https://ci.appveyor.com/project/OlehKulykov/plzmasdk/branch/master)\n\n\n**P**LzmaSDK is (**P**ortable, **P**atched, **P**ackage, cross-**P**-latform) Lzma SDK.\nBased on original [LZMA SDK] version 24.09 and patched for unix platforms.\nAvailable for all Apple's platforms(iOS, macOS, tvOS, watchOS), Android, Windows, Linux and any unix'es.\n\n\n### Features / detailed description\n-----------\n- The SDK is available for the next programming languages:\n  * [Swift] via [Swift Package Manager] or [CocoaPods].\n  * [Objective-C] via [CocoaPods].\n  * [JavaScript] via [npm].\n  * Pure C++ via [git] + [CMake] or copy 2 main lib headers([libplzma.h] and [libplzma.hpp] files) and [src] folder to your project.\n  * Pure C, also via [git] + [CMake] or copy 2 main lib headers([libplzma.h] and [libplzma.hpp] files) and [src] folder to your project. But this internal C bindings code might be disabled via [CMake]'s boolean option `LIBPLZMA_OPT_NO_C_BINDINGS:BOOL=YES` or preprocessor definition `LIBPLZMA_NO_C_BINDINGS=1`, see below.\n- Supports next archives:\n  * [7z]. Both, encrypted/password-protected and unencrypted archive items-list and it's content. [Lzma] and [Lzma2] compression methods.\n  * [xz]. [Lzma2] compression method.\n  * [tar]/[tarball]. *.tar, *.tar.xz and *.tar.7z archives.\n- Supports list, test, extract and compress operations. All these operations can be executed in a separate thread and aborted during the process.\n- Supports [7z] multivolume archives.\n- Thread safe encoder, decoder and progress tracking. Depending of usage, you can disable all thread synchronizations via [CMake]'s boolean option `LIBPLZMA_OPT_THREAD_UNSAFE:BOOL=YES` or preprocessor definition `LIBPLZMA_THREAD_UNSAFE=1`.\n- Supports memory and file IO streams. The extracting and compressing might be from ⇔ to memory or file.\n- Support extracting and compressing archive files with size more than 4GB(x64 support).\n- Track smoothed progress.\n- Full UTF8 support.\n- Available for any platform with compiller which supports the [C++11] standard. Let's say, almost everywhere nowadays.\n- No external dependencies. Also no [STL] (of couse not in a public interface and internally).\n- The SDK is organized as C **and** C++ library at the same time. And supports static and dynamic linking.\n  * The [libplzma.h] - the library header for a pure C environment. Contains generic functions, types and optional bindings to the whole functionality of the library. Currently uses with [Swift Package Manager] and [CocoaPods].\n  * The [libplzma.hpp] - the library header for a pure C++ environment and must be used together with [libplzma.h] header. Currently uses with [npm] native module and [Objective-C].\n  * The [swift](https://github.com/OlehKulykov/PLzmaSDK/tree/master/swift) directory contains [Swift] part of the SDK and available via [Swift Package Manager] and [CocoaPods], see ```Installation``` section.\n  * The [objc](https://github.com/OlehKulykov/PLzmaSDK/tree/master/objc) directory contains [Objective-C] part of the SDK and available via [CocoaPods], see ```Installation``` section.\n  * The [node](https://github.com/OlehKulykov/PLzmaSDK/tree/master/node) directory contains Node.js native, inline module implementation. \n\n### Optional features\nAll optional features are enabled by default, but they might be disabled during the build process to reduce the binary size, and of course, if you are not planning to use them.\n\n- [tar]/[tarball] archive support. To disable, use the [CMake]'s boolean option `LIBPLZMA_OPT_NO_TAR:BOOL=YES` or preprocessor definition `LIBPLZMA_NO_TAR=1`\n- Thread safety. To disable, use the [CMake]'s boolean option `LIBPLZMA_OPT_THREAD_UNSAFE:BOOL=YES` or preprocessor definition `LIBPLZMA_THREAD_UNSAFE=1`\n- Progress tracking. To disable, use the [CMake]'s boolean option `LIBPLZMA_OPT_NO_PROGRESS:BOOL=YES` or preprocessor definition `LIBPLZMA_NO_PROGRESS=1`\n- C bindings to the whole functionality of the library in [libplzma.h] header. To disable, use the [CMake]'s boolean option `LIBPLZMA_OPT_NO_C_BINDINGS:BOOL=YES` or preprocessor definition `LIBPLZMA_NO_C_BINDINGS=1`\n- Crypto functionality. Not recommended! But possible. Do this only if you know what are you doing! To disable, use the [CMake]'s boolean option `LIBPLZMA_OPT_NO_CRYPTO:BOOL=YES` or preprocessor definition `LIBPLZMA_NO_CRYPTO=1`\n\n### Installation\n-----------\n#### Swift Package Manager\n```swift\n.package(url: \"https://github.com/OlehKulykov/PLzmaSDK.git\", .exact(\"1.5.0\"))\n```\n\n#### CocoaPods Podfile (Swift)\n```ruby\nuse_frameworks!\nplatform :ios, '11.0'\n\ntarget '\u003cREPLACE_WITH_YOUR_TARGET\u003e' do\n    pod 'PLzmaSDK', '1.5.0'\nend\n```\n\n#### CocoaPods Podfile (Objective-C)\n```ruby\nuse_frameworks!\nplatform :ios, '9.0'\n\ntarget '\u003cREPLACE_WITH_YOUR_TARGET\u003e' do\n    pod 'PLzmaSDK-ObjC', '1.5.0'\nend\n```\n\n#### npm via 'package.json'\n```json\n{\n  \"engines\": {\n    \"node\": \"\u003e=13.0.0\",\n    \"npm\": \"\u003e=6.0.0\"\n  },\n  \"dependencies\": {\n    \"plzmasdk\": \"1.5.0\"\n  }\n}\n```\n\n#### Android NDK\n```bash\ncd \u003cPATH_TO_ANDROID_NDK\u003e\n./ndk-build NDK_PROJECT_PATH=\u003cPATH_TO_PLZMASDK\u003e/PLzmaSDK/android\n```\n\n#### CMake Unix\n```bash\ncd PLzmaSDK\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release ..\nmake -j4\n```\n\n#### CMake Windows (MSVC)\n```bash\ncd PLzmaSDK\nmd build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release ..\ncmake --build . --config Release --parallel 4\n```\n\n#### CMake Windows (MinGW)\n```bash\n...\ncmake -G\"MinGW Makefiles\" -DCMAKE_MAKE_PROGRAM=mingw32-make -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release ..\ncmake --build . --config Release --parallel 4\n```\n\n### Examples\n-----------\n#### Extract or test\n##### Open, list and select archive items for extracting or testing.  \nThe process consists of four steps:\n1. Create a source input stream for reading archive file content. The input stream might be created with:\n   1. The path to the archive file.\n   2. The archive file content in memory, i.e. using const memory or it's copy for internal usage.\n   3. The custom read/seek callbacks(C/C++ only).\n2. Create decoder with source input stream, type of the archive and optional progress delegate.\n   1. Optionaly provide the password to open and list encrypted archive and for a future extracting or testing.\n3. Select archive items for extracting or testing. Migth be skiped if you want to process all items(the whole archive), see below.\n   1. Select all archive items as is.\n   2. Retrieve the number of items, iterate them by index, filter and/or select.\n4. Extract or test selected archive items. The extract process might be:\n   1. Extract all items to a directory. In this case, you can skip the step #3.\n   2. Extract selected items to a directory.\n   3. Extract each item to a custom out-stream. The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.\n\n##### Swift\n```swift\ndo {\n    // 1. Create a source input stream for reading archive file content.\n    //  1.1. Create a source input stream with the path to an archive file.\n    let archivePath = try Path(\"path/to/archive.7z\")\n    let archivePathInStream = try InStream(path: archivePath)\n\n    //  1.2. Create a source input stream with the file content.\n    let archiveData = Data(...)\n    let archiveDataInStream = try InStream(dataNoCopy: archiveData) // also available Data(dataCopy: Data)\n\n    // 2. Create decoder with source input stream, type of archive and optional delegate.\n    let decoder = try Decoder(stream: archiveDataInStream /* archivePathInStream */, fileType: .sevenZ, delegate: self)\n    \n    //  2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.\n    try decoder.setPassword(\"1234\")\n    \n    let opened = try decoder.open()\n    \n    // 3. Select archive items for extracting or testing.\n    //  3.1. Select all archive items.\n    let allArchiveItems = try decoder.items()\n    \n    //  3.2. Get the number of items, iterate items by index, filter and select items.\n    let numberOfArchiveItems = try decoder.count()\n    let selectedItemsDuringIteration = try ItemArray(capacity: numberOfArchiveItems)\n    let selectedItemsToStreams = try ItemOutStreamArray()\n    for itemIndex in 0..\u003cnumberOfArchiveItems {\n        let item = try decoder.item(at: itemIndex)\n        try selectedItemsDuringIteration.add(item: item)\n        try selectedItemsToStreams.add(item: item, stream: OutStream()) // to memory stream\n    }\n    \n    // 4. Extract or test selected archive items. The extract process might be:\n    //  4.1. Extract all items to a directory. In this case, you can skip the step #3.\n    let extracted = try decoder.extract(to: Path(\"path/outdir\"))\n    \n    //  4.2. Extract selected items to a directory.\n    let extracted = try decoder.extract(items: selectedItemsDuringIteration, to: Path(\"path/outdir\"))\n    \n    //  4.3. Extract each item to a custom out-stream. \n    //       The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.\n    let extracted = try decoder.extract(itemsToStreams: selectedItemsToStreams)\n} catch let exception as Exception {\n    print(\"Exception: \\(exception)\")\n}\n```\n\n##### JavaScript\n```javascript\nconst plzma = require('plzmasdk');\n\ntry {\n    // 1. Create a source input stream for reading archive file content.\n    //  1.1. Create a source input stream with the path to an archive file.\n    const archivePath = plzma.Path(__dirname).append('path/to/archive.7z');\n    const archivePathInStream = new plzma.InStream(archivePath /* 'path/to/archive.7z' */);\n\n    //  1.2. Create a source input stream with the file content.\n    const archiveData = new ArrayBuffer(...);\n    const archiveDataInStream = new plzma.InStream(archiveData);\n\n    // 2. Create decoder with source input stream, type of archive and optional delegate.\n    const decoder = new plzma.Decoder(archivePathInStream, plzma.FileType.sevenZ);\n    decoder.setProgressDelegate((path, progress) =\u003e console.log(`Delegating progress, path: ${path}, progress: ${progress}`) );\n\n    //  2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.\n    decoder.setPassword('1234');\n\n    const opened = await decoder.openAsync(); // also available sync. version 'decoder.open()'\n\n    // 3. Select archive items for extracting or testing.\n    //  3.1. Select all archive items.\n    const allArchiveItems = decoder.items;\n\n    //  3.2. Get the number of items, iterate items by index, filter and select items.\n    const selectedItemsDuringIteration = [];\n    const selectedItemsToStreams = new Map();\n    for (let itemIndex = 0, numberOfArchiveItems = decoder.count; itemIndex \u003c  numberOfArchiveItems; itemIndex++) {\n        const item = decoder.itemAt(itemIndex);\n        selectedItemsDuringIteration.push(item);\n        selectedItemsToStreams.set(item, plzma.OutStream()); // to memory stream\n    }\n    \n    // 4. Extract or test selected archive items. The extract process might be:\n    //  4.1. Extract all items to a directory. In this case, you can skip the step #3.\n    const extracted = await decoder.extractAsync('path/outdir'); // also available sync. version 'decoder.extract()'\n    \n    //  4.2. Extract selected items to a directory.\n    const extracted = await decoder.extractAsync(selectedItemsDuringIteration, 'path/outdir'); // also available sync. version 'decoder.extract()'\n    \n    //  4.3. Extract each item to a custom out-stream. \n    //       The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.\n    const extracted = await decoder.extractAsync(selectedItemsToStreams); // also available sync. version 'decoder.extract()'\n} catch (error) {\n    console.log(`Exception: ${error}`);\n}\n```\n\n##### C++\n```cpp\ntry {\n    // 1. Create a source input stream for reading archive file content.\n    //  1.1. Create a source input stream with the path to an archive file.\n    Path archivePath(\"path/to/archive.7z\"); // Path(L\"C:\\\\\\\\path\\\\to\\\\archive.7z\");\n    auto archivePathInStream = makeSharedInStream(archivePath /* std::move(archivePath) */);\n    \n    //  1.2. Create a source input stream with the file content.\n    auto archiveDataInStream = makeSharedInStream(\u003cFILE DATA\u003e, \u003cFILE SIZE\u003e);\n    \n    // 2. Create decoder with source input stream, type of archive and provide optional delegate.\n    auto decoder = makeSharedDecoder(archiveDataInStream, plzma_file_type_7z);\n    decoder-\u003esetProgressDelegate(this);\n    \n    //  2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.\n    decoder-\u003esetPassword(\"1234\"); // decoder-\u003esetPassword(L\"1234\");\n        \n    bool opened = decoder-\u003eopen();\n    \n    // 3. Select archive items for extracting or testing.\n    //  3.1. Select all archive items.\n    auto allArchiveItems = decoder-\u003eitems();\n\n    //  3.2. Get the number of items, iterate items by index, filter and select items.\n    size_t numberOfArchiveItems = decoder-\u003ecount();\n    auto selectedItemsDuringIteration = makeShared\u003cItemArray\u003e(numberOfArchiveItems);\n    auto selectedItemsToStreams = makeShared\u003cItemOutStreamArray\u003e();\n    for (size_t itemIndex = 0; itemIndex \u003c numberOfArchiveItems; itemIndex++) {\n        auto item = decoder-\u003eitemAt(itemIndex);\n        selectedItemsDuringIteration-\u003epush(item /* std::move(item) */);\n        selectedItemsToStreams-\u003epush(Pair\u003cSharedPtr\u003cItem\u003e, SharedPtr\u003cOutStream\u003e \u003e(item, makeSharedOutStream())); // to memory stream\n    }\n    \n    // 4. Extract or test selected archive items. The extract process might be:\n    //  4.1. Extract all items to a directory. In this case, you can skip the step #3.\n    bool extracted = decoder-\u003eextract(Path(\"path/outdir\"));\n    \n    //  4.2. Extract selected items to a directory.\n    bool extracted = decoder-\u003eextract(selectedItemsDuringIteration, Path(\"path/outdir\"));\n    \n    //  4.3. Extract each item to a custom out-stream. \n    //       The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.\n    bool extracted = decoder-\u003eextract(selectedItemsToStreams);\n} catch (const Exception \u0026 exception) {\n    std::cout \u003c\u003c \"Exception: \" \u003c\u003c exception.what() \u003c\u003c std::endl;\n}\n```\n\n##### C\n```c\n// 1. Create a source input stream for reading archive file content.\n//  1.1. Create a source input stream with the path to an archive file.\nplzma_path archivePath = plzma_path_create_with_utf8_string(\"path/to/archive.7z\"); // plzma_path_create_with_wide_string(L\"C:\\\\\\\\path\\\\to\\\\archive.7z\");\nplzma_in_stream archivePathInStream = plzma_in_stream_create_with_path(\u0026archivePath); // plzma_in_stream_create_with_pathm(...);\nplzma_path_release(\u0026archivePath);\nplzma_in_stream_release(\u0026archivePathInStream); // when no longer needed\n\n//  1.2. Create a source input stream with the file content in memory.\nplzma_in_stream archiveDataInStream = plzma_in_stream_create_with_memory_copy(\u003cFILE DATA\u003e, \u003cFILE SIZE\u003e); // plzma_in_stream_create_with_memory(...);\n\n// 2. Create decoder with source input stream, type of archive, context for optional delegate and provide optional delegate callback.\nplzma_decoder decoder = plzma_decoder_create(\u0026archiveDataInStream, plzma_file_type_7z, plzma_context{ nullptr, nullptr }); // C2059 = { .context = nullptr, .deinitializer = nullptr }\nplzma_in_stream_release(\u0026archiveDataInStream); // when no longer needed\n\nplzma_decoder_set_progress_delegate_utf8_callback(\u0026decoder, \u003cUTF8 C CALLBACK\u003e);  // plzma_decoder_set_progress_delegate_wide_callback(...);\n\n//  2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.\nplzma_decoder_set_password_utf8_string(\u0026decoder, \"1234\"); // plzma_decoder_set_password_wide_string(\u0026decoder, L\"1234\");\n\nbool opened = plzma_decoder_open(\u0026decoder);    \n\n// 3. Select archive items for extracting or testing.\n//  3.1. Select all archive items.\nplzma_item_array allArchiveItems = plzma_decoder_items(\u0026decoder);\n\n//  3.2. Get the number of items, iterate items by index, filter and select items.\nsize_t numberOfArchiveItems = plzma_decoder_count(\u0026decoder);\nplzma_item_array selectedItemsDuringIteration = plzma_item_array_create(numberOfArchiveItems);\nplzma_item_out_stream_array selectedItemsToStreams = plzma_item_out_stream_array_create(numberOfArchiveItems);\nfor (size_t itemIndex = 0; itemIndex \u003c numberOfArchiveItems; itemIndex++) {\n    plzma_item item = plzma_decoder_item_at(\u0026decoder, itemIndex);\n    plzma_item_array_add(\u0026selectedItemsDuringIteration, \u0026item);\n    \n    plzma_out_stream outItemStream = plzma_out_stream_create_memory_stream(); // to memory stream\n    plzma_item_out_stream_array_add(\u0026selectedItemsToStreams, \u0026item, \u0026outItemStream);\n    plzma_out_stream_release(\u0026outItemStream);\n    \n    plzma_item_release(\u0026item);\n}\n\n// 4. Extract or test selected archive items. The extract process might be:\n//  4.1. Extract all items to a directory. In this case, you can skip the step #3.\nplzma_path extractPath = plzma_path_create_with_utf8_string(\"path/outdir\");\nbool extracted = plzma_decoder_extract_all_items_to_path(\u0026decoder, \u0026extractPath, true);\nplzma_path_release(\u0026extractPath);\n\n//  4.2. Extract selected items to a directory.\nplzma_path extractPath = plzma_path_create_with_utf8_string(\"path/outdir\");\nbool extracted = plzma_decoder_extract_items_to_path(\u0026decoder, \u0026selectedItemsDuringIteration, \u0026extractPath, true);\nplzma_path_release(\u0026extractPath);\n\n//  4.3. Extract each item to a custom out-stream. \n//       The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.\nbool extracted = plzma_decoder_extract_item_out_stream_array(\u0026decoder, \u0026selectedItemsToStreams);\n\nplzma_item_array_release(\u0026selectedItemsDuringIteration); // when no longer needed \nplzma_item_array_release(\u0026allArchiveItems); // when no longer needed\nplzma_item_out_stream_array_release(\u0026selectedItemsToStreams); // when no longer needed\nplzma_decoder_release(\u0026decoder); // when no longer needed\n```\n\n-----------\n#### Compress\n##### Create output, setup encoder/archive, add content, open \u0026 compress.  \nThe process consists of 4 steps:\n1. Create output stream for writing archive's file content. The output stream might be created with:\n   1. The path to the archive file.\n   2. Create memory stream without any arguments.\n2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.\n   1. Optionaly provide the password in case of header and/or content encryption.\n   2. Setup archive properties.\n3. Add content for archiving. The content might be next:\n   1. Single file path with optional path inside the archive.\n   2. Single directory path with optional directory iteration option and optional path inside the archive.\n   3. Any input stream with required path inside the archive.\n4. Open \u0026 compress.\n\n##### Swift\n```swift\ndo {\n    // 1. Create output stream for writing archive's file content.\n    //  1.1. Using file path.\n    let archivePath = Path(\"path/out.7z\");\n    let archivePathOutStream = try OutStream(path: archivePath)\n    \n    // 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.\n    let encoder = try Encoder(stream: archivePathOutStream, fileType: .sevenZ, method: .LZMA2, delegate: self)\n    \n    //  2.1. Optionaly provide the password in case of header and/or content encryption.\n    try encoder.setPassword(\"1234\")\n    \n    //  2.2. Setup archive properties.\n    try encoder.setShouldEncryptHeader(true)  // use this option with password.\n    try encoder.setShouldEncryptContent(true) // use this option with password.\n    try encoder.setCompressionLevel(9)\n    \n    // 3. Add content for archiving.\n    //  3.1. Single file path with optional path inside the archive.\n    try encoder.add(path: Path(\"dir/my_file1.txt\")) // store as \"dir/my_file1.txt\", as is.\n    try encoder.add(path: Path(\"dir/my_file2.txt\"), mode: .default, archivePath: Path(\"renamed_file2.txt\")) // store as \"renamed_file2.txt\"\n    \n    //  3.2. Single directory path with optional directory iteration option and optional path inside the archive.\n    try encoder.add(path: Path(\"dir/dir1\")) // store as \"dir1/...\"\n    try encoder.add(path: Path(\"dir/dir2\"), mode: .followSymlinks, archivePath: Path(\"renamed_dir2\")) // store as \"renamed_dir2/...\"\n    \n    //  3.3. Any input stream with required path inside the archive.\n    let itemStream = try InStream(dataCopy: \u003cData\u003e) // InStream(dataNoCopy: \u003cData\u003e)\n    try encoder.add(stream: itemStream, archivePath: Path(\"my_file3.txt\")) // store as \"my_file3.txt\"\n    \n    // 4. Open.\n    let opened = try encoder.open()\n    \n    // 4. Compress.\n    let compressed = try encoder.compress()\n} catch let exception as Exception {\n    print(\"Exception: \\(exception)\")\n}\n```\n\n##### JavaScript\n```javascript\nconst plzma = require('plzmasdk');\n\ntry {\n    // 1. Create output stream for writing archive's file content.\n    //  1.1. Using file path.\n    const archivePathOutStream = new plzma.OutStream('path/out.7z');\n\n    // 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.\n    const encoder = plzma.Encoder(archivePathOutStream, plzma.FileType.sevenZ, plzma.Method.LZMA2);\n    encoder.setProgressDelegate((path, progress) =\u003e console.log(`Delegating progress, path: ${path}, progress: ${progress}`) );\n    \n    //  2.1. Optionaly provide the password in case of header and/or content encryption.\n    encoder.setPassword('1234');\n\n    //  2.2. Setup archive properties.\n    encoder.shouldEncryptHeader = true;  // use this option with password.\n    encoder.shouldEncryptContent = true; // use this option with password.\n    encoder.compressionLevel = 9;\n    \n    // 3. Add content for archiving.\n    //  3.1. Single file path with optional path inside the archive.\n    encoder.add('dir/my_file1.txt'); // store as \"dir/my_file1.txt\", as is.\n    encoder.add('dir/my_file2.txt', 0, 'renamed_file2.txt'); // store as \"renamed_file2.txt\"\n    \n    //  3.2. Single directory path with optional directory iteration option and optional path inside the archive.\n    encoder.add('dir/dir1'); // store as \"dir1/...\"\n    encoder.add('dir/dir2', plzma.OpenDirMode.followSymlinks, 'renamed_dir2'); // store as \"renamed_dir2/...\"\n\n    //  3.3. Any input stream with required path inside the archive.\n    const itemStream = plzma.InStream(new ArrayBuffer(...));\n    encoder.add(itemStream, 'my_file3.txt'); // store as \"my_file3.txt\"\n    \n    // 4. Open.\n    const opened = await encoder.openAsync(); // also available sync. version 'encoder.open()'\n    \n    // 4. Compress.\n    const compressed = await encoder.compressAsync(); // also available sync. version 'encoder.compress()'\n} catch (error) {\n    console.log(`Exception: ${error}`);\n}\n```\n\n##### C++\n```cpp\ntry {\n    // 1. Create output stream for writing archive's file content.\n    //  1.1. Using file path.\n    const auto archivePathOutStream = makeSharedOutStream(Path(\"path/out.7z\"));\n\n    // 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.\n    auto encoder = makeSharedEncoder(archivePathOutStream, plzma_file_type_7z, plzma_method_LZMA2);\n    encoder-\u003esetProgressDelegate(_progressDelegate);\n\n    //  2.1. Optionaly provide the password in case of header and/or content encryption.\n    encoder-\u003esetPassword(\"1234\");\n    \n    //  2.2. Setup archive properties.\n    encoder-\u003esetShouldEncryptHeader(true);   // use this option with password.\n    encoder-\u003esetShouldEncryptContent(true);  // use this option with password.\n    encoder-\u003esetCompressionLevel(9);\n\n    // 3. Add content for archiving.\n    //  3.1. Single file path with optional path inside the archive.\n    encoder-\u003eadd(Path(\"dir/my_file1.txt\"));  // store as \"dir/my_file1.txt\", as is.\n    encoder-\u003eadd(Path(\"dir/my_file2.txt\"), 0, Path(\"renamed_file2.txt\")); // store as \"renamed_file2.txt\"\n\n    //  3.2. Single directory path with optional directory iteration option and optional path inside the archive.\n    encoder-\u003eadd(Path(\"dir/dir1\")); // store as \"dir1/...\"\n    encoder-\u003eadd(Path(\"dir/dir2\"), plzma_open_dir_mode_follow_symlinks, Path(\"renamed_dir2\")); // store as \"renamed_dir2/...\"\n\n    //  3.3. Any input stream with required path inside the archive.\n    auto itemStream = makeSharedInStream(\u003cDATA\u003e, \u003cDATA_SIZE\u003e);\n    encoder-\u003eadd(itemStream, Path(\"my_file3.txt\")); // store as \"my_file3.txt\"\n    \n    // 4. Open.\n    bool opened = encoder-\u003eopen();\n\n    // 4. Compress.\n    bool compressed = encoder-\u003ecompress();\n} catch (const Exception \u0026 exception) {\n    std::cout \u003c\u003c \"Exception: \" \u003c\u003c exception.what() \u003c\u003c std::endl;\n}\n```\n\n##### C\n```c\n// 1. Create output stream for writing archive's file content.\n//  1.1. Using file path.\nplzma_path archivePath = plzma_path_create_with_utf8_string(\"path/out.7z\");\nplzma_out_stream archivePathOutStream = plzma_out_stream_create_with_path(\u0026archivePath);\n\n// 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.\nplzma_context context;\nplzma_encoder encoder = plzma_encoder_create(\u0026archivePathOutStream, plzma_file_type_7z, plzma_method_LZMA2, context);\nplzma_encoder_set_progress_delegate_utf8_callback(\u0026encoder, \u003cC_CALLBACK_FUNCTION\u003e);\n\n//  2.1. Optionaly provide the password in case of header and/or content encryption.\nplzma_encoder_set_password_utf8_string(\u0026encoder, \"1234\");\n\n//  2.2. Setup archive properties.\nplzma_encoder_set_should_encrypt_header(\u0026encoder, true);   // use this option with password.\nplzma_encoder_set_should_encrypt_content(\u0026encoder, true);  // use this option with password.\nplzma_encoder_set_compression_level(\u0026encoder, 9);\n\n// 3. Add content for archiving.\n//  3.1. Single file path with optional path inside the archive.\nplzma_path itemPath = plzma_path_create_with_utf8_string(\"dir/my_file1.txt\");\nplzma_encoder_add_path(\u0026encoder, \u0026itemPath, 0, NULL); // store as \"dir/my_file1.txt\", as is.\nplzma_path_release(\u0026itemPath);\n\nitemPath = plzma_path_create_with_utf8_string(\"dir/my_file2.txt\");\nplzma_path itemArchivePath = plzma_path_create_with_utf8_string(\"renamed_file2.txt\");\nplzma_encoder_add_path(\u0026encoder, \u0026itemPath, 0, \u0026itemArchivePath); // store as \"renamed_file2.txt\"\nplzma_path_release(\u0026itemPath);\nplzma_path_release(\u0026itemArchivePath);\n\n//  3.2. Single directory path with optional directory iteration option and optional path inside the archive.\nitemPath = plzma_path_create_with_utf8_string(\"dir/dir1\");\nplzma_encoder_add_path(\u0026encoder, \u0026itemPath, 0, NULL); // store as \"dir1/...\"\nplzma_path_release(\u0026itemPath);\n\nitemPath = plzma_path_create_with_utf8_string(\"dir/dir2\");\nitemArchivePath = plzma_path_create_with_utf8_string(\"renamed_dir2\");\nplzma_encoder_add_path(\u0026encoder, \u0026itemPath, plzma_open_dir_mode_follow_symlinks, \u0026itemArchivePath); // store as \"renamed_dir2/...\"\nplzma_path_release(\u0026itemPath);\nplzma_path_release(\u0026itemArchivePath);\n\n//  3.3. Any input stream with required path inside the archive.\nitemArchivePath = plzma_path_create_with_utf8_string(\"my_file3.txt\");\nplzma_in_stream itemStream = plzma_in_stream_create_with_memory(\u003cDATA\u003e, \u003cDATA_SIZE\u003e);\nplzma_encoder_add_stream(\u0026encoder, \u0026itemStream, \u0026itemArchivePath); // store as \"my_file3.txt\"\nplzma_in_stream_release(\u0026itemStream);\nplzma_path_release(\u0026itemArchivePath);\n\n// 4. Open.\nbool opened = plzma_encoder_open(\u0026encoder);\n\n// 4. Compress.\nbool compressed = plzma_encoder_compress(\u0026encoder);\n\nplzma_out_stream_release(\u0026archivePathOutStream); // when no longer needed\nplzma_path_release(\u0026archivePath); // when no longer needed\nplzma_encoder_release(\u0026encoder); // when no longer needed\n```\n\n\n### License\n-----------\nBy using this all you are accepting original [LZMA SDK] and MIT license (*see below*):\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 - 2025 Oleh Kulykov \u003colehkulykov@gmail.com\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n\n[LZMA SDK]:http://www.7-zip.org/sdk.html\n[7z]:https://www.7-zip.org/7z.html\n[LZMA]:https://www.7-zip.org/7z.html\n[LZMA2]:https://www.7-zip.org/7z.html\n[xz]:https://tukaani.org/xz\n[tar]:https://en.wikipedia.org/wiki/Tar_(computing)\n[tarball]:https://en.wikipedia.org/wiki/Tar_(computing)\n[C++11]:https://en.cppreference.com/w/cpp/11\n[STL]:https://en.wikipedia.org/wiki/Standard_Template_Library\n[libplzma.h]:https://github.com/OlehKulykov/PLzmaSDK/blob/master/libplzma.h\n[libplzma.hpp]:https://github.com/OlehKulykov/PLzmaSDK/blob/master/libplzma.hpp\n[src]:https://github.com/OlehKulykov/PLzmaSDK/tree/master/src\n[Swift]:https://swift.org\n[Objective-C]:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html\n[Swift Package Manager]:https://swift.org/package-manager\n[CocoaPods]:https://cocoapods.org/pods/PLzmaSDK\n[npm]:https://www.npmjs.com/package/plzmasdk\n[CMake]:https://cmake.org\n[git]:https://git-scm.com\n[JavaScript]:https://en.wikipedia.org/wiki/JavaScript\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlehKulykov%2FPLzmaSDK","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOlehKulykov%2FPLzmaSDK","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlehKulykov%2FPLzmaSDK/lists"}