Frost Moon Project

Src/wakewake.cpp-わけわけ。 Ver.1.01- アクセスランキング

Home > ソフトウェア > わけわけ。 > wakewake101.zip > Src > wakewake.cpp

wakewake.cpp
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
//######################################################
//
//                    わけわけ。
//                Ver.1.01 by x@rgs
//
//#####################################################
 
#include<sys/stat.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<ctype.h>
 
#if ((defined WIN32)||(defined WIN64))
    #define UNICODE
    #define _UNICODE
 
    typedef wchar_t TCHAR;
    #define __TEXT(q)   L##q
    #define _tmain wmain
 
    #define _tprintf    wprintf
    #define _stprintf   swprintf
    #define _tfopen     _wfopen
    #define _ftprintf   fwprintf
    #define _totlower   towlower
    #define _tcstold    wcstold
    #define _tstati64   _stati64
    #define _tcslen     wcslen
    #define _tcsrchr    wcsrchr
    #define _tcsncpy    wcsncpy
    #define _tsetlocale _wsetlocale
#else
    typedef char    TCHAR;
    #define __TEXT(q)   q
    #define _tmain main
 
    #define _tprintf    printf
    #define _stprintf   sprintf
    #define _tfopen     fopen
    #define _ftprintf   fprintf
    #define _totlower   tolower
    #define _tcstold    strtold
    #define _tstati64   stat64
    #define _fstati64   fstat64
    #define _tcslen     strlen
    #define _tcsrchr    strrchr
    #define _tcsncpy    strncpy
    #define _tsetlocale setlocale
#endif
 
#define _T(x)       __TEXT(x)
 
#ifdef __cplusplus
    extern "C"
#endif
void __wgetmainargs(int*,wchar_t***,wchar_t***,int,int*);
 
const long split_buffer_size=(1<<20)*5;
const long split_max_part=999+26*26*26;
 
struct option{
    TCHAR size[128];
};
 
 
//分割ファイル名の拡張子を作成
TCHAR* create_part_ext(long count,int ext_length=3);
 
 
//分割ファイル名の拡張子を作成
TCHAR* create_part_ext(long count,int ext_length){
    //'static'注意
    static TCHAR ext[256];
 
    int maxnumber=0;
    long maxalphabet=1;
 
    //'999'や'99999'など数字のみで構成される拡張子のmaxを作成
    for(int ii=0;ii<ext_length;ii++){
        int temp=9;
        for(int iii=0;iii<ii;iii++)temp*=10;
        maxnumber+=temp;
    }
 
    //アルファベットのみで構成される拡張子の総数を計算
    for(int iii=0;iii<ext_length;iii++)maxalphabet*=26;
 
    if(count<=maxnumber){
        _stprintf(ext,_T("%0*ld"),ext_length,count);
    }else if(count<=maxnumber+maxalphabet){
        long i;
 
        ext[ext_length]=_T('\0');
        i=count-(maxnumber+1);
        for(long ii=ext_length-1;;ii--){
            ext[ii]=i%26+_T('a');
            if(ii>0)i/=26;
            else break;
        }
    }
    return ext;
}
 
