Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

heatshrink_decoder_poll return HSDR_POLL_MORE if out buffer is exactly sized as the decoded result #74

Open
IvanoBono opened this issue Jul 7, 2022 · 4 comments

Comments

@IvanoBono
Copy link

in this example output buffer is sized exactly as the input buffer: program remain il loop.
if i resize the output buffer as sizeof(data)+1 it work, and leftover 1 byte

`
const char data[] = "Cappuccetto Rosso, chiamata anche Cappuccetto, e' una bambina che vive con la sua mamma in una casetta vicino al bosco. Un giorno la mamma le consegna un cestino pieno di cose buone da portare alla nonna malata, che vive al di la' della foresta. La mamma "; //256byte data

char compress[1500];
char out[sizeof(data)];

int Encode() {
heatshrink_encoder hse; //512byte in stack
heatshrink_encoder_reset(&hse);
size_t copied;
size_t tot_copied = 0;
const char* in=data;
size_t remaining = sizeof(data);
size_t srclen = remaining;
size_t readed;
do
{
heatshrink_encoder_sink(&hse, (uint8_t*)in, remaining, &readed);
in += readed;
remaining -= readed;
//printf("readed:%lu\n",readed);
heatshrink_encoder_poll(&hse, (uint8_t*)compress + tot_copied, sizeof(compress)- tot_copied,&copied);
tot_copied += copied;
//printf("copied:%lu tot:%lu\n",copied,tot_copied);
} while (remaining);
heatshrink_encoder_finish(&hse);
HSE_poll_res pres;
do
{
pres = heatshrink_encoder_poll(&hse, (uint8_t*)compress + tot_copied, sizeof(compress)- tot_copied,&copied);
tot_copied += copied;
} while (pres != HSER_POLL_EMPTY);
Uart_Printf(">>>>>>>>>>>>src:%lu dst:%lu\n", srclen, tot_copied);
return tot_copied;
}

int Decode(size_t remaining) {
HSD_sink_res sres;
HSD_poll_res pres;
HSD_finish_res fres;
heatshrink_decoder hsd;
heatshrink_decoder_reset(&hsd);
size_t tot_copied = 0;
size_t readed;
size_t copied;
const uint8_t* in = (const uint8_t*)compress;
do
{
sres =
heatshrink_decoder_sink(&hsd, in, remaining, &readed);
in += readed;
remaining -= readed;
//printf("readed:%lu\n",readed);
pres =heatshrink_decoder_poll(&hsd, (uint8_t*)out + tot_copied,sizeof(out)- tot_copied, &copied);
tot_copied += copied;
//printf("copied:%lu tot:%lu\n",copied,tot_copied);
} while (remaining);
fres = heatshrink_decoder_finish(&hsd);
do //REMAIN ON THIS LOOP FOREVER !!!
{
pres =heatshrink_decoder_poll(&hsd, (uint8_t*)out + tot_copied, sizeof(out) - tot_copied, &copied);
tot_copied += copied;
//printf("src:%lu dst:%lu\n",srclen,tot_copied);
} while (pres != HSER_POLL_EMPTY);
Uart_Printf(">>>>>>>>>>>>decompress:%lu\n", tot_copied);
return tot_copied;
}

void main() {
SysTimer_Init();
Uart_Init(Uart_STDOUT, 0); //console
int n=Encode();
Decode(n);
Uart_Println(out);
Uart_Println("end");
while (1);
}
`

@unixdj
Copy link
Contributor

unixdj commented Jul 20, 2022

Bug introduced in commit 8669992

Sorry about that.

@unixdj
Copy link
Contributor

unixdj commented Jul 20, 2022

To reproduce:

cc -g -Iinclude -Isrc -DHEATSHRINK_DYNAMIC_ALLOC=0 foo.c src/heatshrink_decoder.c src/heatshrink_encoder.c -o foo && ./foo

with foo.c containing:

#include <stdio.h>
#include "heatshrink_encoder.h"
#include "heatshrink_decoder.h"

