1+ /*
2+ This file is part of the ArduinoIoTCloud library.
3+
4+ Copyright (c) 2024 Arduino SA
5+
6+ This Source Code Form is subject to the terms of the Mozilla Public
7+ License, v. 2.0. If a copy of the MPL was not distributed with this
8+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+ */
10+
11+ #pragma once
12+
13+ /* *************************************************************************************
14+ INCLUDE
15+ **************************************************************************************/
16+ #include < Arduino.h>
17+ #include < functional>
18+ #include < stdint.h>
19+
20+ /* *************************************************************************************
21+ FUNCTION DEFINITION
22+ **************************************************************************************/
23+
24+ /* *************************************************************************************
25+ LZSS DECODER CLASS
26+ **************************************************************************************/
27+
28+
29+ class LZSSDecoder {
30+ public:
31+
32+ /* *
33+ * Build an LZSS decoder by providing a callback for storing the decoded bytes
34+ * @param putc_cbk: a callback that takes a char and stores it e.g. a callback to fwrite
35+ */
36+ LZSSDecoder (std::function<void (const uint8_t )> putc_cbk);
37+
38+ /* *
39+ * Build an LZSS decoder providing a callback for getting a char and putting a char
40+ * in this way you need to call decompress with no parameters
41+ * @param putc_cbk: a callback that takes a char and stores it e.g. a callback to fwrite
42+ * @param getc_cbk: a callback that returns the next char to consume
43+ * -1 means EOF, -2 means buffer is temporairly finished
44+ */
45+ LZSSDecoder (std::function<int ()> getc_cbk, std::function<void (const uint8_t )> putc_cbk);
46+
47+ /* *
48+ * this enum describes the result of the computation of a single FSM computation
49+ * DONE: the decompression is completed
50+ * IN_PROGRESS: the decompression cycle completed successfully, ready to compute next
51+ * NOT_COMPLETED: the current cycle didn't complete because the available data is not enough
52+ */
53+ enum status: uint8_t {
54+ DONE,
55+ IN_PROGRESS,
56+ NOT_COMPLETED
57+ };
58+
59+ /* *
60+ * decode the provided buffer until buffer ends, then pause the process
61+ * @return DONE if the decompression is completed, NOT_COMPLETED if not
62+ */
63+ status decompress (uint8_t * const buffer=nullptr , uint32_t size=0 );
64+
65+ static const int LZSS_EOF = -1 ;
66+ static const int LZSS_BUFFER_EMPTY = -2 ;
67+ private:
68+ // TODO provide a way for the user to set these parameters
69+ static const int EI = 11 ; /* typically 10..13 */
70+ static const int EJ = 4 ; /* typically 4..5 */
71+ static const int N = (1 << EI); /* buffer size */
72+ static const int F = ((1 << EJ) + 1 ); /* lookahead buffer size */
73+
74+ // algorithm specific buffer used to store text that could be later referenced and copied
75+ uint8_t buffer[N * 2 ];
76+
77+ // this function gets 1 single char from the input buffer
78+ int getc ();
79+ uint8_t * in_buffer = nullptr ;
80+ uint32_t available = 0 ;
81+
82+ status handle_state ();
83+
84+ // get 1 bit from the available input buffer
85+ int getbit (uint8_t n);
86+ // the following 2 are variables used by getbits
87+ uint32_t buf, buf_size=0 ;
88+
89+ enum FSM_STATES: uint8_t {
90+ FSM_0 = 0 ,
91+ FSM_1 = 1 ,
92+ FSM_2 = 2 ,
93+ FSM_3 = 3 ,
94+ FSM_EOF
95+ } state;
96+
97+ // these variable are used in a decode session and specific to the old C implementation
98+ // there is no documentation about their meaning
99+ int i, r;
100+
101+ std::function<void (const uint8_t )> put_char_cbk;
102+ std::function<uint8_t ()> get_char_cbk;
103+
104+ inline void putc (const uint8_t c) { if (put_char_cbk) { put_char_cbk (c); } }
105+
106+ // get the number of bits the FSM will require given its state
107+ uint8_t bits_required (FSM_STATES s);
108+ };
0 commit comments