Diff

Not logged in

Differences From Artifact [9075347c70b2342c]:

To Artifact [3b6f189d5603825c]:


1 -private import std.string; 1 +private import win32.windows; 2 +private import std.string; 2 3 private import std.file; 3 4 private import std.c.stdio; 5 +private import std.string; 4 6 private import etc.c.zlib; 5 -private import win32.ansi.windows; 6 7 private import libbz2.bzlib; 7 8 private import util; 8 9 9 10 //---------------------------------------------------------------- 10 11 // Bga書庫のファイルヘッダ形式 11 12 //---------------------------------------------------------------- 12 13 ................................................................................ 23 24 ubyte header_type; // ヘッダの種類( 現在は常に 0 ) 24 25 ushort arc_type; // アーカイブタイプ 25 26 // 0:(ext==↓?非圧縮:圧縮) 1:圧縮 2:非圧縮 26 27 // .ARC, .ARJ, .BZ2, .BZA, .CAB, .GZ, .GZA, .LZH, 27 28 // .LZS, .PAK, .RAR, .TAZ, .TBZ, .TGZ, .Z, .ZIP, .ZOO 28 29 ushort dir_name_len; // ディレクトリ名の長さ 29 30 ushort file_name_len; // ファイル名の長さ 30 - char[] fname; // dir_name_len + file_name_len ( no '\0' ) 31 + string fname; // dir_name_len + file_name_len ( no '\0' ) 31 32 } 32 33 33 34 //---------------------------------------------------------------- 34 35 // エラー発生時に投げる例外 35 36 //---------------------------------------------------------------- 36 37 37 38 class BgaMelterError : Error ................................................................................ 90 91 } 91 92 92 93 class Filep 93 94 { 94 95 private FILE* fp; 95 96 private this( FILE* p ) { fp = p; } 96 97 97 - static Filep open( char[] filename, bool read ) 98 + static Filep open( string filename, bool read ) 98 99 { 99 100 FILE* fp = fopen( toStringz(filename), read?"rb":"wb" ); 100 101 return (fp ? new Filep(fp) : null); 101 102 } 102 103 103 104 int dup_han() 104 105 { ................................................................................ 106 107 lseek( fd, cur(), 0 ); 107 108 return fd; 108 109 } 109 110 110 111 void[] read( int siz ) 111 112 { 112 113 char[] buf; buf.length = siz; 113 - int rsiz = fread( buf, 1, siz, fp ); 114 + int rsiz = fread( buf.ptr, 1, siz, fp ); 114 115 if( rsiz < 0 ) 115 116 throw new BgaMelterError(ERROR_FILE_OPEN); 116 117 buf.length = rsiz; 117 118 return buf; 118 119 } 119 120 120 121 void write( void[] buf ) 121 122 { 122 123 while( buf.length > 0 ) 123 124 { 124 - int rsiz = fwrite( buf, 1, buf.length, fp ); 125 + int rsiz = fwrite( buf.ptr, 1, buf.length, fp ); 125 126 if( rsiz < 0 ) return; 126 - buf = buf[rsiz .. length]; 127 + buf = buf[rsiz .. $]; 127 128 } 128 129 } 129 130 130 131 int cur() 131 132 { 132 133 return ftell(fp); 133 134 } ................................................................................ 151 152 152 153 //---------------------------------------------------------------- 153 154 // メインクラス 154 155 //---------------------------------------------------------------- 155 156 156 157 class BgaMelter 157 158 { 158 - alias BgaAnswer delegate(inout BgaHeader) FileHandler; 159 + alias BgaAnswer delegate(ref BgaHeader) FileHandler; 159 160 alias BgaAnswer delegate(int, int) ProgressHandler; 160 161 161 162 private Filep fp = null; 162 163 163 - this( char[] arc_name ) 164 + this( string arc_name ) 164 165 { 165 166 fp = Filep.open( arc_name, true ); 166 167 if( fp is null ) 167 168 throw new BgaMelterError(ERROR_FILE_OPEN); 168 169 } 169 170 170 171 void close() ................................................................................ 212 213 bContinue = GzDec( hdr.compressed_size, hdr.original_size, outf, ph ); 213 214 else if( hdr.method == "BZ2\0" ) 214 215 bContinue = BzDec( hdr.original_size, outf, ph ); 215 216 216 217 // 閉じて属性設定 217 218 outf.close(); 218 219 dosSetFTime( hdr.fname, hdr.date, hdr.time ); 219 - SetFileAttributes( hdr.fname, hdr.attrib ); 220 + SetFileAttributesA( toStringz(hdr.fname), hdr.attrib ); 220 221 if( !bContinue ) 221 222 return; 222 223 } 223 224 finally { fp.seek_to(nextpos); } 224 225 } 225 226 } 226 227 finally { close(); } ................................................................................ 230 231 { 231 232 int cn = c; 232 233 return (cn>=0x80 ? cn|0xffffff00 : cn); 233 234 } 234 235 235 236 private int find_header() 236 237 { 237 - char[] dat = cast(char[]) fp.read(0x10000); 238 + string dat = cast(string) fp.read(0x10000); 238 239 239 240 for( int i=0; i<dat.length-28; ++i ) 240 241 { 241 242 if( dat[i+4]!='G' && dat[i+4]!='B' ) continue; 242 243 if( dat[i+5]!='Z' ) continue; 243 244 if( dat[i+6]!='I' && dat[i+6]!='2' ) continue; 244 245 if( dat[i+7]!='P' && dat[i+7]!='\0') continue; ................................................................................ 256 257 257 258 return -1; 258 259 } 259 260 260 261 private bool read_header( out BgaHeader hdr ) 261 262 { 262 263 // リトルエンディアンを仮定。ヘッダ読み込み 263 - char[] buf = cast(char[]) fp.read(28); 264 + string buf = cast(string) fp.read(28); 264 265 if( buf.length < 28 ) return false; 265 266 buf.length = BgaHeader.sizeof; 266 267 hdr = (cast(BgaHeader[]) buf)[0]; 267 268 hdr.fname = ""; 268 269 269 270 // ファイル名 270 - hdr.fname = cast(char[]) fp.read(hdr.dir_name_len + hdr.file_name_len); 271 + hdr.fname = cast(string) fp.read(hdr.dir_name_len + hdr.file_name_len); 271 272 if( hdr.fname.length < hdr.dir_name_len + hdr.file_name_len ) return false; 272 273 273 274 // チェックサム 274 275 int sum = 0; 275 276 for( int i=4; i!=28; ++i ) sum += signed_char(buf[i]); 276 277 foreach( char c ; hdr.fname ) sum += signed_char(c); 277 278 return (sum == hdr.checksum); 278 279 } 279 280 280 - private bool is_compressed( inout BgaHeader hdr ) // inout=just for optimization 281 + private bool is_compressed( ref BgaHeader hdr ) // ref=just for optimization 281 282 { 282 283 // ヘッダから、ファイルが圧縮格納されているかどうかを判定 283 284 if( hdr.arc_type==2 ) 284 285 return false; 285 286 if( hdr.arc_type==0 && hdr.compressed_size==hdr.original_size ) 286 287 { 287 - int x = rfind( hdr.fname, '.' ); 288 + int x = hdr.fname.lastIndexOf('.'); 288 289 if( x == -1 ) 289 290 return true; 290 - char[] ext = tolower(hdr.fname[x+1 .. length]); 291 + string ext = toLower(hdr.fname[x+1 .. $]); 291 292 if( ext=="arc" || ext=="arj" || ext=="bz2" || ext=="bza" 292 293 || ext=="cab" || ext=="gz" || ext=="gza" || ext=="lzh" 293 294 || ext=="lzs" || ext=="pak" || ext=="rar" || ext=="taz" 294 295 || ext=="tbz" || ext=="tgz" || ext=="z" || ext=="zip" 295 296 || ext=="zoo" ) 296 297 return false; 297 298 } 298 299 return true; 299 300 } 300 301 301 - static char[] pathMake( char[] path ) 302 + static string pathMake( string path ) 302 303 { 303 - char* ps = toStringz(path); 304 + char* ps = cast(char*)toStringz(path); 304 305 for(char* p=ps;;) 305 306 { 306 - for(; *p!=0&&*p!='\\'&&*p!='/'; p=CharNext(p)) {} 307 + for(; *p!=0&&*p!='\\'&&*p!='/'; p=CharNextA(p)) {} 307 308 if( *p==0 ) 308 309 break; 309 - CreateDirectory( toStringz(ps[0..(p-ps)]), null ); 310 + CreateDirectoryA( toStringz(ps[0..(p-ps)]), null ); 310 311 ++p; 311 312 } 312 313 return path; 313 314 } 314 315 315 316 enum { BUFSIZ = 65536 } 316 317 ................................................................................ 317 318 private bool NcDec( uint usiz, Filep outf, ProgressHandler ph ) 318 319 { 319 320 uint init_usiz = usiz; 320 321 321 322 // 非圧縮。コピーするだけ 322 323 while( usiz ) 323 324 { 324 - char[] r = cast(char[]) fp.read( BUFSIZ<usiz?BUFSIZ:usiz ); 325 + string r = cast(string) fp.read( BUFSIZ<usiz?BUFSIZ:usiz ); 325 326 usiz -= r.length; 326 - outf.write(r); 327 + outf.write(cast(char[])r); 327 328 328 329 // dlg 329 330 if( BgaAnswer.Abort==ph(init_usiz-usiz,usiz) ) return false; 330 331 } 331 332 332 333 // dlg 333 334 if( BgaAnswer.Abort==ph(init_usiz-usiz,usiz) ) return false; ................................................................................ 346 347 347 348 // zlib準備 348 349 z_stream zs; 349 350 zs.zalloc = null; 350 351 zs.zfree = null; 351 352 352 353 // 出力バッファ 353 - zs.next_out = outbuf; 354 + zs.next_out = outbuf.ptr; 354 355 zs.avail_out = outbuf.length; 355 356 356 357 // 入力バッファ 357 358 inbuf = cast(ubyte[]) fp.read( csiz<65536 ? csiz : 65536 ); 358 359 csiz -= inbuf.length; 359 - zs.next_in = inbuf; 360 + zs.next_in = inbuf.ptr; 360 361 zs.avail_in = inbuf.length; 361 362 362 363 // スタート 363 364 inflateInit2( &zs, -15 ); 364 365 try { 365 366 366 367 // 書庫から入力し終わるまでループ ................................................................................ 375 376 if( !csiz ) 376 377 break; 377 378 378 379 if( zs.avail_in<=0 ) 379 380 { 380 381 inbuf = cast(ubyte[]) fp.read( csiz<65536 ? csiz : 65536 ); 381 382 csiz -= inbuf.length; 382 - zs.next_in = inbuf; 383 + zs.next_in = inbuf.ptr; 383 384 zs.avail_in = inbuf.length; 384 385 385 386 if( inbuf.length==0 ) 386 387 { 387 388 err = Z_STREAM_END; 388 389 csiz = 0; 389 390 break; ................................................................................ 391 392 } 392 393 } 393 394 394 395 int written = outbuf.length - zs.avail_out; 395 396 if( usiz < written ) written = usiz; 396 397 usiz -= written; 397 398 outf.write( outbuf[0..written] ); 398 - zs.next_out = outbuf; 399 + zs.next_out = outbuf.ptr; 399 400 zs.avail_out = outbuf.length; 400 401 401 402 // dlg 402 403 if( BgaAnswer.Abort==ph(init_usiz-usiz,usiz) ) return false; 403 404 } 404 405 405 406 // 出力残しを無くす。 ................................................................................ 409 410 if( err!=Z_STREAM_END && err!=Z_OK ) 410 411 break; 411 412 412 413 int written = outbuf.length - zs.avail_out; 413 414 if( usiz < written ) written = usiz; 414 415 usiz -= written; 415 416 outf.write( outbuf[0..written] ); 416 - zs.next_out = outbuf; 417 + zs.next_out = outbuf.ptr; 417 418 zs.avail_out = outbuf.length; 418 419 419 420 // dlg 420 421 if( BgaAnswer.Abort==ph(init_usiz-usiz,usiz) ) return false; 421 422 } 422 423 423 424 // 終了 ................................................................................ 430 431 431 432 private bool BzDec( uint usiz, Filep outf, ProgressHandler ph ) 432 433 { 433 434 uint init_usiz = usiz; 434 435 435 436 // libbz2で展開 436 437 int err; 437 - BZFILE* b = BZ2_bzReadOpen( &err, fp.get_fp(), 0, 0, NULL, 0 ); 438 + BZFILE* b = BZ2_bzReadOpen( &err, fp.get_fp(), 0, 0, null, 0 ); 438 439 if( err!=BZ_OK || b is null ) 439 440 return true; 440 441 441 442 try 442 443 { 443 444 char[] buf; buf.length = BUFSIZ; 444 445 int len; 445 - while( 0<(len=BZ2_bzRead( &err, b, buf, BUFSIZ<usiz?BUFSIZ:usiz )) ) 446 + while( 0<(len=BZ2_bzRead( &err, b, buf.ptr, BUFSIZ<usiz?BUFSIZ:usiz )) ) 446 447 { 447 448 outf.write( buf[0..len] ); 448 449 usiz -= len; 449 450 if( err != BZ_OK ) 450 451 break; 451 452 452 453 // dlg