22#include <stdio.h>
33#include <stdlib.h>
44#include <sys/stat.h>
5+ #include <fcntl.h>
56#include <time.h>
6- #ifdef __WINNT__
7+ #ifdef _WIN32
78 #include <windows.h>
9+ #else
10+ #include <sys/mman.h>
811#endif
912#endif
1013#include "base14.h"
@@ -18,122 +21,169 @@ static off_t get_file_size(const char* filepath) {
1821}
1922#endif
2023
24+ char encbuf [BUFSIZ * 1024 /7 * 7 ];
25+ char decbuf [BUFSIZ * 1024 /8 * 8 + 2 ];
26+
2127void encode_file (const char * input , const char * output ) {
2228 off_t inputsize = get_file_size (input );
2329 if (inputsize <= 0 ) {
24- puts ("Get file size error! " );
30+ perror ("Get file size error: " );
2531 return ;
2632 }
27- FILE * fp = NULL ;
28- fp = fopen (input , "rb" );
29- if (!fp ) {
30- puts ("Open input file error!" );
33+ if (inputsize > (1u <<31 )- 1 ) {
34+ puts ("Input file too big!" );
3135 return ;
3236 }
3337 FILE * fpo = NULL ;
3438 fpo = fopen (output , "wb" );
3539 if (!fpo ) {
36- puts ( "Open output file error! " );
40+ perror ( "Fopen output file error: " );
3741 return ;
3842 }
39- if (inputsize > BUFSIZ * 1024 ) inputsize = BUFSIZ * 1024 /7 * 7 ; // big file
40- char * bufi = (char * )malloc (inputsize );
41- if (!bufi ) {
42- puts ("Allocate input buffer error!" );
43- return ;
43+ if (inputsize > BUFSIZ * 1024 ) { // big file, use encbuf & fread
44+ inputsize = BUFSIZ * 1024 /7 * 7 ;
45+ #ifdef _WIN32
4446 }
45- int outputsize = encode_len (inputsize )+ 16 ;
46- char * bufo = (char * )malloc (outputsize );
47- if (!bufo ) {
48- puts ("Allocate output buffer error!" );
49- return ;
50- }
51- size_t cnt = 0 ;
52- fputc (0xFE , fpo );
53- fputc (0xFF , fpo );
54- while ((cnt = fread (bufi , sizeof (char ), inputsize , fp ))) {
55- int n = encode (bufi , cnt , bufo , outputsize );
56- if (fwrite (bufo , n , 1 , fpo ) <= 0 ) {
57- puts ("Write file error!" );
47+ #endif
48+ FILE * fp = NULL ;
49+ fp = fopen (input , "rb" );
50+ if (!fp ) {
51+ perror ("Fopen input file error: " );
5852 return ;
5953 }
54+
55+ int outputsize = encode_len (inputsize )+ 16 ;
56+ size_t cnt = 0 ;
57+ fputc (0xFE , fpo );
58+ fputc (0xFF , fpo );
59+ while ((cnt = fread (encbuf , sizeof (char ), inputsize , fp ))) {
60+ int n = encode (encbuf , cnt , decbuf , outputsize );
61+ if (fwrite (decbuf , n , 1 , fpo ) <= 0 ) {
62+ perror ("Write file error: " );
63+ return ;
64+ }
65+ }
66+ /* 由操作系统负责释放资源
67+ fclose(fpo);
68+ fclose(fp);
69+ 以缩短程序运行时间 */
70+ #ifndef _WIN32
71+ } else { // small file, use mmap & fwrite
72+ int fd = open (input , O_RDONLY );
73+ if (fd <= 0 ) {
74+ perror ("Open input file error: " );
75+ return ;
76+ }
77+ char * input_file = mmap (NULL , (size_t )inputsize , PROT_READ , MAP_PRIVATE , fd , 0 );
78+ if (input_file == MAP_FAILED ) {
79+ perror ("Map input file error: " );
80+ return ;
81+ }
82+ int outputsize = encode_len (inputsize )+ 16 ;
83+ fputc (0xFE , fpo );
84+ fputc (0xFF , fpo );
85+ int n = encode (input_file , (int )inputsize , decbuf , outputsize );
86+ if (fwrite (decbuf , n , 1 , fpo ) <= 0 ) {
87+ perror ("Write file error: " );
88+ return ;
89+ }
90+ munmap (input_file , (size_t )inputsize );
91+ /* 由操作系统负责释放资源
92+ fclose(fpo);
93+ close(fd);
94+ 以缩短程序运行时间 */
6095 }
61- /* 由操作系统负责释放资源
62- free(bufo);
63- free(bufi);
64- fclose(fpo);
65- fclose(fp);
66- 以缩短程序运行时间 */
96+ #endif
6797}
6898
69- void rm_head (FILE * fp ) {
70- int ch = fgetc (fp );
71- if (ch == 0xFE ) fgetc (fp );
72- else rewind (fp );
99+ #define rm_head (fp ) {\
100+ int ch = fgetc(fp);\
101+ if(ch == 0xFE) fgetc(fp);\
102+ else rewind(fp);\
73103}
74104
105+ #define skip_offset (input_file ) ((input_file[0]==(char)0xFE)?2:0)
106+
75107static int is_next_end (FILE * fp ) {
76108 int ch = fgetc (fp );
77109 if (ch == '=' ) return fgetc (fp );
78- else {
79- ungetc (ch , fp );
80- return 0 ;
81- }
110+ ungetc (ch , fp );
111+ return 0 ;
82112}
83113
84114void decode_file (const char * input , const char * output ) {
85115 off_t inputsize = get_file_size (input );
86116 if (inputsize <= 0 ) {
87- puts ("Get file size error! " );
117+ perror ("Get file size error: " );
88118 return ;
89119 }
90- FILE * fp = NULL ;
91- fp = fopen (input , "rb" );
92- if (!fp ) {
93- puts ("Open input file error!" );
120+ if (inputsize > (1u <<31 )- 1 ) {
121+ puts ("Input file too big!" );
94122 return ;
95123 }
96124 FILE * fpo = NULL ;
97125 fpo = fopen (output , "wb" );
98126 if (!fpo ) {
99- puts ( "Open output file error! " );
127+ perror ( "Fopen output file error: " );
100128 return ;
101129 }
102- if (inputsize > BUFSIZ * 1024 ) inputsize = BUFSIZ * 1024 /8 * 8 ; // big file
103- char * bufi = (char * )malloc (inputsize + 2 ); // +2避免漏检结束偏移标志
104- if (!bufi ) {
105- puts ("Allocate input buffer error!" );
106- return ;
130+ if (inputsize > BUFSIZ * 1024 ) { // big file, use decbuf & fread
131+ inputsize = BUFSIZ * 1024 /8 * 8 ;
132+ #ifdef _WIN32
107133 }
108- int outputsize = decode_len (inputsize , 0 )+ 16 ;
109- char * bufo = (char * )malloc (outputsize );
110- if (!bufo ) {
111- puts ("Allocate output buffer error!" );
112- return ;
113- }
114- int cnt = 0 ;
115- int end = 0 ;
116- rm_head (fp );
117- while ((cnt = fread (bufi , sizeof (char ), inputsize , fp ))) {
118- if ((end = is_next_end (fp ))) {
119- bufi [cnt ++ ] = '=' ;
120- bufi [cnt ++ ] = end ;
134+ #endif
135+ FILE * fp = NULL ;
136+ fp = fopen (input , "rb" );
137+ if (!fp ) {
138+ perror ("Fopen input file error: " );
139+ return ;
121140 }
122- int n = decode (bufi , cnt , bufo , outputsize );
123- if (fwrite (bufo , n , 1 , fpo ) <= 0 ) {
124- puts ("Write file error!" );
141+ int outputsize = decode_len (inputsize , 0 )+ 16 ;
142+ int cnt = 0 ;
143+ int end = 0 ;
144+ rm_head (fp );
145+ while ((cnt = fread (decbuf , sizeof (char ), inputsize , fp ))) {
146+ if ((end = is_next_end (fp ))) {
147+ decbuf [cnt ++ ] = '=' ;
148+ decbuf [cnt ++ ] = end ;
149+ }
150+ if (fwrite (encbuf , decode (decbuf , cnt , encbuf , outputsize ), 1 , fpo ) <= 0 ) {
151+ perror ("Write file error: " );
152+ return ;
153+ }
154+ }
155+ /* 由操作系统负责释放资源
156+ fclose(fpo);
157+ fclose(fp);
158+ 以缩短程序运行时间 */
159+ #ifndef _WIN32
160+ } else { // small file, use mmap & fwrite
161+ int fd = open (input , O_RDONLY );
162+ if (fd <= 0 ) {
163+ perror ("Open input file error: " );
164+ return ;
165+ }
166+ char * input_file = mmap (NULL , (size_t )inputsize , PROT_READ , MAP_PRIVATE , fd , 0 );
167+ if (input_file == MAP_FAILED ) {
168+ perror ("Map input file error: " );
125169 return ;
126170 }
171+ int outputsize = decode_len (inputsize , 0 )+ 16 ;
172+ int off = skip_offset (input_file );
173+ if (fwrite (encbuf , decode (input_file + off , inputsize - off , encbuf , outputsize ), 1 , fpo ) <= 0 ) {
174+ perror ("Write file error: " );
175+ return ;
176+ }
177+ munmap (input_file , (size_t )inputsize );
178+ /* 由操作系统负责释放资源
179+ fclose(fpo);
180+ close(fd);
181+ 以缩短程序运行时间 */
127182 }
128- /* 由操作系统负责释放资源
129- free(bufo);
130- free(bufi);
131- fclose(fpo);
132- fclose(fp);
133- 以缩短程序运行时间 */
183+ #endif
134184}
135185
136- #ifndef __WINNT__
186+ #ifndef _WIN32
137187unsigned long get_start_ms () {
138188 struct timespec ts ;
139189 clock_gettime (CLOCK_MONOTONIC , & ts );
0 commit comments