mirror of
https://github.com/aaru-dps/Aaru.Compression.Native.git
synced 2025-12-16 19:24:31 +00:00
183 lines
5.3 KiB
C++
183 lines
5.3 KiB
C++
/*
|
|
* This file is part of the Aaru Data Preservation Suite.
|
|
* Copyright (c) 2019-2025 Natalia Portillo.
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <climits>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "../library.h"
|
|
#include "../crc32.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#define OUTPUT_CHUNK 8192
|
|
#define EXPECTED_SIZE 152089
|
|
#define EXPECTED_CRC32_VAL 0x66007dba
|
|
|
|
static long long filesize_of(const char* path)
|
|
{
|
|
struct stat st;
|
|
if(stat(path, &st) == 0) return (long long)st.st_size;
|
|
return -1;
|
|
}
|
|
|
|
class lzdFixture : public ::testing::Test
|
|
{
|
|
protected:
|
|
void SetUp() override
|
|
{
|
|
char cwd[PATH_MAX];
|
|
char filename[PATH_MAX];
|
|
|
|
getcwd(cwd, PATH_MAX);
|
|
snprintf(filename, PATH_MAX, "%s/data/alice29.lzd", cwd);
|
|
|
|
inFile = fopen(filename, "rb");
|
|
ASSERT_NE(inFile, nullptr) << "Failed to open input file";
|
|
|
|
fileSize = filesize_of(filename);
|
|
}
|
|
|
|
void TearDown() override
|
|
{
|
|
if(inFile) fclose(inFile);
|
|
}
|
|
|
|
FILE* inFile = nullptr;
|
|
long long fileSize = 0;
|
|
};
|
|
|
|
typedef enum {
|
|
LZD_OK = 0,
|
|
LZD_NEED_INPUT = 1,
|
|
LZD_NEED_OUTPUT = 2,
|
|
LZD_DONE = 3
|
|
} LZDStatus;
|
|
|
|
TEST_F(lzdFixture, ZooMethod1)
|
|
{
|
|
unsigned char inbuf[OUTPUT_CHUNK];
|
|
unsigned char outbuf[OUTPUT_CHUNK];
|
|
|
|
bool flushed = false;
|
|
bool eof = false;
|
|
size_t total_out = 0;
|
|
size_t total_in = 0;
|
|
size_t iter = 0;
|
|
|
|
fprintf(stderr, "INPUT FILE SIZE=%lld bytes\n", fileSize);
|
|
|
|
void* ctx = CreateLZDContext();
|
|
ASSERT_NE(ctx, nullptr) << "Failed to create LZD context";
|
|
|
|
// allocate buffer for full output to CRC at the end
|
|
uint8_t* full_out = (uint8_t*)malloc(EXPECTED_SIZE);
|
|
ASSERT_NE(full_out, nullptr);
|
|
size_t full_offset = 0;
|
|
|
|
while(!eof)
|
|
{
|
|
size_t nread = fread(inbuf, 1, sizeof inbuf, inFile);
|
|
if(nread == 0)
|
|
{
|
|
fprintf(stderr, "[FEED] size=0 flushed=0 (final empty feed)\n");
|
|
LZD_FeedNative(ctx, nullptr, 0);
|
|
flushed = true;
|
|
}
|
|
else
|
|
{
|
|
total_in += nread;
|
|
fprintf(stderr, "[FEED] size=%zu flushed=0 (real data) total_in=%zu\n",
|
|
nread, total_in);
|
|
LZD_FeedNative(ctx, inbuf, nread);
|
|
}
|
|
|
|
size_t produced = 0;
|
|
int st = LZD_OK;
|
|
do
|
|
{
|
|
produced = 0;
|
|
st = LZD_DrainNative(ctx, outbuf, sizeof outbuf, &produced);
|
|
fprintf(stderr, "-- LOOP iter=%zu total_out=%zu --\n", iter++, total_out);
|
|
fprintf(stderr, "[DRAIN] produced=%zu status=%d flushed=%d eof=%d\n",
|
|
produced, st, flushed ? 1 : 0, eof ? 1 : 0);
|
|
|
|
if(produced > 0)
|
|
{
|
|
memcpy(full_out + full_offset, outbuf, produced);
|
|
full_offset += produced;
|
|
total_out += produced;
|
|
}
|
|
if(st == LZD_DONE)
|
|
{
|
|
fprintf(stderr, ">>> SET eof=1 (DONE from decoder)\n");
|
|
eof = true;
|
|
}
|
|
} while(produced > 0);
|
|
|
|
if(flushed)
|
|
{
|
|
for(int spins = 0; spins < 8 && !eof; spins++)
|
|
{
|
|
size_t more = 0;
|
|
int st2 = LZD_DrainNative(ctx, outbuf, sizeof outbuf, &more);
|
|
fprintf(stderr, "-- LOOP iter=%zu total_out=%zu --\n", iter++, total_out);
|
|
fprintf(stderr, "[DRAIN] produced=%zu status=%d flushed=1 eof=%d\n",
|
|
more, st2, eof ? 1 : 0);
|
|
if(more > 0)
|
|
{
|
|
memcpy(full_out + full_offset, outbuf, more);
|
|
full_offset += more;
|
|
total_out += more;
|
|
}
|
|
else if(st2 == LZD_DONE)
|
|
{
|
|
fprintf(stderr, ">>> SET eof=1 (DONE after flush)\n");
|
|
eof = true;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(!eof)
|
|
{
|
|
fprintf(stderr, ">>> SET eof=1 (no more data and already flushed)\n");
|
|
eof = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "\nTOTAL IN=%zu bytes\n", total_in);
|
|
fprintf(stderr, "TOTAL OUT=%zu bytes\n", total_out);
|
|
|
|
DestroyLZDContext(ctx);
|
|
|
|
// Now verify the decompressed size and CRC
|
|
EXPECT_EQ(total_out, static_cast<size_t>(EXPECTED_SIZE));
|
|
uint32_t crc = crc32_data(full_out, total_out);
|
|
free(full_out);
|
|
|
|
EXPECT_EQ(crc, static_cast<uint32_t>(EXPECTED_CRC32_VAL));
|
|
EXPECT_EQ(total_in, static_cast<size_t>(fileSize));
|
|
}
|