mirror of
https://github.com/fumiama/base16384.git
synced 2026-06-21 06:30:25 +08:00
fix(file): wierd fgetc/ungetc behavior on Windows
This commit is contained in:
@@ -84,8 +84,8 @@ union base16384_io_function_t {
|
|||||||
typedef union base16384_io_function_t base16384_io_function_t;
|
typedef union base16384_io_function_t base16384_io_function_t;
|
||||||
|
|
||||||
struct base16384_stream_t {
|
struct base16384_stream_t {
|
||||||
const base16384_io_function_t f;
|
base16384_io_function_t f;
|
||||||
const void *client_data;
|
void *client_data;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @brief for stream encode/decode
|
* @brief for stream encode/decode
|
||||||
|
|||||||
20
file.c
20
file.c
@@ -248,10 +248,10 @@ base16384_err_t base16384_encode_stream_detailed(base16384_stream_t* input, base
|
|||||||
return base16384_err_ok;
|
return base16384_err_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define rm_head(fp) {\
|
static inline void rm_head(FILE* fp) {
|
||||||
int ch = fgetc(fp);\
|
int ch = fgetc(fp);
|
||||||
if(ch == 0xFE) fgetc(fp);\
|
if(ch == 0xFE) fgetc(fp);
|
||||||
else ungetc(ch, fp);\
|
else ungetc(ch, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define skip_offset(input_file) ((input_file[0]==(char)0xFE)?2:0)
|
#define skip_offset(input_file) ((input_file[0]==(char)0xFE)?2:0)
|
||||||
@@ -299,9 +299,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, {});
|
goto_base16384_file_detailed_cleanup(decode, base16384_err_fopen_input_file, {});
|
||||||
}
|
}
|
||||||
rm_head(fp);
|
rm_head(fp);
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) {
|
if(errno) {
|
||||||
goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
||||||
size_t total_decoded_len = 0;
|
size_t total_decoded_len = 0;
|
||||||
while((cnt = fread(decbuf, sizeof(char), inputsize, fp)) > 0) {
|
while((cnt = fread(decbuf, sizeof(char), inputsize, fp)) > 0) {
|
||||||
@@ -316,7 +318,9 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou
|
|||||||
decbuf[cnt++] = '=';
|
decbuf[cnt++] = '=';
|
||||||
decbuf[cnt++] = end;
|
decbuf[cnt++] = end;
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
if(errno) goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
|
||||||
|
#endif
|
||||||
offset = decbuf[cnt-1];
|
offset = decbuf[cnt-1];
|
||||||
last_decbuf_cnt = cnt;
|
last_decbuf_cnt = cnt;
|
||||||
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
||||||
@@ -376,9 +380,11 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
|
|||||||
off_t inputsize = _BASE16384_DECBUFSZ;
|
off_t inputsize = _BASE16384_DECBUFSZ;
|
||||||
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
|
||||||
rm_head(input);
|
rm_head(input);
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) {
|
if(errno) {
|
||||||
return base16384_err_read_file;
|
return base16384_err_read_file;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
|
||||||
size_t total_decoded_len = 0;
|
size_t total_decoded_len = 0;
|
||||||
while((cnt = fread(decbuf, sizeof(char), inputsize, input)) > 0) {
|
while((cnt = fread(decbuf, sizeof(char), inputsize, input)) > 0) {
|
||||||
@@ -393,7 +399,9 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
|
|||||||
decbuf[cnt++] = '=';
|
decbuf[cnt++] = '=';
|
||||||
decbuf[cnt++] = end;
|
decbuf[cnt++] = end;
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) return base16384_err_read_file;
|
if(errno) return base16384_err_read_file;
|
||||||
|
#endif
|
||||||
offset = decbuf[cnt-1];
|
offset = decbuf[cnt-1];
|
||||||
last_decbuf_cnt = cnt;
|
last_decbuf_cnt = cnt;
|
||||||
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
|
||||||
@@ -464,9 +472,11 @@ base16384_err_t base16384_decode_fd_detailed(int input, int output, char* encbuf
|
|||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
uint16_t next = is_next_end_fd(input);
|
uint16_t next = is_next_end_fd(input);
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) {
|
if(errno) {
|
||||||
return base16384_err_read_file;
|
return base16384_err_read_file;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if((uint16_t)(~next)) {
|
if((uint16_t)(~next)) {
|
||||||
if(next&0xff00) {
|
if(next&0xff00) {
|
||||||
decbuf[n++] = '=';
|
decbuf[n++] = '=';
|
||||||
@@ -543,9 +553,11 @@ base16384_err_t base16384_decode_stream_detailed(base16384_stream_t* input, base
|
|||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
uint16_t next = is_next_end_stream(input);
|
uint16_t next = is_next_end_stream(input);
|
||||||
|
#ifndef _WIN32 // windows is crazy and always throws EINVAL
|
||||||
if(errno) {
|
if(errno) {
|
||||||
return base16384_err_read_file;
|
return base16384_err_read_file;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if((uint16_t)(~next)) {
|
if((uint16_t)(~next)) {
|
||||||
if(next&0xff00) {
|
if(next&0xff00) {
|
||||||
decbuf[n++] = '=';
|
decbuf[n++] = '=';
|
||||||
|
|||||||
@@ -97,14 +97,14 @@ static char tstbuf[BASE16384_ENCBUFSZ];
|
|||||||
for(i = TEST_SIZE; i > 0; i--) { \
|
for(i = TEST_SIZE; i > 0; i--) { \
|
||||||
reset_and_truncate(fd, 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"); \
|
loop_ok(!fdout, i, "open"); \
|
||||||
\
|
\
|
||||||
err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, flag); \
|
err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, flag); \
|
||||||
base16384_loop_ok(err); \
|
base16384_loop_ok(err); \
|
||||||
loop_ok(close(fd), i, "close"); \
|
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(!fdval, i, "open"); \
|
||||||
\
|
\
|
||||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
||||||
@@ -124,7 +124,7 @@ static char tstbuf[BASE16384_ENCBUFSZ];
|
|||||||
for(i = TEST_SIZE; i > 0; i--) { \
|
for(i = TEST_SIZE; i > 0; i--) { \
|
||||||
reset_and_truncate(fd, 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"); \
|
loop_ok(!fdout, i, "open"); \
|
||||||
\
|
\
|
||||||
err = base16384_encode_stream_detailed(&(base16384_stream_t){ \
|
err = base16384_encode_stream_detailed(&(base16384_stream_t){ \
|
||||||
@@ -137,7 +137,7 @@ static char tstbuf[BASE16384_ENCBUFSZ];
|
|||||||
base16384_loop_ok(err); \
|
base16384_loop_ok(err); \
|
||||||
loop_ok(close(fd), i, "close"); \
|
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(!fdval, i, "open"); \
|
||||||
\
|
\
|
||||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
|
||||||
@@ -171,12 +171,6 @@ static char tstbuf[BASE16384_ENCBUFSZ];
|
|||||||
\
|
\
|
||||||
test_##name##_detailed(BASE16384_FLAG_NOHEADER|BASE16384_FLAG_SUM_CHECK_ON_REMAIN|BASE16384_FLAG_DO_SUM_CHECK_FORCELY);
|
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() {
|
int main() {
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
@@ -184,6 +178,8 @@ int main() {
|
|||||||
int fd, i;
|
int fd, i;
|
||||||
base16384_err_t err;
|
base16384_err_t err;
|
||||||
|
|
||||||
|
init_test_files();
|
||||||
|
|
||||||
test_detailed(file);
|
test_detailed(file);
|
||||||
test_detailed(fp);
|
test_detailed(fp);
|
||||||
test_detailed(fd);
|
test_detailed(fd);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define ok(has_failed, reason) \
|
#define ok(has_failed, reason) \
|
||||||
if (has_failed) { \
|
if (has_failed) { \
|
||||||
perror(reason); \
|
perror(reason); \
|
||||||
@@ -83,8 +85,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define init_input_file() \
|
#define init_input_file() \
|
||||||
for(i = 0; i < BASE16384_ENCBUFSZ; i += sizeof(int)) { \
|
fprintf(stderr, "fill encbufsz: %d\n", BASE16384_ENCBUFSZ);\
|
||||||
*(int*)(&encbuf[i]) = rand(); \
|
for(i = 0; i < BASE16384_ENCBUFSZ/sizeof(uint16_t); i++) { \
|
||||||
|
((uint16_t*)encbuf)[i] = (uint16_t)rand(); \
|
||||||
} \
|
} \
|
||||||
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
|
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
|
||||||
ok(!fp, "fopen"); \
|
ok(!fp, "fopen"); \
|
||||||
@@ -92,6 +95,23 @@
|
|||||||
ok(fclose(fp), "fclose"); \
|
ok(fclose(fp), "fclose"); \
|
||||||
fputs("input file created.\n", stderr);
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ int main() {
|
|||||||
int fd, i;
|
int fd, i;
|
||||||
base16384_err_t err;
|
base16384_err_t err;
|
||||||
|
|
||||||
|
init_test_files();
|
||||||
|
|
||||||
fputs("testing base16384_en/decode_file...\n", stderr);
|
fputs("testing base16384_en/decode_file...\n", stderr);
|
||||||
init_input_file();
|
init_input_file();
|
||||||
for(i = TEST_SIZE; i > 0; i--) {
|
for(i = TEST_SIZE; i > 0; i--) {
|
||||||
@@ -101,14 +103,14 @@ int main() {
|
|||||||
for(i = TEST_SIZE; i > 0; i--) {
|
for(i = TEST_SIZE; i > 0; i--) {
|
||||||
reset_and_truncate(fd, 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");
|
loop_ok(!fdout, i, "open");
|
||||||
|
|
||||||
err = base16384_encode_fd(fd, fdout, encbuf, decbuf);
|
err = base16384_encode_fd(fd, fdout, encbuf, decbuf);
|
||||||
base16384_loop_ok(err);
|
base16384_loop_ok(err);
|
||||||
loop_ok(close(fd), i, "close");
|
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(!fdval, i, "open");
|
||||||
|
|
||||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
||||||
@@ -127,7 +129,7 @@ int main() {
|
|||||||
for(i = TEST_SIZE; i > 0; i--) {
|
for(i = TEST_SIZE; i > 0; i--) {
|
||||||
reset_and_truncate(fd, 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");
|
loop_ok(!fdout, i, "open");
|
||||||
|
|
||||||
err = base16384_encode_stream(&(base16384_stream_t){
|
err = base16384_encode_stream(&(base16384_stream_t){
|
||||||
@@ -140,7 +142,7 @@ int main() {
|
|||||||
base16384_loop_ok(err);
|
base16384_loop_ok(err);
|
||||||
loop_ok(close(fd), i, "close");
|
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(!fdval, i, "open");
|
||||||
|
|
||||||
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
|
||||||
@@ -160,9 +162,7 @@ int main() {
|
|||||||
validate_result();
|
validate_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(TEST_INPUT_FILENAME);
|
remove_test_files();
|
||||||
remove(TEST_OUTPUT_FILENAME);
|
|
||||||
remove(TEST_VALIDATE_FILENAME);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user