//ファイルを分割する(分割サイズまたは分割数指定による)
//分割サイズは1024b、10k、100mの様に指定する(10kb、100mbでも可)
//分割数は6,12の様に単位を付加せず指定する
bool splitfile(const TCHAR* target_file_name,const TCHAR* split_opt){
    FILE *fpr,*fpw;
    TCHAR output_file_name[FILENAME_MAX];
    TCHAR* buffer;
    long long splitsize=0;
    long long* splitsizes=NULL;
    long long chunks=0;
 
    if(target_file_name==NULL||split_opt==NULL){
        return false;
    }
 
    if(!(fpr=_tfopen(target_file_name,_T("rb")))){
        _ftprintf(stderr,_T("分割対象ファイル '%s' を開くことが出来ませんでした。\n"),target_file_name);
        return false;
    }
 
    {
        //'k'or'kb'
        TCHAR c=_totlower(split_opt[_tcslen(split_opt)-1]),cc=_totlower(split_opt[_tcslen(split_opt)-2]);
        long double input_size=_tcstold(split_opt,NULL);
 
        if(c==_T('k')||cc==_T('k')){
            splitsize=input_size*1024;
        }else if(c==_T('m')||cc==_T('m')){
            splitsize=input_size*1024*1024;
        }else if(c==_T('g')||cc==_T('g')){
            splitsize=input_size*1024*1024*1024;
        }else if(c==_T('b')){
            splitsize=input_size;
        }else{
            chunks=splitsize=input_size;
        }
    }
 
    if(splitsize<1){
        _ftprintf(stderr,_T("分割サイズまたは分割数が正しくありません。\n"));
        return false;
    }
 
    long long src_file_size;
    {
        struct _tstati64 st;
        _fstati64(fileno(fpr),&st);
        src_file_size=st.st_size;
    }
 
    if(src_file_size<=splitsize){
        _ftprintf(stderr,_T("分割する必要がありません。\n"));
        return false;
    }
 
    if(chunks>split_max_part||
       (chunks==0&&src_file_size/splitsize>split_max_part)){
        _ftprintf(stderr,_T("分割数が多すぎます。\n"));
        return false;
    }
 
    if(chunks>0){
        splitsizes=new long long[chunks];
 
        for(int ii=0;ii<chunks;ii++){
            //小数点以下を切り捨てた数値を配列に代入
            splitsizes[ii]=src_file_size/chunks;
        }
 
        if(src_file_size%chunks!=0){
            //割り切れなければ、先頭のファイルから1バイトずつファイルサイズを増やす
            for(int i=0;i<chunks;i++){
                splitsizes[i]++;
                long long total=0;
                for(int ii=0;ii<chunks;ii++){
                    total+=splitsizes[ii];
                }
                //割り切れればループを抜ける
                if(src_file_size%total==0)break;
            }
        }
    }
 
    buffer=new TCHAR[split_buffer_size];
    if(buffer==NULL){
        _ftprintf(stderr,_T("メモリの確保に失敗しました。\n"));
        return false;
    }
 
 
    long long totalwrite=0;
 
    for(long i=0;;i++){
        long long dest_file_size=0,readsize=0,writesize=0;
 
        _stprintf(output_file_name,_T("%s.%s"),target_file_name,create_part_ext(i+1));
 
        if(!(fpw=_tfopen(output_file_name,_T("wb")))){
            _ftprintf(stderr,_T("分割ファイルの作成に失敗しました。\n"));
            return false;
        }
 
        _tprintf(_T("%s\n"),output_file_name);
 
        if(chunks>0)splitsize=splitsizes[i];
 
        for(dest_file_size=0,readsize=split_buffer_size;dest_file_size<splitsize;dest_file_size+=readsize){
            if(readsize>splitsize-dest_file_size)readsize=splitsize-dest_file_size;
 
            writesize=fread(buffer,1,readsize,fpr);
            totalwrite+=writesize;
            if(writesize<=0)break;
 
            fwrite(buffer,1,writesize,fpw);
        }
        if(writesize<=0||totalwrite==src_file_size)break;
    }
    if(chunks)delete[] splitsizes;
    delete[] buffer;
    return true;
}
 
//分割ファイルの先頭ファイルかどうか
//拡張子が000、001、0000、00001、000000など
bool is_splitfile(const TCHAR* target_file_name,int* pext_length){
    bool result=false;
    int ext_length=0,dot_position=0;
 
    {
        const TCHAR* tmp=_tcsrchr(target_file_name,_T('.'));
        if(!tmp)return false;
        dot_position=tmp-target_file_name;
    }
 
    if(dot_position!=-1){
        TCHAR ext[256]={0};
 
        _tcsncpy(ext,target_file_name+dot_position+1,_tcslen(target_file_name)+1);
        if(ext[_tcslen(ext)-1]==_T('0')||ext[_tcslen(ext)-1]==_T('1')){
            //拡張子末尾が'0'か'1'であれば
            ext_length++;
            if(_tcslen(ext)==1){
                //'.0'の様に一桁である場合
                result=true;
            }else{
                for(int i=2;i<=_tcslen(ext);i++){
                    if(ext[_tcslen(ext)-i]==_T('0')){
                        ext_length++;
                        result=true;
                    }else{
                        //'0'以外の数字があるため先頭ファイルではない
                        result=false;
                        ext_length=0;
                        break;
                    }
                }
            }
        }
    }
    if(pext_length)*(pext_length)=ext_length;
    return result;
}
 
//ファイルを結合する
bool joinfile(const TCHAR* target_file_name,int ext_length){
    FILE *fpr,*fpw;
    TCHAR src_file_name[FILENAME_MAX]={0},dest_file_name[FILENAME_MAX]={0};
    TCHAR* buffer;
 
    {
        const TCHAR* tmp=_tcsrchr(target_file_name,_T('.'));
        if(!tmp)return false;
        int dot_position=tmp-target_file_name;
 
        if(target_file_name==NULL||dot_position==-1){
            return false;
        }
 
        _tcsncpy(dest_file_name,target_file_name,dot_position);
    }
 
    if(!(fpw=_tfopen(dest_file_name,_T("wb")))){
        _ftprintf(stderr,_T("結合ファイルの作成に失敗しました。\n"));
        return false;
    }
 
    buffer=new TCHAR[split_buffer_size];
    if(buffer==NULL){
        _ftprintf(stderr,_T("メモリの確保に失敗しました。\n"));
        return false;
    }
 
    for(long i=0;;i++){
        long long dest_file_size=0,writesize=0;
 
        _stprintf(src_file_name,_T("%s.%s"),dest_file_name,create_part_ext(i,ext_length));
 
        if(!(fpr=_tfopen(src_file_name,_T("rb")))){
            //拡張子'00...0'が存在しない場合以外は分割ファイル終端とみなす
            if(i!=0)break;
            else continue;
        }
 
        while((writesize=fread(buffer,1,split_buffer_size,fpr))){
            fwrite(buffer,1,writesize,fpw);
            dest_file_size+=writesize;
        }
    }
 
    _tprintf(_T("%s\n"),dest_file_name);
 
    delete[] buffer;
 
    return true;
}
 
int _tmain(int argc,TCHAR* argv[]){
    _tsetlocale(LC_ALL,_T("Japanese"));
 
    if(argc==1){
        _tprintf(_T("splilt:  wakewake -s<分割サイズ[k|m|g][b]> <対象ファイル...>\n")
                 _T("         wakewake -s<分割数> <対象ファイル...>\n")
                 _T("join  :  wakewake <対象ファイル...>\n"));
        return EXIT_FAILURE;
    }
 
    TCHAR *p,*pp;
    bool end_scan=false;
    option opt={0};
 
    while(--argc){
        ++argv;
        if(!end_scan&&**argv==_T('-')){
            if(**argv==*((*argv)+1)){
                //解析終了(--)
                end_scan=true;
                continue;
            }
 
            ++(pp=++(p=*argv));
            switch(*p){
                case _T('s'):
                    //サイズ指定
                    if(*pp){
                        _tcsncpy(opt.size,pp,sizeof(opt.size)/sizeof(TCHAR));
                    }
                    break;
            }
        }else{
            p=*argv;
 
            if(*opt.size){
                //分割を行う
                splitfile(p,opt.size);
            }else{
                //結合を行う
                int ext_length=0;
 
                if(is_splitfile(p,&ext_length)){
                    joinfile(p,ext_length);
                }else{
                    _ftprintf(stderr,_T("'%s' は分割されたファイルではありません。\n"),p);
                }
            }
        }
    }
    return 0;
}
 
#if ((defined WIN32)||(defined WIN64))
int main(){
    wchar_t** argv;
    wchar_t** enpv;
    int argc=0,si=0;
 
    __wgetmainargs(&argc,&argv,&enpv,1,&si);
    return wmain(argc,argv);
}
#endif


Home > ソフトウェア > わけわけ。 > wakewake101.zip > Src > wakewake.cpp