/* * This file is part of Espruino, a JavaScript interpreter for Microcontrollers * * Copyright (C) 2013 Gordon Williams * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * ---------------------------------------------------------------------------- * Wrapper for LZ4 encode/decode * ---------------------------------------------------------------------------- */ #include "jsutils.h" #include "jsinteractive.h" #include "jsdevices.h" #include "jsvariterator.h" #include "compress_heatshrink.h" #include "heatshrink_encoder.h" #include "heatshrink_decoder.h" #define BUFFERSIZE 128 void heatshrink_ptr_output_cb(unsigned char ch, uint32_t *cbdata) { unsigned char **outPtr = (unsigned char**)cbdata; *((*outPtr)++) = ch; } int heatshrink_ptr_input_cb(uint32_t *cbdata) { HeatShrinkPtrInputCallbackInfo *info = (HeatShrinkPtrInputCallbackInfo *)cbdata; if (!info->len) return -1; info->len--; return *(info->ptr++); } void heatshrink_var_output_cb(unsigned char ch, uint32_t *cbdata) { JsvStringIterator *it = (JsvStringIterator *)cbdata; jsvStringIteratorSetCharAndNext(it, (char)ch); } int heatshrink_var_input_cb(uint32_t *cbdata) { JsvIterator *it = (JsvIterator *)cbdata; int d = -1; if (jsvIteratorHasElement(it)) d = jsvIteratorGetIntegerValue(it) & 0xFF; jsvIteratorNext(it); return d; } /** gets data from callback, writes to callback if nonzero. Returns total length. */ uint32_t heatshrink_encode_cb(int (*in_callback)(uint32_t *cbdata), uint32_t *in_cbdata, void (*out_callback)(unsigned char ch, uint32_t *cbdata), uint32_t *out_cbdata) { heatshrink_encoder hse; uint8_t inBuf[BUFFERSIZE]; uint8_t outBuf[BUFFERSIZE]; heatshrink_encoder_reset(&hse); size_t i; size_t count = 0; size_t polled = 0; int lastByte = 0; size_t inBufCount = 0; size_t inBufOffset = 0; while (lastByte >= 0 || inBufCount>0) { // Read data from input if (inBufCount==0) { inBufOffset = 0; while (inBufCount=0) { lastByte = in_callback(in_cbdata); if (lastByte >= 0) inBuf[inBufCount++] = (uint8_t)lastByte; } } // encode bool ok = heatshrink_encoder_sink(&hse, &inBuf[inBufOffset], inBufCount, &count) >= 0; assert(ok);NOT_USED(ok); inBufCount -= count; inBufOffset += count; if ((inBufCount==0) && (lastByte < 0)) { heatshrink_encoder_finish(&hse); } HSE_poll_res pres; do { pres = heatshrink_encoder_poll(&hse, outBuf, sizeof(outBuf), &count); assert(pres >= 0); if (out_callback) for (i=0;i= 0 || inBufCount>0) { // Read data from input if (inBufCount==0) { inBufOffset = 0; while (inBufCount=0) { lastByte = in_callback(in_cbdata); if (lastByte >= 0) inBuf[inBufCount++] = (uint8_t)lastByte; } } // decode bool ok = heatshrink_decoder_sink(&hsd, &inBuf[inBufOffset], inBufCount, &count) >= 0; assert(ok);NOT_USED(ok); inBufCount -= count; inBufOffset += count; if ((inBufCount==0) && (lastByte < 0)) { heatshrink_decoder_finish(&hsd); } HSD_poll_res pres; do { pres = heatshrink_decoder_poll(&hsd, outBuf, sizeof(outBuf), &count); assert(pres >= 0); if (out_callback) for (i=0;i