mirror of
https://github.com/fumiama/base16384.git
synced 2026-06-27 12:10:24 +08:00
Merge branch 'master' of https://github.com/fumiama/base16384 into debian
This commit is contained in:
@@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 2.8.12)
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif (POLICY CMP0048)
|
||||
project(base16384 VERSION 2.3.0)
|
||||
project(base16384 VERSION 2.3.1)
|
||||
|
||||
add_definitions(-DBASE16384_VERSION="${PROJECT_VERSION}")
|
||||
add_definitions(-DBASE16384_VERSION_DATE="April 5th 2024")
|
||||
add_definitions(-DBASE16384_VERSION_DATE="April 7th 2024")
|
||||
|
||||
message(STATUS "Testing endian...")
|
||||
include(TestBigEndian)
|
||||
|
||||
22
base1432.c
22
base1432.c
@@ -30,7 +30,7 @@ typedef union {
|
||||
int base16384_encode_safe(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -127,7 +127,7 @@ int base16384_encode_safe(const char* data, int dlen, char* buf) {
|
||||
int base16384_encode(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -202,7 +202,7 @@ int base16384_encode(const char* data, int dlen, char* buf) {
|
||||
int base16384_encode_unsafe(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -244,7 +244,7 @@ int base16384_decode_safe(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -259,7 +259,7 @@ int base16384_decode_safe(const char* data, int dlen, char* buf) {
|
||||
const uint32_t* vals = (const uint32_t*)data;
|
||||
uint32_t n = 0;
|
||||
int32_t i = 0;
|
||||
for(; i < outlen - 7; i+=7) { // n实际每次自增2
|
||||
for(; i < outlen - 7; i+=7) { // n += 2 in one loop
|
||||
register uint32_t sum = 0;
|
||||
register uint32_t shift = htobe32(vals[n++]) - 0x4e004e00;
|
||||
shift <<= 2;
|
||||
@@ -341,7 +341,7 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -356,7 +356,7 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
const uint32_t* vals = (const uint32_t*)data;
|
||||
uint32_t n = 0;
|
||||
int32_t i = 0;
|
||||
for(; i <= outlen - 7; i+=7) { // n实际每次自增2
|
||||
for(; i <= outlen - 7; i+=7) { // n += 2 in one loop
|
||||
register uint32_t sum = 0;
|
||||
register uint32_t shift = htobe32(vals[n++]) - 0x4e004e00;
|
||||
shift <<= 2;
|
||||
@@ -375,7 +375,7 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
}
|
||||
if(*(uint8_t*)(&vals[n]) == '=') return outlen;
|
||||
if(offset--) {
|
||||
// 这里有读取越界
|
||||
// here comes a read overlap
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
register uint32_t sum = __builtin_bswap32(vals[n++]);
|
||||
#else
|
||||
@@ -391,7 +391,7 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
if(offset--) {
|
||||
buf[i] = (sum & 0x0f000000) >> 20;
|
||||
if(*(uint8_t*)(&vals[n]) == '=') return outlen;
|
||||
// 这里有读取越界
|
||||
// here comes a read overlap
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
sum = __builtin_bswap32(vals[n]);
|
||||
#else
|
||||
@@ -418,7 +418,7 @@ int base16384_decode_unsafe(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -433,7 +433,7 @@ int base16384_decode_unsafe(const char* data, int dlen, char* buf) {
|
||||
const uint32_t* vals = (const uint32_t*)data;
|
||||
uint32_t n = 0;
|
||||
int32_t i = 0;
|
||||
for(; i < outlen-7; i+=7) { // n实际每次自增2
|
||||
for(; i < outlen-7; i+=7) { // n += 2 in one loop
|
||||
register uint32_t sum = 0;
|
||||
register uint32_t shift = htobe32(vals[n++]) - 0x4e004e00;
|
||||
shift <<= 2;
|
||||
|
||||
42
base1464.c
42
base1464.c
@@ -30,7 +30,7 @@ typedef union {
|
||||
int base16384_encode_safe(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -112,7 +112,7 @@ int base16384_encode_safe(const char* data, int dlen, char* buf) {
|
||||
int base16384_encode(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -127,7 +127,7 @@ int base16384_encode(const char* data, int dlen, char* buf) {
|
||||
int64_t i = 0;
|
||||
for(; i <= dlen - 7; i += 7) {
|
||||
register uint64_t sum = 0;
|
||||
register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; // 这里有读取越界
|
||||
register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; // here comes a read overlap
|
||||
sum |= shift & 0x3fff000000000000;
|
||||
shift >>= 2;
|
||||
sum |= shift & 0x00003fff00000000;
|
||||
@@ -177,7 +177,7 @@ int base16384_encode(const char* data, int dlen, char* buf) {
|
||||
int base16384_encode_unsafe(const char* data, int dlen, char* buf) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -192,7 +192,7 @@ int base16384_encode_unsafe(const char* data, int dlen, char* buf) {
|
||||
int64_t i = 0;
|
||||
for(; i < dlen; i += 7) {
|
||||
register uint64_t sum = 0;
|
||||
register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; // 这里有读取越界
|
||||
register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; // here comes a read overlap
|
||||
sum |= shift & 0x3fff000000000000;
|
||||
shift >>= 2;
|
||||
sum |= shift & 0x00003fff00000000;
|
||||
@@ -215,7 +215,7 @@ int base16384_decode_safe(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -264,20 +264,20 @@ int base16384_decode_safe(const char* data, int dlen, char* buf) {
|
||||
#else
|
||||
register uint64_t sum = valbuf.val - 0x000000000000004e;
|
||||
#endif
|
||||
buf[i++] = ((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14);
|
||||
buf[i++] = (char)(((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14));
|
||||
if(offset--) {
|
||||
sum -= 0x00000000004e0000;
|
||||
buf[i++] = ((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20);
|
||||
buf[i++] = (char)(((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20));
|
||||
if(offset--) {
|
||||
buf[i++] = ((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28);
|
||||
buf[i++] = (char)(((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28));
|
||||
if(offset--) {
|
||||
sum -= 0x0000004e00000000;
|
||||
buf[i++] = ((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34);
|
||||
buf[i++] = (char)(((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34));
|
||||
if(offset--) {
|
||||
buf[i++] = ((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42);
|
||||
buf[i++] = (char)(((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42));
|
||||
if(offset--) {
|
||||
sum -= 0x004e000000000000;
|
||||
buf[i] = ((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48);
|
||||
buf[i] = (char)(((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -322,26 +322,26 @@ int base16384_decode(const char* data, int dlen, char* buf) {
|
||||
}
|
||||
if(*(uint8_t*)(&vals[n]) == '=') return outlen;
|
||||
if(offset--) {
|
||||
// 这里有读取越界
|
||||
// here comes a read overlap
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
register uint64_t sum = __builtin_bswap64(vals[n]) - 0x000000000000004e;
|
||||
#else
|
||||
register uint64_t sum = vals[n] - 0x000000000000004e;
|
||||
#endif
|
||||
buf[i++] = ((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14);
|
||||
buf[i++] = (char)(((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14));
|
||||
if(offset--) {
|
||||
sum -= 0x00000000004e0000;
|
||||
buf[i++] = ((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20);
|
||||
buf[i++] = (char)(((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20));
|
||||
if(offset--) {
|
||||
buf[i++] = ((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28);
|
||||
buf[i++] = (char)(((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28));
|
||||
if(offset--) {
|
||||
sum -= 0x0000004e00000000;
|
||||
buf[i++] = ((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34);
|
||||
buf[i++] = (char)(((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34));
|
||||
if(offset--) {
|
||||
buf[i++] = ((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42);
|
||||
buf[i++] = (char)(((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42));
|
||||
if(offset--) {
|
||||
sum -= 0x004e000000000000;
|
||||
buf[i] = ((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48);
|
||||
buf[i] = (char)(((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ int base16384_decode_unsafe(const char* data, int dlen, char* buf) {
|
||||
int offset = 0;
|
||||
if(data[dlen-2] == '=') {
|
||||
offset = data[dlen-1];
|
||||
switch(offset) { // 算上偏移标志字符占用的2字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.TH BASE16384 1 "5 April 2024" "GNU" "User Commands"
|
||||
.TH BASE16384 1 "7 April 2024" "GNU" "User Commands"
|
||||
.SH NAME
|
||||
base16384 \- Encode binary files to printable utf16be
|
||||
.SH SYNOPSIS
|
||||
.B base16384
|
||||
-[edtn] <\fIinputfile\fR> <\fIoutputfile\fR>
|
||||
-[ed][t][n][cC] <\fIinputfile\fR> <\fIoutputfile\fR>
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
There are
|
||||
|
||||
10
base16384.c
10
base16384.c
@@ -27,11 +27,11 @@
|
||||
#endif
|
||||
#include "base16384.h"
|
||||
|
||||
char encbuf[BASE16384_ENCBUFSZ];
|
||||
char decbuf[BASE16384_DECBUFSZ];
|
||||
static char encbuf[BASE16384_ENCBUFSZ];
|
||||
static char decbuf[BASE16384_DECBUFSZ];
|
||||
|
||||
#ifndef _WIN32
|
||||
unsigned long get_start_ms() {
|
||||
static unsigned long get_start_ms() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
|
||||
@@ -52,11 +52,11 @@ static base16384_err_t print_usage() {
|
||||
BASE16384_VERSION_DATE
|
||||
"). Usage:\n", stderr
|
||||
);
|
||||
fputs("base16384 [-edtn] [inputfile] [outputfile]\n", stderr);
|
||||
fputs("base16384 -[ed][t][n][cC] [inputfile] [outputfile]\n", stderr);
|
||||
fputs(" -e\t\tencode (default)\n", stderr);
|
||||
fputs(" -d\t\tdecode\n", stderr);
|
||||
fputs(" -t\t\tshow spend time\n", stderr);
|
||||
fputs(" -n\t\tdon't write utf16be file header (0xFEFF)\n", stderr);
|
||||
fputs(" -n\t\tdonot write utf16be file header (0xFEFF)\n", stderr);
|
||||
fputs(" -c\t\tembed or validate checksum in remainder\n", stderr);
|
||||
fputs(" -C\t\tdo -c forcely\n", stderr);
|
||||
fputs(" inputfile\tpass - to read from stdin\n", stderr);
|
||||
|
||||
67
base16384.h
67
base16384.h
@@ -23,6 +23,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#include <BaseTsd.h>
|
||||
#ifndef ssize_t
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum base16384_err_t {
|
||||
base16384_err_ok,
|
||||
@@ -59,6 +65,39 @@ typedef enum base16384_err_t base16384_err_t;
|
||||
// forcely do sumcheck without checking data length
|
||||
#define BASE16384_FLAG_DO_SUM_CHECK_FORCELY (1<<2)
|
||||
|
||||
/**
|
||||
* @brief custom reader function interface
|
||||
* @param client_data the data pointer defined by the client
|
||||
* @param buffer to where put data
|
||||
* @param count read bytes count
|
||||
* @return the size read
|
||||
*/
|
||||
typedef ssize_t (*base16384_reader_t)(const void *client_data, void *buffer, size_t count);
|
||||
|
||||
/**
|
||||
* @brief custom writer function interface
|
||||
* @param client_data the data pointer defined by the client
|
||||
* @param buffer from where read data
|
||||
* @param count write bytes count
|
||||
* @return the size written
|
||||
*/
|
||||
typedef ssize_t (*base16384_writer_t)(const void *client_data, const void *buffer, size_t count);
|
||||
|
||||
union base16384_io_function_t {
|
||||
base16384_reader_t reader;
|
||||
base16384_writer_t writer;
|
||||
};
|
||||
typedef union base16384_io_function_t base16384_io_function_t;
|
||||
|
||||
struct base16384_stream_t {
|
||||
base16384_io_function_t f;
|
||||
void *client_data;
|
||||
};
|
||||
/**
|
||||
* @brief for stream encode/decode
|
||||
*/
|
||||
typedef struct base16384_stream_t base16384_stream_t;
|
||||
|
||||
/**
|
||||
* @brief calculate the exact encoded size
|
||||
* @param dlen the data length to encode
|
||||
@@ -67,7 +106,7 @@ typedef enum base16384_err_t base16384_err_t;
|
||||
static inline int _base16384_encode_len(int dlen) {
|
||||
int outlen = dlen / 7 * 8;
|
||||
int offset = dlen % 7;
|
||||
switch(offset) { // 算上偏移标志字符占用的 2 字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen += 4; break;
|
||||
case 2:
|
||||
@@ -97,7 +136,7 @@ static inline int base16384_encode_len(int dlen) {
|
||||
*/
|
||||
static inline int _base16384_decode_len(int dlen, int offset) {
|
||||
int outlen = dlen;
|
||||
switch(offset) { // 算上偏移标志字符占用的 2 字节
|
||||
switch(offset) { // also count 0x3dxx
|
||||
case 0: break;
|
||||
case 1: outlen -= 4; break;
|
||||
case 2:
|
||||
@@ -210,6 +249,17 @@ base16384_err_t base16384_encode_fp_detailed(base16384_typed_flag_params(FILE*))
|
||||
*/
|
||||
base16384_err_t base16384_encode_fd_detailed(base16384_typed_flag_params(int));
|
||||
|
||||
/**
|
||||
* @brief encode custom input reader to custom output writer
|
||||
* @param input custom input reader
|
||||
* @param output custom output writer
|
||||
* @param encbuf must be no less than BASE16384_ENCBUFSZ
|
||||
* @param decbuf must be no less than BASE16384_DECBUFSZ
|
||||
* @param flag BASE16384_FLAG_xxx value, add multiple flags by `|`
|
||||
* @return the error code
|
||||
*/
|
||||
base16384_err_t base16384_encode_stream_detailed(base16384_typed_flag_params(base16384_stream_t*));
|
||||
|
||||
/**
|
||||
* @brief decode input file to output file
|
||||
* @param input filename or `-` to specify stdin
|
||||
@@ -243,16 +293,29 @@ base16384_err_t base16384_decode_fp_detailed(base16384_typed_flag_params(FILE*))
|
||||
*/
|
||||
base16384_err_t base16384_decode_fd_detailed(base16384_typed_flag_params(int));
|
||||
|
||||
/**
|
||||
* @brief decode custom input reader to custom output writer
|
||||
* @param input custom input reader
|
||||
* @param output custom output writer
|
||||
* @param encbuf must be no less than BASE16384_ENCBUFSZ
|
||||
* @param decbuf must be no less than BASE16384_DECBUFSZ
|
||||
* @param flag BASE16384_FLAG_xxx value, add multiple flags by `|`
|
||||
* @return the error code
|
||||
*/
|
||||
base16384_err_t base16384_decode_stream_detailed(base16384_typed_flag_params(base16384_stream_t*));
|
||||
|
||||
#define BASE16384_WRAP_DECL(method, name, type) \
|
||||
base16384_err_t base16384_##method##_##name(base16384_typed_params(type));
|
||||
|
||||
BASE16384_WRAP_DECL(encode, file, const char*);
|
||||
BASE16384_WRAP_DECL(encode, fp, FILE*);
|
||||
BASE16384_WRAP_DECL(encode, fd, int);
|
||||
BASE16384_WRAP_DECL(encode, stream, base16384_stream_t*);
|
||||
|
||||
BASE16384_WRAP_DECL(decode, file, const char*);
|
||||
BASE16384_WRAP_DECL(decode, fp, FILE*);
|
||||
BASE16384_WRAP_DECL(decode, fd, int);
|
||||
BASE16384_WRAP_DECL(decode, stream, base16384_stream_t*);
|
||||
|
||||
#undef BASE16384_WRAP_DECL
|
||||
|
||||
|
||||
4
binary.h
4
binary.h
@@ -90,7 +90,11 @@
|
||||
// initial sum value used in BASE16384_FLAG_SUM_CHECK_ON_REMAIN
|
||||
#define BASE16384_SIMPLE_SUM_INIT_VALUE (0x8e29c213)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static inline uint32_t calc_sum(uint32_t sum, int cnt, const char* encbuf) {
|
||||
#else
|
||||
static inline uint32_t calc_sum(uint32_t sum, size_t cnt, const char* encbuf) {
|
||||
#endif
|
||||
size_t i;
|
||||
uint32_t buf;
|
||||
for(i = 0; i < cnt; i++) {
|
||||
|
||||
168
file.c
168
file.c
@@ -16,6 +16,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __cosmopolitan
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -57,14 +63,14 @@ static inline off_t get_file_size(const char* filepath) {
|
||||
#define do_sum_check(flag) ((flag)&(BASE16384_FLAG_DO_SUM_CHECK_FORCELY|BASE16384_FLAG_SUM_CHECK_ON_REMAIN))
|
||||
|
||||
base16384_err_t base16384_encode_file_detailed(const char* input, const char* output, char* encbuf, char* decbuf, int flag) {
|
||||
off_t inputsize;
|
||||
FILE *fp = NULL, *fpo;
|
||||
int errnobak = 0, is_stdin = is_standard_io(input);
|
||||
base16384_err_t retval = base16384_err_ok;
|
||||
if(!input || !output || strlen(input) <= 0 || strlen(output) <= 0) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_invalid_file_name;
|
||||
}
|
||||
base16384_err_t retval = base16384_err_ok;
|
||||
off_t inputsize;
|
||||
FILE *fp = NULL, *fpo;
|
||||
int errnobak = 0, is_stdin = is_standard_io(input);
|
||||
if(is_stdin) { // read from stdin
|
||||
inputsize = _BASE16384_ENCBUFSZ;
|
||||
fp = stdin;
|
||||
@@ -91,7 +97,11 @@ base16384_err_t base16384_encode_file_detailed(const char* input, const char* ou
|
||||
fputc(0xFE, fpo);
|
||||
fputc(0xFF, fpo);
|
||||
}
|
||||
size_t cnt;
|
||||
#ifdef _MSC_VER
|
||||
int cnt;
|
||||
#else
|
||||
size_t cnt;
|
||||
#endif
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
while((cnt = fread(encbuf, sizeof(char), inputsize, fp)) > 0) {
|
||||
int n;
|
||||
@@ -159,7 +169,11 @@ base16384_err_t base16384_encode_fp_detailed(FILE* input, FILE* output, char* en
|
||||
}
|
||||
off_t inputsize = _BASE16384_ENCBUFSZ;
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
size_t cnt;
|
||||
#ifdef _MSC_VER
|
||||
int cnt;
|
||||
#else
|
||||
size_t cnt;
|
||||
#endif
|
||||
while((cnt = fread(encbuf, sizeof(char), inputsize, input)) > 0) {
|
||||
int n;
|
||||
while(cnt%7) {
|
||||
@@ -213,10 +227,45 @@ base16384_err_t base16384_encode_fd_detailed(int input, int output, char* encbuf
|
||||
return base16384_err_ok;
|
||||
}
|
||||
|
||||
#define rm_head(fp) {\
|
||||
int ch = fgetc(fp);\
|
||||
if(ch == 0xFE) fgetc(fp);\
|
||||
else ungetc(ch, fp);\
|
||||
#define call_reader(cd, buf, n) (input->f.reader((cd)->client_data, (buf), (n)))
|
||||
#define call_writer(cd, buf, n) (output->f.writer((cd)->client_data, (buf), (n)))
|
||||
|
||||
base16384_err_t base16384_encode_stream_detailed(base16384_stream_t* input, base16384_stream_t* output, char* encbuf, char* decbuf, int flag) {
|
||||
if(!input || !input->f.reader) {
|
||||
return base16384_err_fopen_input_file;
|
||||
}
|
||||
if(!output || !output->f.writer) {
|
||||
return base16384_err_fopen_output_file;
|
||||
}
|
||||
off_t inputsize = _BASE16384_ENCBUFSZ;
|
||||
size_t cnt = 0;
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
if(!(flag&BASE16384_FLAG_NOHEADER)) call_writer(output, "\xfe\xff", 2);
|
||||
while((cnt = call_reader(input, encbuf, inputsize)) > 0) {
|
||||
ssize_t n;
|
||||
while(cnt%7) {
|
||||
n = call_reader(input, encbuf+cnt, sizeof(char));
|
||||
if(n > 0) cnt++;
|
||||
else break;
|
||||
}
|
||||
if(do_sum_check(flag)) {
|
||||
sum = calc_sum(sum, cnt, encbuf);
|
||||
if(cnt%7) { // last encode
|
||||
*(uint32_t*)(&encbuf[cnt]) = htobe32(sum);
|
||||
}
|
||||
}
|
||||
n = base16384_encode_unsafe(encbuf, cnt, decbuf);
|
||||
if(n && call_writer(output, decbuf, n) < n) {
|
||||
return base16384_err_write_file;
|
||||
}
|
||||
}
|
||||
return base16384_err_ok;
|
||||
}
|
||||
|
||||
static inline void rm_head(FILE* fp) {
|
||||
int ch = fgetc(fp);
|
||||
if(ch == 0xFE) fgetc(fp);
|
||||
else ungetc(ch, fp);
|
||||
}
|
||||
|
||||
#define skip_offset(input_file) ((input_file[0]==(char)0xFE)?2:0)
|
||||
@@ -230,16 +279,16 @@ static inline int is_next_end(FILE* fp) {
|
||||
}
|
||||
|
||||
base16384_err_t base16384_decode_file_detailed(const char* input, const char* output, char* encbuf, char* decbuf, int flag) {
|
||||
if(!input || !output || strlen(input) <= 0 || strlen(output) <= 0) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_invalid_file_name;
|
||||
}
|
||||
off_t inputsize;
|
||||
FILE* fp = NULL;
|
||||
FILE* fpo;
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
base16384_err_t retval = base16384_err_ok;
|
||||
int errnobak = 0, is_stdin = is_standard_io(input);
|
||||
if(!input || !output || strlen(input) <= 0 || strlen(output) <= 0) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_invalid_file_name;
|
||||
}
|
||||
if(is_stdin) { // read from stdin
|
||||
inputsize = _BASE16384_DECBUFSZ;
|
||||
fp = stdin;
|
||||
@@ -264,9 +313,11 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou
|
||||
goto_base16384_file_detailed_cleanup(decode, base16384_err_fopen_input_file, {});
|
||||
}
|
||||
rm_head(fp);
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) {
|
||||
goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
||||
}
|
||||
#endif
|
||||
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
||||
size_t total_decoded_len = 0;
|
||||
while((cnt = fread(decbuf, sizeof(char), inputsize, fp)) > 0) {
|
||||
@@ -281,7 +332,9 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou
|
||||
decbuf[cnt++] = '=';
|
||||
decbuf[cnt++] = end;
|
||||
}
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
||||
#endif
|
||||
offset = decbuf[cnt-1];
|
||||
last_decbuf_cnt = cnt;
|
||||
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
||||
@@ -341,9 +394,11 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
|
||||
off_t inputsize = _BASE16384_DECBUFSZ;
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
rm_head(input);
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) {
|
||||
return base16384_err_read_file;
|
||||
}
|
||||
#endif
|
||||
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
||||
size_t total_decoded_len = 0;
|
||||
while((cnt = fread(decbuf, sizeof(char), inputsize, input)) > 0) {
|
||||
@@ -358,7 +413,9 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
|
||||
decbuf[cnt++] = '=';
|
||||
decbuf[cnt++] = end;
|
||||
}
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) return base16384_err_read_file;
|
||||
#endif
|
||||
offset = decbuf[cnt-1];
|
||||
last_decbuf_cnt = cnt;
|
||||
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
||||
@@ -429,9 +486,11 @@ base16384_err_t base16384_decode_fd_detailed(int input, int output, char* encbuf
|
||||
else break;
|
||||
}
|
||||
uint16_t next = is_next_end_fd(input);
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) {
|
||||
return base16384_err_read_file;
|
||||
}
|
||||
#endif
|
||||
if((uint16_t)(~next)) {
|
||||
if(next&0xff00) {
|
||||
decbuf[n++] = '=';
|
||||
@@ -458,3 +517,84 @@ base16384_err_t base16384_decode_fd_detailed(int input, int output, char* encbuf
|
||||
}
|
||||
return base16384_err_ok;
|
||||
}
|
||||
|
||||
static inline uint16_t is_next_end_stream(base16384_stream_t* input) {
|
||||
uint8_t ch = 0;
|
||||
if(call_reader(input, &ch, 1) != 1) return (uint16_t)EOF;
|
||||
uint16_t ret = (uint16_t)ch & 0x00ff;
|
||||
if(ch == '=') {
|
||||
if(call_reader(input, &ch, 1) != 1) return (uint16_t)EOF;
|
||||
ret <<= 8;
|
||||
ret |= (uint16_t)ch & 0x00ff;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
base16384_err_t base16384_decode_stream_detailed(base16384_stream_t* input, base16384_stream_t* output, char* encbuf, char* decbuf, int flag) {
|
||||
if(!input || !input->f.reader) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_fopen_input_file;
|
||||
}
|
||||
if(!output || !output->f.writer) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_fopen_output_file;
|
||||
}
|
||||
|
||||
off_t inputsize = _BASE16384_DECBUFSZ;
|
||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||
uint8_t remains[8];
|
||||
|
||||
decbuf[0] = 0;
|
||||
if(call_reader(input, remains, 2) != 2) {
|
||||
return base16384_err_read_file;
|
||||
}
|
||||
|
||||
int p = 0;
|
||||
if(remains[0] != (uint8_t)(0xfe)) p = 2;
|
||||
|
||||
int n, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
||||
size_t total_decoded_len = 0;
|
||||
while((n = call_reader(input, decbuf+p, inputsize-p)) > 0) {
|
||||
if(p) {
|
||||
memcpy(decbuf, remains, p);
|
||||
n += p;
|
||||
p = 0;
|
||||
}
|
||||
int x;
|
||||
while(n%8) {
|
||||
x = call_reader(input, decbuf+n, sizeof(char));
|
||||
if(x > 0) n++;
|
||||
else break;
|
||||
}
|
||||
uint16_t next = is_next_end_stream(input);
|
||||
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||
if(errno) {
|
||||
return base16384_err_read_file;
|
||||
}
|
||||
#endif
|
||||
if((uint16_t)(~next)) {
|
||||
if(next&0xff00) {
|
||||
decbuf[n++] = '=';
|
||||
decbuf[n++] = (char)(next&0x00ff);
|
||||
} else remains[p++] = (char)(next&0x00ff);
|
||||
}
|
||||
offset = decbuf[n-1];
|
||||
last_decbuf_cnt = n;
|
||||
n = base16384_decode_unsafe(decbuf, n, encbuf);
|
||||
if(n && call_writer(output, encbuf, n) != n) {
|
||||
return base16384_err_write_file;
|
||||
}
|
||||
total_decoded_len += n;
|
||||
if(do_sum_check(flag)) sum = calc_sum(sum, n, encbuf);
|
||||
last_encbuf_cnt = n;
|
||||
}
|
||||
if(do_sum_check(flag)
|
||||
&& (flag&BASE16384_FLAG_DO_SUM_CHECK_FORCELY || total_decoded_len >= _BASE16384_ENCBUFSZ)
|
||||
&& last_decbuf_cnt > 2
|
||||
&& decbuf[last_decbuf_cnt-2] == '='
|
||||
&& check_sum(sum, *(uint32_t*)(&encbuf[last_encbuf_cnt]), offset)) {
|
||||
errno = EINVAL;
|
||||
return base16384_err_invalid_decoding_checksum;
|
||||
}
|
||||
return base16384_err_ok;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
#define TEST_SIZE (4096)
|
||||
|
||||
char encbuf[TEST_SIZE+16];
|
||||
char decbuf[TEST_SIZE/7*8+16];
|
||||
char tstbuf[TEST_SIZE+16];
|
||||
static char encbuf[TEST_SIZE+16];
|
||||
static char decbuf[TEST_SIZE/7*8+16];
|
||||
static char tstbuf[TEST_SIZE+16];
|
||||
|
||||
#define loop_diff(target) \
|
||||
for(i = start; i < end; i++) { \
|
||||
|
||||
@@ -39,19 +39,9 @@
|
||||
#define TEST_OUTPUT_FILENAME "file_test_output.bin"
|
||||
#define TEST_VALIDATE_FILENAME "file_test_validate.bin"
|
||||
|
||||
char encbuf[BASE16384_ENCBUFSZ];
|
||||
char decbuf[BASE16384_DECBUFSZ];
|
||||
char tstbuf[BASE16384_ENCBUFSZ];
|
||||
|
||||
#define init_input_file() \
|
||||
for(i = 0; i < BASE16384_ENCBUFSZ; i += sizeof(int)) { \
|
||||
*(int*)(&encbuf[i]) = rand(); \
|
||||
} \
|
||||
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
|
||||
ok(!fp, "fopen"); \
|
||||
ok(fwrite(encbuf, BASE16384_ENCBUFSZ, 1, fp) != 1, "fwrite"); \
|
||||
ok(fclose(fp), "fclose"); \
|
||||
fputs("input file created.\n", stderr);
|
||||
static char encbuf[BASE16384_ENCBUFSZ];
|
||||
static char decbuf[BASE16384_DECBUFSZ];
|
||||
static char tstbuf[BASE16384_ENCBUFSZ];
|
||||
|
||||
#define test_file_detailed(flag) \
|
||||
fputs("testing base16384_en/decode_file with flag "#flag"...\n", stderr); \
|
||||
@@ -107,19 +97,58 @@ char tstbuf[BASE16384_ENCBUFSZ];
|
||||
for(i = TEST_SIZE; i > 0; i--) { \
|
||||
reset_and_truncate(fd, i); \
|
||||
\
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND); \
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644); \
|
||||
loop_ok(!fdout, i, "open"); \
|
||||
\
|
||||
err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, 0); \
|
||||
err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, flag); \
|
||||
base16384_loop_ok(err); \
|
||||
loop_ok(close(fd), i, "close"); \
|
||||
\
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT); \
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
|
||||
loop_ok(!fdval, i, "open"); \
|
||||
\
|
||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
||||
\
|
||||
err = base16384_decode_fd_detailed(fdout, fdval, encbuf, decbuf, 0); \
|
||||
err = base16384_decode_fd_detailed(fdout, fdval, encbuf, decbuf, flag); \
|
||||
base16384_loop_ok(err); \
|
||||
\
|
||||
loop_ok(close(fdout), i, "close"); \
|
||||
loop_ok(close(fdval), i, "close"); \
|
||||
\
|
||||
validate_result(); \
|
||||
}
|
||||
|
||||
#define test_stream_detailed(flag) \
|
||||
fputs("testing base16384_en/decode_stream with flag "#flag"...\n", stderr); \
|
||||
init_input_file(); \
|
||||
for(i = TEST_SIZE; i > 0; i--) { \
|
||||
reset_and_truncate(fd, i); \
|
||||
\
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644); \
|
||||
loop_ok(!fdout, i, "open"); \
|
||||
\
|
||||
err = base16384_encode_stream_detailed(&(base16384_stream_t){ \
|
||||
.client_data = (void*)(uintptr_t)fd, \
|
||||
.f.reader = base16384_test_file_reader, \
|
||||
}, &(base16384_stream_t){ \
|
||||
.client_data = (void*)(uintptr_t)fdout, \
|
||||
.f.writer = base16384_test_file_writer, \
|
||||
}, encbuf, decbuf, flag); \
|
||||
base16384_loop_ok(err); \
|
||||
loop_ok(close(fd), i, "close"); \
|
||||
\
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
|
||||
loop_ok(!fdval, i, "open"); \
|
||||
\
|
||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
||||
\
|
||||
err = base16384_decode_stream_detailed(&(base16384_stream_t){ \
|
||||
.client_data = (void*)(uintptr_t)fdout, \
|
||||
.f.reader = base16384_test_file_reader, \
|
||||
}, &(base16384_stream_t){ \
|
||||
.client_data = (void*)(uintptr_t)fdval, \
|
||||
.f.writer = base16384_test_file_writer, \
|
||||
}, encbuf, decbuf, flag); \
|
||||
base16384_loop_ok(err); \
|
||||
\
|
||||
loop_ok(close(fdout), i, "close"); \
|
||||
@@ -142,12 +171,6 @@ char tstbuf[BASE16384_ENCBUFSZ];
|
||||
\
|
||||
test_##name##_detailed(BASE16384_FLAG_NOHEADER|BASE16384_FLAG_SUM_CHECK_ON_REMAIN|BASE16384_FLAG_DO_SUM_CHECK_FORCELY);
|
||||
|
||||
|
||||
#define remove_test_files() \
|
||||
remove(TEST_INPUT_FILENAME); \
|
||||
remove(TEST_OUTPUT_FILENAME); \
|
||||
remove(TEST_VALIDATE_FILENAME);
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
|
||||
@@ -155,9 +178,12 @@ int main() {
|
||||
int fd, i;
|
||||
base16384_err_t err;
|
||||
|
||||
init_test_files();
|
||||
|
||||
test_detailed(file);
|
||||
test_detailed(fp);
|
||||
test_detailed(fd);
|
||||
test_detailed(stream);
|
||||
|
||||
remove_test_files();
|
||||
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ok(has_failed, reason) \
|
||||
if (has_failed) { \
|
||||
perror(reason); \
|
||||
@@ -82,4 +90,66 @@
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define init_input_file() \
|
||||
fprintf(stderr, "fill encbufsz: %d\n", BASE16384_ENCBUFSZ);\
|
||||
for(i = 0; i < BASE16384_ENCBUFSZ/sizeof(uint16_t); i++) { \
|
||||
((uint16_t*)encbuf)[i] = (uint16_t)rand(); \
|
||||
} \
|
||||
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
|
||||
ok(!fp, "fopen"); \
|
||||
ok(fwrite(encbuf, BASE16384_ENCBUFSZ, 1, fp) != 1, "fwrite"); \
|
||||
ok(fclose(fp), "fclose"); \
|
||||
fputs("input file created.\n", stderr);
|
||||
|
||||
#define init_test_files() {\
|
||||
fd = open(TEST_INPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
|
||||
ok(fd<0, "open"); \
|
||||
ok(close(fd), "close"); \
|
||||
fd = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
|
||||
ok(fd<0, "open"); \
|
||||
ok(close(fd), "close"); \
|
||||
fd = open(TEST_VALIDATE_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
|
||||
ok(fd<0, "open"); \
|
||||
ok(close(fd), "close");
|
||||
|
||||
#define remove_test_files() \
|
||||
remove(TEST_INPUT_FILENAME); \
|
||||
remove(TEST_OUTPUT_FILENAME); \
|
||||
remove(TEST_VALIDATE_FILENAME); \
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
static ssize_t base16384_test_file_reader(const void *client_data, void *buffer, size_t count) {
|
||||
int fd = (int)((uintptr_t)client_data);
|
||||
ssize_t ret = read(fd, buffer, count);
|
||||
if(ret < 0) return ret;
|
||||
ssize_t i;
|
||||
for(i = 0; i < ret; i++) {
|
||||
((uint8_t*)(buffer))[i] = ~((uint8_t*)(buffer))[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t base16384_test_file_writer(const void *client_data, const void *buffer, size_t count) {
|
||||
int fd = (int)((uintptr_t)client_data);
|
||||
if(count <= 0) {
|
||||
errno = EINVAL;
|
||||
return -100;
|
||||
}
|
||||
uint8_t* wbuf = (uint8_t*)malloc(count);
|
||||
if(!wbuf) return -200;
|
||||
ssize_t i;
|
||||
for(i = 0; i < count; i++) {
|
||||
wbuf[i] = ~((uint8_t*)(buffer))[i];
|
||||
}
|
||||
ssize_t ret = write(fd, buffer, count);
|
||||
int errnobak = errno;
|
||||
free(wbuf);
|
||||
errno = errnobak;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,19 +39,9 @@
|
||||
#define TEST_OUTPUT_FILENAME "wrap_test_output.bin"
|
||||
#define TEST_VALIDATE_FILENAME "wrap_test_validate.bin"
|
||||
|
||||
char encbuf[BASE16384_ENCBUFSZ];
|
||||
char decbuf[BASE16384_DECBUFSZ];
|
||||
char tstbuf[BASE16384_ENCBUFSZ];
|
||||
|
||||
#define init_input_file() \
|
||||
for(i = 0; i < BASE16384_ENCBUFSZ; i += sizeof(int)) { \
|
||||
*(int*)(&encbuf[i]) = rand(); \
|
||||
} \
|
||||
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
|
||||
ok(!fp, "fopen"); \
|
||||
ok(fwrite(encbuf, BASE16384_ENCBUFSZ, 1, fp) != 1, "fwrite"); \
|
||||
ok(fclose(fp), "fclose"); \
|
||||
fputs("input file created.\n", stderr);
|
||||
static char encbuf[BASE16384_ENCBUFSZ];
|
||||
static char decbuf[BASE16384_DECBUFSZ];
|
||||
static char tstbuf[BASE16384_ENCBUFSZ];
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
@@ -60,6 +50,8 @@ int main() {
|
||||
int fd, i;
|
||||
base16384_err_t err;
|
||||
|
||||
init_test_files();
|
||||
|
||||
fputs("testing base16384_en/decode_file...\n", stderr);
|
||||
init_input_file();
|
||||
for(i = TEST_SIZE; i > 0; i--) {
|
||||
@@ -111,14 +103,14 @@ int main() {
|
||||
for(i = TEST_SIZE; i > 0; i--) {
|
||||
reset_and_truncate(fd, i);
|
||||
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND);
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644);
|
||||
loop_ok(!fdout, i, "open");
|
||||
|
||||
err = base16384_encode_fd(fd, fdout, encbuf, decbuf);
|
||||
base16384_loop_ok(err);
|
||||
loop_ok(close(fd), i, "close");
|
||||
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT);
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
loop_ok(!fdval, i, "open");
|
||||
|
||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
||||
@@ -132,9 +124,45 @@ int main() {
|
||||
validate_result();
|
||||
}
|
||||
|
||||
remove(TEST_INPUT_FILENAME);
|
||||
remove(TEST_OUTPUT_FILENAME);
|
||||
remove(TEST_VALIDATE_FILENAME);
|
||||
fputs("testing base16384_en/decode_stream...\n", stderr);
|
||||
init_input_file();
|
||||
for(i = TEST_SIZE; i > 0; i--) {
|
||||
reset_and_truncate(fd, i);
|
||||
|
||||
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644);
|
||||
loop_ok(!fdout, i, "open");
|
||||
|
||||
err = base16384_encode_stream(&(base16384_stream_t){
|
||||
.client_data = (void*)(uintptr_t)fd,
|
||||
.f.reader = base16384_test_file_reader,
|
||||
}, &(base16384_stream_t){
|
||||
.client_data = (void*)(uintptr_t)fdout,
|
||||
.f.writer = base16384_test_file_writer,
|
||||
}, encbuf, decbuf);
|
||||
base16384_loop_ok(err);
|
||||
loop_ok(close(fd), i, "close");
|
||||
|
||||
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
loop_ok(!fdval, i, "open");
|
||||
|
||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
||||
|
||||
err = base16384_decode_stream(&(base16384_stream_t){
|
||||
.client_data = (void*)(uintptr_t)fdout,
|
||||
.f.reader = base16384_test_file_reader,
|
||||
}, &(base16384_stream_t){
|
||||
.client_data = (void*)(uintptr_t)fdval,
|
||||
.f.writer = base16384_test_file_writer,
|
||||
}, encbuf, decbuf);
|
||||
base16384_loop_ok(err);
|
||||
|
||||
loop_ok(close(fdout), i, "close");
|
||||
loop_ok(close(fdval), i, "close");
|
||||
|
||||
validate_result();
|
||||
}
|
||||
|
||||
remove_test_files();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
2
wrap.c
2
wrap.c
@@ -28,10 +28,12 @@
|
||||
BASE16384_WRAP_DECL(encode, file, const char*);
|
||||
BASE16384_WRAP_DECL(encode, fp, FILE*);
|
||||
BASE16384_WRAP_DECL(encode, fd, int);
|
||||
BASE16384_WRAP_DECL(encode, stream, base16384_stream_t*);
|
||||
|
||||
BASE16384_WRAP_DECL(decode, file, const char*);
|
||||
BASE16384_WRAP_DECL(decode, fp, FILE*);
|
||||
BASE16384_WRAP_DECL(decode, fd, int);
|
||||
BASE16384_WRAP_DECL(decode, stream, base16384_stream_t*);
|
||||
|
||||
#undef BASE16384_WRAP_DECL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user