const char data[] = "Cappuccetto Rosso, chiamata anche Cappuccetto, e' una bambina che vive con la sua mamma in una casetta vicino al bosco. Un giorno la mamma le consegna un cestino pieno di cose buone da portare alla nonna malata, che vive al di la' della foresta. La mamma "; //256byte data

char compress[1500];
char out[sizeof(data)];

int Encode() {
	heatshrink_encoder hse; //512byte in stack
	heatshrink_encoder_reset(&hse);
	size_t copied;
	size_t tot_copied = 0;
	const char* in=data;
	size_t remaining = sizeof(data);
	size_t srclen = remaining;
	size_t readed;
	do
	{
		heatshrink_encoder_sink(&hse, (uint8_t*)in, remaining, &readed);
		in += readed;
		remaining -= readed;
		//printf("readed:%lu\n",readed);
		heatshrink_encoder_poll(&hse, (uint8_t*)compress + tot_copied, sizeof(compress)- tot_copied,&copied);
		tot_copied += copied;
		//printf("copied:%lu tot:%lu\n",copied,tot_copied);
	} while (remaining);
	heatshrink_encoder_finish(&hse);
	HSE_poll_res pres;
	do
	{
		pres = heatshrink_encoder_poll(&hse, (uint8_t*)compress + tot_copied, sizeof(compress)- tot_copied,&copied);
		tot_copied += copied;
	} while (pres != HSER_POLL_EMPTY);
	printf(">>>>>>>>>>>>src:%lu dst:%lu\n", srclen, tot_copied);
	return tot_copied;
}

int Decode(size_t remaining) {
	HSD_sink_res sres;
	HSD_poll_res pres;
	HSD_finish_res fres;
	heatshrink_decoder hsd;
	heatshrink_decoder_reset(&hsd);
	size_t tot_copied = 0;
	size_t readed;
	size_t copied;
	const uint8_t* in = (const uint8_t*)compress;
	do
	{
		sres =
		    heatshrink_decoder_sink(&hsd, in, remaining, &readed);
		in += readed;
		remaining -= readed;
		//printf("readed:%lu\n",readed);
		pres =heatshrink_decoder_poll(&hsd, (uint8_t*)out + tot_copied,sizeof(out)- tot_copied, &copied);
		tot_copied += copied;
		//printf("copied:%lu tot:%lu\n",copied,tot_copied);
	} while (remaining);
	fres = heatshrink_decoder_finish(&hsd);
	do //REMAIN ON THIS LOOP FOREVER !!!
	{
		pres =heatshrink_decoder_poll(&hsd, (uint8_t*)out + tot_copied, sizeof(out) - tot_copied, &copied);
		tot_copied += copied;
		//printf("src:%lu dst:%lu\n",srclen,tot_copied);
	} while (pres != HSER_POLL_EMPTY);
	printf(">>>>>>>>>>>>decompress:%lu\n", tot_copied);
	return tot_copied;
}

void main() {
	// SysTimer_Init();
	// Uart_Init(Uart_STDOUT, 0); //console
	int n=Encode();
	Decode(n);
	// Uart_Println(out);
	// Uart_Println("end");
	// while (1);
}

@unixdj
Copy link
Contributor

unixdj commented Jul 21, 2022

@silentbicycle Please check that my answer is correct.

You should check the return value of heatshrink_decoder_finish() in the last loop, like so:

        while (heatshrink_decoder_finish(&hsd) != HSDR_FINISH_DONE) {
                pres =heatshrink_decoder_poll(&hsd, (uint8_t*)out + tot_copied, sizeof(out) - tot_copied, &copied);
                tot_copied += copied;
                //printf("src:%lu dst:%lu\n",srclen,tot_copied);
        }

@IvanoBono
Copy link
Author

in this example your suggestion would solve the problem. but in my application i'm developing i receive small packets of 8 bytes and as they arrive i decode them and reply to the sender that he can send the next packet.
the problem is that when i get to fill the heatshrink_decoder_poll buffer i get HSER_POLL_MORE and i can't confirm to the sender to send the next packet (normally the next packet would be the one that indicates the end and would trigger the heatshrink_decoder_finish but i can't be sure and since i know that there are more bytes to decode and the buffer is full i should signal error...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants