)
+endif()
diff --git a/README.md b/README.md
index 4d6d382..3bcaf38 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,130 @@
+# qt-lzstring
-Qt implementation of LZ-String, version 1.4.4.
-
-Based on the LZ-String compression algorithm found here:
-http://pieroxy.net/blog/pages/lz-string/index.html
-
-
-WTFPL Licence
-http://www.wtfpl.net/
-
-Implemented functions:
-
-- compress() / decompress() - YES
-- compressToUTF16() / decompressFromUTF16() - YES
-- compressToBase64() / decompressFromBase64() - YES
-- compressToUint8Array() / decompressFromUint8Array() - NO
-- compressToEncodedURIComponent() / decompressFromEncodedURIComponent() - NO
-
+Qt implementation of LZ-String with a platform-agnostic core and a simple CLI.
+
+Refactor highlights
+- LZ core extracted to `src/LZCore.{h,cpp}`. It contains the compression/decompression logic and depends only on an abstract platform interface.
+- New platform interface `src/ILZPlatform.h` encapsulates string/character operations the core needs.
+- Two platform implementations:
+ - `src/QtLZPlatform.{h,cpp}` for Qt builds (uses QString/QChar/QHash).
+ - `src/StdLZPlatform.{h,cpp}` for non-Qt builds (uses std::string and simple containers).
+- `src/lzstring.cpp` is a thin facade that selects the platform at compile time and delegates to `LZCore`.
+- Build files (CMake and qmake .pri) updated to include the new sources.
+
+Public API
+- `LZString` public static methods are unchanged: `compress`, `compressToUTF16`, `compressToBase64`, and corresponding `decompress*` variants.
+
+Notes
+- The core does not depend on Qt; only the platform layer bridges to Qt or std. This improves separation of concerns and makes the LZ implementation reusable.
+- Non-Qt mode (CMake default) is intended for simple CLI usage. For full Unicode fidelity and UTF‑16/Base64 behavior identical to the original Qt implementation, build/run the Qt test target which uses `QString` code units.
+
+Installation (Linux)
+- Prerequisites: a C++ compiler and either Qt (for the full-featured test suite) or just CMake (for the minimal non‑Qt CLI + std round‑trip tests).
+
+Debian/Ubuntu
+```bash
+sudo apt-get update
+sudo apt-get install -y build-essential cmake
+# For Qt tests (optional)
+sudo apt-get install -y qtbase5-dev qtbase5-dev-tools
+```
+
+Fedora
+```bash
+sudo dnf install -y cmake make gcc-c++
+# For Qt tests (optional)
+sudo dnf install -y qt5-qtbase-devel
+```
+
+Build (CMake)
+- Default (non-Qt CLI only):
+ - Windows (cmd.exe):
+ ```cmd
+ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_QT_TESTS=OFF
+ cmake --build build --config Release
+ ```
+ - Linux/macOS:
+ ```bash
+ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_QT_TESTS=OFF
+ cmake --build build --config Release
+ ```
+ - Binary: `lzstring` / `lzstring.exe` in the build tree.
+
+- With Qt tests (auto-detect Qt5/Qt6):
+ ```bash
+ cmake -S . -B build -DBUILD_QT_TESTS=ON
+ cmake --build build --target lzstring_test
+ ctest --test-dir build -V -R lzstring_test
+ ```
+ If Qt isn't found, a status message is printed and the normal CLI plus non-Qt tests still build.
+
+Tests (CMake)
+- Always built: `lzstring_std_test` (non-Qt, exercises `StdLZPlatform`).
+ ```bash
+ cmake -S . -B build -DBUILD_QT_TESTS=OFF
+ cmake --build build --target lzstring_std_test
+ ctest --test-dir build -V -R lzstring_std_test
+ ```
+- Optionally (with Qt): `lzstring_test` (original Qt/QString test + benchmarks). Data file `data.json` is auto-copied beside the test binary and the working directory set via CTest so relative open succeeds.
+
+Build (qmake, legacy / optional)
+- The `.pri` pulls in all sources; tests are under `tests/`.
+- Linux/macOS:
+ ```bash
+ qmake
+ make -j
+ ```
+- Windows (from a Qt command prompt):
+ ```cmd
+ qmake
+ nmake
+ ```
+
+Getting the sources
+```bash
+git clone
+cd qt-lzstring
+```
+
+Usage (CLI)
+- The CLI reads from a file or stdin (`-`) and writes to a file or stdout (`-`).
+- Binary name: `lzstring` (`.exe` on Windows)
+- Operations:
+ - `--compress`
+ - `--compressToUTF16`
+ - `--compressToBase64`
+ - `--decompress`
+ - `--decompressFromUTF16`
+ - `--decompressFromBase64`
+ - `--test` (round‑trip checks for all codecs on the provided input; prints boolean results and exits)
+
+Examples (Linux/macOS)
+```bash
+./lzstring --compress input.txt output.lz
+./lzstring --compressToUTF16 input.txt output.lz16
+./lzstring --compressToBase64 input.txt output.lz64
+./lzstring --decompress input.lz output.txt
+./lzstring --decompressFromUTF16 input.lz16 output.txt
+./lzstring --decompressFromBase64 input.lz64 output.txt
+./lzstring --test input.txt
+cat input.txt | ./lzstring --compress - -
+cat input.lz | ./lzstring --decompress - -
+```
+
+Examples (Windows cmd.exe)
+```cmd
+lzstring.exe --compress input.txt output.lz
+lzstring.exe --decompress input.lz output.txt
+lzstring.exe --test input.txt
+:: Pipes
+type input.txt | lzstring.exe --compress - -
+type input.lz | lzstring.exe --decompress - -
+```
+
+Extending tests
+- Add more corpus cases: modify `tests/std_roundtrip_test.cpp` or the Qt test's `test_data()` method.
+- For performance comparisons, run the Qt benchmarks (they use `QBENCHMARK`).
+- To disable the std test (e.g., in a packaging build), you can wrap its target creation in an option similar to `BUILD_QT_TESTS`.
+
+License
+- This project is licensed under the WTFPL: http://www.wtfpl.net/
diff --git a/lzstring.pro b/lzstring.pro
index 8515aa2..9a379a3 100644
--- a/lzstring.pro
+++ b/lzstring.pro
@@ -1,5 +1,13 @@
-
-TEMPLATE = subdirs
+TEMPLATE = app
SUBDIRS += tests
+#EDIT to fit you cofiguration
+LIBS += -L/usr/lib/x86_64-linux-gnu -lQt5Core -lQt5Widgets
+INCLUDEPATH += /usr/include/x86_64-linux-gnu/qt5/
+QT += core widgets
+
include(src/lzstring.pri)
+
+TARGET = lzstring
+
+CONFIG = release console
diff --git a/src/ILZPlatform.h b/src/ILZPlatform.h
new file mode 100644
index 0000000..dc5e326
--- /dev/null
+++ b/src/ILZPlatform.h
@@ -0,0 +1,32 @@
+#ifndef ILZPLATFORM_H
+#define ILZPLATFORM_H
+
+#include "lzstring.h"
+
+// Interface abstracting platform-specific string and character utilities
+class ILZPlatform {
+public:
+ virtual ~ILZPlatform() = default;
+
+ // String operations
+ virtual int length(const QString& s) const = 0;
+ virtual bool isEmpty(const QString& s) const = 0;
+ virtual QString slice(const QString& s, int pos, int len) const = 0;
+ virtual QString concat(const QString& a, const QString& b) const = 0;
+ virtual void append(QString& dst, const QString& src) const = 0;
+
+ // Character/code unit operations
+ virtual int charCodeAt(const QString& s, int index) const = 0; // 0..65535 (Qt) or 0..255 (std)
+ virtual QString charFromCode(int code) const = 0; // single-code-unit string
+
+ // Output mappers for compression writers
+ virtual void appendFromInt_Normal(QString& out, int code) const = 0; // 16-bit path uses code as-is
+ virtual void appendFromInt_UTF16(QString& out, int code) const = 0; // code + 32
+ virtual void appendFromInt_Base64(QString& out, int code) const = 0; // map using Base64 alphabet
+
+ // Reverse mapping for Base64 during decompression
+ virtual int base64ReverseIndex(int charCode) const = 0; // -1 if not found
+};
+
+#endif // ILZPLATFORM_H
+
diff --git a/src/LZCore.cpp b/src/LZCore.cpp
new file mode 100644
index 0000000..c1066c7
--- /dev/null
+++ b/src/LZCore.cpp
@@ -0,0 +1,491 @@
+#include
+#include