File: base16384.c

package info (click to toggle)
base16384 2.3.2-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 256 kB
  • sloc: ansic: 2,190; makefile: 2
file content (140 lines) | stat: -rw-r--r-- 4,140 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* base16384.c
 * This file is part of the base16384 distribution (https://github.com/fumiama/base16384).
 * Copyright (c) 2022-2025 Fumiama Minamoto.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __cosmopolitan
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#ifdef _WIN32
	#include <windows.h>
#endif
#endif
#include "base16384.h"

static char encbuf[BASE16384_ENCBUFSZ];
static char decbuf[BASE16384_DECBUFSZ];

#ifndef _WIN32
static unsigned long get_start_ms() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}
#endif

static base16384_err_t print_usage() {
	#ifndef BASE16384_VERSION
		#define BASE16384_VERSION "dev"
	#endif
	#ifndef BASE16384_VERSION_DATE
		#define BASE16384_VERSION_DATE "unknown date"
	#endif
	fputs(
		"Copyright (c) 2022-2025 Fumiama Minamoto.\nBase16384 "
		BASE16384_VERSION
		" ("
			BASE16384_VERSION_DATE
		"). Usage:\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\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);
	fputs("  outputfile\tpass - to write to stdout\n", stderr);
	return base16384_err_invalid_commandline_parameter;
}

int main(int argc, char** argv) {

	const char* cmd = argv[1];
	if(argc != 4 || cmd[0] != '-') return print_usage();

	int flaglen = strlen(cmd);
	if(flaglen <= 1 || flaglen > 5) return print_usage();

	#ifdef _WIN32
		clock_t t = 0;
	#else
		unsigned long t = 0;
	#endif

	uint16_t is_encode = 1, use_timer = 0, no_header = 0, use_checksum = 0;
	#define set_flag(f, v) ((f) = (((((f)>>8)+1) << 8)&0xff00) | (v&0x00ff))
	#define flag_has_been_set(f) ((f)>>8)
	#define set_or_test_flag(f, v) (flag_has_been_set(f)?1:(set_flag(f, v), 0))
	while(--flaglen) switch(cmd[flaglen]) { // skip cmd[0] = '-'
		case 'e':
			if(set_or_test_flag(is_encode, 1)) return print_usage();
		break;
		case 'd':
			if(set_or_test_flag(is_encode, 0)) return print_usage();
		break;
		case 't':
			if(set_or_test_flag(use_timer, 1)) return print_usage();
		break;
		case 'n':
			if(set_or_test_flag(no_header, 1)) return print_usage();
		break;
		case 'c':
			if(set_or_test_flag(use_checksum, 1)) return print_usage();
		break;
		case 'C':
			if(set_or_test_flag(use_checksum, 2)) return print_usage();
		break;
		default:
			return print_usage();
		break;
	}
	#define clear_high_byte(x) ((x) &= 0x00ff)
	clear_high_byte(is_encode); clear_high_byte(use_timer);
	clear_high_byte(no_header); clear_high_byte(use_checksum);

	if(use_timer) {
		#ifdef _WIN32
			t = clock();
		#else
			t = get_start_ms();
		#endif
	}

	base16384_err_t exitstat = base16384_err_ok;

	#define do_coding(method) base16384_##method##_file_detailed( \
		argv[2], argv[3], encbuf, decbuf, \
		(no_header?BASE16384_FLAG_NOHEADER:0) \
		| ((use_checksum&1)?BASE16384_FLAG_SUM_CHECK_ON_REMAIN:0) \
		| ((use_checksum&2)?BASE16384_FLAG_DO_SUM_CHECK_FORCELY:0) \
	)
		exitstat = is_encode?do_coding(encode):do_coding(decode);
	#undef do_coding
	if(t) {
		#ifdef _WIN32
			fprintf(stderr, "spend time: %lums\n", clock() - t);
		#else
			fprintf(stderr, "spend time: %lums\n", get_start_ms() - t);
		#endif
	}

    return base16384_perror(exitstat);

}