SHA1 Hash: | 5128eecc9f0e25ac9f741e09a2b3bee347e5c8b8 |
---|---|
Date: | 2011-02-23 13:30:53 |
User: | kinaba |
Comment: | Copied from private svn repository. |
Timelines: | family | ancestors | descendants | both | trunk |
Downloads: | Tarball | ZIP archive |
Other Links: | files | file ages | manifest |
- branch=trunk inherited from [dfc8d66a93]
- sym-trunk inherited from [dfc8d66a93]
Added CabTool.cpp version [f2120072ecb51fca]
1 + 2 +#include "stdafx.h" 3 +#include "CabTool.h" 4 +#include "kiutil.h" 5 +#include "fdi/fdi.h" 6 +#include "kilib/kilib.h" 7 + 8 +// 無理矢理SFXも解凍 9 +static int seeker=0; 10 +static int offhan=-1; 11 +static int offhan2=-1; 12 +static const char* sdll; 13 +static kiPath* sdllr; 14 + 15 +// CallBack 定義 16 +static FNALLOC(mymalloc) 17 +{ 18 + return (void*)new BYTE[cb]; 19 +} 20 +static FNFREE(mymfree) 21 +{ 22 + delete [] (BYTE*)pv; 23 +} 24 +static FNOPEN(myfopen) 25 +{ 26 + int han=_open( pszFile, oflag, pmode ); 27 + if( han!=-1 && seeker!=0 && !(oflag&_O_WRONLY) ) 28 + { 29 + _lseek( han,seeker,SEEK_SET ); 30 + if( offhan==-1 )offhan=han; 31 + else if( offhan2==-1 )offhan2=han; 32 + } 33 + return han; 34 +} 35 +static FNREAD(myfread) 36 +{ 37 + return _read( hf, pv, cb ); 38 +} 39 +static FNWRITE(myfwrite) 40 +{ 41 + return _write( hf, pv, cb ); 42 +} 43 +static FNCLOSE(myfclose) 44 +{ 45 + if( hf==offhan )offhan=-1; 46 + else if( hf==offhan2 )offhan2=-1; 47 + return _close(hf); 48 +} 49 +static FNSEEK(myfseek) 50 +{ 51 + if( hf==offhan || hf==offhan2 ) 52 + { 53 + if( seektype==SEEK_SET ) 54 + return _lseek( hf, dist+seeker, SEEK_SET ) - seeker; 55 + return _lseek( hf, dist, seektype ) - seeker; 56 + } 57 + return _lseek( hf, dist, seektype ); 58 +} 59 +static FNFDINOTIFY(mynotif) 60 +{ 61 + switch( fdint ) 62 + { 63 + case fdintCOPY_FILE: 64 + { 65 + char* name = kiutil::pathMake(pfdin->psz1); 66 + if( 0==strcmpi( kiPath::name(name), sdll ) ) // DLLの位置を記憶 67 + *sdllr = name; 68 + 69 + return myfopen( name, 70 + _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY|_O_SEQUENTIAL, 71 + _S_IREAD|_S_IWRITE ); 72 + } 73 + 74 + case fdintCLOSE_FILE_INFO: 75 + myfclose( pfdin->hf ); 76 + kiutil::timeSet( pfdin->psz1, pfdin->date, pfdin->time ); 77 + SetFileAttributes( pfdin->psz1, 78 + pfdin->attribs&(_A_RDONLY| _A_HIDDEN|_A_SYSTEM|_A_ARCH) ); 79 + return TRUE; 80 + } 81 + return 0; 82 +} 83 + 84 +int CCabTool::FindHeader( const char* fname, const BYTE* hdr, DWORD siz ) 85 +{ 86 + // FDI初期化 87 + FDICABINETINFO info; 88 + ERF erf; 89 + HFDI fdi=FDICreate( mymalloc,mymfree,myfopen,myfread, 90 + myfwrite,myfclose,myfseek,cpuUNKNOWN,&erf ); 91 + if( fdi==NULL ) 92 + return false; 93 + 94 + // 開く 95 + int ans=-1, han=myfopen( const_cast<char*>(fname), 96 + _O_BINARY|_O_RDONLY|_O_SEQUENTIAL,0 ); 97 + 98 + // ヘッダ検索 99 + if( -1!=han ) 100 + { 101 + if( siz>10 && hdr[0]=='M' && hdr[1]=='Z' ) 102 + { 103 + for( DWORD i=2; i<siz; i++ ) 104 + if( hdr[i+0]=='M' && hdr[i+1]=='S' && hdr[i+2]=='C' && 105 + hdr[i+3]=='F' && hdr[i+4]== 0 && hdr[i+5]== 0 && 106 + hdr[i+6]== 0 && hdr[i+7]==0 ) 107 + { 108 + myfseek( han,i,SEEK_SET ); 109 + if( FDIIsCabinet(fdi,han,&info) ) 110 + { 111 + ans=i; 112 + break; 113 + } 114 + } 115 + } 116 + else 117 + { 118 + if( FDIIsCabinet( fdi,han,&info ) ) 119 + ans = 0; 120 + } 121 + myfclose(han); 122 + } 123 + 124 + FDIDestroy( fdi ); 125 + return ans; 126 +} 127 + 128 +bool CCabTool::Extract( const char* aname, const char* dll, kiPath& dll_rel_path ) 129 +{ 130 + sdll = dll, sdllr = &dll_rel_path; 131 + 132 + // ヘッダを探す 133 + FILE* fp = fopen( aname,"rb" ); 134 + if( !fp ) 135 + return false; 136 + unsigned char* buff = new unsigned char[128<<10]; 137 + DWORD siz = fread( buff, 1, 128<<10, fp ); 138 + fclose( fp ); 139 + 140 + seeker = 0; 141 + seeker = FindHeader( aname,buff,siz ); 142 + delete [] buff; 143 + if( seeker==-1 ) 144 + return false; 145 + 146 + // FDI初期化 147 + ERF erf; 148 + HFDI fdi=FDICreate( mymalloc,mymfree,myfopen,myfread, 149 + myfwrite,myfclose,myfseek,cpuUNKNOWN,&erf ); 150 + if( fdi==NULL ) 151 + return false; 152 + 153 + // FDIに渡すためにファイル名分割 154 + int y,d; 155 + kiutil::pathSplit( aname,&y,&d ); 156 + 157 + char fbody[MAX_PATH], fdir[MAX_PATH]={0}; 158 + strcpy( fbody,&aname[y+1] ); 159 + if( y!=-1 ) 160 + strncpy( fdir,aname,y+1 ); 161 + 162 + // 展開 163 + BOOL ans=FDICopy( fdi,fbody,fdir,0,mynotif,NULL,NULL ); 164 + 165 + // 終了 166 + FDIDestroy(fdi); 167 + return ans!=FALSE; 168 +}
Added CabTool.h version [bd466b1efae9792f]
1 +#ifndef AFX_CABTOOL_H__7CA00740_39A0_11D4_8D96_871A6CA2BE31__INCLUDED_ 2 +#define AFX_CABTOOL_H__7CA00740_39A0_11D4_8D96_871A6CA2BE31__INCLUDED_ 3 + 4 +// Cab Archive Extraction ... ( XacRett #39 SubSet ) 5 + 6 +class CCabTool 7 +{ 8 +public: 9 + //-- 外向きインターフェイス -------------- 10 + bool Extract( const char* aname, const char* dll, kiPath& dll_rel_path ); 11 + 12 +private: 13 + //-- 内部処理 14 + int FindHeader( const char* fname, const BYTE* hdr, DWORD siz ); 15 +}; 16 + 17 +#endif
Added Caldix.cpp version [e18cd84486006455]
1 + 2 +#include "stdafx.h" 3 +#include "resource.h" 4 + 5 + 6 + 7 +//---------------------------------------------------------------------------- 8 +// ユーティリティー 9 +//---------------------------------------------------------------------------- 10 + 11 +#ifndef ListView_SetCheckState 12 +#define ListView_SetCheckState(_hwndLV, _i, _fCheck) \ 13 + ListView_SetItemState(_hwndLV, _i, \ 14 + INDEXTOSTATEIMAGEMASK((_fCheck)+1), LVIS_STATEIMAGEMASK) 15 +#endif 16 + 17 + 18 +// 挿入caldixF 19 + 20 +// なんか長いし分り難いんで(w 21 +#define IsDblChar(x) IsDBCSLeadByte((BYTE)(x)) 22 + 23 +// 一番前=TRUE(後ろ=FALSE)の何か=cのインデックスを探して返す 24 +int GetcX(char *buf,char c,BOOL fl) 25 +{ 26 + int rt; 27 + int i,len; 28 + 29 + len = lstrlen(buf); 30 + rt = 0; 31 + for (i = 0;i < len;i++){ 32 + // 2バイト文字なら飛ばす 33 + if (IsDblChar(buf[i])){ 34 + i++; 35 + continue; 36 + } 37 + else{ 38 + if (buf[i] == c){ 39 + rt = i; 40 + // 最初の奴を探すのなら 41 + if (fl) 42 + return(rt); 43 + } 44 + } 45 + } 46 + // 最後まで無かった 47 + if (!rt && (i == len)) 48 + rt = len; 49 + 50 + return(rt); 51 +} 52 + 53 +// ファイル名取得 54 +char *GetFileName(char *buf) 55 +{ 56 + int ly; 57 + 58 + // 最後の¥ 59 + ly = GetcX(buf,'\\',FALSE); 60 + 61 + // そのまま返す 62 + if (ly == lstrlen(buf)) 63 + return(buf); 64 + 65 + // \の次のポインタを返す 66 + return(&buf[ly+1]); 67 +} 68 +// 挿入ここまでcaldixF 69 + 70 +static void move_later( const char* from, const char* to ) 71 +{ 72 + // 移動先と同じディレクトリへ動かしておく 73 + kiPath tmp( to ); 74 + ::CopyFile( from, tmp+=".tmp", FALSE ); 75 + ::DeleteFile( from ); 76 + 77 + // NT系ならMoveFileExが成功するはず 78 + if( ::MoveFileEx( tmp, to, MOVEFILE_REPLACE_EXISTING|MOVEFILE_DELAY_UNTIL_REBOOT ) ) 79 + return; 80 + 81 + // 9x系ならWININIT.INIをいじる 82 + char inifile[MAX_PATH]; 83 + ::GetWindowsDirectory( inifile, sizeof(inifile) ); 84 + ::lstrcat( inifile, "\\WININIT.INI" ); 85 + 86 + // ショート名前に変換 87 + char sfrom[MAX_PATH], sto[MAX_PATH]; 88 + ::GetShortPathName( tmp, sfrom, MAX_PATH ); 89 + ::GetShortPathName( to, sto, MAX_PATH ); 90 + 91 + // Renameセクションに追加 92 + static char buf[30000]; 93 + ::GetPrivateProfileSection( "Rename", buf, 30000, inifile ); 94 + char* p = buf; 95 + while(*p)while(*p++); 96 + ::lstrcpy( p, "NUL=" ); 97 + ::lstrcat( p, sto ); 98 + ::lstrcat( p, "\r\n" ); 99 + ::lstrcat( p, sto ); 100 + ::lstrcat( p, "=" ); 101 + ::lstrcat( p, sfrom ); 102 + while(*p++); 103 + *p='\0'; 104 + 105 + // 2発打って確実に書き込む 106 + ::WritePrivateProfileSection( "Rename", buf, inifile ); 107 + ::WritePrivateProfileString( NULL, NULL, NULL, inifile ); 108 +} 109 + 110 +static void rebootWindows() 111 +{ 112 + if( app()->osver().dwPlatformId == VER_PLATFORM_WIN32_NT ) 113 + { 114 + // NT系では特権を取得しなくてはいけない 115 + HANDLE hToken; 116 + TOKEN_PRIVILEGES tkp; 117 + ::OpenProcessToken( ::GetCurrentProcess(), 118 + TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken ); 119 + ::LookupPrivilegeValue( 120 + NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid ); 121 + tkp.PrivilegeCount = 1; 122 + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 123 + ::AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, NULL, 0 ); 124 + } 125 + ::ExitWindowsEx( EWX_REBOOT, 0 ); 126 +} 127 + 128 +static bool cancelShiteIidesuka() 129 +{ 130 + return IDYES == app()->msgBox( kiStr().loadRsrc( IDS_CANCELOK ), 131 + "caldix", MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 ); 132 +} 133 + 134 +template <class T> static inline bool show( const T& dlg ) 135 +{ 136 + (const_cast<T&>(dlg)).doModal(); 137 + return IDOK == (const_cast<T&>(dlg)).getEndCode(); 138 +} 139 + 140 + 141 + 142 +//---------------------------------------------------------------------------- 143 +// 解凍関係 144 +//---------------------------------------------------------------------------- 145 + 146 +#include "kiutil.h" 147 +#include "LzhTool.h" 148 +#include "CabTool.h" 149 +#include "ZipTool.h" 150 +#define is_lzh(xx) (xx[2]=='-' && xx[3]=='l' && xx[4]=='h' && xx[6]=='-' && '0'<=xx[5] && xx[5]<='9') 151 +#define is_zip(xx) (xx[2]=='P' && xx[3]=='K' && xx[4]==0x3 && xx[6]==0x4) 152 +#define is_cab(xx) (xx[0]=='M' && xx[1]=='S' && xx[2]=='C' && xx[3]=='F') 153 + 154 +enum arctype{ e_lzh, e_zip, e_cab, unknown }; 155 + 156 +static arctype get_archive_type( const char* arcname ) 157 +{ 158 + // 手抜き判別 159 + arctype ans = unknown; 160 + kiFile fp; 161 + if( fp.open(arcname) ) 162 + { 163 + unsigned long asize = 128 << 10; 164 + unsigned char *buf = new unsigned char[asize]; 165 + unsigned char *p=buf, *end=buf+fp.read( buf, asize-6 ); 166 + 167 + while( p!=end ) 168 + { 169 + if( is_lzh(p) ) { ans=e_lzh; break; } 170 + else if( is_zip(p) ) { ans=e_zip; break; } 171 + else if( is_cab(p) ) { ans=e_cab; break; } 172 + p++; 173 + } 174 + 175 + delete [] buf; 176 + } 177 + return ans; 178 +} 179 + 180 +static void melt_it( const char* arcname, const char* dllname, kiPath& dll_rel_path ) 181 +{ 182 + const char* ext = kiPath::ext( arcname ); 183 + arctype type = unknown; 184 + 185 + // 判別 186 + if( 0==stricmp( ext, "lzh" ) ) type = e_lzh; 187 + else if( 0==stricmp( ext, "zip" ) ) type = e_zip; 188 + else if( 0==stricmp( ext, "cab" ) ) type = e_cab; 189 + else type = get_archive_type(arcname); 190 + 191 + // 展開 192 + switch( type ) 193 + { 194 + case e_lzh:{ CLzhTool().Extract( arcname, dllname, dll_rel_path ); }break; 195 + case e_zip:{ CZipTool().Extract( arcname, dllname, dll_rel_path ); }break; 196 + case e_cab:{ CCabTool().Extract( arcname, dllname, dll_rel_path ); }break; 197 + } 198 +} 199 + 200 + 201 + 202 +//---------------------------------------------------------------------------- 203 +// DLL情報管理:Meta-WWWC-Contentの解析など 204 +//---------------------------------------------------------------------------- 205 + 206 +class DLLInfo 207 +{ 208 +public: 209 + 210 + DLLInfo( const char* _name, const char* _html, int _wwwc ) 211 + : name( _name ), html( _html ), wwwc( _wwwc ), size( 0 ) {} 212 + 213 + bool ParseHTML( char* str ); 214 + const kiStr& htmlName() const { return html; } 215 + bool needToUpdate( kiPath& dlldir ); 216 + const kiStr& getName() const { return name; } 217 + const kiStr& getState() const { return stat; } 218 + const int getSize() const { return size; } 219 + const kiStr& getArchiveName() const { return arch; } 220 + 221 +private: 222 + 223 + char* Get_WWWC_Content( char* str ); 224 + bool ParseWWWC( char* str ); 225 + bool CheckDateTime( const char* localDLL ); 226 + bool VersionCheckLogic( 227 + const kiStr& dllName, const kiStr& htmlVer, int Ver, int subVer ); 228 + 229 +private: 230 + 231 + // 固定情報 232 + const kiStr name; // DLLの名前 233 + const kiStr html; // チェック先HTMLの名前 234 + const int wwwc; // 何番目のWWWCタグを利用するか 235 + 236 +private: 237 + 238 + // HTMLから取得する情報 239 + kiStr arch; // 書庫名 240 + kiStr vers; // バージョン 241 + kiStr dttm; // 日付&時刻 242 + int size; // サイズ 243 + 244 + // バージョン照合の結果 245 + kiStr stat; // 更新状況 246 +}; 247 + 248 +char* DLLInfo::Get_WWWC_Content( char* x ) 249 +{ 250 + // もーれつに雑。 251 + while( *x==' ' || *x=='\t' || *x=='\r' || *x=='\n' ) x++; 252 + if( (x[0]=='m' || x[0]=='M') 253 + && (x[1]=='e' || x[1]=='E') 254 + && (x[2]=='t' || x[2]=='T') 255 + && (x[3]=='a' || x[3]=='A') ) 256 + { 257 + x+=4; 258 + while( *x==' ' || *x=='\t' || *x=='\r' || *x=='\n' ) x++; 259 + if( (x[0]=='n' || x[0]=='N') 260 + && (x[1]=='a' || x[1]=='A') 261 + && (x[2]=='m' || x[2]=='M') 262 + && (x[3]=='e' || x[3]=='E') 263 + && (x[4]=='=') 264 + && (x[5]=='"') 265 + && (x[6]=='w' || x[6]=='W') 266 + && (x[7]=='w' || x[7]=='W') 267 + && (x[8]=='w' || x[8]=='W') 268 + && (x[9]=='c' || x[9]=='C') 269 + && (x[10]=='"') ) 270 + { 271 + x+=11; 272 + while( *x==' ' || *x=='\t' || *x=='\r' || *x=='\n' ) x++; 273 + if( (x[0]=='c' || x[0]=='C') 274 + && (x[1]=='o' || x[1]=='O') 275 + && (x[2]=='n' || x[2]=='N') 276 + && (x[3]=='t' || x[3]=='T') 277 + && (x[4]=='e' || x[4]=='E') 278 + && (x[5]=='n' || x[5]=='N') 279 + && (x[6]=='t' || x[6]=='T') 280 + && (x[7]=='=') 281 + && (x[8]=='"') ) 282 + { 283 + x+=9; 284 + char* p=x; 285 + while( *p!='\0' && *p!='"' ) p++; 286 + *p='\0'; 287 + return x; 288 + } 289 + } 290 + } 291 + return NULL; 292 +} 293 + 294 +bool DLLInfo::ParseHTML( char* str ) 295 +{ 296 + int ct = wwwc; 297 + for( char* p=str; *p; ++p ) 298 + if( *p == '<' ) 299 + { 300 + for( char* x=p+1; *x; ++x ) 301 + if( *x == '>' ) 302 + break; 303 + *x = '\0'; 304 + 305 + char* w = Get_WWWC_Content( p+1 ); 306 + if( w && (--ct)==0 ) 307 + return ParseWWWC( w ); 308 + 309 + p = x; 310 + } 311 + return false; 312 +} 313 + 314 +bool DLLInfo::ParseWWWC( char* str ) 315 +{ 316 + char *x,*k,*t,*p=str; 317 + 318 + // 2個目のスペースまでが更新日時 319 + for( int spc=2; *p; ++p ) 320 + if( *p==' ' ) 321 + if( (--spc)==0 ) 322 + break; 323 + if( *p=='\0' ) 324 + return false; 325 + *(p++) = '\0'; 326 + dttm = str; 327 + 328 + // [xxx: ---] 部分 329 + while( true ) 330 + { 331 + while( *p!='\0' && *p!='[' ) ++p; 332 + if( *p!='\0' ) ++p; 333 + if( *p=='\0' )break; 334 + 335 + t=x=k=p; 336 + while( *x!='\0' && *x!=']' ) x++; 337 + while( *k!='\0' && *k!=':' ) k++; 338 + if( *x=='\0' || *k=='\0' || k>=x )break; 339 + *k=*x='\0'; 340 + p=k+1; 341 + 342 + if( 0==lstrcmpi( t, "File" ) ) 343 + arch = p; 344 + else if( 0==lstrcmpi( t, "Ver" ) ) 345 + { 346 + while( *p && (*p<'0' || '9'<*p) ) 347 + ++p; 348 + vers = p; 349 + } 350 + else if( 0==lstrcmpi( t, "Size" ) ) 351 + { 352 + // atoi 353 + for( int n=0; *p; p++ ) 354 + if( '0'<=*p && *p<='9' ) 355 + n = (10*n) + (*p - '0'); 356 + size = n; 357 + } 358 + p=x+1; 359 + } 360 + 361 + return ( size!=0 && arch.len()!=0 ); 362 +} 363 + 364 +//---------------------------------------------------------------------------- 365 +// caldixの設定項目管理 366 +//---------------------------------------------------------------------------- 367 + 368 +enum { 369 + UNLHA, UNZIP, ZIP, CAB, TAR, UNRAR, UNGCA, 370 + UNARJ, YZ1, BGA, JACK, AISH, ISH, UNBEL, SvZIP, 371 + UNIMP, BH, YZ2, 372 +DLLID_NUM }; 373 + 374 +struct CldxConfig 375 +{ 376 + kiStr UA; // ユーザーエージェント名 377 + 378 + bool SuperAutoMode; // (利用しない) 379 + bool AutoMode; // 全自動ならtrue, カスタムならfalse 380 + 381 + kiPath InstallTo; // インストール先 382 + int CheckServer; // 更新チェックに使うサーバ 窓辺=0, CSD=1, 惑星=2 383 + 384 + int ProxyPort; // プロキシのポート番号 385 + kiStr ProxyServer; // プロキシサーバ名 386 + kiStr ProxyUser; // プロキシユーザ名(利用しない) 387 + kiStr ProxyPwd; // プロキシパスワード(利用しない) 388 + 389 + bool George; // 常時接続モードならtrue, 汎用モードならfalse 390 + bool UseCustomDir; // 全自動でも、カスタムと同じディレクトリを用いる 391 + bool ShowReadMe; // 最後にcldxフォルダを開くか否か 392 + 393 +// 挿入caldixF 394 + kiStr Filer; // フォルダを開くファイラー 395 + kiStr F_Prefix; // ファイラに渡すオプション前 396 + kiStr F_Suffix; // ファイラに渡すオプション後ろ 397 + 398 +// 挿入ここまでcaldixF 399 + 400 + bool DoCheck[DLLID_NUM]; // 各DLLをチェック対象にするかどうか 401 + int InstMode; // ダウンロードしたDLLの扱い 402 + int Expire; // 日時チェックで更新対象とする範囲(単位:Day) 403 + 404 + kiArray<DLLInfo*> List; // チェック対象DLLのリスト 405 + 406 + CldxConfig() 407 + : UA( "caldix/1.21" ) 408 + , SuperAutoMode( false ) 409 + , AutoMode( true ) 410 + , InstallTo( kiPath::Sys ) 411 + { 412 + kiIniFile ini; 413 + ini.setFileName( "caldix.ini" ); 414 + ini.setSection( "conf" ); 415 + 416 + InstallTo = ini.getStr ( "dll", InstallTo ); 417 + CheckServer = ini.getInt ( "checkserv", 0 ) % 3; 418 + ProxyServer = ini.getStr ( "proxy", "" ); 419 + ProxyPort = ini.getInt ( "proxyport", -80 ); 420 + George =!ini.getBool( "askhang", false ); // [1.21] デフォルトを false に変更。流石に今時… 421 + UseCustomDir = ini.getBool( "custdir", false ); 422 + ShowReadMe = ini.getBool( "readme", true ); 423 + InstMode = ini.getInt ( "mode", 1 ); 424 + Expire = ini.getInt ( "expire", 7 ); 425 + int version = ini.getInt ( "ver", 110 ); 426 + 427 +// 挿入caldixF 428 + Filer = ini.getStr ( "Filer","explorer"); 429 + F_Prefix = ini.getStr ( "F_Prefix",""); 430 + F_Suffix = ini.getStr ( "F_Suffix",""); 431 + if( Filer=="" || Filer.isSame("explorer") ) 432 + Filer = kiPath(kiPath::Win,true), Filer += "explorer.exe"; 433 +// 挿入ここまでcaldixF 434 + 435 + for( int i=0; i<DLLID_NUM; ++i ) 436 + DoCheck[i] = false; 437 + const char* ptr = ini.getStr( "DLLList", "LZzCTRGAYBJaIb7iH" ); 438 + while( *ptr ) 439 + switch( 0x7f & (*(ptr++)) ) 440 + { 441 + case 'L': DoCheck[UNLHA] = true; break; 442 + case 'Z': DoCheck[UNZIP] = true; break; 443 + case 'z': DoCheck[ZIP] = true; break; 444 + case 'C': DoCheck[CAB] = true; break; 445 + case 'T': DoCheck[TAR] = true; break; 446 + case 'R': DoCheck[UNRAR] = true; break; 447 + case 'G': DoCheck[UNGCA] = true; break; 448 + case 'A': DoCheck[UNARJ] = true; break; 449 + case 'Y': DoCheck[YZ1] = true; break; 450 + case 'B': DoCheck[BGA] = true; break; 451 + case 'J': DoCheck[JACK] = true; break; 452 + case 'a': DoCheck[AISH] = true; break; 453 + case 'I': DoCheck[ISH] = true; break; 454 + case 'b': DoCheck[UNBEL] = true; break; 455 + case '7': DoCheck[SvZIP] = true; break; 456 + case 'i': DoCheck[UNIMP] = true; break; 457 + case 'H': DoCheck[BH] = true; break; 458 + case '2': DoCheck[YZ2] = true; break; 459 + } 460 + if( version<111 ) 461 + DoCheck[SvZIP] = true; // ver1.11より前には7-zip32.dllは 462 + // 存在しなかったのでここで強制ON 463 + if( version<112 ) 464 + DoCheck[UNIMP] = true; // ver1.12より前にはUnImp32.dllは 465 + // 存在しなかったのでここで強制ON 466 + if( version<118 ) 467 + DoCheck[BH] = true; // ver1.18より前にはBh32.dllは 468 + // 存在しなかったのでここで強制ON 469 + if( version<120 ) 470 + DoCheck[YZ2] = true; // ver1.20より前にはYz2.dllは 471 + // 存在しなかったのでここで強制ON 472 + } 473 + 474 + void GenerateDLLList() 475 + { 476 + if( DoCheck[UNLHA] ) 477 + List.add( new DLLInfo( "Unlha32.dll", "unlha32.html", 1 ) ); 478 + if( DoCheck[UNZIP] ) 479 + List.add( new DLLInfo( "UnZip32.dll", "unzip32.html", 1 ) ); 480 + if( DoCheck[ZIP] ) 481 + List.add( new DLLInfo( "Zip32j.dll", "zip32j.html", 1 ) ), 482 + List.add( new DLLInfo( "Zip32.dll", "zip32j.html", 2 ) ), 483 + List.add( new DLLInfo( "Sfx32gui.dat", "sfx32gui.html", 1 ) ); 484 + if( DoCheck[CAB] ) 485 + List.add( new DLLInfo( "Cab32.dll", "cab32.html", 1 ) ); 486 + if( DoCheck[TAR] ) 487 + List.add( new DLLInfo( "Tar32.dll", "tar32.html", 1 ) ); 488 + if( DoCheck[UNRAR] ) 489 + List.add( new DLLInfo( "Unrar32.dll", "unrar32.html", 1 ) ); 490 + if( DoCheck[UNGCA] ) 491 + List.add( new DLLInfo( "UnGCA32.dll", "ungca32.html", 1 ) ); 492 + if( DoCheck[UNARJ] ) 493 + List.add( new DLLInfo( "Unarj32j.dll", "unarj32.html", 1 ) ); 494 + if( DoCheck[YZ1] ) 495 + List.add( new DLLInfo( "Yz1.dll", "yz1.html", 1 ) ); 496 + if( DoCheck[BGA] ) 497 + List.add( new DLLInfo( "Bga32.dll", "bga32.html", 1 ) ); 498 + if( DoCheck[JACK] ) 499 + List.add( new DLLInfo( "Jack32.dll", "jack32.html", 1 ) ); 500 + if( DoCheck[AISH] ) 501 + List.add( new DLLInfo( "Aish32.dll", "aish32.html", 1 ) ); 502 + if( DoCheck[ISH] ) 503 + List.add( new DLLInfo( "Ish32.dll", "ish32.html", 1 ) ); 504 + if( DoCheck[UNBEL] ) 505 + List.add( new DLLInfo( "Unbel32.dll", "unbel32.html", 1 ) ); 506 + if( DoCheck[SvZIP] ) 507 + List.add( new DLLInfo( "7-zip32.dll", "7-zip32.html", 1 ) ); 508 + if( DoCheck[UNIMP] ) 509 + List.add( new DLLInfo( "UnImp32.dll", "unimp32.html", 1 ) ); 510 + if( DoCheck[BH] ) 511 + List.add( new DLLInfo( "Bh32.dll", "bh32.html", 1 ) ); 512 + if( DoCheck[YZ2] ) 513 + List.add( new DLLInfo( "Yz2.dll", "yz2.html", 1 ) ); 514 + } 515 + 516 + ~CldxConfig() 517 + { 518 + if( !AutoMode ) 519 + { 520 + kiIniFile ini; 521 + ini.setFileName( "caldix.ini" ); 522 + ini.setSection( "conf" ); 523 + 524 + ini.putStr ( "dll", InstallTo ); 525 + ini.putInt ( "checkserv", CheckServer ); 526 + ini.putStr ( "proxy", ProxyServer ); 527 + ini.putInt ( "proxyport", ProxyPort ); 528 + ini.putBool( "askhang", !George ); 529 + ini.putBool( "custdir", UseCustomDir ); 530 + ini.putBool( "readme", ShowReadMe ); 531 + ini.putInt ( "mode", InstMode ); 532 + ini.putInt ( "expire", Expire ); 533 + ini.putInt ( "ver", 121 ); 534 +// 挿入caldixF 535 + ini.putStr ( "Filer", Filer ); 536 + ini.putStr ( "F_Prefix", F_Prefix ); 537 + ini.putStr ( "F_Suffix", F_Suffix ); 538 +// 挿入ここまでcaldixF 539 + 540 + kiStr chk; 541 + for( int i=0; i<DLLID_NUM; ++i ) 542 + if( DoCheck[i] ) 543 + chk += "LZzCTRGAYBJaIb7iH2"[i]; 544 + ini.putStr( "DLLList", chk ); 545 + } 546 + 547 + for( unsigned int i=0; i<List.len(); ++i ) 548 + delete List[i]; 549 + } 550 +}; 551 + 552 +CldxConfig* cfg = NULL; 553 + 554 + 555 + 556 +//---------------------------------------------------------------------------- 557 +// DLLのバージョンチェック 558 +//---------------------------------------------------------------------------- 559 + 560 +struct _zip_version_type 561 +{ 562 + unsigned char major; 563 + unsigned char minor; 564 + unsigned char patchlevel; 565 + unsigned char not_used; 566 +}; 567 + 568 +struct ZpVer 569 +{ 570 + unsigned long structlen; 571 + unsigned long flag; 572 + char betalevel[10]; 573 + char date[20]; 574 + char zlib_version[10]; 575 + _zip_version_type zip; 576 + _zip_version_type os2dll; 577 + _zip_version_type windll; 578 +}; 579 + 580 +static WORD Zip32DLLGetVersion( const char* dll ) 581 +{ 582 + WORD ans=0; 583 + HINSTANCE inst = kiutil::safepathLoadLibrary( dll ); // dll はフルパスなので要らないはずだけど念のため 584 + if( inst ) 585 + { 586 + typedef int (WINAPI * ZPVR)(ZpVer*); 587 + ZPVR v = (ZPVR)::GetProcAddress( inst, "ZpVersion" ); 588 + if( v ) 589 + { 590 + ZpVer x; 591 + v( &x ); 592 + ans = x.zip.major*100 + x.zip.minor*10 + x.zip.patchlevel; 593 + } 594 + ::FreeLibrary( inst ); 595 + } 596 + return ans; 597 +} 598 + 599 +bool DLLInfo::CheckDateTime( const char* localDLL ) 600 +{ 601 + // ローカルのDLLの日付を取得 602 + FILETIME ft; 603 + SYSTEMTIME StLocal; 604 + HANDLE h = ::CreateFile( 605 + localDLL, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 606 + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL ); 607 + if( h == INVALID_HANDLE_VALUE ) 608 + return true; 609 + ::GetFileTime( h, NULL, NULL, &ft ); 610 + ::FileTimeToSystemTime( &ft, &StLocal ); 611 + ::CloseHandle( h ); 612 + 613 + // Webの方のの日付を取得 614 + const char* p = dttm; 615 + SYSTEMTIME StWeb = StLocal; 616 + for( StWeb.wYear=0; *p && *p!='/'; ++p ) 617 + StWeb.wYear = StWeb.wYear*10 + (*p-'0'); 618 + if(*p)++p; 619 + for( StWeb.wMonth=0; *p && *p!='/'; ++p ) 620 + StWeb.wMonth = StWeb.wMonth*10 + (*p-'0'); 621 + if(*p)++p; 622 + for( StWeb.wDay=0; *p && *p!=' '; ++p ) 623 + StWeb.wDay = StWeb.wDay*10 + (*p-'0'); 624 + 625 + // Webの方が1週間以上新しければ更新とかそんな感じ 626 + 627 + if( (StLocal.wYear> StWeb.wYear) 628 + || (StLocal.wYear==StWeb.wYear && StLocal.wMonth>StWeb.wMonth) 629 + || (StLocal.wYear==StWeb.wYear && StLocal.wMonth==StWeb.wMonth && StLocal.wDay>=StWeb.wDay) ) 630 + return false; // ローカルの方が新しいので更新しない 631 + 632 + if( StLocal.wYear+2 < StWeb.wYear ) 633 + return true; // 確実に1年以上新しいので更新 634 + if( StLocal.wYear+1 == StWeb.wYear ) 635 + StWeb.wMonth += 12; 636 + 637 + // cfg->Expire 日以上新しければ更新 638 + StWeb.wDay += 30 * (StWeb.wMonth - StLocal.wMonth); 639 + return ( StLocal.wDay+cfg->Expire < StWeb.wDay ); 640 +} 641 + 642 +//------------------------------------------------------------------------------- 643 +// バージョンチェック for caldix/1.15 or older + caldixF fix 644 +//------------------------------------------------------------------------------- 645 +/* 646 +bool DLLInfo::VersionCheckLogic( 647 + const kiStr& dllName, 648 + const kiStr& htmlVer, 649 + int ver, int sub ) 650 +{ 651 + // 文字列に変換 652 + char verstr[100]; 653 + if( dllName=="Unimp32.dll" ) 654 + if( sub==0 ) 655 + ::wsprintf( verstr, "%d.%02d", ver/100, ver%100 ); 656 + else if( sub >= 100 ) 657 + ::wsprintf( verstr, "%d.%02d%c", ver/100, ver%100, sub/100+'a'-1 ); 658 + else 659 + ::wsprintf( verstr, "%d.%02d%c", ver/100, ver%100, sub+'a'-1 ); 660 + else if( dllName=="7-zip32.dll" ) // 7-zipだけは無条件でSubVersionも数値で入れる 661 + ::wsprintf( verstr, "%d.%02d.%02d.%02d", ver/100, ver%100, sub/100,sub%100 ); 662 + else if( sub < 100 ) 663 + ::wsprintf( verstr, "%d.%02d", ver/100, ver%100 ); 664 + else 665 + ::wsprintf( verstr, "%d.%02d%c", ver/100, ver%100, sub/100+'a'-1 ); 666 + 667 + // 比較(htmlVerの方がVer.subVerより新しければtrue) 668 + return 669 + (CSTR_GREATER_THAN == ::CompareString(LOCALE_USER_DEFAULT,SORT_STRINGSORT,vers,-1,verstr,-1)); 670 +} 671 +*/ 672 +//------------------------------------------------------------------------------- 673 +// バージョンチェック for caldix/1.17 or newer 674 +//------------------------------------------------------------------------------- 675 + 676 +const char* find_first_non_digit( const char* p ) 677 +{ 678 + while( '0'<=*p && *p<='9' ) ++p; 679 + return p; 680 +} 681 + 682 +bool DLLInfo::VersionCheckLogic( 683 + const kiStr& dllName, // DLL名 684 + const kiStr& htmVerStr, // HTML上のバージョン文字列 685 + int locVer, int locSub ) // ローカルDLLのバージョン 686 +{ 687 + const char* vs = htmVerStr; 688 + if( dllName == "Unimp32.dll" && locSub<100 ) 689 + locSub *= 100; 690 + 691 + // バージョン文字列を解析。以下の4つの形式を認識する 692 + //("%d.%d.%d.%d", ver/100, ver%100, sub/100, sub%100) 693 + //("%d.%d", ver/100, ver%100) && sub<100 694 + //("%d.%d%c", ver/100, ver%100, sub/100+'a'-1) 695 + //("%d.%d.%d", ver/100, ver%100, sub) 696 + 697 + int htmVer=0, htmSub=0; 698 + { 699 + // [%d][.] 700 + const int d1 = atoi(vs); 701 + vs = find_first_non_digit(vs); 702 + if( *vs!='.' ) return false; ++vs; 703 + // [%d] 704 + const int d2 = atoi(vs); 705 + const char* vs2 = find_first_non_digit(vs); 706 + if( vs2-vs==1 && dllName=="Zip32.dll" ) // adhoc対処 707 + htmVer = d1*100 + d2*10; 708 + else 709 + htmVer = d1*100 + d2; 710 + vs = vs2; 711 + if( *vs=='.' ) // [.] 712 + { 713 + ++vs; 714 + // [%d] 715 + const int d3 = atoi(vs); 716 + vs = find_first_non_digit(vs); 717 + if( *vs=='.' ) // [.] 718 + { 719 + ++vs; 720 + // [%d] 721 + const int d4 = atoi(vs); 722 + htmSub = d3*100 + d4; 723 + } 724 + else 725 + htmSub = d3; 726 + } 727 + else if( 'a'<=*vs && *vs<='z' ) // [a-z] 728 + htmSub = (*vs-'a'+1) * 100; 729 + else if( 'A'<=*vs && *vs<='Z' ) // [A-Z] 730 + htmSub = (*vs-'A'+1) * 100; 731 + } 732 + return (locVer < htmVer) || (locVer==htmVer && locSub<htmSub); 733 +} 734 + 735 +bool DLLInfo::needToUpdate( kiPath& dlldir ) 736 +{ 737 + // 情報取得できていなかった場合は更新しない 738 + if( vers.len() == 0 ) 739 + return false; 740 + 741 + // 対象DLLのフルパス 742 + kiPath dllPath( dlldir ); 743 + dllPath += name; 744 + 745 + // DLLが存在しなかった場合は新しくインストール 746 + if( !kiSUtil::exist( dllPath ) ) 747 + { 748 + stat.loadRsrc( IDS_NEWINST ); 749 + return true; 750 + } 751 + 752 + // 存在した場合… 753 + bool updatable = false; 754 + 755 + if( name=="Sfx32gui.dat" ) 756 + { 757 + // 特別処理1:Sfx32gui.datの場合は日付チェック 758 + updatable = CheckDateTime( dllPath ); 759 + } 760 + else 761 + { 762 + // それ以外は、バージョン番号でチェック 763 + WORD ver=1, sub=0; 764 + if( name == "Zip32.dll" ) 765 + { 766 + ver = Zip32DLLGetVersion( dllPath ); 767 + } 768 + else if( name != "Sfx32gui.dat" ) 769 + { 770 + kiArcDLLRaw dll( dllPath ); 771 + ver = dll.getVer(); 772 + sub = dll.getVerSub(); 773 + if( name=="Unimp32.dll" && !dll.isVerSubAvail() ) 774 + ver=6, sub=0; // 特殊処理2:古いunimpは0.0.6.0として扱う 775 + } 776 + 777 + // バージョンチェックをここで実行 778 + updatable = VersionCheckLogic( name, vers, ver, sub ); 779 + 780 + // 特殊処理3:Unrar32.dllで、違いがSubVersionだけのときは日付チェック 781 + if( updatable && name=="Unrar32.dll" ) 782 + { 783 + char verstr[100]; 784 + ::wsprintf( verstr, "%d.%02dz", ver/100, ver%100 ); 785 + if( CSTR_GREATER_THAN == ::CompareString(LOCALE_USER_DEFAULT,SORT_STRINGSORT,verstr,-1,vers,-1) ) 786 + updatable = CheckDateTime( kiPath(dlldir)+="Unrar.dll" ); 787 + } 788 + } 789 + 790 + // 更新可能 791 + if( updatable ) 792 + { 793 + char str[100]; 794 + ::wsprintf( str, stat.loadRsrc( IDS_UPDINST ), (const char*)vers ); 795 + stat = str; 796 + } 797 + return updatable; 798 +} 799 + 800 + 801 + 802 +//---------------------------------------------------------------------------- 803 +// startDlg : 自動|カスタムの選択 804 +//---------------------------------------------------------------------------- 805 + 806 +class startDlg : public kiDialog 807 +{ 808 +public: 809 + startDlg() : kiDialog( IDD_START ) {} 810 + 811 +private: 812 + virtual BOOL onInit() 813 + { 814 + // 二重起動禁止 815 + char cls[256], wnd[256]; 816 + ::GetClassName( hwnd(), cls, sizeof(cls)-1 ); 817 + ::GetWindowText( hwnd(), wnd, sizeof(wnd)-1 ); 818 + if( HWND h = ::FindWindow(cls,wnd) ) 819 + if( h!=hwnd() || (h=::FindWindowEx(NULL,h,cls,wnd)) ) 820 + { 821 + end( IDCANCEL ); 822 + setFront( h ); 823 + return FALSE; 824 + } 825 + 826 + app()->setMainWnd( this ); 827 + UINT md = (cfg->AutoMode ? IDC_WORKTYPE1 : IDC_WORKTYPE2); 828 + sendMsgToItem( md, BM_SETCHECK, BST_CHECKED ); 829 + return FALSE; 830 + } 831 + 832 + virtual bool onOK() 833 + { 834 + cfg->AutoMode = 835 + (BST_CHECKED == sendMsgToItem( IDC_WORKTYPE1, BM_GETCHECK )); 836 + return true; 837 + } 838 +}; 839 + 840 + 841 + 842 +//---------------------------------------------------------------------------- 843 +// customDlg : 接続先/インストール先の選択 プロキシ|詳細への分岐 844 +//---------------------------------------------------------------------------- 845 + 846 +class customDlg : public kiDialog 847 +{ 848 +public: 849 + customDlg() : kiDialog( IDD_CUSTOM1 ) {} 850 + 851 +private: 852 + virtual BOOL onInit() 853 + { 854 + app()->setMainWnd( this ); 855 + sendMsgToItem( IDC_DLLDIR, WM_SETTEXT, 0, (LPARAM)(const char*)(cfg->InstallTo) ); 856 + sendMsgToItem( IDC_CONNECTTO1+cfg->CheckServer, BM_SETCHECK, BST_CHECKED ); 857 + return FALSE; 858 + } 859 + 860 + virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) 861 + { 862 + if( msg==WM_COMMAND ) 863 + if( LOWORD(wp)==IDC_REF ) 864 + { 865 + kiSUtil::getFolderDlgOfEditBox( item(IDC_DLLDIR), hwnd(), NULL ); 866 + return TRUE; 867 + } 868 + else if( LOWORD(wp)==IDC_PROXY ) 869 + { 870 + show( proxyDlg() ); 871 + return TRUE; 872 + } 873 + else if( LOWORD(wp)==IDC_DETAIL ) 874 + { 875 + show( detailDlg() ); 876 + return TRUE; 877 + } 878 + return FALSE; 879 + } 880 + 881 + virtual bool onOK() 882 + { 883 + char str[MAX_PATH]; 884 + sendMsgToItem( IDC_DLLDIR, WM_GETTEXT, sizeof(str)-1, (LPARAM)str ); 885 + cfg->InstallTo=str, cfg->InstallTo.beBackSlash( true ); 886 + for(int i=0; i<=2; ++i) 887 + if( BST_CHECKED == sendMsgToItem( IDC_CONNECTTO1+i, BM_GETCHECK ) ) 888 + cfg->CheckServer = i; 889 + return true; 890 + } 891 + 892 + virtual bool onCancel() 893 + { 894 + return cancelShiteIidesuka(); 895 + } 896 + 897 +private: 898 + class detailDlg : public kiDialog 899 + { 900 + public: 901 + detailDlg() : kiDialog( IDD_DETAIL ) {} 902 + private: 903 + virtual BOOL onInit() 904 + { 905 + if( cfg->George ) 906 + sendMsgToItem( IDC_CONNECT_ALWAYS, BM_SETCHECK, BST_CHECKED ); 907 + if( cfg->ShowReadMe ) 908 + sendMsgToItem( IDC_SHOW_README, BM_SETCHECK, BST_CHECKED ); 909 + if( cfg->UseCustomDir ) 910 + sendMsgToItem( IDC_SAVE_DESTDIR, BM_SETCHECK, BST_CHECKED ); 911 + for( int i=0; i<DLLID_NUM; ++i ) 912 + if( cfg->DoCheck[i] ) 913 + sendMsgToItem( IDC_DLHA+i, BM_SETCHECK, BST_CHECKED ); 914 +// 挿入caldixF 915 + sendMsgToItem( IDC_FILERPATH, WM_SETTEXT, 0, (LPARAM)(const char*)(cfg->Filer) ); 916 + sendMsgToItem( IDC_FILEROPT, WM_SETTEXT, 0, (LPARAM)(const char*)(cfg->F_Prefix) ); 917 + sendMsgToItem( IDC_FILEROPT2, WM_SETTEXT, 0, (LPARAM)(const char*)(cfg->F_Suffix) ); 918 + 919 +// 挿入ここまでcaldixF 920 + return FALSE; 921 + } 922 + 923 +// 挿入caldixF 924 + virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) 925 + { 926 + // 指定ボタン 927 + if((msg==WM_COMMAND) && (LOWORD(wp)==IDC_REF )){ 928 + kiSUtil::getOpenFileNameDlgOfEditBox(item(IDC_FILERPATH),hwnd()); 929 + return TRUE; 930 + } 931 + return FALSE; 932 + } 933 +// 挿入ここまでcaldixF 934 + 935 + virtual bool onOK() 936 + { 937 + cfg->George = 938 + (BST_CHECKED==sendMsgToItem( IDC_CONNECT_ALWAYS, BM_GETCHECK )); 939 + cfg->ShowReadMe = 940 + (BST_CHECKED==sendMsgToItem( IDC_SHOW_README, BM_GETCHECK )); 941 + cfg->UseCustomDir = 942 + (BST_CHECKED==sendMsgToItem( IDC_SAVE_DESTDIR, BM_GETCHECK )); 943 + for( int i=0; i<DLLID_NUM; ++i ) 944 + cfg->DoCheck[i] = 945 + (BST_CHECKED==sendMsgToItem( IDC_DLHA+i, BM_GETCHECK )); 946 +// 挿入caldixF 947 + char str[500]; 948 + 949 + sendMsgToItem( IDC_FILERPATH, WM_GETTEXT, sizeof(str)-1, (LPARAM)str ); 950 + cfg->Filer = str; 951 + sendMsgToItem( IDC_FILEROPT, WM_GETTEXT, sizeof(str)-1, (LPARAM)str ); 952 + cfg->F_Prefix = str; 953 + sendMsgToItem( IDC_FILEROPT2, WM_GETTEXT, sizeof(str)-1, (LPARAM)str ); 954 + cfg->F_Suffix = str; 955 +// 挿入ここまでcaldixF 956 + return true; 957 + } 958 + }; 959 + 960 + class proxyDlg : public kiDialog 961 + { 962 + public: 963 + proxyDlg() : kiDialog( IDD_PROXY ) {} 964 + private: 965 + virtual BOOL onInit() 966 + { 967 + if( cfg->ProxyPort>0 ) 968 + { 969 + sendMsgToItem( IDC_USEPROXY, BM_SETCHECK, BST_CHECKED ); 970 + ::EnableWindow( item(IDC_HOST_N), TRUE ); 971 + ::EnableWindow( item(IDC_PORT_N), TRUE ); 972 + ::EnableWindow( item(IDC_HOST), TRUE ); 973 + ::EnableWindow( item(IDC_PORT), TRUE ); 974 + ::SetDlgItemInt( hwnd(), IDC_PORT, cfg->ProxyPort, FALSE ); 975 + } 976 + else 977 + ::SetDlgItemInt( hwnd(), IDC_PORT, -cfg->ProxyPort, FALSE ); 978 + sendMsgToItem( IDC_HOST, WM_SETTEXT, 0, (LPARAM)(const char*)cfg->ProxyServer ); 979 + return FALSE; 980 + } 981 + 982 + virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) 983 + { 984 + if((msg==WM_COMMAND) && (LOWORD(wp)==IDC_USEPROXY)){ 985 + BOOL x = ( BST_CHECKED==sendMsgToItem( IDC_USEPROXY, BM_GETCHECK ) ); 986 + ::EnableWindow( item(IDC_HOST_N), x ); 987 + ::EnableWindow( item(IDC_PORT_N), x ); 988 + ::EnableWindow( item(IDC_HOST), x ); 989 + ::EnableWindow( item(IDC_PORT), x ); 990 + return TRUE; 991 + } 992 + return FALSE; 993 + } 994 + 995 + virtual bool onOK() 996 + { 997 + char str[500]; 998 + sendMsgToItem( IDC_HOST, WM_GETTEXT, sizeof(str)-1, (LPARAM)str ); 999 + cfg->ProxyServer = str; 1000 + cfg->ProxyPort = ::GetDlgItemInt( hwnd(), IDC_PORT, NULL, FALSE ); 1001 + if( BST_CHECKED!=sendMsgToItem( IDC_USEPROXY, BM_GETCHECK ) ) 1002 + cfg->ProxyPort *= -1; 1003 + return true; 1004 + } 1005 + }; 1006 +}; 1007 + 1008 +//---------------------------------------------------------------------------- 1009 +// mirrorMan : バージョンチェック先サーバ情報管理 1010 +//---------------------------------------------------------------------------- 1011 + 1012 +class mirrorInfo 1013 +{ 1014 +private: 1015 + enum { MAD, CSD, WAK, SERVER_NUM }; 1016 + static const char* c_serv[SERVER_NUM]; 1017 + static const char* c_path[SERVER_NUM]; 1018 + static const char* c_nick[SERVER_NUM]; 1019 + 1020 + int mirrors[SERVER_NUM+1]; 1021 + 1022 +public: 1023 + mirrorInfo() 1024 + { 1025 + for(int i=0; i!=SERVER_NUM+1; ++i) 1026 + mirrors[i] = -1; 1027 + } 1028 + 1029 + // どのサーバを先に見に行くか選択。 1030 + void setPreferedServer( int p ) 1031 + { 1032 + switch( p ) 1033 + { 1034 + default: 1035 + case MAD: 1036 + mirrors[0] = MAD; 1037 + mirrors[1] = CSD; 1038 + mirrors[2] = WAK; 1039 + break; 1040 + case CSD: 1041 + mirrors[0] = CSD; 1042 + mirrors[1] = MAD; 1043 + mirrors[2] = WAK; 1044 + break; 1045 + case WAK: 1046 + mirrors[0] = WAK; 1047 + mirrors[1] = MAD; 1048 + mirrors[2] = CSD; 1049 + break; 1050 + } 1051 + } 1052 + 1053 + // m番目のミラーサーバがDownしてるっぽい場合、候補から消去 1054 + void server_is_down( int m ) 1055 + { 1056 + for(int i=m; i!=SERVER_NUM; ++i) 1057 + mirrors[i] = mirrors[i+1]; 1058 + } 1059 + 1060 + // t番目のミラーサーバの情報を取得 1061 + bool isMirrorLeft( int m ) const { return mirrors[m] >= 0; } 1062 + kiStr serverName ( int m ) const { return c_serv[mirrors[m]]; } 1063 + kiStr basePath ( int m ) const { return c_path[mirrors[m]]; } 1064 + kiStr nickname ( int m ) const { return c_nick[mirrors[m]]; } 1065 + kiStr baseURL ( int m ) const { 1066 + return (kiStr("http://")+=c_serv[mirrors[m]])+=c_path[mirrors[m]]; 1067 + } 1068 +}; 1069 + 1070 +// static constants 1071 + 1072 +const char* mirrorInfo::c_serv[mirrorInfo::SERVER_NUM] = { 1073 + "www.madobe.net", 1074 + "www.csdinc.co.jp", 1075 + "archiver.wakusei.ne.jp", 1076 +}; 1077 +const char* mirrorInfo::c_path[mirrorInfo::SERVER_NUM] = { 1078 + "/archiver/lib/", 1079 + "/archiver/lib/", 1080 + "/lib/", 1081 +}; 1082 +const char* mirrorInfo::c_nick[mirrorInfo::SERVER_NUM] = { 1083 + "Madobe", 1084 + "CSD", 1085 + "Wakusei", 1086 +}; 1087 +static mirrorInfo mirrorMan; 1088 + 1089 +//---------------------------------------------------------------------------- 1090 +// verDlg : 接続して実際のバージョンチェックを行う 1091 +//---------------------------------------------------------------------------- 1092 + 1093 +class verDlg : public kiDialog 1094 +{ 1095 +public: 1096 + verDlg( HINTERNET hi ) 1097 + : kiDialog( IDD_VERCHECK ), h(hi), ss(NULL), http(NULL) {} 1098 + 1099 + ~verDlg() 1100 + { 1101 + if( ss ) 1102 + ::InternetCloseHandle( ss ); 1103 + if( http ) 1104 + ::InternetCloseHandle( http ); 1105 + } 1106 + 1107 +private: 1108 + 1109 + HANDLE hT; 1110 + HINTERNET h, http, ss; 1111 + volatile bool m_endFlag; 1112 + 1113 + BOOL onInit() 1114 + { 1115 + app()->setMainWnd( this ); 1116 + sendMsgToItem( IDC_BAR, PBM_SETSTEP, 1 ); 1117 + sendMsgToItem( IDC_BAR, PBM_SETRANGE, 0, MAKELPARAM(0,cfg->List.len()*3) ); 1118 + 1119 + m_endFlag = false; 1120 + DWORD id; 1121 + if( !(hT = ::CreateThread( NULL, 0, threadEntry, this, 0, &id )) ) 1122 + end( IDCANCEL ); 1123 + return FALSE; 1124 + } 1125 + 1126 + bool onCancel() 1127 + { 1128 + m_endFlag = true; 1129 + DWORD ex; 1130 + while( ::GetExitCodeThread( hT, &ex ) && ex==STILL_ACTIVE ) 1131 + ::Sleep(0); 1132 + ::CloseHandle( hT ); 1133 + return true; 1134 + } 1135 + 1136 + static DWORD WINAPI threadEntry( void* prm ) 1137 + { 1138 + ((verDlg*)prm)->threadWorker(); 1139 + return 0; 1140 + } 1141 + 1142 +private: 1143 + 1144 + // 作業用マクロ 1145 + #define CHECK_CANCEL() if(m_endFlag) break 1146 + #define STEP_GRAPH() CHECK_CANCEL(); sendMsgToItem( IDC_BAR, PBM_STEPIT ) 1147 + #define RETRY_() ::InternetCloseHandle( http ); http=NULL; goto retry; 1148 + #define RETRY_error() do{ ++Mir; RETRY_() }while(0) 1149 + #define RETRY_serverdown() do{ mirrorMan.server_is_down(Mir); RETRY_() }while(0) 1150 + #define INET_CONNECT( __s ) ::InternetConnect( h, __s, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ) 1151 + #define HTTP_REQ( __n ) ::HttpOpenRequest( http, "GET", __n, "HTTP/1.0", NULL, NULL, 0, 0 ) 1152 + #define HTTP_SEND() status=0,::HttpSendRequest( ss, NULL, 0, NULL, 0 ), ::HttpQueryInfoA( ss, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&status,&size,&dw),status; 1153 + 1154 + void threadWorker() 1155 + { 1156 + // 作業変数 1157 + DWORD dw = 0, size = sizeof(DWORD), status; 1158 + kiStr name; 1159 + char buf[4000]; 1160 + 1161 + // メインループ 1162 + for( unsigned int i=0; i<cfg->List.len(); ++i ) 1163 + { 1164 + if( !mirrorMan.isMirrorLeft(0) ) 1165 + break; // どのサーバにも繋げない場合、終了 1166 + STEP_GRAPH(); 1167 + 1168 + // 1169 + // 未接続ならサーバへ繋ぐ 1170 + // 1171 + int Mir = 0; 1172 + retry: 1173 + if( !http ) 1174 + { 1175 + if( !mirrorMan.isMirrorLeft(Mir) ) 1176 + continue; // このDLLの情報取得は無理でした 1177 + http = INET_CONNECT( mirrorMan.serverName(Mir) ); 1178 + if( !http ) 1179 + RETRY_serverdown(); // 次のミラーを試す 1180 + } 1181 + 1182 + // 1183 + // HTTPリクエスト作成 1184 + // 1185 + name = mirrorMan.basePath(Mir); 1186 + name+= cfg->List[i]->htmlName(); 1187 + ss = HTTP_REQ( name ); 1188 + if( !ss ) 1189 + RETRY_serverdown(); 1190 + CHECK_CANCEL(); 1191 + 1192 + // 1193 + // HTTPリクエスト送信 1194 + // 1195 + bool succeeded = false; 1196 + int try_auth = 3; 1197 + while( !succeeded && (try_auth-->0) ) 1198 + { 1199 + status = HTTP_SEND(); 1200 + 1201 + if( status/100 == 2 ) // 200など。成功 1202 + { 1203 + succeeded = true; 1204 + break; 1205 + } 1206 + else if( status == 0 ) // タイムアウト。別サーバをtry 1207 + { 1208 + ::InternetCloseHandle( ss ); 1209 + RETRY_serverdown(); 1210 + } 1211 + else if( status == 407 ) // 407 Proxy Authentication Required 1212 + { 1213 + // パスワードを打たせてもう一度 1214 + DWORD dwRet = ::InternetErrorDlg( 1215 + hwnd(), ss, GetLastError(), 1216 + FLAGS_ERROR_UI_FILTER_FOR_ERRORS | 1217 + FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | 1218 + FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, 1219 + NULL ); 1220 + // 認証失敗したら終了 1221 + if( dwRet != ERROR_INTERNET_FORCE_RETRY ) 1222 + { 1223 + ::InternetCloseHandle( ss ); 1224 + end( IDOK ); return; 1225 + } 1226 + continue; 1227 + } 1228 + else // その他のエラー。あきらめて次のDLLに進む 1229 + { 1230 + ::InternetCloseHandle( ss ); 1231 + break; 1232 + } 1233 + } 1234 + 1235 + // 1236 + // 読込 1237 + // 1238 + STEP_GRAPH(); 1239 + if( succeeded ) 1240 + { 1241 + DWORD read; 1242 + ::InternetReadFile( ss, buf, sizeof(buf)-1, &read ); 1243 + ::InternetCloseHandle( ss ); 1244 + buf[ read ] = '\0'; 1245 + } 1246 + 1247 + // 1248 + // 解析 1249 + // 1250 + STEP_GRAPH(); 1251 + if( succeeded ) 1252 + cfg->List[i]->ParseHTML( buf ); 1253 + } 1254 + 1255 + if( !m_endFlag ) 1256 + end( IDOK ); 1257 + } 1258 +}; 1259 + 1260 + 1261 + 1262 +//---------------------------------------------------------------------------- 1263 +// dllDlg: ダウンロードするDLLの選択 1264 +//---------------------------------------------------------------------------- 1265 + 1266 +class dllDlg : public kiDialog 1267 +{ 1268 +public: 1269 + dllDlg( kiArray<DLLInfo*>& upd ) : kiDialog( IDD_CUSTOM2 ), m_upd(upd) {} 1270 + 1271 +private: 1272 + kiArray<DLLInfo*>& m_upd; 1273 + 1274 + BOOL onInit() 1275 + { 1276 + app()->setMainWnd( this ); 1277 + 1278 + SHFILEINFO fi; 1279 + HIMAGELIST hI = (HIMAGELIST)::SHGetFileInfo( 1280 + kiPath(kiPath::Sys)+="KERNEL32.DLL", 0, &fi, sizeof(fi), 1281 + SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_SMALLICON ); 1282 + int iDLL = fi.iIcon; 1283 + int iEXE = kiSUtil::getSysIcon( "exe" ); 1284 + 1285 + kiStr str; 1286 + kiListView list( this, IDC_UPDATELIST ); 1287 + list.setImageList( NULL, hI ); 1288 + list.insertColumn( 0, str.loadRsrc( IDS_LV_DLLNAME ), 120 ); 1289 + list.insertColumn( 1, str.loadRsrc( IDS_LV_STATE ), 110 ); 1290 + for( unsigned int i=0; i<m_upd.len(); i++ ) 1291 + { 1292 + list.insertItem( i, m_upd[i]->getName(), 0, strcmpi( "dll", kiPath::ext(m_upd[i]->getName()) ) ? iEXE : iDLL ); 1293 + list.setSubItem( i, 1, m_upd[i]->getState() ); 1294 + } 1295 + sendMsgToItem( IDC_UPDATELIST,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES ); 1296 + for( i=0; i!=m_upd.len(); i++ ) 1297 + ListView_SetCheckState( item(IDC_UPDATELIST), i, TRUE ); 1298 + for( int j=0; j!=3; j++ ) 1299 + sendMsgToItem( IDC_INSTMODE1+j,BM_SETCHECK,j==cfg->InstMode ? BST_CHECKED : BST_UNCHECKED ); 1300 + return FALSE; 1301 + } 1302 + bool onCancel() 1303 + { 1304 + if( !cancelShiteIidesuka() ) 1305 + return false; 1306 + kiListView( this, IDC_UPDATELIST ).setImageList( NULL, NULL ); 1307 + return true; 1308 + } 1309 + bool onOK() 1310 + { 1311 + for( unsigned int i=0; i!=3; i++ ) 1312 + if( BST_CHECKED == sendMsgToItem( IDC_INSTMODE1+i, BM_GETCHECK ) ) 1313 + { 1314 + cfg->InstMode = i; 1315 + break; 1316 + } 1317 + 1318 + kiArray<DLLInfo*> res; 1319 + res = m_upd, m_upd.empty(); 1320 + for( i=0; i<res.len(); i++ ) 1321 + if( ListView_GetCheckState( item(IDC_UPDATELIST), i ) ) 1322 + m_upd.add( res[i] ); 1323 + 1324 + kiListView( this, IDC_UPDATELIST ).setImageList( NULL, NULL ); 1325 + return true; 1326 + } 1327 +}; 1328 + 1329 + 1330 + 1331 +//---------------------------------------------------------------------------- 1332 +// downloadDlg : ダウンロード 1333 +//---------------------------------------------------------------------------- 1334 + 1335 +class downloadDlg : public kiDialog, IBindStatusCallback 1336 +{ 1337 +public: 1338 + downloadDlg( const kiArray<DLLInfo*>& lst, const kiPath& pth ) 1339 + : kiDialog( IDD_VERCHECK ), m_lst( lst ), m_pth( pth ), m_cRef( 1 ){} 1340 + 1341 +private: 1342 + const kiArray<DLLInfo*>& m_lst; 1343 + const kiPath& m_pth; 1344 + unsigned long m_cRef; 1345 + unsigned long m_total; 1346 + unsigned long m_step; 1347 + unsigned long m_startTime, m_lastTime; 1348 + bool m_stateCancel; 1349 + 1350 + BOOL onInit() 1351 + { 1352 + app()->setMainWnd( this ); 1353 + 1354 + m_startTime = m_lastTime = ::GetTickCount(); 1355 + m_stateCancel = false; 1356 + m_step = m_total = 0; 1357 + for( unsigned int i=0; i<m_lst.len(); i++ ) 1358 + m_total += m_lst[i]->getSize(); 1359 + sendMsgToItem( IDC_BAR, PBM_SETRANGE,0, MAKELPARAM(0,32768) ); 1360 + setTimeInfo( 0 ); 1361 + ::ShowWindow( hwnd(), SW_SHOW ); 1362 + ::UpdateWindow( hwnd() ); 1363 + 1364 + kiPath url, fil; 1365 + 1366 + // メインループ 1367 + for( i=0; i<m_lst.len(); i++ ) 1368 + { 1369 + int Mir = 0; 1370 + retry: 1371 + if( !mirrorMan.isMirrorLeft(Mir) ) 1372 + { 1373 + app()->msgBox( kiStr(1000).loadRsrc( IDS_DLERROR ), "caldix", MB_ICONINFORMATION|MB_SYSTEMMODAL ); 1374 + break; 1375 + } 1376 + 1377 + // "○○をダウンロード中..." のテキストを更新 1378 + char msg[300]; 1379 + ::wsprintf( msg, kiStr().loadRsrc(IDS_DOWNLOADING), 1380 + (const char*)m_lst[i]->getName(), (const char*)mirrorMan.nickname(Mir) ); 1381 + sendMsgToItem( IDC_MSG, WM_SETTEXT, 0, (LPARAM)msg ); 1382 + ::EnableWindow( item(IDC_MSG), FALSE ); 1383 + ::EnableWindow( item(IDC_MSG), TRUE ); 1384 + 1385 + // ダウンロード元とダウンロード先 1386 + url = mirrorMan.baseURL(Mir), url += m_lst[i]->getArchiveName(); 1387 + fil = m_pth, fil += m_lst[i]->getArchiveName(); 1388 + if( S_OK != ::URLDownloadToFile( NULL, url, fil, 0, this ) ) 1389 + { 1390 + ++Mir; 1391 + goto retry; 1392 + } 1393 + m_step += m_lst[i]->getSize(); 1394 + } 1395 + end( i==m_lst.len() ? IDOK : IDCANCEL ); 1396 + return FALSE; 1397 + } 1398 + bool onCancel() 1399 + { 1400 + if( cancelShiteIidesuka() ) 1401 + m_stateCancel = true; 1402 + return false; 1403 + } 1404 + 1405 +public: 1406 + void setTimeInfo( unsigned long bytesread ) 1407 + { 1408 + int sec = (bytesread==0 || m_lastTime==m_startTime) 1409 + ? (int)((double)(m_total) / 7000) 1410 + : (int)((double)((m_total-bytesread)) * (m_lastTime - m_startTime) / 1000 / bytesread); 1411 + 1412 + static char str[300]; 1413 + ::wsprintf( str, (const char*)(kiStr().loadRsrc(IDS_REST)), 1414 + (m_total-bytesread)/1000, sec/60, sec%60 ); 1415 + 1416 + sendMsgToItem( IDC_RESTTIME, WM_SETTEXT, 0, (LPARAM)str ); 1417 + } 1418 + 1419 + STDMETHODIMP_(ULONG) AddRef() { return (++m_cRef); } 1420 + STDMETHODIMP_(ULONG) Release() { return (m_cRef ? --m_cRef : 0L); } 1421 + STDMETHODIMP GetBindInfo( DWORD*, BINDINFO* ) { return E_NOTIMPL; } 1422 + STDMETHODIMP GetPriority( LONG* ) { return E_NOTIMPL; } 1423 + STDMETHODIMP OnLowResource( DWORD ) { return E_NOTIMPL; } 1424 + STDMETHODIMP OnDataAvailable( DWORD, DWORD, FORMATETC*, STGMEDIUM* ) { return E_NOTIMPL; } 1425 + STDMETHODIMP OnObjectAvailable( REFIID, IUnknown* ) { return E_NOTIMPL; } 1426 + STDMETHODIMP OnStartBinding( DWORD, IBinding* ) { return E_NOTIMPL; } 1427 + STDMETHODIMP OnStopBinding( HRESULT, LPCWSTR ) { return E_NOTIMPL; } 1428 + STDMETHODIMP QueryInterface( REFIID riid, void** ppv ) 1429 + { 1430 + *ppv = NULL; 1431 + AddRef(); 1432 + if( IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_IBindStatusCallback ) ) 1433 + *ppv = (IBindStatusCallback*)this; 1434 + else 1435 + { 1436 + Release(); 1437 + return E_NOINTERFACE; 1438 + } 1439 + return NOERROR; 1440 + } 1441 + STDMETHODIMP OnProgress( ULONG cur, ULONG max, ULONG status, LPCWSTR txt ) 1442 + { 1443 + msgLoop( PEEK ); 1444 + 1445 + if( m_stateCancel ) 1446 + { 1447 + end( IDCANCEL ); 1448 + return E_ABORT; 1449 + } 1450 + 1451 + DWORD time = ::GetTickCount(); 1452 + if( time-m_lastTime >= 5000 ) 1453 + { 1454 + m_lastTime = time; 1455 + setTimeInfo( m_step+cur ); 1456 + } 1457 + 1458 + sendMsgToItem( IDC_BAR, PBM_SETPOS, (int)(((double)(m_step+cur))/m_total*32768) ); 1459 + return S_OK; 1460 + } 1461 +}; 1462 + 1463 + 1464 + 1465 +//---------------------------------------------------------------------------- 1466 +// instDlg : system等へインストール 1467 +//---------------------------------------------------------------------------- 1468 + 1469 +class instDlg : public kiDialog 1470 +{ 1471 +public: 1472 + instDlg( kiArray<DLLInfo*>& upd, const kiPath& arcdir, const kiPath& work, const kiPath& to ) 1473 + : kiDialog( IDD_INSTALL ), m_upd( upd ), m_arcdir( arcdir ), m_workdir( work ), m_dlldir( to ) {} 1474 + 1475 +private: 1476 + kiArray<DLLInfo*>& m_upd; 1477 + const kiPath& m_arcdir; 1478 + const kiPath& m_workdir; 1479 + const kiPath& m_dlldir; 1480 + bool onCancel() { return false; } 1481 + bool onOK() { return false; } 1482 + 1483 + BOOL onInit() 1484 + { 1485 + bool needreboot=false; 1486 + app()->setMainWnd( this ); 1487 + ::ShowWindow( hwnd(), SW_SHOW ); 1488 + ::UpdateWindow( hwnd() ); 1489 + //-- 解凍&インストール開始〜 --------------- 1490 + 1491 + char tmp[MAX_PATH]; 1492 + kiPath arc, dll, path; 1493 + for( unsigned int i=0; i<m_upd.len(); i++ ) 1494 + { 1495 + // 書庫名:フルパス 1496 + arc = m_arcdir, arc += m_upd[i]->getArchiveName(); 1497 + // ドキュメント保存先:フルパス 1498 + dll = m_workdir, ::lstrcpyn(tmp,m_upd[i]->getName(),m_upd[i]->getName().len()-3), dll += tmp, dll.remove(); 1499 + dll += "\\", dll.mkdir(), ::SetCurrentDirectory( dll ); 1500 + // 解凍( path=書庫内のDLLの相対パス ) 1501 + melt_it( arc, m_upd[i]->getName(), path ); 1502 + // インストール 1503 + if( !install_it( dll, path ) ) 1504 + { 1505 + needreboot = true; 1506 + } 1507 + if( path.isSame( "aish32.dll" ) ) 1508 + { 1509 + if( !install_it( dll, "Aishmv32.dll" ) ) 1510 + needreboot = true; 1511 + } 1512 + else if( path.isSame( "unrar32.dll" ) ) 1513 + { 1514 + if( !install_it( dll, "unrar.dll" ) ) 1515 + needreboot = true; 1516 + } 1517 + else if( path.isSame( "yz1.dll" ) ) 1518 + { 1519 + if( !install_it( dll, "yzdec.exe" ) ) 1520 + needreboot = true; 1521 + kiPath uyz( m_dlldir ); 1522 + if( !kiSUtil::exist( uyz+="UnYz1.dll" ) ) 1523 + if( !install_it( dll, "UnYz1.dll" ) ) 1524 + needreboot = true; 1525 + } 1526 + else if( path.isSame( "bh32.dll" ) ) 1527 + { 1528 + if( !install_it( dll, "bhsfx.exe" ) ) 1529 + needreboot = true; 1530 + } 1531 + // メッセージ処理 1532 + msg(); 1533 + } 1534 + 1535 + //-- 解凍&インストール終了〜 --------------- 1536 + end( needreboot ? IDCANCEL : IDOK ); 1537 + return FALSE; 1538 + } 1539 + 1540 +private: 1541 + bool install_it( const char* position, const char* relpath ) 1542 + { 1543 + kiPath from( position ); from += relpath; 1544 + if( ::GetFileAttributes(from) != 0xffffffff ) 1545 + { 1546 + kiPath to( m_dlldir ); to += kiPath::name(relpath); 1547 + if( ::CopyFile( from, to, FALSE ) ) 1548 + ::DeleteFile( from ); 1549 + else 1550 + { 1551 + // 再起動後コピー準備 1552 + move_later( from, to ); 1553 + return false; 1554 + } 1555 + } 1556 + return true; 1557 + } 1558 +}; 1559 + 1560 + 1561 + 1562 +//---------------------------------------------------------------------------- 1563 +// caldix : メインルーチン 1564 +//---------------------------------------------------------------------------- 1565 + 1566 +#include <ras.h> 1567 +#include <raserror.h> 1568 + 1569 +class caldix : public kiApp 1570 +{ 1571 + caldix() 1572 + { 1573 + shellInit(); 1574 + kiutil::pathInit(); 1575 + 1576 + cfg = new CldxConfig; 1577 + } 1578 + 1579 + void run( kiCmdParser& cmd ) 1580 + { 1581 + // ダイアログ [全自動/カスタム] 1582 + if( !cfg->SuperAutoMode && !show( startDlg() ) ) 1583 + return; 1584 + 1585 + if( cfg->AutoMode ) 1586 + { 1587 + // 全自動なら、インストール先をシステムにするかもしれない 1588 + if( !cfg->UseCustomDir ) 1589 + cfg->InstallTo.beSpecialPath( kiPath::Sys ); 1590 + } 1591 + else 1592 + { 1593 + // ダイアログ [インストール先とか] 1594 + if( !show( customDlg() ) ) 1595 + return; 1596 + } 1597 + 1598 + // 設定の調整 1599 + cfg->InstallTo.beBackSlash( true ); 1600 + cfg->GenerateDLLList(); 1601 + 1602 + // 常時接続モードでない場合、接続を確立 1603 + if( !cfg->George ) 1604 + if( ERROR_SUCCESS != ::InternetAttemptConnect(0) ) 1605 + { 1606 + msgBox( kiStr().loadRsrc( IDS_NOINTERNET ) ); 1607 + return; 1608 + } 1609 + 1610 + // WinInet開始… 1611 + HINTERNET h = ::InternetOpen( cfg->UA, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); 1612 + if( !h ) 1613 + { 1614 + msgBox( kiStr().loadRsrc( IDS_NOINTERNET ) ); 1615 + return; 1616 + } 1617 + 1618 + // プロクシの設定 1619 + if( cfg->ProxyServer.len() && cfg->ProxyPort>0 ) 1620 + { 1621 + kiStr pr( "http=http://" ); 1622 + pr += cfg->ProxyServer; 1623 + pr += ':'; 1624 + pr += kiStr().setInt(cfg->ProxyPort); 1625 + INTERNET_PROXY_INFO pi = {INTERNET_OPEN_TYPE_PROXY,(const char*)pr,"<local>"}; 1626 + ::InternetSetOption( h, INTERNET_OPTION_PROXY, (void*)&pi, sizeof(pi) ); 1627 + ::UrlMkSetSessionOption( INTERNET_OPTION_PROXY, (void*)&pi, sizeof(pi), 0 ); 1628 + } 1629 + 1630 + // タイムアウトは5秒 1631 + DWORD TimeOut = 5*1000; 1632 + ::InternetSetOption( h, INTERNET_OPTION_RECEIVE_TIMEOUT, &TimeOut, sizeof(TimeOut) ); 1633 + 1634 + // 接続先サーバ情報を設定から取得 1635 + mirrorMan.setPreferedServer( cfg->CheckServer ); 1636 + 1637 + // ダイアログ [WWWC META CHECK] 1638 + if( !show( verDlg(h) ) ) 1639 + { 1640 + ::InternetCloseHandle( h ); 1641 + askRasHangUp(); 1642 + return; 1643 + } 1644 + 1645 + // バージョン比較 1646 + kiStr tmp; 1647 + kiArray<DLLInfo*> upd; 1648 + for( unsigned int i=0; i<cfg->List.len(); ++i ) 1649 + if( cfg->List[i]->needToUpdate( cfg->InstallTo ) ) 1650 + upd.add( cfg->List[i] ); 1651 + 1652 + if( upd.len()==0 ) 1653 + { 1654 + ::InternetCloseHandle( h ); 1655 + msgBox( kiStr().loadRsrc( IDS_NONEED ), "caldix", MB_ICONINFORMATION ); 1656 + askRasHangUp(); 1657 + return; 1658 + } 1659 + 1660 + if( ! cfg->AutoMode ) 1661 + { 1662 + // ダイアログ [インストールするDLLとか] 1663 + if( !show(dllDlg(upd)) || upd.len()==0 ) 1664 + { 1665 + ::InternetCloseHandle( h ); 1666 + askRasHangUp(); 1667 + return; 1668 + } 1669 + } 1670 + 1671 + // ダウンロード 1672 + char buf[MAX_PATH]; 1673 + ::GetTempFileName( kiPath( kiPath::Tmp ), "cld", 0, buf ); 1674 + ::DeleteFile( buf ); 1675 + kiPath dlto( buf ); 1676 + dlto.beBackSlash( true ); 1677 + dlto.mkdir(); 1678 + 1679 + if( !show( downloadDlg(upd, dlto) ) ) 1680 + { 1681 + dlto.remove(); 1682 + ::InternetCloseHandle( h ); 1683 + askRasHangUp(); 1684 + return; 1685 + } 1686 + 1687 + // インストール準備 1688 + bool needreboot = false; 1689 + cfg->InstallTo.mkdir(); 1690 + kiPath workDir( kiPath::Exe ); workDir.lower(); 1691 + UINT drv = workDir.getDriveType(); 1692 + if( strstr(workDir,"temporary internet files")!=NULL 1693 + || (drv!=DRIVE_FIXED && drv!=DRIVE_REMOTE && drv!=DRIVE_UNKNOWN) ) 1694 + workDir.beSpecialPath( kiPath::Dsk ), workDir.beBackSlash( true ); 1695 + workDir += "cldx\\"; 1696 + workDir.mkdir(); 1697 + 1698 + if( cfg->InstMode != 1 ) 1699 + { 1700 + // 書庫コピー 1701 + kiPath from, to; 1702 + for( unsigned int i=0; i<upd.len(); i++ ) 1703 + { 1704 + from = dlto, from += upd[i]->getArchiveName(); 1705 + to = workDir, to += upd[i]->getArchiveName(); 1706 + ::CopyFile( from, to, FALSE ); 1707 + } 1708 + } 1709 + if( cfg->InstMode != 0 ) 1710 + { 1711 + // インストール 1712 + if( !show( instDlg( upd, dlto, workDir, cfg->InstallTo ) ) ) 1713 + needreboot = true; 1714 + } 1715 + 1716 + // 閉じ処理 1717 + dlto.remove(); 1718 + ::InternetCloseHandle( h ); 1719 + 1720 + if( !needreboot ) 1721 + { 1722 + if( ! cfg->SuperAutoMode ) 1723 + msgBox( kiStr(500).loadRsrc( IDS_FINISHED ), "caldix", MB_ICONINFORMATION|MB_SYSTEMMODAL ); 1724 + askRasHangUp(); 1725 + } 1726 + else 1727 + if( IDYES!=msgBox( kiStr(1000).loadRsrc( IDS_REBOOT ), "caldix", MB_ICONINFORMATION|MB_YESNO|MB_SYSTEMMODAL ) ) 1728 + needreboot = false; 1729 + 1730 + // 簡易説明書出力 1731 + if( ::GetACP() == 932 ) 1732 + { 1733 + kiFile fp; 1734 + if( fp.open( kiPath(workDir)+="読んでね.txt", false ) ) 1735 + { 1736 + static const char * text = 1737 +"このフォルダには、caldixでダウンロードされた\r\n" 1738 +"DLLの説明書を格納してあります。よくお読み下さい。\r\n" 1739 +"\r\n" 1740 +"★ UNZIP32.DLL を企業内等で利用する場合には、必ず\r\n" 1741 +"★ ライセンス契約が必要です。詳細は下記ページにて。\r\n" 1742 +"★ http://www.csdinc.co.jp/archiver/lib/unzip32.html\r\n" 1743 +"\r\n" 1744 +"それぞれのDLLの作者様のサイトは、\r\n" 1745 +" 『統合アーカイバプロジェクト』\r\n" 1746 +" http://www.csdinc.co.jp/archiver/ \r\n" 1747 +"からリンクをたどって訪れることが出来ます。\r\n" 1748 +"是非一度は行ってみることをお勧めします。\r\n" 1749 +"\r\n" 1750 +"DLLのアンインストールは uncaldix が便利。\r\n" 1751 +" http://www6.plala.or.jp/amasoft/soft/uncaldix.html\r\n" 1752 +"\r\n" 1753 +"caldixに関するご質問等は( http://www.kmonos.net/ )へ\r\n" 1754 + ; fp.write( text, ki_strlen(text) ); 1755 + } 1756 + } 1757 + 1758 + // 出力先開く 1759 + if( cfg->ShowReadMe ) 1760 + { 1761 + char cmdline[1000]; 1762 +// コメントアウトcaldixF 1763 +/* 1764 + ::wsprintf( cmdline, "explorer \"%s\"", (const char*)workDir ); 1765 + ::WinExec( cmdline, SW_SHOWDEFAULT ); 1766 +*/ 1767 +// コメントアウトここまでcaldixF 1768 + 1769 +// 挿入caldixF 1770 + char wdir[MAX_PATH*3]; 1771 + 1772 + // caldixのパスを取得 1773 + GetModuleFileName(NULL,wdir,MAX_PATH); 1774 + // caldix.exe→cldxにする 1775 + lstrcpy(GetFileName(wdir),"cldx"); 1776 + 1777 + // prefixとpostfixをつける( modified by k.inaba ) 1778 + bool bNeedQuote = false; 1779 + for(int i=0; i!=cfg->Filer.len(); ++i) 1780 + if(cfg->Filer[i]==' ') { bNeedQuote=true; break; } 1781 + ::wsprintf( cmdline, 1782 + bNeedQuote ? "\"%s\" %s\"%s\"%s" : "%s %s\"%s\"%s", 1783 + (const char*)cfg->Filer, 1784 + (const char*)cfg->F_Prefix, wdir, (const char*)cfg->F_Suffix); 1785 + 1786 + // ファイラ起動( modified by k.inaba ) 1787 + STARTUPINFO si = {sizeof(si)}; 1788 + PROCESS_INFORMATION pi; 1789 + { 1790 + kiPath original_cur(kiPath::Cur), sys(kiPath::Sys); // 大丈夫なはずだけど念のためのカレント移動 1791 + ::SetCurrentDirectory(sys); 1792 + ::CreateProcess( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, wdir, &si, &pi ); 1793 + ::SetCurrentDirectory(original_cur); 1794 + } 1795 + ::CloseHandle(pi.hProcess); 1796 + ::CloseHandle(pi.hThread); 1797 +// 挿入ここまでcaldixF 1798 + } 1799 + 1800 + if( needreboot ) 1801 + rebootWindows(); // 再起動でーす 1802 + } 1803 + 1804 + void askRasHangUp() 1805 + { 1806 + // 訊かないモード 1807 + if( cfg->George ) 1808 + return; 1809 + 1810 + // DLL,及び必要な関数をロード 1811 + HINSTANCE rasdll = kiutil::safepathLoadLibrary( "RASAPI32.DLL" ); 1812 + if( rasdll == NULL ) 1813 + return; 1814 + typedef DWORD (WINAPI * rE)( LPRASCONN,LPDWORD,LPDWORD ); 1815 + typedef DWORD (WINAPI * rH)( HRASCONN ); 1816 + typedef BOOL (WINAPI * rS)( HRASCONN,LPRASCONNSTATUS ); 1817 + rE RasEnumConnections = (rE)::GetProcAddress( rasdll, "RasEnumConnectionsA" ); 1818 + rH RasHangUp = (rH)::GetProcAddress( rasdll, "RasHangUpA" ); 1819 + rS RasGetConnectStatus= (rS)::GetProcAddress( rasdll, "RasGetConnectStatusA" ); 1820 + if( RasEnumConnections!=NULL && RasHangUp!=NULL && RasGetConnectStatus!=NULL ) 1821 + { 1822 + RASCONN* RasConn = new RASCONN[1]; 1823 + DWORD Num, Size = sizeof(RASCONN); 1824 + RasConn->dwSize = sizeof(RASCONN); 1825 + int Sts = RasEnumConnections( RasConn, &Size, &Num ); 1826 + if( (Sts==ERROR_BUFFER_TOO_SMALL) || (Sts==ERROR_NOT_ENOUGH_MEMORY) ) 1827 + { 1828 + delete [] RasConn; 1829 + RasConn = new RASCONN[Size/sizeof(RASCONN)]; 1830 + Sts = RasEnumConnections( RasConn, &Size, &Num ); 1831 + } 1832 + if( Sts==0 && Num>=1 ) 1833 + { 1834 + // 訊く。 1835 + if( IDYES==msgBox( kiStr(1000).loadRsrc( IDS_RASHANGUP ), "caldix", MB_ICONINFORMATION|MB_YESNO|MB_SYSTEMMODAL ) ) 1836 + { 1837 + // 切る 1838 + RASCONNSTATUS RasSts; 1839 + RasSts.dwSize = sizeof(RASCONNSTATUS); 1840 + for( DWORD i=0; i<Num; i++ ) 1841 + { 1842 + RasHangUp( RasConn->hrasconn ); 1843 + while( RasGetConnectStatus( RasConn->hrasconn, &RasSts ) != ERROR_INVALID_HANDLE ) 1844 + ::Sleep( 10 ); 1845 + } 1846 + } 1847 + } 1848 + delete [] RasConn; 1849 + } 1850 + ::FreeLibrary( rasdll ); 1851 + } 1852 + 1853 + ~caldix() 1854 + { 1855 + delete cfg; 1856 + } 1857 + 1858 + friend void kilib_create_new_app(); 1859 +}; 1860 + 1861 +void kilib_create_new_app() 1862 +{ 1863 + new caldix; 1864 +}
Added Caldix.dsp version [349c593e8a5c109a]
1 +# Microsoft Developer Studio Project File - Name="Caldix" - Package Owner=<4> 2 +# Microsoft Developer Studio Generated Build File, Format Version 6.00 3 +# ** 編集しないでください ** 4 + 5 +# TARGTYPE "Win32 (x86) Application" 0x0101 6 + 7 +CFG=Caldix - Win32 Debug 8 +!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。 9 +!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください 10 +!MESSAGE 11 +!MESSAGE NMAKE /f "Caldix.mak". 12 +!MESSAGE 13 +!MESSAGE NMAKE の実行時に構成を指定できます 14 +!MESSAGE コマンド ライン上でマクロの設定を定義します。例: 15 +!MESSAGE 16 +!MESSAGE NMAKE /f "Caldix.mak" CFG="Caldix - Win32 Debug" 17 +!MESSAGE 18 +!MESSAGE 選択可能なビルド モード: 19 +!MESSAGE 20 +!MESSAGE "Caldix - Win32 Release" ("Win32 (x86) Application" 用) 21 +!MESSAGE "Caldix - Win32 Debug" ("Win32 (x86) Application" 用) 22 +!MESSAGE 23 + 24 +# Begin Project 25 +# PROP AllowPerConfigDependencies 0 26 +# PROP Scc_ProjName "" 27 +# PROP Scc_LocalPath "" 28 +CPP=cl.exe 29 +MTL=midl.exe 30 +RSC=rc.exe 31 + 32 +!IF "$(CFG)" == "Caldix - Win32 Release" 33 + 34 +# PROP BASE Use_MFC 0 35 +# PROP BASE Use_Debug_Libraries 0 36 +# PROP BASE Output_Dir "Release" 37 +# PROP BASE Intermediate_Dir "Release" 38 +# PROP BASE Target_Dir "" 39 +# PROP Use_MFC 0 40 +# PROP Use_Debug_Libraries 0 41 +# PROP Output_Dir "Release" 42 +# PROP Intermediate_Dir "Release" 43 +# PROP Ignore_Export_Lib 0 44 +# PROP Target_Dir "" 45 +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c 46 +# ADD CPP /nologo /W3 /O1 /Oy /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c 47 +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 48 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 49 +# ADD BASE RSC /l 0x411 /d "NDEBUG" 50 +# ADD RSC /l 0x411 /d "NDEBUG" 51 +BSC32=bscmake.exe 52 +# ADD BASE BSC32 /nologo 53 +# ADD BSC32 /nologo 54 +LINK32=link.exe 55 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 56 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib ws2_32.lib wininet.lib fdi/fdi.lib urlmon.lib /nologo /subsystem:windows /machine:I386 /opt:"nowin98" 57 +# SUBTRACT LINK32 /pdb:none 58 + 59 +!ELSEIF "$(CFG)" == "Caldix - Win32 Debug" 60 + 61 +# PROP BASE Use_MFC 0 62 +# PROP BASE Use_Debug_Libraries 1 63 +# PROP BASE Output_Dir "Debug" 64 +# PROP BASE Intermediate_Dir "Debug" 65 +# PROP BASE Target_Dir "" 66 +# PROP Use_MFC 0 67 +# PROP Use_Debug_Libraries 1 68 +# PROP Output_Dir "Debug" 69 +# PROP Intermediate_Dir "Debug" 70 +# PROP Ignore_Export_Lib 0 71 +# PROP Target_Dir "" 72 +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c 73 +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c 74 +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 75 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 76 +# ADD BASE RSC /l 0x411 /d "_DEBUG" 77 +# ADD RSC /l 0x411 /d "_DEBUG" 78 +BSC32=bscmake.exe 79 +# ADD BASE BSC32 /nologo 80 +# ADD BSC32 /nologo 81 +LINK32=link.exe 82 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept 83 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib ws2_32.lib wininet.lib fdi/fdi.lib urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept 84 + 85 +!ENDIF 86 + 87 +# Begin Target 88 + 89 +# Name "Caldix - Win32 Release" 90 +# Name "Caldix - Win32 Debug" 91 +# Begin Group "Source Files" 92 + 93 +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 94 +# Begin Source File 95 + 96 +SOURCE=.\CabTool.cpp 97 +# End Source File 98 +# Begin Source File 99 + 100 +SOURCE=.\Caldix.cpp 101 +# End Source File 102 +# Begin Source File 103 + 104 +SOURCE=.\kiutil.cpp 105 +# End Source File 106 +# Begin Source File 107 + 108 +SOURCE=.\LzhDecoder2.cpp 109 +# End Source File 110 +# Begin Source File 111 + 112 +SOURCE=.\LzhTool.cpp 113 +# End Source File 114 +# Begin Source File 115 + 116 +SOURCE=.\StdAfx.cpp 117 +# ADD CPP /Yc"stdafx.h" 118 +# End Source File 119 +# Begin Source File 120 + 121 +SOURCE=.\ZipTool.cpp 122 +# End Source File 123 +# End Group 124 +# Begin Group "Header Files" 125 + 126 +# PROP Default_Filter "h;hpp;hxx;hm;inl" 127 +# Begin Source File 128 + 129 +SOURCE=.\CabTool.h 130 +# End Source File 131 +# Begin Source File 132 + 133 +SOURCE=.\kiutil.h 134 +# End Source File 135 +# Begin Source File 136 + 137 +SOURCE=.\LzhDecoder2.h 138 +# End Source File 139 +# Begin Source File 140 + 141 +SOURCE=.\LzhTool.h 142 +# End Source File 143 +# Begin Source File 144 + 145 +SOURCE=.\StdAfx.h 146 +# End Source File 147 +# Begin Source File 148 + 149 +SOURCE=.\ZipTool.h 150 +# End Source File 151 +# End Group 152 +# Begin Group "Resource Files" 153 + 154 +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 155 +# Begin Source File 156 + 157 +SOURCE=.\caldix.ico 158 +# End Source File 159 +# Begin Source File 160 + 161 +SOURCE=.\Caldix.rc 162 +# End Source File 163 +# Begin Source File 164 + 165 +SOURCE=.\manifest.xml 166 +# End Source File 167 +# Begin Source File 168 + 169 +SOURCE=.\resource.h 170 +# End Source File 171 +# End Group 172 +# Begin Group "K.I.LIB" 173 + 174 +# PROP Default_Filter "" 175 +# Begin Source File 176 + 177 +SOURCE=.\kilib\kilib.h 178 +# End Source File 179 +# Begin Source File 180 + 181 +SOURCE=.\kilib\kilibext.h 182 +# End Source File 183 +# Begin Source File 184 + 185 +SOURCE=.\kilib\kl_app.cpp 186 +# End Source File 187 +# Begin Source File 188 + 189 +SOURCE=.\kilib\kl_app.h 190 +# End Source File 191 +# Begin Source File 192 + 193 +SOURCE=.\kilib\kl_carc.cpp 194 +# End Source File 195 +# Begin Source File 196 + 197 +SOURCE=.\kilib\kl_carc.h 198 +# End Source File 199 +# Begin Source File 200 + 201 +SOURCE=.\kilib\kl_cmd.cpp 202 +# End Source File 203 +# Begin Source File 204 + 205 +SOURCE=.\kilib\kl_cmd.h 206 +# End Source File 207 +# Begin Source File 208 + 209 +SOURCE=.\kilib\kl_dnd.cpp 210 +# End Source File 211 +# Begin Source File 212 + 213 +SOURCE=.\kilib\kl_dnd.h 214 +# End Source File 215 +# Begin Source File 216 + 217 +SOURCE=.\kilib\kl_file.cpp 218 +# End Source File 219 +# Begin Source File 220 + 221 +SOURCE=.\kilib\kl_file.h 222 +# End Source File 223 +# Begin Source File 224 + 225 +SOURCE=.\kilib\kl_find.cpp 226 +# End Source File 227 +# Begin Source File 228 + 229 +SOURCE=.\kilib\kl_find.h 230 +# End Source File 231 +# Begin Source File 232 + 233 +SOURCE=.\kilib\kl_misc.h 234 +# End Source File 235 +# Begin Source File 236 + 237 +SOURCE=.\kilib\kl_reg.cpp 238 +# End Source File 239 +# Begin Source File 240 + 241 +SOURCE=.\kilib\kl_reg.h 242 +# End Source File 243 +# Begin Source File 244 + 245 +SOURCE=.\kilib\kl_str.cpp 246 +# End Source File 247 +# Begin Source File 248 + 249 +SOURCE=.\kilib\kl_str.h 250 +# End Source File 251 +# Begin Source File 252 + 253 +SOURCE=.\kilib\kl_wcmn.cpp 254 +# End Source File 255 +# Begin Source File 256 + 257 +SOURCE=.\kilib\kl_wcmn.h 258 +# End Source File 259 +# Begin Source File 260 + 261 +SOURCE=.\kilib\kl_wnd.cpp 262 +# End Source File 263 +# Begin Source File 264 + 265 +SOURCE=.\kilib\kl_wnd.h 266 +# End Source File 267 +# End Group 268 +# Begin Group "zlib" 269 + 270 +# PROP Default_Filter "" 271 +# Begin Source File 272 + 273 +SOURCE=.\zlib\adler32.c 274 +# SUBTRACT CPP /YX /Yc /Yu 275 +# End Source File 276 +# Begin Source File 277 + 278 +SOURCE=.\zlib\compress.c 279 +# SUBTRACT CPP /YX /Yc /Yu 280 +# End Source File 281 +# Begin Source File 282 + 283 +SOURCE=.\zlib\crc32.c 284 +# SUBTRACT CPP /YX /Yc /Yu 285 +# End Source File 286 +# Begin Source File 287 + 288 +SOURCE=.\zlib\deflate.c 289 +# SUBTRACT CPP /YX /Yc /Yu 290 +# End Source File 291 +# Begin Source File 292 + 293 +SOURCE=.\zlib\deflate.h 294 +# End Source File 295 +# Begin Source File 296 + 297 +SOURCE=.\zlib\gzio.c 298 +# SUBTRACT CPP /YX /Yc /Yu 299 +# End Source File 300 +# Begin Source File 301 + 302 +SOURCE=.\zlib\infblock.c 303 +# SUBTRACT CPP /YX /Yc /Yu 304 +# End Source File 305 +# Begin Source File 306 + 307 +SOURCE=.\zlib\infblock.h 308 +# End Source File 309 +# Begin Source File 310 + 311 +SOURCE=.\zlib\infcodes.c 312 +# SUBTRACT CPP /YX /Yc /Yu 313 +# End Source File 314 +# Begin Source File 315 + 316 +SOURCE=.\zlib\infcodes.h 317 +# End Source File 318 +# Begin Source File 319 + 320 +SOURCE=.\zlib\inffast.c 321 +# SUBTRACT CPP /YX /Yc /Yu 322 +# End Source File 323 +# Begin Source File 324 + 325 +SOURCE=.\zlib\inffast.h 326 +# End Source File 327 +# Begin Source File 328 + 329 +SOURCE=.\zlib\inffixed.h 330 +# End Source File 331 +# Begin Source File 332 + 333 +SOURCE=.\zlib\inflate.c 334 +# SUBTRACT CPP /YX /Yc /Yu 335 +# End Source File 336 +# Begin Source File 337 + 338 +SOURCE=.\zlib\inftrees.c 339 +# SUBTRACT CPP /YX /Yc /Yu 340 +# End Source File 341 +# Begin Source File 342 + 343 +SOURCE=.\zlib\inftrees.h 344 +# End Source File 345 +# Begin Source File 346 + 347 +SOURCE=.\zlib\infutil.c 348 +# SUBTRACT CPP /YX /Yc /Yu 349 +# End Source File 350 +# Begin Source File 351 + 352 +SOURCE=.\zlib\infutil.h 353 +# End Source File 354 +# Begin Source File 355 + 356 +SOURCE=.\zlib\maketree.c 357 +# SUBTRACT CPP /YX /Yc /Yu 358 +# End Source File 359 +# Begin Source File 360 + 361 +SOURCE=.\zlib\trees.c 362 +# SUBTRACT CPP /YX /Yc /Yu 363 +# End Source File 364 +# Begin Source File 365 + 366 +SOURCE=.\zlib\trees.h 367 +# End Source File 368 +# Begin Source File 369 + 370 +SOURCE=.\zlib\uncompr.c 371 +# SUBTRACT CPP /YX /Yc /Yu 372 +# End Source File 373 +# Begin Source File 374 + 375 +SOURCE=.\zlib\zconf.h 376 +# End Source File 377 +# Begin Source File 378 + 379 +SOURCE=.\zlib\zlib.h 380 +# End Source File 381 +# Begin Source File 382 + 383 +SOURCE=.\zlib\zutil.c 384 +# SUBTRACT CPP /YX /Yc /Yu 385 +# End Source File 386 +# Begin Source File 387 + 388 +SOURCE=.\zlib\zutil.h 389 +# End Source File 390 +# End Group 391 +# Begin Source File 392 + 393 +SOURCE=.\ReadMe.txt 394 +# End Source File 395 +# End Target 396 +# End Project
Added Caldix.dsw version [c726760d9ce0a8b4]
1 +Microsoft Developer Studio Workspace File, Format Version 6.00 2 +# 警告: このワークスペース ファイル を編集または削除しないでください! 3 + 4 +############################################################################### 5 + 6 +Project: "Caldix"=.\Caldix.dsp - Package Owner=<4> 7 + 8 +Package=<5> 9 +{{{ 10 +}}} 11 + 12 +Package=<4> 13 +{{{ 14 +}}} 15 + 16 +############################################################################### 17 + 18 +Global: 19 + 20 +Package=<5> 21 +{{{ 22 +}}} 23 + 24 +Package=<3> 25 +{{{ 26 +}}} 27 + 28 +############################################################################### 29 +
Added Caldix.rc version [04eaa031711e6a57]
1 +//Microsoft Developer Studio generated resource script. 2 +// 3 +#include "resource.h" 4 + 5 +#define APSTUDIO_READONLY_SYMBOLS 6 +///////////////////////////////////////////////////////////////////////////// 7 +// 8 +// Generated from the TEXTINCLUDE 2 resource. 9 +// 10 +#include "afxres.h" 11 + 12 +///////////////////////////////////////////////////////////////////////////// 13 +#undef APSTUDIO_READONLY_SYMBOLS 14 + 15 +///////////////////////////////////////////////////////////////////////////// 16 +// 日本語 resources 17 + 18 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) 19 +#ifdef _WIN32 20 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT 21 +#pragma code_page(932) 22 +#endif //_WIN32 23 + 24 +#ifndef _MAC 25 +///////////////////////////////////////////////////////////////////////////// 26 +// 27 +// Version 28 +// 29 + 30 +VS_VERSION_INFO VERSIONINFO 31 + FILEVERSION 1,2,1,0 32 + PRODUCTVERSION 1,2,1,0 33 + FILEFLAGSMASK 0x3fL 34 +#ifdef _DEBUG 35 + FILEFLAGS 0x1L 36 +#else 37 + FILEFLAGS 0x0L 38 +#endif 39 + FILEOS 0x4L 40 + FILETYPE 0x1L 41 + FILESUBTYPE 0x0L 42 +BEGIN 43 + BLOCK "StringFileInfo" 44 + BEGIN 45 + BLOCK "041104b0" 46 + BEGIN 47 + VALUE "Comments", "http://www.kmonos.net/\0" 48 + VALUE "CompanyName", "\0" 49 + VALUE "FileDescription", "Common Archivers Library DLL Installer X\0" 50 + VALUE "FileVersion", "1.21\0" 51 + VALUE "InternalName", "caldix\0" 52 + VALUE "LegalCopyright", "proposed by k.inaba\0" 53 + VALUE "LegalTrademarks", "\0" 54 + VALUE "OriginalFilename", "caldix.exe\0" 55 + VALUE "PrivateBuild", "\0" 56 + VALUE "ProductName", "K.I.Lib caldix\0" 57 + VALUE "ProductVersion", "1.21\0" 58 + VALUE "SpecialBuild", "\0" 59 + END 60 + END 61 + BLOCK "VarFileInfo" 62 + BEGIN 63 + VALUE "Translation", 0x411, 1200 64 + END 65 +END 66 + 67 +#endif // !_MAC 68 + 69 + 70 +#ifdef APSTUDIO_INVOKED 71 +///////////////////////////////////////////////////////////////////////////// 72 +// 73 +// TEXTINCLUDE 74 +// 75 + 76 +1 TEXTINCLUDE DISCARDABLE 77 +BEGIN 78 + "resource.h\0" 79 +END 80 + 81 +2 TEXTINCLUDE DISCARDABLE 82 +BEGIN 83 + "#include ""afxres.h""\r\n" 84 + "\0" 85 +END 86 + 87 +3 TEXTINCLUDE DISCARDABLE 88 +BEGIN 89 + "\r\n" 90 + "\0" 91 +END 92 + 93 +#endif // APSTUDIO_INVOKED 94 + 95 + 96 +///////////////////////////////////////////////////////////////////////////// 97 +// 98 +// 24 99 +// 100 + 101 +1 24 MOVEABLE PURE "manifest.xml" 102 + 103 +///////////////////////////////////////////////////////////////////////////// 104 +// 105 +// Dialog 106 +// 107 + 108 +IDD_START DIALOG DISCARDABLE 0, 0, 263, 99 109 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 110 + WS_SYSMENU 111 +CAPTION "統合アーカイバDLL自動インストーラ" 112 +FONT 9, "MS Pゴシック" 113 +BEGIN 114 + LTEXT "このソフトは、「統合アーカイバDLL」をインターネットから自動で入手し、貴方のパソコンで使用できるように設定を整えるためのソフトです。\r\n\r\n開始ボタンを押すと作業を始めます。\r\n\r\n注意!DCさくらやFlashGet等のソフトでブラウザ監視をしている方は、監視機能を一時的にOFFにして下さい。", 115 + IDC_STATIC,7,7,138,85,SS_SUNKEN 116 + GROUPBOX "実行方法",IDC_STATIC,153,9,102,49 117 + CONTROL "全自動(入門者向け)(&A)",IDC_WORKTYPE1,"Button", 118 + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,160,23,86,10 119 + CONTROL "カスタム(上級者向け)(&C)",IDC_WORKTYPE2,"Button", 120 + BS_AUTORADIOBUTTON,160,38,90,10 121 + DEFPUSHBUTTON "開始",IDOK,156,71,49,21,WS_GROUP 122 + PUSHBUTTON "中止",IDCANCEL,208,71,47,21 123 +END 124 + 125 +IDD_VERCHECK DIALOG DISCARDABLE 0, 0, 183, 65 126 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 127 + WS_SYSMENU 128 +CAPTION "統合アーカイバDLL自動インストーラ" 129 +FONT 9, "MS Pゴシック" 130 +BEGIN 131 + DEFPUSHBUTTON "中止",IDCANCEL,66,44,50,14 132 + LTEXT "最新バージョンの情報を集めています…",IDC_MSG,7,10,169, 133 + 8 134 + CONTROL "Progress1",IDC_BAR,"msctls_progress32",PBS_SMOOTH | 135 + WS_BORDER,7,31,169,9 136 + RTEXT "",IDC_RESTTIME,73,19,103,9 137 +END 138 + 139 +IDD_CUSTOM1 DIALOG DISCARDABLE 0, 0, 263, 97 140 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 141 + WS_SYSMENU 142 +CAPTION "統合アーカイバDLL自動インストーラ" 143 +FONT 9, "MS Pゴシック" 144 +BEGIN 145 + GROUPBOX "&DLLをインストールするディレクトリ",IDC_STATIC,7,7,249, 146 + 35,WS_GROUP 147 + EDITTEXT IDC_DLLDIR,16,22,200,12,ES_AUTOHSCROLL 148 + PUSHBUTTON "指定(&R)...",IDC_REF,221,21,31,14 149 + GROUPBOX "接続先サーバ",IDC_STATIC,7,45,69,45 150 + CONTROL "&Madobe",IDC_CONNECTTO1,"Button",BS_AUTORADIOBUTTON | 151 + WS_GROUP | WS_TABSTOP,14,55,38,10 152 + CONTROL "C&SD Inc.",IDC_CONNECTTO2,"Button",BS_AUTORADIOBUTTON, 153 + 14,65,41,10 154 + CONTROL "&Wakusei",IDC_CONNECTTO3,"Button",BS_AUTORADIOBUTTON,14, 155 + 75,40,10 156 + PUSHBUTTON "&Proxy設定...",IDC_PROXY,82,54,57,14,WS_GROUP 157 + PUSHBUTTON "その他の設定(&E)...",IDC_DETAIL,82,73,57,14 158 + DEFPUSHBUTTON "次へ",IDOK,156,69,49,21,WS_GROUP 159 + PUSHBUTTON "中止",IDCANCEL,208,69,47,21 160 +END 161 + 162 +IDD_CUSTOM2 DIALOG DISCARDABLE 0, 0, 263, 99 163 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 164 + WS_SYSMENU 165 +CAPTION "統合アーカイバDLL自動インストーラ" 166 +FONT 9, "MS Pゴシック" 167 +BEGIN 168 + CONTROL "List1",IDC_UPDATELIST,"SysListView32",LVS_REPORT | 169 + LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER | 170 + WS_TABSTOP,7,7,144,85 171 + CONTROL "ダウンロードのみ(&D)",IDC_INSTMODE1,"Button", 172 + BS_AUTORADIOBUTTON,156,20,70,12 173 + CONTROL "インストール(書庫残さない)(&R)",IDC_INSTMODE2,"Button", 174 + BS_AUTORADIOBUTTON,156,33,99,10 175 + CONTROL "インストール(書庫残す)(&I)",IDC_INSTMODE3,"Button", 176 + BS_AUTORADIOBUTTON,156,46,90,10 177 + DEFPUSHBUTTON "実行",IDOK,156,71,49,21,WS_GROUP 178 + PUSHBUTTON "中止",IDCANCEL,208,71,47,21 179 +END 180 + 181 +IDD_INSTALL DIALOG DISCARDABLE 0, 0, 183, 65 182 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 183 + WS_SYSMENU 184 +CAPTION "統合アーカイバDLL自動インストーラ" 185 +FONT 9, "MS Pゴシック" 186 +BEGIN 187 + LTEXT "DLLをインストールしています…",IDC_STATIC,44,28,92,8 188 +END 189 + 190 +IDD_PROXY DIALOG DISCARDABLE 0, 0, 187, 79 191 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 192 +CAPTION "プロキシの設定" 193 +FONT 9, "MS Pゴシック" 194 +BEGIN 195 + CONTROL "プロキシを指定する(&P)",IDC_USEPROXY,"Button", 196 + BS_AUTOCHECKBOX | WS_TABSTOP,7,7,82,10 197 + LTEXT "ホスト名(&H)",IDC_HOST_N,23,24,34,8,WS_DISABLED 198 + EDITTEXT IDC_HOST,60,21,113,12,ES_AUTOHSCROLL | WS_DISABLED 199 + LTEXT "ポート番号(&T)",IDC_PORT_N,16,38,41,8,WS_DISABLED 200 + EDITTEXT IDC_PORT,60,36,41,12,ES_AUTOHSCROLL | ES_NUMBER | 201 + WS_DISABLED 202 + DEFPUSHBUTTON "OK",IDOK,73,58,50,14 203 + PUSHBUTTON "キャンセル",IDCANCEL,130,58,50,14 204 +END 205 + 206 +IDD_DETAIL DIALOG DISCARDABLE 0, 0, 251, 187 207 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 208 + WS_SYSMENU 209 +CAPTION "caldix詳細設定" 210 +FONT 9, "MS Pゴシック" 211 +BEGIN 212 + CONTROL "常時接続環境で利用(&F)",IDC_CONNECT_ALWAYS,"Button", 213 + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,7,9,86,10 214 + CONTROL "「カスタム」で指定したディレクトリを「全自動」でも使用する(&U)", 215 + IDC_SAVE_DESTDIR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7, 216 + 20,191,10 217 + CONTROL "終了時にcldxフォルダを開く(&O)",IDC_SHOW_README,"Button", 218 + BS_AUTOCHECKBOX | WS_TABSTOP,7,31,105,10 219 + GROUPBOX "フォルダを開くファイラー",IDC_STATIC,7,43,237,47 220 + EDITTEXT IDC_FILERPATH,12,55,194,12,ES_AUTOHSCROLL 221 + PUSHBUTTON "指定(&Q)...",IDC_REF,211,54,31,14 222 + LTEXT "オプション",IDC_STATIC,14,74,30,8 223 + LTEXT "前(&P):",IDC_STATIC,53,73,18,8 224 + EDITTEXT IDC_FILEROPT,79,71,40,12,ES_AUTOHSCROLL 225 + LTEXT "後ろ(&S):",IDC_STATIC,137,74,23,8 226 + EDITTEXT IDC_FILEROPT2,166,71,40,12,ES_AUTOHSCROLL 227 + GROUPBOX "チェック対象にするDLL",IDC_STATIC,7,93,234,62,WS_GROUP 228 + CONTROL "Un&lha32",IDC_DLHA,"Button",BS_AUTOCHECKBOX | 229 + WS_TABSTOP,14,104,35,10 230 + CONTROL "Un&Zip32",IDC_DUZP,"Button",BS_AUTOCHECKBOX | 231 + WS_TABSTOP,14,116,35,10 232 + CONTROL "Zi&p圧縮系",IDC_DZIP,"Button",BS_AUTOCHECKBOX | 233 + WS_TABSTOP,14,128,43,10 234 + CONTROL "&Cab32",IDC_DCAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 235 + 14,140,31,10 236 + CONTROL "&Tar32",IDC_DTAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 237 + 61,104,33,10 238 + CONTROL "&Rar解凍系",IDC_DRAR,"Button",BS_AUTOCHECKBOX | 239 + WS_TABSTOP,61,116,45,10 240 + CONTROL "Un&GCA32",IDC_DGCA,"Button",BS_AUTOCHECKBOX | 241 + WS_TABSTOP,61,128,45,10 242 + CONTROL "Un&arj32j",IDC_DARJ,"Button",BS_AUTOCHECKBOX | 243 + WS_TABSTOP,61,140,35,10 244 + CONTROL "&Yz1系",IDC_DYZ1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 245 + 109,104,35,10 246 + CONTROL "&Bga32",IDC_DBGA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 247 + 109,116,35,10 248 + CONTROL "&Jack32",IDC_DJCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 249 + 109,128,35,10 250 + CONTROL "Ais&h32",IDC_DAIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 251 + 109,140,35,10 252 + CONTROL "&Ish32",IDC_DISH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 253 + 151,103,35,10 254 + CONTROL "Unb&el32",IDC_DBEL,"Button",BS_AUTOCHECKBOX | 255 + WS_TABSTOP,151,115,35,10 256 + CONTROL "&7-zip32",IDC_D7ZP,"Button",BS_AUTOCHECKBOX | 257 + WS_TABSTOP,151,127,35,10 258 + CONTROL "UnI&mp32",IDC_DIMP,"Button",BS_AUTOCHECKBOX | 259 + WS_TABSTOP,151,140,35,10 260 + CONTROL "Bh&32",IDC_DBH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 261 + 195,103,35,10 262 + DEFPUSHBUTTON "OK",IDOK,140,159,49,21,WS_GROUP 263 + PUSHBUTTON "キャンセル",IDCANCEL,195,159,47,21 264 +END 265 + 266 + 267 +///////////////////////////////////////////////////////////////////////////// 268 +// 269 +// DESIGNINFO 270 +// 271 + 272 +#ifdef APSTUDIO_INVOKED 273 +GUIDELINES DESIGNINFO DISCARDABLE 274 +BEGIN 275 + IDD_START, DIALOG 276 + BEGIN 277 + LEFTMARGIN, 7 278 + RIGHTMARGIN, 256 279 + TOPMARGIN, 7 280 + BOTTOMMARGIN, 92 281 + END 282 + 283 + IDD_VERCHECK, DIALOG 284 + BEGIN 285 + LEFTMARGIN, 7 286 + RIGHTMARGIN, 176 287 + TOPMARGIN, 7 288 + BOTTOMMARGIN, 58 289 + END 290 + 291 + IDD_CUSTOM1, DIALOG 292 + BEGIN 293 + LEFTMARGIN, 7 294 + RIGHTMARGIN, 256 295 + TOPMARGIN, 7 296 + BOTTOMMARGIN, 90 297 + END 298 + 299 + IDD_CUSTOM2, DIALOG 300 + BEGIN 301 + LEFTMARGIN, 7 302 + RIGHTMARGIN, 255 303 + TOPMARGIN, 7 304 + BOTTOMMARGIN, 92 305 + END 306 + 307 + IDD_INSTALL, DIALOG 308 + BEGIN 309 + LEFTMARGIN, 7 310 + RIGHTMARGIN, 176 311 + TOPMARGIN, 7 312 + BOTTOMMARGIN, 58 313 + END 314 + 315 + IDD_PROXY, DIALOG 316 + BEGIN 317 + LEFTMARGIN, 7 318 + RIGHTMARGIN, 180 319 + TOPMARGIN, 7 320 + BOTTOMMARGIN, 72 321 + END 322 + 323 + IDD_DETAIL, DIALOG 324 + BEGIN 325 + LEFTMARGIN, 7 326 + RIGHTMARGIN, 244 327 + TOPMARGIN, 7 328 + BOTTOMMARGIN, 180 329 + END 330 +END 331 +#endif // APSTUDIO_INVOKED 332 + 333 + 334 +///////////////////////////////////////////////////////////////////////////// 335 +// 336 +// Icon 337 +// 338 + 339 +// Icon with lowest ID value placed first to ensure application icon 340 +// remains consistent on all systems. 341 +IDI_MAIN ICON DISCARDABLE "caldix.ico" 342 + 343 +///////////////////////////////////////////////////////////////////////////// 344 +// 345 +// String Table 346 +// 347 + 348 +STRINGTABLE DISCARDABLE 349 +BEGIN 350 + IDS_NOINTERNET "インターネットに接続できませんでした。終了します。" 351 + IDS_LV_DLLNAME "DLL名" 352 + IDS_LV_STATE "作業の種類" 353 + IDS_NONEED "全て最新版が入っています。バージョンアップの必要はありません。" 354 + IDS_FINISHED "インストールは無事終了しました。\n\nDLLの説明書は ""cldx"" フォルダに保存してあります。" 355 + IDS_NEWINST "新規導入" 356 + IDS_UPDINST "%sに更新" 357 + IDS_DOWNLOADING "%sをダウンロード中です。[%s]" 358 + IDS_REBOOT "作業を完了するために、Windowsを再起動する必要があります。今すぐ再起動してよろしいですか?(起動中のアプリケーションは保存終了して下さい。)" 359 + IDS_CANCELOK "DLLのインストールを中止してよろしいですか?" 360 + IDS_RASHANGUP "インターネットへの接続回線を切断しますか?" 361 + IDS_REST "残り %dKB (約%d分%02d秒)" 362 +END 363 + 364 +STRINGTABLE DISCARDABLE 365 +BEGIN 366 + IDS_DLERROR "ダウンロードに失敗しました。日をおいてからもう一度実行してみて下さい。" 367 +END 368 + 369 +#endif // 日本語 resources 370 +///////////////////////////////////////////////////////////////////////////// 371 + 372 + 373 +///////////////////////////////////////////////////////////////////////////// 374 +// 英語 (アメリカ) resources 375 + 376 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 377 +#ifdef _WIN32 378 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 379 +#pragma code_page(1252) 380 +#endif //_WIN32 381 + 382 +///////////////////////////////////////////////////////////////////////////// 383 +// 384 +// Dialog 385 +// 386 + 387 +IDD_CUSTOM1 DIALOG DISCARDABLE 0, 0, 263, 97 388 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 389 + WS_SYSMENU 390 +CAPTION "Common Archivers Library DLL Installer X" 391 +FONT 9, "MS Sans Serif" 392 +BEGIN 393 + GROUPBOX "&Directory to install DLL",IDC_STATIC,7,7,249,35, 394 + WS_GROUP 395 + EDITTEXT IDC_DLLDIR,16,22,205,12,ES_AUTOHSCROLL 396 + PUSHBUTTON "&Ref...",IDC_REF,226,21,24,14 397 + GROUPBOX "Update Info Server",IDC_STATIC,7,45,84,45 398 + CONTROL "&Madobe",IDC_CONNECTTO1,"Button",BS_AUTORADIOBUTTON | 399 + WS_GROUP | WS_TABSTOP,14,56,38,10 400 + CONTROL "C&SD Inc.",IDC_CONNECTTO2,"Button",BS_AUTORADIOBUTTON, 401 + 14,66,41,10 402 + CONTROL "&Wakusei",IDC_CONNECTTO3,"Button",BS_AUTORADIOBUTTON,14, 403 + 76,40,10 404 + PUSHBUTTON "&Proxy...",IDC_PROXY,100,75,49,14 405 + DEFPUSHBUTTON "Next",IDOK,156,69,49,21,WS_GROUP 406 + PUSHBUTTON "Cancel",IDCANCEL,208,69,47,21 407 +END 408 + 409 +IDD_CUSTOM2 DIALOG DISCARDABLE 0, 0, 263, 99 410 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 411 + WS_SYSMENU 412 +CAPTION "Common Archivers Library DLL Installer X" 413 +FONT 9, "MS Sans Serif" 414 +BEGIN 415 + CONTROL "List1",IDC_UPDATELIST,"SysListView32",LVS_REPORT | 416 + LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER | 417 + WS_TABSTOP,7,7,144,85 418 + DEFPUSHBUTTON "Start",IDOK,156,71,49,21,WS_GROUP 419 + PUSHBUTTON "Cancel",IDCANCEL,208,71,47,21 420 + CONTROL "&Download Only",IDC_INSTMODE1,"Button", 421 + BS_AUTORADIOBUTTON,159,18,93,10 422 + CONTROL "Install(&Remove Archive)",IDC_INSTMODE2,"Button", 423 + BS_AUTORADIOBUTTON,159,30,96,10 424 + CONTROL "&Install",IDC_INSTMODE3,"Button",BS_AUTORADIOBUTTON,159, 425 + 42,96,10 426 +END 427 + 428 +IDD_START DIALOG DISCARDABLE 0, 0, 263, 99 429 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 430 + WS_SYSMENU 431 +CAPTION "Common Archivers Library DLL Installer X" 432 +FONT 9, "MS Sans Serif" 433 +BEGIN 434 + LTEXT "You can automatically download and install ""Common Archiver DLLs"" from Internet by this software.\r\n\r\nPush 'Start' button to begin installation.", 435 + IDC_STATIC,7,7,138,85,SS_SUNKEN 436 + GROUPBOX "Install Type",IDC_STATIC,153,7,102,52 437 + CONTROL "Full &Automatic",IDC_WORKTYPE1,"Button", 438 + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,161,22,86,10 439 + CONTROL "&Custom",IDC_WORKTYPE2,"Button",BS_AUTORADIOBUTTON,161, 440 + 36,90,10 441 + DEFPUSHBUTTON "Start",IDOK,156,71,49,21,WS_GROUP 442 + PUSHBUTTON "Cancel",IDCANCEL,208,71,47,21 443 +END 444 + 445 +IDD_VERCHECK DIALOG DISCARDABLE 0, 0, 183, 65 446 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 447 + WS_SYSMENU 448 +CAPTION "Common Archivers Library DLL Installer X" 449 +FONT 9, "MS Sans Serif" 450 +BEGIN 451 + DEFPUSHBUTTON "Cancel",IDCANCEL,66,44,50,14 452 + LTEXT "Collecting the latest information...",IDC_MSG,7,10,162, 453 + 8 454 + CONTROL "Progress1",IDC_BAR,"msctls_progress32",PBS_SMOOTH | 455 + WS_BORDER,7,26,169,9 456 +END 457 + 458 +IDD_INSTALL DIALOG DISCARDABLE 0, 0, 183, 65 459 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 460 + WS_SYSMENU 461 +CAPTION "Common Archivers Library DLL Installer X" 462 +FONT 9, "MS Sans Serif" 463 +BEGIN 464 + CTEXT "Installing DLLs...",IDC_STATIC,27,28,124,8 465 +END 466 + 467 +IDD_PROXY DIALOG DISCARDABLE 0, 0, 187, 79 468 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 469 +CAPTION "Proxy" 470 +FONT 9, "MS Sans Serif" 471 +BEGIN 472 + CONTROL "Use &Proxy",IDC_USEPROXY,"Button",BS_AUTOCHECKBOX | 473 + WS_TABSTOP,7,7,165,10 474 + LTEXT "&Host",IDC_HOST_N,23,24,15,8,WS_DISABLED 475 + EDITTEXT IDC_HOST,42,21,129,12,ES_AUTOHSCROLL | WS_DISABLED 476 + LTEXT "Por&t",IDC_PORT_N,24,38,13,8,WS_DISABLED 477 + EDITTEXT IDC_PORT,42,36,41,12,ES_AUTOHSCROLL | ES_NUMBER | 478 + WS_DISABLED 479 + DEFPUSHBUTTON "OK",IDOK,73,58,50,14 480 + PUSHBUTTON "Cancel",IDCANCEL,130,58,50,14 481 +END 482 + 483 + 484 +///////////////////////////////////////////////////////////////////////////// 485 +// 486 +// DESIGNINFO 487 +// 488 + 489 +#ifdef APSTUDIO_INVOKED 490 +GUIDELINES DESIGNINFO DISCARDABLE 491 +BEGIN 492 + IDD_CUSTOM1, DIALOG 493 + BEGIN 494 + LEFTMARGIN, 7 495 + RIGHTMARGIN, 256 496 + TOPMARGIN, 7 497 + BOTTOMMARGIN, 90 498 + END 499 + 500 + IDD_CUSTOM2, DIALOG 501 + BEGIN 502 + LEFTMARGIN, 7 503 + RIGHTMARGIN, 256 504 + TOPMARGIN, 7 505 + BOTTOMMARGIN, 92 506 + END 507 + 508 + IDD_START, DIALOG 509 + BEGIN 510 + LEFTMARGIN, 7 511 + RIGHTMARGIN, 256 512 + TOPMARGIN, 7 513 + BOTTOMMARGIN, 92 514 + END 515 + 516 + IDD_VERCHECK, DIALOG 517 + BEGIN 518 + LEFTMARGIN, 7 519 + RIGHTMARGIN, 176 520 + TOPMARGIN, 7 521 + BOTTOMMARGIN, 58 522 + END 523 + 524 + IDD_INSTALL, DIALOG 525 + BEGIN 526 + LEFTMARGIN, 7 527 + RIGHTMARGIN, 176 528 + TOPMARGIN, 7 529 + BOTTOMMARGIN, 58 530 + END 531 + 532 + IDD_PROXY, DIALOG 533 + BEGIN 534 + LEFTMARGIN, 7 535 + RIGHTMARGIN, 180 536 + TOPMARGIN, 7 537 + BOTTOMMARGIN, 72 538 + END 539 +END 540 +#endif // APSTUDIO_INVOKED 541 + 542 + 543 +///////////////////////////////////////////////////////////////////////////// 544 +// 545 +// String Table 546 +// 547 + 548 +STRINGTABLE DISCARDABLE 549 +BEGIN 550 + IDS_NOINTERNET "Couldn't connect to network." 551 + IDS_LV_DLLNAME "Name" 552 + IDS_LV_STATE "State" 553 + IDS_NONEED "You already have the latest version DLLs. No need to update." 554 + IDS_FINISHED "Installation finished. Document of each DLL is in 'cldx' folder." 555 + IDS_NEWINST "New" 556 + IDS_UPDINST "%s is avail." 557 + IDS_DOWNLOADING "Downloading %s ... [%s]" 558 + IDS_REBOOT "You should reboot Windows to finish installation. Are you ready to reboot ?" 559 + IDS_CANCELOK "Do you want to abort the installation ?" 560 + IDS_RASHANGUP "Do you want to Hang up the dial-up connection ?" 561 + IDS_REST "Rest %d KB (%d'%02d)" 562 +END 563 + 564 +STRINGTABLE DISCARDABLE 565 +BEGIN 566 + IDS_DLERROR "Download error !" 567 +END 568 + 569 +#endif // 英語 (アメリカ) resources 570 +///////////////////////////////////////////////////////////////////////////// 571 + 572 + 573 + 574 +#ifndef APSTUDIO_INVOKED 575 +///////////////////////////////////////////////////////////////////////////// 576 +// 577 +// Generated from the TEXTINCLUDE 3 resource. 578 +// 579 + 580 + 581 +///////////////////////////////////////////////////////////////////////////// 582 +#endif // not APSTUDIO_INVOKED 583 +
Added LzhDecoder2.cpp version [449e48789d18c169]
1 + 2 +#include "stdafx.h" 3 +#include "LzhDecoder2.h" 4 + 5 +void CLzhDecoder2::Unstore() 6 +{ 7 +#define UNS_BUFSIZE (32768) 8 + int how_much; 9 + char buf[UNS_BUFSIZE]; 10 + 11 + if( cmpsize==-1 ) 12 + { 13 + while( (how_much=fread(buf,1,UNS_BUFSIZE,in))!=0 ) 14 + { 15 + if( how_much==-1 ) 16 + break; 17 + fwrite(buf,1,how_much,out); 18 + } 19 + return; 20 + } 21 + 22 + while( cmpsize>0 ) 23 + { 24 + how_much = cmpsize>UNS_BUFSIZE?UNS_BUFSIZE:cmpsize; 25 + if( 0>=(how_much=fread( buf,1,how_much,in )) ) 26 + break; 27 + fwrite( buf,1,how_much,out ); 28 + cmpsize -= how_much; 29 + } 30 +} 31 + 32 +void CLzhDecoder2::Decode( lzh_method mhd,FILE* infile,DWORD insize, 33 + FILE* outfile,DWORD outsize ) 34 +{ 35 + in = infile; 36 + cmpsize = insize; 37 + out = outfile; 38 + orisize = outsize; 39 + 40 + DWORD dicsiz,dicbit; 41 + 42 + // メソッドによっていろいろ切り替え 43 + switch( mhd ) 44 + { 45 + case LH0:Unstore(); return; 46 + default: return; 47 + 48 + case LH4: np=14,pbit=4,dicbit=12,dicsiz=(1<<dicbit);break; 49 + case LH5: np=14,pbit=4,dicbit=13,dicsiz=(1<<dicbit);break; 50 + case LH6: np=16,pbit=5,dicbit=15,dicsiz=(1<<dicbit);break; 51 + case LH7: np=17,pbit=5,dicbit=16,dicsiz=(1<<dicbit);break; 52 + } 53 + 54 + BYTE* text = new BYTE[dicsiz]; 55 + memset( text,' ',dicsiz ); 56 + 57 + init_getbits(); 58 + blocksize = 0; 59 + 60 + // デコード 61 + DWORD count=0; 62 + loc=0; 63 + int offset=(0x0100-3); 64 + while( count<orisize ) 65 + { 66 + int c = Decode_C(mhd); 67 + 68 + if( c<=255 ) 69 + { 70 + text[loc++] = c; 71 + if( loc==dicsiz ) 72 + { 73 + fwrite(text,1,dicsiz,out); 74 + loc = 0; 75 + } 76 + count++; 77 + } 78 + else 79 + { 80 + int j = c - offset; 81 + count += j; 82 + int i = Decode_P(mhd); 83 + if( (i=loc-i-1)<0 ) 84 + i += dicsiz; 85 + 86 + for( int k=0; k<j; k++ ) 87 + { 88 + text[loc++] = text[i]; 89 + if( loc>=dicsiz ) 90 + { 91 + fwrite( text,1,dicsiz,out ); 92 + loc = 0; 93 + } 94 + if( ++i>=(int)dicsiz ) 95 + i = 0; 96 + } 97 + } 98 + } 99 + 100 + if( loc!=0 ) 101 + fwrite( text,1,loc,out ); 102 + 103 + delete [] text; 104 +} 105 + 106 +/**************** LH4-7,ARJ,ZOO ************************/ 107 + 108 +void CLzhDecoder2::make_table(WORD nchar,BYTE* bitlen, 109 + WORD tablebits,WORD* table) 110 +{ 111 + WORD count[17],weight[17],start[17],total,*p; 112 + unsigned int i; 113 + int j,k,l,m,n,avail; 114 + 115 + avail = nchar; 116 + 117 + for( i=1; i<=16; i++ ) 118 + { 119 + count[i] = 0; 120 + weight[i] = 1 << (16 - i); 121 + } 122 + 123 + for( i=0; i<nchar; i++ ) 124 + count[bitlen[i]]++; 125 + 126 + total = 0; 127 + for( i=1; i<=16; i++ ) 128 + { 129 + start[i] = total; 130 + total += weight[i] * count[i]; 131 + } 132 + if( (total & 0xffff) != 0 ) 133 + return;//error("Bad table (5)\n"); 134 + 135 + m = 16 - tablebits; 136 + for( i=1; i<=tablebits; i++ ) 137 + { 138 + start[i] >>= m; 139 + weight[i] >>= m; 140 + } 141 + 142 + j = start[tablebits + 1] >> m; 143 + k = 1 << tablebits; 144 + if( j!=0 ) 145 + for( i=j; i<(unsigned)k; i++ ) 146 + table[i] = 0; 147 + 148 + for( j=0; j<nchar; j++ ) 149 + { 150 + k = bitlen[j]; 151 + if( k==0 ) 152 + continue; 153 + l = start[k] + weight[k]; 154 + if( k<=tablebits ) 155 + { 156 + for( i=start[k]; i<(unsigned)l; i++ ) 157 + table[i] = j; 158 + } 159 + else 160 + { 161 + p = &table[(i = start[k]) >> m]; 162 + i <<= tablebits; 163 + n = k - tablebits; 164 + while (--n >= 0) 165 + { 166 + if (*p == 0) 167 + { 168 + right[avail] = left[avail] = 0; 169 + *p = avail++; 170 + } 171 + if (i & 0x8000) 172 + p = &right[*p]; 173 + else 174 + p = &left[*p]; 175 + i <<= 1; 176 + } 177 + *p = j; 178 + } 179 + start[k] = l; 180 + } 181 +} 182 + 183 +void CLzhDecoder2::read_pt_len(short nn,short nbit,short i_special) 184 +{ 185 + short i, c, n=getbits((BYTE)nbit); 186 + 187 + if( n==0 ) 188 + { 189 + c = getbits((BYTE)nbit); 190 + for( i=0; i<nn; i++ ) pt_len[i] = 0; 191 + for( i=0; i<256; i++ ) pt_table[i] = c; 192 + } 193 + else 194 + { 195 + short i = 0; 196 + while( i<n ) 197 + { 198 + c = bitbuf >> (16-3); 199 + if( c==7 ) 200 + { 201 + WORD mask = 1<<(16-4); 202 + while( mask&bitbuf ) 203 + { 204 + mask >>= 1; 205 + c++; 206 + } 207 + } 208 + fillbuf( (c<7) ? 3 : c-3 ); 209 + pt_len[i++] = (BYTE)c; 210 + if( i==i_special ) 211 + { 212 + c = getbits(2); 213 + while( --c>=0 ) 214 + pt_len[i++] = 0; 215 + } 216 + } 217 + while( i<nn ) 218 + pt_len[i++] = 0; 219 + make_table(nn,pt_len,8,pt_table); 220 + } 221 +} 222 + 223 +void CLzhDecoder2::read_c_len() 224 +{ 225 + short i, c, n=getbits(CBIT); 226 + 227 + if( n==0 ) 228 + { 229 + c = getbits(CBIT); 230 + for( i=0; i<NC; i++ ) c_len[i] = 0; 231 + for( i=0; i<4096; i++ ) c_table[i] = c; 232 + } 233 + else 234 + { 235 + short i = 0; 236 + while( i<n ) 237 + { 238 + c = pt_table[ bitbuf>>(16-8) ]; 239 + if( c>=NT ) 240 + { 241 + WORD mask = 1<<(16-9); 242 + do 243 + { 244 + if( bitbuf&mask )c = right[c]; 245 + else c = left[c]; 246 + mask >>= 1; 247 + }while( c>=NT ); 248 + } 249 + fillbuf(pt_len[c]); 250 + if( c<=2 ) 251 + { 252 + if( c==0 ) c = 1; 253 + else if( c==1 ) c = getbits(4) + 3; 254 + else c = getbits(CBIT) + 20; 255 + while( --c>=0 ) 256 + c_len[i++] = 0; 257 + } 258 + else 259 + c_len[i++] = c-2; 260 + } 261 + while( i<NC ) 262 + c_len[i++]=0; 263 + make_table(NC,c_len,12,c_table); 264 + } 265 +} 266 + 267 +WORD CLzhDecoder2::decode_c_st1() 268 +{ 269 + WORD j,mask; 270 + 271 + if( blocksize==0 ) 272 + { 273 + blocksize = getbits(16); 274 + read_pt_len(NT,TBIT,3); 275 + read_c_len(); 276 + read_pt_len(np,pbit,-1); 277 + } 278 + blocksize--; 279 + j = c_table[ bitbuf>>4 ]; 280 + if( j<NC ) 281 + fillbuf(c_len[j]); 282 + else 283 + { 284 + fillbuf(12); 285 + mask = 1 << (16-1); 286 + do 287 + { 288 + if( bitbuf&mask ) j = right[j]; 289 + else j = left[j]; 290 + mask >>= 1; 291 + }while( j>=NC ); 292 + fillbuf( c_len[j]-12 ); 293 + } 294 + return j; 295 +} 296 + 297 +WORD CLzhDecoder2::decode_p_st1() 298 +{ 299 + WORD j, mask; 300 + 301 + j = pt_table[ bitbuf>>(16-8) ]; 302 + if( j<np ) 303 + fillbuf(pt_len[j]); 304 + else 305 + { 306 + fillbuf(8); 307 + mask = 1 << (16-1); 308 + do 309 + { 310 + if( bitbuf&mask ) j = right[j]; 311 + else j = left[j]; 312 + mask >>= 1; 313 + }while( j>=np ); 314 + fillbuf(pt_len[j] - 8); 315 + } 316 + if( j!=0 ) 317 + j = (1<<(j-1)) + getbits(j-1); 318 + return j; 319 +} 320 + 321 + 322 +/******************** bit単位のread&write ************************/ 323 + 324 +void CLzhDecoder2::init_getbits() 325 +{ 326 + bitbuf = 0; 327 + subbitbuf = 0; 328 + bitcount = 0; 329 + fillbuf(16); 330 +} 331 + 332 +void CLzhDecoder2::fillbuf(BYTE n) 333 +{ 334 + while( n>bitcount ) 335 + { 336 + n -= bitcount; 337 + bitbuf = (bitbuf<<bitcount) + (subbitbuf>>(8-bitcount)); 338 + if( cmpsize!=0 ) 339 + { 340 + cmpsize--; 341 + subbitbuf = (BYTE)getc(in); 342 + } 343 + else 344 + subbitbuf = 0; 345 + bitcount = 8; 346 + } 347 + bitcount -= n; 348 + bitbuf = (bitbuf<<n) + (subbitbuf>>(8-n)); 349 + subbitbuf <<= n; 350 +} 351 + 352 +WORD CLzhDecoder2::getbits(BYTE n) 353 +{ 354 + WORD x = bitbuf>>(16-n); 355 + fillbuf(n); 356 + return x; 357 +}
Added LzhDecoder2.h version [3b0fe0be3dd0a1e5]
1 +#ifndef AFX_LZHDECODER2_H__31F8AA04_3F84_11D4_8D96_8AB5A6462337__INCLUDED_ 2 +#define AFX_LZHDECODER2_H__31F8AA04_3F84_11D4_8D96_8AB5A6462337__INCLUDED_ 3 + 4 +#define MAXMATCH 256 5 +#define THRESHOLD 3 6 + 7 +#define NT (16+3) 8 +#define TBIT 5 9 +#define CBIT 9 10 +#define NC (255+MAXMATCH+2-THRESHOLD) 11 +#define NPT 0x80 12 + 13 +#define N_CHAR (256+60-THRESHOLD+1) 14 +#define TREESIZE_C (N_CHAR*2) 15 +#define TREESIZE_P (128*2) 16 +#define TREESIZE (TREESIZE_C+TREESIZE_P) 17 +#define ROOT_C 0 18 +#define ROOT_P TREESIZE_C 19 + 20 +enum lzh_method{ LH0,LH4,LH5,LH6,LH7,UNKNOWN }; 21 + 22 +class CLzhDecoder2 23 +{ 24 +public: 25 + void Decode( lzh_method mhd,FILE* infile,DWORD insize, 26 + FILE* outfile,DWORD outsize ); 27 + 28 +private: 29 + void Unstore(); 30 + WORD Decode_C(lzh_method mhd) 31 + {switch( mhd ){ 32 + case LH4: 33 + case LH5: 34 + case LH6: 35 + case LH7:return decode_c_st1(); 36 + }return 0;}; 37 + WORD Decode_P(lzh_method mhd) 38 + {switch( mhd ){ 39 + case LH4: 40 + case LH5: 41 + case LH6: 42 + case LH7:return decode_p_st1(); 43 + }return 0;}; 44 + 45 +private: 46 + // 全般的に 47 + FILE *in,*out; 48 + DWORD cmpsize,orisize; 49 + 50 + DWORD loc; 51 + 52 + // lh4-lh7 53 + void make_table(WORD nchar,BYTE* bitlen,WORD tablebits,WORD* table); 54 + void read_pt_len(short nn,short nbit,short i_special); 55 + void read_c_len(); 56 + WORD decode_c_st1(); 57 + WORD decode_p_st1(); 58 + 59 + WORD left[ 2*NC-1 ], right[ 2*NC-1 ]; 60 + BYTE c_len[NC], pt_len[NPT]; 61 + WORD c_table[4096],pt_table[256]; 62 + 63 + WORD blocksize; 64 + int pbit; 65 + int np; 66 + 67 + // bit単位のread&write 68 + void init_getbits(); 69 + void fillbuf(BYTE n); 70 + WORD getbits(BYTE n); 71 + WORD bitbuf;BYTE subbitbuf,bitcount; 72 +}; 73 + 74 +#endif
Added LzhTool.cpp version [4a1f472039c28674]
1 + 2 +#include "stdafx.h" 3 +#include "LzhTool.h" 4 +#include "LzhDecoder2.h" 5 +#include "kiutil.h" 6 +#include "kilib/kilib.h" 7 + 8 +bool CLzhTool::crcinit; 9 +unsigned short CLzhTool::crctable[256]; 10 + 11 +bool CLzhTool::Extract( const char* aname, const char* dll, kiPath& dll_rel_path ) 12 +{ 13 + // 先頭の方を読み込み 14 + FILE* fp = fopen( aname,"rb" ); 15 + if( !fp ) 16 + return false; 17 + unsigned char* buff = new unsigned char[65536]; 18 + DWORD siz = fread( buff, 1, 65536, fp ); 19 + fclose( fp ); 20 + // ヘッダを探す 21 + int ps = FindHeader( aname,buff,siz ); 22 + // 書庫を開く 23 + if( ps==-1 || !(lzh = fopen( aname,"rb" )) ) 24 + { 25 + delete [] buff; 26 + return false; 27 + } 28 + 29 + fseek( lzh,ps,SEEK_SET ); 30 + 31 + // 格納ファイル毎に処理 32 + while( ReadHeader( buff ) ) 33 + { 34 + long base = ftell( lzh ); 35 + char* name; 36 + 37 + if( h_FileName[0]!='!' && h_FileName[0]!='$' && h_FileName[0]!='%' ) 38 + if( out=fopen( name=kiutil::pathMake(h_FileName),"wb" ) ) 39 + { 40 + if( 0==strcmpi( kiPath::name(name), dll ) ) // DLLの位置を記憶 41 + dll_rel_path = name; 42 + 43 + // デコード 44 + CLzhDecoder2 dec; 45 + lzh_method mhd = UNKNOWN; 46 + if( 0==strcmp(h_Method,"-lh0-") )mhd=LH0; 47 + else if( 0==strcmp(h_Method,"-lh5-") )mhd=LH5; 48 + else if( 0==strcmp(h_Method,"-lh6-") )mhd=LH6; 49 + else if( 0==strcmp(h_Method,"-lh7-") )mhd=LH7; 50 + dec.Decode( mhd, lzh, h_CompSize, out, h_OrigSize ); 51 + 52 + // 属性など設定 53 + fclose( out ); 54 + 55 + SetFileAttributes( name,h_Attrib ); 56 + if( h_Level<2 ) 57 + kiutil::timeSet( name, (WORD)(h_Update>>16),(WORD)h_Update ); 58 + else 59 + kiutil::timeSet( name, h_Update ); 60 + } 61 + 62 + fseek( lzh, base+h_CompSize, SEEK_SET ); 63 + } 64 + 65 + delete [] buff; 66 + fclose( lzh ); 67 + return true; 68 +} 69 + 70 +int CLzhTool::FindHeader( const char* fname, const BYTE* hdr, DWORD siz ) 71 +{ 72 + bool bopen = false; 73 + BYTE* temp; 74 + int ans=-1; 75 + 76 + for( DWORD i=0; i<siz-20; i++ ) 77 + { 78 + if( hdr[i+2]=='-' && hdr[i+3]=='l' && 79 + (hdr[i+4]=='h' || hdr[i+4]=='z') ) 80 + { 81 + if( !bopen ) 82 + if( !(lzh=fopen( fname,"rb" )) ) 83 + return -1; 84 + else 85 + bopen=true, temp = new BYTE[65536]; 86 + 87 + fseek( lzh,i,SEEK_SET ); 88 + if( ReadHeader(temp) ) 89 + {ans=(signed)i;break;} 90 + } 91 + } 92 + 93 + if( bopen ) 94 + {delete [] temp;fclose( lzh );} 95 + return ans; 96 +} 97 + 98 +bool CLzhTool::ReadHeader( unsigned char* buf ) 99 +{ 100 +// 初期化 101 + *h_FileName=0; 102 + sum=0,crc=0; 103 + 104 +// だいたい共通な部分 105 +// 106 +// 0- 1: [0]=header_size [1]=check_sum (h0) 107 +// [0]=bas_hdr_siz [1]=check_sum (h1) 108 +// [WORD] = all_header_size (h2) 109 +// 110 +// 2- 6: method 111 +// 112 +// 7-10: [DWORD]=compressed_size (h0/h2) 113 +// [DWORD]=offset_to_next_hdr (h1) 114 +// 115 +// 11-14: [DWORD]=original_size 116 +// 117 +// 15-18: [ftime]=update_date_time 118 +// 119 +// 19: attribute (h0) 120 +// 0x20 (h1/h2) 121 +// 122 +// 20: header_level 123 +// 124 + if( 21!=fread_crc(buf,21) ) 125 + return false; 126 + sum-=(buf[0]+buf[1]); 127 + 128 + if( (h_Level=buf[20])>2 ) // LV3以上未対応 129 + return false; 130 + 131 + BYTE bshdr = (h_Level==2)?26:buf[0]+2; 132 + if( bshdr<21 || buf[0]==0 ) 133 + return false; 134 + BYTE hdrsum= buf[1]; 135 + for( int i=0; i!=5; i++ ) 136 + h_Method[i]=(char)buf[2+i];h_Method[5]=0; 137 + h_CompSize = (buf[ 7])+(buf[ 8]<<8)+(buf[ 9]<<16)+(buf[10]<<24); 138 + h_OrigSize = (buf[11])+(buf[12]<<8)+(buf[13]<<16)+(buf[14]<<24); 139 + h_Update = (buf[15])+(buf[16]<<8)+(buf[17]<<16)+(buf[18]<<24); 140 + h_Attrib = buf[19]; 141 + if( h_Method[0]!='-' || h_Method[1]!='l' ) 142 + return false; 143 + 144 +// レベル共通じゃない基本ヘッダ部分 145 +// <h0> 146 +// 21: file_name_length 147 +// 22- n: file_name ( with path info ) 148 +// WORD: crc16_of_file 149 +// : and some extension part 150 +// 151 +// <h1> 152 +// 21: file_name_length 153 +// 22- n: file_name ( with no path info ) 154 +// WORD: crc16_of_file 155 +// BYTE: os_flag 156 +// : and some extension part 157 +// 158 +// <h2> 159 +// WORD: crc16_of_file 160 +// BYTE: os_flag 161 +// 162 +// 163 + if( (bshdr-21)!=fread_crc(buf+21,(bshdr-21)) ) 164 + return false; 165 + if( h_Level!=2 ) 166 + { 167 + if( sum!=hdrsum || 21+1+buf[21]+2>bshdr ) 168 + return false; 169 + memcpy( h_FileName,buf+22,buf[21] ); 170 + h_FileName[buf[21]]=0; 171 + } 172 + 173 +// 拡張ヘッダ( h1/h2 ) 174 +// repeating of such blocks. 175 +//------------------------------------------------------ 176 +// WORD: size_of_this_block ( if 0 then end_of_header ) 177 +// BYTE: type_flag 178 +// : data ( (blocksize-3) bytes ) 179 +//------------------------------------------------------ 180 + 181 + char PathName[MAX_PATH*2]={0}; 182 + if( h_Level!=0 ) 183 + { 184 + DWORD hdrcrc=0xffffffff; 185 + WORD tmpcrc; 186 + 187 + // ここでループって拡張ヘッダ読み込み 188 + WORD ehs; 189 + ehs = ((buf[bshdr-2])|(buf[bshdr-1]<<8)); 190 + 191 + while( ehs>2 ) 192 + { 193 + tmpcrc=crc;//CRC自身を読み込んだときに直すため 194 + if( ehs!=fread_crc(buf,ehs) ) 195 + return false; 196 + if( h_Level==1 ) 197 + h_CompSize-=ehs; 198 + 199 + switch( *buf ) 200 + { 201 + case 0x00://共通 202 + if( ehs>=5 && hdrcrc==0xffffffff ) 203 + { 204 + hdrcrc=((buf[1])|(buf[2]<<8)); 205 + 206 + crc=tmpcrc; 207 + buf[1]=buf[2]=0; 208 + UpdateCRC(buf,ehs); 209 + } 210 + break; 211 + case 0x01://ファイル名 212 + memcpy(h_FileName,buf+1,ehs-3>MAX_PATH?MAX_PATH:ehs-3); 213 + h_FileName[ehs-3>MAX_PATH?MAX_PATH:ehs-3]=0; 214 + break; 215 + case 0x02://パス名 216 + memcpy(PathName,buf+1,ehs-3>MAX_PATH?MAX_PATH:ehs-3); 217 + PathName[ehs-3>MAX_PATH?MAX_PATH:ehs-3]=0; 218 + break; 219 + case 0xff://新属性 220 + break; 221 + case 0x40://属性(DOS依存) 222 + if( ehs>=5 ) 223 + h_Attrib=((buf[1])|(buf[2]<<8)); 224 + break; 225 + case 0x41://タイムスタンプ(UNLHA32.DLL) 226 + //は、なんだかうまくいかないので無視する。 227 + break; 228 + } 229 + 230 + ehs = ((buf[ehs-2])|(buf[ehs-1]<<8)); 231 + } 232 + 233 + if( hdrcrc!=0xffffffff && crc!=hdrcrc ) 234 + return false; 235 + } 236 + 237 + // ff -> \\ 変換 238 + char* x; 239 + for( x=h_FileName; *x!=0; x=CharNext(x) ) 240 + if( (BYTE)*x==0xff ) 241 + *x='\\'; 242 + for( x=PathName; *x!=0; x=CharNext(x) ) 243 + if( (BYTE)*x==0xff ) 244 + *x='\\'; 245 + strcat( PathName,h_FileName ); 246 + strcpy( h_FileName,PathName ); 247 + return true; 248 + 249 +// lha header MEMO 250 +// (h0/h1) 251 +// 1 byte 目は、「1byte目自身を除いた基本ヘッダのサイズ」 252 +// チェックサムは、「1,2byte目自身を除いた基本ヘッダの合計」 253 +// (h1) 254 +// offset_to_next_hdr は、基本ヘッダ末端から次のヘッダへの距離 255 +// (h1/h2) 256 +// crcは自分自身は0000として他全部から算出 257 +}
Added LzhTool.h version [b09630e0fb2982da]
1 +#ifndef AFX_LZHTOOL_H__31F8AA01_3F84_11D4_8D96_8AB5A6462337__INCLUDED_ 2 +#define AFX_LZHTOOL_H__31F8AA01_3F84_11D4_8D96_8AB5A6462337__INCLUDED_ 3 + 4 +// Lzh Archive Extraction ... ( XacRett #39 SubSet ) 5 + 6 +class CLzhTool 7 +{ 8 +public: 9 + //-- 外向きインターフェイス -------------- 10 + bool Extract( const char* aname, const char* dll, kiPath& dll_rel_path ); 11 + 12 +public: 13 + //-- CRC 計算 --------------------------- 14 + static bool crcinit; 15 + static unsigned short crctable[256]; 16 + static void init_crc_table(){ 17 + if( !crcinit ) 18 + for( unsigned short i=0,j,r; i!=256; i++ ) 19 + { 20 + r = i; 21 + for( j=0; j!=8; j++ ) 22 + { 23 + if( r&1 ) r = ((r>>1)^0xA001); 24 + else r>>=1; 25 + } 26 + crctable[i] = r; 27 + }} 28 + CLzhTool() { init_crc_table(); } 29 + 30 +private: 31 + //-- 内部処理 32 + int FindHeader( const char* fname, const BYTE* hdr, DWORD siz ); 33 + bool ReadHeader( unsigned char* buf ); 34 + 35 + WORD crc; 36 + BYTE sum; 37 + void UpdateCRC( BYTE *p,int n ) 38 + {while( n-- )crc = crctable[(crc^(*p++))&0xff] ^ (crc >> 8);} 39 + void UpdateSum( BYTE *p,int n ) 40 + {while( n-- )sum+=*(p++);} 41 + int fread_crc( BYTE* p,int n) 42 + {n=fread(p,1,n,lzh);if(n==-1)n=0; 43 + UpdateCRC(p,n);UpdateSum(p,n);return n;} 44 + 45 + FILE *lzh,*out; 46 + BYTE h_Level; // ヘッダレベル 47 + char h_FileName[MAX_PATH*2]; // ファイル名(パス付き) 48 + char h_Method[6]; // 圧縮法 "-lh5-" など。 49 + DWORD h_CompSize; // 圧縮されたサイズ 50 + DWORD h_OrigSize; // 元のサイズ 51 + WORD h_Attrib; // 属性 52 + DWORD h_Update; // 更新日時(h0,h1:ftime h2:time_t) 53 +}; 54 + 55 +#endif
Added ReadMe.txt version [a8fe65ab6366a4e0]
1 + 2 +★ caldix 1.21 について色々 3 +★ 2010/11/25 4 + 5 + 6 + 7 +【ダウンロード対象とするDLLを減らす方法】 8 + 9 + caldix.iniファイルを用意し、以下のような3行を書いてください。 10 + 11 + [conf] 12 + Ver=121 13 + DLLList=LZzCTARBJGbaIY7iH 14 + 15 + DLLList= の右側の各文字が、対象とするDLLを表しています。 16 + L : Unlha32 17 + Z : UnZip32 18 + z : Zip32j Zip32 sfx32gui.dat (zip圧縮系) 19 + C : Cab32 20 + T : Tar32 21 + A : Unarj32j 22 + R : Unrar32 Unrar (rar解凍系) 23 + B : Bga32 24 + J : Jack32 25 + G : UnGCA32 26 + b : Unbel32 27 + a : Aish32 28 + I : Ish32 29 + Y : Yz1 30 + 7 : 7-zip32 31 + i : Unimp32 32 + H : Bh32 33 + 以上の通りです。例えばUnlhaとUnzipだけで十分なら、 34 + 35 + [conf] 36 + Ver=121 37 + DLLList=LZ 38 + 39 + と書けばよいわけです。 40 + 使わないDLLは無視するようにして作業時間を短縮したい方や、 41 + 他のソフトのバンドル用として使うために、非対応DLLは 42 + 落とさなくても良い、という場合にご利用下さい。 43 + 44 + 1.10までのバージョンと比べて、Ver= という行が増えていることに 45 + 注意して下さい。古いバージョンのcaldixから自動生成されたcaldix.iniには 46 + 新しいDLLである7-zip32.dll対応用の"7"が含まれていないため、そのまま 47 + 1.11に移行しても7-zipを認識しないという悲しい状況になってしまうため、 48 + 急遽付け足したフラグがこの Ver= です。えーと要するに私K.INABAの 49 + 設計ミスとも言います。 50 + 51 + 動作としては、Ver=111 (以上)が入っていないと、"7" が無くても 52 + 7-zip32.dllをダウンロードしてしまう、という違いになります。 53 + 54 + 55 + 56 +【ソースについて】 57 + 58 + Visual C++ 6.0 用です。笑っちゃうような適当なコードが 59 + 散見されますので、参考にしようと思った方はたぶん失望します。 60 + 61 + Special Thanks! 62 + 63 + T.Matsumoto 氏による caldixF Version 1.16 の改善点を 64 + caldix/1.17 へ取り込みました。感謝します。 65 + -- http://tmsoft.webhop.net/caldix/ 66 + 67 + caldix::askRasHangUp() は、曽田氏作の FFFTP を参考にしています。 68 + -- http://www2.biglobe.ne.jp/~sota/ 69 + 70 + 認証の必要なProxyに対応できるようになるソースを、 71 + ユーザーの川崎氏にご教授いただきました。ありがとうございます。 72 + 73 + zip展開部分に zlib 1.1.3 を使用しています。 74 + (C) 1995-1998 Jean-loup Gailly and Mark Adler 75 + -- http://www.info-zip.org/pub/infozip/zlib/ 76 + 77 + lzh展開部分に LHa for unix のソースを利用しています。 78 + -- http://www2m.biglobe.ne.jp/~dolphin/lha/lha-unix.htm 79 + 80 + cab展開部分に Microsoft社 の CabinetSDK を使用しています。 81 + 82 + ! caldixをビルドするには、fdi ディレクトリに fdi.lib と fdi.h を 83 + ! 入れておいてください。Platform SDK から入手できます。 84 + -- http://www.microsoft.com/msdownload/platformsdk/sdkupdate/ 85 + 86 + 87 + 88 +【利用条件】 89 + 90 + caldix の「zlib/* LzhDecoder2.* を除くソース全て」及び 91 + 配布バイナリ「caldix.exe」は以下のライセンスの下に公開されています。 92 + 93 + 94 + --- NYSL ver 0.9982 ( http://nysl.kinaba.cjb.net )--- 95 + 96 + A. 本ソフトウェアは Everyone'sWare です。このソフトを手にした一人一人が、 97 + ご自分の作ったものを扱うのと同じように、自由に利用することが出来ます。 98 + 99 + A-1. フリーウェアです。作者からは使用料等を要求しません。 100 + A-2. 有料無料や媒体の如何を問わず、自由に転載・再配布できます。 101 + A-3. いかなる種類の 改変・他プログラムでの利用 を行っても構いません。 102 + A-4. 変更したものや部分的に使用したものは、あなたのものになります。 103 + 公開する場合は、あなたの名前の下で行って下さい。 104 + 105 + B. このソフトを利用することによって生じた損害等について、作者は 106 + 責任を負わないものとします。各自の責任においてご利用下さい。 107 + 108 + C. 著作者人格権は K.INABA に帰属します。著作権は放棄します。 109 + 110 + D. 以上の3項は、ソース・実行バイナリの双方に適用されます。 111 + 112 +-------------------------------------------------------- 113 +by k.inaba( http://www.kmonos.net/ )
Added StdAfx.cpp version [418358bc9659fdca]
1 +// stdafx.cpp : 標準インクルードファイルを含むソース ファイル 2 +// Caldix.pch 生成されるプリコンパイル済ヘッダー 3 +// stdafx.obj 生成されるプリコンパイル済タイプ情報 4 + 5 +#include "stdafx.h" 6 + 7 +// TODO: STDAFX.H に含まれていて、このファイルに記述されていない 8 +// ヘッダーファイルを追加してください。
Added StdAfx.h version [cef59c2068371b3f]
1 +#ifndef FX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ 2 +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ 3 + 4 +#undef WINVER 5 +#define WINVER 0x0400 6 +#include <windows.h> 7 + 8 +#include <shlobj.h> 9 +#include <wininet.h> 10 + 11 +#include "kilib/kilibext.h" 12 +#include <stdio.h> 13 +#include <time.h> 14 +#include <io.h> 15 +#include <fcntl.h> 16 +#include <sys/stat.h> 17 + 18 +#endif
Added ZipTool.cpp version [c1387119b3ae0ab5]
1 + 2 +#include "stdafx.h" 3 +#include "ZipTool.h" 4 +#include "zlib/zlib.h" 5 +#include "kiutil.h" 6 +#include "kilib/kilib.h" 7 + 8 +bool CZipTool::Extract( const char* aname, const char* dll, kiPath& dll_rel_path ) 9 +{ 10 + ZipLocalHeader hdr; 11 + 12 + if( !(zip=fopen(aname,"rb")) ) 13 + return false; 14 + 15 + while( doHeader( &hdr ) ) 16 + { 17 + unsigned long posnext = ftell( zip ) + hdr.csz; 18 + char* name; 19 + 20 + if( out=fopen( name=kiutil::pathMake(hdr.fnm),"wb") ) 21 + { 22 + if( 0==strcmpi( kiPath::name(name), dll ) ) // DLLの位置を記憶 23 + dll_rel_path = name; 24 + 25 + // 展開! 26 + switch( hdr.mhd ) 27 + { 28 + case Stored: Unstore( hdr.usz, hdr.csz ); break; 29 + case Deflated: Inflate( hdr.usz, hdr.csz ); break; 30 + } 31 + 32 + // 事後処理 33 + fclose( out ); 34 + 35 + kiutil::timeSet( name, 36 + (WORD)(hdr.dat),(WORD)(hdr.tim)); 37 + } 38 + 39 + fseek( zip, posnext, SEEK_SET ); 40 + } 41 + 42 + fclose( zip ); 43 + return true; 44 +} 45 + 46 +//---- CRC 関係 --------------------- 47 + 48 +// make crc table 49 +//static void zip_make_crc_table() 50 +//{ 51 +// for( DWORD c,n=0; n!=256; n++ ) 52 +// { 53 +// c = n; 54 +// for( DWORD k=8; k; k-- ) 55 +// c = (c&1) ? ((0xedb88320L)^(c>>1)) : (c>>1); 56 +// crc_table[n] = c; 57 +// } 58 +//} 59 + 60 +// the result 61 +static DWORD crc_table[256] = { 62 +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 63 +0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 64 +0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 65 +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 66 +0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 67 +0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 68 +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 69 +0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 70 +0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 71 +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 72 +0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 73 +0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 74 +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 75 +0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 76 +0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 77 +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 78 +0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 79 +0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 80 +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 81 +0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 82 +0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 83 +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 84 +0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 85 +0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 86 +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 87 +0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 88 +0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 89 +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 90 +0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 91 +0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 92 +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 93 +0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 94 +}; 95 + 96 +// update crc 97 +#define calc_crc(c,b) (crc_table[(c&0xff)^(b&0xff)]^((c)>>8)) 98 + 99 +DWORD CZipTool::crc32( DWORD crc, const BYTE* dat, int len ) 100 +{ 101 + crc ^= 0xffffffffL; 102 + while( len-- ) 103 + crc = calc_crc( crc,*dat++ ); 104 + return (crc^0xffffffffL); 105 +} 106 + 107 +//-- ヘッダ処理 ----------------------------------- 108 + 109 +bool CZipTool::read_header( ZipLocalHeader* hdr ) 110 +{ 111 + unsigned char* buf = new unsigned char[65536]; 112 + 113 + if( 26 != fread(buf,1,26,zip) ) 114 + { delete [] buf; return false; } 115 + 116 + hdr->ver = ((buf[ 0])|(buf[ 1]<<8)); 117 + hdr->flg = ((buf[ 2])|(buf[ 3]<<8)); 118 + hdr->mhd = ((buf[ 4])|(buf[ 5]<<8)); 119 + hdr->tim = ((buf[ 6])|(buf[ 7]<<8)); 120 + hdr->dat = ((buf[ 8])|(buf[ 9]<<8)); 121 + hdr->crc = ((buf[10])|(buf[11]<<8)|(buf[12]<<16)|(buf[13]<<24)); 122 + hdr->csz = ((buf[14])|(buf[15]<<8)|(buf[16]<<16)|(buf[17]<<24)); 123 + hdr->usz = ((buf[18])|(buf[19]<<8)|(buf[20]<<16)|(buf[21]<<24)); 124 + hdr->fnl = ((buf[22])|(buf[23]<<8)); 125 + hdr->exl = ((buf[24])|(buf[25]<<8)); 126 + 127 + if( hdr->fnl!=fread(buf,1,hdr->fnl,zip) ) 128 + { delete [] buf; return false; } 129 + 130 + int l = (hdr->fnl>MAX_PATH-1)?(MAX_PATH-1):(hdr->fnl); 131 + memcpy( hdr->fnm, buf, l ); 132 + hdr->fnm[l]='\0'; 133 + char* pp; 134 + for( pp=hdr->fnm; *pp!=0; pp++ ); 135 + 136 + if( hdr->mhd > Deflated || hdr->mhd==Tokenized ) 137 + { delete [] buf; return false; } 138 + if( pp-hdr->fnm != l ) 139 + { delete [] buf; return false; } 140 + if( hdr->exl != fread(buf,1,hdr->exl,zip) ) 141 + { delete [] buf; return false; } 142 + 143 + delete [] buf; 144 + return true; 145 +} 146 + 147 +bool CZipTool::doHeader( ZipLocalHeader* hdr ) 148 +{ 149 + int c, stage=0; 150 + while( EOF != (c=fgetc(zip)) ) 151 + { 152 + if( c=='P' ) stage++; 153 + else if( c=='K' && stage==1 ) stage++; 154 + else if( c==0x03 && stage==2 ) stage++; 155 + else if( c==0x04 && stage==3 ) 156 + { 157 + stage++; 158 + int x=ftell(zip); 159 + if( read_header( hdr ) ) 160 + return true; 161 + fseek( zip,x,SEEK_SET ); 162 + } 163 + else stage=0; 164 + } 165 + 166 + return false; 167 +} 168 + 169 +//////////////////////////////////////////////////////////////// 170 +// Store : 無圧縮格納 171 +//////////////////////////////////////////////////////////////// 172 + 173 +void CZipTool::Unstore( DWORD usz, DWORD csz ) 174 +{ 175 + unsigned char* buf = new unsigned char[65536]; 176 +//--------------------------------------------------------------------// 177 + 178 + int how_much; 179 + while( csz ) 180 + { 181 + how_much = csz > 65536 ? 65536 : csz; 182 + if( 0>=(how_much=zipread( buf, how_much )) ) 183 + break; 184 + zipwrite( buf, how_much ); 185 + csz -= how_much; 186 + } 187 + 188 + delete [] buf; 189 +} 190 + 191 +//////////////////////////////////////////////////////////////// 192 +// Deflate : lzss+huffman。現在のpkzipのメソッド 193 +//////////////////////////////////////////////////////////////// 194 + 195 +static void* my_zalloc(void* prm,UINT num,UINT siz) 196 + {return (void*)new char[num*siz];} 197 +static void my_zfree(void* prm,void* ptr) 198 + {delete [] (char*)ptr;} 199 +void CZipTool::Inflate( DWORD usz, DWORD csz ) 200 +{ 201 + unsigned char* outbuf = new unsigned char[65536]; 202 + unsigned char* inbuf = outbuf + 32768; 203 +//--------------------------------------------------------------------// 204 + 205 + // zlib準備 206 + z_stream_s zs; 207 + zs.zalloc = my_zalloc; 208 + zs.zfree = my_zfree; 209 + 210 + // 出力バッファ 211 + int outsiz = 32768; 212 + zs.next_out = outbuf; 213 + zs.avail_out= outsiz; 214 + 215 + // 入力バッファ 216 + int insiz = zipread( inbuf, 217 + 32768 > csz ? csz : 32768 ); 218 + if( insiz<=0 ) 219 + return; 220 + csz -= insiz; 221 + zs.next_in = inbuf; 222 + zs.avail_in = insiz; 223 + 224 + // スタート 225 + inflateInit2( &zs, -15 ); 226 + 227 + // 書庫から入力し終わるまでループ 228 + int err = Z_OK; 229 + while( csz ) 230 + { 231 + while( zs.avail_out > 0 ) 232 + { 233 + err = inflate( &zs,Z_PARTIAL_FLUSH ); 234 + if( err!=Z_STREAM_END && err!=Z_OK ) 235 + csz=0; 236 + if( !csz ) 237 + break; 238 + 239 + if( zs.avail_in<=0 ) 240 + { 241 + int insiz = zipread( inbuf, 32768 > csz ? 242 + csz : 32768 ); 243 + if( insiz<=0 ) 244 + { 245 + err = Z_STREAM_END; 246 + csz = 0; 247 + break; 248 + } 249 + 250 + csz -= insiz; 251 + zs.next_in = inbuf; 252 + zs.avail_in = insiz; 253 + } 254 + } 255 + 256 + zipwrite( outbuf, outsiz-zs.avail_out ); 257 + zs.next_out = outbuf; 258 + zs.avail_out = outsiz; 259 + } 260 + 261 + // 出力残しを無くす。 262 + while( err!=Z_STREAM_END ) 263 + { 264 + err = inflate(&zs,Z_PARTIAL_FLUSH); 265 + if( err!=Z_STREAM_END && err!=Z_OK ) 266 + break; 267 + 268 + zipwrite( outbuf, outsiz-zs.avail_out ); 269 + zs.next_out = outbuf; 270 + zs.avail_out = outsiz; 271 + } 272 + 273 + // 終了 274 + inflateEnd(&zs); 275 + 276 + delete [] outbuf; 277 +}
Added ZipTool.h version [c145f6b51ea7d982]
1 +#ifndef AFX_ZIPTOOL_H__4C5F3720_4483_11D4_8D96_88668194683D__INCLUDED_ 2 +#define AFX_ZIPTOOL_H__4C5F3720_4483_11D4_8D96_88668194683D__INCLUDED_ 3 + 4 +// Zip Archive Extraction ... ( XacRett #39 SubSet ) 5 + 6 +// ローカルヘッダ 7 +struct ZipLocalHeader 8 +{ 9 + // 'P' 'K' 03 04 10 + WORD ver; // version_needed_to_extract 11 + WORD flg; // general_purpose_bit_flag 12 + WORD mhd; // compression_method 13 + WORD tim; // last_modified_file_time 14 + WORD dat; // last_modified_file_date 15 + DWORD crc; // crc32 16 + DWORD csz; // compressed-size 17 + DWORD usz; // uncompressed-size 18 + WORD fnl; // filename-len 19 + WORD exl; // extra_field_length 20 + 21 + char fnm[MAX_PATH]; 22 +// BYTE ext[]; 23 +}; 24 + 25 +// 圧縮メソッドの種類 26 +enum ZipMethod 27 +{ 28 + Stored, // 0 29 + Shrunk, // 1 30 + Reduced1, // 2-5 31 + Reduced2, 32 + Reduced3, 33 + Reduced4, 34 + Imploded, // 6 35 + Tokenized, // 7 ( not supported ) 36 + Deflated, // 8 37 + EnhDeflated,// 9 ( not supported ) 38 + DclImploded,//10 ( not supported ) 39 + 40 + Err=178 // this value is used by xacrett (^^; 41 +}; 42 + 43 +class CZipTool 44 +{ 45 + 46 +public: 47 + //-- 外向きインターフェイス -------------- 48 + bool Extract( const char* aname, const char* dll, kiPath& dll_rel_path ); 49 + 50 +private: //-- Zip内部処理用 ----------------------- 51 + 52 +// CRC 53 + DWORD crc32( DWORD crc, const BYTE* dat, int len ); 54 +// ファイルIO 55 + FILE *zip,*out; 56 + void zipwrite( BYTE* dat, int len ) 57 + { fwrite( dat, 1, len, out ); } 58 + int zipread( BYTE* dat, int len ) 59 + { return fread( dat, 1, len, zip ); } 60 +// bit-reader 61 + unsigned long bitbuf; 62 + int bits_left; 63 + bool bits_eof; 64 + 65 + void initbits() 66 + { 67 + bits_eof=false, bits_left=0, bitbuf=0; 68 + } 69 + int getbits( int n ) 70 + { 71 + if( n <= bits_left ) 72 + { 73 + int c = (int)(bitbuf & ((1<<n)-1)); 74 + bitbuf >>= n; 75 + bits_left -= n; 76 + return c; 77 + } 78 + return fillbits( n ); 79 + } 80 + int fillbits( int n ) 81 + { 82 + BYTE next; 83 + 84 + if( !zipread( &next,1 ) ) 85 + bits_eof = true; 86 + else 87 + { 88 + bitbuf |= (next<<bits_left); 89 + bits_left += 8; 90 + 91 + if( zipread( &next,1 ) ) 92 + { 93 + bitbuf |= (next<<bits_left); 94 + bits_left += 8; 95 + } 96 + } 97 + 98 + int c = (int)(bitbuf & ((1<<n)-1)); 99 + bitbuf >>= n; 100 + bits_left -= n; 101 + return c; 102 + } 103 + 104 +// 展開アルゴリズム 105 + void Unstore( DWORD usz, DWORD csz ); 106 + void Inflate( DWORD usz, DWORD csz ); 107 + 108 +// ヘッダ処理 109 +// 面倒なのでCentralDirectory系は一切無視! 110 + 111 + // 現在のファイル位置からヘッダとして読む 112 + bool read_header( ZipLocalHeader* hdr ); 113 + // ヘッダ位置を探し出して読む 114 + bool doHeader( ZipLocalHeader* hdr ); 115 +}; 116 + 117 +#endif
Added caldix.ico version [42d8db56669ee894]
cannot compute difference between binary files
Added fdi/FDI.H version [09e1df4f8b2c168d]
1 +/* 2 + * FDI.H -- File Decompression Interface 3 + * 4 + * Copyright (C) Microsoft Corporation 1993-1997 5 + * All Rights Reserved. 6 + */ 7 + 8 +#ifdef __cplusplus 9 +extern "C" { 10 +#endif 11 + 12 +#ifndef INCLUDED_TYPES_FCI_FDI 13 +#define INCLUDED_TYPES_FCI_FDI 1 14 + 15 +#ifndef HUGE 16 +#define HUGE 17 +#endif 18 + 19 +#ifndef FAR 20 +#define FAR 21 +#endif 22 + 23 +#ifndef DIAMONDAPI 24 +#define DIAMONDAPI __cdecl 25 +#endif 26 + 27 + 28 +//** Specify structure packing explicitly for clients of FDI 29 +#pragma pack(4) 30 + 31 +//** Don't redefine types defined in Win16 WINDOWS.H (_INC_WINDOWS) 32 +// or Win32 WINDOWS.H (_WINDOWS_) 33 +// 34 +#if !defined(_INC_WINDOWS) && !defined(_WINDOWS_) 35 +typedef int BOOL; /* f */ 36 +typedef unsigned char BYTE; /* b */ 37 +typedef unsigned int UINT; /* ui */ 38 +typedef unsigned short USHORT; /* us */ 39 +typedef unsigned long ULONG; /* ul */ 40 +#endif // _INC_WINDOWS 41 + 42 +typedef unsigned long CHECKSUM; /* csum */ 43 + 44 +typedef unsigned long UOFF; /* uoff - uncompressed offset */ 45 +typedef unsigned long COFF; /* coff - cabinet file offset */ 46 + 47 + 48 +#ifndef TRUE 49 +#define TRUE 1 50 +#endif 51 + 52 +#ifndef FALSE 53 +#define FALSE 0 54 +#endif 55 + 56 +#ifndef NULL 57 +#define NULL 0 58 +#endif 59 + 60 + 61 +/*** ERF - Error structure 62 + * 63 + * This structure returns error information from FCI/FDI. The caller should 64 + * not modify this structure. 65 + */ 66 +typedef struct { 67 + int erfOper; // FCI/FDI error code -- see FDIERROR_XXX 68 + // and FCIERR_XXX equates for details. 69 + 70 + int erfType; // Optional error value filled in by FCI/FDI. 71 + // For FCI, this is usually the C run-time 72 + // *errno* value. 73 + 74 + BOOL fError; // TRUE => error present 75 +} ERF; /* erf */ 76 +typedef ERF FAR *PERF; /* perf */ 77 + 78 +#ifdef _DEBUG 79 +// don't hide statics from map during debugging 80 +#define STATIC 81 +#else // !DEBUG 82 +#define STATIC static 83 +#endif // !DEBUG 84 + 85 +#define CB_MAX_CHUNK 32768U 86 +#define CB_MAX_DISK 0x7fffffffL 87 +#define CB_MAX_FILENAME 256 88 +#define CB_MAX_CABINET_NAME 256 89 +#define CB_MAX_CAB_PATH 256 90 +#define CB_MAX_DISK_NAME 256 91 + 92 +/*** tcompXXX - Compression types 93 + * 94 + * These are passed to FCIAddFile(), and are also stored in the CFFOLDER 95 + * structures in cabinet files. 96 + * 97 + * NOTE: We reserve bits for the TYPE, QUANTUM_LEVEL, and QUANTUM_MEM 98 + * to provide room for future expansion. Since this value is stored 99 + * in the CFDATA records in the cabinet file, we don't want to 100 + * have to change the format for existing compression configurations 101 + * if we add new ones in the future. This will allows us to read 102 + * old cabinet files in the future. 103 + */ 104 + 105 +typedef unsigned short TCOMP; /* tcomp */ 106 + 107 +#define tcompMASK_TYPE 0x000F // Mask for compression type 108 +#define tcompTYPE_NONE 0x0000 // No compression 109 +#define tcompTYPE_MSZIP 0x0001 // MSZIP 110 +#define tcompTYPE_QUANTUM 0x0002 // Quantum 111 +#define tcompTYPE_LZX 0x0003 // LZX 112 +#define tcompBAD 0x000F // Unspecified compression type 113 + 114 +#define tcompMASK_LZX_WINDOW 0x1F00 // Mask for LZX Compression Memory 115 +#define tcompLZX_WINDOW_LO 0x0F00 // Lowest LZX Memory (15) 116 +#define tcompLZX_WINDOW_HI 0x1500 // Highest LZX Memory (21) 117 +#define tcompSHIFT_LZX_WINDOW 8 // Amount to shift over to get int 118 + 119 +#define tcompMASK_QUANTUM_LEVEL 0x00F0 // Mask for Quantum Compression Level 120 +#define tcompQUANTUM_LEVEL_LO 0x0010 // Lowest Quantum Level (1) 121 +#define tcompQUANTUM_LEVEL_HI 0x0070 // Highest Quantum Level (7) 122 +#define tcompSHIFT_QUANTUM_LEVEL 4 // Amount to shift over to get int 123 + 124 +#define tcompMASK_QUANTUM_MEM 0x1F00 // Mask for Quantum Compression Memory 125 +#define tcompQUANTUM_MEM_LO 0x0A00 // Lowest Quantum Memory (10) 126 +#define tcompQUANTUM_MEM_HI 0x1500 // Highest Quantum Memory (21) 127 +#define tcompSHIFT_QUANTUM_MEM 8 // Amount to shift over to get int 128 + 129 +#define tcompMASK_RESERVED 0xE000 // Reserved bits (high 3 bits) 130 + 131 + 132 + 133 +#define CompressionTypeFromTCOMP(tc) \ 134 + ((tc) & tcompMASK_TYPE) 135 + 136 +#define CompressionLevelFromTCOMP(tc) \ 137 + (((tc) & tcompMASK_QUANTUM_LEVEL) >> tcompSHIFT_QUANTUM_LEVEL) 138 + 139 +#define CompressionMemoryFromTCOMP(tc) \ 140 + (((tc) & tcompMASK_QUANTUM_MEM) >> tcompSHIFT_QUANTUM_MEM) 141 + 142 +#define TCOMPfromTypeLevelMemory(t,l,m) \ 143 + (((m) << tcompSHIFT_QUANTUM_MEM ) | \ 144 + ((l) << tcompSHIFT_QUANTUM_LEVEL) | \ 145 + ( t )) 146 + 147 +#define LZXCompressionWindowFromTCOMP(tc) \ 148 + (((tc) & tcompMASK_LZX_WINDOW) >> tcompSHIFT_LZX_WINDOW) 149 + 150 +#define TCOMPfromLZXWindow(w) \ 151 + (((w) << tcompSHIFT_LZX_WINDOW ) | \ 152 + ( tcompTYPE_LZX )) 153 + 154 + 155 +//** Revert to default structure packing 156 +#pragma pack() 157 + 158 +#endif // !INCLUDED_TYPES_FCI_FDI 159 + 160 +/* 161 + * Concepts: 162 + * A *cabinet* file contains one or more *folders*. A folder contains 163 + * one or more (pieces of) *files*. A folder is by definition a 164 + * decompression unit, i.e., to extract a file from a folder, all of 165 + * the data from the start of the folder up through and including the 166 + * desired file must be read and decompressed. 167 + * 168 + * A folder can span one (or more) cabinet boundaries, and by implication 169 + * a file can also span one (or more) cabinet boundaries. Indeed, more 170 + * than one file can span a cabinet boundary, since FCI concatenates 171 + * files together into a single data stream before compressing (actually, 172 + * at most one file will span any one cabinet boundary, but FCI does 173 + * not know which file this is, since the mapping from uncompressed bytes 174 + * to compressed bytes is pretty obscure. Also, since FCI compresses 175 + * in blocks of 32K (at present), any files with data in a 32K block that 176 + * spans a cabinet boundary require FDI to read both cabinet files 177 + * to get the two halves of the compressed block). 178 + * 179 + * Overview: 180 + * The File Decompression Interface is used to simplify the reading of 181 + * cabinet files. A setup program will proceed in a manner very 182 + * similar to the pseudo code below. An FDI context is created, the 183 + * setup program calls FDICopy() for each cabinet to be processed. For 184 + * each file in the cabinet, FDICopy() calls a notification callback 185 + * routine, asking the setup program if the file should be copied. 186 + * This call-back approach is great because it allows the cabinet file 187 + * to be read and decompressed in an optimal manner, and also makes FDI 188 + * independent of the run-time environment -- FDI makes *no* C run-time 189 + * calls whatsoever. All memory allocation and file I/O functions are 190 + * passed into FDI by the client. 191 + * 192 + * main(...) 193 + * { 194 + * // Read INF file to construct list of desired files. 195 + * // Ideally, these would be sorted in the same order as the 196 + * // files appear in the cabinets, so that you can just walk 197 + * // down the list in response to fdintCOPY_FILE notifications. 198 + * 199 + * // Construct list of required cabinets. 200 + * 201 + * hfdi = FDICreate(...); // Create FDI context 202 + * For (cabinet in List of Cabinets) { 203 + * FDICopy(hfdi,cabinet,fdiNotify,...); // Process each cabinet 204 + * } 205 + * FDIDestroy(hfdi); 206 + * ... 207 + * } 208 + * 209 + * // Notification callback function 210 + * fdiNotify(fdint,...) 211 + * { 212 + * If (User Aborted) // Permit cancellation 213 + * if (fdint == fdintCLOSE_FILE_INFO) 214 + * close open file 215 + * return -1; 216 + * switch (fdint) { 217 + * case fdintCOPY_FILE: // File to copy, maybe 218 + * // Check file against list of desired files 219 + * if want to copy file 220 + * open destination file and return handle 221 + * else 222 + * return NULL; // Skip file 223 + * case fdintCLOSE_FILE_INFO: 224 + * close file 225 + * set date, time, and attributes 226 + * 227 + * case fdintNEXT_CABINET: 228 + * if not an error callback 229 + * Tell FDI to use suggested directory name 230 + * else 231 + * Tell user what the problem was, and prompt 232 + * for a new disk and/or path. 233 + * if user aborts 234 + * Tell FDI to abort 235 + * else 236 + * return to FDI to try another cabinet 237 + * 238 + * default: 239 + * return 0; // more messages may be defined 240 + * ... 241 + * } 242 + * 243 + * Error Handling Suggestions: 244 + * Since you the client have passed in *all* of the functions that 245 + * FDI uses to interact with the "outside" world, you are in prime 246 + * position to understand and deal with errors. 247 + * 248 + * The general philosophy of FDI is to pass all errors back up to 249 + * the client. FDI returns fairly generic error codes in the case 250 + * where one of the callback functions (PFNOPEN, PFNREAD, etc.) fail, 251 + * since it assumes that the callback function will save enough 252 + * information in a static/global so that when FDICopy() returns 253 + * fail, the client can examine this information and report enough 254 + * detail about the problem that the user can take corrective action. 255 + * 256 + * For very specific errors (CORRUPT_CABINET, for example), FDI returns 257 + * very specific error codes. 258 + * 259 + * THE BEST POLICY IS FOR YOUR CALLBACK ROUTINES TO AVOID RETURNING 260 + * ERRORS TO FDI! 261 + * 262 + * Examples: 263 + * (1) If the disk is getting full, instead of returning an error 264 + * from your PFNWRITE function, you should -- inside your 265 + * PFNWRITE function -- put up a dialog telling the user to free 266 + * some disk space. 267 + * (2) When you get the fdintNEXT_CABINET notification, you should 268 + * verify that the cabinet you return is the correct one (call 269 + * FDIIsCabinet(), and make sure the setID matches the one for 270 + * the current cabinet specified in the fdintCABINET_INFO, and 271 + * that the disk number is one greater. 272 + * 273 + * NOTE: FDI will continue to call fdintNEXT_CABINET until it 274 + * gets the cabinet it wants, or until you return -1 275 + * to abort the FDICopy() call. 276 + * 277 + * The documentation below on the FDI error codes provides explicit 278 + * guidance on how to avoid each error. 279 + * 280 + * If you find you must return a failure to FDI from one of your 281 + * callback functions, then FDICopy() frees all resources it allocated 282 + * and closes all files. If you can figure out how to overcome the 283 + * problem, you can call FDICopy() again on the last cabinet, and 284 + * skip any files that you already copied. But, note that FDI does 285 + * *not* maintain any state between FDICopy() calls, other than possibly 286 + * memory allocated for the decompressor. 287 + * 288 + * See FDIERROR for details on FDI error codes and recommended actions. 289 + * 290 + * 291 + * Progress Indicator Suggestions: 292 + * As above, all of the file I/O functions are supplied by you. So, 293 + * updating a progress indicator is very simple. You keep track of 294 + * the target files handles you have opened, along with the uncompressed 295 + * size of the target file. When you see writes to the handle of a 296 + * target file, you use the write count to update your status! 297 + * Since this method is available, there is no separate callback from 298 + * FDI just for progess indication. 299 + */ 300 + 301 +#ifndef INCLUDED_FDI 302 +#define INCLUDED_FDI 1 303 + 304 +//** Specify structure packing explicitly for clients of FDI 305 +#pragma pack(4) 306 + 307 + 308 +/*** FDIERROR - Error codes returned in erf.erfOper field 309 + * 310 + * In general, FDI will only fail if one of the passed in memory or 311 + * file I/O functions fails. Other errors are pretty unlikely, and are 312 + * caused by corrupted cabinet files, passing in a file which is not a 313 + * cabinet file, or cabinet files out of order. 314 + * 315 + * Description: Summary of error. 316 + * Cause: List of possible causes of this error. 317 + * Response: How client might respond to this error, or avoid it in 318 + * the first place. 319 + */ 320 +typedef enum { 321 + FDIERROR_NONE, 322 + // Description: No error 323 + // Cause: Function was successfull. 324 + // Response: Keep going! 325 + 326 + FDIERROR_CABINET_NOT_FOUND, 327 + // Description: Cabinet not found 328 + // Cause: Bad file name or path passed to FDICopy(), or returned 329 + // to fdintNEXT_CABINET. 330 + // Response: To prevent this error, validate the existence of the 331 + // the cabinet *before* passing the path to FDI. 332 + 333 + FDIERROR_NOT_A_CABINET, 334 + // Description: Cabinet file does not have the correct format 335 + // Cause: File passed to to FDICopy(), or returned to 336 + // fdintNEXT_CABINET, is too small to be a cabinet file, 337 + // or does not have the cabinet signature in its first 338 + // four bytes. 339 + // Response: To prevent this error, call FDIIsCabinet() to check a 340 + // cabinet before calling FDICopy() or returning the 341 + // cabinet path to fdintNEXT_CABINET. 342 + 343 + FDIERROR_UNKNOWN_CABINET_VERSION, 344 + // Description: Cabinet file has an unknown version number. 345 + // Cause: File passed to to FDICopy(), or returned to 346 + // fdintNEXT_CABINET, has what looks like a cabinet file 347 + // header, but the version of the cabinet file format 348 + // is not one understood by this version of FDI. The 349 + // erf.erfType field is filled in with the version number 350 + // found in the cabinet file. 351 + // Response: To prevent this error, call FDIIsCabinet() to check a 352 + // cabinet before calling FDICopy() or returning the 353 + // cabinet path to fdintNEXT_CABINET. 354 + 355 + FDIERROR_CORRUPT_CABINET, 356 + // Description: Cabinet file is corrupt 357 + // Cause: FDI returns this error any time it finds a problem 358 + // with the logical format of a cabinet file, and any 359 + // time one of the passed-in file I/O calls fails when 360 + // operating on a cabinet (PFNOPEN, PFNSEEK, PFNREAD, 361 + // or PFNCLOSE). The client can distinguish these two 362 + // cases based upon whether the last file I/O call 363 + // failed or not. 364 + // Response: Assuming this is not a real corruption problem in 365 + // a cabinet file, the file I/O functions could attempt 366 + // to do retries on failure (for example, if there is a 367 + // temporary network connection problem). If this does 368 + // not work, and the file I/O call has to fail, then the 369 + // FDI client will have to clean up and call the 370 + // FDICopy() function again. 371 + 372 + FDIERROR_ALLOC_FAIL, 373 + // Description: Could not allocate enough memory 374 + // Cause: FDI tried to allocate memory with the PFNALLOC 375 + // function, but it failed. 376 + // Response: If possible, PFNALLOC should take whatever steps 377 + // are possible to allocate the memory requested. If 378 + // memory is not immediately available, it might post a 379 + // dialog asking the user to free memory, for example. 380 + // Note that the bulk of FDI's memory allocations are 381 + // made at FDICreate() time and when the first cabinet 382 + // file is opened during FDICopy(). 383 + 384 + FDIERROR_BAD_COMPR_TYPE, 385 + // Description: Unknown compression type in a cabinet folder 386 + // Cause: [Should never happen.] A folder in a cabinet has an 387 + // unknown compression type. This is probably caused by 388 + // a mismatch between the version of FCI.LIB used to 389 + // create the cabinet and the FDI.LIB used to read the 390 + // cabinet. 391 + // Response: Abort. 392 + 393 + FDIERROR_MDI_FAIL, 394 + // Description: Failure decompressing data from a cabinet file 395 + // Cause: The decompressor found an error in the data coming 396 + // from the file cabinet. The cabinet file was corrupted. 397 + // [11-Apr-1994 bens When checksuming is turned on, this 398 + // error should never occur.] 399 + // Response: Probably should abort; only other choice is to cleanup 400 + // and call FDICopy() again, and hope there was some 401 + // intermittent data error that will not reoccur. 402 + 403 + FDIERROR_TARGET_FILE, 404 + // Description: Failure writing to target file 405 + // Cause: FDI returns this error any time it gets an error back 406 + // from one of the passed-in file I/O calls fails when 407 + // writing to a file being extracted from a cabinet. 408 + // Response: To avoid or minimize this error, the file I/O functions 409 + // could attempt to avoid failing. A common cause might 410 + // be disk full -- in this case, the PFNWRITE function 411 + // could have a check for free space, and put up a dialog 412 + // asking the user to free some disk space. 413 + 414 + FDIERROR_RESERVE_MISMATCH, 415 + // Description: Cabinets in a set do not have the same RESERVE sizes 416 + // Cause: [Should never happen]. FDI requires that the sizes of 417 + // the per-cabinet, per-folder, and per-data block 418 + // RESERVE sections be consistent across all the cabinets 419 + // in a set. 420 + // Response: Abort. 421 + 422 + FDIERROR_WRONG_CABINET, 423 + // Description: Cabinet returned on fdintNEXT_CABINET is incorrect 424 + // Cause: NOTE: THIS ERROR IS NEVER RETURNED BY FDICopy()! 425 + // Rather, FDICopy() keeps calling the fdintNEXT_CABINET 426 + // callback until either the correct cabinet is specified, 427 + // or you return ABORT. 428 + // When FDICopy() is extracting a file that crosses a 429 + // cabinet boundary, it calls fdintNEXT_CABINET to ask 430 + // for the path to the next cabinet. Not being very 431 + // trusting, FDI then checks to make sure that the 432 + // correct continuation cabinet was supplied! It does 433 + // this by checking the "setID" and "iCabinet" fields 434 + // in the cabinet. When MAKECAB.EXE creates a set of 435 + // cabinets, it constructs the "setID" using the sum 436 + // of the bytes of all the destination file names in 437 + // the cabinet set. FDI makes sure that the 16-bit 438 + // setID of the continuation cabinet matches the 439 + // cabinet file just processed. FDI then checks that 440 + // the cabinet number (iCabinet) is one more than the 441 + // cabinet number for the cabinet just processed. 442 + // Response: You need code in your fdintNEXT_CABINET (see below) 443 + // handler to do retries if you get recalled with this 444 + // error. See the sample code (EXTRACT.C) to see how 445 + // this should be handled. 446 + 447 + FDIERROR_USER_ABORT, 448 + // Description: FDI aborted. 449 + // Cause: An FDI callback returnd -1 (usually). 450 + // Response: Up to client. 451 + 452 +} FDIERROR; 453 + 454 + 455 +/* 456 + * FAT file attribute flag used by FCI/FDI to indicate that 457 + * the filename in the CAB is a UTF string 458 + */ 459 +#ifndef _A_NAME_IS_UTF 460 +#define _A_NAME_IS_UTF 0x80 461 +#endif 462 + 463 +/* 464 + * FAT file attribute flag used by FCI/FDI to indicate that 465 + * the file should be executed after extraction 466 + */ 467 +#ifndef _A_EXEC 468 +#define _A_EXEC 0x40 469 +#endif 470 + 471 + 472 +/*** HFDI - Handle to an FDI context 473 + * 474 + * FDICreate() creates this, and it must be passed to all other FDI 475 + * functions. 476 + */ 477 +typedef void FAR *HFDI; /* hfdi */ 478 + 479 + 480 +/*** FDICABINETINFO - Information about a cabinet 481 + * 482 + */ 483 +typedef struct { 484 + long cbCabinet; // Total length of cabinet file 485 + USHORT cFolders; // Count of folders in cabinet 486 + USHORT cFiles; // Count of files in cabinet 487 + USHORT setID; // Cabinet set ID 488 + USHORT iCabinet; // Cabinet number in set (0 based) 489 + BOOL fReserve; // TRUE => RESERVE present in cabinet 490 + BOOL hasprev; // TRUE => Cabinet is chained prev 491 + BOOL hasnext; // TRUE => Cabinet is chained next 492 +} FDICABINETINFO; /* fdici */ 493 +typedef FDICABINETINFO FAR *PFDICABINETINFO; /* pfdici */ 494 + 495 + 496 +/*** FDIDECRYPTTYPE - PFNFDIDECRYPT command types 497 + * 498 + */ 499 +typedef enum { 500 + fdidtNEW_CABINET, // New cabinet 501 + fdidtNEW_FOLDER, // New folder 502 + fdidtDECRYPT, // Decrypt a data block 503 +} FDIDECRYPTTYPE; /* fdidt */ 504 + 505 + 506 +/*** FDIDECRYPT - Data for PFNFDIDECRYPT function 507 + * 508 + */ 509 +typedef struct { 510 + FDIDECRYPTTYPE fdidt; // Command type (selects union below) 511 + void FAR *pvUser; // Decryption context 512 + union { 513 + struct { // fdidtNEW_CABINET 514 + void FAR *pHeaderReserve; // RESERVE section from CFHEADER 515 + USHORT cbHeaderReserve; // Size of pHeaderReserve 516 + USHORT setID; // Cabinet set ID 517 + int iCabinet; // Cabinet number in set (0 based) 518 + } cabinet; 519 + 520 + struct { // fdidtNEW_FOLDER 521 + void FAR *pFolderReserve; // RESERVE section from CFFOLDER 522 + USHORT cbFolderReserve; // Size of pFolderReserve 523 + USHORT iFolder; // Folder number in cabinet (0 based) 524 + } folder; 525 + 526 + struct { // fdidtDECRYPT 527 + void FAR *pDataReserve; // RESERVE section from CFDATA 528 + USHORT cbDataReserve; // Size of pDataReserve 529 + void FAR *pbData; // Data buffer 530 + USHORT cbData; // Size of data buffer 531 + BOOL fSplit; // TRUE if this is a split data block 532 + USHORT cbPartial; // 0 if this is not a split block, or 533 + // the first piece of a split block; 534 + // Greater than 0 if this is the 535 + // second piece of a split block. 536 + } decrypt; 537 + }; 538 +} FDIDECRYPT; /* fdid */ 539 +typedef FDIDECRYPT FAR *PFDIDECRYPT; /* pfdid */ 540 + 541 + 542 +/*** FNALLOC - Memory Allocation 543 + * FNFREE - Memory Free 544 + * 545 + * These are modeled after the C run-time routines malloc() and free() 546 + * FDI expects error handling to be identical to these C run-time routines. 547 + * 548 + * As long as you faithfully copy the semantics of malloc() and free(), 549 + * you can supply any functions you like! 550 + * 551 + * WARNING: You should never assume anything about the sequence of 552 + * PFNALLOC and PFNFREE calls -- incremental releases of 553 + * FDI may have radically different numbers of 554 + * PFNALLOC calls and allocation sizes! 555 + */ 556 +//** Memory functions for FDI 557 +typedef void HUGE * (FAR DIAMONDAPI *PFNALLOC)(ULONG cb); /* pfna */ 558 +#define FNALLOC(fn) void HUGE * FAR DIAMONDAPI fn(ULONG cb) 559 + 560 +typedef void (FAR DIAMONDAPI *PFNFREE)(void HUGE *pv); /* pfnf */ 561 +#define FNFREE(fn) void FAR DIAMONDAPI fn(void HUGE *pv) 562 + 563 + 564 +/*** PFNOPEN - File I/O callbacks for FDI 565 + * PFNREAD 566 + * PFNWRITE 567 + * PFNCLOSE 568 + * PFNSEEK 569 + * 570 + * These are modeled after the C run-time routines _open, _read, 571 + * _write, _close, and _lseek. The values for the PFNOPEN oflag 572 + * and pmode calls are those defined for _open. FDI expects error 573 + * handling to be identical to these C run-time routines. 574 + * 575 + * As long as you faithfully copy these aspects, you can supply 576 + * any functions you like! 577 + * 578 + * WARNING: You should never assume you know what file is being 579 + * opened at any one point in time! FDI will usually 580 + * stick to opening cabinet files, but it is possible 581 + * that in a future implementation it may open temporary 582 + * files or open cabinet files in a different order. 583 + * 584 + * Notes for Memory Mapped File fans: 585 + * You can write wrapper routines to allow FDI to work on memory 586 + * mapped files. You'll have to create your own "handle" type so that 587 + * you can store the base memory address of the file and the current 588 + * seek position, and then you'll allocate and fill in one of these 589 + * structures and return a pointer to it in response to the PFNOPEN 590 + * call and the fdintCOPY_FILE call. Your PFNREAD and PFNWRITE 591 + * functions will do memcopy(), and update the seek position in your 592 + * "handle" structure. PFNSEEK will just change the seek position 593 + * in your "handle" structure. 594 + */ 595 +//** File I/O functions for FDI 596 +typedef int (FAR DIAMONDAPI *PFNOPEN) (char FAR *pszFile, int oflag, int pmode); 597 +typedef UINT (FAR DIAMONDAPI *PFNREAD) (int hf, void FAR *pv, UINT cb); 598 +typedef UINT (FAR DIAMONDAPI *PFNWRITE)(int hf, void FAR *pv, UINT cb); 599 +typedef int (FAR DIAMONDAPI *PFNCLOSE)(int hf); 600 +typedef long (FAR DIAMONDAPI *PFNSEEK) (int hf, long dist, int seektype); 601 + 602 +#define FNOPEN(fn) int FAR DIAMONDAPI fn(char FAR *pszFile, int oflag, int pmode) 603 +#define FNREAD(fn) UINT FAR DIAMONDAPI fn(int hf, void FAR *pv, UINT cb) 604 +#define FNWRITE(fn) UINT FAR DIAMONDAPI fn(int hf, void FAR *pv, UINT cb) 605 +#define FNCLOSE(fn) int FAR DIAMONDAPI fn(int hf) 606 +#define FNSEEK(fn) long FAR DIAMONDAPI fn(int hf, long dist, int seektype) 607 + 608 + 609 + 610 +/*** PFNFDIDECRYPT - FDI Decryption callback 611 + * 612 + * If this function is passed on the FDICopy() call, then FDI calls it 613 + * at various times to update the decryption state and to decrypt FCDATA 614 + * blocks. 615 + * 616 + * Common Entry Conditions: 617 + * pfdid->fdidt - Command type 618 + * pfdid->pvUser - pvUser value from FDICopy() call 619 + * 620 + * fdidtNEW_CABINET: //** Notification of a new cabinet 621 + * Entry: 622 + * pfdid->cabinet. 623 + * pHeaderReserve - RESERVE section from CFHEADER 624 + * cbHeaderReserve - Size of pHeaderReserve 625 + * setID - Cabinet set ID 626 + * iCabinet - Cabinet number in set (0 based) 627 + * Exit-Success: 628 + * returns anything but -1; 629 + * Exit-Failure: 630 + * returns -1; FDICopy() is aborted. 631 + * Notes: 632 + * (1) This call allows the decryption code to pick out any information 633 + * from the cabinet header reserved area (placed there by DIACRYPT) 634 + * needed to perform decryption. If there is no such information, 635 + * this call would presumably be ignored. 636 + * (2) This call is made very soon after fdintCABINET_INFO. 637 + * 638 + * fdidtNEW_FOLDER: //** Notification of a new folder 639 + * Entry: 640 + * pfdid->folder. 641 + * pFolderReserve - RESERVE section from CFFOLDER 642 + * cbFolderReserve - Size of pFolderReserve 643 + * iFolder - Folder number in cabinet (0 based) 644 + * Exit-Success: 645 + * returns anything but -1; 646 + * Exit-Failure: 647 + * returns -1; FDICopy() is aborted. 648 + * Notes: 649 + * This call allows the decryption code to pick out any information 650 + * from the folder reserved area (placed there by DIACRYPT) needed 651 + * to perform decryption. If there is no such information, this 652 + * call would presumably be ignored. 653 + * 654 + * fdidtDECRYPT: //** Decrypt a data buffer 655 + * Entry: 656 + * pfdid->folder. 657 + * pDataReserve - RESERVE section for this CFDATA block 658 + * cbDataReserve - Size of pDataReserve 659 + * pbData - Data buffer 660 + * cbData - Size of data buffer 661 + * fSplit - TRUE if this is a split data block 662 + * cbPartial - 0 if this is not a split block, or the first 663 + * piece of a split block; Greater than 0 if 664 + * this is the second piece of a split block. 665 + * Exit-Success: 666 + * returns TRUE; 667 + * Exit-Failure: 668 + * returns FALSE; error during decrypt 669 + * returns -1; FDICopy() is aborted. 670 + * Notes: 671 + * FCI will split CFDATA blocks across cabinet boundaries if 672 + * necessary. To provide maximum flexibility, FDI will call the 673 + * fdidtDECRYPT function twice on such split blocks, once when 674 + * the first portion is read, and again when the second portion 675 + * is read. And, of course, most data blocks will not be split. 676 + * So, there are three cases: 677 + * 678 + * 1) fSplit == FALSE 679 + * You have the entire data block, so decrypt it. 680 + * 681 + * 2) fSplit == TRUE, cbPartial == 0 682 + * This is the first portion of a split data block, so cbData 683 + * is the size of this portion. You can either choose to decrypt 684 + * this piece, or ignore this call and decrypt the full CFDATA 685 + * block on the next (second) fdidtDECRYPT call. 686 + * 687 + * 3) fSplit == TRUE, cbPartial > 0 688 + * This is the second portion of a split data block (indeed, 689 + * cbPartial will have the same value as cbData did on the 690 + * immediately preceeding fdidtDECRYPT call!). If you decrypted 691 + * the first portion on the first call, then you can decrypt the 692 + * second portion now. If you ignored the first call, then you 693 + * can decrypt the entire buffer. 694 + * NOTE: pbData points to the second portion of the split data 695 + * block in this case, *not* the entire data block. If 696 + * you want to wait until the second piece to decrypt the 697 + * *entire* block, pbData-cbPartial is the address of the 698 + * start of the whole block, and cbData+cbPartial is its 699 + * size. 700 + */ 701 +typedef int (FAR DIAMONDAPI *PFNFDIDECRYPT)(PFDIDECRYPT pfdid); /* pfnfdid */ 702 +#define FNFDIDECRYPT(fn) int FAR DIAMONDAPI fn(PFDIDECRYPT pfdid) 703 + 704 + 705 +/*** FDINOTIFICATION - Notification structure for PFNFDINOTIFY 706 + * 707 + * See the FDINOTIFICATIONTYPE definition for information on usage and 708 + * meaning of these fields. 709 + */ 710 +typedef struct { 711 +// long fields 712 + long cb; 713 + char FAR *psz1; 714 + char FAR *psz2; 715 + char FAR *psz3; // Points to a 256 character buffer 716 + void FAR *pv; // Value for client 717 + 718 +// int fields 719 + int hf; 720 + 721 +// short fields 722 + USHORT date; 723 + USHORT time; 724 + USHORT attribs; 725 + 726 + USHORT setID; // Cabinet set ID 727 + USHORT iCabinet; // Cabinet number (0-based) 728 + USHORT iFolder; // Folder number (0-based) 729 + 730 + FDIERROR fdie; 731 +} FDINOTIFICATION, FAR *PFDINOTIFICATION; /* fdin, pfdin */ 732 + 733 + 734 +/*** FDINOTIFICATIONTYPE - FDICopy notification types 735 + * 736 + * The notification function for FDICopy can be called with the following 737 + * values for the fdint parameter. In all cases, the pfdin->pv field is 738 + * filled in with the value of the pvUser argument passed in to FDICopy(). 739 + * 740 + * A typical sequence of calls will be something like this: 741 + * fdintCABINET_INFO // Info about the cabinet 742 + * fdintENUMERATE // Starting enumeration 743 + * fdintPARTIAL_FILE // Only if this is not the first cabinet, and 744 + * // one or more files were continued from the 745 + * // previous cabinet. 746 + * ... 747 + * fdintPARTIAL_FILE 748 + * fdintCOPY_FILE // The first file that starts in this cabinet 749 + * ... 750 + * fdintCOPY_FILE // Now let's assume you want this file... 751 + * // PFNWRITE called multiple times to write to this file. 752 + * fdintCLOSE_FILE_INFO // File done, set date/time/attributes 753 + * 754 + * fdintCOPY_FILE // Now let's assume you want this file... 755 + * // PFNWRITE called multiple times to write to this file. 756 + * fdintNEXT_CABINET // File was continued to next cabinet! 757 + * fdintCABINET_INFO // Info about the new cabinet 758 + * // PFNWRITE called multiple times to write to this file. 759 + * fdintCLOSE_FILE_INFO // File done, set date/time/attributes 760 + * ... 761 + * fdintENUMERATE // Ending enumeration 762 + * 763 + * fdintCABINET_INFO: 764 + * Called exactly once for each cabinet opened by FDICopy(), including 765 + * continuation cabinets opened due to file(s) spanning cabinet 766 + * boundaries. Primarily intended to permit EXTRACT.EXE to 767 + * automatically select the next cabinet in a cabinet sequence even if 768 + * not copying files that span cabinet boundaries. 769 + * Entry: 770 + * pfdin->psz1 = name of next cabinet 771 + * pfdin->psz2 = name of next disk 772 + * pfdin->psz3 = cabinet path name 773 + * pfdin->setID = cabinet set ID (a random 16-bit number) 774 + * pfdin->iCabinet = Cabinet number within cabinet set (0-based) 775 + * Exit-Success: 776 + * Return anything but -1 777 + * Exit-Failure: 778 + * Returns -1 => Abort FDICopy() call 779 + * Notes: 780 + * This call is made *every* time a new cabinet is examined by 781 + * FDICopy(). So if "foo2.cab" is examined because a file is 782 + * continued from "foo1.cab", and then you call FDICopy() again 783 + * on "foo2.cab", you will get *two* fdintCABINET_INFO calls all 784 + * told. 785 + * 786 + * fdintCOPY_FILE: 787 + * Called for each file that *starts* in the current cabinet, giving 788 + * the client the opportunity to request that the file be copied or 789 + * skipped. 790 + * Entry: 791 + * pfdin->psz1 = file name in cabinet 792 + * pfdin->cb = uncompressed size of file 793 + * pfdin->date = file date 794 + * pfdin->time = file time 795 + * pfdin->attribs = file attributes 796 + * pfdin->iFolder = file's folder index 797 + * Exit-Success: 798 + * Return non-zero file handle for destination file; FDI writes 799 + * data to this file use the PFNWRITE function supplied to FDICreate, 800 + * and then calls fdintCLOSE_FILE_INFO to close the file and set 801 + * the date, time, and attributes. NOTE: This file handle returned 802 + * must also be closeable by the PFNCLOSE function supplied to 803 + * FDICreate, since if an error occurs while writing to this handle, 804 + * FDI will use the PFNCLOSE function to close the file so that the 805 + * client may delete it. 806 + * Exit-Failure: 807 + * Returns 0 => Skip file, do not copy 808 + * Returns -1 => Abort FDICopy() call 809 + * 810 + * fdintCLOSE_FILE_INFO: 811 + * Called after all of the data has been written to a target file. 812 + * This function must close the file and set the file date, time, 813 + * and attributes. 814 + * Entry: 815 + * pfdin->psz1 = file name in cabinet 816 + * pfdin->hf = file handle 817 + * pfdin->date = file date 818 + * pfdin->time = file time 819 + * pfdin->attribs = file attributes 820 + * pfdin->iFolder = file's folder index 821 + * pfdin->cb = Run After Extract (0 - don't run, 1 Run) 822 + * Exit-Success: 823 + * Returns TRUE 824 + * Exit-Failure: 825 + * Returns FALSE, or -1 to abort; 826 + * 827 + * IMPORTANT NOTE IMPORTANT: 828 + * pfdin->cb is overloaded to no longer be the size of 829 + * the file but to be a binary indicated run or not 830 + * 831 + * IMPORTANT NOTE: 832 + * FDI assumes that the target file was closed, even if this 833 + * callback returns failure. FDI will NOT attempt to use 834 + * the PFNCLOSE function supplied on FDICreate() to close 835 + * the file! 836 + * 837 + * fdintPARTIAL_FILE: 838 + * Called for files at the front of the cabinet that are CONTINUED 839 + * from a previous cabinet. This callback occurs only when FDICopy is 840 + * started on second or subsequent cabinet in a series that has files 841 + * continued from a previous cabinet. 842 + * Entry: 843 + * pfdin->psz1 = file name of file CONTINUED from a PREVIOUS cabinet 844 + * pfdin->psz2 = name of cabinet where file starts 845 + * pfdin->psz3 = name of disk where file starts 846 + * Exit-Success: 847 + * Return anything other than -1; enumeration continues 848 + * Exit-Failure: 849 + * Returns -1 => Abort FDICopy() call 850 + * 851 + * fdintENUMERATE: 852 + * Called once after a call to FDICopy() starts scanning a CAB's 853 + * CFFILE entries, and again when there are no more CFFILE entries. 854 + * If CAB spanning occurs, an additional call will occur after the 855 + * first spanned file is completed. If the pfdin->iFolder value is 856 + * changed from zero, additional calls will occur next time it reaches 857 + * zero. If iFolder is changed to zero, FDICopy will terminate, as if 858 + * there were no more CFFILE entries. Primarily intended to allow an 859 + * application with it's own file list to help FDI advance quickly to 860 + * a CFFILE entry of interest. Can also be used to allow an 861 + * application to determine the cb values for each file in the CAB. 862 + * Entry: 863 + * pfdin->cb = current CFFILE position 864 + * pfdin->iFolder = number of files remaining 865 + * pfdin->setID = current CAB's setID value 866 + * Exit-Don't Care: 867 + * Don't change anything. 868 + * Return anything but -1. 869 + * Exit-Forcing a skip: 870 + * pfdin->cb = desired CFFILE position 871 + * pfdin->iFolder = desired # of files remaining 872 + * Return anything but -1. 873 + * Exit-Stop: 874 + * pfdin->iFolder = set to 0 875 + * Return anything but -1. 876 + * Exit-Failure: 877 + * Return -1 => Abort FDICopy call ("user aborted".) 878 + * Notes: 879 + * This call can be ignored by applications which want normal file 880 + * searching. The application can adjust the supplied values to 881 + * force FDICopy() to continue it's search at another location, or 882 + * to force FDICopy() to terminate the search, by setting iFolder to 0. 883 + * (FDICopy() will report no error when terminated this way.) 884 + * FDI has no means to verify the supplied cb or iFolder values. 885 + * Arbitrary values are likely to cause undesirable results. An 886 + * application should cross-check pfdin->setID to be certain the 887 + * external database is in sync with the CAB. Reverse-skips are OK 888 + * (but may be inefficient) unless fdintNEXT_CABINET has been called. 889 + * 890 + * fdintNEXT_CABINET: 891 + * This function is *only* called when fdintCOPY_FILE was told to copy 892 + * a file in the current cabinet that is continued to a subsequent 893 + * cabinet file. It is important that the cabinet path name (psz3) 894 + * be validated before returning! This function should ensure that 895 + * the cabinet exists and is readable before returning. So, this 896 + * is the function that should, for example, issue a disk change 897 + * prompt and make sure the cabinet file exists. 898 + * 899 + * When this function returns to FDI, FDI will check that the setID 900 + * and iCabinet match the expected values for the next cabinet. 901 + * If not, FDI will continue to call this function until the correct 902 + * cabinet file is specified, or until this function returns -1 to 903 + * abort the FDICopy() function. pfdin->fdie is set to 904 + * FDIERROR_WRONG_CABINET to indicate this case. 905 + * 906 + * If you *haven't* ensured that the cabinet file is present and 907 + * readable, or the cabinet file has been damaged, pfdin->fdie will 908 + * receive other appropriate error codes: 909 + * 910 + * FDIERROR_CABINET_NOT_FOUND 911 + * FDIERROR_NOT_A_CABINET 912 + * FDIERROR_UNKNOWN_CABINET_VERSION 913 + * FDIERROR_CORRUPT_CABINET 914 + * FDIERROR_BAD_COMPR_TYPE 915 + * FDIERROR_RESERVE_MISMATCH 916 + * FDIERROR_WRONG_CABINET 917 + * 918 + * Entry: 919 + * pfdin->psz1 = name of next cabinet where current file is continued 920 + * pfdin->psz2 = name of next disk where current file is continued 921 + * pfdin->psz3 = cabinet path name; FDI concatenates psz3 with psz1 922 + * to produce the fully-qualified path for the cabinet 923 + * file. The 256-byte buffer pointed at by psz3 may 924 + * be modified, but psz1 may not! 925 + * pfdin->fdie = FDIERROR_WRONG_CABINET if the previous call to 926 + * fdintNEXT_CABINET specified a cabinet file that 927 + * did not match the setID/iCabinet that was expected. 928 + * Exit-Success: 929 + * Return anything but -1 930 + * Exit-Failure: 931 + * Returns -1 => Abort FDICopy() call 932 + * Notes: 933 + * This call is almost always made when a target file is open and 934 + * being written to, and the next cabinet is needed to get more 935 + * data for the file. 936 + */ 937 +typedef enum { 938 + fdintCABINET_INFO, // General information about cabinet 939 + fdintPARTIAL_FILE, // First file in cabinet is continuation 940 + fdintCOPY_FILE, // File to be copied 941 + fdintCLOSE_FILE_INFO, // close the file, set relevant info 942 + fdintNEXT_CABINET, // File continued to next cabinet 943 + fdintENUMERATE, // Enumeration status 944 +} FDINOTIFICATIONTYPE; /* fdint */ 945 + 946 +typedef int (FAR DIAMONDAPI *PFNFDINOTIFY)(FDINOTIFICATIONTYPE fdint, 947 + PFDINOTIFICATION pfdin); /* pfnfdin */ 948 + 949 +#define FNFDINOTIFY(fn) int FAR DIAMONDAPI fn(FDINOTIFICATIONTYPE fdint, \ 950 + PFDINOTIFICATION pfdin) 951 + 952 + 953 +/*** cpuType values for FDICreate() 954 + * 955 + * (Ignored by 32-bit FDI.) 956 + */ 957 +#define cpuUNKNOWN (-1) /* FDI does detection */ 958 +#define cpu80286 (0) /* '286 opcodes only */ 959 +#define cpu80386 (1) /* '386 opcodes used */ 960 + 961 + 962 +/*** FDICreate - Create an FDI context 963 + * 964 + * Entry: 965 + * pfnalloc 966 + * pfnfree 967 + * pfnopen 968 + * pfnread 969 + * pfnwrite 970 + * pfnclose 971 + * pfnlseek 972 + * cpuType - Select CPU type (auto-detect, 286, or 386+) 973 + * NOTE: For the 32-bit FDI.LIB, this parameter is ignored! 974 + * perf 975 + * 976 + * Exit-Success: 977 + * Returns non-NULL FDI context handle. 978 + * 979 + * Exit-Failure: 980 + * Returns NULL; perf filled in with error code 981 + * 982 + */ 983 +HFDI FAR DIAMONDAPI FDICreate(PFNALLOC pfnalloc, 984 + PFNFREE pfnfree, 985 + PFNOPEN pfnopen, 986 + PFNREAD pfnread, 987 + PFNWRITE pfnwrite, 988 + PFNCLOSE pfnclose, 989 + PFNSEEK pfnseek, 990 + int cpuType, 991 + PERF perf); 992 + 993 + 994 +/*** FDIIsCabinet - Determines if file is a cabinet, returns info if it is 995 + * 996 + * Entry: 997 + * hfdi - Handle to FDI context (created by FDICreate()) 998 + * hf - File handle suitable for PFNREAD/PFNSEEK, positioned 999 + * at offset 0 in the file to test. 1000 + * pfdici - Buffer to receive info about cabinet if it is one. 1001 + * 1002 + * Exit-Success: 1003 + * Returns TRUE; file is a cabinet, pfdici filled in. 1004 + * 1005 + * Exit-Failure: 1006 + * Returns FALSE, file is not a cabinet; If an error occurred, 1007 + * perf (passed on FDICreate call!) filled in with error. 1008 + */ 1009 +BOOL FAR DIAMONDAPI FDIIsCabinet(HFDI hfdi, 1010 + int hf, 1011 + PFDICABINETINFO pfdici); 1012 + 1013 + 1014 +/*** FDICopy - extracts files from a cabinet 1015 + * 1016 + * Entry: 1017 + * hfdi - handle to FDI context (created by FDICreate()) 1018 + * pszCabinet - main name of cabinet file 1019 + * pszCabPath - Path to cabinet file(s) 1020 + * flags - Flags to modify behavior 1021 + * pfnfdin - Notification function 1022 + * pfnfdid - Decryption function (pass NULL if not used) 1023 + * pvUser - User specified value to pass to notification function 1024 + * 1025 + * Exit-Success: 1026 + * Returns TRUE; 1027 + * 1028 + * Exit-Failure: 1029 + * Returns FALSE, perf (passed on FDICreate call!) filled in with 1030 + * error. 1031 + * 1032 + * Notes: 1033 + * (1) If FDICopy() fails while a target file is being written out, then 1034 + * FDI will use the PFNCLOSE function to close the file handle for that 1035 + * target file that was returned from the fdintCOPY_FILE notification. 1036 + * The client application is then free to delete the target file, since 1037 + * it will not be in a valid state (since there was an error while 1038 + * writing it out). 1039 + */ 1040 +BOOL FAR DIAMONDAPI FDICopy(HFDI hfdi, 1041 + char FAR *pszCabinet, 1042 + char FAR *pszCabPath, 1043 + int flags, 1044 + PFNFDINOTIFY pfnfdin, 1045 + PFNFDIDECRYPT pfnfdid, 1046 + void FAR *pvUser); 1047 + 1048 + 1049 +/*** FDIDestroy - Destroy an FDI context 1050 + * 1051 + * Entry: 1052 + * hfdi - handle to FDI context (created by FDICreate()) 1053 + * 1054 + * Exit-Success: 1055 + * Returns TRUE; 1056 + * 1057 + * Exit-Failure: 1058 + * Returns FALSE; 1059 + */ 1060 +BOOL FAR DIAMONDAPI FDIDestroy(HFDI hfdi); 1061 + 1062 + 1063 +//** Revert to default structure packing 1064 +#pragma pack() 1065 + 1066 +#endif // !INCLUDED_FDI 1067 + 1068 +#ifdef __cplusplus 1069 +} 1070 +#endif
Added fdi/FDI.LIB version [333dbfdd781b6114]
cannot compute difference between binary files
Added fdi/readme.txt version [59984b7546f8b514]
1 +The files are copied from old Cabinet SDK so that the whole project compiles with VC6.
Added kilib/kilib.h version [88c58602a7d81809]
1 +//--- K.I.LIB --- 2 +// kilib.h : main-header of K.I.LIB 3 + 4 +#ifndef AFX_KILIB_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 5 +#define AFX_KILIB_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 6 + 7 +#include "kl_misc.h" 8 +#include "kl_cmd.h" 9 +#include "kl_str.h" 10 +#include "kl_wnd.h" 11 +#include "kl_file.h" 12 +#include "kl_app.h" 13 +#include "kl_reg.h" 14 +#include "kl_find.h" 15 +#include "kl_wcmn.h" 16 +#include "kl_dnd.h" 17 + 18 +extern kiApp* app(); 19 +extern void kilib_create_new_app(); 20 + 21 +#ifdef KILIB_LOG 22 +#define Log(_s_) app()->log((const char*)(_s_)) 23 +#else 24 +#define Log(_s_) 25 +#endif 26 + 27 +#endif
Added kilib/kilibext.h version [4783cacefbe06bfc]
1 +//--- K.I.LIB --- 2 +// kilibext.h : extra-classes of K.I.LIB 3 + 4 +#ifndef AFX_KILIBEXT_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 5 +#define AFX_KILIBEXT_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 6 + 7 +#include "kilib.h" 8 +#include "kl_carc.h" 9 +#include "kl_rythp.h" 10 + 11 +#endif
Added kilib/kl_app.cpp version [fb426ee0b574818a]
1 +//--- K.I.LIB --- 2 +// kl_app.h : application class for K.I.LIB 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 +//------------ 唯一のアプリケーションオブジェクトの管理 ------------// 8 + 9 +kiApp* kiApp::st_pApp = NULL; 10 + 11 +kiApp* app() 12 +{ 13 + return kiApp::st_pApp; 14 +} 15 + 16 +//-------------------- スタートアップコード ------------------------// 17 + 18 +void kilib_startUp() 19 +{ 20 + //-- K.I.LIB 初期化 21 + kiStr::init(); 22 + kiWindow::init(); 23 + 24 + //-- キーボード状態クリア 25 + ::GetAsyncKeyState( VK_SHIFT ); 26 + 27 + //-- アプリケーションインスタンスを作成 28 + kilib_create_new_app(); 29 + if( app() ) 30 + { 31 + // コマンドライン分割 32 + kiCmdParser cmd( ::GetCommandLine(), true ); 33 + 34 + // 実行 35 + app()->run( cmd ); 36 + } 37 + 38 + //-- K.I.LIB 終了 39 + kiWindow::finish(); 40 + 41 + delete app(); 42 + ::ExitProcess( 0 ); 43 +} 44 + 45 +//--------------- C-Runtime初期化コード削除周りの処理 ---------------// 46 + 47 +#if 1 48 + 49 +int APIENTRY WinMain( HINSTANCE, HINSTANCE, char*, int ) 50 +{ 51 + kilib_startUp(); 52 + return 0; 53 +} 54 + 55 +#else 56 + 57 +void* operator new( size_t siz ) 58 +{ 59 + return (void*)::GlobalAlloc( GMEM_FIXED, siz ); 60 +} 61 + 62 +void operator delete( void* ptr ) 63 +{ 64 + ::GlobalFree( (HGLOBAL)ptr ); 65 +} 66 + 67 +void main() 68 +{ 69 + // main がないと何故か libc.lib がリンクエラーになるのでダミー 70 +} 71 + 72 +#endif 73 + 74 +//--------------------------------------------------------------//
Added kilib/kl_app.h version [45f14add3bfa4c0a]
1 +//--- K.I.LIB --- 2 +// kl_app.h : application class for K.I.LIB 3 + 4 +#ifndef AFX_KIAPP_H__AC24C8AF_2187_4873_83E8_AB4F2325017B__INCLUDED_ 5 +#define AFX_KIAPP_H__AC24C8AF_2187_4873_83E8_AB4F2325017B__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// 汎用アプリケーションクラス 9 + 10 +class kiApp 11 +{ 12 +friend kiApp* app(); 13 +friend void kilib_startUp(); 14 + 15 +public: //-- 外向きインターフェイス -------------------------- 16 + 17 + // インスタンス 18 + HINSTANCE inst() const 19 + { 20 + return m_hInst; 21 + } 22 + 23 + // メインウインドウ 24 + HWND mainhwnd() const 25 + { 26 + return m_pMainWnd ? m_pMainWnd->hwnd() : NULL; 27 + } 28 + kiWindow* mainwnd() const 29 + { 30 + return m_pMainWnd; 31 + } 32 + void setMainWnd( kiWindow* wnd ) 33 + { 34 + m_pMainWnd = wnd; 35 + } 36 + 37 + // OSバージョン 38 + const OSVERSIONINFO& osver() const 39 + { 40 + return m_OsVer; 41 + } 42 + 43 + // メッセージボックス 44 + int msgBox( const char* msg, const char* caption=NULL, UINT type=MB_OK ) 45 + { 46 + return ::MessageBox( mainhwnd(), msg, caption, type ); 47 + } 48 + 49 + // シェルのアロケータでメモリ解放 50 + void shellFree( void* ptr ) const 51 + { 52 + m_pShellAlloc->Free( ptr ); 53 + } 54 + 55 + // 仮想コード vKey のキーは押されているか? 56 + static bool keyPushed( int vKey ) 57 + { 58 + return( 0!=(::GetAsyncKeyState( vKey )>>15) ); 59 + } 60 + 61 + // CommonControl / OLE 初期化 62 + void shellInit() 63 + { 64 + if( !m_bShellInit ) 65 + { 66 + ::InitCommonControls(); 67 + ::OleInitialize( NULL ); 68 + m_bShellInit = true; 69 + } 70 + } 71 + 72 +#ifdef KILIB_LOG 73 + void log( const char* str ) 74 + { 75 + if( !m_log.isOpened() ) 76 + { 77 + kiPath logtxt( kiPath::Exe ); logtxt += "log.txt"; 78 + m_log.open( logtxt, false ); 79 + } 80 + m_log.write( str, ki_strlen(str) ); 81 + m_log.write( "\r\n", 2 ); 82 + } 83 +#endif 84 + 85 +protected: //-- 派生クラス向け ----------------------------- 86 + 87 + // 起動時に呼ばれる関数。必須。 88 + virtual void run( kiCmdParser& cmd ) = 0; 89 + 90 +protected: //-- 内部処理 ----------------------------------- 91 + 92 + kiApp() 93 + { 94 + st_pApp = this; 95 + m_hInst = ::GetModuleHandle( NULL ); 96 + m_pMainWnd = NULL; 97 + m_bShellInit = false; 98 + m_OsVer.dwOSVersionInfoSize = sizeof( m_OsVer ); 99 + ::GetVersionEx( &m_OsVer ); 100 + ::SHGetMalloc( &m_pShellAlloc ); 101 + } 102 + 103 +protected: 104 + 105 + virtual ~kiApp() 106 + { 107 + m_pShellAlloc->Release(); 108 + if( m_bShellInit ) 109 + ::OleUninitialize(); 110 + } 111 + 112 +private: 113 + 114 + HINSTANCE m_hInst; 115 + IMalloc* m_pShellAlloc; 116 + bool m_bShellInit; 117 + OSVERSIONINFO m_OsVer; 118 + kiWindow* m_pMainWnd; 119 + static kiApp* st_pApp; 120 +#ifdef KILIB_LOG 121 + kiFile m_log; 122 +#endif 123 +}; 124 + 125 +#endif
Added kilib/kl_carc.cpp version [a43fef9c4a2d0569]
1 +//--- K.I.LIB --- 2 +// kl_carc.cpp : handling "common archivers' dll" 3 + 4 +#include "stdafx.h" 5 +#include "kilibext.h" 6 +#include "../kiutil.h" 7 + 8 +//------------------------ load/unload 制御 ----------------------// 9 + 10 + 11 +kiArcDLLRaw::kiArcDLLRaw( const char* dllname ) 12 + : m_DllPath( dllname ), not_loaded_yet( true ) 13 +{ 14 + ki_memzero( m_Proc, ISARC_FUNCTION_END*sizeof(FARPROC) ); 15 + f_VSb = NULL; 16 +} 17 + 18 +kiArcDLLRaw::~kiArcDLLRaw() 19 +{ 20 + unload(); 21 +} 22 + 23 +bool kiArcDLLRaw::load() 24 +{ 25 + not_loaded_yet = false; 26 + 27 + m_hDLL = kiutil::safepathLoadLibrary( m_DllPath ); 28 + if( !m_hDLL ) 29 + return false; 30 + 31 + // DLLの名前部分を切り出し 32 + char str[MAX_PATH], *p; 33 + const char *x, *y, *z; 34 + for( x=y=m_DllPath; *x!='\0'; x=kiStr::next(x) ) 35 + if( *x=='\\' || *x=='/' ) 36 + y = x + 1; 37 + for( p=str, z=y; (*z!='.' && *z!='3' && *z!='\0'); p++, z++ ) 38 + *p = *z; 39 + *p = '\0'; 40 + 41 + // コマンド送りAPIを取得。ccで始まるAPI名かも? 42 + f_Cmd = ::GetProcAddress( m_hDLL, str ); 43 + if( f_Cmd ) 44 + m_DllNameBody = str; 45 + else 46 + { 47 + f_Cmd = ::GetProcAddress( m_hDLL, "ccCommand" ); 48 + if( f_Cmd ) 49 + m_DllNameBody = "cc"; 50 + else 51 + { 52 + if( str[0]=='7' && (f_Cmd=::GetProcAddress(m_hDLL,"SevenZip")) ) 53 + m_DllNameBody = "SevenZip"; 54 + else 55 + return false; 56 + } 57 + } 58 + 59 + return true; 60 +} 61 + 62 +void kiArcDLLRaw::unload() 63 +{ 64 + if( !not_loaded_yet && m_hDLL ) 65 + { 66 + ki_memzero( m_Proc, ISARC_FUNCTION_END*sizeof(FARPROC) ); 67 + ::FreeLibrary( m_hDLL ); 68 + not_loaded_yet = true; 69 + } 70 +} 71 + 72 +bool kiArcDLLRaw::isAlive() 73 +{ 74 + if( not_loaded_yet ) 75 + load(); 76 + 77 + return (m_hDLL != NULL); 78 +} 79 + 80 +FARPROC kiArcDLLRaw::getProc( const char* procname ) 81 +{ 82 + kiStr funcName = (const char*)m_DllNameBody; 83 + funcName += procname; 84 + return ::GetProcAddress( m_hDLL, funcName ); 85 +} 86 + 87 +//----------------------------- APIのラッパ群 --------------------------// 88 + 89 + 90 +int kiArcDLLRaw::command( const HWND wnd, LPCSTR cmd, LPSTR buf, const DWORD siz ) 91 +{ 92 + if( not_loaded_yet ) 93 + if( !load() ) 94 + return ERROR_NOT_SUPPORT; 95 + 96 + // コマンド関数は必ずロードされている 97 + 98 + typedef int (WINAPI * CARC_CMD)(const HWND,const char*,char*,const DWORD); 99 + return ((CARC_CMD)f_Cmd)( wnd, cmd, buf, siz ); 100 +} 101 + 102 +WORD kiArcDLLRaw::getVer() 103 +{ 104 + if( not_loaded_yet ) 105 + if( !load() ) 106 + return 0; 107 + 108 + if( !f_Ver ) 109 + f_Ver = getProc( "GetVersion" ); 110 + 111 + typedef WORD (WINAPI * CARC_VER)(void); 112 + return f_Ver ? ((CARC_VER)f_Ver)() : 0; 113 +} 114 + 115 +WORD kiArcDLLRaw::getVerSub() 116 +{ 117 + if( not_loaded_yet ) 118 + if( !load() ) 119 + return 0; 120 + 121 + if( !f_VSb ) 122 + f_VSb = getProc( "GetSubVersion" ); 123 + 124 + typedef WORD (WINAPI * CARC_VER)(void); 125 + return f_VSb ? ((CARC_VER)f_VSb)() : 0; 126 +} 127 + 128 +bool kiArcDLLRaw::isVerSubAvail() 129 +{ 130 + if( not_loaded_yet ) 131 + if( !load() ) 132 + return 0; 133 + if( !f_VSb ) 134 + f_VSb = getProc( "GetSubVersion" ); 135 + return f_VSb != 0; 136 +} 137 + 138 +BOOL kiArcDLLRaw::check( LPCSTR filename, const int mode ) 139 +{ 140 + if( not_loaded_yet ) 141 + if( !load() ) 142 + return FALSE; 143 + 144 + if( !f_Chk ) 145 + f_Chk = getProc( "CheckArchive" ); 146 + 147 + typedef BOOL (WINAPI * CARC_CHK)(const char*,const int); 148 + return f_Chk ? ((CARC_CHK)f_Chk)( filename, mode ) : FALSE; 149 +} 150 + 151 +HARC kiArcDLLRaw::openArc( const HWND wnd, LPCSTR arcname, const DWORD flag ) 152 +{ 153 + if( not_loaded_yet ) 154 + if( !load() ) 155 + return NULL; 156 + 157 + if( !f_Opn ) 158 + f_Opn = getProc( "OpenArchive" ); 159 + 160 + typedef HARC (WINAPI * CARC_OPN)(const HWND,LPCSTR,const DWORD); 161 + return f_Opn ? ((CARC_OPN)f_Opn)( wnd, arcname, flag ) : NULL; 162 +} 163 + 164 +void kiArcDLLRaw::closeArc( HARC arc ) 165 +{ 166 + if( not_loaded_yet ) 167 + if( !load() ) 168 + return; 169 + 170 + if( !f_Cls ) 171 + f_Cls = getProc( "CloseArchive" ); 172 + 173 + typedef int (WINAPI * CARC_CLS)(HARC); 174 + if( f_Cls ) 175 + ((CARC_CLS)f_Cls)( arc ); 176 +} 177 + 178 +int kiArcDLLRaw::findfirst( HARC arc, LPCSTR wildname, INDIVIDUALINFO* inf ) 179 +{ 180 + if( not_loaded_yet ) 181 + if( !load() ) 182 + return ERROR_NOT_SUPPORT; 183 + 184 + if( !f_Ffs ) 185 + f_Ffs = getProc( "FindFirst" ); 186 + 187 + typedef int (WINAPI * CARC_FFS)(HARC,LPCSTR,INDIVIDUALINFO FAR *); 188 + return f_Ffs ? ((CARC_FFS)f_Ffs)( arc, wildname, inf ) : ERROR_NOT_SUPPORT; 189 +} 190 + 191 +int kiArcDLLRaw::findnext( HARC arc, INDIVIDUALINFO* inf ) 192 +{ 193 + if( not_loaded_yet ) 194 + if( !load() ) 195 + return ERROR_NOT_SUPPORT; 196 + 197 + if( !f_Fnx ) 198 + f_Fnx = getProc( "FindNext" ); 199 + 200 + typedef int (WINAPI * CARC_FNX)(HARC,INDIVIDUALINFO FAR *); 201 + return f_Fnx ? ((CARC_FNX)f_Fnx)( arc, inf ) : ERROR_NOT_SUPPORT; 202 +} 203 + 204 +int kiArcDLLRaw::getAttr( HARC arc ) 205 +{ 206 + if( not_loaded_yet ) 207 + if( !load() ) 208 + return ERROR_NOT_SUPPORT; 209 + 210 + if( !f_GAr ) 211 + f_GAr = getProc( "GetAttribute" ); 212 + 213 + typedef int (WINAPI * CARC_GAR)(HARC); 214 + return f_GAr ? ((CARC_GAR)f_GAr)( arc ) : 0; 215 +} 216 + 217 +BOOL kiArcDLLRaw::setOwner( HWND wnd ) 218 +{ 219 + if( not_loaded_yet ) 220 + if( !load() ) 221 + return ERROR_NOT_SUPPORT; 222 + 223 + if( !f_SOw ) 224 + f_SOw = getProc( "SetOwnerWindow" ); 225 + 226 + typedef BOOL (WINAPI * CARC_SOW)(HWND); 227 + return f_SOw ? ((CARC_SOW)f_SOw)( wnd ) : FALSE; 228 +} 229 + 230 +BOOL kiArcDLLRaw::clearOwner() 231 +{ 232 + if( not_loaded_yet ) 233 + if( !load() ) 234 + return ERROR_NOT_SUPPORT; 235 + 236 + if( !f_COw ) 237 + f_COw = getProc( "ClearOwnerWindow" ); 238 + 239 + typedef BOOL (WINAPI * CARC_COW)(); 240 + return f_COw ? ((CARC_COW)f_COw)() : FALSE; 241 +} 242 +
Added kilib/kl_carc.h version [4be9089a5e7577df]
1 +//--- K.I.LIB --- 2 +// kl_carc.h : handling "common archivers' dll" 3 + 4 +#ifndef AFX_KIARCDLLRAW_H__C94DE2A0_4292_49CE_8471_2CAA1340D216__INCLUDED_ 5 +#define AFX_KIARCDLLRAW_H__C94DE2A0_4292_49CE_8471_2CAA1340D216__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// 統合アーカイバDLL共通の定義 9 + 10 +// FNAME_MAX 11 +#if !defined(FNAME_MAX32) 12 +#define FNAME_MAX32 512 13 +#define FNAME_MAX FNAME_MAX32 14 +#else 15 +#if !defined(FNAME_MAX) 16 +#define FNAME_MAX 128 17 +#endif 18 +#endif 19 + 20 +// CHECKARCHIVE 21 +#if !defined(CHECKARCHIVE_RAPID) 22 +#define CHECKARCHIVE_RAPID 0 23 +#define CHECKARCHIVE_BASIC 1 24 +#define CHECKARCHIVE_FULLCRC 2 25 +#endif 26 + 27 +// ISARC 28 +#if !defined(ISARC_FUNCTION_START) 29 +#define ISARC_FUNCTION_START 0 30 +#define ISARC 0 31 +#define ISARC_GET_VERSION 1 32 +#define ISARC_GET_CURSOR_INTERVAL 2 33 +#define ISARC_SET_CURSOR_INTERVAL 3 34 +#define ISARC_GET_BACK_GROUND_MODE 4 35 +#define ISARC_SET_BACK_GROUND_MODE 5 36 +#define ISARC_GET_CURSOR_MODE 6 37 +#define ISARC_SET_CURSOR_MODE 7 38 +#define ISARC_GET_RUNNING 8 39 + 40 +#define ISARC_CHECK_ARCHIVE 16 41 +#define ISARC_CONFIG_DIALOG 17 42 +#define ISARC_GET_FILE_COUNT 18 43 +#define ISARC_QUERY_FUNCTION_LIST 19 44 +#define ISARC_HOUT 20 45 +#define ISARC_STRUCTOUT 21 46 +#define ISARC_GET_ARC_FILE_INFO 22 47 + 48 +#define ISARC_OPEN_ARCHIVE 23 49 +#define ISARC_CLOSE_ARCHIVE 24 50 +#define ISARC_FIND_FIRST 25 51 +#define ISARC_FIND_NEXT 26 52 +#define ISARC_EXTRACT 27 53 +#define ISARC_ADD 28 54 +#define ISARC_MOVE 29 55 +#define ISARC_DELETE 30 56 +#define ISARC_SETOWNERWINDOW 31 57 +#define ISARC_CLEAROWNERWINDOW 32 58 +#define ISARC_SETOWNERWINDOWEX 33 59 +#define ISARC_KILLOWNERWINDOWEX 34 60 + 61 +#define ISARC_GET_ARC_FILE_NAME 40 62 +#define ISARC_GET_ARC_FILE_SIZE 41 63 +#define ISARC_GET_ARC_ORIGINAL_SIZE 42 64 +#define ISARC_GET_ARC_COMPRESSED_SIZE 43 65 +#define ISARC_GET_ARC_RATIO 44 66 +#define ISARC_GET_ARC_DATE 45 67 +#define ISARC_GET_ARC_TIME 46 68 +#define ISARC_GET_ARC_OS_TYPE 47 69 +#define ISARC_GET_ARC_IS_SFX_FILE 48 70 +#define ISARC_GET_ARC_WRITE_TIME_EX 49 71 +#define ISARC_GET_ARC_CREATE_TIME_EX 50 72 +#define ISARC_GET_ARC_ACCESS_TIME_EX 51 73 +#define ISARC_GET_ARC_CREATE_TIME_EX2 52 74 +#define ISARC_GET_ARC_WRITE_TIME_EX2 53 75 +#define ISARC_GET_FILE_NAME 57 76 +#define ISARC_GET_ORIGINAL_SIZE 58 77 +#define ISARC_GET_COMPRESSED_SIZE 59 78 +#define ISARC_GET_RATIO 60 79 +#define ISARC_GET_DATE 61 80 +#define ISARC_GET_TIME 62 81 +#define ISARC_GET_CRC 63 82 +#define ISARC_GET_ATTRIBUTE 64 83 +#define ISARC_GET_OS_TYPE 65 84 +#define ISARC_GET_METHOD 66 85 +#define ISARC_GET_WRITE_TIME 67 86 +#define ISARC_GET_CREATE_TIME 68 87 +#define ISARC_GET_ACCESS_TIME 69 88 +#define ISARC_GET_WRITE_TIME_EX 70 89 +#define ISARC_GET_CREATE_TIME_EX 71 90 +#define ISARC_GET_ACCESS_TIME_EX 72 91 +#define ISARC_SET_ENUM_MEMBERS_PROC 80 92 +#define ISARC_CLEAR_ENUM_MEMBERS_PROC 81 93 + 94 +#define ISARC_FUNCTION_END 81 95 +#endif 96 + 97 +// ERROR 98 +#if !defined(ERROR_START) 99 +#define ERROR_START 0x8000 100 + // warning 101 +#define ERROR_DISK_SPACE 0x8005 102 +#define ERROR_READ_ONLY 0x8006 103 +#define ERROR_USER_SKIP 0x8007 104 +#define ERROR_UNKNOWN_TYPE 0x8008 105 +#define ERROR_METHOD 0x8009 106 +#define ERROR_PASSWORD_FILE 0x800A 107 +#define ERROR_VERSION 0x800B 108 +#define ERROR_FILE_CRC 0x800C 109 +#define ERROR_FILE_OPEN 0x800D 110 +#define ERROR_MORE_FRESH 0x800E 111 +#define ERROR_NOT_EXIST 0x800F 112 +#define ERROR_ALREADY_EXIST 0x8010 113 + 114 +#define ERROR_TOO_MANY_FILES 0x8011 115 + // error 116 +#define ERROR_MAKEDIRECTORY 0x8012 117 +#define ERROR_CANNOT_WRITE 0x8013 118 +#define ERROR_HUFFMAN_CODE 0x8014 119 +#define ERROR_COMMENT_HEADER 0x8015 120 +#define ERROR_HEADER_CRC 0x8016 121 +#define ERROR_HEADER_BROKEN 0x8017 122 +#define ERROR_ARC_FILE_OPEN 0x8018 123 +#define ERROR_NOT_ARC_FILE 0x8019 124 +#define ERROR_CANNOT_READ 0x801A 125 +#define ERROR_FILE_STYLE 0x801B 126 +#define ERROR_COMMAND_NAME 0x801C 127 +#define ERROR_MORE_HEAP_MEMORY 0x801D 128 +#define ERROR_ENOUGH_MEMORY 0x801E 129 +#if !defined(ERROR_ALREADY_RUNNING) 130 +#define ERROR_ALREADY_RUNNING 0x801F 131 +#endif 132 +#define ERROR_USER_CANCEL 0x8020 133 +#define ERROR_HARC_ISNOT_OPENED 0x8021 134 +#define ERROR_NOT_SEARCH_MODE 0x8022 135 +#define ERROR_NOT_SUPPORT 0x8023 136 +#define ERROR_TIME_STAMP 0x8024 137 +#define ERROR_TMP_OPEN 0x8025 138 +#define ERROR_LONG_FILE_NAME 0x8026 139 +#define ERROR_ARC_READ_ONLY 0x8027 140 +#define ERROR_SAME_NAME_FILE 0x8028 141 +#define ERROR_NOT_FIND_ARC_FILE 0x8029 142 +#define ERROR_RESPONSE_READ 0x802A 143 +#define ERROR_NOT_FILENAME 0x802B 144 +#define ERROR_TMP_COPY 0x802C 145 +#define ERROR_EOF 0x802D 146 +#define ERROR_ADD_TO_LARC 0x802E 147 +#define ERROR_TMP_BACK_SPACE 0x802F 148 +#define ERROR_SHARING 0x8030 149 +#define ERROR_NOT_FIND_FILE 0x8031 150 +#define ERROR_LOG_FILE 0x8032 151 +#define ERROR_NO_DEVICE 0x8033 152 +#define ERROR_GET_ATTRIBUTES 0x8034 153 +#define ERROR_SET_ATTRIBUTES 0x8035 154 +#define ERROR_GET_INFORMATION 0x8036 155 +#define ERROR_GET_POINT 0x8037 156 +#define ERROR_SET_POINT 0x8038 157 +#define ERROR_CONVERT_TIME 0x8039 158 +#define ERROR_GET_TIME 0x803a 159 +#define ERROR_SET_TIME 0x803b 160 +#define ERROR_CLOSE_FILE 0x803c 161 +#define ERROR_HEAP_MEMORY 0x803d 162 +#define ERROR_HANDLE 0x803e 163 +#define ERROR_TIME_STAMP_RANGE 0x803f 164 +#define ERROR_MAKE_ARCHIVE 0x8040 165 + 166 +#define ERROR_END ERROR_MAKE_ARCHIVE 167 +#define ERROR_BUF_TOO_SMALL 0x8041 /**/ 168 +#endif 169 + 170 +// CONFIG 171 +#if !defined(UNPACK_CONFIG_MODE) 172 +#define UNPACK_CONFIG_MODE 1 173 +#define PACK_CONFIG_MODE 2 174 +#endif 175 + 176 +// OPENARCHIVE 177 +#if !defined(EXTRACT_FOUND_FILE) 178 +#define M_INIT_FILE_USE 0x00000001L 179 +#define M_REGARDLESS_INIT_FILE 0x00000002L 180 +#define M_NO_BACKGROUND_MODE 0x00000004L 181 +#define M_NOT_USE_TIME_STAMP 0x00000008L 182 +#define M_EXTRACT_REPLACE_FILE 0x00000010L 183 +#define M_EXTRACT_NEW_FILE 0x00000020L 184 +#define M_EXTRACT_UPDATE_FILE 0x00000040L 185 +#define M_CHECK_ALL_PATH 0x00000100L 186 +#define M_CHECK_FILENAME_ONLY 0x00000200L 187 +#define M_CHECK_DISK_SIZE 0x00000400L 188 +#define M_REGARDLESS_DISK_SIZE 0x00000800L 189 +#define M_USE_DRIVE_LETTER 0x00001000L 190 +#define M_NOT_USE_DRIVE_LETTER 0x00002000L 191 +#define M_INQUIRE_DIRECTORY 0x00004000L 192 +#define M_NOT_INQUIRE_DIRECTORY 0x00008000L 193 +#define M_INQUIRE_WRITE 0x00010000L 194 +#define M_NOT_INQUIRE_WRITE 0x00020000L 195 +#define M_CHECK_READONLY 0x00040000L 196 +#define M_REGARDLESS_READONLY 0x00080000L 197 +#define M_REGARD_E_COMMAND 0x00100000L 198 +#define M_REGARD_X_COMMAND 0x00200000L 199 +#define M_ERROR_MESSAGE_ON 0x00400000L 200 +#define M_ERROR_MESSAGE_OFF 0x00800000L 201 +#define M_BAR_WINDOW_ON 0x01000000L 202 +#define M_BAR_WINDOW_OFF 0x02000000L 203 +#define M_CHECK_PATH 0x04000000L 204 +#define M_RECOVERY_ON 0x08000000L 205 + 206 +#define M_MAKE_INDEX_FILE 0x10000000L 207 +#define M_NOT_MAKE_INDEX_FILE 0x20000000L 208 +#define EXTRACT_FOUND_FILE 0x40000000L 209 +#define EXTRACT_NAMED_FILE 0x80000000L 210 +#endif 211 + 212 +// ATTRIBUTE 213 +#ifndef FA_RDONLY 214 +#define FA_RDONLY 0x01 215 +#define FA_HIDDEN 0x02 216 +#define FA_SYSTEM 0x04 217 +#define FA_LABEL 0x08 218 +#define FA_DIREC 0x10 219 +#define FA_ARCH 0x20 220 +#endif 221 +#ifndef FA_ENCRYPTED 222 +#define FA_ENCRYPTED 0x40 223 +#endif 224 + 225 +// STRUCTURES 226 +#if defined(__BORLANDC__) 227 +#pragma option -a- 228 +#else 229 +#pragma pack(1) 230 +#endif 231 + 232 +typedef HGLOBAL HARCHIVE; 233 + 234 +#ifndef ARC_DECSTRACT 235 +#define ARC_DECSTRACT 236 +typedef HGLOBAL HARC; 237 + 238 +typedef struct { 239 + DWORD dwOriginalSize; 240 + DWORD dwCompressedSize; 241 + DWORD dwCRC; 242 + UINT uFlag; 243 + UINT uOSType; 244 + WORD wRatio; 245 + WORD wDate; 246 + WORD wTime; 247 + char szFileName[FNAME_MAX32 + 1]; 248 + char dummy1[3]; 249 + char szAttribute[8]; 250 + char szMode[8]; 251 +} INDIVIDUALINFO, FAR *LPINDIVIDUALINFO; 252 + 253 +typedef struct { 254 + DWORD dwFileSize; 255 + DWORD dwWriteSize; 256 + char szSourceFileName[FNAME_MAX32 + 1]; 257 + char dummy1[3]; 258 + char szDestFileName[FNAME_MAX32 + 1]; 259 + char dummy[3]; 260 +} EXTRACTINGINFO, FAR *LPEXTRACTINGINFO; 261 + 262 +typedef struct { 263 + EXTRACTINGINFO exinfo; 264 + DWORD dwCompressedSize; 265 + DWORD dwCRC; 266 + UINT uOSType; 267 + WORD wRatio; 268 + WORD wDate; 269 + WORD wTime; 270 + char szAttribute[8]; 271 + char szMode[8]; 272 +} EXTRACTINGINFOEX, *LPEXTRACTINGINFOEX; 273 +#endif 274 + 275 +#if !defined(__BORLANDC__) 276 +#pragma pack() 277 +#else 278 +#pragma option -a. 279 +#endif 280 + 281 +#if !defined(__BORLANDC__) 282 +#define _export 283 +#endif 284 + 285 +// WindowsMessage 286 +#ifndef WM_ARCEXTRACT 287 +#define WM_ARCEXTRACT "wm_arcextract" 288 +#define ARCEXTRACT_BEGIN 0 289 +#define ARCEXTRACT_INPROCESS 1 290 +#define ARCEXTRACT_END 2 291 +#define ARCEXTRACT_OPEN 3 292 +#define ARCEXTRACT_COPY 4 293 +typedef BOOL CALLBACK ARCHIVERPROC(HWND,UINT,UINT,LPEXTRACTINGINFOEX); 294 +typedef ARCHIVERPROC *LPARCHIVERPROC; 295 +#endif 296 + 297 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 298 +// 統合アーカイバDLLを非常に薄く覆うレイヤ 299 + 300 +class kiArcDLLRaw 301 +{ 302 +public: //-- 外向きインターフェイス -------------------------- 303 + 304 + // DLL名で初期化。 305 + kiArcDLLRaw( const char* dllname ); 306 + kiPath& name() 307 + { return m_DllPath; } 308 + 309 + // DLLが生きているかどうか。 310 + bool isAlive(); 311 + 312 + // API のラッパ [ DLLやAPIが無いときの返値 ] 313 + 314 + // バージョンx100 [ 0 ] 315 + WORD getVer(); 316 + // バージョンサブx100 [ 0 ] 317 + WORD getVerSub(); 318 + // バージョンサブが取れるかどうか? 319 + bool isVerSubAvail(); 320 + // コマンド送り [ ERROR_NOT_SUPPORT ] 321 + int command( const HWND wnd, LPCSTR cmd, LPSTR buf, const DWORD siz ); 322 + // 書庫チェック [ FALSE ] 323 + BOOL check( LPCSTR filename, const int mode ); 324 + 325 + // 開く [ NULL ] 326 + HARC openArc( const HWND wnd, LPCSTR arcname, const DWORD flag ); 327 + // 閉じる 328 + void closeArc( HARC arc ); 329 + // 一つ目を検索 [ ERROR_NOT_SUPPORT ] 330 + int findfirst( HARC arc, LPCSTR wildname, INDIVIDUALINFO* inf ); 331 + // 二つ目以降を検索 [ ERROR_NOT_SUPPORT ] 332 + int findnext( HARC arc, INDIVIDUALINFO* inf ); 333 + // 属性取得 [ 0 ] 334 + int getAttr( HARC arc ); 335 + 336 + // オーナー指定 [ FALSE ] 337 + BOOL setOwner( HWND wnd ); 338 + // オーナー解除 [ FALSE ] 339 + BOOL clearOwner(); 340 + 341 + // ※load系は呼ばなくても内部で何とかするのでできれば使わないこと。 342 + bool load(); 343 + void unload(); 344 + 345 +private: //-- 内部処理 ----------------------------------- 346 + 347 + HINSTANCE m_hDLL; 348 + bool not_loaded_yet; 349 + 350 + kiPath m_DllPath; 351 + kiStr m_DllNameBody; 352 + FARPROC getProc( const char* procname ); 353 + 354 + FARPROC m_Proc[ ISARC_FUNCTION_END ]; 355 + FARPROC f_VSb; 356 +#define f_Cmd m_Proc[ ISARC ] 357 +#define f_Chk m_Proc[ ISARC_GET_VERSION ] 358 +#define f_Ver m_Proc[ ISARC_CHECK_ARCHIVE ] 359 +#define f_Opn m_Proc[ ISARC_OPEN_ARCHIVE ] 360 +#define f_Cls m_Proc[ ISARC_CLOSE_ARCHIVE ] 361 +#define f_Ffs m_Proc[ ISARC_FIND_FIRST ] 362 +#define f_Fnx m_Proc[ ISARC_FIND_NEXT ] 363 +#define f_GAr m_Proc[ ISARC_GET_ATTRIBUTE ] 364 +#define f_SOw m_Proc[ ISARC_SETOWNERWINDOW ] 365 +#define f_COw m_Proc[ ISARC_CLEAROWNERWINDOW ] 366 + 367 +public: 368 + virtual ~kiArcDLLRaw(); 369 +}; 370 + 371 +#endif
Added kilib/kl_cmd.cpp version [815f69faf09d6d48]
1 +//--- K.I.LIB --- 2 +// kl_cmd.h : commandline parser 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 + 8 +//------------------------ 文字列のメモリ処理など -----------------------// 9 + 10 + 11 +kiCmdParser::kiCmdParser( char* cmd, bool ignoreFirst ) 12 +{ 13 + m_Buffer = NULL; 14 + if( cmd ) 15 + doit( cmd, ignoreFirst ); 16 +} 17 + 18 +kiCmdParser::kiCmdParser( const char* cmd, bool ignoreFirst ) 19 +{ 20 + m_Buffer=NULL; 21 + if( cmd ) 22 + { 23 + m_Buffer = new char[ ki_strlen(cmd)+1 ]; 24 + ki_strcpy( m_Buffer, cmd ); 25 + doit( m_Buffer, ignoreFirst ); 26 + } 27 +} 28 + 29 +kiCmdParser::~kiCmdParser() 30 +{ 31 + delete [] m_Buffer; 32 +} 33 + 34 + 35 +//---------------------------- 分割の処理 -----------------------------// 36 + 37 + 38 +void kiCmdParser::doit( char* start, bool ignoreFirst ) 39 +{ 40 + char* p=start; 41 + char endc; 42 + bool first = true; 43 + 44 + while( *p!='\0' ) 45 + { 46 + // 余分な空白はスキップ 47 + while( *p==' ' ) //|| *p=='\t' || *p=='\r' || *p=='\n' ) 48 + p++; 49 + 50 + // " だったら、その旨記録してさらに一個進める 51 + if( *p=='"' ) 52 + endc='"', p++; 53 + else 54 + endc=' '; 55 + 56 + // end-of-text なら終了 57 + if( *p=='\0' ) 58 + break; 59 + 60 + if( first && ignoreFirst ) 61 + first = false; 62 + else 63 + { 64 + // 引数を保存 65 + if( *p=='-' ) 66 + m_Switch.add( p ); 67 + else 68 + m_Param.add( p ); 69 + } 70 + 71 + // 引数の終わりへ… 72 + while( *p!=endc && *p!='\0' ) 73 + p++; 74 + 75 + // 終わりは'\0'にすることによって、引数を区切る 76 + if( *p!='\0' ) 77 + *(p++) = '\0'; 78 + } 79 +}
Added kilib/kl_cmd.h version [12ecf570cf0caedb]
1 +//--- K.I.LIB --- 2 +// kl_cmd.h : commandline parser 3 + 4 +#ifndef AFX_KICMDPARSER_H__843A27E0_5DBF_48AF_A748_FA7F111F699A__INCLUDED_ 5 +#define AFX_KICMDPARSER_H__843A27E0_5DBF_48AF_A748_FA7F111F699A__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// kiCmdParser : コマンド文字列をchar*の配列に分割 9 + 10 +class kiCmdParser 11 +{ 12 +public: //-- 外向きインターフェイス -------------------------- 13 + 14 + // 文字列で初期化 15 + kiCmdParser( char* cmd, bool ignoreFirst=false ); 16 + kiCmdParser( const char* cmd, bool ignoreFirst=false ); 17 + 18 + // スイッチ文字列の配列 19 + cCharArray& option() 20 + { return m_Switch; } 21 + 22 + // スイッチ以外の文字列の配列 23 + cCharArray& param() 24 + { return m_Param; } 25 + 26 +private: //-- 内部処理 ----------------------------------- 27 + 28 + void doit( char* start, bool ignoreFirst ); 29 + cCharArray m_Param; 30 + cCharArray m_Switch; 31 + char* m_Buffer; 32 + 33 +public: 34 + 35 + virtual ~kiCmdParser(); 36 +}; 37 + 38 +#endif
Added kilib/kl_dnd.cpp version [c1d100a942724719]
1 +//--- K.I.LIB --- 2 +// kl_dnd.h : drag and drop operation 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 +//--------------------------------------------------------------------// 8 + 9 +bool kiDropSource::DnD( kiDataObject* pObj, DWORD efct, DWORD* pefct ) 10 +{ 11 + kiDropSource* pDrpSrc = new kiDropSource; 12 + pDrpSrc->AddRef(); 13 + pObj->begin(); 14 + 15 + DWORD d, *p=(pefct==NULL ? &d : pefct); 16 + HRESULT hr = ::DoDragDrop( pObj, pDrpSrc, efct, p ); 17 + 18 + pDrpSrc->Release(); 19 + return (hr == DRAGDROP_S_DROP); 20 +} 21 + 22 +//------------------------ IUnknown Implement -------------------------// 23 + 24 +kiDropSource::kiDropSource() : m_cRef( 0L ) 25 +{ 26 + app()->shellInit(); // OleInitialize() 27 +} 28 + 29 +STDMETHODIMP_(ULONG) kiDropSource::AddRef() 30 +{ 31 + return ++m_cRef; 32 +} 33 + 34 +STDMETHODIMP_(ULONG) kiDropSource::Release() 35 +{ 36 + if( --m_cRef ) 37 + return m_cRef; 38 + 39 + delete this; 40 + return 0L; 41 +} 42 + 43 +STDMETHODIMP kiDropSource::QueryInterface( REFIID riid, void** ppObj ) 44 +{ 45 + if( ::IsEqualIID( riid, IID_IUnknown ) 46 + || ::IsEqualIID( riid, IID_IDropSource ) ) 47 + { 48 + *ppObj = (void*)this; 49 + AddRef(); 50 + return S_OK; 51 + } 52 + 53 + *ppObj = NULL; 54 + return E_NOINTERFACE; 55 +} 56 + 57 +//------------------------ IDropSource Implement -------------------------// 58 + 59 +STDMETHODIMP kiDropSource::GiveFeedback( DWORD dwEffect ) 60 +{ 61 + return DRAGDROP_S_USEDEFAULTCURSORS; 62 +} 63 + 64 +STDMETHODIMP kiDropSource::QueryContinueDrag( BOOL keyESC, DWORD keyOther ) 65 +{ 66 + if( keyESC ) 67 + return DRAGDROP_S_CANCEL; 68 + if( !(keyOther&MK_LBUTTON) && !(keyOther&MK_RBUTTON) ) 69 + return DRAGDROP_S_DROP; 70 + return S_OK; 71 +} 72 + 73 +//------------------------ IUnknown Implement -------------------------// 74 + 75 +kiDataObject::kiDataObject() : m_cRef( 0L ), m_FormatList( 2 ) 76 +{ 77 +} 78 + 79 +STDMETHODIMP_(ULONG) kiDataObject::AddRef() 80 +{ 81 + return ++m_cRef; 82 +} 83 + 84 +STDMETHODIMP_(ULONG) kiDataObject::Release() 85 +{ 86 + if( --m_cRef ) 87 + return m_cRef; 88 + 89 + delete this; 90 + return 0L; 91 +} 92 + 93 +STDMETHODIMP kiDataObject::QueryInterface( REFIID riid, void** ppObj ) 94 +{ 95 + if( ::IsEqualIID( riid, IID_IUnknown ) 96 + || ::IsEqualIID( riid, IID_IDataObject ) ) 97 + { 98 + *ppObj = (void*)this; 99 + AddRef(); 100 + return S_OK; 101 + } 102 + 103 + *ppObj = NULL; 104 + return E_NOINTERFACE; 105 +} 106 + 107 +//------------------------ IDataObject Implement -------------------------// 108 + 109 + 110 +STDMETHODIMP kiDataObject::GetData( FORMATETC* fmtc, STGMEDIUM* stg ) 111 +{ 112 + HRESULT hr = QueryGetData( fmtc ); 113 + if( FAILED(hr) ) 114 + return hr; 115 + bool res = giveData( *fmtc, stg, m_bFirst ); 116 + m_bFirst = false; 117 + return res ? S_OK : STG_E_MEDIUMFULL; 118 +} 119 + 120 +STDMETHODIMP kiDataObject::QueryGetData( FORMATETC* fmtc ) 121 +{ 122 + for( unsigned int i=0; i!=m_FormatList.len(); i++ ) 123 + if( m_FormatList[i].cfFormat == fmtc->cfFormat ) 124 +// if(fmtc & TYMED_HGLOBAL) 125 + return S_OK; 126 + return DV_E_FORMATETC; 127 +} 128 + 129 +//---------- Enumrator ---------// 130 + 131 +class kiDataObject_Enum : public IEnumFORMATETC 132 +{ 133 +public: 134 + kiDataObject_Enum( kiDataObject* p ) 135 + : m_cRef( 0L ), m_pObj( p ), m_nCur( 0L ) 136 + { 137 + m_pObj->AddRef(); 138 + } 139 + ~kiDataObject_Enum() 140 + { 141 + m_pObj->Release(); 142 + } 143 + STDMETHODIMP_(ULONG) AddRef() 144 + { 145 + return ++m_cRef; 146 + } 147 + STDMETHODIMP_(ULONG) Release() 148 + { 149 + if( --m_cRef ) 150 + return m_cRef; 151 + delete this; 152 + return 0L; 153 + } 154 + STDMETHODIMP QueryInterface( REFIID riid, void** ppObj ) 155 + { 156 + if( ::IsEqualIID( riid, IID_IUnknown ) 157 + || ::IsEqualIID( riid, IID_IEnumFORMATETC ) ) 158 + { 159 + *ppObj = (void*)this; 160 + AddRef(); 161 + return S_OK; 162 + } 163 + *ppObj = NULL; 164 + return E_NOINTERFACE; 165 + } 166 + STDMETHODIMP Clone( IEnumFORMATETC** ppNew ) 167 + { 168 + *ppNew = new kiDataObject_Enum( m_pObj ); 169 + ((kiDataObject_Enum*)(*ppNew))->m_nCur = m_nCur; 170 + (*ppNew)->AddRef(); 171 + return S_OK; 172 + } 173 + STDMETHODIMP Reset() 174 + { 175 + m_nCur = 0; 176 + return S_OK; 177 + } 178 + STDMETHODIMP Skip( ULONG celt ) 179 + { 180 + m_nCur += celt; 181 + if( m_pObj->m_FormatList.len() <= m_nCur ) 182 + { 183 + m_nCur = m_pObj->m_FormatList.len() - 1; 184 + return S_FALSE; 185 + } 186 + return S_OK; 187 + } 188 + STDMETHODIMP Next( ULONG celt, FORMATETC* pFmt, ULONG* fetched ) 189 + { 190 + if( fetched ) 191 + *fetched = 0L; 192 + if( !pFmt ) 193 + return E_POINTER; 194 + ULONG i; 195 + for( i=0; i < celt && m_nCur < m_pObj->m_FormatList.len(); i++,m_nCur++ ) 196 + *pFmt++ = m_pObj->m_FormatList[m_nCur]; 197 + if( fetched ) 198 + *fetched = i; 199 + return i==celt ? S_OK : S_FALSE; 200 + } 201 +private: 202 + ULONG m_cRef; 203 + ULONG m_nCur; 204 + kiDataObject* m_pObj; 205 +}; 206 + 207 +STDMETHODIMP kiDataObject::EnumFormatEtc( DWORD drctn, IEnumFORMATETC** ppEnm ) 208 +{ 209 + if( !ppEnm ) 210 + return E_INVALIDARG; 211 + *ppEnm = NULL; 212 + if( drctn!=DATADIR_GET ) 213 + return E_NOTIMPL; 214 + 215 + (*ppEnm = new kiDataObject_Enum( this ))->AddRef(); 216 + return S_OK; 217 +}
Added kilib/kl_dnd.h version [3378ce3cda9a549d]
1 +//--- K.I.LIB --- 2 +// kl_dnd.h : drag and drop operation 3 + 4 +#ifndef AFX_KIDROPSOURCE_H__141BEF0D_0DA2_4156_93E4_313535916A23__INCLUDED_ 5 +#define AFX_KIDROPSOURCE_H__141BEF0D_0DA2_4156_93E4_313535916A23__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// kiDataObject : ドロップデータとしての標準処理 9 + 10 +class kiDataObject : public IDataObject 11 +{ 12 +protected: // 派生クラス向け処理 13 + 14 + virtual bool giveData( const FORMATETC& fmt, STGMEDIUM* stg, bool firstcall ) = 0; 15 + void addFormat( const FORMATETC& frm ) 16 + { 17 + m_FormatList.add( frm ); 18 + } 19 + 20 +protected: //-- IUnknown ----------- 21 + 22 + kiDataObject(); 23 + STDMETHODIMP QueryInterface( REFIID, void** ); 24 + STDMETHODIMP_(ULONG) AddRef(); 25 + STDMETHODIMP_(ULONG) Release(); 26 +private: 27 + ULONG m_cRef; 28 + 29 +private: //-- IDataObject ------------ 30 + 31 + STDMETHODIMP GetData( FORMATETC*, STGMEDIUM* ); 32 + STDMETHODIMP QueryGetData( FORMATETC* ); 33 + STDMETHODIMP EnumFormatEtc( DWORD, IEnumFORMATETC** ); 34 + STDMETHODIMP GetDataHere( FORMATETC*, STGMEDIUM* ) 35 + { 36 + return E_NOTIMPL; 37 + } 38 + STDMETHODIMP GetCanonicalFormatEtc( FORMATETC*, FORMATETC* ) 39 + { 40 + return E_NOTIMPL; 41 + } 42 + STDMETHODIMP SetData( FORMATETC*, STGMEDIUM*, BOOL ) 43 + { 44 + return E_NOTIMPL; 45 + } 46 + STDMETHODIMP DAdvise( FORMATETC*, DWORD, IAdviseSink*, DWORD* ) 47 + { 48 + return OLE_E_ADVISENOTSUPPORTED; 49 + } 50 + STDMETHODIMP DUnadvise( DWORD ) 51 + { 52 + return OLE_E_NOCONNECTION; 53 + } 54 + STDMETHODIMP EnumDAdvise( IEnumSTATDATA** ) 55 + { 56 + return OLE_E_ADVISENOTSUPPORTED; 57 + } 58 + 59 +private: //-- 内部処理 ----------------- 60 + 61 + kiArray<FORMATETC> m_FormatList; 62 + bool m_bFirst; 63 + friend class kiDataObject_Enum; 64 + 65 +public: 66 + void begin() 67 + { 68 + m_bFirst = true; 69 + } 70 +}; 71 + 72 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 73 +// kiDropSource : ドロップ元としての標準処理 74 + 75 +class kiDropSource : public IDropSource 76 +{ 77 +public: //-- ドラッグ&ドロップ実行! 78 + 79 + static bool DnD( kiDataObject* pObj, DWORD efct, DWORD* pefct=NULL ); 80 + 81 +private: //-- IUnknown 82 + 83 + kiDropSource(); 84 + STDMETHODIMP QueryInterface( REFIID, void** ); 85 + STDMETHODIMP_(ULONG) AddRef(); 86 + STDMETHODIMP_(ULONG) Release(); 87 + ULONG m_cRef; 88 + 89 +private: //-- IDropSource 90 + 91 + STDMETHODIMP QueryContinueDrag( BOOL, DWORD ); 92 + STDMETHODIMP GiveFeedback( DWORD ); 93 +}; 94 + 95 +#endif
Added kilib/kl_file.cpp version [7b5e9e59cf9067ee]
1 +//--- K.I.LIB --- 2 +// kl_file.cpp : file operations 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 +//--------------------------- static --------------------------// 8 + 9 +unsigned long kiFile::getSize( const char* fname, unsigned long err ) 10 +{ 11 + HANDLE h = ::CreateFile( fname, 12 + GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 13 + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL ); 14 + if( h==INVALID_HANDLE_VALUE ) 15 + return err; 16 + 17 + unsigned long ans = ::GetFileSize( h, NULL ); 18 + ::CloseHandle( h ); 19 + 20 + return ans==0xffffffff ? err : ans; 21 +} 22 + 23 +//--------------------------- 結んで開いて --------------------------// 24 + 25 + 26 +bool kiFile::open( const char* filename, bool read, bool create ) 27 +{ 28 + close(); 29 + 30 + if( m_bReadMode = read ) 31 + m_hFile = ::CreateFile( filename, 32 + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 33 + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); 34 + else 35 + m_hFile = ::CreateFile( filename, 36 + GENERIC_WRITE, FILE_SHARE_READ, NULL, 37 + create ? CREATE_ALWAYS : OPEN_EXISTING, 38 + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); 39 + if( m_hFile == INVALID_HANDLE_VALUE ) 40 + return false; 41 + 42 + m_nBufPos = 0; 43 + if( m_bReadMode ) 44 + flush(); 45 + 46 + return true; 47 +} 48 + 49 +void kiFile::close() 50 +{ 51 + if( m_hFile != INVALID_HANDLE_VALUE ) 52 + { 53 + if( !m_bReadMode ) 54 + flush(); 55 + 56 + ::CloseHandle( m_hFile ); 57 + m_hFile = INVALID_HANDLE_VALUE; 58 + } 59 +} 60 + 61 + 62 +//-------------------------- 読み書き ----------------------------// 63 + 64 + 65 +unsigned long kiFile::read( unsigned char* buf, unsigned long len ) 66 +{ 67 + unsigned long ans = 0; 68 + if( m_nBufSize!=0 && m_hFile!=INVALID_HANDLE_VALUE && m_bReadMode ) 69 + { 70 + while( (m_nBufSize-m_nBufPos) <= len ) 71 + { 72 + ans += (m_nBufSize-m_nBufPos); 73 + ki_memcpy( buf, m_pBuf+m_nBufPos, m_nBufSize-m_nBufPos ); 74 + len -= (m_nBufSize-m_nBufPos); 75 + buf += (m_nBufSize-m_nBufPos); 76 + 77 + flush(); 78 + if( m_nBufSize == 0 ) 79 + return ans; 80 + } 81 + ans += len; 82 + ki_memcpy( buf, m_pBuf+m_nBufPos, len ); 83 + m_nBufPos += len; 84 + } 85 + return ans; 86 +} 87 + 88 +void kiFile::write( const void* buf, unsigned long len ) 89 +{ 90 + if( m_hFile==INVALID_HANDLE_VALUE || m_bReadMode ) 91 + return; 92 + const unsigned char* ubuf = (const unsigned char*)buf; 93 + 94 + while( (kifile_bufsize-m_nBufPos) <= len ) 95 + { 96 + ki_memcpy( m_pBuf+m_nBufPos, buf, (kifile_bufsize-m_nBufPos) ); 97 + len -= (kifile_bufsize-m_nBufPos); 98 + ubuf += (kifile_bufsize-m_nBufPos); 99 + m_nBufPos = kifile_bufsize; 100 + flush(); 101 + } 102 + ki_memcpy( m_pBuf+m_nBufPos, ubuf, len ); 103 + m_nBufPos += len; 104 +} 105 + 106 +#undef putc 107 +void kiFile::putc( unsigned char c ) 108 +{ 109 + if( m_hFile==INVALID_HANDLE_VALUE || m_bReadMode ) 110 + return; 111 + if( (kifile_bufsize-m_nBufPos) <= 1 ) 112 + flush(); 113 + m_pBuf[ m_nBufPos++ ] = c; 114 +} 115 + 116 +#undef getc 117 +int kiFile::getc() 118 +{ 119 + if( m_nBufSize==0 || m_hFile==INVALID_HANDLE_VALUE || !m_bReadMode ) 120 + return -1; 121 + 122 + if( 0==(m_nBufSize-m_nBufPos) ) 123 + { 124 + flush(); 125 + if( m_nBufSize==0 ) 126 + return -1; 127 + } 128 + if( 1==(m_nBufSize-m_nBufPos) ) 129 + { 130 + int ans = m_pBuf[ m_nBufPos++ ]; 131 + flush(); 132 + return ans; 133 + } 134 + 135 + return m_pBuf[ m_nBufPos++ ]; 136 +} 137 + 138 +void kiFile::flush() 139 +{ 140 + if( m_bReadMode ) 141 + { 142 + ::ReadFile( m_hFile, m_pBuf, kifile_bufsize, &m_nBufSize, NULL ); 143 + m_nBufPos = 0; 144 + } 145 + else 146 + { 147 + ::WriteFile( m_hFile, m_pBuf, m_nBufPos, &m_nBufSize, NULL ); 148 + m_nBufSize = m_nBufPos = 0; 149 + } 150 +}
Added kilib/kl_file.h version [9f575eb6951cda32]
1 +//--- K.I.LIB --- 2 +// kl_file.h : file operations 3 + 4 +#ifndef AFX_KIFILE_H__7D126C1E_3E5C_476E_9A4E_81CA8055621D__INCLUDED_ 5 +#define AFX_KIFILE_H__7D126C1E_3E5C_476E_9A4E_81CA8055621D__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// バイナリファイル操作 9 + 10 +class kiFile 11 +{ 12 +public: //-- static ---------------------------------------- 13 + 14 + // ファイルサイズ取得( 名前, エラー時に返したい値 ) 15 + static unsigned long getSize( const char* fname, unsigned long err=0xffffffff ); 16 + 17 +public: //-- 外向きインターフェイス -------------------------- 18 + 19 + // 開いて閉じて 20 + bool open( const char* filename, bool read=true, bool create=true ); 21 + void close(); 22 + 23 + // 読んで書いて 24 + unsigned long read( unsigned char* buf, unsigned long len ); 25 + void write( const void* buf, unsigned long len ); 26 + int getc(); 27 + void putc( unsigned char c ); 28 + 29 + // シーク 30 + void seekTo( unsigned long pos ) 31 + { 32 + if( !m_bReadMode ) flush(); 33 + ::SetFilePointer( m_hFile, pos, NULL, FILE_BEGIN ); 34 + if( m_bReadMode ) flush(); 35 + } 36 + void seek( long pos ) 37 + { 38 + if( !m_bReadMode ) flush(); 39 + ::SetFilePointer( m_hFile, 40 + pos-(signed)m_nBufSize+(signed)m_nBufPos, NULL, 41 + FILE_CURRENT ); 42 + if( m_bReadMode ) flush(); 43 + } 44 + unsigned long tell() 45 + { 46 + return ::SetFilePointer( m_hFile, 0, NULL, FILE_CURRENT ) 47 + - m_nBufSize + m_nBufPos; 48 + } 49 + 50 + // 情報取得 51 + bool isOpened() 52 + { 53 + return m_hFile != INVALID_HANDLE_VALUE; 54 + } 55 + unsigned long getSize( unsigned long* higher=NULL ) 56 + { 57 + return ::GetFileSize( m_hFile, higher ); 58 + } 59 + bool isEOF() 60 + { 61 + return (m_nBufPos==0 && m_nBufSize==0); 62 + } 63 + 64 +public: //-- 内部処理 ----------------------------------- 65 + 66 + kiFile() : kifile_bufsize( 65536 ) 67 + { 68 + m_hFile= INVALID_HANDLE_VALUE; 69 + m_pBuf = new unsigned char[kifile_bufsize]; 70 + } 71 + 72 + virtual ~kiFile() 73 + { 74 + close(); 75 + delete [] m_pBuf; 76 + } 77 + 78 +private: 79 + const int kifile_bufsize; 80 + void flush(); 81 + 82 + HANDLE m_hFile; 83 + bool m_bReadMode; 84 + unsigned char* m_pBuf; 85 + unsigned long m_nBufSize, m_nBufPos; 86 +}; 87 + 88 +#endif
Added kilib/kl_find.cpp version [16c2c7129051abe4]
1 +//--- K.I.LIB --- 2 +// kl_find.h : FindFirstFile wrapper 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 +#define isDots(p) (*p=='.' && (p[1]=='\0' || (p[1]=='.' && p[2]=='\0'))) 8 + 9 +bool kiFindFile::findfirst( const char* wild, WIN32_FIND_DATA* pfd ) 10 +{ 11 + HANDLE xh = ::FindFirstFile( wild, pfd ); 12 + if( xh==INVALID_HANDLE_VALUE ) 13 + return false; 14 + while( isDots(pfd->cFileName) ) 15 + if( !::FindNextFile( xh, pfd ) ) 16 + { 17 + ::FindClose( xh ); 18 + return false; 19 + } 20 + ::FindClose( xh ); 21 + return true; 22 +} 23 + 24 +void kiFindFile::close() 25 +{ 26 + first=true; 27 + if( h!=INVALID_HANDLE_VALUE ) 28 + { 29 + ::FindClose( h ), h=INVALID_HANDLE_VALUE; 30 + } 31 +} 32 + 33 +bool kiFindFile::begin( const char* wild ) 34 +{ 35 + close(); 36 + 37 + h = ::FindFirstFile( wild, &fd ); 38 + if( h==INVALID_HANDLE_VALUE ) 39 + return false; 40 + while( isDots(fd.cFileName) ) 41 + if( !::FindNextFile( h, &fd ) ) 42 + { 43 + close(); 44 + return false; 45 + } 46 + return true; 47 +} 48 + 49 +bool kiFindFile::next( WIN32_FIND_DATA* pfd ) 50 +{ 51 + if( h==INVALID_HANDLE_VALUE ) 52 + return false; 53 + if( first ) 54 + { 55 + first = false; 56 + ki_memcpy( pfd, &fd, sizeof(fd) ); 57 + return true; 58 + } 59 + if( !::FindNextFile( h, pfd ) ) 60 + return false; 61 + while( isDots(fd.cFileName) ) 62 + if( !::FindNextFile( h, pfd ) ) 63 + return false; 64 + return true; 65 +} 66 + 67 +#undef isDots
Added kilib/kl_find.h version [64a6dbf816844dba]
1 +//--- K.I.LIB --- 2 +// kl_find.h : FindFirstFile wrapper 3 + 4 +#ifndef AFX_KIFINDFILE_H__86462791_815C_4F44_9F16_802B54B411BA__INCLUDED_ 5 +#define AFX_KIFINDFILE_H__86462791_815C_4F44_9F16_802B54B411BA__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// ファイル検索 9 + 10 +class kiFindFile 11 +{ 12 +public: //-- 外向きインターフェイス -------------------------- 13 + 14 + static bool findfirst( const char* wild, WIN32_FIND_DATA* pfd ); 15 + bool begin( const char* wild ); 16 + bool next( WIN32_FIND_DATA* pfd ); 17 + 18 +public: //-- 内部処理 ----------------------------------- 19 + 20 + kiFindFile() 21 + { h = INVALID_HANDLE_VALUE; } 22 + virtual ~kiFindFile() 23 + { close(); } 24 + void close(); 25 + 26 +private: 27 + HANDLE h; 28 + bool first; 29 + WIN32_FIND_DATA fd; 30 +}; 31 + 32 +#endif
Added kilib/kl_misc.h version [497c03c8bc7cf457]
1 +//--- K.I.LIB --- 2 +// kl_misc.h : common-classes for K.I.LIB 3 + 4 +#ifndef AFX_KILIBBASE_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 5 +#define AFX_KILIBBASE_H__89998F34_A9FE_4A27_A159_671F85AA9383__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// 使用する外部関数を何となくマクロ化しておく 9 +// 追記:何でこんなことやったんだ…? > 昔の自分(^^; 10 + 11 +#define ki_strlen(p) ::lstrlen(p) 12 +#define ki_strcpy(p,s) ::lstrcpy(p,s) 13 +#define ki_strcat(p,s) ::lstrcat(p,s) 14 +#define ki_strcmp(p,s) ::lstrcmp(p,s) 15 +#define ki_strcmpi(p,s) ::lstrcmpi(p,s) 16 +#define ki_memzero(p,l) ::ZeroMemory(p,l) 17 +#define ki_memcpy(p,s,l) ::CopyMemory(p,s,l) 18 +#define ki_memmov(p,s,l) ::MoveMemory(p,s,l) 19 +#define ki_memset(p,c,l) ::FillMemory(p,l,c) 20 +inline bool ki_memcmp( const char* x, const char* y, int l ) 21 +{ 22 + while( *x++==*y++ && --l ); 23 + return l==0; 24 +} 25 + 26 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 27 +// kiArray : 配列のようなキューのような代物 28 + 29 +template <class T> class kiArray 30 +{ 31 +public: //-- 外向きインターフェイス -------------------------- 32 + 33 + // 初期サイズ( 10〜255 )で初期化 34 + kiArray( unsigned char start_size=10 ) 35 + { 36 + m_pArray = new T[ m_ALen=start_size ]; 37 + m_Len = 0; 38 + } 39 + 40 + // 配列を空にする 41 + void empty() 42 + { 43 + m_Len = 0; 44 + } 45 + 46 + // 要素数を取得 47 + unsigned long len() const 48 + { 49 + return m_Len; 50 + } 51 + 52 + // 末尾に一個追加 53 + void add( const T& obj ) 54 + { 55 + if( m_Len>=m_ALen ) 56 + { 57 + T* p = new T[ m_ALen<<=1 ]; 58 + for( unsigned long i=0; i!=m_Len; i++ ) 59 + p[i] = m_pArray[i]; 60 + delete [] m_pArray; 61 + m_pArray = p; 62 + } 63 + m_pArray[ m_Len++ ] = obj; 64 + } 65 + 66 + // 要素にアクセス 67 + T& operator []( unsigned long i ) 68 + { 69 + return m_pArray[i]; 70 + } 71 + const T& operator []( unsigned long i ) const 72 + { 73 + return m_pArray[i]; 74 + } 75 + 76 + // 配列コピー 77 + kiArray<T>& operator = ( const kiArray<T>& o ) 78 + { 79 + if( &o != this ) 80 + { 81 + empty(); 82 + for( unsigned int i=0; i!=o.len(); i++ ) 83 + add( o[i] ); 84 + } 85 + return *this; 86 + } 87 + 88 + //-- ちょっと危険なメソッド群 89 + void alloc( unsigned long x ) 90 + { 91 + if( x > m_ALen ) 92 + { 93 + T* p = new T[ m_ALen=(m_ALen<<1)>x?(m_ALen<<1):x ]; 94 + for( unsigned long i=0; i!=m_Len; i++ ) 95 + p[i] = m_pArray[i]; 96 + delete [] m_pArray; 97 + m_pArray = p; 98 + } 99 + } 100 + void forcelen( unsigned long x ) 101 + { 102 + alloc( x ); 103 + m_Len = x; 104 + } 105 + 106 +private: //-- 内部処理 ----------------------------------- 107 + 108 + T* m_pArray; 109 + unsigned long m_Len, m_ALen; 110 + 111 +public: 112 + 113 + virtual ~kiArray() 114 + { 115 + delete [] m_pArray; 116 + } 117 +}; 118 + 119 +#define BoolArray kiArray<bool> 120 +#define CharArray kiArray<char*> 121 +#define cCharArray kiArray<const char*> 122 +#define StrArray kiArray<kiStr> 123 + 124 +#endif
Added kilib/kl_reg.cpp version [6b590b6d15780424]
1 +//--- K.I.LIB --- 2 +// kl_reg.h : registry and ini-file operation 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 + 8 +//---------------------------- open系 ----------------------------// 9 + 10 + 11 +bool kiRegKey::open( HKEY parent, LPCTSTR keyname, REGSAM access ) 12 +{ 13 + return (ERROR_SUCCESS == RegOpenKeyEx( parent, 14 + keyname, 0, access, &m_hKey )); 15 +} 16 + 17 +bool kiRegKey::create( HKEY parent, LPCTSTR keyname, REGSAM access ) 18 +{ 19 + DWORD x; 20 + return (ERROR_SUCCESS == RegCreateKeyEx( parent, 21 + keyname, 0, REG_NONE, REG_OPTION_NON_VOLATILE, access, NULL, &m_hKey, &x )); 22 +} 23 + 24 + 25 +//------------------------- query/set系 ----------------------------// 26 + 27 + 28 +bool kiRegKey::get( LPCTSTR valname, DWORD* val ) 29 +{ 30 + DWORD x=4; 31 + return (ERROR_SUCCESS == RegQueryValueEx( m_hKey, 32 + valname, NULL, NULL, (BYTE*)val, &x )); 33 +} 34 + 35 +bool kiRegKey::get( LPCTSTR valname, BYTE* val, DWORD siz ) 36 +{ 37 + return (ERROR_SUCCESS == RegQueryValueEx( m_hKey, 38 + valname, NULL, NULL, val, &siz )); 39 +} 40 + 41 +bool kiRegKey::get( LPCTSTR valname, kiStr* val ) 42 +{ 43 + static char dat[2048]; 44 + DWORD x = 2048; 45 + if( ERROR_SUCCESS == RegQueryValueEx( m_hKey, 46 + valname, NULL, NULL, (BYTE*)dat, &x )) 47 + { 48 + *val = dat; 49 + return true; 50 + } 51 + return false; 52 +} 53 + 54 +bool kiRegKey::set( LPCTSTR valname, DWORD val ) 55 +{ 56 + return (ERROR_SUCCESS == RegSetValueEx( m_hKey, 57 + valname, 0, REG_DWORD, (BYTE*)&val, 4 )); 58 +} 59 + 60 +bool kiRegKey::set( LPCTSTR valname, BYTE* val, DWORD siz ) 61 +{ 62 + return (ERROR_SUCCESS == RegSetValueEx( m_hKey, 63 + valname, 0, REG_BINARY, (BYTE*)val, siz )); 64 +} 65 + 66 +bool kiRegKey::set( LPCTSTR valname, LPCTSTR val ) 67 +{ 68 + return (ERROR_SUCCESS == RegSetValueEx( m_hKey, 69 + valname, 0, REG_SZ, (BYTE*)val, ki_strlen(val)+1 )); 70 +} 71 + 72 + 73 +//--------------------------- delete系 ----------------------------// 74 + 75 + 76 +bool kiRegKey::del( LPCTSTR valname ) 77 +{ 78 + return (ERROR_SUCCESS == RegDeleteValue( m_hKey, valname )); 79 +} 80 + 81 +bool kiRegKey::delSubKey( LPCTSTR keyname ) 82 +{ 83 + if( app()->osver().dwPlatformId == VER_PLATFORM_WIN32_NT ) 84 + return delSubKeyRecursive( m_hKey, keyname ); 85 + else 86 + return (ERROR_SUCCESS == RegDeleteKey( m_hKey, keyname )); 87 +} 88 + 89 +bool kiRegKey::delSubKeyRecursive( HKEY k, LPCTSTR n ) 90 +{ 91 + HKEY k2; 92 + if( ERROR_SUCCESS!=RegOpenKeyEx( k,n,0,KEY_READ,&k2 ) ) 93 + return false; 94 + 95 + bool ans = true; 96 + static char buf[2048]; 97 + DWORD bs = sizeof(buf); 98 + 99 + for( int i=0; 100 + ERROR_SUCCESS==RegEnumKeyEx( k2,i,buf,&bs,NULL,NULL,NULL,NULL ); 101 + i++ ) 102 + { 103 + if( !delSubKeyRecursive( k2,buf ) ) 104 + ans = false; 105 + bs = sizeof(buf); 106 + } 107 + 108 + RegCloseKey( k2 ); 109 + RegDeleteKey( k,n ); 110 + return ans; 111 +} 112 + 113 +//--------------------------- ini:初期化 ----------------------------// 114 + 115 + 116 +void kiIniFile::setFileName( const char* ini, bool exepath ) 117 +{ 118 + if( !exepath ) 119 + m_FileName = ""; 120 + else 121 + { 122 + m_FileName.beSpecialPath( kiPath.Exe ); 123 + m_FileName.beBackSlash( true ); 124 + } 125 + m_FileName += ini; 126 +} 127 + 128 + 129 +//--------------------------- ini:read系 ----------------------------// 130 + 131 + 132 +int kiIniFile::getInt( const char* key, int defval ) 133 +{ 134 + return ::GetPrivateProfileInt( m_CurSec, key, defval, m_FileName ); 135 +} 136 + 137 +bool kiIniFile::getBool( const char* key, bool defval ) 138 +{ 139 + return (0 != ::GetPrivateProfileInt( m_CurSec, 140 + key, defval?1:0, m_FileName ) ); 141 +} 142 + 143 +const char* kiIniFile::getStr( const char* key, const char* defval ) 144 +{ 145 + ::GetPrivateProfileString( m_CurSec, key, defval, 146 + m_StrBuf, sizeof(m_StrBuf), m_FileName ); 147 + return m_StrBuf; 148 +} 149 + 150 + 151 +//--------------------------- ini:write系 ----------------------------// 152 + 153 + 154 +bool kiIniFile::putStr( const char* key, const char* val ) 155 +{ 156 + return (FALSE != ::WritePrivateProfileString( 157 + m_CurSec, key, val, m_FileName ) ); 158 +} 159 + 160 +bool kiIniFile::putInt( const char* key, int val ) 161 +{ 162 + ::wsprintf( m_StrBuf, "%d", val ); 163 + return putStr( key, m_StrBuf ); 164 +} 165 + 166 +bool kiIniFile::putBool( const char* key, bool val ) 167 +{ 168 + return putStr( key, val ? "1" : "0" ); 169 +}
Added kilib/kl_reg.h version [b513b5f4430bdfd8]
1 +//--- K.I.LIB --- 2 +// kl_reg.h : registry and ini-file operation 3 + 4 +#ifndef AFX_KIREGKEY_H__4FD5E1B3_B8FE_45B3_B19E_3D30407C94BA__INCLUDED_ 5 +#define AFX_KIREGKEY_H__4FD5E1B3_B8FE_45B3_B19E_3D30407C94BA__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// レジストリ操作&ini操作 9 + 10 +class kiRegKey 11 +{ 12 +public: //-- 外向きインターフェイス -------------------------- 13 + 14 + // 開く&閉じる 15 + bool open( HKEY parent, LPCTSTR keyname, REGSAM access = KEY_ALL_ACCESS ); 16 + bool create( HKEY parent, LPCTSTR keyname, REGSAM access = KEY_ALL_ACCESS ); 17 + void close() 18 + { 19 + if( m_hKey ) 20 + RegCloseKey( m_hKey ); 21 + } 22 + 23 + // サブキーが存在するや否や 24 + bool exist( LPCTSTR keyname ) 25 + { 26 + HKEY k; 27 + if( ERROR_SUCCESS==RegOpenKeyEx( m_hKey,keyname,0,KEY_READ,&k ) ) 28 + { 29 + RegCloseKey( k ); 30 + return true; 31 + } 32 + return false; 33 + } 34 + // HKEYへキャスト 35 + operator HKEY() const 36 + { 37 + return m_hKey; 38 + } 39 + 40 + // 値を得る 41 + bool get( LPCTSTR valname, DWORD* val ); 42 + bool get( LPCTSTR valname, BYTE* val, DWORD siz ); 43 + bool get( LPCTSTR valname, kiStr* val ); 44 + 45 + // 値を設定 46 + bool set( LPCTSTR valname, DWORD val ); 47 + bool set( LPCTSTR valname, BYTE* val, DWORD siz ); 48 + bool set( LPCTSTR valname, LPCTSTR val ); 49 + 50 + // 削除 51 + bool del( LPCTSTR valname ); 52 + bool delSubKey( LPCTSTR keyname ); 53 + 54 +public: //-- 内部処理 ----------------------------------- 55 + 56 + kiRegKey() 57 + { 58 + m_hKey = NULL; 59 + } 60 + 61 + virtual ~kiRegKey() 62 + { 63 + close(); 64 + } 65 + 66 +private: 67 + 68 + HKEY m_hKey; 69 + static bool delSubKeyRecursive( HKEY k, LPCTSTR n ); 70 +}; 71 + 72 +class kiIniFile 73 +{ 74 +public: //-- 外向きインターフェイス -------------------------- 75 + 76 + // iniファイル名を設定 77 + void setFileName( const char* ini, bool exepath=true ); 78 + void setSection( const char* section ) 79 + { m_CurSec = section; } 80 + 81 + // 読み込み 82 + // ※ 注意!getStrの返値は内部バッファな為、 83 + // ※ 呼び出し直後以外は内容を保証しない。 84 + int getInt( const char* key, int defval ); 85 + bool getBool( const char* key, bool defval ); 86 + const char* getStr( const char* key, const char* defval ); 87 + 88 + // 書き込み 89 + bool putStr( const char* key, const char* val ); 90 + bool putInt( const char* key, int val ); 91 + bool putBool( const char* key, bool val ); 92 + 93 +private: //-- 内部処理 ----------------------------------- 94 + 95 + kiPath m_FileName; 96 + kiStr m_CurSec; 97 + char m_StrBuf[256]; 98 +}; 99 + 100 +#endif
Added kilib/kl_rythp.cpp version [aff058b39f0d5658]
1 +//--- K.I.LIB --- 2 +// kl_rythp.cpp : interpretor for simple script langauage 'Rythp' 3 + 4 +#include "stdafx.h" 5 +#include "kilibext.h" 6 + 7 +//-------------------- Variant 型変数 --------------------------// 8 + 9 +int kiVar::getInt() 10 +{ 11 + int n=0; 12 + bool minus = (*m_pBuf=='-'); 13 + for( char* p = minus ? m_pBuf+1 : m_pBuf; *p; p=next(p) ) 14 + { 15 + if( '0'>*p || *p>'9' ) 16 + return 0; 17 + n = (10*n) + (*p-'0'); 18 + } 19 + return minus ? -n : n; 20 +} 21 + 22 +void kiVar::quote() 23 +{ 24 + if( m_pBuf[0]=='\"' ) 25 + return; 26 + for( const char* p=m_pBuf; *p; p=next(p) ) 27 + if( *p==' ' ) 28 + break; 29 + if( !(*p) ) 30 + return; 31 + 32 + int ln=len()+1; 33 + if( m_ALen<ln+2 ) 34 + { 35 + char* tmp = new char[m_ALen=ln+2]; 36 + ki_memcpy( tmp+1,m_pBuf,ln ); 37 + delete [] m_pBuf; 38 + m_pBuf = tmp; 39 + } 40 + else 41 + ki_memmov( m_pBuf+1,m_pBuf,ln ); 42 + m_pBuf[0]=m_pBuf[ln]='\"', m_pBuf[ln+1]='\0'; 43 +} 44 + 45 +//---------------------- 初期化・破棄 ----------------------------// 46 + 47 +kiRythpVM::kiRythpVM() 48 +{ 49 + ele['%'] = "%"; 50 + ele['('] = "("; 51 + ele[')'] = ")"; 52 + ele['"'] = "\""; 53 + ele['/'] = "\n"; 54 +} 55 + 56 +//---------------------- パラメータ毎に分割 ----------------------// 57 + 58 +char* kiRythpVM::split_tonext( char* p ) 59 +{ 60 + while( *p!='\0' && ( *p=='\t' || *p==' ' || *p=='\r' || *p=='\n' ) ) 61 + p++; 62 + return (*p=='\0' ? NULL : p); 63 +} 64 + 65 +char* kiRythpVM::split_toend( char* p ) 66 +{ 67 + int kkc=0, dqc=0; 68 + while( *p!='\0' && kkc>=0 ) 69 + { 70 + if( *p=='(' && !(dqc&1) ) 71 + kkc++; 72 + else if( *p==')' && !(dqc&1) ) 73 + kkc--; 74 + else if( *p=='\"' ) 75 + dqc++; 76 + else if( *p=='%' ) 77 + p++; 78 + else if( (*p=='\t' || *p==' ' || *p=='\r' || *p=='\n') && kkc==0 && !(dqc&1) ) 79 + return p; 80 + p++; 81 + } 82 + return (kkc==0 && !(dqc&1)) ? p : NULL; 83 +} 84 + 85 +bool kiRythpVM::split( char* buf, kiArray<char*>& argv, kiArray<bool>& argb, int& argc ) 86 +{ 87 + argv.empty(), argb.empty(), argc=0; 88 + 89 + for( char* p=buf; p=split_tonext(p); p++,argc++ ) 90 + { 91 + argv.add( p ); 92 + argb.add( *p=='(' ); 93 + 94 + if( !(p=split_toend(p)) ) 95 + return false; 96 + 97 + if( argv[argc][0]=='(' || argv[argc][0]=='"' ) 98 + argv[argc]++, *(p-1)='\0'; 99 + if( *p=='\0' ) 100 + { 101 + argc++; 102 + break; 103 + } 104 + *p='\0'; 105 + } 106 + return true; 107 +} 108 + 109 +//------------------------- 実行 -------------------------// 110 + 111 +void kiRythpVM::eval( char* str, kiVar* ans ) 112 +{ 113 + // 返値をクリアしておく 114 + kiVar tmp,*aaa=&tmp; 115 + if(ans) 116 + *ans="",aaa=ans; 117 + 118 + // "function param1 param2 ..." 形式の文字列をパラメータに分割 119 + kiArray<char*> av; 120 + kiArray<bool> ab; 121 + int ac; 122 + if( split( str,av,ab,ac ) && ac ) 123 + { 124 + // function名取得 125 + kiVar name; 126 + getarg( av[0],ab[0],&name ); 127 + 128 + // function実行! 129 + exec_function( name, av, ab, ac, aaa ); 130 + } 131 +} 132 + 133 +void kiRythpVM::getarg( char* a, bool b, kiVar* arg ) 134 +{ 135 + kiVar t; 136 + const char* p; 137 + 138 + // (...) なら eval する。 139 + if( b ) 140 + eval( a,&t ), p = t; 141 + else 142 + p = a; 143 + 144 + // 変数置き換え 145 + *arg=""; 146 + for( ; *p; *p && p++ ) 147 + if( *p!='%' ) 148 + { 149 + *arg += *p; 150 + } 151 + else 152 + { 153 + p++, *arg+=ele[(*p)&0xff]; 154 + } 155 +} 156 + 157 +//------------------------- Minimum-Rythp環境 -------------------------// 158 + 159 +bool kiRythpVM::exec_function( const kiVar& name, 160 + const kiArray<char*>& a, const kiArray<bool>& b,int c, kiVar* r ) 161 +{ 162 +// Minimum-Rythp で利用できる function は以下の通り。 163 +// exec, while, if, let, +, -, *, /, =, !, between, mod 164 + 165 + kiVar t; 166 + int i,A,B,C; 167 + 168 +//----- ---- --- -- - - - 169 +//-- (exec 実行文 実行文 ...) returns last-result 170 +//----- ---- --- -- - - - 171 + if( name=="exec" ) 172 + { 173 + for( i=1; i<c; i++ ) 174 + getarg( a[i],b[i],r ); 175 + } 176 +//----- ---- --- -- - - - 177 +//-- (while 条件 繰り返す内容) returns last-result 178 +//----- ---- --- -- - - - 179 + else if( name=="while" ) 180 + { 181 + if( c>=3 ) 182 + { 183 + // (特殊処理)複数回呼ぶコードなのでコピらなきゃ駄目。 184 + int L1=ki_strlen(a[1]), L2=ki_strlen(a[2]); 185 + char* tmp = new char[ 1 + (L1>L2 ? L1 : L2) ]; 186 + while( getarg( ki_strcpy(tmp,a[1]), b[1], &t ), t.len() ) 187 + getarg( ki_strcpy(tmp,a[2]), b[2], r ); 188 + delete [] tmp; 189 + } 190 + } 191 +//----- ---- --- -- - - - 192 +//-- (if 条件 真なら [偽なら]) returns executed-result 193 +//----- ---- --- -- - - - 194 + else if( name=="if" ) 195 + { 196 + if( c>=3 ) 197 + { 198 + if( getarg( a[1],b[1],&t ), t.len() ) 199 + getarg( a[2],b[2],r ); 200 + else if( c>=4 ) 201 + getarg( a[3],b[3],r ); 202 + } 203 + } 204 +//----- ---- --- -- - - - 205 +//-- (let 変数名 値 値 ...) returns new-value 206 +//----- ---- --- -- - - - 207 + else if( name=="let" ) 208 + { 209 + if( c>=2 ) 210 + { 211 + *r = ""; 212 + for( i=2; i<c; i++ ) 213 + getarg( a[i],b[i],&t ), *r+=t; 214 + ele[a[1][0]&0xff] = *r; 215 + } 216 + } 217 +//----- ---- --- -- - - - 218 +//-- (= 値A 値B) returns A==B ? 219 +//----- ---- --- -- - - - 220 + else if( name=="=" ) 221 + { 222 + if( c>=3 ) 223 + { 224 + getarg(a[1],b[1],&t), A=t.getInt(); 225 + getarg(a[2],b[2],&t), B=t.getInt(); 226 + *r = A==B ? "1" : ""; 227 + } 228 + } 229 +//----- ---- --- -- - - - 230 +//-- (between 値A 値B 値C) returns A <= B <= C ? 231 +//----- ---- --- -- - - - 232 + else if( name=="between" ) 233 + { 234 + if( c>=4 ) 235 + { 236 + getarg(a[1],b[1],&t), A=t.getInt(); 237 + getarg(a[2],b[2],&t), B=t.getInt(); 238 + getarg(a[3],b[3],&t), C=t.getInt(); 239 + *r = (A<=B && B<=C) ? "1" : ""; 240 + } 241 + } 242 +//----- ---- --- -- - - - 243 +//-- (! 値A [値B]) returns A!=B ? or !A 244 +//----- ---- --- -- - - - 245 + else if( name=="!" ) 246 + { 247 + if( c>=2 ) 248 + { 249 + getarg(a[1],b[1],&t), A=t.getInt(); 250 + if( c==2 ) 251 + *r = A==0 ? "1" : ""; 252 + else 253 + { 254 + getarg(a[2],b[2],&t), B=t.getInt(); 255 + *r = A!=B ? "1" : ""; 256 + } 257 + } 258 + } 259 +//----- ---- --- -- - - - 260 +//-- (+ 値A 値B) returns A+B 261 +//----- ---- --- -- - - - 262 + else if( name=="+" ) 263 + { 264 + if( c>=3 ) 265 + { 266 + getarg(a[1],b[1],&t), A=t.getInt(); 267 + getarg(a[2],b[2],&t), B=t.getInt(); 268 + r->setInt( A+B ); 269 + } 270 + } 271 +//----- ---- --- -- - - - 272 +//-- (- 値A 値B) returns A-B 273 +//----- ---- --- -- - - - 274 + else if( name=="-" ) 275 + { 276 + if( c>=3 ) 277 + { 278 + getarg(a[1],b[1],&t), A=t.getInt(); 279 + getarg(a[2],b[2],&t), B=t.getInt(); 280 + r->setInt( A-B ); 281 + } 282 + } 283 +//----- ---- --- -- - - - 284 +//-- (* 値A 値B) returns A*B 285 +//----- ---- --- -- - - - 286 + else if( name=="*" ) 287 + { 288 + if( c>=3 ) 289 + { 290 + getarg(a[1],b[1],&t), A=t.getInt(); 291 + getarg(a[2],b[2],&t), B=t.getInt(); 292 + r->setInt( A*B ); 293 + } 294 + } 295 +//----- ---- --- -- - - - 296 +//-- (/ 値A 値B) returns A/B 297 +//----- ---- --- -- - - - 298 + else if( name=="/" ) 299 + { 300 + if( c>=3 ) 301 + { 302 + getarg(a[1],b[1],&t), A=t.getInt(); 303 + getarg(a[2],b[2],&t), B=t.getInt(); 304 + r->setInt( A/B ); 305 + } 306 + } 307 +//----- ---- --- -- - - - 308 +//-- (mod 値A 値B) returns A%B 309 +//----- ---- --- -- - - - 310 + else if( name=="mod" ) 311 + { 312 + if( c>=3 ) 313 + { 314 + getarg(a[1],b[1],&t), A=t.getInt(); 315 + getarg(a[2],b[2],&t), B=t.getInt(); 316 + r->setInt( A%B ); 317 + } 318 + } 319 + else 320 + return false; 321 + return true; 322 +} 323 +
Added kilib/kl_rythp.h version [f76d7e48f9028031]
1 +//--- K.I.LIB --- 2 +// kl_rythp.h : interpretor for simple script langauage 'Rythp' 3 + 4 +#ifndef AFX_KIRYTHPVM_H__4F3C28A9_7EFE_4605_A149_2C0B9A9236E5__INCLUDED_ 5 +#define AFX_KIRYTHPVM_H__4F3C28A9_7EFE_4605_A149_2C0B9A9236E5__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// kiVar : Rythp用のVariant変数型。ほとんどただのkiStr。 9 + 10 +class kiVar : public kiStr 11 +{ 12 +public: 13 + kiVar() : kiStr(20) {} 14 + explicit kiVar( const char* s ) : kiStr( s, 20 ){} 15 + explicit kiVar( const kiStr& s ) : kiStr( s, 20 ){} 16 + explicit kiVar( const kiVar& s ) : kiStr( s, 20 ){} 17 + void operator = ( const char* s ){ kiStr::operator =(s); } 18 + 19 + int getInt(); 20 + void quote(); 21 +}; 22 + 23 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 24 +// kiRythpVM : 最小限Rythp。実用には、派生して独自の exec_function を実装すべし 25 + 26 +class kiRythpVM 27 +{ 28 +public: 29 + kiRythpVM(); 30 + virtual ~kiRythpVM() {} 31 + 32 +public: 33 + // eval 34 + void eval( char* str, kiVar* ans=NULL ); 35 + 36 +protected: 37 + // 引数を適当にevalや変数置き換えをした形で取得 38 + void getarg( char* a, bool b, kiVar* arg ); 39 + 40 + // function実行。[ bool=処理したか?、 name=function名、 a,b,c=引数、 r=返値 ] 41 + virtual bool exec_function( const kiVar& name, 42 + const CharArray& a, const BoolArray& b,int c, kiVar* r ); 43 + 44 +private: 45 + // 変数 46 + kiVar ele[256]; 47 + 48 + // パラメータ分割 49 + static char* split_tonext( char* p ); 50 + static char* split_toend( char* p ); 51 + static bool split( char* buf, CharArray& argv, BoolArray& argb, int& argc ); 52 +}; 53 + 54 +#endif
Added kilib/kl_str.cpp version [3d729f78441cf8a6]
1 +//--- K.I.LIB --- 2 +// kl_str.cpp : string classes for K.I.LIB 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 + 8 +//------------------------ 2byte文字処理用 ----------------------// 9 + 10 + 11 +char kiStr::st_lb[256]; 12 + 13 +void kiStr::init() 14 +{ 15 + st_lb[0] = 0; 16 + for( int c=1; c!=256; c++ ) 17 + st_lb[c] = (::IsDBCSLeadByte(c) ? 2 : 1); 18 +} 19 + 20 + 21 +//-------------------------- コピー系色々 ------------------------// 22 + 23 + 24 +kiStr::kiStr( int start_size ) 25 +{ 26 + (m_pBuf = new char[ m_ALen = start_size ])[0] = '\0'; 27 +} 28 + 29 +kiStr::kiStr( const char* s, int min_size ) 30 +{ 31 + int slen = ki_strlen(s) + 1; 32 + m_ALen = ( slen < min_size ) ? min_size : slen; 33 + ki_memcpy( m_pBuf=new char[m_ALen], s, slen ); 34 +} 35 + 36 +kiStr::kiStr( const kiStr& s ) 37 +{ 38 + ki_memcpy( m_pBuf=new char[m_ALen=s.m_ALen], s.m_pBuf, m_ALen=s.m_ALen ); 39 +} 40 + 41 +kiStr& kiStr::operator = ( const kiStr& s ) 42 +{ 43 + if( this != &s ) 44 + *this = (const char*)s; 45 + return *this; 46 +} 47 + 48 +kiStr& kiStr::operator = ( const char* s ) 49 +{ 50 + int slen = ki_strlen( s ) + 1; 51 + int len = this->len(); 52 + 53 + if( m_ALen < slen || s <= m_pBuf+len || m_pBuf <= s+slen ) 54 + { 55 + char* tmp = new char[ m_ALen = ( m_ALen>slen ? m_ALen : slen) ]; 56 + ki_memcpy( tmp, s, slen ); 57 + delete [] m_pBuf; 58 + m_pBuf = tmp; 59 + } 60 + else 61 + ki_memcpy( m_pBuf, s, slen ); 62 + return *this; 63 +} 64 + 65 +kiStr& kiStr::operator += ( const char* s ) 66 +{ 67 + int slen = ki_strlen( s ) + 1; 68 + int len = this->len(); 69 + 70 + if( m_ALen < len+slen+1 71 + || ( s <= m_pBuf && m_pBuf <= s+len ) 72 + || ( m_pBuf <= s && s <= m_pBuf+slen ) ) 73 + { 74 + char* tmp = new char[ m_ALen = ( m_ALen>slen+len+1 ? m_ALen : slen+len+1) ]; 75 + ki_memcpy( tmp, m_pBuf, len ); 76 + delete [] m_pBuf; 77 + m_pBuf = tmp; 78 + } 79 + 80 + ki_memcpy( m_pBuf+len, s, slen+1 ); 81 + return *this; 82 +} 83 + 84 +kiStr& kiStr::operator += ( char c ) 85 +{ 86 + int len = this->len(); 87 + 88 + if( m_ALen < len+2 ) 89 + { 90 + char* tmp = new char[ m_ALen=len+20 ]; 91 + ki_memcpy( tmp, m_pBuf, len ); 92 + delete [] m_pBuf; 93 + m_pBuf = tmp; 94 + } 95 + 96 + m_pBuf[len]=c, m_pBuf[len+1]='\0'; 97 + return *this; 98 +} 99 + 100 +kiStr& kiStr::setInt( int n, bool cm ) 101 +{ 102 + if( n==0 ) 103 + m_pBuf[0] = '0', m_pBuf[1] = '\0'; 104 + else 105 + { 106 + bool minus = (n<0); 107 + if( minus ) 108 + n= -n; 109 + 110 + char tmp[30]; 111 + tmp[29]='\0'; 112 + int i; 113 + 114 + for( i=28; i>=0; i-- ) 115 + { 116 + if( cm && (29-i)%4==0 ) 117 + tmp[i--] = ','; 118 + tmp[i] = '0' + n%10; 119 + n /= 10; 120 + if( n==0 ) 121 + break; 122 + } 123 + 124 + if( minus ) 125 + tmp[--i] = '-'; 126 + 127 + (*this) = tmp+i; 128 + } 129 + return (*this); 130 +} 131 + 132 +//-------------------------- 文字列処理全般 ------------------------// 133 + 134 + 135 +kiStr::~kiStr() 136 +{ 137 + delete [] m_pBuf; 138 +} 139 + 140 +kiStr::operator const char*() const 141 +{ 142 + return m_pBuf; 143 +} 144 + 145 +bool kiStr::operator == ( const char* s ) const 146 +{ 147 + return 0==ki_strcmp( m_pBuf, s ); 148 +} 149 + 150 +bool kiStr::isSame( const char* s ) const 151 +{ 152 + return 0==ki_strcmpi( m_pBuf, s ); 153 +} 154 + 155 +int kiStr::len() const 156 +{ 157 + return ki_strlen( m_pBuf ); 158 +} 159 + 160 + 161 +//-------------------------- ユーティリティー ------------------------// 162 + 163 + 164 +kiStr& kiStr::loadRsrc( UINT id ) 165 +{ 166 + ::LoadString( GetModuleHandle(NULL), id, m_pBuf, m_ALen ); 167 + return *this; 168 +} 169 + 170 +void kiPath::beSpecialPath( int nPATH ) 171 +{ 172 + switch( nPATH ) 173 + { 174 + case Win: ::GetWindowsDirectory( m_pBuf, m_ALen ); break; 175 + case Sys: ::GetSystemDirectory( m_pBuf, m_ALen ); break; 176 + case Tmp: ::GetTempPath( m_ALen, m_pBuf ); break; 177 + case Cur: ::GetCurrentDirectory( m_ALen, m_pBuf ); break; 178 + case Exe_name: 179 + ::GetModuleFileName( NULL, m_pBuf, m_ALen );break; 180 + case Exe: 181 + { 182 + ::GetModuleFileName( NULL, m_pBuf, m_ALen ); 183 + 184 + char* m=NULL; 185 + for( char *p=m_pBuf; *p!='\0'; p=next(p) ) 186 + if( *p=='\\' ) 187 + m = p; 188 + if( m ) 189 + *m='\0'; 190 + break; 191 + } 192 + default: 193 + { 194 + *m_pBuf = '\0'; 195 + 196 + LPITEMIDLIST il; 197 + if( NOERROR!=::SHGetSpecialFolderLocation( NULL, nPATH, &il ) ) 198 + return; 199 + ::SHGetPathFromIDList( il, m_pBuf ); 200 + app()->shellFree( il ); 201 + } 202 + } 203 +} 204 + 205 +void kiPath::beBackSlash( bool add ) 206 +{ 207 + char* last = m_pBuf; 208 + for( char* p=m_pBuf; *p!='\0'; p=next(p) ) 209 + last=p; 210 + if( *last=='\\' || *last=='/' ) 211 + { 212 + if( !add ) 213 + *last = '\0'; 214 + } 215 + else if( add && last!=m_pBuf ) 216 + *this += '\\'; 217 +} 218 + 219 +bool kiPath::beDirOnly() 220 +{ 221 + char* lastslash = m_pBuf-1; 222 + for( char* p=m_pBuf; *p; p=next(p) ) 223 + if( *p=='\\' || *p=='/' ) 224 + lastslash = p; 225 + 226 + *(lastslash+1) = '\0'; 227 + 228 + return (lastslash+1 != m_pBuf); 229 +} 230 + 231 +void kiPath::beShortPath() 232 +{ 233 + ::GetShortPathName( m_pBuf, m_pBuf, m_ALen ); 234 +} 235 + 236 +void kiPath::mkdir() 237 +{ 238 + for( char *p=m_pBuf; *p; p=kiStr::next(p) ) 239 + { 240 + if( (*p!='\\' && *p!='/') || (p-m_pBuf<=4) ) 241 + continue; 242 + *p = '\0'; 243 + if( !kiSUtil::exist(m_pBuf) ) 244 + if( ::CreateDirectory( m_pBuf, NULL ) ) 245 + ::SHChangeNotify( SHCNE_MKDIR,SHCNF_PATH,(const void*)m_pBuf,NULL ); 246 + *p = '\\'; 247 + } 248 +} 249 + 250 +void kiPath::remove() 251 +{ 252 + if( !kiSUtil::exist(*this) ) 253 + return; 254 + if( !kiSUtil::isdir(*this) ) 255 + { 256 + ::DeleteFile(*this); 257 + return; 258 + } 259 + 260 + // buf == filename with no last '\\' 261 + kiPath buf(*this); 262 + buf.beBackSlash(false); 263 + 264 + kiPath tmp(buf); 265 + WIN32_FIND_DATA fd; 266 + kiFindFile find; 267 + find.begin( tmp += "\\*" ); 268 + while( find.next( &fd ) ) 269 + { 270 + tmp = buf; 271 + tmp += '\\'; 272 + tmp += fd.cFileName; 273 + tmp.remove(); 274 + } 275 + find.close(); 276 + 277 + ::RemoveDirectory( buf ); 278 +} 279 + 280 +void kiPath::getBody( kiStr& str ) const 281 +{ 282 + char *p=const_cast<char*>(name()),*x,c; 283 + for( x=p; *x; x=next(x) ) 284 + if( *x=='.' ) 285 + break; 286 + c=*x, *x='\0'; 287 + str=p; 288 + *x=c; 289 +} 290 + 291 +const char* kiPath::name( const char* str ) 292 +{ 293 + const char* ans = str - 1; 294 + for( const char* p=str; *p; p=next(p) ) 295 + if( *p=='\\' || *p=='/' ) 296 + ans = p; 297 + return (ans+1); 298 +} 299 + 300 +const char* kiPath::ext( const char* str ) 301 +{ 302 + const char *ans = NULL, *p; 303 + for( p=name(str); *p; p=next(p) ) 304 + if( *p=='.' ) 305 + ans = p; 306 + return ans ? (ans+1) : p; 307 +} 308 + 309 +const char* kiPath::ext_all( const char* str ) 310 +{ 311 + const char* p; 312 + for( p=name(str); *p; p=next(p) ) 313 + if( *p=='.' ) 314 + return (p+1); 315 + return p; 316 +} 317 + 318 +void kiPath::body( const char* str, char* buf ) 319 +{ 320 + char *n=const_cast<char*>(kiPath::name(str)),*x; 321 + for( x=n; *x; x=next(x) ) 322 + if( *x=='.' ) 323 + break; 324 + memcpy( buf, str, x-n ); 325 + buf[x-n]='\0'; 326 +} 327 + 328 +UINT kiPath::getDriveType() const 329 +{ 330 + char* p; 331 + for( p=m_pBuf; *p=='\\'; p=next(p) ); 332 + for( p=m_pBuf; *p && *p!='\\'; p=next(p) ); 333 + char c=*(++p);*p='\0'; 334 + UINT ans=::GetDriveType( m_pBuf ); 335 + *p=c; return ans; 336 +} 337 + 338 +bool kiPath::endwithyen( const char* str ) 339 +{ 340 + for( const char *p=str,*last=str; *p; p=next(p) ) 341 + last=p; 342 + return ( *last=='\\' || *last=='/' ); 343 +} 344 +
Added kilib/kl_str.h version [801f887518c9b771]
1 +//--- K.I.LIB --- 2 +// kl_str.h : string classes for K.I.LIB 3 + 4 +#ifndef AFX_KISTR_H__1932CA2C_ACA6_4606_B57A_ACD0B7D1D35B__INCLUDED_ 5 +#define AFX_KISTR_H__1932CA2C_ACA6_4606_B57A_ACD0B7D1D35B__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// kiStr : 単純文字列 9 + 10 +class kiStr 11 +{ 12 +friend void kilib_startUp(); 13 + 14 +private: //-- グローバルな初期化処理など --------------------- 15 + 16 + static void init(); 17 + 18 +public: //-- 外向きインターフェイス -------------------------- 19 + 20 + // 2byte文字の処理を高速化(したような気分) 21 + static char* next( char* p ) 22 + { return p+st_lb[(*p)&0xff]; } 23 + static const char* next( const char* p ) 24 + { return p+st_lb[(*p)&0xff]; } 25 + static bool isLeadByte( char c ) 26 + { return st_lb[c&0xff]==2; } 27 + 28 + // 初期化 29 + kiStr( int start_size = 100 ); 30 + kiStr( const char* s, int min_size = 100 ); 31 + explicit kiStr( const kiStr& s ); 32 + 33 + // 演算子 34 + kiStr& operator = ( const kiStr& ); 35 + kiStr& operator = ( const char* s ); 36 + kiStr& operator += ( const char* s ); 37 + kiStr& operator += ( char c ); 38 + bool operator == ( const char* s ) const; 39 + bool isSame( const char* s ) const; 40 + operator const char*() const; 41 + int len() const; 42 + char operator[]( int i ) const 43 + { return m_pBuf[i]; } 44 + void lower() 45 + { ::CharLower(m_pBuf); } 46 + void upper() 47 + { ::CharUpper(m_pBuf); } 48 + kiStr& setInt( int n, bool cm=false ); 49 + 50 + // リソースからロード 51 + kiStr& loadRsrc( UINT id ); 52 + 53 +protected: //-- 派生クラス向け ----------------------------- 54 + 55 + char* m_pBuf; 56 + int m_ALen; 57 + 58 +private: //-- 内部処理 ------------------------------------- 59 + 60 + static char st_lb[256]; 61 + 62 +public: 63 + 64 + virtual ~kiStr(); 65 +}; 66 + 67 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 68 +// kiPath : パス特有の処理用関数付き文字列 69 + 70 +class kiPath : public kiStr 71 +{ 72 +public: //-- 外向きインターフェイス -------------------------- 73 + 74 + // 初期化 75 + kiPath() : kiStr( MAX_PATH ){} 76 + explicit kiPath( const char* s ) : kiStr( s, MAX_PATH ){} 77 + explicit kiPath( const kiStr& s ) : kiStr( s, MAX_PATH ){} 78 + explicit kiPath( const kiPath& s ) : kiStr( s, MAX_PATH ){} 79 + kiPath( int nPATH, bool bs = true ) : kiStr( MAX_PATH ) 80 + { 81 + beSpecialPath( nPATH ); 82 + if( nPATH != Exe_name ) 83 + beBackSlash( bs ); 84 + } 85 + 86 + // operator 87 + void operator = ( const char* s ){ kiStr::operator =(s); } 88 + 89 + // 特殊パス取得 90 + void beSpecialPath( int nPATH ); 91 + enum { Win=0x1787, Sys, Tmp, Prg, Exe, Cur, Exe_name, 92 + Snd=CSIDL_SENDTO, Dsk=CSIDL_DESKTOP, Doc=CSIDL_PERSONAL }; 93 + 94 + // 短いパス 95 + void beShortPath(); 96 + 97 + // 最後のバックスラッシュ制御 98 + void beBackSlash( bool add ); 99 + 100 + // ディレクトリ名のみ 101 + bool beDirOnly(); 102 + // ファイル名except拡張子のみ 103 + void getBody( kiStr& str ) const; 104 + 105 + // 複数階層mkdir 106 + void mkdir(); 107 + // 複数階層rmdir 108 + void remove(); 109 + 110 + // ドライブタイプ 111 + UINT getDriveType() const; 112 + 113 + // [static] ディレクトリ情報を含まない、ファイル名のみ抽出 114 + static const char* name( const char* str ); 115 + // [static] 最後の拡張子。無ければNULL 116 + static const char* ext( const char* str ); 117 + // [static] 拡張子全部。無ければNULL 118 + static const char* ext_all( const char* str ); 119 + // [static] body部分抽出。 120 + static void body( const char* str, char* buf ); 121 + // [static] \ / で終わるか否か 122 + static bool endwithyen( const char* str ); 123 + 124 + // non-static-ver 125 + const char* name() const 126 + { return name(m_pBuf); } 127 + const char* ext() const 128 + { return ext(m_pBuf); } 129 + const char* ext_all() const 130 + { return ext_all(m_pBuf); } 131 +}; 132 + 133 +#endif
Added kilib/kl_wcmn.cpp version [9574967cdc8457be]
1 +//--- K.I.LIB --- 2 +// kl_wcmn.h : windows-common-interface operatin 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 +static int CALLBACK __ki__ofp( HWND w, UINT m, LPARAM l, LPARAM d ) 8 +{ 9 + if( m==BFFM_INITIALIZED && d ) 10 + ::SendMessage( w, BFFM_SETSELECTION, TRUE, d ); 11 + return 0; 12 +} 13 + 14 +bool kiSUtil::getFolderDlg( char* buf, HWND par, const char* title, const char* def ) 15 +{ 16 + // 情報セット 17 + BROWSEINFO bi; 18 + ki_memzero( &bi, sizeof(bi) ); 19 + bi.hwndOwner = par; 20 + bi.pszDisplayName = buf; 21 + bi.lpszTitle = title; 22 + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_DONTGOBELOWDOMAIN; 23 + bi.lpfn = __ki__ofp; 24 + bi.lParam = (long)def; 25 + 26 + // ダイアログ表示 27 + ITEMIDLIST* id = SHBrowseForFolder( &bi ); 28 + if( id==NULL ) 29 + return false; 30 + SHGetPathFromIDList( id, buf ); 31 + app()->shellFree( id ); 32 + 33 + // 終了 34 + return true; 35 +} 36 + 37 +void kiSUtil::getFolderDlgOfEditBox( HWND wnd, HWND par, const char* title ) 38 +{ 39 + char str[MAX_PATH]; 40 + ::SendMessage( wnd, WM_GETTEXT, MAX_PATH, (LPARAM)str ); 41 + for( char* x=str,*l=str; *x; x=kiStr::next(x) ) 42 + l=x; 43 + if( *l=='\\' || *l=='/' ) 44 + *l='\0'; 45 + if( getFolderDlg( str, par, title, str ) ) 46 + ::SendMessage( wnd, WM_SETTEXT, 0, (LPARAM)str ); 47 +} 48 + 49 +int kiSUtil::getSysIcon( const char* ext ) 50 +{ 51 + SHFILEINFO fi; 52 + ::SHGetFileInfo( 53 + kiPath("test.")+=ext, 0, &fi, sizeof(fi), 54 + SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_SMALLICON ); 55 + return fi.iIcon; 56 +} 57 + 58 +void kiSUtil::msgLastError() 59 +{ 60 + char* pMsg; 61 + ::FormatMessage( 62 + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 63 + NULL,::GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&pMsg,0,NULL ); 64 + app()->msgBox( pMsg ); 65 + ::LocalFree( pMsg ); 66 +} 67 + 68 +void kiSUtil::createShortCut( const kiPath& at, const char* name ) 69 +{ 70 + ::CoInitialize(NULL); 71 + 72 + IShellLink* psl; 73 + if( SUCCEEDED(::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&psl)) ) 74 + { 75 + psl->SetPath( kiPath(kiPath::Exe_name) ); 76 + psl->SetWorkingDirectory( kiPath(kiPath::Exe,false) ); 77 + 78 + IPersistFile* ppf; 79 + if( SUCCEEDED(psl->QueryInterface(IID_IPersistFile,(void**)&ppf)) ) 80 + { 81 + WORD wsz[MAX_PATH]; 82 + kiPath lnkfile( at ); 83 + lnkfile += name, lnkfile += ".lnk"; 84 + ::MultiByteToWideChar(CP_ACP,0,lnkfile,-1,wsz,MAX_PATH); 85 + ppf->Save(wsz,TRUE); 86 + ppf->Release(); 87 + } 88 + psl->Release(); 89 + } 90 + ::CoUninitialize(); 91 +} 92 + 93 +bool kiSUtil::exist( const char* fname ) 94 +{ 95 + return 0xffffffff != ::GetFileAttributes( fname ); 96 +} 97 + 98 +bool kiSUtil::isdir( const char* fname ) 99 +{ 100 + DWORD attr = ::GetFileAttributes( fname ); 101 + return attr!=0xffffffff && (attr&FILE_ATTRIBUTE_DIRECTORY); 102 +} 103 + 104 +// 挿入caldixF 105 +// ファイル参照ダイアログ手抜き版 106 +bool kiSUtil::getOpenFileNameDlg(HWND hwnd,char *rfn) 107 +{ 108 + OPENFILENAME ofn; 109 + 110 + ZeroMemory((LPVOID)&ofn, sizeof(OPENFILENAME)); 111 + ofn.lStructSize = sizeof(OPENFILENAME); 112 + ofn.hwndOwner = hwnd; 113 + ofn.lpstrFilter = "アプリケーション(*.exe)\0*.exe\0全てのファイル(*.*)\0*.*\0\0"; 114 + ofn.lpstrFile = rfn; 115 + ofn.nMaxFile = MAX_PATH; 116 + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER; 117 + ofn.lpfnHook = NULL; 118 + // なんか持ってれば 119 + if (GetOpenFileName(&ofn)){ 120 + lstrcpy(rfn,ofn.lpstrFile); 121 + return TRUE; 122 + } 123 + 124 + return FALSE; 125 +} 126 + 127 +void kiSUtil::getOpenFileNameDlgOfEditBox(HWND wnd,HWND par) 128 +{ 129 + char str[MAX_PATH]; 130 + 131 + str[0] = '\0'; 132 + ::SendMessage( wnd, WM_GETTEXT, MAX_PATH, (LPARAM)str ); 133 + if( getOpenFileNameDlg(par,str) ) 134 + ::SendMessage( wnd, WM_SETTEXT, 0, (LPARAM)str ); 135 +} 136 +// 挿入ここまでcaldixF
Added kilib/kl_wcmn.h version [1fa60e16a8a46b53]
1 +//--- K.I.LIB --- 2 +// kl_wcmn.h : windows-common-interface operatin 3 + 4 +#ifndef AFX_KIWINCOMMON_H__0686721C_CAFB_4C2C_9FE5_0F482EA6A60B__INCLUDED_ 5 +#define AFX_KIWINCOMMON_H__0686721C_CAFB_4C2C_9FE5_0F482EA6A60B__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// シェルユーティリティークラス 9 + 10 +class kiSUtil 11 +{ 12 +public: 13 + // 「フォルダの選択」ダイアログ 14 + static bool getFolderDlg( char* buf, HWND par, const char* title, const char* def ); 15 + static void getFolderDlgOfEditBox( HWND wnd, HWND par, const char* title ); 16 + 17 + // 対応する拡張子用アイコンの、システムイメージリストのインデックスを返す。 18 + static int getSysIcon( const char* ext ); 19 + 20 + // 最後のエラーを表示 21 + static void msgLastError(); 22 + 23 + // 自分へのショートカット作成 24 + static void createShortCut( const kiPath& at, const char* name ); 25 + 26 + // ファイルが存在する? 27 + static bool exist( const char* fname ); 28 + static bool isdir( const char* fname ); 29 + 30 +// 挿入caldixF 31 + // ファイル参照ダイアログ手抜き版 32 + static bool getOpenFileNameDlg(HWND, char*); 33 + static void getOpenFileNameDlgOfEditBox(HWND, HWND); 34 +// 挿入ここまでcaldixF 35 +}; 36 + 37 +#endif
Added kilib/kl_wnd.cpp version [ebac3a7facda17a5]
1 +//--- K.I.LIB --- 2 +// kl_wnd.cpp : window information manager 3 + 4 +#include "stdafx.h" 5 +#include "kilib.h" 6 + 7 + 8 +//-------- Windowを作成時に HWND に kiWindow* をセットするための処理 -------// 9 + 10 + 11 +kiWindow* kiWindow::st_pCurInit = NULL; 12 + HHOOK kiWindow::st_hHook = NULL; 13 + 14 +void kiWindow::init() 15 +{ 16 + // CreateWindow 用フック設置 17 + st_hHook = ::SetWindowsHookEx( WH_CBT, &CBTProc, NULL, ::GetCurrentThreadId() ); 18 +} 19 + 20 +void kiWindow::finish() 21 +{ 22 + // CreateWindow 用フック解除 23 + ::UnhookWindowsHookEx( st_hHook ); 24 +} 25 + 26 +LRESULT CALLBACK kiWindow::CBTProc( int code, WPARAM wp, LPARAM lp ) 27 +{ 28 + if( code == HCBT_CREATEWND ) 29 + { 30 + if( st_pCurInit ) 31 + { 32 + // k.i.lib のウインドウが CreateWindow された場合 33 + st_pCurInit->setHwnd( (HWND)wp ); 34 + ::SetWindowLong( (HWND)wp, GWL_USERDATA, (LONG)st_pCurInit ); 35 + st_pCurInit = NULL; 36 + } 37 + else 38 + ::SetWindowLong( (HWND)wp, GWL_USERDATA, 0 ); 39 + } 40 + 41 + return ::CallNextHookEx( st_hHook, code, wp, lp ); 42 +} 43 + 44 +void kiWindow::detachHwnd() 45 +{ 46 + ::SetWindowLong( hwnd(), GWL_USERDATA, 0 ); 47 + if( this == app()->mainwnd() ) 48 + app()->setMainWnd( NULL ); 49 + setHwnd( NULL ); 50 +} 51 + 52 + 53 +//------------ Window にまつわるエトセトラな処理 (static) ---------------// 54 + 55 + 56 +bool kiWindow::loopbreaker = false; 57 + 58 +void kiWindow::msg() 59 +{ 60 + for( MSG msg; ::PeekMessage( &msg,NULL,0,0,PM_REMOVE ); ) 61 + ::TranslateMessage( &msg ), ::DispatchMessage( &msg ); 62 +} 63 + 64 +void kiWindow::msgLoop( msglooptype type ) 65 +{ 66 + kiWindow* wnd; 67 + MSG msg; 68 + while( !loopbreaker && 69 + type==GET ? ::GetMessage( &msg,NULL,0,0 ) 70 + : ::PeekMessage( &msg,NULL,0,0,PM_REMOVE ) ) 71 + { 72 + if( wnd = app()->mainwnd() ) 73 + { 74 + if( wnd->m_hAccel ) 75 + if( ::TranslateAccelerator( wnd->hwnd(), wnd->m_hAccel, &msg ) ) 76 + continue; 77 + if( wnd->isDlgMsg( &msg ) ) 78 + continue; 79 + } 80 + ::TranslateMessage( &msg ), ::DispatchMessage( &msg ); 81 + } 82 + loopbreaker = false; 83 +} 84 + 85 +void kiWindow::setFront( HWND wnd ) 86 +{ 87 + const OSVERSIONINFO& v = app()->osver(); 88 + 89 + // Win2000 以上 or Win98 以上 90 + if( ( v.dwPlatformId==VER_PLATFORM_WIN32_NT && v.dwMajorVersion>=5 ) 91 + || ( v.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS && 92 + v.dwMajorVersion*100+v.dwMinorVersion>=410 ) ) 93 + { 94 + DWORD pid; 95 + DWORD th1 = ::GetWindowThreadProcessId( ::GetForegroundWindow(), &pid ); 96 + DWORD th2 = ::GetCurrentThreadId(); 97 + ::AttachThreadInput( th2, th1, TRUE ); 98 + ::SetForegroundWindow( wnd ); 99 + ::AttachThreadInput( th2, th1, FALSE ); 100 + ::BringWindowToTop( wnd ); 101 + } 102 + else // 古いWin 103 + ::SetForegroundWindow( wnd ); 104 + 105 + // Special Thanks To kazubon !! ( the author of TClock ) 106 +} 107 + 108 +void kiWindow::setCenter( HWND wnd, HWND rel ) 109 +{ 110 + RECT rc,pr; 111 + ::GetWindowRect( wnd, &rc ); 112 + 113 + if( rel ) 114 + ::GetWindowRect( rel, &pr ); 115 + else 116 + ::SystemParametersInfo( SPI_GETWORKAREA, 0, &pr, 0 ); 117 + 118 + ::SetWindowPos( wnd, 0, 119 + pr.left + ( (pr.right-pr.left)-(rc.right-rc.left) )/2, 120 + pr.top + ( (pr.bottom-pr.top)-(rc.bottom-rc.top) )/2, 121 + 0, 0, SWP_NOSIZE|SWP_NOZORDER ); 122 +} 123 + 124 + 125 +//------------------ Windowベースクラスとしての処理 ----------------------// 126 + 127 + 128 +kiWindow::kiWindow() 129 +{ 130 + m_hWnd = NULL; 131 + m_hAccel = NULL; 132 + app()->shellInit(); 133 +} 134 + 135 +kiWindow::~kiWindow() 136 +{ 137 + if( m_hWnd && ::IsWindow( m_hWnd ) ) 138 + { 139 + ::SetWindowLong( m_hWnd, GWL_USERDATA, 0 ); 140 + ::DestroyWindow( m_hWnd ); 141 + } 142 +} 143 + 144 +void kiWindow::loadAccel( UINT id ) 145 +{ 146 + m_hAccel = ::LoadAccelerators( app()->inst(), MAKEINTRESOURCE(id) ); 147 +} 148 + 149 + 150 +//---------------- スタンドアロンのWindowの処理 ---------------------// 151 + 152 +// …未完成… 153 + 154 +//---------------------------- Dialog -----------------------------// 155 + 156 + 157 +kiDialog::kiDialog( UINT id ) 158 +{ 159 + m_Rsrc = id; 160 +} 161 + 162 +void kiDialog::doModal( HWND parent ) 163 +{ 164 + setState( true ); 165 + preCreate( this ); 166 + 167 + ::DialogBoxParam( app()->inst(), MAKEINTRESOURCE(m_Rsrc), 168 + parent, commonDlg, (LPARAM)this ); 169 +} 170 + 171 +void kiDialog::createModeless( HWND parent ) 172 +{ 173 + setState( false ); 174 + preCreate( this ); 175 + 176 + ::CreateDialogParam( app()->inst(), MAKEINTRESOURCE(m_Rsrc), 177 + parent, commonDlg, (LPARAM)this ); 178 + 179 + ::ShowWindow( hwnd(), SW_SHOW ); 180 + ::UpdateWindow( hwnd() ); 181 +} 182 + 183 +void kiDialog::end( UINT endcode ) 184 +{ 185 + setEndCode( endcode ); 186 + 187 + if( isModal() ) 188 + ::EndDialog( hwnd(), getEndCode() ); 189 + else 190 + ::DestroyWindow( hwnd() ); 191 +} 192 + 193 +BOOL kiDialog::commonDlg( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ) 194 +{ 195 + // kiDialog インターフェイスへのポインタを取得 196 + kiDialog* ptr = (kiDialog*)::GetWindowLong( dlg, GWL_USERDATA ); 197 + if( !ptr ) return FALSE; 198 + 199 + // WM_INITDIALOG なら onInit を呼ぶ 200 + if( msg == WM_INITDIALOG ) 201 + return ptr->onInit(); 202 + 203 + // OK / Cancel 処理 204 + else if( msg == WM_COMMAND ) 205 + { 206 + switch( LOWORD(wp) ) 207 + { 208 + case IDOK: 209 + if( ptr->onOK() ) 210 + ptr->end( IDOK ); 211 + return TRUE; 212 + case IDCANCEL: 213 + if( ptr->onCancel() ) 214 + ptr->end( IDCANCEL ); 215 + return TRUE; 216 + } 217 + } 218 + 219 + // 普通のメッセージ 220 + BOOL ans = ptr->proc( msg, wp, lp ); 221 + 222 + // WM_DESTORY ならウインドウハンドル切り離し 223 + if( msg == WM_DESTROY ) 224 + ptr->detachHwnd(); 225 + 226 + return ans; 227 +} 228 + 229 + 230 +//------------------------ PropertySheet -------------------------// 231 + 232 + 233 +kiPropSheet* kiPropSheet::st_CurInitPS = NULL; 234 + 235 +kiPropSheet::kiPropSheet() : kiDialog( 0 ) 236 +{ 237 + ki_memzero( &m_Header, sizeof(m_Header) ); 238 + m_Header.dwSize = sizeof(m_Header); 239 + m_Header.dwFlags |=PSH_USECALLBACK | PSH_PROPSHEETPAGE; 240 + m_Header.pfnCallback = main_initProc; 241 + m_Header.hInstance = app()->inst(); 242 + m_Header.nStartPage = 0; 243 +} 244 + 245 +void kiPropSheet::begin() 246 +{ 247 + int l = m_Pages.len(); 248 + PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[ l ]; 249 + ki_memzero( ppsp, sizeof(PROPSHEETPAGE)*l ); 250 + 251 + for( int i=0; i<l; i++ ) 252 + { 253 + ppsp[i].dwSize = sizeof( PROPSHEETPAGE ); 254 + ppsp[i].hInstance = app()->inst(); 255 + ppsp[i].pfnCallback = page_initProc; 256 + ppsp[i].pfnDlgProc = page_cmmnProc; 257 + ppsp[i].dwFlags = PSP_USECALLBACK | PSP_HASHELP; 258 + m_Pages[i]->setInfo( ppsp+i ); 259 + } 260 + 261 + m_Header.ppsp = ppsp; 262 + m_Header.nPages = l; 263 + 264 + st_CurInitPS = this; 265 + PropertySheet( &m_Header ); 266 + delete [] ppsp; 267 +} 268 + 269 +void kiPropSheet::doModal( HWND parent ) 270 +{ 271 + m_Header.dwFlags &= (~PSH_MODELESS); 272 + setState( true ); 273 + begin(); 274 +} 275 + 276 +void kiPropSheet::createModeless( HWND parent ) 277 +{ 278 + m_Header.dwFlags |= PSH_MODELESS; 279 + setState( false ); 280 + begin(); 281 +} 282 + 283 +void kiPropSheet::end( UINT endcode ) 284 +{ 285 + // 終了コードセット 286 + setEndCode( endcode ); 287 + 288 + // サブクラス化解除 289 + ::SetWindowLong( hwnd(), GWL_WNDPROC, (LONG)m_DefProc ); 290 + 291 + // 終了 292 + if( isModal() ) // サブクラス化解除してるので、再度 end が呼ばれることはないはず。 293 + ::PostMessage( hwnd(), WM_COMMAND, IDCANCEL, 0 ); 294 + else 295 + ::DestroyWindow( hwnd() ); 296 + 297 + // WM_DESTROY時相当の動作 298 + detachHwnd(); 299 +} 300 + 301 +LRESULT CALLBACK kiPropSheet::main_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ) 302 +{ 303 + kiPropSheet* ptr = (kiPropSheet*)::GetWindowLong( dlg, GWL_USERDATA ); 304 + if( !ptr ) 305 + return 0; 306 + 307 + // まずデフォルトの処理 308 + LRESULT result = ::CallWindowProc( ptr->m_DefProc, dlg, msg, wp, lp ); 309 + 310 + // ×ボタンはキャンセル扱い 311 + if( msg==WM_SYSCOMMAND && wp==SC_CLOSE ) 312 + ::PostMessage( dlg, WM_COMMAND, IDCANCEL, 0 ); 313 + 314 + // コマンド処理 315 + else if( msg==WM_COMMAND ) 316 + { 317 + switch( LOWORD(wp) ) 318 + { 319 + case IDOK: 320 + if( ptr->onOK() ) 321 + ptr->end( IDOK ); 322 + return TRUE; 323 + case IDCANCEL: 324 + if( ptr->onCancel() ) 325 + ptr->end( IDCANCEL ); 326 + return TRUE; 327 + case IDAPPLY: 328 + ptr->onApply(); 329 + break; 330 + case ID_KIPS_HELP: 331 + ptr->onHelp(); 332 + break; 333 + default: 334 + ptr->onCommand( LOWORD(wp) ); 335 + break; 336 + } 337 + } 338 + 339 + // ドラッグ&ドロップ 340 + else if( msg==WM_DROPFILES ) 341 + ptr->onDrop( (HDROP)wp ); 342 + 343 + return result; 344 +} 345 + 346 +struct DLGTEMPLATEEX 347 +{ 348 + WORD dlgVer; 349 + WORD signature; 350 + DWORD helpID; 351 + DWORD exStyle; 352 + DWORD style; 353 + WORD cDlgItems; 354 + short x; 355 + short y; 356 + short cx; 357 + short cy; 358 +}; 359 + 360 +int CALLBACK kiPropSheet::main_initProc( HWND dlg, UINT msg, LPARAM lp ) 361 +{ 362 + if( msg == PSCB_PRECREATE ) 363 + { 364 + // スタイルを指すDWORDのアドレスを取得 365 + DWORD* pst = ( 0xffff==((DLGTEMPLATEEX*)lp)->signature ) ? 366 + &(((DLGTEMPLATEEX*)lp)->style) : &(((DLGTEMPLATE*)lp)->style); 367 + // ヘルプボタンを消して最小化ボタンを付ける 368 + (*pst) &= ~DS_CONTEXTHELP; 369 + (*pst) |= WS_MINIMIZEBOX; 370 + 371 + preCreate( st_CurInitPS ); 372 + } 373 + else if( msg == PSCB_INITIALIZED ) 374 + { 375 + // 何故か出来てしまう余計なメニューを削除 376 + HMENU sysm = ::GetSystemMenu( dlg, FALSE ); 377 + ::DeleteMenu( sysm, SC_SIZE, MF_BYCOMMAND ); 378 + ::DeleteMenu( sysm, SC_MAXIMIZE, MF_BYCOMMAND ); 379 + 380 + // 起動時はウインドウを必ず前面へ 381 + setFront( dlg ); 382 + 383 + //サブクラス化する 384 + st_CurInitPS->m_DefProc = (WNDPROC)::SetWindowLong( dlg, GWL_WNDPROC, (LONG)main_cmmnProc ); 385 + st_CurInitPS->onInit(); 386 + } 387 + return 0; 388 +} 389 + 390 +BOOL kiPropSheet::page_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ) 391 +{ 392 + kiPropSheetPage* ptr = (kiPropSheetPage*)::GetWindowLong( dlg, GWL_USERDATA ); 393 + if( !ptr ) 394 + return FALSE; 395 + 396 + // ここで、共通処理 397 + switch( msg ) 398 + { 399 + case WM_INITDIALOG: 400 + return ptr->onInit(); 401 + 402 + case WM_NOTIFY: 403 + switch( ((NMHDR*)lp)->code ) 404 + { 405 + case PSN_APPLY: 406 + ptr->onOK(); 407 + return TRUE; 408 + } 409 + break; 410 + 411 + case WM_COMMAND: 412 + if( lp ) 413 + switch( HIWORD(wp) ) 414 + { 415 + case BN_CLICKED: 416 + if((HWND)lp==::GetFocus()) 417 + case EN_CHANGE: 418 + case CBN_SELCHANGE: 419 + PropSheet_Changed( ptr->parent()->hwnd(), dlg ); 420 + } 421 + break; 422 + 423 + case WM_DESTROY: 424 + BOOL ans=ptr->proc( msg, wp, lp ); 425 + ptr->detachHwnd(); 426 + return ans; 427 + } 428 + 429 + return ptr->proc( msg, wp, lp ); 430 +} 431 + 432 +UINT CALLBACK kiPropSheet::page_initProc( HWND dlg, UINT msg, LPPROPSHEETPAGE ppsp ) 433 +{ 434 + if( msg == PSPCB_CREATE ) 435 + preCreate( (kiWindow*)(ppsp->lParam) ); 436 + return TRUE; 437 +} 438 + 439 +void kiPropSheetPage::setInfo( PROPSHEETPAGE* p ) 440 +{ 441 + p->pszTemplate = MAKEINTRESOURCE( getRsrcID() ); 442 + p->lParam = (LPARAM)this; 443 + 444 + if( m_hIcon ) 445 + { 446 + p->dwFlags|= PSP_USEHICON; 447 + p->hIcon = m_hIcon; 448 + } 449 +} 450 +
Added kilib/kl_wnd.h version [f33ef5bd22524140]
1 +//--- K.I.LIB --- 2 +// kl_wnd.h : window information manager 3 + 4 +#ifndef AFX_KIWINDOW_H__26105B94_1E36_42FA_8916_C2F7FB9EF994__INCLUDED_ 5 +#define AFX_KIWINDOW_H__26105B94_1E36_42FA_8916_C2F7FB9EF994__INCLUDED_ 6 + 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +// kiWindow : Windowの簡単な管理 9 + 10 +class kiWindow 11 +{ 12 +friend void kilib_startUp(); 13 + 14 +private: //-- グローバルな初期化処理など --------------------- 15 + 16 + static void init(); 17 + static void finish(); 18 + 19 +public: //-- 外向きインターフェイス -------------------------- 20 + 21 + // 関連付けられているHWND 22 + HWND hwnd() 23 + { 24 + return m_hWnd; 25 + } 26 + 27 + // そのWindow用にアクセラレータをロード 28 + void loadAccel( UINT id ); 29 + 30 + // ウインドウがまだ残っているかどうかチェック 31 + bool isAlive() 32 + { 33 + if( !m_hWnd ) 34 + return false; 35 + if( ::IsWindow(m_hWnd) ) 36 + return true; 37 + m_hWnd = NULL; 38 + return false; 39 + } 40 + 41 + // 親 42 + kiWindow* parent() 43 + { 44 + return kiwnd( ::GetParent( hwnd() ) ); 45 + } 46 + 47 + // メッセージ送信 48 + int sendMsg( UINT msg, WPARAM wp=0, LPARAM lp=0 ) 49 + { 50 + return ::SendMessage( hwnd(), msg, wp, lp ); 51 + } 52 + 53 + // [static] キューにあるメッセージを全て処理 54 + static void msg(); 55 + 56 + // [static] メッセージループをまわす。 57 + enum msglooptype {PEEK, GET}; 58 + static void msgLoop( msglooptype type = GET ); 59 + 60 + // [static] Windowを強制的に front へ 61 + static void setFront( HWND wnd ); 62 + 63 + // [static] Windowを中央へ 64 + static void setCenter( HWND wnd, HWND rel=NULL ); 65 + 66 + // [static] HWND -> kiWindow ( もしあれば ) 67 + static kiWindow* kiwnd( HWND wnd ) 68 + { 69 + kiWindow* ptr = (kiWindow*)::GetWindowLong( wnd, GWL_USERDATA ); 70 + if( !ptr ) return NULL; 71 + if( ::IsBadCodePtr((FARPROC)&ptr) ) return NULL; 72 + return ptr; 73 + } 74 + 75 +protected: //-- 派生クラス向け ----------------------------- 76 + 77 + // 派生クラスは、作成直前にコレを呼ぶこと。 78 + static void preCreate( kiWindow* wnd ) 79 + { st_pCurInit = wnd; } 80 + // 破棄直前にコレを呼ぶこと。 81 + void detachHwnd(); 82 + // いったんGET/POSTメッセージループを停止 83 + static void loopbreak() 84 + { 85 + loopbreaker = true; 86 + } 87 + 88 +private: //-- 内部処理 ------------------------------------- 89 + 90 + // ウインドウハンドル設定 91 + static LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp ); 92 + static HHOOK st_hHook; 93 + static kiWindow* st_pCurInit; 94 + void setHwnd( HWND wnd ) 95 + { 96 + m_hWnd = wnd; 97 + } 98 + 99 + // ウインドウ情報保持用変数 100 + HWND m_hWnd; 101 + HACCEL m_hAccel; 102 + // ダイアログメッセージ 103 + virtual bool isDlgMsg( MSG* msg ) 104 + { return false; } 105 + // GETループ一時抜けだし 106 + static bool loopbreaker; 107 + 108 +protected: 109 + kiWindow(); 110 +public: 111 + virtual ~kiWindow(); 112 +}; 113 + 114 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 115 +// kiDialog : DialogをkiWindowとして管理する 116 + 117 +class kiDialog : public kiWindow 118 +{ 119 +public: //-- 外向きインターフェイス -------------------------- 120 + 121 + // モーダルダイアログとして実行 122 + virtual void doModal( HWND parent=NULL ); 123 + 124 + // モードレスダイアログとして作成 125 + virtual void createModeless( HWND parent=NULL ); 126 + 127 + // 終了コード取得 128 + UINT getEndCode() 129 + { 130 + return m_EndCode; 131 + } 132 + 133 + // モーダルか否か 134 + bool isModal() 135 + { 136 + return m_bStateModal; 137 + } 138 + 139 + // ダイアログアイテム 140 + int sendMsgToItem( UINT id, UINT msg, WPARAM wp=0, LPARAM lp=0 ) 141 + { 142 + return ::SendDlgItemMessage( hwnd(), id, msg, wp, lp ); 143 + } 144 + HWND item( UINT id ) 145 + { 146 + return ::GetDlgItem( hwnd(), id ); 147 + } 148 + 149 +protected: //-- 派生クラス向け ----------------------------- 150 + 151 + // リソースIDで初期化 152 + kiDialog( UINT id ); 153 + 154 + // リソースID取得 155 + UINT getRsrcID() 156 + { 157 + return m_Rsrc; 158 + } 159 + 160 + // 終了コードをセット 161 + void setEndCode( UINT endcode ) 162 + { 163 + m_EndCode = endcode; 164 + } 165 + 166 + // モーダルか否かのフラグ"のみ"を切替 167 + void setState( bool modal ) 168 + { 169 + m_bStateModal = modal; 170 + } 171 + 172 + // 終了コードをセットして、終了する( IDOK を渡しても onOK() は呼ばれないことに注意! ) 173 + virtual void end( UINT endcode ); 174 + 175 + // コマンド・メッセージ発生時に呼ばれる 176 + 177 + // OK -> onOK -> if true end(IDOK) 178 + virtual bool onOK() {return true;} 179 + // 取消 -> onCancel -> if true end(IDCANCEL) 180 + virtual bool onCancel() {return true;} 181 + // WM_INITDIALOG -> onInit 182 + virtual BOOL onInit() {return FALSE;} 183 + // WM_???? -> proc 184 + virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) {return FALSE;} 185 + 186 +private: //-- 内部処理 ------------------------------------- 187 + 188 + UINT m_EndCode; 189 + UINT m_Rsrc; 190 + bool m_bStateModal; 191 + bool isDlgMsg( MSG* msg ) 192 + { 193 + return (FALSE!=::IsDialogMessage( hwnd(), msg )); 194 + } 195 + static BOOL CALLBACK commonDlg( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ); 196 +}; 197 + 198 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 199 +// kiPropSheet : PropertySheetをkiWindowとして管理する。 200 + 201 +#define IDAPPLY (0x3021) 202 +#define ID_KIPS_HELP (0x0009) 203 + 204 +class kiPropSheetPage : public kiDialog 205 +{ 206 +friend class kiPropSheet; 207 + 208 +protected: //-- 派生クラス向け ---------------------------- 209 + 210 + // ダイアログやアイコンのIDで初期化 211 + kiPropSheetPage( UINT dlgid ) 212 + : kiDialog( dlgid ), m_hIcon( NULL ) {} 213 + void setIcon( HICON h ) 214 + { m_hIcon = h; } 215 + 216 + // OK/適用 -> page::onOK -> sheet::onOK -> (if ok 終了) 217 + // virtual bool onOK() 218 + // WM_INITDIALOG 219 + // virtual BOOL onInit() 220 + // その他 221 + // virtual BOOL CALLBACK proc( UINT msg, WPARAM wp, LPARAM lp ) 222 + 223 +private: //-- 内部処理 ------------------------------------- 224 + 225 + void end( UINT endcode ) {} 226 + void setInfo( PROPSHEETPAGE* p ); 227 + HICON m_hIcon; 228 +}; 229 + 230 +class kiPropSheet : public kiDialog 231 +{ 232 +friend class kiPropSheetPage; 233 + 234 +public: //-- 外向きインターフェイス -------------------------- 235 + 236 + // モーダルダイアログとして実行 237 + void doModal( HWND parent ); 238 + 239 + // モードレスダイアログとして作成 240 + void createModeless( HWND parent ); 241 + 242 +protected: //-- 派生クラス向け ---------------------------- 243 + 244 + // コンストラクタ辺りで↓これをいじるべし 245 + PROPSHEETHEADER m_Header; 246 + kiArray<kiPropSheetPage*> m_Pages; 247 + 248 + // 終了 249 + void end( UINT endcode ); 250 + // 251 + void sendOK2All() 252 + { 253 + for( unsigned int i=0;i!=m_Pages.len(); i++ ) 254 + if( m_Pages[i]->isAlive() ) 255 + m_Pages[i]->onOK(); 256 + } 257 + 258 + // OK/適用 -> page::onOK -> sheet::onOK -> (if ok 終了) 259 + // virtual void onOK() 260 + // キャンセル -> sheet::onCancel -> 終了 261 + // virtual void onCancel() 262 + // PSCB_INITIALIZED 263 + // virtual BOOL onInit() 264 + // 適用 265 + virtual void onApply() {} 266 + // ヘルプ 267 + virtual void onHelp() {} 268 + // その他コマンド 269 + virtual void onCommand( UINT id ) {} 270 + // ファイルドロップ 271 + virtual void onDrop( HDROP hdrop ) {} 272 + 273 +private: //-- 内部処理 --------------------------------------- 274 + 275 + void begin(); 276 + bool m_bStateModal; 277 + 278 + static kiPropSheet* st_CurInitPS; 279 + WNDPROC m_DefProc; 280 + bool isDlgMsg( MSG* msg ) 281 + { return (FALSE!=PropSheet_IsDialogMessage( hwnd(),msg )); } 282 + static int CALLBACK main_initProc( HWND dlg, UINT msg, LPARAM lp ); 283 + static LRESULT CALLBACK main_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ); 284 + static BOOL CALLBACK page_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp ); 285 + static UINT CALLBACK page_initProc( HWND dlg, UINT msg, LPPROPSHEETPAGE ppsp ); 286 + 287 +protected: 288 + kiPropSheet(); 289 +public: 290 + ~kiPropSheet() 291 + { for( unsigned int i=0; i!=m_Pages.len(); i++ ) delete m_Pages[i]; } 292 +}; 293 + 294 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 295 +// kiListView : ListViewコントロールの簡単なラッパ 296 + 297 +class kiListView 298 +{ 299 +public: 300 + kiListView( kiDialog* dlg, UINT id ) 301 + { 302 + m_hWnd = ::GetDlgItem( dlg->hwnd(), id ); 303 + } 304 + 305 + void insertColumn( int y, const char* title, 306 + int width=100, int fmt=LVCFMT_LEFT ) 307 + { 308 + LVCOLUMN col; 309 + col.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH; 310 + col.pszText = const_cast<char*>(title); 311 + col.cx = width; 312 + col.fmt = fmt; 313 + ::SendMessage( m_hWnd, LVM_INSERTCOLUMN, y, (LPARAM)&col ); 314 + } 315 + 316 + void insertItem( int x, const char* str, LPARAM param=0, int iImage=-1 ) 317 + { 318 + LVITEM item; 319 + item.mask = LVIF_TEXT | LVIF_PARAM | (iImage!=-1 ? LVIF_IMAGE : 0); 320 + item.pszText = const_cast<char*>(str); 321 + item.iItem = x; 322 + item.iSubItem = 0; 323 + item.iImage = iImage; 324 + item.lParam = param; 325 + ::SendMessage( m_hWnd, LVM_INSERTITEM, 0, (LPARAM)&item ); 326 + } 327 + 328 + void setSubItem( int x, int y, const char* str ) 329 + { 330 + LVITEM item; 331 + item.mask = LVIF_TEXT; 332 + item.pszText = const_cast<char*>(str); 333 + item.iItem = x; 334 + item.iSubItem = y; 335 + ::SendMessage( m_hWnd, LVM_SETITEM, 0, (LPARAM)&item ); 336 + } 337 + 338 + void setImageList( HIMAGELIST Large, HIMAGELIST Small ) 339 + { 340 + ::SendMessage( m_hWnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)Large ); 341 + ::SendMessage( m_hWnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)Small ); 342 + } 343 + 344 +private: 345 + HWND m_hWnd; 346 +}; 347 + 348 +#endif
Added kiutil.cpp version [1eab6b89a8a30aee]
1 + 2 +#include "stdafx.h" 3 +#include "kiutil.h" 4 + 5 +/////////////// 6 + 7 +void kiutil::timeSet( const char* fname, FILETIME* pft ) 8 +{ 9 + HANDLE han = CreateFile( fname, 10 + GENERIC_READ | GENERIC_WRITE, 11 + FILE_SHARE_READ,NULL, 12 + OPEN_EXISTING, 13 + FILE_ATTRIBUTE_NORMAL, 14 + NULL ); 15 + if( han==INVALID_HANDLE_VALUE ) 16 + return; 17 + 18 + SetFileTime( han,pft,NULL,pft ); 19 + 20 + CloseHandle( han ); 21 +} 22 + 23 +void kiutil::timeSet( const char* fname, DWORD sec ) 24 +{ 25 + struct tm* time=gmtime((long*)&sec); 26 + if( time!=NULL ) 27 + { 28 + FILETIME ft; 29 + SYSTEMTIME sys; 30 + 31 + sys.wYear = time->tm_year+1900; 32 + sys.wMonth = time->tm_mon+1; 33 + sys.wDayOfWeek = time->tm_wday; 34 + sys.wDay = time->tm_mday; 35 + sys.wHour = time->tm_hour; 36 + sys.wMinute = time->tm_min; 37 + sys.wSecond = time->tm_sec; 38 + sys.wMilliseconds = 0; 39 + SystemTimeToFileTime(&sys,&ft); 40 + timeSet( fname,&ft ); 41 + } 42 +} 43 + 44 +void kiutil::timeSet( const char* fname,WORD date,WORD time ) 45 +{ 46 + FILETIME ft,lc; 47 + if( DosDateTimeToFileTime( date, time, &lc ) ) 48 + { 49 + if( LocalFileTimeToFileTime( &lc, &ft ) ) 50 + timeSet( fname,&ft ); 51 + } 52 +} 53 + 54 +////////////// 55 + 56 +void kiutil::wndFront( HWND wnd ) 57 +{ 58 + static DWORD Ver = GetVersion(); 59 + 60 + if( ( (Ver&0x80000000) && LOBYTE(LOWORD(Ver))>=4 && HIBYTE(LOWORD(Ver))>=10 ) || 61 + (!(Ver&0x80000000) && LOBYTE(LOWORD(Ver))>=5 )) // 新しいWindows 62 + { 63 + DWORD pid; 64 + DWORD thread1 = GetWindowThreadProcessId( GetForegroundWindow(),&pid ); 65 + DWORD thread2 = GetCurrentThreadId(); 66 + AttachThreadInput( thread2, thread1, TRUE ); 67 + SetForegroundWindow( wnd ); 68 + AttachThreadInput( thread2, thread1, FALSE ); 69 + BringWindowToTop( wnd ); 70 + } 71 + else // 古いWindows 72 + SetForegroundWindow( wnd ); 73 +} 74 + 75 +/////////////// 76 + 77 +char kiutil::lb[256]; 78 + 79 +void kiutil::pathInit() 80 +{ 81 + lb[0] = 0; 82 + for( int c=1; c!=256; c++ ) 83 + lb[c] = (IsDBCSLeadByte(c) ? 2 : 1); 84 +} 85 + 86 +#define isdblb(c) (lb[(unsigned char)(c)]==2) 87 +#define step(p) (p+=lb[(unsigned char)*(p)]) 88 + 89 +char* kiutil::pathMake( char* path ) 90 +{ 91 + char* st = path; 92 + 93 + while( *st=='/' || *st=='\\' || *st=='?' ) 94 + st++; 95 + if( st[0]!='\0' && st[1]==':' ) 96 + st+=2; 97 + while( *st=='/' || *st=='\\' || *st=='?' ) 98 + st++; 99 + 100 + for( unsigned char *p=(unsigned char*)st; *p!='\0'; step(p) ) 101 + { 102 + if( isdblb(*p) ) 103 + continue; 104 + 105 + if( *p=='\\' || *p=='/' ) 106 + { 107 + *p='\0'; 108 + CreateDirectory( st, NULL ); 109 + *p='\\'; 110 + } 111 + else if( *p<' ' || ( *p>'~' && !( 0xa0<=*p && *p<=0xdf ) ) || strchr(":*?\"<>|",*p) ) 112 + *p = '_'; 113 + } 114 + 115 + return st; 116 +} 117 + 118 +void kiutil::pathMakeAbs( char* path ) 119 +{ 120 + int i=0; 121 + for( char* p=path; *p!='\0'; step(p) ) 122 + { 123 + if( i++ < 4 ) // 最初の4文字以内の \ はドライブを表す、ということにしておく。 124 + continue; 125 + 126 + if( *p=='\\' ) 127 + { 128 + *p='\0'; 129 + CreateDirectory( path, NULL ); 130 + *p='\\'; 131 + } 132 + } 133 +} 134 + 135 +void kiutil::pathSplit( const char* path, int* y, int* d ) 136 +{ 137 + *y=-1, *d=-1; 138 + for( const char* x=path; *x!='\0'; step(x) ) 139 + { 140 + if( *x=='\\' || *x=='/' ) *y=x-path,*d=-1; 141 + else if( *x=='.' ) *d=x-path; 142 + } 143 +} 144 + 145 +const char* kiutil::pathExt( const char* path ) 146 +{ 147 + int y,d; 148 + kiutil::pathSplit( path,&y,&d ); 149 + return (d!=-1) ? path+d+1 : path+strlen(path); 150 +} 151 + 152 +const char* kiutil::pathName( const char* path ) 153 +{ 154 + int y,d; 155 + kiutil::pathSplit( path,&y,&d ); 156 + return path+y+1; 157 +} 158 + 159 +#undef step 160 +#undef isdblb 161 + 162 +////////////// 163 + 164 +char* kiutil::getline( char* str, int size, FILE* fp ) 165 +{ 166 + if( size>0 ) 167 + { 168 + char* p=str; 169 + 170 + while( --size ) 171 + { 172 + int c = fgetc(fp); 173 + 174 + if( c<=0 ) // EOF || '\0' 175 + break; 176 + else if( c=='\n' ) 177 + break; 178 + else if( c=='\r' ) 179 + { 180 + c = fgetc(fp); 181 + if( c!=EOF && c!='\n' ) 182 + ungetc( c,fp ); 183 + break; 184 + } 185 + else 186 + *(p++) = c; 187 + } 188 + 189 + *p='\0'; 190 + } 191 + 192 + return feof(fp) ? NULL : str; 193 +} 194 + 195 +void kiutil::getOriginalName( char* nw, const char* od, char* ext ) 196 +{ 197 + int y,d; 198 + kiutil::pathSplit( od,&y,&d ); 199 + strcpy( nw,od+y+1 ); 200 + 201 + if( ext ) 202 + { 203 + strcat( nw,"." ); 204 + strcat( nw,ext ); 205 + } 206 + else 207 + nw[d-y-1]='\0'; 208 +} 209 +
Added kiutil.h version [b599308488667041]
1 +#ifndef AFX_KIUTIL_H__D2E1F380_468E_11D3_8D94_ECF8CA9E4339__INCLUDED_ 2 +#define AFX_KIUTIL_H__D2E1F380_468E_11D3_8D94_ECF8CA9E4339__INCLUDED_ 3 + 4 +// ちょっと便利かも知れない関数群「kiutil」 5 +// 6 +// VC++ のツリーでひとまとめで表示させるためにクラス化 7 +// しただけで、実は全部 public & static だったりする。(^^; 8 + 9 +class kiutil 10 +{ 11 +public: 12 + 13 +// タイムスタンプ 14 + 15 + // WIN( 0.1 millisec from 1601.1.1 ) 16 + static void timeSet( const char* fname, FILETIME* pft ); 17 + // DOS( 0-4:day 5-8:month 9-15:year+1980, 0-4:sec/2 5-10:min 11-15:hour ) 18 + static void timeSet( const char* fname, WORD date, WORD time ); 19 + // UNIX( sec from 1970.1.1 ) 20 + static void timeSet( const char* fname, DWORD sec ); 21 + 22 +// パス文字列 23 + 24 + // ↓最初に必ずコレを呼んでおくこと! 25 + static void pathInit(); 26 + 27 + // 相対パスを与えると [不正文字除去],[複数階層makeDir] を行う 28 + static char* pathMake( char* path ); 29 + // 絶対パスを与えると [複数階層makeDir] 30 + static void pathMakeAbs( char* path ); 31 + // yに最後の\, dに最後の. の位置を入れる 32 + static void pathSplit( const char* path, int* y, int* d ); 33 + // 拡張子 34 + static const char* pathExt( const char* path ); 35 + // ファイル名 36 + static const char* pathName( const char* path ); 37 + 38 +// window 39 + 40 + // 強制的に前面へ。( kazubon氏の TClock のソースより。感謝! ) 41 + static void wndFront( HWND wnd ); 42 + 43 +// その他 44 + 45 + // fgets改訂版(CR/LF/CRLFを改行と認定。改行コードは含めない文字列を返す) 46 + static char* getline( char* str, int size, FILE* fp ); 47 + // 拡張子変換 48 + static void getOriginalName( char* nw, const char* od, char* ext ); 49 + // 安全なところに移ってからLoadLibrary 50 + static HMODULE safepathLoadLibrary(LPCTSTR lpFileName) 51 + { 52 + kiPath original_cur(kiPath::Cur), sys(kiPath::Sys); 53 + ::SetCurrentDirectory(sys); 54 + HMODULE han = ::LoadLibrary(lpFileName); 55 + ::SetCurrentDirectory(original_cur); 56 + return han; 57 + } 58 + 59 +// 変数 60 + 61 +private: 62 + static char lb[256]; 63 +}; 64 + 65 +#endif
Added manifest.xml version [3c5cdefb4ff321c0]
1 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 3 + <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="KILIB.Noah" type="win32" /> 4 + <description>DnD Melter/Freezer</description> 5 + <dependency><dependentAssembly> 6 + <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" /> 7 + </dependentAssembly></dependency> 8 +</assembly>
Added resource.h version [4ef4eccb711b4b79]
1 +//{{NO_DEPENDENCIES}} 2 +// Microsoft Developer Studio generated include file. 3 +// Used by Caldix.rc 4 +// 5 +#define IDS_NOINTERNET 2 6 +#define IDS_LV_DLLNAME 3 7 +#define IDS_LV_STATE 5 8 +#define IDS_NONEED 6 9 +#define IDS_FINISHED 7 10 +#define IDS_NEWINST 9 11 +#define IDS_UPDINST 10 12 +#define IDS_DOWNLOADING 11 13 +#define IDS_REBOOT 12 14 +#define IDS_CANCELOK 13 15 +#define IDS_RASHANGUP 14 16 +#define IDS_REST 15 17 +#define IDS_DLERROR 16 18 +#define IDD_START 106 19 +#define IDD_VERCHECK 108 20 +#define IDD_CUSTOM1 109 21 +#define IDD_CUSTOM2 110 22 +#define IDI_MAIN 111 23 +#define IDD_INSTALL 112 24 +#define IDD_PROXY 113 25 +#define IDD_DETAIL 114 26 +#define IDC_WORKTYPE1 1011 27 +#define IDC_WORKTYPE2 1012 28 +#define IDC_BAR 1012 29 +#define IDC_DLLDIR 1013 30 +#define IDC_CONNECTTO1 1014 31 +#define IDC_CONNECTTO2 1015 32 +#define IDC_CONNECTTO3 1016 33 +#define IDC_REF 1017 34 +#define IDC_UPDATELIST 1018 35 +#define IDC_MSG 1024 36 +#define IDC_RESTTIME 1025 37 +#define IDC_INSTMODE1 1026 38 +#define IDC_INSTMODE2 1027 39 +#define IDC_INSTMODE3 1028 40 +#define IDC_USEPROXY 1029 41 +#define IDC_HOST 1030 42 +#define IDC_PORT 1031 43 +#define IDC_HOST_N 1032 44 +#define IDC_PORT_N 1033 45 +#define IDC_ASKHANG 1034 46 +#define IDC_DETAIL 1035 47 +#define IDC_PROXY 1036 48 +#define IDC_CONNECT_ALWAYS 1037 49 +#define IDC_SAVE_DESTDIR 1038 50 +#define IDC_DLHA 1039 51 +#define IDC_DUZP 1040 52 +#define IDC_DZIP 1041 53 +#define IDC_DCAB 1042 54 +#define IDC_DTAR 1043 55 +#define IDC_DRAR 1044 56 +#define IDC_DGCA 1045 57 +#define IDC_DARJ 1046 58 +#define IDC_DYZ1 1047 59 +#define IDC_DBGA 1048 60 +#define IDC_DJCK 1049 61 +#define IDC_DAIS 1050 62 +#define IDC_DISH 1051 63 +#define IDC_DBEL 1052 64 +#define IDC_D7ZP 1053 65 +#define IDC_DIMP 1054 66 +#define IDC_DBH 1055 67 +#define IDC_FILERPATH 1056 68 +#define IDC_FILEROPT 1057 69 +#define IDC_FILEROPT2 1058 70 +#define IDC_SHOW_README 1059 71 + 72 +// Next default values for new objects 73 +// 74 +#ifdef APSTUDIO_INVOKED 75 +#ifndef APSTUDIO_READONLY_SYMBOLS 76 +#define _APS_NEXT_RESOURCE_VALUE 114 77 +#define _APS_NEXT_COMMAND_VALUE 40001 78 +#define _APS_NEXT_CONTROL_VALUE 1060 79 +#define _APS_NEXT_SYMED_VALUE 101 80 +#endif 81 +#endif
Added zlib/README version [32f349b9aa6b4cdd]
1 +zlib 1.1.3 is a general purpose data compression library. All the code 2 +is thread safe. The data format used by the zlib library 3 +is described by RFCs (Request for Comments) 1950 to 1952 in the files 4 +ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate 5 +format) and rfc1952.txt (gzip format). These documents are also available in 6 +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html 7 + 8 +All functions of the compression library are documented in the file zlib.h 9 +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage 10 +example of the library is given in the file example.c which also tests that 11 +the library is working correctly. Another example is given in the file 12 +minigzip.c. The compression library itself is composed of all source files 13 +except example.c and minigzip.c. 14 + 15 +To compile all files and run the test program, follow the instructions 16 +given at the top of Makefile. In short "make test; make install" 17 +should work for most machines. For Unix: "configure; make test; make install" 18 +For MSDOS, use one of the special makefiles such as Makefile.msc. 19 +For VMS, use Make_vms.com or descrip.mms. 20 + 21 +Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to 22 +Gilles Vollant <info@winimage.com> for the Windows DLL version. 23 +The zlib home page is http://www.cdrom.com/pub/infozip/zlib/ 24 +The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/ 25 +Before reporting a problem, please check those sites to verify that 26 +you have the latest version of zlib; otherwise get the latest version and 27 +check whether the problem still exists or not. 28 + 29 +Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997 30 +issue of Dr. Dobb's Journal; a copy of the article is available in 31 +http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm 32 + 33 +The changes made in version 1.1.3 are documented in the file ChangeLog. 34 +The main changes since 1.1.2 are: 35 + 36 +- fix "an inflate input buffer bug that shows up on rare but persistent 37 + occasions" (Mark) 38 +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) 39 +- fix gzseek(..., SEEK_SET) in write mode 40 +- fix crc check after a gzeek (Frank Faubert) 41 +- fix miniunzip when the last entry in a zip file is itself a zip file 42 + (J Lillge) 43 +- add contrib/asm586 and contrib/asm686 (Brian Raiter) 44 + See http://www.muppetlabs.com/~breadbox/software/assembly.html 45 +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) 46 +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) 47 +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) 48 +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) 49 +- added a FAQ file 50 + 51 +plus many changes for portability. 52 + 53 +Unsupported third party contributions are provided in directory "contrib". 54 + 55 +A Java implementation of zlib is available in the Java Development Kit 1.1 56 +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html 57 +See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details. 58 + 59 +A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> 60 +is in the CPAN (Comprehensive Perl Archive Network) sites, such as: 61 +ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* 62 + 63 +A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> 64 +is available in Python 1.5 and later versions, see 65 +http://www.python.org/doc/lib/module-zlib.html 66 + 67 +A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> 68 +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html 69 + 70 +An experimental package to read and write files in .zip format, 71 +written on top of zlib by Gilles Vollant <info@winimage.com>, is 72 +available at http://www.winimage.com/zLibDll/unzip.html 73 +and also in the contrib/minizip directory of zlib. 74 + 75 + 76 +Notes for some targets: 77 + 78 +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc 79 + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL 80 + The zlib DLL support was initially done by Alessandro Iacopetti and is 81 + now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL 82 + home page at http://www.winimage.com/zLibDll 83 + 84 + From Visual Basic, you can call the DLL functions which do not take 85 + a structure as argument: compress, uncompress and all gz* functions. 86 + See contrib/visual-basic.txt for more information, or get 87 + http://www.tcfb.com/dowseware/cmp-z-it.zip 88 + 89 +- For 64-bit Irix, deflate.c must be compiled without any optimization. 90 + With -O, one libpng test fails. The test works in 32 bit mode (with 91 + the -n32 compiler flag). The compiler bug has been reported to SGI. 92 + 93 +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 94 + it works when compiled with cc. 95 + 96 +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 97 + is necessary to get gzprintf working correctly. This is done by configure. 98 + 99 +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works 100 + with other compilers. Use "make test" to check your compiler. 101 + 102 +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. 103 + 104 +- For Turbo C the small model is supported only with reduced performance to 105 + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 106 + 107 +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html 108 + Per Harald Myrvang <perm@stud.cs.uit.no> 109 + 110 + 111 +Acknowledgments: 112 + 113 + The deflate format used by zlib was defined by Phil Katz. The deflate 114 + and zlib specifications were written by L. Peter Deutsch. Thanks to all the 115 + people who reported problems and suggested various improvements in zlib; 116 + they are too numerous to cite here. 117 + 118 +Copyright notice: 119 + 120 + (C) 1995-1998 Jean-loup Gailly and Mark Adler 121 + 122 + This software is provided 'as-is', without any express or implied 123 + warranty. In no event will the authors be held liable for any damages 124 + arising from the use of this software. 125 + 126 + Permission is granted to anyone to use this software for any purpose, 127 + including commercial applications, and to alter it and redistribute it 128 + freely, subject to the following restrictions: 129 + 130 + 1. The origin of this software must not be misrepresented; you must not 131 + claim that you wrote the original software. If you use this software 132 + in a product, an acknowledgment in the product documentation would be 133 + appreciated but is not required. 134 + 2. Altered source versions must be plainly marked as such, and must not be 135 + misrepresented as being the original software. 136 + 3. This notice may not be removed or altered from any source distribution. 137 + 138 + Jean-loup Gailly Mark Adler 139 + jloup@gzip.org madler@alumni.caltech.edu 140 + 141 +If you use the zlib library in a product, we would appreciate *not* 142 +receiving lengthy legal documents to sign. The sources are provided 143 +for free but without warranty of any kind. The library has been 144 +entirely written by Jean-loup Gailly and Mark Adler; it does not 145 +include third-party code. 146 + 147 +If you redistribute modified sources, we would appreciate that you include 148 +in the file ChangeLog history information documenting your changes.
Added zlib/adler32.c version [d2f93402a7ab9a34]
1 +/* adler32.c -- compute the Adler-32 checksum of a data stream 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* @(#) $Id$ */ 7 + 8 +#include "zlib.h" 9 + 10 +#define BASE 65521L /* largest prime smaller than 65536 */ 11 +#define NMAX 5552 12 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 13 + 14 +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} 15 +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 16 +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 17 +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 18 +#define DO16(buf) DO8(buf,0); DO8(buf,8); 19 + 20 +/* ========================================================================= */ 21 +uLong ZEXPORT adler32(adler, buf, len) 22 + uLong adler; 23 + const Bytef *buf; 24 + uInt len; 25 +{ 26 + unsigned long s1 = adler & 0xffff; 27 + unsigned long s2 = (adler >> 16) & 0xffff; 28 + int k; 29 + 30 + if (buf == Z_NULL) return 1L; 31 + 32 + while (len > 0) { 33 + k = len < NMAX ? len : NMAX; 34 + len -= k; 35 + while (k >= 16) { 36 + DO16(buf); 37 + buf += 16; 38 + k -= 16; 39 + } 40 + if (k != 0) do { 41 + s1 += *buf++; 42 + s2 += s1; 43 + } while (--k); 44 + s1 %= BASE; 45 + s2 %= BASE; 46 + } 47 + return (s2 << 16) | s1; 48 +}
Added zlib/compress.c version [8196f041ac1881b1]
1 +/* compress.c -- compress a memory buffer 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* @(#) $Id$ */ 7 + 8 +#include "zlib.h" 9 +#ifndef KI_GZ_NO_COMPRESSION 10 + 11 +/* =========================================================================== 12 + Compresses the source buffer into the destination buffer. The level 13 + parameter has the same meaning as in deflateInit. sourceLen is the byte 14 + length of the source buffer. Upon entry, destLen is the total size of the 15 + destination buffer, which must be at least 0.1% larger than sourceLen plus 16 + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 17 + 18 + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 19 + memory, Z_BUF_ERROR if there was not enough room in the output buffer, 20 + Z_STREAM_ERROR if the level parameter is invalid. 21 +*/ 22 +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) 23 + Bytef *dest; 24 + uLongf *destLen; 25 + const Bytef *source; 26 + uLong sourceLen; 27 + int level; 28 +{ 29 + z_stream stream; 30 + int err; 31 + 32 + stream.next_in = (Bytef*)source; 33 + stream.avail_in = (uInt)sourceLen; 34 +#ifdef MAXSEG_64K 35 + /* Check for source > 64K on 16-bit machine: */ 36 + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 37 +#endif 38 + stream.next_out = dest; 39 + stream.avail_out = (uInt)*destLen; 40 + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 41 + 42 + stream.zalloc = (alloc_func)0; 43 + stream.zfree = (free_func)0; 44 + stream.opaque = (voidpf)0; 45 + 46 + err = deflateInit(&stream, level); 47 + if (err != Z_OK) return err; 48 + 49 + err = deflate(&stream, Z_FINISH); 50 + if (err != Z_STREAM_END) { 51 + deflateEnd(&stream); 52 + return err == Z_OK ? Z_BUF_ERROR : err; 53 + } 54 + *destLen = stream.total_out; 55 + 56 + err = deflateEnd(&stream); 57 + return err; 58 +} 59 + 60 +/* =========================================================================== 61 + */ 62 +int ZEXPORT compress (dest, destLen, source, sourceLen) 63 + Bytef *dest; 64 + uLongf *destLen; 65 + const Bytef *source; 66 + uLong sourceLen; 67 +{ 68 + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); 69 +} 70 + 71 +#endif /* KI_GZ_NO_COMPRESSION */
Added zlib/crc32.c version [51cae87bbab84055]
1 +/* crc32.c -- compute the CRC-32 of a data stream 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* @(#) $Id$ */ 7 + 8 +#include "zlib.h" 9 + 10 +#define local static 11 + 12 +#ifdef DYNAMIC_CRC_TABLE 13 + 14 +local int crc_table_empty = 1; 15 +local uLongf crc_table[256]; 16 +local void make_crc_table OF((void)); 17 + 18 +/* 19 + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: 20 + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. 21 + 22 + Polynomials over GF(2) are represented in binary, one bit per coefficient, 23 + with the lowest powers in the most significant bit. Then adding polynomials 24 + is just exclusive-or, and multiplying a polynomial by x is a right shift by 25 + one. If we call the above polynomial p, and represent a byte as the 26 + polynomial q, also with the lowest power in the most significant bit (so the 27 + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, 28 + where a mod b means the remainder after dividing a by b. 29 + 30 + This calculation is done using the shift-register method of multiplying and 31 + taking the remainder. The register is initialized to zero, and for each 32 + incoming bit, x^32 is added mod p to the register if the bit is a one (where 33 + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by 34 + x (which is shifting right by one and adding x^32 mod p if the bit shifted 35 + out is a one). We start with the highest power (least significant bit) of 36 + q and repeat for all eight bits of q. 37 + 38 + The table is simply the CRC of all possible eight bit values. This is all 39 + the information needed to generate CRC's on data a byte at a time for all 40 + combinations of CRC register values and incoming bytes. 41 +*/ 42 +local void make_crc_table() 43 +{ 44 + uLong c; 45 + int n, k; 46 + uLong poly; /* polynomial exclusive-or pattern */ 47 + /* terms of polynomial defining this crc (except x^32): */ 48 + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 49 + 50 + /* make exclusive-or pattern from polynomial (0xedb88320L) */ 51 + poly = 0L; 52 + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) 53 + poly |= 1L << (31 - p[n]); 54 + 55 + for (n = 0; n < 256; n++) 56 + { 57 + c = (uLong)n; 58 + for (k = 0; k < 8; k++) 59 + c = c & 1 ? poly ^ (c >> 1) : c >> 1; 60 + crc_table[n] = c; 61 + } 62 + crc_table_empty = 0; 63 +} 64 +#else 65 +/* ======================================================================== 66 + * Table of CRC-32's of all single-byte values (made by make_crc_table) 67 + */ 68 +local const uLongf crc_table[256] = { 69 + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 70 + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 71 + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 72 + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 73 + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 74 + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 75 + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 76 + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 77 + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 78 + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 79 + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 80 + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 81 + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 82 + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 83 + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 84 + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 85 + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 86 + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 87 + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 88 + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 89 + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 90 + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 91 + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 92 + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 93 + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 94 + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 95 + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 96 + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 97 + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 98 + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 99 + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 100 + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 101 + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 102 + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 103 + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 104 + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 105 + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 106 + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 107 + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 108 + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 109 + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 110 + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 111 + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 112 + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 113 + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 114 + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 115 + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 116 + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 117 + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 118 + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 119 + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 120 + 0x2d02ef8dL 121 +}; 122 +#endif 123 + 124 +/* ========================================================================= 125 + * This function can be used by asm versions of crc32() 126 + */ 127 +const uLongf * ZEXPORT get_crc_table() 128 +{ 129 +#ifdef DYNAMIC_CRC_TABLE 130 + if (crc_table_empty) make_crc_table(); 131 +#endif 132 + return (const uLongf *)crc_table; 133 +} 134 + 135 +/* ========================================================================= */ 136 +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); 137 +#define DO2(buf) DO1(buf); DO1(buf); 138 +#define DO4(buf) DO2(buf); DO2(buf); 139 +#define DO8(buf) DO4(buf); DO4(buf); 140 + 141 +/* ========================================================================= */ 142 +uLong ZEXPORT crc32(crc, buf, len) 143 + uLong crc; 144 + const Bytef *buf; 145 + uInt len; 146 +{ 147 + if (buf == Z_NULL) return 0L; 148 +#ifdef DYNAMIC_CRC_TABLE 149 + if (crc_table_empty) 150 + make_crc_table(); 151 +#endif 152 + crc = crc ^ 0xffffffffL; 153 + while (len >= 8) 154 + { 155 + DO8(buf); 156 + len -= 8; 157 + } 158 + if (len) do { 159 + DO1(buf); 160 + } while (--len); 161 + return crc ^ 0xffffffffL; 162 +}
Added zlib/deflate.c version [6f2623ffd4a0f5e8]
1 +/* deflate.c -- compress data using the deflation algorithm 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* 7 + * ALGORITHM 8 + * 9 + * The "deflation" process depends on being able to identify portions 10 + * of the input text which are identical to earlier input (within a 11 + * sliding window trailing behind the input currently being processed). 12 + * 13 + * The most straightforward technique turns out to be the fastest for 14 + * most input files: try all possible matches and select the longest. 15 + * The key feature of this algorithm is that insertions into the string 16 + * dictionary are very simple and thus fast, and deletions are avoided 17 + * completely. Insertions are performed at each input character, whereas 18 + * string matches are performed only when the previous match ends. So it 19 + * is preferable to spend more time in matches to allow very fast string 20 + * insertions and avoid deletions. The matching algorithm for small 21 + * strings is inspired from that of Rabin & Karp. A brute force approach 22 + * is used to find longer strings when a small match has been found. 23 + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze 24 + * (by Leonid Broukhis). 25 + * A previous version of this file used a more sophisticated algorithm 26 + * (by Fiala and Greene) which is guaranteed to run in linear amortized 27 + * time, but has a larger average cost, uses more memory and is patented. 28 + * However the F&G algorithm may be faster for some highly redundant 29 + * files if the parameter max_chain_length (described below) is too large. 30 + * 31 + * ACKNOWLEDGEMENTS 32 + * 33 + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and 34 + * I found it in 'freeze' written by Leonid Broukhis. 35 + * Thanks to many people for bug reports and testing. 36 + * 37 + * REFERENCES 38 + * 39 + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". 40 + * Available in ftp://ds.internic.net/rfc/rfc1951.txt 41 + * 42 + * A description of the Rabin and Karp algorithm is given in the book 43 + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. 44 + * 45 + * Fiala,E.R., and Greene,D.H. 46 + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 47 + * 48 + */ 49 + 50 +/* @(#) $Id$ */ 51 + 52 +#include "deflate.h" 53 +#ifndef KI_GZ_NO_COMPRESSION 54 + 55 +const char deflate_copyright[] = 56 + " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly "; 57 +/* 58 + If you use the zlib library in a product, an acknowledgment is welcome 59 + in the documentation of your product. If for some reason you cannot 60 + include such an acknowledgment, I would appreciate that you keep this 61 + copyright string in the executable of your product. 62 + */ 63 + 64 +/* =========================================================================== 65 + * Function prototypes. 66 + */ 67 +typedef enum { 68 + need_more, /* block not completed, need more input or more output */ 69 + block_done, /* block flush performed */ 70 + finish_started, /* finish started, need only more output at next deflate */ 71 + finish_done /* finish done, accept no more input or output */ 72 +} block_state; 73 + 74 +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); 75 +/* Compression function. Returns the block state after the call. */ 76 + 77 +local void fill_window OF((deflate_state *s)); 78 +local block_state deflate_stored OF((deflate_state *s, int flush)); 79 +local block_state deflate_fast OF((deflate_state *s, int flush)); 80 +local block_state deflate_slow OF((deflate_state *s, int flush)); 81 +local void lm_init OF((deflate_state *s)); 82 +local void putShortMSB OF((deflate_state *s, uInt b)); 83 +local void flush_pending OF((z_streamp strm)); 84 +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); 85 +#ifdef ASMV 86 + void match_init OF((void)); /* asm code initialization */ 87 + uInt longest_match OF((deflate_state *s, IPos cur_match)); 88 +#else 89 +local uInt longest_match OF((deflate_state *s, IPos cur_match)); 90 +#endif 91 + 92 +#ifdef DEBUG 93 +local void check_match OF((deflate_state *s, IPos start, IPos match, 94 + int length)); 95 +#endif 96 + 97 +/* =========================================================================== 98 + * Local data 99 + */ 100 + 101 +#define NIL 0 102 +/* Tail of hash chains */ 103 + 104 +#ifndef TOO_FAR 105 +# define TOO_FAR 4096 106 +#endif 107 +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ 108 + 109 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) 110 +/* Minimum amount of lookahead, except at the end of the input file. 111 + * See deflate.c for comments about the MIN_MATCH+1. 112 + */ 113 + 114 +/* Values for max_lazy_match, good_match and max_chain_length, depending on 115 + * the desired pack level (0..9). The values given below have been tuned to 116 + * exclude worst case performance for pathological files. Better values may be 117 + * found for specific files. 118 + */ 119 +typedef struct config_s { 120 + ush good_length; /* reduce lazy search above this match length */ 121 + ush max_lazy; /* do not perform lazy search above this match length */ 122 + ush nice_length; /* quit search above this match length */ 123 + ush max_chain; 124 + compress_func func; 125 +} config; 126 + 127 +local const config configuration_table[10] = { 128 +/* good lazy nice chain */ 129 +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ 130 +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ 131 +/* 2 */ {4, 5, 16, 8, deflate_fast}, 132 +/* 3 */ {4, 6, 32, 32, deflate_fast}, 133 + 134 +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ 135 +/* 5 */ {8, 16, 32, 32, deflate_slow}, 136 +/* 6 */ {8, 16, 128, 128, deflate_slow}, 137 +/* 7 */ {8, 32, 128, 256, deflate_slow}, 138 +/* 8 */ {32, 128, 258, 1024, deflate_slow}, 139 +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ 140 + 141 +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 142 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different 143 + * meaning. 144 + */ 145 + 146 +#define EQUAL 0 147 +/* result of memcmp for equal strings */ 148 + 149 +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ 150 + 151 +/* =========================================================================== 152 + * Update a hash value with the given input byte 153 + * IN assertion: all calls to to UPDATE_HASH are made with consecutive 154 + * input characters, so that a running hash key can be computed from the 155 + * previous key instead of complete recalculation each time. 156 + */ 157 +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) 158 + 159 + 160 +/* =========================================================================== 161 + * Insert string str in the dictionary and set match_head to the previous head 162 + * of the hash chain (the most recent string with same hash key). Return 163 + * the previous length of the hash chain. 164 + * If this file is compiled with -DFASTEST, the compression level is forced 165 + * to 1, and no hash chains are maintained. 166 + * IN assertion: all calls to to INSERT_STRING are made with consecutive 167 + * input characters and the first MIN_MATCH bytes of str are valid 168 + * (except for the last MIN_MATCH-1 bytes of the input file). 169 + */ 170 +#ifdef FASTEST 171 +#define INSERT_STRING(s, str, match_head) \ 172 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ 173 + match_head = s->head[s->ins_h], \ 174 + s->head[s->ins_h] = (Pos)(str)) 175 +#else 176 +#define INSERT_STRING(s, str, match_head) \ 177 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ 178 + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ 179 + s->head[s->ins_h] = (Pos)(str)) 180 +#endif 181 + 182 +/* =========================================================================== 183 + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). 184 + * prev[] will be initialized on the fly. 185 + */ 186 +#define CLEAR_HASH(s) \ 187 + s->head[s->hash_size-1] = NIL; \ 188 + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); 189 + 190 +/* ========================================================================= */ 191 +int ZEXPORT deflateInit_(strm, level, version, stream_size) 192 + z_streamp strm; 193 + int level; 194 + const char *version; 195 + int stream_size; 196 +{ 197 + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 198 + Z_DEFAULT_STRATEGY, version, stream_size); 199 + /* To do: ignore strm->next_in if we use it as window */ 200 +} 201 + 202 +/* ========================================================================= */ 203 +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, 204 + version, stream_size) 205 + z_streamp strm; 206 + int level; 207 + int method; 208 + int windowBits; 209 + int memLevel; 210 + int strategy; 211 + const char *version; 212 + int stream_size; 213 +{ 214 + deflate_state *s; 215 + int noheader = 0; 216 + static const char* my_version = ZLIB_VERSION; 217 + 218 + ushf *overlay; 219 + /* We overlay pending_buf and d_buf+l_buf. This works since the average 220 + * output size for (length,distance) codes is <= 24 bits. 221 + */ 222 + 223 + if (version == Z_NULL || version[0] != my_version[0] || 224 + stream_size != sizeof(z_stream)) { 225 + return Z_VERSION_ERROR; 226 + } 227 + if (strm == Z_NULL) return Z_STREAM_ERROR; 228 + 229 + strm->msg = Z_NULL; 230 + if (strm->zalloc == Z_NULL) { 231 + strm->zalloc = zcalloc; 232 + strm->opaque = (voidpf)0; 233 + } 234 + if (strm->zfree == Z_NULL) strm->zfree = zcfree; 235 + 236 + if (level == Z_DEFAULT_COMPRESSION) level = 6; 237 +#ifdef FASTEST 238 + level = 1; 239 +#endif 240 + 241 + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ 242 + noheader = 1; 243 + windowBits = -windowBits; 244 + } 245 + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || 246 + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || 247 + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { 248 + return Z_STREAM_ERROR; 249 + } 250 + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); 251 + if (s == Z_NULL) return Z_MEM_ERROR; 252 + strm->state = (struct internal_state FAR *)s; 253 + s->strm = strm; 254 + 255 + s->noheader = noheader; 256 + s->w_bits = windowBits; 257 + s->w_size = 1 << s->w_bits; 258 + s->w_mask = s->w_size - 1; 259 + 260 + s->hash_bits = memLevel + 7; 261 + s->hash_size = 1 << s->hash_bits; 262 + s->hash_mask = s->hash_size - 1; 263 + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); 264 + 265 + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); 266 + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); 267 + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); 268 + 269 + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ 270 + 271 + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); 272 + s->pending_buf = (uchf *) overlay; 273 + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); 274 + 275 + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || 276 + s->pending_buf == Z_NULL) { 277 + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); 278 + deflateEnd (strm); 279 + return Z_MEM_ERROR; 280 + } 281 + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); 282 + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; 283 + 284 + s->level = level; 285 + s->strategy = strategy; 286 + s->method = (Byte)method; 287 + 288 + return deflateReset(strm); 289 +} 290 + 291 +/* ========================================================================= */ 292 +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) 293 + z_streamp strm; 294 + const Bytef *dictionary; 295 + uInt dictLength; 296 +{ 297 + deflate_state *s; 298 + uInt length = dictLength; 299 + uInt n; 300 + IPos hash_head = 0; 301 + 302 + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || 303 + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; 304 + 305 + s = strm->state; 306 + strm->adler = adler32(strm->adler, dictionary, dictLength); 307 + 308 + if (length < MIN_MATCH) return Z_OK; 309 + if (length > MAX_DIST(s)) { 310 + length = MAX_DIST(s); 311 +#ifndef USE_DICT_HEAD 312 + dictionary += dictLength - length; /* use the tail of the dictionary */ 313 +#endif 314 + } 315 + zmemcpy(s->window, dictionary, length); 316 + s->strstart = length; 317 + s->block_start = (long)length; 318 + 319 + /* Insert all strings in the hash table (except for the last two bytes). 320 + * s->lookahead stays null, so s->ins_h will be recomputed at the next 321 + * call of fill_window. 322 + */ 323 + s->ins_h = s->window[0]; 324 + UPDATE_HASH(s, s->ins_h, s->window[1]); 325 + for (n = 0; n <= length - MIN_MATCH; n++) { 326 + INSERT_STRING(s, n, hash_head); 327 + } 328 + if (hash_head) hash_head = 0; /* to make compiler happy */ 329 + return Z_OK; 330 +} 331 + 332 +/* ========================================================================= */ 333 +int ZEXPORT deflateReset (strm) 334 + z_streamp strm; 335 +{ 336 + deflate_state *s; 337 + 338 + if (strm == Z_NULL || strm->state == Z_NULL || 339 + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; 340 + 341 + strm->total_in = strm->total_out = 0; 342 + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ 343 + strm->data_type = Z_UNKNOWN; 344 + 345 + s = (deflate_state *)strm->state; 346 + s->pending = 0; 347 + s->pending_out = s->pending_buf; 348 + 349 + if (s->noheader < 0) { 350 + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ 351 + } 352 + s->status = s->noheader ? BUSY_STATE : INIT_STATE; 353 + strm->adler = 1; 354 + s->last_flush = Z_NO_FLUSH; 355 + 356 + _tr_init(s); 357 + lm_init(s); 358 + 359 + return Z_OK; 360 +} 361 + 362 +/* ========================================================================= */ 363 +int ZEXPORT deflateParams(strm, level, strategy) 364 + z_streamp strm; 365 + int level; 366 + int strategy; 367 +{ 368 + deflate_state *s; 369 + compress_func func; 370 + int err = Z_OK; 371 + 372 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 373 + s = strm->state; 374 + 375 + if (level == Z_DEFAULT_COMPRESSION) { 376 + level = 6; 377 + } 378 + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { 379 + return Z_STREAM_ERROR; 380 + } 381 + func = configuration_table[s->level].func; 382 + 383 + if (func != configuration_table[level].func && strm->total_in != 0) { 384 + /* Flush the last buffer: */ 385 + err = deflate(strm, Z_PARTIAL_FLUSH); 386 + } 387 + if (s->level != level) { 388 + s->level = level; 389 + s->max_lazy_match = configuration_table[level].max_lazy; 390 + s->good_match = configuration_table[level].good_length; 391 + s->nice_match = configuration_table[level].nice_length; 392 + s->max_chain_length = configuration_table[level].max_chain; 393 + } 394 + s->strategy = strategy; 395 + return err; 396 +} 397 + 398 +/* ========================================================================= 399 + * Put a short in the pending buffer. The 16-bit value is put in MSB order. 400 + * IN assertion: the stream state is correct and there is enough room in 401 + * pending_buf. 402 + */ 403 +local void putShortMSB (s, b) 404 + deflate_state *s; 405 + uInt b; 406 +{ 407 + put_byte(s, (Byte)(b >> 8)); 408 + put_byte(s, (Byte)(b & 0xff)); 409 +} 410 + 411 +/* ========================================================================= 412 + * Flush as much pending output as possible. All deflate() output goes 413 + * through this function so some applications may wish to modify it 414 + * to avoid allocating a large strm->next_out buffer and copying into it. 415 + * (See also read_buf()). 416 + */ 417 +local void flush_pending(strm) 418 + z_streamp strm; 419 +{ 420 + unsigned len = strm->state->pending; 421 + 422 + if (len > strm->avail_out) len = strm->avail_out; 423 + if (len == 0) return; 424 + 425 + zmemcpy(strm->next_out, strm->state->pending_out, len); 426 + strm->next_out += len; 427 + strm->state->pending_out += len; 428 + strm->total_out += len; 429 + strm->avail_out -= len; 430 + strm->state->pending -= len; 431 + if (strm->state->pending == 0) { 432 + strm->state->pending_out = strm->state->pending_buf; 433 + } 434 +} 435 + 436 +/* ========================================================================= */ 437 +int ZEXPORT deflate (strm, flush) 438 + z_streamp strm; 439 + int flush; 440 +{ 441 + int old_flush; /* value of flush param for previous deflate call */ 442 + deflate_state *s; 443 + 444 + if (strm == Z_NULL || strm->state == Z_NULL || 445 + flush > Z_FINISH || flush < 0) { 446 + return Z_STREAM_ERROR; 447 + } 448 + s = strm->state; 449 + 450 + if (strm->next_out == Z_NULL || 451 + (strm->next_in == Z_NULL && strm->avail_in != 0) || 452 + (s->status == FINISH_STATE && flush != Z_FINISH)) { 453 + ERR_RETURN(strm, Z_STREAM_ERROR); 454 + } 455 + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); 456 + 457 + s->strm = strm; /* just in case */ 458 + old_flush = s->last_flush; 459 + s->last_flush = flush; 460 + 461 + /* Write the zlib header */ 462 + if (s->status == INIT_STATE) { 463 + 464 + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; 465 + uInt level_flags = (s->level-1) >> 1; 466 + 467 + if (level_flags > 3) level_flags = 3; 468 + header |= (level_flags << 6); 469 + if (s->strstart != 0) header |= PRESET_DICT; 470 + header += 31 - (header % 31); 471 + 472 + s->status = BUSY_STATE; 473 + putShortMSB(s, header); 474 + 475 + /* Save the adler32 of the preset dictionary: */ 476 + if (s->strstart != 0) { 477 + putShortMSB(s, (uInt)(strm->adler >> 16)); 478 + putShortMSB(s, (uInt)(strm->adler & 0xffff)); 479 + } 480 + strm->adler = 1L; 481 + } 482 + 483 + /* Flush as much pending output as possible */ 484 + if (s->pending != 0) { 485 + flush_pending(strm); 486 + if (strm->avail_out == 0) { 487 + /* Since avail_out is 0, deflate will be called again with 488 + * more output space, but possibly with both pending and 489 + * avail_in equal to zero. There won't be anything to do, 490 + * but this is not an error situation so make sure we 491 + * return OK instead of BUF_ERROR at next call of deflate: 492 + */ 493 + s->last_flush = -1; 494 + return Z_OK; 495 + } 496 + 497 + /* Make sure there is something to do and avoid duplicate consecutive 498 + * flushes. For repeated and useless calls with Z_FINISH, we keep 499 + * returning Z_STREAM_END instead of Z_BUFF_ERROR. 500 + */ 501 + } else if (strm->avail_in == 0 && flush <= old_flush && 502 + flush != Z_FINISH) { 503 + ERR_RETURN(strm, Z_BUF_ERROR); 504 + } 505 + 506 + /* User must not provide more input after the first FINISH: */ 507 + if (s->status == FINISH_STATE && strm->avail_in != 0) { 508 + ERR_RETURN(strm, Z_BUF_ERROR); 509 + } 510 + 511 + /* Start a new block or continue the current one. 512 + */ 513 + if (strm->avail_in != 0 || s->lookahead != 0 || 514 + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { 515 + block_state bstate; 516 + 517 + bstate = (*(configuration_table[s->level].func))(s, flush); 518 + 519 + if (bstate == finish_started || bstate == finish_done) { 520 + s->status = FINISH_STATE; 521 + } 522 + if (bstate == need_more || bstate == finish_started) { 523 + if (strm->avail_out == 0) { 524 + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ 525 + } 526 + return Z_OK; 527 + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call 528 + * of deflate should use the same flush parameter to make sure 529 + * that the flush is complete. So we don't have to output an 530 + * empty block here, this will be done at next call. This also 531 + * ensures that for a very small output buffer, we emit at most 532 + * one empty block. 533 + */ 534 + } 535 + if (bstate == block_done) { 536 + if (flush == Z_PARTIAL_FLUSH) { 537 + _tr_align(s); 538 + } else { /* FULL_FLUSH or SYNC_FLUSH */ 539 + _tr_stored_block(s, (char*)0, 0L, 0); 540 + /* For a full flush, this empty block will be recognized 541 + * as a special marker by inflate_sync(). 542 + */ 543 + if (flush == Z_FULL_FLUSH) { 544 + CLEAR_HASH(s); /* forget history */ 545 + } 546 + } 547 + flush_pending(strm); 548 + if (strm->avail_out == 0) { 549 + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ 550 + return Z_OK; 551 + } 552 + } 553 + } 554 + Assert(strm->avail_out > 0, "bug2"); 555 + 556 + if (flush != Z_FINISH) return Z_OK; 557 + if (s->noheader) return Z_STREAM_END; 558 + 559 + /* Write the zlib trailer (adler32) */ 560 + putShortMSB(s, (uInt)(strm->adler >> 16)); 561 + putShortMSB(s, (uInt)(strm->adler & 0xffff)); 562 + flush_pending(strm); 563 + /* If avail_out is zero, the application will call deflate again 564 + * to flush the rest. 565 + */ 566 + s->noheader = -1; /* write the trailer only once! */ 567 + return s->pending != 0 ? Z_OK : Z_STREAM_END; 568 +} 569 + 570 +/* ========================================================================= */ 571 +int ZEXPORT deflateEnd (strm) 572 + z_streamp strm; 573 +{ 574 + int status; 575 + 576 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 577 + 578 + status = strm->state->status; 579 + if (status != INIT_STATE && status != BUSY_STATE && 580 + status != FINISH_STATE) { 581 + return Z_STREAM_ERROR; 582 + } 583 + 584 + /* Deallocate in reverse order of allocations: */ 585 + TRY_FREE(strm, strm->state->pending_buf); 586 + TRY_FREE(strm, strm->state->head); 587 + TRY_FREE(strm, strm->state->prev); 588 + TRY_FREE(strm, strm->state->window); 589 + 590 + ZFREE(strm, strm->state); 591 + strm->state = Z_NULL; 592 + 593 + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; 594 +} 595 + 596 +/* ========================================================================= 597 + * Copy the source state to the destination state. 598 + * To simplify the source, this is not supported for 16-bit MSDOS (which 599 + * doesn't have enough memory anyway to duplicate compression states). 600 + */ 601 +int ZEXPORT deflateCopy (dest, source) 602 + z_streamp dest; 603 + z_streamp source; 604 +{ 605 +#ifdef MAXSEG_64K 606 + return Z_STREAM_ERROR; 607 +#else 608 + deflate_state *ds; 609 + deflate_state *ss; 610 + ushf *overlay; 611 + 612 + 613 + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { 614 + return Z_STREAM_ERROR; 615 + } 616 + 617 + ss = source->state; 618 + 619 + *dest = *source; 620 + 621 + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); 622 + if (ds == Z_NULL) return Z_MEM_ERROR; 623 + dest->state = (struct internal_state FAR *) ds; 624 + *ds = *ss; 625 + ds->strm = dest; 626 + 627 + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); 628 + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); 629 + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); 630 + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); 631 + ds->pending_buf = (uchf *) overlay; 632 + 633 + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || 634 + ds->pending_buf == Z_NULL) { 635 + deflateEnd (dest); 636 + return Z_MEM_ERROR; 637 + } 638 + /* following zmemcpy do not work for 16-bit MSDOS */ 639 + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); 640 + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); 641 + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); 642 + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); 643 + 644 + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); 645 + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); 646 + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; 647 + 648 + ds->l_desc.dyn_tree = ds->dyn_ltree; 649 + ds->d_desc.dyn_tree = ds->dyn_dtree; 650 + ds->bl_desc.dyn_tree = ds->bl_tree; 651 + 652 + return Z_OK; 653 +#endif 654 +} 655 + 656 +/* =========================================================================== 657 + * Read a new buffer from the current input stream, update the adler32 658 + * and total number of bytes read. All deflate() input goes through 659 + * this function so some applications may wish to modify it to avoid 660 + * allocating a large strm->next_in buffer and copying from it. 661 + * (See also flush_pending()). 662 + */ 663 +local int read_buf(strm, buf, size) 664 + z_streamp strm; 665 + Bytef *buf; 666 + unsigned size; 667 +{ 668 + unsigned len = strm->avail_in; 669 + 670 + if (len > size) len = size; 671 + if (len == 0) return 0; 672 + 673 + strm->avail_in -= len; 674 + 675 + if (!strm->state->noheader) { 676 + strm->adler = adler32(strm->adler, strm->next_in, len); 677 + } 678 + zmemcpy(buf, strm->next_in, len); 679 + strm->next_in += len; 680 + strm->total_in += len; 681 + 682 + return (int)len; 683 +} 684 + 685 +/* =========================================================================== 686 + * Initialize the "longest match" routines for a new zlib stream 687 + */ 688 +local void lm_init (s) 689 + deflate_state *s; 690 +{ 691 + s->window_size = (ulg)2L*s->w_size; 692 + 693 + CLEAR_HASH(s); 694 + 695 + /* Set the default configuration parameters: 696 + */ 697 + s->max_lazy_match = configuration_table[s->level].max_lazy; 698 + s->good_match = configuration_table[s->level].good_length; 699 + s->nice_match = configuration_table[s->level].nice_length; 700 + s->max_chain_length = configuration_table[s->level].max_chain; 701 + 702 + s->strstart = 0; 703 + s->block_start = 0L; 704 + s->lookahead = 0; 705 + s->match_length = s->prev_length = MIN_MATCH-1; 706 + s->match_available = 0; 707 + s->ins_h = 0; 708 +#ifdef ASMV 709 + match_init(); /* initialize the asm code */ 710 +#endif 711 +} 712 + 713 +/* =========================================================================== 714 + * Set match_start to the longest match starting at the given string and 715 + * return its length. Matches shorter or equal to prev_length are discarded, 716 + * in which case the result is equal to prev_length and match_start is 717 + * garbage. 718 + * IN assertions: cur_match is the head of the hash chain for the current 719 + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 720 + * OUT assertion: the match length is not greater than s->lookahead. 721 + */ 722 +#ifndef ASMV 723 +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or 724 + * match.S. The code will be functionally equivalent. 725 + */ 726 +#ifndef FASTEST 727 +local uInt longest_match(s, cur_match) 728 + deflate_state *s; 729 + IPos cur_match; /* current match */ 730 +{ 731 + unsigned chain_length = s->max_chain_length;/* max hash chain length */ 732 + register Bytef *scan = s->window + s->strstart; /* current string */ 733 + register Bytef *match; /* matched string */ 734 + register int len; /* length of current match */ 735 + int best_len = s->prev_length; /* best match length so far */ 736 + int nice_match = s->nice_match; /* stop if match long enough */ 737 + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? 738 + s->strstart - (IPos)MAX_DIST(s) : NIL; 739 + /* Stop when cur_match becomes <= limit. To simplify the code, 740 + * we prevent matches with the string of window index 0. 741 + */ 742 + Posf *prev = s->prev; 743 + uInt wmask = s->w_mask; 744 + 745 +#ifdef UNALIGNED_OK 746 + /* Compare two bytes at a time. Note: this is not always beneficial. 747 + * Try with and without -DUNALIGNED_OK to check. 748 + */ 749 + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; 750 + register ush scan_start = *(ushf*)scan; 751 + register ush scan_end = *(ushf*)(scan+best_len-1); 752 +#else 753 + register Bytef *strend = s->window + s->strstart + MAX_MATCH; 754 + register Byte scan_end1 = scan[best_len-1]; 755 + register Byte scan_end = scan[best_len]; 756 +#endif 757 + 758 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. 759 + * It is easy to get rid of this optimization if necessary. 760 + */ 761 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); 762 + 763 + /* Do not waste too much time if we already have a good match: */ 764 + if (s->prev_length >= s->good_match) { 765 + chain_length >>= 2; 766 + } 767 + /* Do not look for matches beyond the end of the input. This is necessary 768 + * to make deflate deterministic. 769 + */ 770 + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; 771 + 772 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); 773 + 774 + do { 775 + Assert(cur_match < s->strstart, "no future"); 776 + match = s->window + cur_match; 777 + 778 + /* Skip to next match if the match length cannot increase 779 + * or if the match length is less than 2: 780 + */ 781 +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) 782 + /* This code assumes sizeof(unsigned short) == 2. Do not use 783 + * UNALIGNED_OK if your compiler uses a different size. 784 + */ 785 + if (*(ushf*)(match+best_len-1) != scan_end || 786 + *(ushf*)match != scan_start) continue; 787 + 788 + /* It is not necessary to compare scan[2] and match[2] since they are 789 + * always equal when the other bytes match, given that the hash keys 790 + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at 791 + * strstart+3, +5, ... up to strstart+257. We check for insufficient 792 + * lookahead only every 4th comparison; the 128th check will be made 793 + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is 794 + * necessary to put more guard bytes at the end of the window, or 795 + * to check more often for insufficient lookahead. 796 + */ 797 + Assert(scan[2] == match[2], "scan[2]?"); 798 + scan++, match++; 799 + do { 800 + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && 801 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && 802 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && 803 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && 804 + scan < strend); 805 + /* The funny "do {}" generates better code on most compilers */ 806 + 807 + /* Here, scan <= window+strstart+257 */ 808 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); 809 + if (*scan == *match) scan++; 810 + 811 + len = (MAX_MATCH - 1) - (int)(strend-scan); 812 + scan = strend - (MAX_MATCH-1); 813 + 814 +#else /* UNALIGNED_OK */ 815 + 816 + if (match[best_len] != scan_end || 817 + match[best_len-1] != scan_end1 || 818 + *match != *scan || 819 + *++match != scan[1]) continue; 820 + 821 + /* The check at best_len-1 can be removed because it will be made 822 + * again later. (This heuristic is not always a win.) 823 + * It is not necessary to compare scan[2] and match[2] since they 824 + * are always equal when the other bytes match, given that 825 + * the hash keys are equal and that HASH_BITS >= 8. 826 + */ 827 + scan += 2, match++; 828 + Assert(*scan == *match, "match[2]?"); 829 + 830 + /* We check for insufficient lookahead only every 8th comparison; 831 + * the 256th check will be made at strstart+258. 832 + */ 833 + do { 834 + } while (*++scan == *++match && *++scan == *++match && 835 + *++scan == *++match && *++scan == *++match && 836 + *++scan == *++match && *++scan == *++match && 837 + *++scan == *++match && *++scan == *++match && 838 + scan < strend); 839 + 840 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); 841 + 842 + len = MAX_MATCH - (int)(strend - scan); 843 + scan = strend - MAX_MATCH; 844 + 845 +#endif /* UNALIGNED_OK */ 846 + 847 + if (len > best_len) { 848 + s->match_start = cur_match; 849 + best_len = len; 850 + if (len >= nice_match) break; 851 +#ifdef UNALIGNED_OK 852 + scan_end = *(ushf*)(scan+best_len-1); 853 +#else 854 + scan_end1 = scan[best_len-1]; 855 + scan_end = scan[best_len]; 856 +#endif 857 + } 858 + } while ((cur_match = prev[cur_match & wmask]) > limit 859 + && --chain_length != 0); 860 + 861 + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; 862 + return s->lookahead; 863 +} 864 + 865 +#else /* FASTEST */ 866 +/* --------------------------------------------------------------------------- 867 + * Optimized version for level == 1 only 868 + */ 869 +local uInt longest_match(s, cur_match) 870 + deflate_state *s; 871 + IPos cur_match; /* current match */ 872 +{ 873 + register Bytef *scan = s->window + s->strstart; /* current string */ 874 + register Bytef *match; /* matched string */ 875 + register int len; /* length of current match */ 876 + register Bytef *strend = s->window + s->strstart + MAX_MATCH; 877 + 878 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. 879 + * It is easy to get rid of this optimization if necessary. 880 + */ 881 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); 882 + 883 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); 884 + 885 + Assert(cur_match < s->strstart, "no future"); 886 + 887 + match = s->window + cur_match; 888 + 889 + /* Return failure if the match length is less than 2: 890 + */ 891 + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; 892 + 893 + /* The check at best_len-1 can be removed because it will be made 894 + * again later. (This heuristic is not always a win.) 895 + * It is not necessary to compare scan[2] and match[2] since they 896 + * are always equal when the other bytes match, given that 897 + * the hash keys are equal and that HASH_BITS >= 8. 898 + */ 899 + scan += 2, match += 2; 900 + Assert(*scan == *match, "match[2]?"); 901 + 902 + /* We check for insufficient lookahead only every 8th comparison; 903 + * the 256th check will be made at strstart+258. 904 + */ 905 + do { 906 + } while (*++scan == *++match && *++scan == *++match && 907 + *++scan == *++match && *++scan == *++match && 908 + *++scan == *++match && *++scan == *++match && 909 + *++scan == *++match && *++scan == *++match && 910 + scan < strend); 911 + 912 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); 913 + 914 + len = MAX_MATCH - (int)(strend - scan); 915 + 916 + if (len < MIN_MATCH) return MIN_MATCH - 1; 917 + 918 + s->match_start = cur_match; 919 + return len <= s->lookahead ? len : s->lookahead; 920 +} 921 +#endif /* FASTEST */ 922 +#endif /* ASMV */ 923 + 924 +#ifdef DEBUG 925 +/* =========================================================================== 926 + * Check that the match at match_start is indeed a match. 927 + */ 928 +local void check_match(s, start, match, length) 929 + deflate_state *s; 930 + IPos start, match; 931 + int length; 932 +{ 933 + /* check that the match is indeed a match */ 934 + if (zmemcmp(s->window + match, 935 + s->window + start, length) != EQUAL) { 936 + fprintf(stderr, " start %u, match %u, length %d\n", 937 + start, match, length); 938 + do { 939 + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); 940 + } while (--length != 0); 941 + z_error("invalid match"); 942 + } 943 + if (z_verbose > 1) { 944 + fprintf(stderr,"\\[%d,%d]", start-match, length); 945 + do { putc(s->window[start++], stderr); } while (--length != 0); 946 + } 947 +} 948 +#else 949 +# define check_match(s, start, match, length) 950 +#endif 951 + 952 +/* =========================================================================== 953 + * Fill the window when the lookahead becomes insufficient. 954 + * Updates strstart and lookahead. 955 + * 956 + * IN assertion: lookahead < MIN_LOOKAHEAD 957 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD 958 + * At least one byte has been read, or avail_in == 0; reads are 959 + * performed for at least two bytes (required for the zip translate_eol 960 + * option -- not supported here). 961 + */ 962 +local void fill_window(s) 963 + deflate_state *s; 964 +{ 965 + register unsigned n, m; 966 + register Posf *p; 967 + unsigned more; /* Amount of free space at the end of the window. */ 968 + uInt wsize = s->w_size; 969 + 970 + do { 971 + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); 972 + 973 + /* Deal with !@#$% 64K limit: */ 974 + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { 975 + more = wsize; 976 + 977 + } else if (more == (unsigned)(-1)) { 978 + /* Very unlikely, but possible on 16 bit machine if strstart == 0 979 + * and lookahead == 1 (input done one byte at time) 980 + */ 981 + more--; 982 + 983 + /* If the window is almost full and there is insufficient lookahead, 984 + * move the upper half to the lower one to make room in the upper half. 985 + */ 986 + } else if (s->strstart >= wsize+MAX_DIST(s)) { 987 + 988 + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); 989 + s->match_start -= wsize; 990 + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ 991 + s->block_start -= (long) wsize; 992 + 993 + /* Slide the hash table (could be avoided with 32 bit values 994 + at the expense of memory usage). We slide even when level == 0 995 + to keep the hash table consistent if we switch back to level > 0 996 + later. (Using level 0 permanently is not an optimal usage of 997 + zlib, so we don't care about this pathological case.) 998 + */ 999 + n = s->hash_size; 1000 + p = &s->head[n]; 1001 + do { 1002 + m = *--p; 1003 + *p = (Pos)(m >= wsize ? m-wsize : NIL); 1004 + } while (--n); 1005 + 1006 + n = wsize; 1007 +#ifndef FASTEST 1008 + p = &s->prev[n]; 1009 + do { 1010 + m = *--p; 1011 + *p = (Pos)(m >= wsize ? m-wsize : NIL); 1012 + /* If n is not on any hash chain, prev[n] is garbage but 1013 + * its value will never be used. 1014 + */ 1015 + } while (--n); 1016 +#endif 1017 + more += wsize; 1018 + } 1019 + if (s->strm->avail_in == 0) return; 1020 + 1021 + /* If there was no sliding: 1022 + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && 1023 + * more == window_size - lookahead - strstart 1024 + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) 1025 + * => more >= window_size - 2*WSIZE + 2 1026 + * In the BIG_MEM or MMAP case (not yet supported), 1027 + * window_size == input_size + MIN_LOOKAHEAD && 1028 + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. 1029 + * Otherwise, window_size == 2*WSIZE so more >= 2. 1030 + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. 1031 + */ 1032 + Assert(more >= 2, "more < 2"); 1033 + 1034 + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); 1035 + s->lookahead += n; 1036 + 1037 + /* Initialize the hash value now that we have some input: */ 1038 + if (s->lookahead >= MIN_MATCH) { 1039 + s->ins_h = s->window[s->strstart]; 1040 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); 1041 +#if MIN_MATCH != 3 1042 + Call UPDATE_HASH() MIN_MATCH-3 more times 1043 +#endif 1044 + } 1045 + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, 1046 + * but this is not important since only literal bytes will be emitted. 1047 + */ 1048 + 1049 + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); 1050 +} 1051 + 1052 +/* =========================================================================== 1053 + * Flush the current block, with given end-of-file flag. 1054 + * IN assertion: strstart is set to the end of the current match. 1055 + */ 1056 +#define FLUSH_BLOCK_ONLY(s, eof) { \ 1057 + _tr_flush_block(s, (s->block_start >= 0L ? \ 1058 + (charf *)&s->window[(unsigned)s->block_start] : \ 1059 + (charf *)Z_NULL), \ 1060 + (ulg)((long)s->strstart - s->block_start), \ 1061 + (eof)); \ 1062 + s->block_start = s->strstart; \ 1063 + flush_pending(s->strm); \ 1064 + Tracev((stderr,"[FLUSH]")); \ 1065 +} 1066 + 1067 +/* Same but force premature exit if necessary. */ 1068 +#define FLUSH_BLOCK(s, eof) { \ 1069 + FLUSH_BLOCK_ONLY(s, eof); \ 1070 + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ 1071 +} 1072 + 1073 +/* =========================================================================== 1074 + * Copy without compression as much as possible from the input stream, return 1075 + * the current block state. 1076 + * This function does not insert new strings in the dictionary since 1077 + * uncompressible data is probably not useful. This function is used 1078 + * only for the level=0 compression option. 1079 + * NOTE: this function should be optimized to avoid extra copying from 1080 + * window to pending_buf. 1081 + */ 1082 +local block_state deflate_stored(s, flush) 1083 + deflate_state *s; 1084 + int flush; 1085 +{ 1086 + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited 1087 + * to pending_buf_size, and each stored block has a 5 byte header: 1088 + */ 1089 + ulg max_block_size = 0xffff; 1090 + ulg max_start; 1091 + 1092 + if (max_block_size > s->pending_buf_size - 5) { 1093 + max_block_size = s->pending_buf_size - 5; 1094 + } 1095 + 1096 + /* Copy as much as possible from input to output: */ 1097 + for (;;) { 1098 + /* Fill the window as much as possible: */ 1099 + if (s->lookahead <= 1) { 1100 + 1101 + Assert(s->strstart < s->w_size+MAX_DIST(s) || 1102 + s->block_start >= (long)s->w_size, "slide too late"); 1103 + 1104 + fill_window(s); 1105 + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; 1106 + 1107 + if (s->lookahead == 0) break; /* flush the current block */ 1108 + } 1109 + Assert(s->block_start >= 0L, "block gone"); 1110 + 1111 + s->strstart += s->lookahead; 1112 + s->lookahead = 0; 1113 + 1114 + /* Emit a stored block if pending_buf will be full: */ 1115 + max_start = s->block_start + max_block_size; 1116 + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { 1117 + /* strstart == 0 is possible when wraparound on 16-bit machine */ 1118 + s->lookahead = (uInt)(s->strstart - max_start); 1119 + s->strstart = (uInt)max_start; 1120 + FLUSH_BLOCK(s, 0); 1121 + } 1122 + /* Flush if we may have to slide, otherwise block_start may become 1123 + * negative and the data will be gone: 1124 + */ 1125 + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { 1126 + FLUSH_BLOCK(s, 0); 1127 + } 1128 + } 1129 + FLUSH_BLOCK(s, flush == Z_FINISH); 1130 + return flush == Z_FINISH ? finish_done : block_done; 1131 +} 1132 + 1133 +/* =========================================================================== 1134 + * Compress as much as possible from the input stream, return the current 1135 + * block state. 1136 + * This function does not perform lazy evaluation of matches and inserts 1137 + * new strings in the dictionary only for unmatched strings or for short 1138 + * matches. It is used only for the fast compression options. 1139 + */ 1140 +local block_state deflate_fast(s, flush) 1141 + deflate_state *s; 1142 + int flush; 1143 +{ 1144 + IPos hash_head = NIL; /* head of the hash chain */ 1145 + int bflush; /* set if current block must be flushed */ 1146 + 1147 + for (;;) { 1148 + /* Make sure that we always have enough lookahead, except 1149 + * at the end of the input file. We need MAX_MATCH bytes 1150 + * for the next match, plus MIN_MATCH bytes to insert the 1151 + * string following the next match. 1152 + */ 1153 + if (s->lookahead < MIN_LOOKAHEAD) { 1154 + fill_window(s); 1155 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { 1156 + return need_more; 1157 + } 1158 + if (s->lookahead == 0) break; /* flush the current block */ 1159 + } 1160 + 1161 + /* Insert the string window[strstart .. strstart+2] in the 1162 + * dictionary, and set hash_head to the head of the hash chain: 1163 + */ 1164 + if (s->lookahead >= MIN_MATCH) { 1165 + INSERT_STRING(s, s->strstart, hash_head); 1166 + } 1167 + 1168 + /* Find the longest match, discarding those <= prev_length. 1169 + * At this point we have always match_length < MIN_MATCH 1170 + */ 1171 + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { 1172 + /* To simplify the code, we prevent matches with the string 1173 + * of window index 0 (in particular we have to avoid a match 1174 + * of the string with itself at the start of the input file). 1175 + */ 1176 + if (s->strategy != Z_HUFFMAN_ONLY) { 1177 + s->match_length = longest_match (s, hash_head); 1178 + } 1179 + /* longest_match() sets match_start */ 1180 + } 1181 + if (s->match_length >= MIN_MATCH) { 1182 + check_match(s, s->strstart, s->match_start, s->match_length); 1183 + 1184 + _tr_tally_dist(s, s->strstart - s->match_start, 1185 + s->match_length - MIN_MATCH, bflush); 1186 + 1187 + s->lookahead -= s->match_length; 1188 + 1189 + /* Insert new strings in the hash table only if the match length 1190 + * is not too large. This saves time but degrades compression. 1191 + */ 1192 +#ifndef FASTEST 1193 + if (s->match_length <= s->max_insert_length && 1194 + s->lookahead >= MIN_MATCH) { 1195 + s->match_length--; /* string at strstart already in hash table */ 1196 + do { 1197 + s->strstart++; 1198 + INSERT_STRING(s, s->strstart, hash_head); 1199 + /* strstart never exceeds WSIZE-MAX_MATCH, so there are 1200 + * always MIN_MATCH bytes ahead. 1201 + */ 1202 + } while (--s->match_length != 0); 1203 + s->strstart++; 1204 + } else 1205 +#endif 1206 + { 1207 + s->strstart += s->match_length; 1208 + s->match_length = 0; 1209 + s->ins_h = s->window[s->strstart]; 1210 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); 1211 +#if MIN_MATCH != 3 1212 + Call UPDATE_HASH() MIN_MATCH-3 more times 1213 +#endif 1214 + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not 1215 + * matter since it will be recomputed at next deflate call. 1216 + */ 1217 + } 1218 + } else { 1219 + /* No match, output a literal byte */ 1220 + Tracevv((stderr,"%c", s->window[s->strstart])); 1221 + _tr_tally_lit (s, s->window[s->strstart], bflush); 1222 + s->lookahead--; 1223 + s->strstart++; 1224 + } 1225 + if (bflush) FLUSH_BLOCK(s, 0); 1226 + } 1227 + FLUSH_BLOCK(s, flush == Z_FINISH); 1228 + return flush == Z_FINISH ? finish_done : block_done; 1229 +} 1230 + 1231 +/* =========================================================================== 1232 + * Same as above, but achieves better compression. We use a lazy 1233 + * evaluation for matches: a match is finally adopted only if there is 1234 + * no better match at the next window position. 1235 + */ 1236 +local block_state deflate_slow(s, flush) 1237 + deflate_state *s; 1238 + int flush; 1239 +{ 1240 + IPos hash_head = NIL; /* head of hash chain */ 1241 + int bflush; /* set if current block must be flushed */ 1242 + 1243 + /* Process the input block. */ 1244 + for (;;) { 1245 + /* Make sure that we always have enough lookahead, except 1246 + * at the end of the input file. We need MAX_MATCH bytes 1247 + * for the next match, plus MIN_MATCH bytes to insert the 1248 + * string following the next match. 1249 + */ 1250 + if (s->lookahead < MIN_LOOKAHEAD) { 1251 + fill_window(s); 1252 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { 1253 + return need_more; 1254 + } 1255 + if (s->lookahead == 0) break; /* flush the current block */ 1256 + } 1257 + 1258 + /* Insert the string window[strstart .. strstart+2] in the 1259 + * dictionary, and set hash_head to the head of the hash chain: 1260 + */ 1261 + if (s->lookahead >= MIN_MATCH) { 1262 + INSERT_STRING(s, s->strstart, hash_head); 1263 + } 1264 + 1265 + /* Find the longest match, discarding those <= prev_length. 1266 + */ 1267 + s->prev_length = s->match_length, s->prev_match = s->match_start; 1268 + s->match_length = MIN_MATCH-1; 1269 + 1270 + if (hash_head != NIL && s->prev_length < s->max_lazy_match && 1271 + s->strstart - hash_head <= MAX_DIST(s)) { 1272 + /* To simplify the code, we prevent matches with the string 1273 + * of window index 0 (in particular we have to avoid a match 1274 + * of the string with itself at the start of the input file). 1275 + */ 1276 + if (s->strategy != Z_HUFFMAN_ONLY) { 1277 + s->match_length = longest_match (s, hash_head); 1278 + } 1279 + /* longest_match() sets match_start */ 1280 + 1281 + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || 1282 + (s->match_length == MIN_MATCH && 1283 + s->strstart - s->match_start > TOO_FAR))) { 1284 + 1285 + /* If prev_match is also MIN_MATCH, match_start is garbage 1286 + * but we will ignore the current match anyway. 1287 + */ 1288 + s->match_length = MIN_MATCH-1; 1289 + } 1290 + } 1291 + /* If there was a match at the previous step and the current 1292 + * match is not better, output the previous match: 1293 + */ 1294 + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { 1295 + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; 1296 + /* Do not insert strings in hash table beyond this. */ 1297 + 1298 + check_match(s, s->strstart-1, s->prev_match, s->prev_length); 1299 + 1300 + _tr_tally_dist(s, s->strstart -1 - s->prev_match, 1301 + s->prev_length - MIN_MATCH, bflush); 1302 + 1303 + /* Insert in hash table all strings up to the end of the match. 1304 + * strstart-1 and strstart are already inserted. If there is not 1305 + * enough lookahead, the last two strings are not inserted in 1306 + * the hash table. 1307 + */ 1308 + s->lookahead -= s->prev_length-1; 1309 + s->prev_length -= 2; 1310 + do { 1311 + if (++s->strstart <= max_insert) { 1312 + INSERT_STRING(s, s->strstart, hash_head); 1313 + } 1314 + } while (--s->prev_length != 0); 1315 + s->match_available = 0; 1316 + s->match_length = MIN_MATCH-1; 1317 + s->strstart++; 1318 + 1319 + if (bflush) FLUSH_BLOCK(s, 0); 1320 + 1321 + } else if (s->match_available) { 1322 + /* If there was no match at the previous position, output a 1323 + * single literal. If there was a match but the current match 1324 + * is longer, truncate the previous match to a single literal. 1325 + */ 1326 + Tracevv((stderr,"%c", s->window[s->strstart-1])); 1327 + _tr_tally_lit(s, s->window[s->strstart-1], bflush); 1328 + if (bflush) { 1329 + FLUSH_BLOCK_ONLY(s, 0); 1330 + } 1331 + s->strstart++; 1332 + s->lookahead--; 1333 + if (s->strm->avail_out == 0) return need_more; 1334 + } else { 1335 + /* There is no previous match to compare with, wait for 1336 + * the next step to decide. 1337 + */ 1338 + s->match_available = 1; 1339 + s->strstart++; 1340 + s->lookahead--; 1341 + } 1342 + } 1343 + Assert (flush != Z_NO_FLUSH, "no flush?"); 1344 + if (s->match_available) { 1345 + Tracevv((stderr,"%c", s->window[s->strstart-1])); 1346 + _tr_tally_lit(s, s->window[s->strstart-1], bflush); 1347 + s->match_available = 0; 1348 + } 1349 + FLUSH_BLOCK(s, flush == Z_FINISH); 1350 + return flush == Z_FINISH ? finish_done : block_done; 1351 +} 1352 + 1353 +#endif /* KI_GZ_NO_COMPRESSION */
Added zlib/deflate.h version [07a5ae1cef0579c0]
1 +/* deflate.h -- internal compression state 2 + * Copyright (C) 1995-1998 Jean-loup Gailly 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +/* @(#) $Id$ */ 12 + 13 +#ifndef _DEFLATE_H 14 +#define _DEFLATE_H 15 +#ifndef KI_GZ_NO_COMPRESSION 16 + 17 +#include "zutil.h" 18 + 19 +/* =========================================================================== 20 + * Internal compression state. 21 + */ 22 + 23 +#define LENGTH_CODES 29 24 +/* number of length codes, not counting the special END_BLOCK code */ 25 + 26 +#define LITERALS 256 27 +/* number of literal bytes 0..255 */ 28 + 29 +#define L_CODES (LITERALS+1+LENGTH_CODES) 30 +/* number of Literal or Length codes, including the END_BLOCK code */ 31 + 32 +#define D_CODES 30 33 +/* number of distance codes */ 34 + 35 +#define BL_CODES 19 36 +/* number of codes used to transfer the bit lengths */ 37 + 38 +#define HEAP_SIZE (2*L_CODES+1) 39 +/* maximum heap size */ 40 + 41 +#define MAX_BITS 15 42 +/* All codes must not exceed MAX_BITS bits */ 43 + 44 +#define INIT_STATE 42 45 +#define BUSY_STATE 113 46 +#define FINISH_STATE 666 47 +/* Stream status */ 48 + 49 + 50 +/* Data structure describing a single value and its code string. */ 51 +typedef struct ct_data_s { 52 + union { 53 + ush freq; /* frequency count */ 54 + ush code; /* bit string */ 55 + } fc; 56 + union { 57 + ush dad; /* father node in Huffman tree */ 58 + ush len; /* length of bit string */ 59 + } dl; 60 +} FAR ct_data; 61 + 62 +#define Freq fc.freq 63 +#define Code fc.code 64 +#define Dad dl.dad 65 +#define Len dl.len 66 + 67 +typedef struct static_tree_desc_s static_tree_desc; 68 + 69 +typedef struct tree_desc_s { 70 + ct_data *dyn_tree; /* the dynamic tree */ 71 + int max_code; /* largest code with non zero frequency */ 72 + static_tree_desc *stat_desc; /* the corresponding static tree */ 73 +} FAR tree_desc; 74 + 75 +typedef ush Pos; 76 +typedef Pos FAR Posf; 77 +typedef unsigned IPos; 78 + 79 +/* A Pos is an index in the character window. We use short instead of int to 80 + * save space in the various tables. IPos is used only for parameter passing. 81 + */ 82 + 83 +typedef struct internal_state { 84 + z_streamp strm; /* pointer back to this zlib stream */ 85 + int status; /* as the name implies */ 86 + Bytef *pending_buf; /* output still pending */ 87 + ulg pending_buf_size; /* size of pending_buf */ 88 + Bytef *pending_out; /* next pending byte to output to the stream */ 89 + int pending; /* nb of bytes in the pending buffer */ 90 + int noheader; /* suppress zlib header and adler32 */ 91 + Byte data_type; /* UNKNOWN, BINARY or ASCII */ 92 + Byte method; /* STORED (for zip only) or DEFLATED */ 93 + int last_flush; /* value of flush param for previous deflate call */ 94 + 95 + /* used by deflate.c: */ 96 + 97 + uInt w_size; /* LZ77 window size (32K by default) */ 98 + uInt w_bits; /* log2(w_size) (8..16) */ 99 + uInt w_mask; /* w_size - 1 */ 100 + 101 + Bytef *window; 102 + /* Sliding window. Input bytes are read into the second half of the window, 103 + * and move to the first half later to keep a dictionary of at least wSize 104 + * bytes. With this organization, matches are limited to a distance of 105 + * wSize-MAX_MATCH bytes, but this ensures that IO is always 106 + * performed with a length multiple of the block size. Also, it limits 107 + * the window size to 64K, which is quite useful on MSDOS. 108 + * To do: use the user input buffer as sliding window. 109 + */ 110 + 111 + ulg window_size; 112 + /* Actual size of window: 2*wSize, except when the user input buffer 113 + * is directly used as sliding window. 114 + */ 115 + 116 + Posf *prev; 117 + /* Link to older string with same hash index. To limit the size of this 118 + * array to 64K, this link is maintained only for the last 32K strings. 119 + * An index in this array is thus a window index modulo 32K. 120 + */ 121 + 122 + Posf *head; /* Heads of the hash chains or NIL. */ 123 + 124 + uInt ins_h; /* hash index of string to be inserted */ 125 + uInt hash_size; /* number of elements in hash table */ 126 + uInt hash_bits; /* log2(hash_size) */ 127 + uInt hash_mask; /* hash_size-1 */ 128 + 129 + uInt hash_shift; 130 + /* Number of bits by which ins_h must be shifted at each input 131 + * step. It must be such that after MIN_MATCH steps, the oldest 132 + * byte no longer takes part in the hash key, that is: 133 + * hash_shift * MIN_MATCH >= hash_bits 134 + */ 135 + 136 + long block_start; 137 + /* Window position at the beginning of the current output block. Gets 138 + * negative when the window is moved backwards. 139 + */ 140 + 141 + uInt match_length; /* length of best match */ 142 + IPos prev_match; /* previous match */ 143 + int match_available; /* set if previous match exists */ 144 + uInt strstart; /* start of string to insert */ 145 + uInt match_start; /* start of matching string */ 146 + uInt lookahead; /* number of valid bytes ahead in window */ 147 + 148 + uInt prev_length; 149 + /* Length of the best match at previous step. Matches not greater than this 150 + * are discarded. This is used in the lazy match evaluation. 151 + */ 152 + 153 + uInt max_chain_length; 154 + /* To speed up deflation, hash chains are never searched beyond this 155 + * length. A higher limit improves compression ratio but degrades the 156 + * speed. 157 + */ 158 + 159 + uInt max_lazy_match; 160 + /* Attempt to find a better match only when the current match is strictly 161 + * smaller than this value. This mechanism is used only for compression 162 + * levels >= 4. 163 + */ 164 +# define max_insert_length max_lazy_match 165 + /* Insert new strings in the hash table only if the match length is not 166 + * greater than this length. This saves time but degrades compression. 167 + * max_insert_length is used only for compression levels <= 3. 168 + */ 169 + 170 + int level; /* compression level (1..9) */ 171 + int strategy; /* favor or force Huffman coding*/ 172 + 173 + uInt good_match; 174 + /* Use a faster search when the previous match is longer than this */ 175 + 176 + int nice_match; /* Stop searching when current match exceeds this */ 177 + 178 + /* used by trees.c: */ 179 + /* Didn't use ct_data typedef below to supress compiler warning */ 180 + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ 181 + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ 182 + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ 183 + 184 + struct tree_desc_s l_desc; /* desc. for literal tree */ 185 + struct tree_desc_s d_desc; /* desc. for distance tree */ 186 + struct tree_desc_s bl_desc; /* desc. for bit length tree */ 187 + 188 + ush bl_count[MAX_BITS+1]; 189 + /* number of codes at each bit length for an optimal tree */ 190 + 191 + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ 192 + int heap_len; /* number of elements in the heap */ 193 + int heap_max; /* element of largest frequency */ 194 + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. 195 + * The same heap array is used to build all trees. 196 + */ 197 + 198 + uch depth[2*L_CODES+1]; 199 + /* Depth of each subtree used as tie breaker for trees of equal frequency 200 + */ 201 + 202 + uchf *l_buf; /* buffer for literals or lengths */ 203 + 204 + uInt lit_bufsize; 205 + /* Size of match buffer for literals/lengths. There are 4 reasons for 206 + * limiting lit_bufsize to 64K: 207 + * - frequencies can be kept in 16 bit counters 208 + * - if compression is not successful for the first block, all input 209 + * data is still in the window so we can still emit a stored block even 210 + * when input comes from standard input. (This can also be done for 211 + * all blocks if lit_bufsize is not greater than 32K.) 212 + * - if compression is not successful for a file smaller than 64K, we can 213 + * even emit a stored file instead of a stored block (saving 5 bytes). 214 + * This is applicable only for zip (not gzip or zlib). 215 + * - creating new Huffman trees less frequently may not provide fast 216 + * adaptation to changes in the input data statistics. (Take for 217 + * example a binary file with poorly compressible code followed by 218 + * a highly compressible string table.) Smaller buffer sizes give 219 + * fast adaptation but have of course the overhead of transmitting 220 + * trees more frequently. 221 + * - I can't count above 4 222 + */ 223 + 224 + uInt last_lit; /* running index in l_buf */ 225 + 226 + ushf *d_buf; 227 + /* Buffer for distances. To simplify the code, d_buf and l_buf have 228 + * the same number of elements. To use different lengths, an extra flag 229 + * array would be necessary. 230 + */ 231 + 232 + ulg opt_len; /* bit length of current block with optimal trees */ 233 + ulg static_len; /* bit length of current block with static trees */ 234 + uInt matches; /* number of string matches in current block */ 235 + int last_eob_len; /* bit length of EOB code for last block */ 236 + 237 +#ifdef DEBUG 238 + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ 239 + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ 240 +#endif 241 + 242 + ush bi_buf; 243 + /* Output buffer. bits are inserted starting at the bottom (least 244 + * significant bits). 245 + */ 246 + int bi_valid; 247 + /* Number of valid bits in bi_buf. All bits above the last valid bit 248 + * are always zero. 249 + */ 250 + 251 +} FAR deflate_state; 252 + 253 +/* Output a byte on the stream. 254 + * IN assertion: there is enough room in pending_buf. 255 + */ 256 +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} 257 + 258 + 259 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) 260 +/* Minimum amount of lookahead, except at the end of the input file. 261 + * See deflate.c for comments about the MIN_MATCH+1. 262 + */ 263 + 264 +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) 265 +/* In order to simplify the code, particularly on 16 bit machines, match 266 + * distances are limited to MAX_DIST instead of WSIZE. 267 + */ 268 + 269 + /* in trees.c */ 270 +void _tr_init OF((deflate_state *s)); 271 +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); 272 +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, 273 + int eof)); 274 +void _tr_align OF((deflate_state *s)); 275 +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, 276 + int eof)); 277 + 278 +#define d_code(dist) \ 279 + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) 280 +/* Mapping from a distance to a distance code. dist is the distance - 1 and 281 + * must not have side effects. _dist_code[256] and _dist_code[257] are never 282 + * used. 283 + */ 284 + 285 +#ifndef DEBUG 286 +/* Inline versions of _tr_tally for speed: */ 287 + 288 +#if defined(GEN_TREES_H) || !defined(STDC) 289 + extern uch _length_code[]; 290 + extern uch _dist_code[]; 291 +#else 292 + extern const uch _length_code[]; 293 + extern const uch _dist_code[]; 294 +#endif 295 + 296 +# define _tr_tally_lit(s, c, flush) \ 297 + { uch cc = (c); \ 298 + s->d_buf[s->last_lit] = 0; \ 299 + s->l_buf[s->last_lit++] = cc; \ 300 + s->dyn_ltree[cc].Freq++; \ 301 + flush = (s->last_lit == s->lit_bufsize-1); \ 302 + } 303 +# define _tr_tally_dist(s, distance, length, flush) \ 304 + { uch len = (length); \ 305 + ush dist = (distance); \ 306 + s->d_buf[s->last_lit] = dist; \ 307 + s->l_buf[s->last_lit++] = len; \ 308 + dist--; \ 309 + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ 310 + s->dyn_dtree[d_code(dist)].Freq++; \ 311 + flush = (s->last_lit == s->lit_bufsize-1); \ 312 + } 313 +#else 314 +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) 315 +# define _tr_tally_dist(s, distance, length, flush) \ 316 + flush = _tr_tally(s, distance, length) 317 +#endif 318 + 319 +#endif /* KI_GZ_NO_COMPRESSION */ 320 +#endif
Added zlib/gzio.c version [4b2f7581152ece4e]
1 +/* gzio.c -- IO on .gz files 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + * 5 + * Compile this file with -DNO_DEFLATE to avoid the compression code. 6 + */ 7 + 8 +/* @(#) $Id$ */ 9 + 10 +#include <stdio.h> 11 + 12 +#include "zutil.h" 13 + 14 +#ifdef KI_GZ_NO_COMPRESSION 15 +#define NO_DEFLATE 16 +#endif /* KI_GZ_NO_COMPRESSION */ 17 + 18 +struct internal_state {int dummy;}; /* for buggy compilers */ 19 + 20 +#ifndef Z_BUFSIZE 21 +# ifdef MAXSEG_64K 22 +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ 23 +# else 24 +# define Z_BUFSIZE 16384 25 +# endif 26 +#endif 27 +#ifndef Z_PRINTF_BUFSIZE 28 +# define Z_PRINTF_BUFSIZE 4096 29 +#endif 30 + 31 +#define ALLOC(size) malloc(size) 32 +#define TRYFREE(p) {if (p) free(p);} 33 + 34 +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ 35 + 36 +/* gzip flag byte */ 37 +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ 38 +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ 39 +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 40 +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 41 +#define COMMENT 0x10 /* bit 4 set: file comment present */ 42 +#define RESERVED 0xE0 /* bits 5..7: reserved */ 43 + 44 +typedef struct gz_stream { 45 + z_stream stream; 46 + int z_err; /* error code for last stream operation */ 47 + int z_eof; /* set if end of input file */ 48 + FILE *file; /* .gz file */ 49 + Byte *inbuf; /* input buffer */ 50 + Byte *outbuf; /* output buffer */ 51 + uLong crc; /* crc32 of uncompressed data */ 52 + char *msg; /* error message */ 53 + char *path; /* path name for debugging only */ 54 + int transparent; /* 1 if input file is not a .gz file */ 55 + char mode; /* 'w' or 'r' */ 56 + long startpos; /* start of compressed data in file (header skipped) */ 57 +} gz_stream; 58 + 59 + 60 +local gzFile gz_open OF((const char *path, const char *mode, int fd)); 61 +local int do_flush OF((gzFile file, int flush)); 62 +local int get_byte OF((gz_stream *s)); 63 +local void check_header OF((gz_stream *s)); 64 +local int destroy OF((gz_stream *s)); 65 +local void putLong OF((FILE *file, uLong x)); 66 +local uLong getLong OF((gz_stream *s)); 67 + 68 +/* =========================================================================== 69 + Opens a gzip (.gz) file for reading or writing. The mode parameter 70 + is as in fopen ("rb" or "wb"). The file is given either by file descriptor 71 + or path name (if fd == -1). 72 + gz_open return NULL if the file could not be opened or if there was 73 + insufficient memory to allocate the (de)compression state; errno 74 + can be checked to distinguish the two cases (if errno is zero, the 75 + zlib error is Z_MEM_ERROR). 76 +*/ 77 +local gzFile gz_open (path, mode, fd) 78 + const char *path; 79 + const char *mode; 80 + int fd; 81 +{ 82 + int err; 83 + int level = Z_DEFAULT_COMPRESSION; /* compression level */ 84 + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ 85 + char *p = (char*)mode; 86 + gz_stream *s; 87 + char fmode[80]; /* copy of mode, without the compression level */ 88 + char *m = fmode; 89 + 90 + if (!path || !mode) return Z_NULL; 91 + 92 + s = (gz_stream *)ALLOC(sizeof(gz_stream)); 93 + if (!s) return Z_NULL; 94 + 95 + s->stream.zalloc = (alloc_func)0; 96 + s->stream.zfree = (free_func)0; 97 + s->stream.opaque = (voidpf)0; 98 + s->stream.next_in = s->inbuf = Z_NULL; 99 + s->stream.next_out = s->outbuf = Z_NULL; 100 + s->stream.avail_in = s->stream.avail_out = 0; 101 + s->file = NULL; 102 + s->z_err = Z_OK; 103 + s->z_eof = 0; 104 + s->crc = crc32(0L, Z_NULL, 0); 105 + s->msg = NULL; 106 + s->transparent = 0; 107 + 108 + s->path = (char*)ALLOC(strlen(path)+1); 109 + if (s->path == NULL) { 110 + return destroy(s), (gzFile)Z_NULL; 111 + } 112 + strcpy(s->path, path); /* do this early for debugging */ 113 + 114 + s->mode = '\0'; 115 + do { 116 + if (*p == 'r') s->mode = 'r'; 117 + if (*p == 'w' || *p == 'a') s->mode = 'w'; 118 + if (*p >= '0' && *p <= '9') { 119 + level = *p - '0'; 120 + } else if (*p == 'f') { 121 + strategy = Z_FILTERED; 122 + } else if (*p == 'h') { 123 + strategy = Z_HUFFMAN_ONLY; 124 + } else { 125 + *m++ = *p; /* copy the mode */ 126 + } 127 + } while (*p++ && m != fmode + sizeof(fmode)); 128 + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; 129 + 130 + if (s->mode == 'w') { 131 +#ifdef NO_DEFLATE 132 + err = Z_STREAM_ERROR; 133 +#else 134 + err = deflateInit2(&(s->stream), level, 135 + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); 136 + /* windowBits is passed < 0 to suppress zlib header */ 137 + 138 + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 139 +#endif 140 + if (err != Z_OK || s->outbuf == Z_NULL) { 141 + return destroy(s), (gzFile)Z_NULL; 142 + } 143 + } else { 144 + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); 145 + 146 + err = inflateInit2(&(s->stream), -MAX_WBITS); 147 + /* windowBits is passed < 0 to tell that there is no zlib header. 148 + * Note that in this case inflate *requires* an extra "dummy" byte 149 + * after the compressed stream in order to complete decompression and 150 + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are 151 + * present after the compressed stream. 152 + */ 153 + if (err != Z_OK || s->inbuf == Z_NULL) { 154 + return destroy(s), (gzFile)Z_NULL; 155 + } 156 + } 157 + s->stream.avail_out = Z_BUFSIZE; 158 + 159 + errno = 0; 160 + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); 161 + 162 + if (s->file == NULL) { 163 + return destroy(s), (gzFile)Z_NULL; 164 + } 165 + if (s->mode == 'w') { 166 + /* Write a very simple .gz header: 167 + */ 168 + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], 169 + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); 170 + s->startpos = 10L; 171 + /* We use 10L instead of ftell(s->file) to because ftell causes an 172 + * fflush on some systems. This version of the library doesn't use 173 + * startpos anyway in write mode, so this initialization is not 174 + * necessary. 175 + */ 176 + } else { 177 + check_header(s); /* skip the .gz header */ 178 + s->startpos = (ftell(s->file) - s->stream.avail_in); 179 + } 180 + 181 + return (gzFile)s; 182 +} 183 + 184 +/* =========================================================================== 185 + Opens a gzip (.gz) file for reading or writing. 186 +*/ 187 +gzFile ZEXPORT gzopen (path, mode) 188 + const char *path; 189 + const char *mode; 190 +{ 191 + return gz_open (path, mode, -1); 192 +} 193 + 194 +/* =========================================================================== 195 + Associate a gzFile with the file descriptor fd. fd is not dup'ed here 196 + to mimic the behavio(u)r of fdopen. 197 +*/ 198 +gzFile ZEXPORT gzdopen (fd, mode) 199 + int fd; 200 + const char *mode; 201 +{ 202 + char name[20]; 203 + 204 + if (fd < 0) return (gzFile)Z_NULL; 205 + sprintf(name, "<fd:%d>", fd); /* for debugging */ 206 + 207 + return gz_open (name, mode, fd); 208 +} 209 + 210 +/* =========================================================================== 211 + * Update the compression level and strategy 212 + */ 213 +int ZEXPORT gzsetparams (file, level, strategy) 214 + gzFile file; 215 + int level; 216 + int strategy; 217 +{ 218 +#ifndef KI_GZ_NO_COMPRESSION 219 + gz_stream *s = (gz_stream*)file; 220 + 221 + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 222 + 223 + /* Make room to allow flushing */ 224 + if (s->stream.avail_out == 0) { 225 + 226 + s->stream.next_out = s->outbuf; 227 + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 228 + s->z_err = Z_ERRNO; 229 + } 230 + s->stream.avail_out = Z_BUFSIZE; 231 + } 232 + 233 + return deflateParams (&(s->stream), level, strategy); 234 +#else 235 + return Z_STREAM_ERROR; 236 +#endif /* KI_GZ_NO_COMPRESSION */ 237 +} 238 + 239 +/* =========================================================================== 240 + Read a byte from a gz_stream; update next_in and avail_in. Return EOF 241 + for end of file. 242 + IN assertion: the stream s has been sucessfully opened for reading. 243 +*/ 244 +local int get_byte(s) 245 + gz_stream *s; 246 +{ 247 + if (s->z_eof) return EOF; 248 + if (s->stream.avail_in == 0) { 249 + errno = 0; 250 + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 251 + if (s->stream.avail_in == 0) { 252 + s->z_eof = 1; 253 + if (ferror(s->file)) s->z_err = Z_ERRNO; 254 + return EOF; 255 + } 256 + s->stream.next_in = s->inbuf; 257 + } 258 + s->stream.avail_in--; 259 + return *(s->stream.next_in)++; 260 +} 261 + 262 +/* =========================================================================== 263 + Check the gzip header of a gz_stream opened for reading. Set the stream 264 + mode to transparent if the gzip magic header is not present; set s->err 265 + to Z_DATA_ERROR if the magic header is present but the rest of the header 266 + is incorrect. 267 + IN assertion: the stream s has already been created sucessfully; 268 + s->stream.avail_in is zero for the first time, but may be non-zero 269 + for concatenated .gz files. 270 +*/ 271 +local void check_header(s) 272 + gz_stream *s; 273 +{ 274 + int method; /* method byte */ 275 + int flags; /* flags byte */ 276 + uInt len; 277 + int c; 278 + 279 + /* Check the gzip magic header */ 280 + for (len = 0; len < 2; len++) { 281 + c = get_byte(s); 282 + if (c != gz_magic[len]) { 283 + if (len != 0) s->stream.avail_in++, s->stream.next_in--; 284 + if (c != EOF) { 285 + s->stream.avail_in++, s->stream.next_in--; 286 + s->transparent = 1; 287 + } 288 + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; 289 + return; 290 + } 291 + } 292 + method = get_byte(s); 293 + flags = get_byte(s); 294 + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { 295 + s->z_err = Z_DATA_ERROR; 296 + return; 297 + } 298 + 299 + /* Discard time, xflags and OS code: */ 300 + for (len = 0; len < 6; len++) (void)get_byte(s); 301 + 302 + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ 303 + len = (uInt)get_byte(s); 304 + len += ((uInt)get_byte(s))<<8; 305 + /* len is garbage if EOF but the loop below will quit anyway */ 306 + while (len-- != 0 && get_byte(s) != EOF) ; 307 + } 308 + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ 309 + while ((c = get_byte(s)) != 0 && c != EOF) ; 310 + } 311 + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ 312 + while ((c = get_byte(s)) != 0 && c != EOF) ; 313 + } 314 + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ 315 + for (len = 0; len < 2; len++) (void)get_byte(s); 316 + } 317 + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; 318 +} 319 + 320 + /* =========================================================================== 321 + * Cleanup then free the given gz_stream. Return a zlib error code. 322 + Try freeing in the reverse order of allocations. 323 + */ 324 +local int destroy (s) 325 + gz_stream *s; 326 +{ 327 + int err = Z_OK; 328 + 329 + if (!s) return Z_STREAM_ERROR; 330 + 331 + TRYFREE(s->msg); 332 + 333 + if (s->stream.state != NULL) { 334 + if (s->mode == 'w') { 335 +#ifdef NO_DEFLATE 336 + err = Z_STREAM_ERROR; 337 +#else 338 + err = deflateEnd(&(s->stream)); 339 +#endif 340 + } else if (s->mode == 'r') { 341 + err = inflateEnd(&(s->stream)); 342 + } 343 + } 344 + if (s->file != NULL && fclose(s->file)) { 345 +#ifdef ESPIPE 346 + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ 347 +#endif 348 + err = Z_ERRNO; 349 + } 350 + if (s->z_err < 0) err = s->z_err; 351 + 352 + TRYFREE(s->inbuf); 353 + TRYFREE(s->outbuf); 354 + TRYFREE(s->path); 355 + TRYFREE(s); 356 + return err; 357 +} 358 + 359 +/* =========================================================================== 360 + Reads the given number of uncompressed bytes from the compressed file. 361 + gzread returns the number of bytes actually read (0 for end of file). 362 +*/ 363 +int ZEXPORT gzread (file, buf, len) 364 + gzFile file; 365 + voidp buf; 366 + unsigned len; 367 +{ 368 + gz_stream *s = (gz_stream*)file; 369 + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ 370 + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ 371 + 372 + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; 373 + 374 + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; 375 + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ 376 + 377 + next_out = (Byte*)buf; 378 + s->stream.next_out = (Bytef*)buf; 379 + s->stream.avail_out = len; 380 + 381 + while (s->stream.avail_out != 0) { 382 + 383 + if (s->transparent) { 384 + /* Copy first the lookahead bytes: */ 385 + uInt n = s->stream.avail_in; 386 + if (n > s->stream.avail_out) n = s->stream.avail_out; 387 + if (n > 0) { 388 + zmemcpy(s->stream.next_out, s->stream.next_in, n); 389 + next_out += n; 390 + s->stream.next_out = next_out; 391 + s->stream.next_in += n; 392 + s->stream.avail_out -= n; 393 + s->stream.avail_in -= n; 394 + } 395 + if (s->stream.avail_out > 0) { 396 + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, 397 + s->file); 398 + } 399 + len -= s->stream.avail_out; 400 + s->stream.total_in += (uLong)len; 401 + s->stream.total_out += (uLong)len; 402 + if (len == 0) s->z_eof = 1; 403 + return (int)len; 404 + } 405 + if (s->stream.avail_in == 0 && !s->z_eof) { 406 + 407 + errno = 0; 408 + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 409 + if (s->stream.avail_in == 0) { 410 + s->z_eof = 1; 411 + if (ferror(s->file)) { 412 + s->z_err = Z_ERRNO; 413 + break; 414 + } 415 + } 416 + s->stream.next_in = s->inbuf; 417 + } 418 + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); 419 + 420 + if (s->z_err == Z_STREAM_END) { 421 + /* Check CRC and original size */ 422 + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 423 + start = s->stream.next_out; 424 + 425 + if (getLong(s) != s->crc) { 426 + s->z_err = Z_DATA_ERROR; 427 + } else { 428 + (void)getLong(s); 429 + /* The uncompressed length returned by above getlong() may 430 + * be different from s->stream.total_out) in case of 431 + * concatenated .gz files. Check for such files: 432 + */ 433 + check_header(s); 434 + if (s->z_err == Z_OK) { 435 + uLong total_in = s->stream.total_in; 436 + uLong total_out = s->stream.total_out; 437 + 438 + inflateReset(&(s->stream)); 439 + s->stream.total_in = total_in; 440 + s->stream.total_out = total_out; 441 + s->crc = crc32(0L, Z_NULL, 0); 442 + } 443 + } 444 + } 445 + if (s->z_err != Z_OK || s->z_eof) break; 446 + } 447 + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 448 + 449 + return (int)(len - s->stream.avail_out); 450 +} 451 + 452 + 453 +/* =========================================================================== 454 + Reads one byte from the compressed file. gzgetc returns this byte 455 + or -1 in case of end of file or error. 456 +*/ 457 +int ZEXPORT gzgetc(file) 458 + gzFile file; 459 +{ 460 + unsigned char c; 461 + 462 + return gzread(file, &c, 1) == 1 ? c : -1; 463 +} 464 + 465 + 466 +/* =========================================================================== 467 + Reads bytes from the compressed file until len-1 characters are 468 + read, or a newline character is read and transferred to buf, or an 469 + end-of-file condition is encountered. The string is then terminated 470 + with a null character. 471 + gzgets returns buf, or Z_NULL in case of error. 472 + 473 + The current implementation is not optimized at all. 474 +*/ 475 +char * ZEXPORT gzgets(file, buf, len) 476 + gzFile file; 477 + char *buf; 478 + int len; 479 +{ 480 + char *b = buf; 481 + if (buf == Z_NULL || len <= 0) return Z_NULL; 482 + 483 + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; 484 + *buf = '\0'; 485 + return b == buf && len > 0 ? Z_NULL : b; 486 +} 487 + 488 + 489 +#ifndef NO_DEFLATE 490 +/* =========================================================================== 491 + Writes the given number of uncompressed bytes into the compressed file. 492 + gzwrite returns the number of bytes actually written (0 in case of error). 493 +*/ 494 +int ZEXPORT gzwrite (file, buf, len) 495 + gzFile file; 496 + const voidp buf; 497 + unsigned len; 498 +{ 499 + gz_stream *s = (gz_stream*)file; 500 + 501 + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 502 + 503 + s->stream.next_in = (Bytef*)buf; 504 + s->stream.avail_in = len; 505 + 506 + while (s->stream.avail_in != 0) { 507 + 508 + if (s->stream.avail_out == 0) { 509 + 510 + s->stream.next_out = s->outbuf; 511 + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 512 + s->z_err = Z_ERRNO; 513 + break; 514 + } 515 + s->stream.avail_out = Z_BUFSIZE; 516 + } 517 + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); 518 + if (s->z_err != Z_OK) break; 519 + } 520 + s->crc = crc32(s->crc, (const Bytef *)buf, len); 521 + 522 + return (int)(len - s->stream.avail_in); 523 +} 524 + 525 +/* =========================================================================== 526 + Converts, formats, and writes the args to the compressed file under 527 + control of the format string, as in fprintf. gzprintf returns the number of 528 + uncompressed bytes actually written (0 in case of error). 529 +*/ 530 +#ifdef STDC 531 +#include <stdarg.h> 532 + 533 +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) 534 +{ 535 + char buf[Z_PRINTF_BUFSIZE]; 536 + va_list va; 537 + int len; 538 + 539 + va_start(va, format); 540 +#ifdef HAS_vsnprintf 541 + (void)vsnprintf(buf, sizeof(buf), format, va); 542 +#else 543 + (void)vsprintf(buf, format, va); 544 +#endif 545 + va_end(va); 546 + len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ 547 + if (len <= 0) return 0; 548 + 549 + return gzwrite(file, buf, (unsigned)len); 550 +} 551 +#else /* not ANSI C */ 552 + 553 +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 554 + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 555 + gzFile file; 556 + const char *format; 557 + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 558 + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 559 +{ 560 + char buf[Z_PRINTF_BUFSIZE]; 561 + int len; 562 + 563 +#ifdef HAS_snprintf 564 + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 565 + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 566 +#else 567 + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 568 + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 569 +#endif 570 + len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ 571 + if (len <= 0) return 0; 572 + 573 + return gzwrite(file, buf, len); 574 +} 575 +#endif 576 + 577 +/* =========================================================================== 578 + Writes c, converted to an unsigned char, into the compressed file. 579 + gzputc returns the value that was written, or -1 in case of error. 580 +*/ 581 +int ZEXPORT gzputc(file, c) 582 + gzFile file; 583 + int c; 584 +{ 585 + unsigned char cc = (unsigned char) c; /* required for big endian systems */ 586 + 587 + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; 588 +} 589 + 590 + 591 +/* =========================================================================== 592 + Writes the given null-terminated string to the compressed file, excluding 593 + the terminating null character. 594 + gzputs returns the number of characters written, or -1 in case of error. 595 +*/ 596 +int ZEXPORT gzputs(file, s) 597 + gzFile file; 598 + const char *s; 599 +{ 600 + return gzwrite(file, (char*)s, (unsigned)strlen(s)); 601 +} 602 + 603 +/* =========================================================================== 604 + Flushes all pending output into the compressed file. The parameter 605 + flush is as in the deflate() function. 606 +*/ 607 +local int do_flush (file, flush) 608 + gzFile file; 609 + int flush; 610 +{ 611 + uInt len; 612 + int done = 0; 613 + gz_stream *s = (gz_stream*)file; 614 + 615 + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 616 + 617 + s->stream.avail_in = 0; /* should be zero already anyway */ 618 + 619 + for (;;) { 620 + len = Z_BUFSIZE - s->stream.avail_out; 621 + 622 + if (len != 0) { 623 + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { 624 + s->z_err = Z_ERRNO; 625 + return Z_ERRNO; 626 + } 627 + s->stream.next_out = s->outbuf; 628 + s->stream.avail_out = Z_BUFSIZE; 629 + } 630 + if (done) break; 631 + s->z_err = deflate(&(s->stream), flush); 632 + 633 + /* Ignore the second of two consecutive flushes: */ 634 + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; 635 + 636 + /* deflate has finished flushing only when it hasn't used up 637 + * all the available space in the output buffer: 638 + */ 639 + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); 640 + 641 + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; 642 + } 643 + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 644 +} 645 + 646 +int ZEXPORT gzflush (file, flush) 647 + gzFile file; 648 + int flush; 649 +{ 650 + gz_stream *s = (gz_stream*)file; 651 + int err = do_flush (file, flush); 652 + 653 + if (err) return err; 654 + fflush(s->file); 655 + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 656 +} 657 +#endif /* NO_DEFLATE */ 658 + 659 +/* =========================================================================== 660 + Sets the starting position for the next gzread or gzwrite on the given 661 + compressed file. The offset represents a number of bytes in the 662 + gzseek returns the resulting offset location as measured in bytes from 663 + the beginning of the uncompressed stream, or -1 in case of error. 664 + SEEK_END is not implemented, returns error. 665 + In this version of the library, gzseek can be extremely slow. 666 +*/ 667 +z_off_t ZEXPORT gzseek (file, offset, whence) 668 + gzFile file; 669 + z_off_t offset; 670 + int whence; 671 +{ 672 + gz_stream *s = (gz_stream*)file; 673 + 674 + if (s == NULL || whence == SEEK_END || 675 + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { 676 + return -1L; 677 + } 678 + 679 + if (s->mode == 'w') { 680 +#ifdef NO_DEFLATE 681 + return -1L; 682 +#else 683 + if (whence == SEEK_SET) { 684 + offset -= s->stream.total_in; 685 + } 686 + if (offset < 0) return -1L; 687 + 688 + /* At this point, offset is the number of zero bytes to write. */ 689 + if (s->inbuf == Z_NULL) { 690 + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ 691 + zmemzero(s->inbuf, Z_BUFSIZE); 692 + } 693 + while (offset > 0) { 694 + uInt size = Z_BUFSIZE; 695 + if (offset < Z_BUFSIZE) size = (uInt)offset; 696 + 697 + size = gzwrite(file, s->inbuf, size); 698 + if (size == 0) return -1L; 699 + 700 + offset -= size; 701 + } 702 + return (z_off_t)s->stream.total_in; 703 +#endif 704 + } 705 + /* Rest of function is for reading only */ 706 + 707 + /* compute absolute position */ 708 + if (whence == SEEK_CUR) { 709 + offset += s->stream.total_out; 710 + } 711 + if (offset < 0) return -1L; 712 + 713 + if (s->transparent) { 714 + /* map to fseek */ 715 + s->stream.avail_in = 0; 716 + s->stream.next_in = s->inbuf; 717 + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; 718 + 719 + s->stream.total_in = s->stream.total_out = (uLong)offset; 720 + return offset; 721 + } 722 + 723 + /* For a negative seek, rewind and use positive seek */ 724 + if ((uLong)offset >= s->stream.total_out) { 725 + offset -= s->stream.total_out; 726 + } else if (gzrewind(file) < 0) { 727 + return -1L; 728 + } 729 + /* offset is now the number of bytes to skip. */ 730 + 731 + if (offset != 0 && s->outbuf == Z_NULL) { 732 + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 733 + } 734 + while (offset > 0) { 735 + int size = Z_BUFSIZE; 736 + if (offset < Z_BUFSIZE) size = (int)offset; 737 + 738 + size = gzread(file, s->outbuf, (uInt)size); 739 + if (size <= 0) return -1L; 740 + offset -= size; 741 + } 742 + return (z_off_t)s->stream.total_out; 743 +} 744 + 745 +/* =========================================================================== 746 + Rewinds input file. 747 +*/ 748 +int ZEXPORT gzrewind (file) 749 + gzFile file; 750 +{ 751 + gz_stream *s = (gz_stream*)file; 752 + 753 + if (s == NULL || s->mode != 'r') return -1; 754 + 755 + s->z_err = Z_OK; 756 + s->z_eof = 0; 757 + s->stream.avail_in = 0; 758 + s->stream.next_in = s->inbuf; 759 + s->crc = crc32(0L, Z_NULL, 0); 760 + 761 + if (s->startpos == 0) { /* not a compressed file */ 762 + rewind(s->file); 763 + return 0; 764 + } 765 + 766 + (void) inflateReset(&s->stream); 767 + return fseek(s->file, s->startpos, SEEK_SET); 768 +} 769 + 770 +/* =========================================================================== 771 + Returns the starting position for the next gzread or gzwrite on the 772 + given compressed file. This position represents a number of bytes in the 773 + uncompressed data stream. 774 +*/ 775 +z_off_t ZEXPORT gztell (file) 776 + gzFile file; 777 +{ 778 + return gzseek(file, 0L, SEEK_CUR); 779 +} 780 + 781 +/* =========================================================================== 782 + Returns 1 when EOF has previously been detected reading the given 783 + input stream, otherwise zero. 784 +*/ 785 +int ZEXPORT gzeof (file) 786 + gzFile file; 787 +{ 788 + gz_stream *s = (gz_stream*)file; 789 + 790 + return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; 791 +} 792 + 793 +/* =========================================================================== 794 + Outputs a long in LSB order to the given file 795 +*/ 796 +local void putLong (file, x) 797 + FILE *file; 798 + uLong x; 799 +{ 800 + int n; 801 + for (n = 0; n < 4; n++) { 802 + fputc((int)(x & 0xff), file); 803 + x >>= 8; 804 + } 805 +} 806 + 807 +/* =========================================================================== 808 + Reads a long in LSB order from the given gz_stream. Sets z_err in case 809 + of error. 810 +*/ 811 +local uLong getLong (s) 812 + gz_stream *s; 813 +{ 814 + uLong x = (uLong)get_byte(s); 815 + int c; 816 + 817 + x += ((uLong)get_byte(s))<<8; 818 + x += ((uLong)get_byte(s))<<16; 819 + c = get_byte(s); 820 + if (c == EOF) s->z_err = Z_DATA_ERROR; 821 + x += ((uLong)c)<<24; 822 + return x; 823 +} 824 + 825 +/* =========================================================================== 826 + Flushes all pending output if necessary, closes the compressed file 827 + and deallocates all the (de)compression state. 828 +*/ 829 +int ZEXPORT gzclose (file) 830 + gzFile file; 831 +{ 832 + gz_stream *s = (gz_stream*)file; 833 + 834 + if (s == NULL) return Z_STREAM_ERROR; 835 + 836 + if (s->mode == 'w') { 837 +#ifdef NO_DEFLATE 838 + return Z_STREAM_ERROR; 839 +#else 840 + err = do_flush (file, Z_FINISH); 841 + if (err != Z_OK) return destroy((gz_stream*)file); 842 + 843 + putLong (s->file, s->crc); 844 + putLong (s->file, s->stream.total_in); 845 +#endif 846 + } 847 + return destroy((gz_stream*)file); 848 +} 849 + 850 +/* =========================================================================== 851 + Returns the error message for the last error which occured on the 852 + given compressed file. errnum is set to zlib error number. If an 853 + error occured in the file system and not in the compression library, 854 + errnum is set to Z_ERRNO and the application may consult errno 855 + to get the exact error code. 856 +*/ 857 +const char* ZEXPORT gzerror (file, errnum) 858 + gzFile file; 859 + int *errnum; 860 +{ 861 + char *m; 862 + gz_stream *s = (gz_stream*)file; 863 + 864 + if (s == NULL) { 865 + *errnum = Z_STREAM_ERROR; 866 + return (const char*)ERR_MSG(Z_STREAM_ERROR); 867 + } 868 + *errnum = s->z_err; 869 + if (*errnum == Z_OK) return (const char*)""; 870 + 871 + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); 872 + 873 + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); 874 + 875 + TRYFREE(s->msg); 876 + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); 877 + strcpy(s->msg, s->path); 878 + strcat(s->msg, ": "); 879 + strcat(s->msg, m); 880 + return (const char*)s->msg; 881 +}
Added zlib/infblock.c version [247ccc67935ee81d]
1 +/* infblock.c -- interpret and process block types to last block 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "infblock.h" 8 +#include "inftrees.h" 9 +#include "infcodes.h" 10 +#include "infutil.h" 11 + 12 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ 13 + 14 +/* simplify the use of the inflate_huft type with some defines */ 15 +#define exop word.what.Exop 16 +#define bits word.what.Bits 17 + 18 +/* Table for deflate from PKZIP's appnote.txt. */ 19 +local const uInt border[] = { /* Order of the bit length code lengths */ 20 + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 21 + 22 +/* 23 + Notes beyond the 1.93a appnote.txt: 24 + 25 + 1. Distance pointers never point before the beginning of the output 26 + stream. 27 + 2. Distance pointers can point back across blocks, up to 32k away. 28 + 3. There is an implied maximum of 7 bits for the bit length table and 29 + 15 bits for the actual data. 30 + 4. If only one code exists, then it is encoded using one bit. (Zero 31 + would be more efficient, but perhaps a little confusing.) If two 32 + codes exist, they are coded using one bit each (0 and 1). 33 + 5. There is no way of sending zero distance codes--a dummy must be 34 + sent if there are none. (History: a pre 2.0 version of PKZIP would 35 + store blocks with no distance codes, but this was discovered to be 36 + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow 37 + zero distance codes, which is sent as one code of zero bits in 38 + length. 39 + 6. There are up to 286 literal/length codes. Code 256 represents the 40 + end-of-block. Note however that the static length tree defines 41 + 288 codes just to fill out the Huffman codes. Codes 286 and 287 42 + cannot be used though, since there is no length base or extra bits 43 + defined for them. Similarily, there are up to 30 distance codes. 44 + However, static trees define 32 codes (all 5 bits) to fill out the 45 + Huffman codes, but the last two had better not show up in the data. 46 + 7. Unzip can check dynamic Huffman blocks for complete code sets. 47 + The exception is that a single code would not be complete (see #4). 48 + 8. The five bits following the block type is really the number of 49 + literal codes sent minus 257. 50 + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits 51 + (1+6+6). Therefore, to output three times the length, you output 52 + three codes (1+1+1), whereas to output four times the same length, 53 + you only need two codes (1+3). Hmm. 54 + 10. In the tree reconstruction algorithm, Code = Code + Increment 55 + only if BitLength(i) is not zero. (Pretty obvious.) 56 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 57 + 12. Note: length code 284 can represent 227-258, but length code 285 58 + really is 258. The last length deserves its own, short code 59 + since it gets used a lot in very redundant files. The length 60 + 258 is special since 258 - 3 (the min match length) is 255. 61 + 13. The literal/length and distance code bit lengths are read as a 62 + single stream of lengths. It is possible (and advantageous) for 63 + a repeat code (16, 17, or 18) to go across the boundary between 64 + the two sets of lengths. 65 + */ 66 + 67 + 68 +void inflate_blocks_reset(s, z, c) 69 +inflate_blocks_statef *s; 70 +z_streamp z; 71 +uLongf *c; 72 +{ 73 + if (c != Z_NULL) 74 + *c = s->check; 75 + if (s->mode == BTREE || s->mode == DTREE) 76 + ZFREE(z, s->sub.trees.blens); 77 + if (s->mode == CODES) 78 + inflate_codes_free(s->sub.decode.codes, z); 79 + s->mode = TYPE; 80 + s->bitk = 0; 81 + s->bitb = 0; 82 + s->read = s->write = s->window; 83 + if (s->checkfn != Z_NULL) 84 + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); 85 + Tracev((stderr, "inflate: blocks reset\n")); 86 +} 87 + 88 + 89 +inflate_blocks_statef *inflate_blocks_new(z, c, w) 90 +z_streamp z; 91 +check_func c; 92 +uInt w; 93 +{ 94 + inflate_blocks_statef *s; 95 + 96 + if ((s = (inflate_blocks_statef *)ZALLOC 97 + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) 98 + return s; 99 + if ((s->hufts = 100 + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) 101 + { 102 + ZFREE(z, s); 103 + return Z_NULL; 104 + } 105 + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) 106 + { 107 + ZFREE(z, s->hufts); 108 + ZFREE(z, s); 109 + return Z_NULL; 110 + } 111 + s->end = s->window + w; 112 + s->checkfn = c; 113 + s->mode = TYPE; 114 + Tracev((stderr, "inflate: blocks allocated\n")); 115 + inflate_blocks_reset(s, z, Z_NULL); 116 + return s; 117 +} 118 + 119 + 120 +int inflate_blocks(s, z, r) 121 +inflate_blocks_statef *s; 122 +z_streamp z; 123 +int r; 124 +{ 125 + uInt t; /* temporary storage */ 126 + uLong b; /* bit buffer */ 127 + uInt k; /* bits in bit buffer */ 128 + Bytef *p; /* input data pointer */ 129 + uInt n; /* bytes available there */ 130 + Bytef *q; /* output window write pointer */ 131 + uInt m; /* bytes to end of window or read pointer */ 132 + 133 + /* copy input/output information to locals (UPDATE macro restores) */ 134 + LOAD 135 + 136 + /* process input based on current state */ 137 + while (1) switch (s->mode) 138 + { 139 + case TYPE: 140 + NEEDBITS(3) 141 + t = (uInt)b & 7; 142 + s->last = t & 1; 143 + switch (t >> 1) 144 + { 145 + case 0: /* stored */ 146 + Tracev((stderr, "inflate: stored block%s\n", 147 + s->last ? " (last)" : "")); 148 + DUMPBITS(3) 149 + t = k & 7; /* go to byte boundary */ 150 + DUMPBITS(t) 151 + s->mode = LENS; /* get length of stored block */ 152 + break; 153 + case 1: /* fixed */ 154 + Tracev((stderr, "inflate: fixed codes block%s\n", 155 + s->last ? " (last)" : "")); 156 + { 157 + uInt bl, bd; 158 + inflate_huft *tl, *td; 159 + 160 + inflate_trees_fixed(&bl, &bd, &tl, &td, z); 161 + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); 162 + if (s->sub.decode.codes == Z_NULL) 163 + { 164 + r = Z_MEM_ERROR; 165 + LEAVE 166 + } 167 + } 168 + DUMPBITS(3) 169 + s->mode = CODES; 170 + break; 171 + case 2: /* dynamic */ 172 + Tracev((stderr, "inflate: dynamic codes block%s\n", 173 + s->last ? " (last)" : "")); 174 + DUMPBITS(3) 175 + s->mode = TABLE; 176 + break; 177 + case 3: /* illegal */ 178 + DUMPBITS(3) 179 + s->mode = BAD; 180 + z->msg = (char*)"invalid block type"; 181 + r = Z_DATA_ERROR; 182 + LEAVE 183 + } 184 + break; 185 + case LENS: 186 + NEEDBITS(32) 187 + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) 188 + { 189 + s->mode = BAD; 190 + z->msg = (char*)"invalid stored block lengths"; 191 + r = Z_DATA_ERROR; 192 + LEAVE 193 + } 194 + s->sub.left = (uInt)b & 0xffff; 195 + b = k = 0; /* dump bits */ 196 + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); 197 + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); 198 + break; 199 + case STORED: 200 + if (n == 0) 201 + LEAVE 202 + NEEDOUT 203 + t = s->sub.left; 204 + if (t > n) t = n; 205 + if (t > m) t = m; 206 + zmemcpy(q, p, t); 207 + p += t; n -= t; 208 + q += t; m -= t; 209 + if ((s->sub.left -= t) != 0) 210 + break; 211 + Tracev((stderr, "inflate: stored end, %lu total out\n", 212 + z->total_out + (q >= s->read ? q - s->read : 213 + (s->end - s->read) + (q - s->window)))); 214 + s->mode = s->last ? DRY : TYPE; 215 + break; 216 + case TABLE: 217 + NEEDBITS(14) 218 + s->sub.trees.table = t = (uInt)b & 0x3fff; 219 +#ifndef PKZIP_BUG_WORKAROUND 220 + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) 221 + { 222 + s->mode = BAD; 223 + z->msg = (char*)"too many length or distance symbols"; 224 + r = Z_DATA_ERROR; 225 + LEAVE 226 + } 227 +#endif 228 + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); 229 + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) 230 + { 231 + r = Z_MEM_ERROR; 232 + LEAVE 233 + } 234 + DUMPBITS(14) 235 + s->sub.trees.index = 0; 236 + Tracev((stderr, "inflate: table sizes ok\n")); 237 + s->mode = BTREE; 238 + case BTREE: 239 + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) 240 + { 241 + NEEDBITS(3) 242 + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; 243 + DUMPBITS(3) 244 + } 245 + while (s->sub.trees.index < 19) 246 + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; 247 + s->sub.trees.bb = 7; 248 + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, 249 + &s->sub.trees.tb, s->hufts, z); 250 + if (t != Z_OK) 251 + { 252 + ZFREE(z, s->sub.trees.blens); 253 + r = t; 254 + if (r == Z_DATA_ERROR) 255 + s->mode = BAD; 256 + LEAVE 257 + } 258 + s->sub.trees.index = 0; 259 + Tracev((stderr, "inflate: bits tree ok\n")); 260 + s->mode = DTREE; 261 + case DTREE: 262 + while (t = s->sub.trees.table, 263 + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) 264 + { 265 + inflate_huft *h; 266 + uInt i, j, c; 267 + 268 + t = s->sub.trees.bb; 269 + NEEDBITS(t) 270 + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); 271 + t = h->bits; 272 + c = h->base; 273 + if (c < 16) 274 + { 275 + DUMPBITS(t) 276 + s->sub.trees.blens[s->sub.trees.index++] = c; 277 + } 278 + else /* c == 16..18 */ 279 + { 280 + i = c == 18 ? 7 : c - 14; 281 + j = c == 18 ? 11 : 3; 282 + NEEDBITS(t + i) 283 + DUMPBITS(t) 284 + j += (uInt)b & inflate_mask[i]; 285 + DUMPBITS(i) 286 + i = s->sub.trees.index; 287 + t = s->sub.trees.table; 288 + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || 289 + (c == 16 && i < 1)) 290 + { 291 + ZFREE(z, s->sub.trees.blens); 292 + s->mode = BAD; 293 + z->msg = (char*)"invalid bit length repeat"; 294 + r = Z_DATA_ERROR; 295 + LEAVE 296 + } 297 + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; 298 + do { 299 + s->sub.trees.blens[i++] = c; 300 + } while (--j); 301 + s->sub.trees.index = i; 302 + } 303 + } 304 + s->sub.trees.tb = Z_NULL; 305 + { 306 + uInt bl, bd; 307 + inflate_huft *tl, *td; 308 + inflate_codes_statef *c; 309 + 310 + bl = 9; /* must be <= 9 for lookahead assumptions */ 311 + bd = 6; /* must be <= 9 for lookahead assumptions */ 312 + t = s->sub.trees.table; 313 + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), 314 + s->sub.trees.blens, &bl, &bd, &tl, &td, 315 + s->hufts, z); 316 + ZFREE(z, s->sub.trees.blens); 317 + if (t != Z_OK) 318 + { 319 + if (t == (uInt)Z_DATA_ERROR) 320 + s->mode = BAD; 321 + r = t; 322 + LEAVE 323 + } 324 + Tracev((stderr, "inflate: trees ok\n")); 325 + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) 326 + { 327 + r = Z_MEM_ERROR; 328 + LEAVE 329 + } 330 + s->sub.decode.codes = c; 331 + } 332 + s->mode = CODES; 333 + case CODES: 334 + UPDATE 335 + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) 336 + return inflate_flush(s, z, r); 337 + r = Z_OK; 338 + inflate_codes_free(s->sub.decode.codes, z); 339 + LOAD 340 + Tracev((stderr, "inflate: codes end, %lu total out\n", 341 + z->total_out + (q >= s->read ? q - s->read : 342 + (s->end - s->read) + (q - s->window)))); 343 + if (!s->last) 344 + { 345 + s->mode = TYPE; 346 + break; 347 + } 348 + s->mode = DRY; 349 + case DRY: 350 + FLUSH 351 + if (s->read != s->write) 352 + LEAVE 353 + s->mode = DONE; 354 + case DONE: 355 + r = Z_STREAM_END; 356 + LEAVE 357 + case BAD: 358 + r = Z_DATA_ERROR; 359 + LEAVE 360 + default: 361 + r = Z_STREAM_ERROR; 362 + LEAVE 363 + } 364 +} 365 + 366 + 367 +int inflate_blocks_free(s, z) 368 +inflate_blocks_statef *s; 369 +z_streamp z; 370 +{ 371 + inflate_blocks_reset(s, z, Z_NULL); 372 + ZFREE(z, s->window); 373 + ZFREE(z, s->hufts); 374 + ZFREE(z, s); 375 + Tracev((stderr, "inflate: blocks freed\n")); 376 + return Z_OK; 377 +} 378 + 379 + 380 +void inflate_set_dictionary(s, d, n) 381 +inflate_blocks_statef *s; 382 +const Bytef *d; 383 +uInt n; 384 +{ 385 + zmemcpy(s->window, d, n); 386 + s->read = s->write = s->window + n; 387 +} 388 + 389 + 390 +/* Returns true if inflate is currently at the end of a block generated 391 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 392 + * IN assertion: s != Z_NULL 393 + */ 394 +int inflate_blocks_sync_point(s) 395 +inflate_blocks_statef *s; 396 +{ 397 + return s->mode == LENS; 398 +}
Added zlib/infblock.h version [d82cce085111a3e6]
1 +/* infblock.h -- header to use infblock.c 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +struct inflate_blocks_state; 12 +typedef struct inflate_blocks_state FAR inflate_blocks_statef; 13 + 14 +extern inflate_blocks_statef * inflate_blocks_new OF(( 15 + z_streamp z, 16 + check_func c, /* check function */ 17 + uInt w)); /* window size */ 18 + 19 +extern int inflate_blocks OF(( 20 + inflate_blocks_statef *, 21 + z_streamp , 22 + int)); /* initial return code */ 23 + 24 +extern void inflate_blocks_reset OF(( 25 + inflate_blocks_statef *, 26 + z_streamp , 27 + uLongf *)); /* check value on output */ 28 + 29 +extern int inflate_blocks_free OF(( 30 + inflate_blocks_statef *, 31 + z_streamp)); 32 + 33 +extern void inflate_set_dictionary OF(( 34 + inflate_blocks_statef *s, 35 + const Bytef *d, /* dictionary */ 36 + uInt n)); /* dictionary length */ 37 + 38 +extern int inflate_blocks_sync_point OF(( 39 + inflate_blocks_statef *s));
Added zlib/infcodes.c version [7f23ab87bf41988d]
1 +/* infcodes.c -- process literals and length/distance pairs 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "inftrees.h" 8 +#include "infblock.h" 9 +#include "infcodes.h" 10 +#include "infutil.h" 11 +#include "inffast.h" 12 + 13 +/* simplify the use of the inflate_huft type with some defines */ 14 +#define exop word.what.Exop 15 +#define bits word.what.Bits 16 + 17 +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 18 + START, /* x: set up for LEN */ 19 + LEN, /* i: get length/literal/eob next */ 20 + LENEXT, /* i: getting length extra (have base) */ 21 + DIST, /* i: get distance next */ 22 + DISTEXT, /* i: getting distance extra */ 23 + COPY, /* o: copying bytes in window, waiting for space */ 24 + LIT, /* o: got literal, waiting for output space */ 25 + WASH, /* o: got eob, possibly still output waiting */ 26 + END, /* x: got eob and all data flushed */ 27 + BADCODE} /* x: got error */ 28 +inflate_codes_mode; 29 + 30 +/* inflate codes private state */ 31 +struct inflate_codes_state { 32 + 33 + /* mode */ 34 + inflate_codes_mode mode; /* current inflate_codes mode */ 35 + 36 + /* mode dependent information */ 37 + uInt len; 38 + union { 39 + struct { 40 + inflate_huft *tree; /* pointer into tree */ 41 + uInt need; /* bits needed */ 42 + } code; /* if LEN or DIST, where in tree */ 43 + uInt lit; /* if LIT, literal */ 44 + struct { 45 + uInt get; /* bits to get for extra */ 46 + uInt dist; /* distance back to copy from */ 47 + } copy; /* if EXT or COPY, where and how much */ 48 + } sub; /* submode */ 49 + 50 + /* mode independent information */ 51 + Byte lbits; /* ltree bits decoded per branch */ 52 + Byte dbits; /* dtree bits decoder per branch */ 53 + inflate_huft *ltree; /* literal/length/eob tree */ 54 + inflate_huft *dtree; /* distance tree */ 55 + 56 +}; 57 + 58 + 59 +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) 60 +uInt bl, bd; 61 +inflate_huft *tl; 62 +inflate_huft *td; /* need separate declaration for Borland C++ */ 63 +z_streamp z; 64 +{ 65 + inflate_codes_statef *c; 66 + 67 + if ((c = (inflate_codes_statef *) 68 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) 69 + { 70 + c->mode = START; 71 + c->lbits = (Byte)bl; 72 + c->dbits = (Byte)bd; 73 + c->ltree = tl; 74 + c->dtree = td; 75 + Tracev((stderr, "inflate: codes new\n")); 76 + } 77 + return c; 78 +} 79 + 80 + 81 +int inflate_codes(s, z, r) 82 +inflate_blocks_statef *s; 83 +z_streamp z; 84 +int r; 85 +{ 86 + uInt j; /* temporary storage */ 87 + inflate_huft *t; /* temporary pointer */ 88 + uInt e; /* extra bits or operation */ 89 + uLong b; /* bit buffer */ 90 + uInt k; /* bits in bit buffer */ 91 + Bytef *p; /* input data pointer */ 92 + uInt n; /* bytes available there */ 93 + Bytef *q; /* output window write pointer */ 94 + uInt m; /* bytes to end of window or read pointer */ 95 + Bytef *f; /* pointer to copy strings from */ 96 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ 97 + 98 + /* copy input/output information to locals (UPDATE macro restores) */ 99 + LOAD 100 + 101 + /* process input and output based on current state */ 102 + while (1) switch (c->mode) 103 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 104 + case START: /* x: set up for LEN */ 105 +#ifndef SLOW 106 + if (m >= 258 && n >= 10) 107 + { 108 + UPDATE 109 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); 110 + LOAD 111 + if (r != Z_OK) 112 + { 113 + c->mode = r == Z_STREAM_END ? WASH : BADCODE; 114 + break; 115 + } 116 + } 117 +#endif /* !SLOW */ 118 + c->sub.code.need = c->lbits; 119 + c->sub.code.tree = c->ltree; 120 + c->mode = LEN; 121 + case LEN: /* i: get length/literal/eob next */ 122 + j = c->sub.code.need; 123 + NEEDBITS(j) 124 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); 125 + DUMPBITS(t->bits) 126 + e = (uInt)(t->exop); 127 + if (e == 0) /* literal */ 128 + { 129 + c->sub.lit = t->base; 130 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? 131 + "inflate: literal '%c'\n" : 132 + "inflate: literal 0x%02x\n", t->base)); 133 + c->mode = LIT; 134 + break; 135 + } 136 + if (e & 16) /* length */ 137 + { 138 + c->sub.copy.get = e & 15; 139 + c->len = t->base; 140 + c->mode = LENEXT; 141 + break; 142 + } 143 + if ((e & 64) == 0) /* next table */ 144 + { 145 + c->sub.code.need = e; 146 + c->sub.code.tree = t + t->base; 147 + break; 148 + } 149 + if (e & 32) /* end of block */ 150 + { 151 + Tracevv((stderr, "inflate: end of block\n")); 152 + c->mode = WASH; 153 + break; 154 + } 155 + c->mode = BADCODE; /* invalid code */ 156 + z->msg = (char*)"invalid literal/length code"; 157 + r = Z_DATA_ERROR; 158 + LEAVE 159 + case LENEXT: /* i: getting length extra (have base) */ 160 + j = c->sub.copy.get; 161 + NEEDBITS(j) 162 + c->len += (uInt)b & inflate_mask[j]; 163 + DUMPBITS(j) 164 + c->sub.code.need = c->dbits; 165 + c->sub.code.tree = c->dtree; 166 + Tracevv((stderr, "inflate: length %u\n", c->len)); 167 + c->mode = DIST; 168 + case DIST: /* i: get distance next */ 169 + j = c->sub.code.need; 170 + NEEDBITS(j) 171 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); 172 + DUMPBITS(t->bits) 173 + e = (uInt)(t->exop); 174 + if (e & 16) /* distance */ 175 + { 176 + c->sub.copy.get = e & 15; 177 + c->sub.copy.dist = t->base; 178 + c->mode = DISTEXT; 179 + break; 180 + } 181 + if ((e & 64) == 0) /* next table */ 182 + { 183 + c->sub.code.need = e; 184 + c->sub.code.tree = t + t->base; 185 + break; 186 + } 187 + c->mode = BADCODE; /* invalid code */ 188 + z->msg = (char*)"invalid distance code"; 189 + r = Z_DATA_ERROR; 190 + LEAVE 191 + case DISTEXT: /* i: getting distance extra */ 192 + j = c->sub.copy.get; 193 + NEEDBITS(j) 194 + c->sub.copy.dist += (uInt)b & inflate_mask[j]; 195 + DUMPBITS(j) 196 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); 197 + c->mode = COPY; 198 + case COPY: /* o: copying bytes in window, waiting for space */ 199 +#ifndef __TURBOC__ /* Turbo C bug for following expression */ 200 + f = (uInt)(q - s->window) < c->sub.copy.dist ? 201 + s->end - (c->sub.copy.dist - (q - s->window)) : 202 + q - c->sub.copy.dist; 203 +#else 204 + f = q - c->sub.copy.dist; 205 + if ((uInt)(q - s->window) < c->sub.copy.dist) 206 + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); 207 +#endif 208 + while (c->len) 209 + { 210 + NEEDOUT 211 + OUTBYTE(*f++) 212 + if (f == s->end) 213 + f = s->window; 214 + c->len--; 215 + } 216 + c->mode = START; 217 + break; 218 + case LIT: /* o: got literal, waiting for output space */ 219 + NEEDOUT 220 + OUTBYTE(c->sub.lit) 221 + c->mode = START; 222 + break; 223 + case WASH: /* o: got eob, possibly more output */ 224 + if (k > 7) /* return unused byte, if any */ 225 + { 226 + Assert(k < 16, "inflate_codes grabbed too many bytes") 227 + k -= 8; 228 + n++; 229 + p--; /* can always return one */ 230 + } 231 + FLUSH 232 + if (s->read != s->write) 233 + LEAVE 234 + c->mode = END; 235 + case END: 236 + r = Z_STREAM_END; 237 + LEAVE 238 + case BADCODE: /* x: got error */ 239 + r = Z_DATA_ERROR; 240 + LEAVE 241 + default: 242 + r = Z_STREAM_ERROR; 243 + LEAVE 244 + } 245 +#ifdef NEED_DUMMY_RETURN 246 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 247 +#endif 248 +} 249 + 250 + 251 +void inflate_codes_free(c, z) 252 +inflate_codes_statef *c; 253 +z_streamp z; 254 +{ 255 + ZFREE(z, c); 256 + Tracev((stderr, "inflate: codes free\n")); 257 +}
Added zlib/infcodes.h version [09999e692f41a6c4]
1 +/* infcodes.h -- header to use infcodes.c 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +struct inflate_codes_state; 12 +typedef struct inflate_codes_state FAR inflate_codes_statef; 13 + 14 +extern inflate_codes_statef *inflate_codes_new OF(( 15 + uInt, uInt, 16 + inflate_huft *, inflate_huft *, 17 + z_streamp )); 18 + 19 +extern int inflate_codes OF(( 20 + inflate_blocks_statef *, 21 + z_streamp , 22 + int)); 23 + 24 +extern void inflate_codes_free OF(( 25 + inflate_codes_statef *, 26 + z_streamp )); 27 +
Added zlib/inffast.c version [be35e084d446d347]
1 +/* inffast.c -- process literals and length/distance pairs fast 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "inftrees.h" 8 +#include "infblock.h" 9 +#include "infcodes.h" 10 +#include "infutil.h" 11 +#include "inffast.h" 12 + 13 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ 14 + 15 +/* simplify the use of the inflate_huft type with some defines */ 16 +#define exop word.what.Exop 17 +#define bits word.what.Bits 18 + 19 +/* macros for bit input with no checking and for returning unused bytes */ 20 +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} 21 +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} 22 + 23 +/* Called with number of bytes left to write in window at least 258 24 + (the maximum string length) and number of input bytes available 25 + at least ten. The ten bytes are six bytes for the longest length/ 26 + distance pair plus four bytes for overloading the bit buffer. */ 27 + 28 +int inflate_fast(bl, bd, tl, td, s, z) 29 +uInt bl, bd; 30 +inflate_huft *tl; 31 +inflate_huft *td; /* need separate declaration for Borland C++ */ 32 +inflate_blocks_statef *s; 33 +z_streamp z; 34 +{ 35 + inflate_huft *t; /* temporary pointer */ 36 + uInt e; /* extra bits or operation */ 37 + uLong b; /* bit buffer */ 38 + uInt k; /* bits in bit buffer */ 39 + Bytef *p; /* input data pointer */ 40 + uInt n; /* bytes available there */ 41 + Bytef *q; /* output window write pointer */ 42 + uInt m; /* bytes to end of window or read pointer */ 43 + uInt ml; /* mask for literal/length tree */ 44 + uInt md; /* mask for distance tree */ 45 + uInt c; /* bytes to copy */ 46 + uInt d; /* distance back to copy from */ 47 + Bytef *r; /* copy source pointer */ 48 + 49 + /* load input, output, bit values */ 50 + LOAD 51 + 52 + /* initialize masks */ 53 + ml = inflate_mask[bl]; 54 + md = inflate_mask[bd]; 55 + 56 + /* do until not enough input or output space for fast loop */ 57 + do { /* assume called with m >= 258 && n >= 10 */ 58 + /* get literal/length code */ 59 + GRABBITS(20) /* max bits for literal/length code */ 60 + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) 61 + { 62 + DUMPBITS(t->bits) 63 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? 64 + "inflate: * literal '%c'\n" : 65 + "inflate: * literal 0x%02x\n", t->base)); 66 + *q++ = (Byte)t->base; 67 + m--; 68 + continue; 69 + } 70 + do { 71 + DUMPBITS(t->bits) 72 + if (e & 16) 73 + { 74 + /* get extra bits for length */ 75 + e &= 15; 76 + c = t->base + ((uInt)b & inflate_mask[e]); 77 + DUMPBITS(e) 78 + Tracevv((stderr, "inflate: * length %u\n", c)); 79 + 80 + /* decode distance base of block to copy */ 81 + GRABBITS(15); /* max bits for distance code */ 82 + e = (t = td + ((uInt)b & md))->exop; 83 + do { 84 + DUMPBITS(t->bits) 85 + if (e & 16) 86 + { 87 + /* get extra bits to add to distance base */ 88 + e &= 15; 89 + GRABBITS(e) /* get extra bits (up to 13) */ 90 + d = t->base + ((uInt)b & inflate_mask[e]); 91 + DUMPBITS(e) 92 + Tracevv((stderr, "inflate: * distance %u\n", d)); 93 + 94 + /* do the copy */ 95 + m -= c; 96 + if ((uInt)(q - s->window) >= d) /* offset before dest */ 97 + { /* just copy */ 98 + r = q - d; 99 + *q++ = *r++; c--; /* minimum count is three, */ 100 + *q++ = *r++; c--; /* so unroll loop a little */ 101 + } 102 + else /* else offset after destination */ 103 + { 104 + e = d - (uInt)(q - s->window); /* bytes from offset to end */ 105 + r = s->end - e; /* pointer to offset */ 106 + if (c > e) /* if source crosses, */ 107 + { 108 + c -= e; /* copy to end of window */ 109 + do { 110 + *q++ = *r++; 111 + } while (--e); 112 + r = s->window; /* copy rest from start of window */ 113 + } 114 + } 115 + do { /* copy all or what's left */ 116 + *q++ = *r++; 117 + } while (--c); 118 + break; 119 + } 120 + else if ((e & 64) == 0) 121 + { 122 + t += t->base; 123 + e = (t += ((uInt)b & inflate_mask[e]))->exop; 124 + } 125 + else 126 + { 127 + z->msg = (char*)"invalid distance code"; 128 + UNGRAB 129 + UPDATE 130 + return Z_DATA_ERROR; 131 + } 132 + } while (1); 133 + break; 134 + } 135 + if ((e & 64) == 0) 136 + { 137 + t += t->base; 138 + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) 139 + { 140 + DUMPBITS(t->bits) 141 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? 142 + "inflate: * literal '%c'\n" : 143 + "inflate: * literal 0x%02x\n", t->base)); 144 + *q++ = (Byte)t->base; 145 + m--; 146 + break; 147 + } 148 + } 149 + else if (e & 32) 150 + { 151 + Tracevv((stderr, "inflate: * end of block\n")); 152 + UNGRAB 153 + UPDATE 154 + return Z_STREAM_END; 155 + } 156 + else 157 + { 158 + z->msg = (char*)"invalid literal/length code"; 159 + UNGRAB 160 + UPDATE 161 + return Z_DATA_ERROR; 162 + } 163 + } while (1); 164 + } while (m >= 258 && n >= 10); 165 + 166 + /* not enough input or output--restore pointers and return */ 167 + UNGRAB 168 + UPDATE 169 + return Z_OK; 170 +}
Added zlib/inffast.h version [06be59e81b93f24a]
1 +/* inffast.h -- header to use inffast.c 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +extern int inflate_fast OF(( 12 + uInt, 13 + uInt, 14 + inflate_huft *, 15 + inflate_huft *, 16 + inflate_blocks_statef *, 17 + z_streamp ));
Added zlib/inffixed.h version [37c7e4d778b4b959]
1 +/* inffixed.h -- table for decoding fixed codes 2 + * Generated automatically by the maketree.c program 3 + */ 4 + 5 +/* WARNING: this file should *not* be used by applications. It is 6 + part of the implementation of the compression library and is 7 + subject to change. Applications should only use zlib.h. 8 + */ 9 + 10 +local uInt fixed_bl = 9; 11 +local uInt fixed_bd = 5; 12 +local inflate_huft fixed_tl[] = { 13 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, 14 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, 15 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, 16 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, 17 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, 18 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, 19 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, 20 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, 21 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, 22 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, 23 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, 24 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, 25 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, 26 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, 27 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, 28 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, 29 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, 30 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, 31 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, 32 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, 33 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, 34 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, 35 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, 36 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, 37 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, 38 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, 39 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, 40 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, 41 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, 42 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, 43 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, 44 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, 45 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, 46 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, 47 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, 48 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, 49 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, 50 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, 51 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, 52 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, 53 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, 54 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, 55 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, 56 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, 57 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, 58 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, 59 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, 60 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, 61 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, 62 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, 63 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, 64 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, 65 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, 66 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, 67 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, 68 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, 69 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, 70 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, 71 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, 72 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, 73 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, 74 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, 75 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, 76 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, 77 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, 78 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, 79 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, 80 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, 81 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, 82 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, 83 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, 84 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, 85 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, 86 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, 87 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, 88 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, 89 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, 90 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, 91 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, 92 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, 93 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, 94 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, 95 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, 96 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, 97 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, 98 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, 99 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, 100 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, 101 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, 102 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, 103 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, 104 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, 105 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, 106 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, 107 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, 108 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, 109 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, 110 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, 111 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, 112 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, 113 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, 114 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, 115 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, 116 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, 117 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, 118 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, 119 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, 120 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, 121 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, 122 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, 123 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, 124 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, 125 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, 126 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, 127 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, 128 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, 129 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, 130 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, 131 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, 132 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, 133 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, 134 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, 135 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, 136 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, 137 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, 138 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, 139 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, 140 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} 141 + }; 142 +local inflate_huft fixed_td[] = { 143 + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, 144 + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, 145 + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, 146 + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, 147 + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, 148 + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, 149 + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, 150 + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} 151 + };
Added zlib/inflate.c version [75455827897c3024]
1 +/* inflate.c -- zlib interface to inflate modules 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "infblock.h" 8 + 9 +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ 10 + 11 +typedef enum { 12 + METHOD, /* waiting for method byte */ 13 + FLAG, /* waiting for flag byte */ 14 + DICT4, /* four dictionary check bytes to go */ 15 + DICT3, /* three dictionary check bytes to go */ 16 + DICT2, /* two dictionary check bytes to go */ 17 + DICT1, /* one dictionary check byte to go */ 18 + DICT0, /* waiting for inflateSetDictionary */ 19 + BLOCKS, /* decompressing blocks */ 20 + CHECK4, /* four check bytes to go */ 21 + CHECK3, /* three check bytes to go */ 22 + CHECK2, /* two check bytes to go */ 23 + CHECK1, /* one check byte to go */ 24 + DONE, /* finished check, done */ 25 + BAD} /* got an error--stay here */ 26 +inflate_mode; 27 + 28 +/* inflate private state */ 29 +struct internal_state { 30 + 31 + /* mode */ 32 + inflate_mode mode; /* current inflate mode */ 33 + 34 + /* mode dependent information */ 35 + union { 36 + uInt method; /* if FLAGS, method byte */ 37 + struct { 38 + uLong was; /* computed check value */ 39 + uLong need; /* stream check value */ 40 + } check; /* if CHECK, check values to compare */ 41 + uInt marker; /* if BAD, inflateSync's marker bytes count */ 42 + } sub; /* submode */ 43 + 44 + /* mode independent information */ 45 + int nowrap; /* flag for no wrapper */ 46 + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 47 + inflate_blocks_statef 48 + *blocks; /* current inflate_blocks state */ 49 + 50 +}; 51 + 52 + 53 +int ZEXPORT inflateReset(z) 54 +z_streamp z; 55 +{ 56 + if (z == Z_NULL || z->state == Z_NULL) 57 + return Z_STREAM_ERROR; 58 + z->total_in = z->total_out = 0; 59 + z->msg = Z_NULL; 60 + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 61 + inflate_blocks_reset(z->state->blocks, z, Z_NULL); 62 + Tracev((stderr, "inflate: reset\n")); 63 + return Z_OK; 64 +} 65 + 66 + 67 +int ZEXPORT inflateEnd(z) 68 +z_streamp z; 69 +{ 70 + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) 71 + return Z_STREAM_ERROR; 72 + if (z->state->blocks != Z_NULL) 73 + inflate_blocks_free(z->state->blocks, z); 74 + ZFREE(z, z->state); 75 + z->state = Z_NULL; 76 + Tracev((stderr, "inflate: end\n")); 77 + return Z_OK; 78 +} 79 + 80 + 81 +int ZEXPORT inflateInit2_(z, w, version, stream_size) 82 +z_streamp z; 83 +int w; 84 +const char *version; 85 +int stream_size; 86 +{ 87 + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 88 + stream_size != sizeof(z_stream)) 89 + return Z_VERSION_ERROR; 90 + 91 + /* initialize state */ 92 + if (z == Z_NULL) 93 + return Z_STREAM_ERROR; 94 + z->msg = Z_NULL; 95 + if (z->zalloc == Z_NULL) 96 + { 97 + z->zalloc = zcalloc; 98 + z->opaque = (voidpf)0; 99 + } 100 + if (z->zfree == Z_NULL) z->zfree = zcfree; 101 + if ((z->state = (struct internal_state FAR *) 102 + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) 103 + return Z_MEM_ERROR; 104 + z->state->blocks = Z_NULL; 105 + 106 + /* handle undocumented nowrap option (no zlib header or check) */ 107 + z->state->nowrap = 0; 108 + if (w < 0) 109 + { 110 + w = - w; 111 + z->state->nowrap = 1; 112 + } 113 + 114 + /* set window size */ 115 + if (w < 8 || w > 15) 116 + { 117 + inflateEnd(z); 118 + return Z_STREAM_ERROR; 119 + } 120 + z->state->wbits = (uInt)w; 121 + 122 + /* create inflate_blocks state */ 123 + if ((z->state->blocks = 124 + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) 125 + == Z_NULL) 126 + { 127 + inflateEnd(z); 128 + return Z_MEM_ERROR; 129 + } 130 + Tracev((stderr, "inflate: allocated\n")); 131 + 132 + /* reset state */ 133 + inflateReset(z); 134 + return Z_OK; 135 +} 136 + 137 + 138 +int ZEXPORT inflateInit_(z, version, stream_size) 139 +z_streamp z; 140 +const char *version; 141 +int stream_size; 142 +{ 143 + return inflateInit2_(z, DEF_WBITS, version, stream_size); 144 +} 145 + 146 + 147 +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} 148 +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 149 + 150 +int ZEXPORT inflate(z, f) 151 +z_streamp z; 152 +int f; 153 +{ 154 + int r; 155 + uInt b; 156 + 157 + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) 158 + return Z_STREAM_ERROR; 159 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 160 + r = Z_BUF_ERROR; 161 + while (1) switch (z->state->mode) 162 + { 163 + case METHOD: 164 + NEEDBYTE 165 + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 166 + { 167 + z->state->mode = BAD; 168 + z->msg = (char*)"unknown compression method"; 169 + z->state->sub.marker = 5; /* can't try inflateSync */ 170 + break; 171 + } 172 + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 173 + { 174 + z->state->mode = BAD; 175 + z->msg = (char*)"invalid window size"; 176 + z->state->sub.marker = 5; /* can't try inflateSync */ 177 + break; 178 + } 179 + z->state->mode = FLAG; 180 + case FLAG: 181 + NEEDBYTE 182 + b = NEXTBYTE; 183 + if (((z->state->sub.method << 8) + b) % 31) 184 + { 185 + z->state->mode = BAD; 186 + z->msg = (char*)"incorrect header check"; 187 + z->state->sub.marker = 5; /* can't try inflateSync */ 188 + break; 189 + } 190 + Tracev((stderr, "inflate: zlib header ok\n")); 191 + if (!(b & PRESET_DICT)) 192 + { 193 + z->state->mode = BLOCKS; 194 + break; 195 + } 196 + z->state->mode = DICT4; 197 + case DICT4: 198 + NEEDBYTE 199 + z->state->sub.check.need = (uLong)NEXTBYTE << 24; 200 + z->state->mode = DICT3; 201 + case DICT3: 202 + NEEDBYTE 203 + z->state->sub.check.need += (uLong)NEXTBYTE << 16; 204 + z->state->mode = DICT2; 205 + case DICT2: 206 + NEEDBYTE 207 + z->state->sub.check.need += (uLong)NEXTBYTE << 8; 208 + z->state->mode = DICT1; 209 + case DICT1: 210 + NEEDBYTE 211 + z->state->sub.check.need += (uLong)NEXTBYTE; 212 + z->adler = z->state->sub.check.need; 213 + z->state->mode = DICT0; 214 + return Z_NEED_DICT; 215 + case DICT0: 216 + z->state->mode = BAD; 217 + z->msg = (char*)"need dictionary"; 218 + z->state->sub.marker = 0; /* can try inflateSync */ 219 + return Z_STREAM_ERROR; 220 + case BLOCKS: 221 + r = inflate_blocks(z->state->blocks, z, r); 222 + if (r == Z_DATA_ERROR) 223 + { 224 + z->state->mode = BAD; 225 + z->state->sub.marker = 0; /* can try inflateSync */ 226 + break; 227 + } 228 + if (r == Z_OK) 229 + r = f; 230 + if (r != Z_STREAM_END) 231 + return r; 232 + r = f; 233 + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 234 + if (z->state->nowrap) 235 + { 236 + z->state->mode = DONE; 237 + break; 238 + } 239 + z->state->mode = CHECK4; 240 + case CHECK4: 241 + NEEDBYTE 242 + z->state->sub.check.need = (uLong)NEXTBYTE << 24; 243 + z->state->mode = CHECK3; 244 + case CHECK3: 245 + NEEDBYTE 246 + z->state->sub.check.need += (uLong)NEXTBYTE << 16; 247 + z->state->mode = CHECK2; 248 + case CHECK2: 249 + NEEDBYTE 250 + z->state->sub.check.need += (uLong)NEXTBYTE << 8; 251 + z->state->mode = CHECK1; 252 + case CHECK1: 253 + NEEDBYTE 254 + z->state->sub.check.need += (uLong)NEXTBYTE; 255 + 256 + if (z->state->sub.check.was != z->state->sub.check.need) 257 + { 258 + z->state->mode = BAD; 259 + z->msg = (char*)"incorrect data check"; 260 + z->state->sub.marker = 5; /* can't try inflateSync */ 261 + break; 262 + } 263 + Tracev((stderr, "inflate: zlib check ok\n")); 264 + z->state->mode = DONE; 265 + case DONE: 266 + return Z_STREAM_END; 267 + case BAD: 268 + return Z_DATA_ERROR; 269 + default: 270 + return Z_STREAM_ERROR; 271 + } 272 +#ifdef NEED_DUMMY_RETURN 273 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 274 +#endif 275 +} 276 + 277 + 278 +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) 279 +z_streamp z; 280 +const Bytef *dictionary; 281 +uInt dictLength; 282 +{ 283 + uInt length = dictLength; 284 + 285 + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) 286 + return Z_STREAM_ERROR; 287 + 288 + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; 289 + z->adler = 1L; 290 + 291 + if (length >= ((uInt)1<<z->state->wbits)) 292 + { 293 + length = (1<<z->state->wbits)-1; 294 + dictionary += dictLength - length; 295 + } 296 + inflate_set_dictionary(z->state->blocks, dictionary, length); 297 + z->state->mode = BLOCKS; 298 + return Z_OK; 299 +} 300 + 301 + 302 +int ZEXPORT inflateSync(z) 303 +z_streamp z; 304 +{ 305 + uInt n; /* number of bytes to look at */ 306 + Bytef *p; /* pointer to bytes */ 307 + uInt m; /* number of marker bytes found in a row */ 308 + uLong r, w; /* temporaries to save total_in and total_out */ 309 + 310 + /* set up */ 311 + if (z == Z_NULL || z->state == Z_NULL) 312 + return Z_STREAM_ERROR; 313 + if (z->state->mode != BAD) 314 + { 315 + z->state->mode = BAD; 316 + z->state->sub.marker = 0; 317 + } 318 + if ((n = z->avail_in) == 0) 319 + return Z_BUF_ERROR; 320 + p = z->next_in; 321 + m = z->state->sub.marker; 322 + 323 + /* search */ 324 + while (n && m < 4) 325 + { 326 + static const Byte mark[4] = {0, 0, 0xff, 0xff}; 327 + if (*p == mark[m]) 328 + m++; 329 + else if (*p) 330 + m = 0; 331 + else 332 + m = 4 - m; 333 + p++, n--; 334 + } 335 + 336 + /* restore */ 337 + z->total_in += p - z->next_in; 338 + z->next_in = p; 339 + z->avail_in = n; 340 + z->state->sub.marker = m; 341 + 342 + /* return no joy or set up to restart on a new block */ 343 + if (m != 4) 344 + return Z_DATA_ERROR; 345 + r = z->total_in; w = z->total_out; 346 + inflateReset(z); 347 + z->total_in = r; z->total_out = w; 348 + z->state->mode = BLOCKS; 349 + return Z_OK; 350 +} 351 + 352 + 353 +/* Returns true if inflate is currently at the end of a block generated 354 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 355 + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH 356 + * but removes the length bytes of the resulting empty stored block. When 357 + * decompressing, PPP checks that at the end of input packet, inflate is 358 + * waiting for these length bytes. 359 + */ 360 +int ZEXPORT inflateSyncPoint(z) 361 +z_streamp z; 362 +{ 363 + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) 364 + return Z_STREAM_ERROR; 365 + return inflate_blocks_sync_point(z->state->blocks); 366 +}
Added zlib/inftrees.c version [73a9ed700002c269]
1 +/* inftrees.c -- generate Huffman trees for efficient decoding 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "inftrees.h" 8 + 9 +#if !defined(BUILDFIXED) && !defined(STDC) 10 +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ 11 +#endif 12 + 13 +const char inflate_copyright[] = 14 + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; 15 +/* 16 + If you use the zlib library in a product, an acknowledgment is welcome 17 + in the documentation of your product. If for some reason you cannot 18 + include such an acknowledgment, I would appreciate that you keep this 19 + copyright string in the executable of your product. 20 + */ 21 +struct internal_state {int dummy;}; /* for buggy compilers */ 22 + 23 +/* simplify the use of the inflate_huft type with some defines */ 24 +#define exop word.what.Exop 25 +#define bits word.what.Bits 26 + 27 + 28 +local int huft_build OF(( 29 + uIntf *, /* code lengths in bits */ 30 + uInt, /* number of codes */ 31 + uInt, /* number of "simple" codes */ 32 + const uIntf *, /* list of base values for non-simple codes */ 33 + const uIntf *, /* list of extra bits for non-simple codes */ 34 + inflate_huft * FAR*,/* result: starting table */ 35 + uIntf *, /* maximum lookup bits (returns actual) */ 36 + inflate_huft *, /* space for trees */ 37 + uInt *, /* hufts used in space */ 38 + uIntf * )); /* space for values */ 39 + 40 +/* Tables for deflate from PKZIP's appnote.txt. */ 41 +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ 42 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 43 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 44 + /* see note #13 above about 258 */ 45 +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ 46 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 47 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ 48 +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 49 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 50 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 51 + 8193, 12289, 16385, 24577}; 52 +local const uInt cpdext[30] = { /* Extra bits for distance codes */ 53 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 54 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 55 + 12, 12, 13, 13}; 56 + 57 +/* 58 + Huffman code decoding is performed using a multi-level table lookup. 59 + The fastest way to decode is to simply build a lookup table whose 60 + size is determined by the longest code. However, the time it takes 61 + to build this table can also be a factor if the data being decoded 62 + is not very long. The most common codes are necessarily the 63 + shortest codes, so those codes dominate the decoding time, and hence 64 + the speed. The idea is you can have a shorter table that decodes the 65 + shorter, more probable codes, and then point to subsidiary tables for 66 + the longer codes. The time it costs to decode the longer codes is 67 + then traded against the time it takes to make longer tables. 68 + 69 + This results of this trade are in the variables lbits and dbits 70 + below. lbits is the number of bits the first level table for literal/ 71 + length codes can decode in one step, and dbits is the same thing for 72 + the distance codes. Subsequent tables are also less than or equal to 73 + those sizes. These values may be adjusted either when all of the 74 + codes are shorter than that, in which case the longest code length in 75 + bits is used, or when the shortest code is *longer* than the requested 76 + table size, in which case the length of the shortest code in bits is 77 + used. 78 + 79 + There are two different values for the two tables, since they code a 80 + different number of possibilities each. The literal/length table 81 + codes 286 possible values, or in a flat code, a little over eight 82 + bits. The distance table codes 30 possible values, or a little less 83 + than five bits, flat. The optimum values for speed end up being 84 + about one bit more than those, so lbits is 8+1 and dbits is 5+1. 85 + The optimum values may differ though from machine to machine, and 86 + possibly even between compilers. Your mileage may vary. 87 + */ 88 + 89 + 90 +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ 91 +#define BMAX 15 /* maximum bit length of any code */ 92 + 93 +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) 94 +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ 95 +uInt n; /* number of codes (assumed <= 288) */ 96 +uInt s; /* number of simple-valued codes (0..s-1) */ 97 +const uIntf *d; /* list of base values for non-simple codes */ 98 +const uIntf *e; /* list of extra bits for non-simple codes */ 99 +inflate_huft * FAR *t; /* result: starting table */ 100 +uIntf *m; /* maximum lookup bits, returns actual */ 101 +inflate_huft *hp; /* space for trees */ 102 +uInt *hn; /* hufts used in space */ 103 +uIntf *v; /* working area: values in order of bit length */ 104 +/* Given a list of code lengths and a maximum table size, make a set of 105 + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR 106 + if the given code set is incomplete (the tables are still built in this 107 + case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of 108 + lengths), or Z_MEM_ERROR if not enough memory. */ 109 +{ 110 + 111 + uInt a; /* counter for codes of length k */ 112 + uInt c[BMAX+1]; /* bit length count table */ 113 + uInt f; /* i repeats in table every f entries */ 114 + int g; /* maximum code length */ 115 + int h; /* table level */ 116 + register uInt i; /* counter, current code */ 117 + register uInt j; /* counter */ 118 + register int k; /* number of bits in current code */ 119 + int l; /* bits per table (returned in m) */ 120 + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ 121 + register uIntf *p; /* pointer into c[], b[], or v[] */ 122 + inflate_huft *q; /* points to current table */ 123 + struct inflate_huft_s r; /* table entry for structure assignment */ 124 + inflate_huft *u[BMAX]; /* table stack */ 125 + register int w; /* bits before this table == (l * h) */ 126 + uInt x[BMAX+1]; /* bit offsets, then code stack */ 127 + uIntf *xp; /* pointer into x */ 128 + int y; /* number of dummy codes added */ 129 + uInt z; /* number of entries in current table */ 130 + 131 + 132 + /* Generate counts for each bit length */ 133 + p = c; 134 +#define C0 *p++ = 0; 135 +#define C2 C0 C0 C0 C0 136 +#define C4 C2 C2 C2 C2 137 + C4 /* clear c[]--assume BMAX+1 is 16 */ 138 + p = b; i = n; 139 + do { 140 + c[*p++]++; /* assume all entries <= BMAX */ 141 + } while (--i); 142 + if (c[0] == n) /* null input--all zero length codes */ 143 + { 144 + *t = (inflate_huft *)Z_NULL; 145 + *m = 0; 146 + return Z_OK; 147 + } 148 + 149 + 150 + /* Find minimum and maximum length, bound *m by those */ 151 + l = *m; 152 + for (j = 1; j <= BMAX; j++) 153 + if (c[j]) 154 + break; 155 + k = j; /* minimum code length */ 156 + if ((uInt)l < j) 157 + l = j; 158 + for (i = BMAX; i; i--) 159 + if (c[i]) 160 + break; 161 + g = i; /* maximum code length */ 162 + if ((uInt)l > i) 163 + l = i; 164 + *m = l; 165 + 166 + 167 + /* Adjust last length count to fill out codes, if needed */ 168 + for (y = 1 << j; j < i; j++, y <<= 1) 169 + if ((y -= c[j]) < 0) 170 + return Z_DATA_ERROR; 171 + if ((y -= c[i]) < 0) 172 + return Z_DATA_ERROR; 173 + c[i] += y; 174 + 175 + 176 + /* Generate starting offsets into the value table for each length */ 177 + x[1] = j = 0; 178 + p = c + 1; xp = x + 2; 179 + while (--i) { /* note that i == g from above */ 180 + *xp++ = (j += *p++); 181 + } 182 + 183 + 184 + /* Make a table of values in order of bit lengths */ 185 + p = b; i = 0; 186 + do { 187 + if ((j = *p++) != 0) 188 + v[x[j]++] = i; 189 + } while (++i < n); 190 + n = x[g]; /* set n to length of v */ 191 + 192 + 193 + /* Generate the Huffman codes and for each, make the table entries */ 194 + x[0] = i = 0; /* first Huffman code is zero */ 195 + p = v; /* grab values in bit order */ 196 + h = -1; /* no tables yet--level -1 */ 197 + w = -l; /* bits decoded == (l * h) */ 198 + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ 199 + q = (inflate_huft *)Z_NULL; /* ditto */ 200 + z = 0; /* ditto */ 201 + 202 + /* go through the bit lengths (k already is bits in shortest code) */ 203 + for (; k <= g; k++) 204 + { 205 + a = c[k]; 206 + while (a--) 207 + { 208 + /* here i is the Huffman code of length k bits for value *p */ 209 + /* make tables up to required level */ 210 + while (k > w + l) 211 + { 212 + h++; 213 + w += l; /* previous table always l bits */ 214 + 215 + /* compute minimum size table less than or equal to l bits */ 216 + z = g - w; 217 + z = z > (uInt)l ? l : z; /* table size upper limit */ 218 + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ 219 + { /* too few codes for k-w bit table */ 220 + f -= a + 1; /* deduct codes from patterns left */ 221 + xp = c + k; 222 + if (j < z) 223 + while (++j < z) /* try smaller tables up to z bits */ 224 + { 225 + if ((f <<= 1) <= *++xp) 226 + break; /* enough codes to use up j bits */ 227 + f -= *xp; /* else deduct codes from patterns */ 228 + } 229 + } 230 + z = 1 << j; /* table entries for j-bit table */ 231 + 232 + /* allocate new table */ 233 + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ 234 + return Z_MEM_ERROR; /* not enough memory */ 235 + u[h] = q = hp + *hn; 236 + *hn += z; 237 + 238 + /* connect to last table, if there is one */ 239 + if (h) 240 + { 241 + x[h] = i; /* save pattern for backing up */ 242 + r.bits = (Byte)l; /* bits to dump before this table */ 243 + r.exop = (Byte)j; /* bits in this table */ 244 + j = i >> (w - l); 245 + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ 246 + u[h-1][j] = r; /* connect to last table */ 247 + } 248 + else 249 + *t = q; /* first table is returned result */ 250 + } 251 + 252 + /* set up table entry in r */ 253 + r.bits = (Byte)(k - w); 254 + if (p >= v + n) 255 + r.exop = 128 + 64; /* out of values--invalid code */ 256 + else if (*p < s) 257 + { 258 + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ 259 + r.base = *p++; /* simple code is just the value */ 260 + } 261 + else 262 + { 263 + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ 264 + r.base = d[*p++ - s]; 265 + } 266 + 267 + /* fill code-like entries with r */ 268 + f = 1 << (k - w); 269 + for (j = i >> w; j < z; j += f) 270 + q[j] = r; 271 + 272 + /* backwards increment the k-bit code i */ 273 + for (j = 1 << (k - 1); i & j; j >>= 1) 274 + i ^= j; 275 + i ^= j; 276 + 277 + /* backup over finished tables */ 278 + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ 279 + while ((i & mask) != x[h]) 280 + { 281 + h--; /* don't need to update q */ 282 + w -= l; 283 + mask = (1 << w) - 1; 284 + } 285 + } 286 + } 287 + 288 + 289 + /* Return Z_BUF_ERROR if we were given an incomplete table */ 290 + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; 291 +} 292 + 293 + 294 +int inflate_trees_bits(c, bb, tb, hp, z) 295 +uIntf *c; /* 19 code lengths */ 296 +uIntf *bb; /* bits tree desired/actual depth */ 297 +inflate_huft * FAR *tb; /* bits tree result */ 298 +inflate_huft *hp; /* space for trees */ 299 +z_streamp z; /* for messages */ 300 +{ 301 + int r; 302 + uInt hn = 0; /* hufts used in space */ 303 + uIntf *v; /* work area for huft_build */ 304 + 305 + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) 306 + return Z_MEM_ERROR; 307 + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, 308 + tb, bb, hp, &hn, v); 309 + if (r == Z_DATA_ERROR) 310 + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; 311 + else if (r == Z_BUF_ERROR || *bb == 0) 312 + { 313 + z->msg = (char*)"incomplete dynamic bit lengths tree"; 314 + r = Z_DATA_ERROR; 315 + } 316 + ZFREE(z, v); 317 + return r; 318 +} 319 + 320 + 321 +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) 322 +uInt nl; /* number of literal/length codes */ 323 +uInt nd; /* number of distance codes */ 324 +uIntf *c; /* that many (total) code lengths */ 325 +uIntf *bl; /* literal desired/actual bit depth */ 326 +uIntf *bd; /* distance desired/actual bit depth */ 327 +inflate_huft * FAR *tl; /* literal/length tree result */ 328 +inflate_huft * FAR *td; /* distance tree result */ 329 +inflate_huft *hp; /* space for trees */ 330 +z_streamp z; /* for messages */ 331 +{ 332 + int r; 333 + uInt hn = 0; /* hufts used in space */ 334 + uIntf *v; /* work area for huft_build */ 335 + 336 + /* allocate work area */ 337 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) 338 + return Z_MEM_ERROR; 339 + 340 + /* build literal/length tree */ 341 + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); 342 + if (r != Z_OK || *bl == 0) 343 + { 344 + if (r == Z_DATA_ERROR) 345 + z->msg = (char*)"oversubscribed literal/length tree"; 346 + else if (r != Z_MEM_ERROR) 347 + { 348 + z->msg = (char*)"incomplete literal/length tree"; 349 + r = Z_DATA_ERROR; 350 + } 351 + ZFREE(z, v); 352 + return r; 353 + } 354 + 355 + /* build distance tree */ 356 + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); 357 + if (r != Z_OK || (*bd == 0 && nl > 257)) 358 + { 359 + if (r == Z_DATA_ERROR) 360 + z->msg = (char*)"oversubscribed distance tree"; 361 + else if (r == Z_BUF_ERROR) { 362 +#ifdef PKZIP_BUG_WORKAROUND 363 + r = Z_OK; 364 + } 365 +#else 366 + z->msg = (char*)"incomplete distance tree"; 367 + r = Z_DATA_ERROR; 368 + } 369 + else if (r != Z_MEM_ERROR) 370 + { 371 + z->msg = (char*)"empty distance tree with lengths"; 372 + r = Z_DATA_ERROR; 373 + } 374 + ZFREE(z, v); 375 + return r; 376 +#endif 377 + } 378 + 379 + /* done */ 380 + ZFREE(z, v); 381 + return Z_OK; 382 +} 383 + 384 + 385 +/* build fixed tables only once--keep them here */ 386 +#ifdef BUILDFIXED 387 +local int fixed_built = 0; 388 +#define FIXEDH 544 /* number of hufts used by fixed tables */ 389 +local inflate_huft fixed_mem[FIXEDH]; 390 +local uInt fixed_bl; 391 +local uInt fixed_bd; 392 +local inflate_huft *fixed_tl; 393 +local inflate_huft *fixed_td; 394 +#else 395 +#include "inffixed.h" 396 +#endif 397 + 398 + 399 +int inflate_trees_fixed(bl, bd, tl, td, z) 400 +uIntf *bl; /* literal desired/actual bit depth */ 401 +uIntf *bd; /* distance desired/actual bit depth */ 402 +inflate_huft * FAR *tl; /* literal/length tree result */ 403 +inflate_huft * FAR *td; /* distance tree result */ 404 +z_streamp z; /* for memory allocation */ 405 +{ 406 +#ifdef BUILDFIXED 407 + /* build fixed tables if not already */ 408 + if (!fixed_built) 409 + { 410 + int k; /* temporary variable */ 411 + uInt f = 0; /* number of hufts used in fixed_mem */ 412 + uIntf *c; /* length list for huft_build */ 413 + uIntf *v; /* work area for huft_build */ 414 + 415 + /* allocate memory */ 416 + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) 417 + return Z_MEM_ERROR; 418 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) 419 + { 420 + ZFREE(z, c); 421 + return Z_MEM_ERROR; 422 + } 423 + 424 + /* literal table */ 425 + for (k = 0; k < 144; k++) 426 + c[k] = 8; 427 + for (; k < 256; k++) 428 + c[k] = 9; 429 + for (; k < 280; k++) 430 + c[k] = 7; 431 + for (; k < 288; k++) 432 + c[k] = 8; 433 + fixed_bl = 9; 434 + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, 435 + fixed_mem, &f, v); 436 + 437 + /* distance table */ 438 + for (k = 0; k < 30; k++) 439 + c[k] = 5; 440 + fixed_bd = 5; 441 + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, 442 + fixed_mem, &f, v); 443 + 444 + /* done */ 445 + ZFREE(z, v); 446 + ZFREE(z, c); 447 + fixed_built = 1; 448 + } 449 +#endif 450 + *bl = fixed_bl; 451 + *bd = fixed_bd; 452 + *tl = fixed_tl; 453 + *td = fixed_td; 454 + return Z_OK; 455 +}
Added zlib/inftrees.h version [2f831281d83bb995]
1 +/* inftrees.h -- header to use inftrees.c 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +/* Huffman code lookup table entry--this entry is four bytes for machines 12 + that have 16-bit pointers (e.g. PC's in the small or medium model). */ 13 + 14 +typedef struct inflate_huft_s FAR inflate_huft; 15 + 16 +struct inflate_huft_s { 17 + union { 18 + struct { 19 + Byte Exop; /* number of extra bits or operation */ 20 + Byte Bits; /* number of bits in this code or subcode */ 21 + } what; 22 + uInt pad; /* pad structure to a power of 2 (4 bytes for */ 23 + } word; /* 16-bit, 8 bytes for 32-bit int's) */ 24 + uInt base; /* literal, length base, distance base, 25 + or table offset */ 26 +}; 27 + 28 +/* Maximum size of dynamic tree. The maximum found in a long but non- 29 + exhaustive search was 1004 huft structures (850 for length/literals 30 + and 154 for distances, the latter actually the result of an 31 + exhaustive search). The actual maximum is not known, but the 32 + value below is more than safe. */ 33 +#define MANY 1440 34 + 35 +extern int inflate_trees_bits OF(( 36 + uIntf *, /* 19 code lengths */ 37 + uIntf *, /* bits tree desired/actual depth */ 38 + inflate_huft * FAR *, /* bits tree result */ 39 + inflate_huft *, /* space for trees */ 40 + z_streamp)); /* for messages */ 41 + 42 +extern int inflate_trees_dynamic OF(( 43 + uInt, /* number of literal/length codes */ 44 + uInt, /* number of distance codes */ 45 + uIntf *, /* that many (total) code lengths */ 46 + uIntf *, /* literal desired/actual bit depth */ 47 + uIntf *, /* distance desired/actual bit depth */ 48 + inflate_huft * FAR *, /* literal/length tree result */ 49 + inflate_huft * FAR *, /* distance tree result */ 50 + inflate_huft *, /* space for trees */ 51 + z_streamp)); /* for messages */ 52 + 53 +extern int inflate_trees_fixed OF(( 54 + uIntf *, /* literal desired/actual bit depth */ 55 + uIntf *, /* distance desired/actual bit depth */ 56 + inflate_huft * FAR *, /* literal/length tree result */ 57 + inflate_huft * FAR *, /* distance tree result */ 58 + z_streamp)); /* for memory allocation */
Added zlib/infutil.c version [52ba94de56ae84aa]
1 +/* inflate_util.c -- data and routines common to blocks and codes 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +#include "zutil.h" 7 +#include "infblock.h" 8 +#include "inftrees.h" 9 +#include "infcodes.h" 10 +#include "infutil.h" 11 + 12 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ 13 + 14 +/* And'ing with mask[n] masks the lower n bits */ 15 +uInt inflate_mask[17] = { 16 + 0x0000, 17 + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 18 + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff 19 +}; 20 + 21 + 22 +/* copy as much as possible from the sliding window to the output area */ 23 +int inflate_flush(s, z, r) 24 +inflate_blocks_statef *s; 25 +z_streamp z; 26 +int r; 27 +{ 28 + uInt n; 29 + Bytef *p; 30 + Bytef *q; 31 + 32 + /* local copies of source and destination pointers */ 33 + p = z->next_out; 34 + q = s->read; 35 + 36 + /* compute number of bytes to copy as far as end of window */ 37 + n = (uInt)((q <= s->write ? s->write : s->end) - q); 38 + if (n > z->avail_out) n = z->avail_out; 39 + if (n && r == Z_BUF_ERROR) r = Z_OK; 40 + 41 + /* update counters */ 42 + z->avail_out -= n; 43 + z->total_out += n; 44 + 45 + /* update check information */ 46 + if (s->checkfn != Z_NULL) 47 + z->adler = s->check = (*s->checkfn)(s->check, q, n); 48 + 49 + /* copy as far as end of window */ 50 + zmemcpy(p, q, n); 51 + p += n; 52 + q += n; 53 + 54 + /* see if more to copy at beginning of window */ 55 + if (q == s->end) 56 + { 57 + /* wrap pointers */ 58 + q = s->window; 59 + if (s->write == s->end) 60 + s->write = s->window; 61 + 62 + /* compute bytes to copy */ 63 + n = (uInt)(s->write - q); 64 + if (n > z->avail_out) n = z->avail_out; 65 + if (n && r == Z_BUF_ERROR) r = Z_OK; 66 + 67 + /* update counters */ 68 + z->avail_out -= n; 69 + z->total_out += n; 70 + 71 + /* update check information */ 72 + if (s->checkfn != Z_NULL) 73 + z->adler = s->check = (*s->checkfn)(s->check, q, n); 74 + 75 + /* copy */ 76 + zmemcpy(p, q, n); 77 + p += n; 78 + q += n; 79 + } 80 + 81 + /* update pointers */ 82 + z->next_out = p; 83 + s->read = q; 84 + 85 + /* done */ 86 + return r; 87 +}
Added zlib/infutil.h version [90529b3df0e042c2]
1 +/* infutil.h -- types and macros common to blocks and codes 2 + * Copyright (C) 1995-1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +#ifndef _INFUTIL_H 12 +#define _INFUTIL_H 13 + 14 +typedef enum { 15 + TYPE, /* get type bits (3, including end bit) */ 16 + LENS, /* get lengths for stored */ 17 + STORED, /* processing stored block */ 18 + TABLE, /* get table lengths */ 19 + BTREE, /* get bit lengths tree for a dynamic block */ 20 + DTREE, /* get length, distance trees for a dynamic block */ 21 + CODES, /* processing fixed or dynamic block */ 22 + DRY, /* output remaining window bytes */ 23 + DONE, /* finished last block, done */ 24 + BAD} /* got a data error--stuck here */ 25 +inflate_block_mode; 26 + 27 +/* inflate blocks semi-private state */ 28 +struct inflate_blocks_state { 29 + 30 + /* mode */ 31 + inflate_block_mode mode; /* current inflate_block mode */ 32 + 33 + /* mode dependent information */ 34 + union { 35 + uInt left; /* if STORED, bytes left to copy */ 36 + struct { 37 + uInt table; /* table lengths (14 bits) */ 38 + uInt index; /* index into blens (or border) */ 39 + uIntf *blens; /* bit lengths of codes */ 40 + uInt bb; /* bit length tree depth */ 41 + inflate_huft *tb; /* bit length decoding tree */ 42 + } trees; /* if DTREE, decoding info for trees */ 43 + struct { 44 + inflate_codes_statef 45 + *codes; 46 + } decode; /* if CODES, current state */ 47 + } sub; /* submode */ 48 + uInt last; /* true if this block is the last block */ 49 + 50 + /* mode independent information */ 51 + uInt bitk; /* bits in bit buffer */ 52 + uLong bitb; /* bit buffer */ 53 + inflate_huft *hufts; /* single malloc for tree space */ 54 + Bytef *window; /* sliding window */ 55 + Bytef *end; /* one byte after sliding window */ 56 + Bytef *read; /* window read pointer */ 57 + Bytef *write; /* window write pointer */ 58 + check_func checkfn; /* check function */ 59 + uLong check; /* check on output */ 60 + 61 +}; 62 + 63 + 64 +/* defines for inflate input/output */ 65 +/* update pointers and return */ 66 +#define UPDBITS {s->bitb=b;s->bitk=k;} 67 +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} 68 +#define UPDOUT {s->write=q;} 69 +#define UPDATE {UPDBITS UPDIN UPDOUT} 70 +#define LEAVE {UPDATE return inflate_flush(s,z,r);} 71 +/* get bytes and bits */ 72 +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} 73 +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} 74 +#define NEXTBYTE (n--,*p++) 75 +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} 76 +#define DUMPBITS(j) {b>>=(j);k-=(j);} 77 +/* output bytes */ 78 +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) 79 +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} 80 +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} 81 +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} 82 +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} 83 +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} 84 +/* load local pointers */ 85 +#define LOAD {LOADIN LOADOUT} 86 + 87 +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ 88 +extern uInt inflate_mask[17]; 89 + 90 +/* copy as much as possible from the sliding window to the output area */ 91 +extern int inflate_flush OF(( 92 + inflate_blocks_statef *, 93 + z_streamp , 94 + int)); 95 + 96 +struct internal_state {int dummy;}; /* for buggy compilers */ 97 + 98 +#endif
Added zlib/maketree.c version [e665ffa93f444da9]
1 +/* maketree.c -- make inffixed.h table for decoding fixed codes 2 + * Copyright (C) 1998 Mark Adler 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +/* This program is included in the distribution for completeness. 12 + You do not need to compile or run this program since inffixed.h 13 + is already included in the distribution. To use this program 14 + you need to compile zlib with BUILDFIXED defined and then compile 15 + and link this program with the zlib library. Then the output of 16 + this program can be piped to inffixed.h. */ 17 + 18 +#include <stdio.h> 19 +#include <stdlib.h> 20 +#include "zutil.h" 21 +#include "inftrees.h" 22 + 23 +/* simplify the use of the inflate_huft type with some defines */ 24 +#define exop word.what.Exop 25 +#define bits word.what.Bits 26 + 27 +/* generate initialization table for an inflate_huft structure array */ 28 +void maketree(uInt b, inflate_huft *t) 29 +{ 30 + int i, e; 31 + 32 + i = 0; 33 + while (1) 34 + { 35 + e = t[i].exop; 36 + if (e && (e & (16+64)) == 0) /* table pointer */ 37 + { 38 + fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); 39 + exit(1); 40 + } 41 + if (i % 4 == 0) 42 + printf("\n "); 43 + printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); 44 + if (++i == (1<<b)) 45 + break; 46 + putchar(','); 47 + } 48 + puts(""); 49 +}
Added zlib/trees.c version [33c4c820010d3bd4]
1 +/* trees.c -- output deflated data using Huffman coding 2 + * Copyright (C) 1995-1998 Jean-loup Gailly 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* 7 + * ALGORITHM 8 + * 9 + * The "deflation" process uses several Huffman trees. The more 10 + * common source values are represented by shorter bit sequences. 11 + * 12 + * Each code tree is stored in a compressed form which is itself 13 + * a Huffman encoding of the lengths of all the code strings (in 14 + * ascending order by source values). The actual code strings are 15 + * reconstructed from the lengths in the inflate process, as described 16 + * in the deflate specification. 17 + * 18 + * REFERENCES 19 + * 20 + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". 21 + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc 22 + * 23 + * Storer, James A. 24 + * Data Compression: Methods and Theory, pp. 49-50. 25 + * Computer Science Press, 1988. ISBN 0-7167-8156-5. 26 + * 27 + * Sedgewick, R. 28 + * Algorithms, p290. 29 + * Addison-Wesley, 1983. ISBN 0-201-06672-6. 30 + */ 31 + 32 +/* @(#) $Id$ */ 33 + 34 +/* #define GEN_TREES_H */ 35 + 36 +#include "deflate.h" 37 + 38 +#ifdef DEBUG 39 +# include <ctype.h> 40 +#endif 41 + 42 +/* =========================================================================== 43 + * Constants 44 + */ 45 + 46 +#define MAX_BL_BITS 7 47 +/* Bit length codes must not exceed MAX_BL_BITS bits */ 48 + 49 +#define END_BLOCK 256 50 +/* end of block literal code */ 51 + 52 +#define REP_3_6 16 53 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ 54 + 55 +#define REPZ_3_10 17 56 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ 57 + 58 +#define REPZ_11_138 18 59 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ 60 + 61 +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ 62 + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; 63 + 64 +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ 65 + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; 66 + 67 +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ 68 + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; 69 + 70 +local const uch bl_order[BL_CODES] 71 + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; 72 +/* The lengths of the bit length codes are sent in order of decreasing 73 + * probability, to avoid transmitting the lengths for unused bit length codes. 74 + */ 75 + 76 +#define Buf_size (8 * 2*sizeof(char)) 77 +/* Number of bits used within bi_buf. (bi_buf might be implemented on 78 + * more than 16 bits on some systems.) 79 + */ 80 + 81 +/* =========================================================================== 82 + * Local data. These are initialized only once. 83 + */ 84 + 85 +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ 86 + 87 +#if defined(GEN_TREES_H) || !defined(STDC) 88 +/* non ANSI compilers may not accept trees.h */ 89 + 90 +local ct_data static_ltree[L_CODES+2]; 91 +/* The static literal tree. Since the bit lengths are imposed, there is no 92 + * need for the L_CODES extra codes used during heap construction. However 93 + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init 94 + * below). 95 + */ 96 + 97 +local ct_data static_dtree[D_CODES]; 98 +/* The static distance tree. (Actually a trivial tree since all codes use 99 + * 5 bits.) 100 + */ 101 + 102 +uch _dist_code[DIST_CODE_LEN]; 103 +/* Distance codes. The first 256 values correspond to the distances 104 + * 3 .. 258, the last 256 values correspond to the top 8 bits of 105 + * the 15 bit distances. 106 + */ 107 + 108 +uch _length_code[MAX_MATCH-MIN_MATCH+1]; 109 +/* length code for each normalized match length (0 == MIN_MATCH) */ 110 + 111 +local int base_length[LENGTH_CODES]; 112 +/* First normalized length for each code (0 = MIN_MATCH) */ 113 + 114 +local int base_dist[D_CODES]; 115 +/* First normalized distance for each code (0 = distance of 1) */ 116 + 117 +#else 118 +# include "trees.h" 119 +#endif /* GEN_TREES_H */ 120 + 121 +struct static_tree_desc_s { 122 + const ct_data *static_tree; /* static tree or NULL */ 123 + const intf *extra_bits; /* extra bits for each code or NULL */ 124 + int extra_base; /* base index for extra_bits */ 125 + int elems; /* max number of elements in the tree */ 126 + int max_length; /* max bit length for the codes */ 127 +}; 128 + 129 +local static_tree_desc static_l_desc = 130 +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; 131 + 132 +local static_tree_desc static_d_desc = 133 +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; 134 + 135 +local static_tree_desc static_bl_desc = 136 +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; 137 + 138 +/* =========================================================================== 139 + * Local (static) routines in this file. 140 + */ 141 + 142 +local void tr_static_init OF((void)); 143 +local void init_block OF((deflate_state *s)); 144 +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); 145 +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); 146 +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); 147 +local void build_tree OF((deflate_state *s, tree_desc *desc)); 148 +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); 149 +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); 150 +local int build_bl_tree OF((deflate_state *s)); 151 +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, 152 + int blcodes)); 153 +local void compress_block OF((deflate_state *s, ct_data *ltree, 154 + ct_data *dtree)); 155 +local void set_data_type OF((deflate_state *s)); 156 +local unsigned bi_reverse OF((unsigned value, int length)); 157 +local void bi_windup OF((deflate_state *s)); 158 +local void bi_flush OF((deflate_state *s)); 159 +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, 160 + int header)); 161 + 162 +#ifdef GEN_TREES_H 163 +local void gen_trees_header OF((void)); 164 +#endif 165 + 166 +#ifndef DEBUG 167 +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) 168 + /* Send a code of the given tree. c and tree must not have side effects */ 169 + 170 +#else /* DEBUG */ 171 +# define send_code(s, c, tree) \ 172 + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ 173 + send_bits(s, tree[c].Code, tree[c].Len); } 174 +#endif 175 + 176 +/* =========================================================================== 177 + * Output a short LSB first on the stream. 178 + * IN assertion: there is enough room in pendingBuf. 179 + */ 180 +#define put_short(s, w) { \ 181 + put_byte(s, (uch)((w) & 0xff)); \ 182 + put_byte(s, (uch)((ush)(w) >> 8)); \ 183 +} 184 + 185 +/* =========================================================================== 186 + * Send a value on a given number of bits. 187 + * IN assertion: length <= 16 and value fits in length bits. 188 + */ 189 +#ifdef DEBUG 190 +local void send_bits OF((deflate_state *s, int value, int length)); 191 + 192 +local void send_bits(s, value, length) 193 + deflate_state *s; 194 + int value; /* value to send */ 195 + int length; /* number of bits */ 196 +{ 197 + Tracevv((stderr," l %2d v %4x ", length, value)); 198 + Assert(length > 0 && length <= 15, "invalid length"); 199 + s->bits_sent += (ulg)length; 200 + 201 + /* If not enough room in bi_buf, use (valid) bits from bi_buf and 202 + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 203 + * unused bits in value. 204 + */ 205 + if (s->bi_valid > (int)Buf_size - length) { 206 + s->bi_buf |= (value << s->bi_valid); 207 + put_short(s, s->bi_buf); 208 + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); 209 + s->bi_valid += length - Buf_size; 210 + } else { 211 + s->bi_buf |= value << s->bi_valid; 212 + s->bi_valid += length; 213 + } 214 +} 215 +#else /* !DEBUG */ 216 + 217 +#define send_bits(s, value, length) \ 218 +{ int len = length;\ 219 + if (s->bi_valid > (int)Buf_size - len) {\ 220 + int val = value;\ 221 + s->bi_buf |= (val << s->bi_valid);\ 222 + put_short(s, s->bi_buf);\ 223 + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ 224 + s->bi_valid += len - Buf_size;\ 225 + } else {\ 226 + s->bi_buf |= (value) << s->bi_valid;\ 227 + s->bi_valid += len;\ 228 + }\ 229 +} 230 +#endif /* DEBUG */ 231 + 232 + 233 +#define MAX(a,b) (a >= b ? a : b) 234 +/* the arguments must not have side effects */ 235 + 236 +/* =========================================================================== 237 + * Initialize the various 'constant' tables. 238 + */ 239 +local void tr_static_init() 240 +{ 241 +#if defined(GEN_TREES_H) || !defined(STDC) 242 + static int static_init_done = 0; 243 + int n; /* iterates over tree elements */ 244 + int bits; /* bit counter */ 245 + int length; /* length value */ 246 + int code; /* code value */ 247 + int dist; /* distance index */ 248 + ush bl_count[MAX_BITS+1]; 249 + /* number of codes at each bit length for an optimal tree */ 250 + 251 + if (static_init_done) return; 252 + 253 + /* For some embedded targets, global variables are not initialized: */ 254 + static_l_desc.static_tree = static_ltree; 255 + static_l_desc.extra_bits = extra_lbits; 256 + static_d_desc.static_tree = static_dtree; 257 + static_d_desc.extra_bits = extra_dbits; 258 + static_bl_desc.extra_bits = extra_blbits; 259 + 260 + /* Initialize the mapping length (0..255) -> length code (0..28) */ 261 + length = 0; 262 + for (code = 0; code < LENGTH_CODES-1; code++) { 263 + base_length[code] = length; 264 + for (n = 0; n < (1<<extra_lbits[code]); n++) { 265 + _length_code[length++] = (uch)code; 266 + } 267 + } 268 + Assert (length == 256, "tr_static_init: length != 256"); 269 + /* Note that the length 255 (match length 258) can be represented 270 + * in two different ways: code 284 + 5 bits or code 285, so we 271 + * overwrite length_code[255] to use the best encoding: 272 + */ 273 + _length_code[length-1] = (uch)code; 274 + 275 + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ 276 + dist = 0; 277 + for (code = 0 ; code < 16; code++) { 278 + base_dist[code] = dist; 279 + for (n = 0; n < (1<<extra_dbits[code]); n++) { 280 + _dist_code[dist++] = (uch)code; 281 + } 282 + } 283 + Assert (dist == 256, "tr_static_init: dist != 256"); 284 + dist >>= 7; /* from now on, all distances are divided by 128 */ 285 + for ( ; code < D_CODES; code++) { 286 + base_dist[code] = dist << 7; 287 + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { 288 + _dist_code[256 + dist++] = (uch)code; 289 + } 290 + } 291 + Assert (dist == 256, "tr_static_init: 256+dist != 512"); 292 + 293 + /* Construct the codes of the static literal tree */ 294 + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; 295 + n = 0; 296 + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; 297 + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; 298 + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; 299 + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; 300 + /* Codes 286 and 287 do not exist, but we must include them in the 301 + * tree construction to get a canonical Huffman tree (longest code 302 + * all ones) 303 + */ 304 + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); 305 + 306 + /* The static distance tree is trivial: */ 307 + for (n = 0; n < D_CODES; n++) { 308 + static_dtree[n].Len = 5; 309 + static_dtree[n].Code = bi_reverse((unsigned)n, 5); 310 + } 311 + static_init_done = 1; 312 + 313 +# ifdef GEN_TREES_H 314 + gen_trees_header(); 315 +# endif 316 +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ 317 +} 318 + 319 +/* =========================================================================== 320 + * Genererate the file trees.h describing the static trees. 321 + */ 322 +#ifdef GEN_TREES_H 323 +# ifndef DEBUG 324 +# include <stdio.h> 325 +# endif 326 + 327 +# define SEPARATOR(i, last, width) \ 328 + ((i) == (last)? "\n};\n\n" : \ 329 + ((i) % (width) == (width)-1 ? ",\n" : ", ")) 330 + 331 +void gen_trees_header() 332 +{ 333 + FILE *header = fopen("trees.h", "w"); 334 + int i; 335 + 336 + Assert (header != NULL, "Can't open trees.h"); 337 + fprintf(header, 338 + "/* header created automatically with -DGEN_TREES_H */\n\n"); 339 + 340 + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); 341 + for (i = 0; i < L_CODES+2; i++) { 342 + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, 343 + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); 344 + } 345 + 346 + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); 347 + for (i = 0; i < D_CODES; i++) { 348 + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, 349 + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); 350 + } 351 + 352 + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); 353 + for (i = 0; i < DIST_CODE_LEN; i++) { 354 + fprintf(header, "%2u%s", _dist_code[i], 355 + SEPARATOR(i, DIST_CODE_LEN-1, 20)); 356 + } 357 + 358 + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); 359 + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { 360 + fprintf(header, "%2u%s", _length_code[i], 361 + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); 362 + } 363 + 364 + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); 365 + for (i = 0; i < LENGTH_CODES; i++) { 366 + fprintf(header, "%1u%s", base_length[i], 367 + SEPARATOR(i, LENGTH_CODES-1, 20)); 368 + } 369 + 370 + fprintf(header, "local const int base_dist[D_CODES] = {\n"); 371 + for (i = 0; i < D_CODES; i++) { 372 + fprintf(header, "%5u%s", base_dist[i], 373 + SEPARATOR(i, D_CODES-1, 10)); 374 + } 375 + 376 + fclose(header); 377 +} 378 +#endif /* GEN_TREES_H */ 379 + 380 +/* =========================================================================== 381 + * Initialize the tree data structures for a new zlib stream. 382 + */ 383 +void _tr_init(s) 384 + deflate_state *s; 385 +{ 386 + tr_static_init(); 387 + 388 + s->l_desc.dyn_tree = s->dyn_ltree; 389 + s->l_desc.stat_desc = &static_l_desc; 390 + 391 + s->d_desc.dyn_tree = s->dyn_dtree; 392 + s->d_desc.stat_desc = &static_d_desc; 393 + 394 + s->bl_desc.dyn_tree = s->bl_tree; 395 + s->bl_desc.stat_desc = &static_bl_desc; 396 + 397 + s->bi_buf = 0; 398 + s->bi_valid = 0; 399 + s->last_eob_len = 8; /* enough lookahead for inflate */ 400 +#ifdef DEBUG 401 + s->compressed_len = 0L; 402 + s->bits_sent = 0L; 403 +#endif 404 + 405 + /* Initialize the first block of the first file: */ 406 + init_block(s); 407 +} 408 + 409 +/* =========================================================================== 410 + * Initialize a new block. 411 + */ 412 +local void init_block(s) 413 + deflate_state *s; 414 +{ 415 + int n; /* iterates over tree elements */ 416 + 417 + /* Initialize the trees. */ 418 + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; 419 + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; 420 + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; 421 + 422 + s->dyn_ltree[END_BLOCK].Freq = 1; 423 + s->opt_len = s->static_len = 0L; 424 + s->last_lit = s->matches = 0; 425 +} 426 + 427 +#define SMALLEST 1 428 +/* Index within the heap array of least frequent node in the Huffman tree */ 429 + 430 + 431 +/* =========================================================================== 432 + * Remove the smallest element from the heap and recreate the heap with 433 + * one less element. Updates heap and heap_len. 434 + */ 435 +#define pqremove(s, tree, top) \ 436 +{\ 437 + top = s->heap[SMALLEST]; \ 438 + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ 439 + pqdownheap(s, tree, SMALLEST); \ 440 +} 441 + 442 +/* =========================================================================== 443 + * Compares to subtrees, using the tree depth as tie breaker when 444 + * the subtrees have equal frequency. This minimizes the worst case length. 445 + */ 446 +#define smaller(tree, n, m, depth) \ 447 + (tree[n].Freq < tree[m].Freq || \ 448 + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) 449 + 450 +/* =========================================================================== 451 + * Restore the heap property by moving down the tree starting at node k, 452 + * exchanging a node with the smallest of its two sons if necessary, stopping 453 + * when the heap property is re-established (each father smaller than its 454 + * two sons). 455 + */ 456 +local void pqdownheap(s, tree, k) 457 + deflate_state *s; 458 + ct_data *tree; /* the tree to restore */ 459 + int k; /* node to move down */ 460 +{ 461 + int v = s->heap[k]; 462 + int j = k << 1; /* left son of k */ 463 + while (j <= s->heap_len) { 464 + /* Set j to the smallest of the two sons: */ 465 + if (j < s->heap_len && 466 + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { 467 + j++; 468 + } 469 + /* Exit if v is smaller than both sons */ 470 + if (smaller(tree, v, s->heap[j], s->depth)) break; 471 + 472 + /* Exchange v with the smallest son */ 473 + s->heap[k] = s->heap[j]; k = j; 474 + 475 + /* And continue down the tree, setting j to the left son of k */ 476 + j <<= 1; 477 + } 478 + s->heap[k] = v; 479 +} 480 + 481 +/* =========================================================================== 482 + * Compute the optimal bit lengths for a tree and update the total bit length 483 + * for the current block. 484 + * IN assertion: the fields freq and dad are set, heap[heap_max] and 485 + * above are the tree nodes sorted by increasing frequency. 486 + * OUT assertions: the field len is set to the optimal bit length, the 487 + * array bl_count contains the frequencies for each bit length. 488 + * The length opt_len is updated; static_len is also updated if stree is 489 + * not null. 490 + */ 491 +local void gen_bitlen(s, desc) 492 + deflate_state *s; 493 + tree_desc *desc; /* the tree descriptor */ 494 +{ 495 + ct_data *tree = desc->dyn_tree; 496 + int max_code = desc->max_code; 497 + const ct_data *stree = desc->stat_desc->static_tree; 498 + const intf *extra = desc->stat_desc->extra_bits; 499 + int base = desc->stat_desc->extra_base; 500 + int max_length = desc->stat_desc->max_length; 501 + int h; /* heap index */ 502 + int n, m; /* iterate over the tree elements */ 503 + int bits; /* bit length */ 504 + int xbits; /* extra bits */ 505 + ush f; /* frequency */ 506 + int overflow = 0; /* number of elements with bit length too large */ 507 + 508 + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; 509 + 510 + /* In a first pass, compute the optimal bit lengths (which may 511 + * overflow in the case of the bit length tree). 512 + */ 513 + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ 514 + 515 + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { 516 + n = s->heap[h]; 517 + bits = tree[tree[n].Dad].Len + 1; 518 + if (bits > max_length) bits = max_length, overflow++; 519 + tree[n].Len = (ush)bits; 520 + /* We overwrite tree[n].Dad which is no longer needed */ 521 + 522 + if (n > max_code) continue; /* not a leaf node */ 523 + 524 + s->bl_count[bits]++; 525 + xbits = 0; 526 + if (n >= base) xbits = extra[n-base]; 527 + f = tree[n].Freq; 528 + s->opt_len += (ulg)f * (bits + xbits); 529 + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); 530 + } 531 + if (overflow == 0) return; 532 + 533 + Trace((stderr,"\nbit length overflow\n")); 534 + /* This happens for example on obj2 and pic of the Calgary corpus */ 535 + 536 + /* Find the first bit length which could increase: */ 537 + do { 538 + bits = max_length-1; 539 + while (s->bl_count[bits] == 0) bits--; 540 + s->bl_count[bits]--; /* move one leaf down the tree */ 541 + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ 542 + s->bl_count[max_length]--; 543 + /* The brother of the overflow item also moves one step up, 544 + * but this does not affect bl_count[max_length] 545 + */ 546 + overflow -= 2; 547 + } while (overflow > 0); 548 + 549 + /* Now recompute all bit lengths, scanning in increasing frequency. 550 + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all 551 + * lengths instead of fixing only the wrong ones. This idea is taken 552 + * from 'ar' written by Haruhiko Okumura.) 553 + */ 554 + for (bits = max_length; bits != 0; bits--) { 555 + n = s->bl_count[bits]; 556 + while (n != 0) { 557 + m = s->heap[--h]; 558 + if (m > max_code) continue; 559 + if (tree[m].Len != (unsigned) bits) { 560 + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); 561 + s->opt_len += ((long)bits - (long)tree[m].Len) 562 + *(long)tree[m].Freq; 563 + tree[m].Len = (ush)bits; 564 + } 565 + n--; 566 + } 567 + } 568 +} 569 + 570 +/* =========================================================================== 571 + * Generate the codes for a given tree and bit counts (which need not be 572 + * optimal). 573 + * IN assertion: the array bl_count contains the bit length statistics for 574 + * the given tree and the field len is set for all tree elements. 575 + * OUT assertion: the field code is set for all tree elements of non 576 + * zero code length. 577 + */ 578 +local void gen_codes (tree, max_code, bl_count) 579 + ct_data *tree; /* the tree to decorate */ 580 + int max_code; /* largest code with non zero frequency */ 581 + ushf *bl_count; /* number of codes at each bit length */ 582 +{ 583 + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ 584 + ush code = 0; /* running code value */ 585 + int bits; /* bit index */ 586 + int n; /* code index */ 587 + 588 + /* The distribution counts are first used to generate the code values 589 + * without bit reversal. 590 + */ 591 + for (bits = 1; bits <= MAX_BITS; bits++) { 592 + next_code[bits] = code = (code + bl_count[bits-1]) << 1; 593 + } 594 + /* Check that the bit counts in bl_count are consistent. The last code 595 + * must be all ones. 596 + */ 597 + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, 598 + "inconsistent bit counts"); 599 + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); 600 + 601 + for (n = 0; n <= max_code; n++) { 602 + int len = tree[n].Len; 603 + if (len == 0) continue; 604 + /* Now reverse the bits */ 605 + tree[n].Code = bi_reverse(next_code[len]++, len); 606 + 607 + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", 608 + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); 609 + } 610 +} 611 + 612 +/* =========================================================================== 613 + * Construct one Huffman tree and assigns the code bit strings and lengths. 614 + * Update the total bit length for the current block. 615 + * IN assertion: the field freq is set for all tree elements. 616 + * OUT assertions: the fields len and code are set to the optimal bit length 617 + * and corresponding code. The length opt_len is updated; static_len is 618 + * also updated if stree is not null. The field max_code is set. 619 + */ 620 +local void build_tree(s, desc) 621 + deflate_state *s; 622 + tree_desc *desc; /* the tree descriptor */ 623 +{ 624 + ct_data *tree = desc->dyn_tree; 625 + const ct_data *stree = desc->stat_desc->static_tree; 626 + int elems = desc->stat_desc->elems; 627 + int n, m; /* iterate over heap elements */ 628 + int max_code = -1; /* largest code with non zero frequency */ 629 + int node; /* new node being created */ 630 + 631 + /* Construct the initial heap, with least frequent element in 632 + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. 633 + * heap[0] is not used. 634 + */ 635 + s->heap_len = 0, s->heap_max = HEAP_SIZE; 636 + 637 + for (n = 0; n < elems; n++) { 638 + if (tree[n].Freq != 0) { 639 + s->heap[++(s->heap_len)] = max_code = n; 640 + s->depth[n] = 0; 641 + } else { 642 + tree[n].Len = 0; 643 + } 644 + } 645 + 646 + /* The pkzip format requires that at least one distance code exists, 647 + * and that at least one bit should be sent even if there is only one 648 + * possible code. So to avoid special checks later on we force at least 649 + * two codes of non zero frequency. 650 + */ 651 + while (s->heap_len < 2) { 652 + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); 653 + tree[node].Freq = 1; 654 + s->depth[node] = 0; 655 + s->opt_len--; if (stree) s->static_len -= stree[node].Len; 656 + /* node is 0 or 1 so it does not have extra bits */ 657 + } 658 + desc->max_code = max_code; 659 + 660 + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, 661 + * establish sub-heaps of increasing lengths: 662 + */ 663 + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); 664 + 665 + /* Construct the Huffman tree by repeatedly combining the least two 666 + * frequent nodes. 667 + */ 668 + node = elems; /* next internal node of the tree */ 669 + do { 670 + pqremove(s, tree, n); /* n = node of least frequency */ 671 + m = s->heap[SMALLEST]; /* m = node of next least frequency */ 672 + 673 + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ 674 + s->heap[--(s->heap_max)] = m; 675 + 676 + /* Create a new node father of n and m */ 677 + tree[node].Freq = tree[n].Freq + tree[m].Freq; 678 + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); 679 + tree[n].Dad = tree[m].Dad = (ush)node; 680 +#ifdef DUMP_BL_TREE 681 + if (tree == s->bl_tree) { 682 + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", 683 + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); 684 + } 685 +#endif 686 + /* and insert the new node in the heap */ 687 + s->heap[SMALLEST] = node++; 688 + pqdownheap(s, tree, SMALLEST); 689 + 690 + } while (s->heap_len >= 2); 691 + 692 + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; 693 + 694 + /* At this point, the fields freq and dad are set. We can now 695 + * generate the bit lengths. 696 + */ 697 + gen_bitlen(s, (tree_desc *)desc); 698 + 699 + /* The field len is now set, we can generate the bit codes */ 700 + gen_codes ((ct_data *)tree, max_code, s->bl_count); 701 +} 702 + 703 +/* =========================================================================== 704 + * Scan a literal or distance tree to determine the frequencies of the codes 705 + * in the bit length tree. 706 + */ 707 +local void scan_tree (s, tree, max_code) 708 + deflate_state *s; 709 + ct_data *tree; /* the tree to be scanned */ 710 + int max_code; /* and its largest code of non zero frequency */ 711 +{ 712 + int n; /* iterates over all tree elements */ 713 + int prevlen = -1; /* last emitted length */ 714 + int curlen; /* length of current code */ 715 + int nextlen = tree[0].Len; /* length of next code */ 716 + int count = 0; /* repeat count of the current code */ 717 + int max_count = 7; /* max repeat count */ 718 + int min_count = 4; /* min repeat count */ 719 + 720 + if (nextlen == 0) max_count = 138, min_count = 3; 721 + tree[max_code+1].Len = (ush)0xffff; /* guard */ 722 + 723 + for (n = 0; n <= max_code; n++) { 724 + curlen = nextlen; nextlen = tree[n+1].Len; 725 + if (++count < max_count && curlen == nextlen) { 726 + continue; 727 + } else if (count < min_count) { 728 + s->bl_tree[curlen].Freq += count; 729 + } else if (curlen != 0) { 730 + if (curlen != prevlen) s->bl_tree[curlen].Freq++; 731 + s->bl_tree[REP_3_6].Freq++; 732 + } else if (count <= 10) { 733 + s->bl_tree[REPZ_3_10].Freq++; 734 + } else { 735 + s->bl_tree[REPZ_11_138].Freq++; 736 + } 737 + count = 0; prevlen = curlen; 738 + if (nextlen == 0) { 739 + max_count = 138, min_count = 3; 740 + } else if (curlen == nextlen) { 741 + max_count = 6, min_count = 3; 742 + } else { 743 + max_count = 7, min_count = 4; 744 + } 745 + } 746 +} 747 + 748 +/* =========================================================================== 749 + * Send a literal or distance tree in compressed form, using the codes in 750 + * bl_tree. 751 + */ 752 +local void send_tree (s, tree, max_code) 753 + deflate_state *s; 754 + ct_data *tree; /* the tree to be scanned */ 755 + int max_code; /* and its largest code of non zero frequency */ 756 +{ 757 + int n; /* iterates over all tree elements */ 758 + int prevlen = -1; /* last emitted length */ 759 + int curlen; /* length of current code */ 760 + int nextlen = tree[0].Len; /* length of next code */ 761 + int count = 0; /* repeat count of the current code */ 762 + int max_count = 7; /* max repeat count */ 763 + int min_count = 4; /* min repeat count */ 764 + 765 + /* tree[max_code+1].Len = -1; */ /* guard already set */ 766 + if (nextlen == 0) max_count = 138, min_count = 3; 767 + 768 + for (n = 0; n <= max_code; n++) { 769 + curlen = nextlen; nextlen = tree[n+1].Len; 770 + if (++count < max_count && curlen == nextlen) { 771 + continue; 772 + } else if (count < min_count) { 773 + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); 774 + 775 + } else if (curlen != 0) { 776 + if (curlen != prevlen) { 777 + send_code(s, curlen, s->bl_tree); count--; 778 + } 779 + Assert(count >= 3 && count <= 6, " 3_6?"); 780 + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); 781 + 782 + } else if (count <= 10) { 783 + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); 784 + 785 + } else { 786 + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); 787 + } 788 + count = 0; prevlen = curlen; 789 + if (nextlen == 0) { 790 + max_count = 138, min_count = 3; 791 + } else if (curlen == nextlen) { 792 + max_count = 6, min_count = 3; 793 + } else { 794 + max_count = 7, min_count = 4; 795 + } 796 + } 797 +} 798 + 799 +/* =========================================================================== 800 + * Construct the Huffman tree for the bit lengths and return the index in 801 + * bl_order of the last bit length code to send. 802 + */ 803 +local int build_bl_tree(s) 804 + deflate_state *s; 805 +{ 806 + int max_blindex; /* index of last bit length code of non zero freq */ 807 + 808 + /* Determine the bit length frequencies for literal and distance trees */ 809 + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); 810 + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); 811 + 812 + /* Build the bit length tree: */ 813 + build_tree(s, (tree_desc *)(&(s->bl_desc))); 814 + /* opt_len now includes the length of the tree representations, except 815 + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. 816 + */ 817 + 818 + /* Determine the number of bit length codes to send. The pkzip format 819 + * requires that at least 4 bit length codes be sent. (appnote.txt says 820 + * 3 but the actual value used is 4.) 821 + */ 822 + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { 823 + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; 824 + } 825 + /* Update opt_len to include the bit length tree and counts */ 826 + s->opt_len += 3*(max_blindex+1) + 5+5+4; 827 + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", 828 + s->opt_len, s->static_len)); 829 + 830 + return max_blindex; 831 +} 832 + 833 +/* =========================================================================== 834 + * Send the header for a block using dynamic Huffman trees: the counts, the 835 + * lengths of the bit length codes, the literal tree and the distance tree. 836 + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. 837 + */ 838 +local void send_all_trees(s, lcodes, dcodes, blcodes) 839 + deflate_state *s; 840 + int lcodes, dcodes, blcodes; /* number of codes for each tree */ 841 +{ 842 + int rank; /* index in bl_order */ 843 + 844 + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); 845 + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, 846 + "too many codes"); 847 + Tracev((stderr, "\nbl counts: ")); 848 + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ 849 + send_bits(s, dcodes-1, 5); 850 + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ 851 + for (rank = 0; rank < blcodes; rank++) { 852 + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); 853 + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); 854 + } 855 + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); 856 + 857 + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ 858 + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); 859 + 860 + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ 861 + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); 862 +} 863 + 864 +/* =========================================================================== 865 + * Send a stored block 866 + */ 867 +void _tr_stored_block(s, buf, stored_len, eof) 868 + deflate_state *s; 869 + charf *buf; /* input block */ 870 + ulg stored_len; /* length of input block */ 871 + int eof; /* true if this is the last block for a file */ 872 +{ 873 + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ 874 +#ifdef DEBUG 875 + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; 876 + s->compressed_len += (stored_len + 4) << 3; 877 +#endif 878 + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ 879 +} 880 + 881 +/* =========================================================================== 882 + * Send one empty static block to give enough lookahead for inflate. 883 + * This takes 10 bits, of which 7 may remain in the bit buffer. 884 + * The current inflate code requires 9 bits of lookahead. If the 885 + * last two codes for the previous block (real code plus EOB) were coded 886 + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode 887 + * the last real code. In this case we send two empty static blocks instead 888 + * of one. (There are no problems if the previous block is stored or fixed.) 889 + * To simplify the code, we assume the worst case of last real code encoded 890 + * on one bit only. 891 + */ 892 +void _tr_align(s) 893 + deflate_state *s; 894 +{ 895 + send_bits(s, STATIC_TREES<<1, 3); 896 + send_code(s, END_BLOCK, static_ltree); 897 +#ifdef DEBUG 898 + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ 899 +#endif 900 + bi_flush(s); 901 + /* Of the 10 bits for the empty block, we have already sent 902 + * (10 - bi_valid) bits. The lookahead for the last real code (before 903 + * the EOB of the previous block) was thus at least one plus the length 904 + * of the EOB plus what we have just sent of the empty static block. 905 + */ 906 + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { 907 + send_bits(s, STATIC_TREES<<1, 3); 908 + send_code(s, END_BLOCK, static_ltree); 909 +#ifdef DEBUG 910 + s->compressed_len += 10L; 911 +#endif 912 + bi_flush(s); 913 + } 914 + s->last_eob_len = 7; 915 +} 916 + 917 +/* =========================================================================== 918 + * Determine the best encoding for the current block: dynamic trees, static 919 + * trees or store, and output the encoded block to the zip file. 920 + */ 921 +void _tr_flush_block(s, buf, stored_len, eof) 922 + deflate_state *s; 923 + charf *buf; /* input block, or NULL if too old */ 924 + ulg stored_len; /* length of input block */ 925 + int eof; /* true if this is the last block for a file */ 926 +{ 927 + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 928 + int max_blindex = 0; /* index of last bit length code of non zero freq */ 929 + 930 + /* Build the Huffman trees unless a stored block is forced */ 931 + if (s->level > 0) { 932 + 933 + /* Check if the file is ascii or binary */ 934 + if (s->data_type == Z_UNKNOWN) set_data_type(s); 935 + 936 + /* Construct the literal and distance trees */ 937 + build_tree(s, (tree_desc *)(&(s->l_desc))); 938 + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, 939 + s->static_len)); 940 + 941 + build_tree(s, (tree_desc *)(&(s->d_desc))); 942 + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, 943 + s->static_len)); 944 + /* At this point, opt_len and static_len are the total bit lengths of 945 + * the compressed block data, excluding the tree representations. 946 + */ 947 + 948 + /* Build the bit length tree for the above two trees, and get the index 949 + * in bl_order of the last bit length code to send. 950 + */ 951 + max_blindex = build_bl_tree(s); 952 + 953 + /* Determine the best encoding. Compute first the block length in bytes*/ 954 + opt_lenb = (s->opt_len+3+7)>>3; 955 + static_lenb = (s->static_len+3+7)>>3; 956 + 957 + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", 958 + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, 959 + s->last_lit)); 960 + 961 + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; 962 + 963 + } else { 964 + Assert(buf != (char*)0, "lost buf"); 965 + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ 966 + } 967 + 968 +#ifdef FORCE_STORED 969 + if (buf != (char*)0) { /* force stored block */ 970 +#else 971 + if (stored_len+4 <= opt_lenb && buf != (char*)0) { 972 + /* 4: two words for the lengths */ 973 +#endif 974 + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. 975 + * Otherwise we can't have processed more than WSIZE input bytes since 976 + * the last block flush, because compression would have been 977 + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to 978 + * transform a block into a stored block. 979 + */ 980 + _tr_stored_block(s, buf, stored_len, eof); 981 + 982 +#ifdef FORCE_STATIC 983 + } else if (static_lenb >= 0) { /* force static trees */ 984 +#else 985 + } else if (static_lenb == opt_lenb) { 986 +#endif 987 + send_bits(s, (STATIC_TREES<<1)+eof, 3); 988 + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); 989 +#ifdef DEBUG 990 + s->compressed_len += 3 + s->static_len; 991 +#endif 992 + } else { 993 + send_bits(s, (DYN_TREES<<1)+eof, 3); 994 + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, 995 + max_blindex+1); 996 + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); 997 +#ifdef DEBUG 998 + s->compressed_len += 3 + s->opt_len; 999 +#endif 1000 + } 1001 + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); 1002 + /* The above check is made mod 2^32, for files larger than 512 MB 1003 + * and uLong implemented on 32 bits. 1004 + */ 1005 + init_block(s); 1006 + 1007 + if (eof) { 1008 + bi_windup(s); 1009 +#ifdef DEBUG 1010 + s->compressed_len += 7; /* align on byte boundary */ 1011 +#endif 1012 + } 1013 + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, 1014 + s->compressed_len-7*eof)); 1015 +} 1016 + 1017 +/* =========================================================================== 1018 + * Save the match info and tally the frequency counts. Return true if 1019 + * the current block must be flushed. 1020 + */ 1021 +int _tr_tally (s, dist, lc) 1022 + deflate_state *s; 1023 + unsigned dist; /* distance of matched string */ 1024 + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ 1025 +{ 1026 + s->d_buf[s->last_lit] = (ush)dist; 1027 + s->l_buf[s->last_lit++] = (uch)lc; 1028 + if (dist == 0) { 1029 + /* lc is the unmatched char */ 1030 + s->dyn_ltree[lc].Freq++; 1031 + } else { 1032 + s->matches++; 1033 + /* Here, lc is the match length - MIN_MATCH */ 1034 + dist--; /* dist = match distance - 1 */ 1035 + Assert((ush)dist < (ush)MAX_DIST(s) && 1036 + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && 1037 + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); 1038 + 1039 + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; 1040 + s->dyn_dtree[d_code(dist)].Freq++; 1041 + } 1042 + 1043 +#ifdef TRUNCATE_BLOCK 1044 + /* Try to guess if it is profitable to stop the current block here */ 1045 + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { 1046 + /* Compute an upper bound for the compressed length */ 1047 + ulg out_length = (ulg)s->last_lit*8L; 1048 + ulg in_length = (ulg)((long)s->strstart - s->block_start); 1049 + int dcode; 1050 + for (dcode = 0; dcode < D_CODES; dcode++) { 1051 + out_length += (ulg)s->dyn_dtree[dcode].Freq * 1052 + (5L+extra_dbits[dcode]); 1053 + } 1054 + out_length >>= 3; 1055 + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", 1056 + s->last_lit, in_length, out_length, 1057 + 100L - out_length*100L/in_length)); 1058 + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; 1059 + } 1060 +#endif 1061 + return (s->last_lit == s->lit_bufsize-1); 1062 + /* We avoid equality with lit_bufsize because of wraparound at 64K 1063 + * on 16 bit machines and because stored blocks are restricted to 1064 + * 64K-1 bytes. 1065 + */ 1066 +} 1067 + 1068 +/* =========================================================================== 1069 + * Send the block data compressed using the given Huffman trees 1070 + */ 1071 +local void compress_block(s, ltree, dtree) 1072 + deflate_state *s; 1073 + ct_data *ltree; /* literal tree */ 1074 + ct_data *dtree; /* distance tree */ 1075 +{ 1076 + unsigned dist; /* distance of matched string */ 1077 + int lc; /* match length or unmatched char (if dist == 0) */ 1078 + unsigned lx = 0; /* running index in l_buf */ 1079 + unsigned code; /* the code to send */ 1080 + int extra; /* number of extra bits to send */ 1081 + 1082 + if (s->last_lit != 0) do { 1083 + dist = s->d_buf[lx]; 1084 + lc = s->l_buf[lx++]; 1085 + if (dist == 0) { 1086 + send_code(s, lc, ltree); /* send a literal byte */ 1087 + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); 1088 + } else { 1089 + /* Here, lc is the match length - MIN_MATCH */ 1090 + code = _length_code[lc]; 1091 + send_code(s, code+LITERALS+1, ltree); /* send the length code */ 1092 + extra = extra_lbits[code]; 1093 + if (extra != 0) { 1094 + lc -= base_length[code]; 1095 + send_bits(s, lc, extra); /* send the extra length bits */ 1096 + } 1097 + dist--; /* dist is now the match distance - 1 */ 1098 + code = d_code(dist); 1099 + Assert (code < D_CODES, "bad d_code"); 1100 + 1101 + send_code(s, code, dtree); /* send the distance code */ 1102 + extra = extra_dbits[code]; 1103 + if (extra != 0) { 1104 + dist -= base_dist[code]; 1105 + send_bits(s, dist, extra); /* send the extra distance bits */ 1106 + } 1107 + } /* literal or match pair ? */ 1108 + 1109 + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ 1110 + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); 1111 + 1112 + } while (lx < s->last_lit); 1113 + 1114 + send_code(s, END_BLOCK, ltree); 1115 + s->last_eob_len = ltree[END_BLOCK].Len; 1116 +} 1117 + 1118 +/* =========================================================================== 1119 + * Set the data type to ASCII or BINARY, using a crude approximation: 1120 + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. 1121 + * IN assertion: the fields freq of dyn_ltree are set and the total of all 1122 + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). 1123 + */ 1124 +local void set_data_type(s) 1125 + deflate_state *s; 1126 +{ 1127 + int n = 0; 1128 + unsigned ascii_freq = 0; 1129 + unsigned bin_freq = 0; 1130 + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; 1131 + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; 1132 + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; 1133 + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); 1134 +} 1135 + 1136 +/* =========================================================================== 1137 + * Reverse the first len bits of a code, using straightforward code (a faster 1138 + * method would use a table) 1139 + * IN assertion: 1 <= len <= 15 1140 + */ 1141 +local unsigned bi_reverse(code, len) 1142 + unsigned code; /* the value to invert */ 1143 + int len; /* its bit length */ 1144 +{ 1145 + register unsigned res = 0; 1146 + do { 1147 + res |= code & 1; 1148 + code >>= 1, res <<= 1; 1149 + } while (--len > 0); 1150 + return res >> 1; 1151 +} 1152 + 1153 +/* =========================================================================== 1154 + * Flush the bit buffer, keeping at most 7 bits in it. 1155 + */ 1156 +local void bi_flush(s) 1157 + deflate_state *s; 1158 +{ 1159 + if (s->bi_valid == 16) { 1160 + put_short(s, s->bi_buf); 1161 + s->bi_buf = 0; 1162 + s->bi_valid = 0; 1163 + } else if (s->bi_valid >= 8) { 1164 + put_byte(s, (Byte)s->bi_buf); 1165 + s->bi_buf >>= 8; 1166 + s->bi_valid -= 8; 1167 + } 1168 +} 1169 + 1170 +/* =========================================================================== 1171 + * Flush the bit buffer and align the output on a byte boundary 1172 + */ 1173 +local void bi_windup(s) 1174 + deflate_state *s; 1175 +{ 1176 + if (s->bi_valid > 8) { 1177 + put_short(s, s->bi_buf); 1178 + } else if (s->bi_valid > 0) { 1179 + put_byte(s, (Byte)s->bi_buf); 1180 + } 1181 + s->bi_buf = 0; 1182 + s->bi_valid = 0; 1183 +#ifdef DEBUG 1184 + s->bits_sent = (s->bits_sent+7) & ~7; 1185 +#endif 1186 +} 1187 + 1188 +/* =========================================================================== 1189 + * Copy a stored block, storing first the length and its 1190 + * one's complement if requested. 1191 + */ 1192 +local void copy_block(s, buf, len, header) 1193 + deflate_state *s; 1194 + charf *buf; /* the input data */ 1195 + unsigned len; /* its length */ 1196 + int header; /* true if block header must be written */ 1197 +{ 1198 + bi_windup(s); /* align on byte boundary */ 1199 + s->last_eob_len = 8; /* enough lookahead for inflate */ 1200 + 1201 + if (header) { 1202 + put_short(s, (ush)len); 1203 + put_short(s, (ush)~len); 1204 +#ifdef DEBUG 1205 + s->bits_sent += 2*16; 1206 +#endif 1207 + } 1208 +#ifdef DEBUG 1209 + s->bits_sent += (ulg)len<<3; 1210 +#endif 1211 + while (len--) { 1212 + put_byte(s, *buf++); 1213 + } 1214 +}
Added zlib/trees.h version [6ab60a17f700321b]
1 +/* header created automatically with -DGEN_TREES_H */ 2 + 3 +local const ct_data static_ltree[L_CODES+2] = { 4 +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, 5 +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, 6 +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, 7 +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, 8 +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, 9 +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, 10 +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, 11 +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, 12 +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, 13 +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, 14 +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, 15 +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, 16 +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, 17 +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, 18 +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, 19 +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, 20 +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, 21 +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, 22 +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, 23 +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, 24 +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, 25 +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, 26 +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, 27 +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, 28 +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, 29 +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, 30 +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, 31 +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, 32 +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, 33 +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, 34 +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, 35 +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, 36 +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, 37 +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, 38 +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, 39 +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, 40 +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, 41 +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, 42 +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, 43 +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, 44 +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, 45 +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, 46 +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, 47 +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, 48 +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, 49 +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, 50 +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, 51 +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, 52 +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, 53 +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, 54 +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, 55 +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, 56 +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, 57 +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, 58 +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, 59 +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, 60 +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, 61 +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} 62 +}; 63 + 64 +local const ct_data static_dtree[D_CODES] = { 65 +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, 66 +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, 67 +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, 68 +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, 69 +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, 70 +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} 71 +}; 72 + 73 +const uch _dist_code[DIST_CODE_LEN] = { 74 + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 75 + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 76 +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 77 +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 78 +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 79 +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 80 +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 81 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 84 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 87 +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 88 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 89 +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 90 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 91 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 92 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 93 +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 94 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 95 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 96 +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 97 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 98 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 99 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 100 +}; 101 + 102 +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { 103 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 104 +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 105 +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 106 +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 107 +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 108 +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 109 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 110 +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 111 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 112 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 113 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 114 +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 115 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 116 +}; 117 + 118 +local const int base_length[LENGTH_CODES] = { 119 +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 120 +64, 80, 96, 112, 128, 160, 192, 224, 0 121 +}; 122 + 123 +local const int base_dist[D_CODES] = { 124 + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 125 + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 126 + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 127 +}; 128 +
Added zlib/uncompr.c version [6977e5c6f5954d97]
1 +/* uncompr.c -- decompress a memory buffer 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* @(#) $Id$ */ 7 + 8 +#include "zlib.h" 9 + 10 +/* =========================================================================== 11 + Decompresses the source buffer into the destination buffer. sourceLen is 12 + the byte length of the source buffer. Upon entry, destLen is the total 13 + size of the destination buffer, which must be large enough to hold the 14 + entire uncompressed data. (The size of the uncompressed data must have 15 + been saved previously by the compressor and transmitted to the decompressor 16 + by some mechanism outside the scope of this compression library.) 17 + Upon exit, destLen is the actual size of the compressed buffer. 18 + This function can be used to decompress a whole file at once if the 19 + input file is mmap'ed. 20 + 21 + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not 22 + enough memory, Z_BUF_ERROR if there was not enough room in the output 23 + buffer, or Z_DATA_ERROR if the input data was corrupted. 24 +*/ 25 +int ZEXPORT uncompress (dest, destLen, source, sourceLen) 26 + Bytef *dest; 27 + uLongf *destLen; 28 + const Bytef *source; 29 + uLong sourceLen; 30 +{ 31 + z_stream stream; 32 + int err; 33 + 34 + stream.next_in = (Bytef*)source; 35 + stream.avail_in = (uInt)sourceLen; 36 + /* Check for source > 64K on 16-bit machine: */ 37 + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 38 + 39 + stream.next_out = dest; 40 + stream.avail_out = (uInt)*destLen; 41 + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 42 + 43 + stream.zalloc = (alloc_func)0; 44 + stream.zfree = (free_func)0; 45 + 46 + err = inflateInit(&stream); 47 + if (err != Z_OK) return err; 48 + 49 + err = inflate(&stream, Z_FINISH); 50 + if (err != Z_STREAM_END) { 51 + inflateEnd(&stream); 52 + return err == Z_OK ? Z_BUF_ERROR : err; 53 + } 54 + *destLen = stream.total_out; 55 + 56 + err = inflateEnd(&stream); 57 + return err; 58 +}
Added zlib/zconf.h version [0b119057717e40de]
1 + 2 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 3 +/*= This source is Modified a little by K.INABA. =*/ 4 +/*= =*/ 5 +/*= Since 'XacRett' doesn't compress, I removed =*/ 6 +/*= compression codes by #ifdef KI_GZ_NO_COMPRESSION . =*/ 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +#ifndef KI_GZ_NO_COMPRESSION 9 +#define KI_GZ_NO_COMPRESSION 10 +#endif 11 + 12 +/* zconf.h -- configuration of the zlib compression library 13 + * Copyright (C) 1995-1998 Jean-loup Gailly. 14 + * For conditions of distribution and use, see copyright notice in zlib.h 15 + */ 16 + 17 +/* @(#) $Id$ */ 18 + 19 +#ifndef _ZCONF_H 20 +#define _ZCONF_H 21 + 22 +/* 23 + * If you *really* need a unique prefix for all types and library functions, 24 + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. 25 + */ 26 +#ifdef Z_PREFIX 27 +# define deflateInit_ z_deflateInit_ 28 +# define deflate z_deflate 29 +# define deflateEnd z_deflateEnd 30 +# define inflateInit_ z_inflateInit_ 31 +# define inflate z_inflate 32 +# define inflateEnd z_inflateEnd 33 +# define deflateInit2_ z_deflateInit2_ 34 +# define deflateSetDictionary z_deflateSetDictionary 35 +# define deflateCopy z_deflateCopy 36 +# define deflateReset z_deflateReset 37 +# define deflateParams z_deflateParams 38 +# define inflateInit2_ z_inflateInit2_ 39 +# define inflateSetDictionary z_inflateSetDictionary 40 +# define inflateSync z_inflateSync 41 +# define inflateSyncPoint z_inflateSyncPoint 42 +# define inflateReset z_inflateReset 43 +# define compress z_compress 44 +# define compress2 z_compress2 45 +# define uncompress z_uncompress 46 +# define adler32 z_adler32 47 +# define crc32 z_crc32 48 +# define get_crc_table z_get_crc_table 49 + 50 +# define Byte z_Byte 51 +# define uInt z_uInt 52 +# define uLong z_uLong 53 +# define Bytef z_Bytef 54 +# define charf z_charf 55 +# define intf z_intf 56 +# define uIntf z_uIntf 57 +# define uLongf z_uLongf 58 +# define voidpf z_voidpf 59 +# define voidp z_voidp 60 +#endif 61 + 62 +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) 63 +# define WIN32 64 +#endif 65 +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) 66 +# ifndef __32BIT__ 67 +# define __32BIT__ 68 +# endif 69 +#endif 70 +#if defined(__MSDOS__) && !defined(MSDOS) 71 +# define MSDOS 72 +#endif 73 + 74 +/* 75 + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more 76 + * than 64k bytes at a time (needed on systems with 16-bit int). 77 + */ 78 +#if defined(MSDOS) && !defined(__32BIT__) 79 +# define MAXSEG_64K 80 +#endif 81 +#ifdef MSDOS 82 +# define UNALIGNED_OK 83 +#endif 84 + 85 +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) 86 +# define STDC 87 +#endif 88 +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) 89 +# ifndef STDC 90 +# define STDC 91 +# endif 92 +#endif 93 + 94 +#ifndef STDC 95 +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ 96 +# define const 97 +# endif 98 +#endif 99 + 100 +/* Some Mac compilers merge all .h files incorrectly: */ 101 +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) 102 +# define NO_DUMMY_DECL 103 +#endif 104 + 105 +/* Old Borland C incorrectly complains about missing returns: */ 106 +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) 107 +# define NEED_DUMMY_RETURN 108 +#endif 109 + 110 + 111 +/* Maximum value for memLevel in deflateInit2 */ 112 +#ifndef MAX_MEM_LEVEL 113 +# ifdef MAXSEG_64K 114 +# define MAX_MEM_LEVEL 8 115 +# else 116 +# define MAX_MEM_LEVEL 9 117 +# endif 118 +#endif 119 + 120 +/* Maximum value for windowBits in deflateInit2 and inflateInit2. 121 + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files 122 + * created by gzip. (Files created by minigzip can still be extracted by 123 + * gzip.) 124 + */ 125 +#ifndef MAX_WBITS 126 +# define MAX_WBITS 15 /* 32K LZ77 window */ 127 +#endif 128 + 129 +/* The memory requirements for deflate are (in bytes): 130 + (1 << (windowBits+2)) + (1 << (memLevel+9)) 131 + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) 132 + plus a few kilobytes for small objects. For example, if you want to reduce 133 + the default memory requirements from 256K to 128K, compile with 134 + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" 135 + Of course this will generally degrade compression (there's no free lunch). 136 + 137 + The memory requirements for inflate are (in bytes) 1 << windowBits 138 + that is, 32K for windowBits=15 (default value) plus a few kilobytes 139 + for small objects. 140 +*/ 141 + 142 + /* Type declarations */ 143 + 144 +#ifndef OF /* function prototypes */ 145 +# ifdef STDC 146 +# define OF(args) args 147 +# else 148 +# define OF(args) () 149 +# endif 150 +#endif 151 + 152 +/* The following definitions for FAR are needed only for MSDOS mixed 153 + * model programming (small or medium model with some far allocations). 154 + * This was tested only with MSC; for other MSDOS compilers you may have 155 + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, 156 + * just define FAR to be empty. 157 + */ 158 +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) 159 + /* MSC small or medium model */ 160 +# define SMALL_MEDIUM 161 +# ifdef _MSC_VER 162 +# define FAR _far 163 +# else 164 +# define FAR far 165 +# endif 166 +#endif 167 +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) 168 +# ifndef __32BIT__ 169 +# define SMALL_MEDIUM 170 +# define FAR _far 171 +# endif 172 +#endif 173 + 174 +/* Compile with -DZLIB_DLL for Windows DLL support */ 175 +#if defined(ZLIB_DLL) 176 +# if defined(_WINDOWS) || defined(WINDOWS) 177 +# ifdef FAR 178 +# undef FAR 179 +# endif 180 +# include <windows.h> 181 +# define ZEXPORT WINAPI 182 +# ifdef WIN32 183 +# define ZEXPORTVA WINAPIV 184 +# else 185 +# define ZEXPORTVA FAR _cdecl _export 186 +# endif 187 +# endif 188 +# if defined (__BORLANDC__) 189 +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) 190 +# include <windows.h> 191 +# define ZEXPORT __declspec(dllexport) WINAPI 192 +# define ZEXPORTRVA __declspec(dllexport) WINAPIV 193 +# else 194 +# if defined (_Windows) && defined (__DLL__) 195 +# define ZEXPORT _export 196 +# define ZEXPORTVA _export 197 +# endif 198 +# endif 199 +# endif 200 +#endif 201 + 202 +#if defined (__BEOS__) 203 +# if defined (ZLIB_DLL) 204 +# define ZEXTERN extern __declspec(dllexport) 205 +# else 206 +# define ZEXTERN extern __declspec(dllimport) 207 +# endif 208 +#endif 209 + 210 +#ifndef ZEXPORT 211 +# define ZEXPORT 212 +#endif 213 +#ifndef ZEXPORTVA 214 +# define ZEXPORTVA 215 +#endif 216 +#ifndef ZEXTERN 217 +# define ZEXTERN extern 218 +#endif 219 + 220 +#ifndef FAR 221 +# define FAR 222 +#endif 223 + 224 +#if !defined(MACOS) && !defined(TARGET_OS_MAC) 225 +typedef unsigned char Byte; /* 8 bits */ 226 +#endif 227 +typedef unsigned int uInt; /* 16 bits or more */ 228 +typedef unsigned long uLong; /* 32 bits or more */ 229 + 230 +#ifdef SMALL_MEDIUM 231 + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ 232 +# define Bytef Byte FAR 233 +#else 234 + typedef Byte FAR Bytef; 235 +#endif 236 +typedef char FAR charf; 237 +typedef int FAR intf; 238 +typedef uInt FAR uIntf; 239 +typedef uLong FAR uLongf; 240 + 241 +#ifdef STDC 242 + typedef void FAR *voidpf; 243 + typedef void *voidp; 244 +#else 245 + typedef Byte FAR *voidpf; 246 + typedef Byte *voidp; 247 +#endif 248 + 249 +#ifdef HAVE_UNISTD_H 250 +# include <sys/types.h> /* for off_t */ 251 +# include <unistd.h> /* for SEEK_* and off_t */ 252 +# define z_off_t off_t 253 +#endif 254 +#ifndef SEEK_SET 255 +# define SEEK_SET 0 /* Seek from beginning of file. */ 256 +# define SEEK_CUR 1 /* Seek from current position. */ 257 +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ 258 +#endif 259 +#ifndef z_off_t 260 +# define z_off_t long 261 +#endif 262 + 263 +/* MVS linker does not support external names larger than 8 bytes */ 264 +#if defined(__MVS__) 265 +# pragma map(deflateInit_,"DEIN") 266 +# pragma map(deflateInit2_,"DEIN2") 267 +# pragma map(deflateEnd,"DEEND") 268 +# pragma map(inflateInit_,"ININ") 269 +# pragma map(inflateInit2_,"ININ2") 270 +# pragma map(inflateEnd,"INEND") 271 +# pragma map(inflateSync,"INSY") 272 +# pragma map(inflateSetDictionary,"INSEDI") 273 +# pragma map(inflate_blocks,"INBL") 274 +# pragma map(inflate_blocks_new,"INBLNE") 275 +# pragma map(inflate_blocks_free,"INBLFR") 276 +# pragma map(inflate_blocks_reset,"INBLRE") 277 +# pragma map(inflate_codes_free,"INCOFR") 278 +# pragma map(inflate_codes,"INCO") 279 +# pragma map(inflate_fast,"INFA") 280 +# pragma map(inflate_flush,"INFLU") 281 +# pragma map(inflate_mask,"INMA") 282 +# pragma map(inflate_set_dictionary,"INSEDI2") 283 +# pragma map(inflate_copyright,"INCOPY") 284 +# pragma map(inflate_trees_bits,"INTRBI") 285 +# pragma map(inflate_trees_dynamic,"INTRDY") 286 +# pragma map(inflate_trees_fixed,"INTRFI") 287 +# pragma map(inflate_trees_free,"INTRFR") 288 +#endif 289 + 290 +#endif /* _ZCONF_H */
Added zlib/zlib.h version [09c59ea7a73abd0c]
1 + 2 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 3 +/*= This source is Modified a little by K.INABA. =*/ 4 +/*= =*/ 5 +/*= Since 'XacRett' doesn't compress, I removed =*/ 6 +/*= compression codes by #ifdef KI_GZ_NO_COMPRESSION . =*/ 7 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 8 +#ifndef KI_GZ_NO_COMPRESSION 9 +#define KI_GZ_NO_COMPRESSION 10 +#endif 11 + 12 +/* zlib.h -- interface of the 'zlib' general purpose compression library 13 + version 1.1.3, July 9th, 1998 14 + 15 + Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler 16 + 17 + This software is provided 'as-is', without any express or implied 18 + warranty. In no event will the authors be held liable for any damages 19 + arising from the use of this software. 20 + 21 + Permission is granted to anyone to use this software for any purpose, 22 + including commercial applications, and to alter it and redistribute it 23 + freely, subject to the following restrictions: 24 + 25 + 1. The origin of this software must not be misrepresented; you must not 26 + claim that you wrote the original software. If you use this software 27 + in a product, an acknowledgment in the product documentation would be 28 + appreciated but is not required. 29 + 2. Altered source versions must be plainly marked as such, and must not be 30 + misrepresented as being the original software. 31 + 3. This notice may not be removed or altered from any source distribution. 32 + 33 + Jean-loup Gailly Mark Adler 34 + jloup@gzip.org madler@alumni.caltech.edu 35 + 36 + 37 + The data format used by the zlib library is described by RFCs (Request for 38 + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt 39 + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). 40 +*/ 41 + 42 +#ifndef _ZLIB_H 43 +#define _ZLIB_H 44 + 45 +#include "zconf.h" 46 + 47 +#ifdef __cplusplus 48 +extern "C" { 49 +#endif 50 + 51 +#define ZLIB_VERSION "1.1.3" 52 + 53 +/* 54 + The 'zlib' compression library provides in-memory compression and 55 + decompression functions, including integrity checks of the uncompressed 56 + data. This version of the library supports only one compression method 57 + (deflation) but other algorithms will be added later and will have the same 58 + stream interface. 59 + 60 + Compression can be done in a single step if the buffers are large 61 + enough (for example if an input file is mmap'ed), or can be done by 62 + repeated calls of the compression function. In the latter case, the 63 + application must provide more input and/or consume the output 64 + (providing more output space) before each call. 65 + 66 + The library also supports reading and writing files in gzip (.gz) format 67 + with an interface similar to that of stdio. 68 + 69 + The library does not install any signal handler. The decoder checks 70 + the consistency of the compressed data, so the library should never 71 + crash even in case of corrupted input. 72 +*/ 73 + 74 +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); 75 +typedef void (*free_func) OF((voidpf opaque, voidpf address)); 76 + 77 +struct internal_state; 78 + 79 +typedef struct z_stream_s { 80 + Bytef *next_in; /* next input byte */ 81 + uInt avail_in; /* number of bytes available at next_in */ 82 + uLong total_in; /* total nb of input bytes read so far */ 83 + 84 + Bytef *next_out; /* next output byte should be put there */ 85 + uInt avail_out; /* remaining free space at next_out */ 86 + uLong total_out; /* total nb of bytes output so far */ 87 + 88 + char *msg; /* last error message, NULL if no error */ 89 + struct internal_state FAR *state; /* not visible by applications */ 90 + 91 + alloc_func zalloc; /* used to allocate the internal state */ 92 + free_func zfree; /* used to free the internal state */ 93 + voidpf opaque; /* private data object passed to zalloc and zfree */ 94 + 95 + int data_type; /* best guess about the data type: ascii or binary */ 96 + uLong adler; /* adler32 value of the uncompressed data */ 97 + uLong reserved; /* reserved for future use */ 98 +} z_stream; 99 + 100 +typedef z_stream FAR *z_streamp; 101 + 102 +/* 103 + The application must update next_in and avail_in when avail_in has 104 + dropped to zero. It must update next_out and avail_out when avail_out 105 + has dropped to zero. The application must initialize zalloc, zfree and 106 + opaque before calling the init function. All other fields are set by the 107 + compression library and must not be updated by the application. 108 + 109 + The opaque value provided by the application will be passed as the first 110 + parameter for calls of zalloc and zfree. This can be useful for custom 111 + memory management. The compression library attaches no meaning to the 112 + opaque value. 113 + 114 + zalloc must return Z_NULL if there is not enough memory for the object. 115 + If zlib is used in a multi-threaded application, zalloc and zfree must be 116 + thread safe. 117 + 118 + On 16-bit systems, the functions zalloc and zfree must be able to allocate 119 + exactly 65536 bytes, but will not be required to allocate more than this 120 + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, 121 + pointers returned by zalloc for objects of exactly 65536 bytes *must* 122 + have their offset normalized to zero. The default allocation function 123 + provided by this library ensures this (see zutil.c). To reduce memory 124 + requirements and avoid any allocation of 64K objects, at the expense of 125 + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). 126 + 127 + The fields total_in and total_out can be used for statistics or 128 + progress reports. After compression, total_in holds the total size of 129 + the uncompressed data and may be saved for use in the decompressor 130 + (particularly if the decompressor wants to decompress everything in 131 + a single step). 132 +*/ 133 + 134 + /* constants */ 135 + 136 +#define Z_NO_FLUSH 0 137 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ 138 +#define Z_SYNC_FLUSH 2 139 +#define Z_FULL_FLUSH 3 140 +#define Z_FINISH 4 141 +/* Allowed flush values; see deflate() below for details */ 142 + 143 +#define Z_OK 0 144 +#define Z_STREAM_END 1 145 +#define Z_NEED_DICT 2 146 +#define Z_ERRNO (-1) 147 +#define Z_STREAM_ERROR (-2) 148 +#define Z_DATA_ERROR (-3) 149 +#define Z_MEM_ERROR (-4) 150 +#define Z_BUF_ERROR (-5) 151 +#define Z_VERSION_ERROR (-6) 152 +/* Return codes for the compression/decompression functions. Negative 153 + * values are errors, positive values are used for special but normal events. 154 + */ 155 + 156 +#define Z_NO_COMPRESSION 0 157 +#define Z_BEST_SPEED 1 158 +#define Z_BEST_COMPRESSION 9 159 +#define Z_DEFAULT_COMPRESSION (-1) 160 +/* compression levels */ 161 + 162 +#define Z_FILTERED 1 163 +#define Z_HUFFMAN_ONLY 2 164 +#define Z_DEFAULT_STRATEGY 0 165 +/* compression strategy; see deflateInit2() below for details */ 166 + 167 +#define Z_BINARY 0 168 +#define Z_ASCII 1 169 +#define Z_UNKNOWN 2 170 +/* Possible values of the data_type field */ 171 + 172 +#define Z_DEFLATED 8 173 +/* The deflate compression method (the only one supported in this version) */ 174 + 175 +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ 176 + 177 +#define zlib_version zlibVersion() 178 +/* for compatibility with versions < 1.0.2 */ 179 + 180 + /* basic functions */ 181 + 182 +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); 183 +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. 184 + If the first character differs, the library code actually used is 185 + not compatible with the zlib.h header file used by the application. 186 + This check is automatically made by deflateInit and inflateInit. 187 + */ 188 + 189 +/* 190 +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); 191 + 192 + Initializes the internal stream state for compression. The fields 193 + zalloc, zfree and opaque must be initialized before by the caller. 194 + If zalloc and zfree are set to Z_NULL, deflateInit updates them to 195 + use default allocation functions. 196 + 197 + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 198 + 1 gives best speed, 9 gives best compression, 0 gives no compression at 199 + all (the input data is simply copied a block at a time). 200 + Z_DEFAULT_COMPRESSION requests a default compromise between speed and 201 + compression (currently equivalent to level 6). 202 + 203 + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not 204 + enough memory, Z_STREAM_ERROR if level is not a valid compression level, 205 + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible 206 + with the version assumed by the caller (ZLIB_VERSION). 207 + msg is set to null if there is no error message. deflateInit does not 208 + perform any compression: this will be done by deflate(). 209 +*/ 210 + 211 +#ifndef KI_GZ_NO_COMPRESSION 212 + 213 +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); 214 +/* 215 + deflate compresses as much data as possible, and stops when the input 216 + buffer becomes empty or the output buffer becomes full. It may introduce some 217 + output latency (reading input without producing any output) except when 218 + forced to flush. 219 + 220 + The detailed semantics are as follows. deflate performs one or both of the 221 + following actions: 222 + 223 + - Compress more input starting at next_in and update next_in and avail_in 224 + accordingly. If not all input can be processed (because there is not 225 + enough room in the output buffer), next_in and avail_in are updated and 226 + processing will resume at this point for the next call of deflate(). 227 + 228 + - Provide more output starting at next_out and update next_out and avail_out 229 + accordingly. This action is forced if the parameter flush is non zero. 230 + Forcing flush frequently degrades the compression ratio, so this parameter 231 + should be set only when necessary (in interactive applications). 232 + Some output may be provided even if flush is not set. 233 + 234 + Before the call of deflate(), the application should ensure that at least 235 + one of the actions is possible, by providing more input and/or consuming 236 + more output, and updating avail_in or avail_out accordingly; avail_out 237 + should never be zero before the call. The application can consume the 238 + compressed output when it wants, for example when the output buffer is full 239 + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK 240 + and with zero avail_out, it must be called again after making room in the 241 + output buffer because there might be more output pending. 242 + 243 + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is 244 + flushed to the output buffer and the output is aligned on a byte boundary, so 245 + that the decompressor can get all input data available so far. (In particular 246 + avail_in is zero after the call if enough output space has been provided 247 + before the call.) Flushing may degrade compression for some compression 248 + algorithms and so it should be used only when necessary. 249 + 250 + If flush is set to Z_FULL_FLUSH, all output is flushed as with 251 + Z_SYNC_FLUSH, and the compression state is reset so that decompression can 252 + restart from this point if previous compressed data has been damaged or if 253 + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade 254 + the compression. 255 + 256 + If deflate returns with avail_out == 0, this function must be called again 257 + with the same value of the flush parameter and more output space (updated 258 + avail_out), until the flush is complete (deflate returns with non-zero 259 + avail_out). 260 + 261 + If the parameter flush is set to Z_FINISH, pending input is processed, 262 + pending output is flushed and deflate returns with Z_STREAM_END if there 263 + was enough output space; if deflate returns with Z_OK, this function must be 264 + called again with Z_FINISH and more output space (updated avail_out) but no 265 + more input data, until it returns with Z_STREAM_END or an error. After 266 + deflate has returned Z_STREAM_END, the only possible operations on the 267 + stream are deflateReset or deflateEnd. 268 + 269 + Z_FINISH can be used immediately after deflateInit if all the compression 270 + is to be done in a single step. In this case, avail_out must be at least 271 + 0.1% larger than avail_in plus 12 bytes. If deflate does not return 272 + Z_STREAM_END, then it must be called again as described above. 273 + 274 + deflate() sets strm->adler to the adler32 checksum of all input read 275 + so far (that is, total_in bytes). 276 + 277 + deflate() may update data_type if it can make a good guess about 278 + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered 279 + binary. This field is only for information purposes and does not affect 280 + the compression algorithm in any manner. 281 + 282 + deflate() returns Z_OK if some progress has been made (more input 283 + processed or more output produced), Z_STREAM_END if all input has been 284 + consumed and all output has been produced (only when flush is set to 285 + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example 286 + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible 287 + (for example avail_in or avail_out was zero). 288 +*/ 289 + 290 + 291 +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); 292 +/* 293 + All dynamically allocated data structures for this stream are freed. 294 + This function discards any unprocessed input and does not flush any 295 + pending output. 296 + 297 + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the 298 + stream state was inconsistent, Z_DATA_ERROR if the stream was freed 299 + prematurely (some input or output was discarded). In the error case, 300 + msg may be set but then points to a static string (which must not be 301 + deallocated). 302 +*/ 303 + 304 +#endif /* KI_GZ_NO_COMPRESSION */ 305 + 306 +/* 307 +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); 308 + 309 + Initializes the internal stream state for decompression. The fields 310 + next_in, avail_in, zalloc, zfree and opaque must be initialized before by 311 + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact 312 + value depends on the compression method), inflateInit determines the 313 + compression method from the zlib header and allocates all data structures 314 + accordingly; otherwise the allocation will be deferred to the first call of 315 + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to 316 + use default allocation functions. 317 + 318 + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough 319 + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the 320 + version assumed by the caller. msg is set to null if there is no error 321 + message. inflateInit does not perform any decompression apart from reading 322 + the zlib header if present: this will be done by inflate(). (So next_in and 323 + avail_in may be modified, but next_out and avail_out are unchanged.) 324 +*/ 325 + 326 + 327 +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); 328 +/* 329 + inflate decompresses as much data as possible, and stops when the input 330 + buffer becomes empty or the output buffer becomes full. It may some 331 + introduce some output latency (reading input without producing any output) 332 + except when forced to flush. 333 + 334 + The detailed semantics are as follows. inflate performs one or both of the 335 + following actions: 336 + 337 + - Decompress more input starting at next_in and update next_in and avail_in 338 + accordingly. If not all input can be processed (because there is not 339 + enough room in the output buffer), next_in is updated and processing 340 + will resume at this point for the next call of inflate(). 341 + 342 + - Provide more output starting at next_out and update next_out and avail_out 343 + accordingly. inflate() provides as much output as possible, until there 344 + is no more input data or no more space in the output buffer (see below 345 + about the flush parameter). 346 + 347 + Before the call of inflate(), the application should ensure that at least 348 + one of the actions is possible, by providing more input and/or consuming 349 + more output, and updating the next_* and avail_* values accordingly. 350 + The application can consume the uncompressed output when it wants, for 351 + example when the output buffer is full (avail_out == 0), or after each 352 + call of inflate(). If inflate returns Z_OK and with zero avail_out, it 353 + must be called again after making room in the output buffer because there 354 + might be more output pending. 355 + 356 + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much 357 + output as possible to the output buffer. The flushing behavior of inflate is 358 + not specified for values of the flush parameter other than Z_SYNC_FLUSH 359 + and Z_FINISH, but the current implementation actually flushes as much output 360 + as possible anyway. 361 + 362 + inflate() should normally be called until it returns Z_STREAM_END or an 363 + error. However if all decompression is to be performed in a single step 364 + (a single call of inflate), the parameter flush should be set to 365 + Z_FINISH. In this case all pending input is processed and all pending 366 + output is flushed; avail_out must be large enough to hold all the 367 + uncompressed data. (The size of the uncompressed data may have been saved 368 + by the compressor for this purpose.) The next operation on this stream must 369 + be inflateEnd to deallocate the decompression state. The use of Z_FINISH 370 + is never required, but can be used to inform inflate that a faster routine 371 + may be used for the single inflate() call. 372 + 373 + If a preset dictionary is needed at this point (see inflateSetDictionary 374 + below), inflate sets strm-adler to the adler32 checksum of the 375 + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 376 + it sets strm->adler to the adler32 checksum of all output produced 377 + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or 378 + an error code as described below. At the end of the stream, inflate() 379 + checks that its computed adler32 checksum is equal to that saved by the 380 + compressor and returns Z_STREAM_END only if the checksum is correct. 381 + 382 + inflate() returns Z_OK if some progress has been made (more input processed 383 + or more output produced), Z_STREAM_END if the end of the compressed data has 384 + been reached and all uncompressed output has been produced, Z_NEED_DICT if a 385 + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was 386 + corrupted (input stream not conforming to the zlib format or incorrect 387 + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent 388 + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not 389 + enough memory, Z_BUF_ERROR if no progress is possible or if there was not 390 + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR 391 + case, the application may then call inflateSync to look for a good 392 + compression block. 393 +*/ 394 + 395 + 396 +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); 397 +/* 398 + All dynamically allocated data structures for this stream are freed. 399 + This function discards any unprocessed input and does not flush any 400 + pending output. 401 + 402 + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state 403 + was inconsistent. In the error case, msg may be set but then points to a 404 + static string (which must not be deallocated). 405 +*/ 406 + 407 + /* Advanced functions */ 408 + 409 +/* 410 + The following functions are needed only in some special applications. 411 +*/ 412 + 413 +/* 414 +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, 415 + int level, 416 + int method, 417 + int windowBits, 418 + int memLevel, 419 + int strategy)); 420 + 421 + This is another version of deflateInit with more compression options. The 422 + fields next_in, zalloc, zfree and opaque must be initialized before by 423 + the caller. 424 + 425 + The method parameter is the compression method. It must be Z_DEFLATED in 426 + this version of the library. 427 + 428 + The windowBits parameter is the base two logarithm of the window size 429 + (the size of the history buffer). It should be in the range 8..15 for this 430 + version of the library. Larger values of this parameter result in better 431 + compression at the expense of memory usage. The default value is 15 if 432 + deflateInit is used instead. 433 + 434 + The memLevel parameter specifies how much memory should be allocated 435 + for the internal compression state. memLevel=1 uses minimum memory but 436 + is slow and reduces compression ratio; memLevel=9 uses maximum memory 437 + for optimal speed. The default value is 8. See zconf.h for total memory 438 + usage as a function of windowBits and memLevel. 439 + 440 + The strategy parameter is used to tune the compression algorithm. Use the 441 + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a 442 + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no 443 + string match). Filtered data consists mostly of small values with a 444 + somewhat random distribution. In this case, the compression algorithm is 445 + tuned to compress them better. The effect of Z_FILTERED is to force more 446 + Huffman coding and less string matching; it is somewhat intermediate 447 + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects 448 + the compression ratio but not the correctness of the compressed output even 449 + if it is not set appropriately. 450 + 451 + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 452 + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid 453 + method). msg is set to null if there is no error message. deflateInit2 does 454 + not perform any compression: this will be done by deflate(). 455 +*/ 456 + 457 +#ifndef KI_GZ_NO_COMPRESSION 458 + 459 +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, 460 + const Bytef *dictionary, 461 + uInt dictLength)); 462 +/* 463 + Initializes the compression dictionary from the given byte sequence 464 + without producing any compressed output. This function must be called 465 + immediately after deflateInit, deflateInit2 or deflateReset, before any 466 + call of deflate. The compressor and decompressor must use exactly the same 467 + dictionary (see inflateSetDictionary). 468 + 469 + The dictionary should consist of strings (byte sequences) that are likely 470 + to be encountered later in the data to be compressed, with the most commonly 471 + used strings preferably put towards the end of the dictionary. Using a 472 + dictionary is most useful when the data to be compressed is short and can be 473 + predicted with good accuracy; the data can then be compressed better than 474 + with the default empty dictionary. 475 + 476 + Depending on the size of the compression data structures selected by 477 + deflateInit or deflateInit2, a part of the dictionary may in effect be 478 + discarded, for example if the dictionary is larger than the window size in 479 + deflate or deflate2. Thus the strings most likely to be useful should be 480 + put at the end of the dictionary, not at the front. 481 + 482 + Upon return of this function, strm->adler is set to the Adler32 value 483 + of the dictionary; the decompressor may later use this value to determine 484 + which dictionary has been used by the compressor. (The Adler32 value 485 + applies to the whole dictionary even if only a subset of the dictionary is 486 + actually used by the compressor.) 487 + 488 + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a 489 + parameter is invalid (such as NULL dictionary) or the stream state is 490 + inconsistent (for example if deflate has already been called for this stream 491 + or if the compression method is bsort). deflateSetDictionary does not 492 + perform any compression: this will be done by deflate(). 493 +*/ 494 + 495 +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, 496 + z_streamp source)); 497 +/* 498 + Sets the destination stream as a complete copy of the source stream. 499 + 500 + This function can be useful when several compression strategies will be 501 + tried, for example when there are several ways of pre-processing the input 502 + data with a filter. The streams that will be discarded should then be freed 503 + by calling deflateEnd. Note that deflateCopy duplicates the internal 504 + compression state which can be quite large, so this strategy is slow and 505 + can consume lots of memory. 506 + 507 + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not 508 + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent 509 + (such as zalloc being NULL). msg is left unchanged in both source and 510 + destination. 511 +*/ 512 + 513 +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); 514 +/* 515 + This function is equivalent to deflateEnd followed by deflateInit, 516 + but does not free and reallocate all the internal compression state. 517 + The stream will keep the same compression level and any other attributes 518 + that may have been set by deflateInit2. 519 + 520 + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 521 + stream state was inconsistent (such as zalloc or state being NULL). 522 +*/ 523 + 524 +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, 525 + int level, 526 + int strategy)); 527 +/* 528 + Dynamically update the compression level and compression strategy. The 529 + interpretation of level and strategy is as in deflateInit2. This can be 530 + used to switch between compression and straight copy of the input data, or 531 + to switch to a different kind of input data requiring a different 532 + strategy. If the compression level is changed, the input available so far 533 + is compressed with the old level (and may be flushed); the new level will 534 + take effect only at the next call of deflate(). 535 + 536 + Before the call of deflateParams, the stream state must be set as for 537 + a call of deflate(), since the currently available input may have to 538 + be compressed and flushed. In particular, strm->avail_out must be non-zero. 539 + 540 + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source 541 + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR 542 + if strm->avail_out was zero. 543 +*/ 544 + 545 +#endif /* KI_GZ_NO_COMPRESSION */ 546 + 547 +/* 548 +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, 549 + int windowBits)); 550 + 551 + This is another version of inflateInit with an extra parameter. The 552 + fields next_in, avail_in, zalloc, zfree and opaque must be initialized 553 + before by the caller. 554 + 555 + The windowBits parameter is the base two logarithm of the maximum window 556 + size (the size of the history buffer). It should be in the range 8..15 for 557 + this version of the library. The default value is 15 if inflateInit is used 558 + instead. If a compressed stream with a larger window size is given as 559 + input, inflate() will return with the error code Z_DATA_ERROR instead of 560 + trying to allocate a larger window. 561 + 562 + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 563 + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative 564 + memLevel). msg is set to null if there is no error message. inflateInit2 565 + does not perform any decompression apart from reading the zlib header if 566 + present: this will be done by inflate(). (So next_in and avail_in may be 567 + modified, but next_out and avail_out are unchanged.) 568 +*/ 569 + 570 +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, 571 + const Bytef *dictionary, 572 + uInt dictLength)); 573 +/* 574 + Initializes the decompression dictionary from the given uncompressed byte 575 + sequence. This function must be called immediately after a call of inflate 576 + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor 577 + can be determined from the Adler32 value returned by this call of 578 + inflate. The compressor and decompressor must use exactly the same 579 + dictionary (see deflateSetDictionary). 580 + 581 + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a 582 + parameter is invalid (such as NULL dictionary) or the stream state is 583 + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the 584 + expected one (incorrect Adler32 value). inflateSetDictionary does not 585 + perform any decompression: this will be done by subsequent calls of 586 + inflate(). 587 +*/ 588 + 589 +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); 590 +/* 591 + Skips invalid compressed data until a full flush point (see above the 592 + description of deflate with Z_FULL_FLUSH) can be found, or until all 593 + available input is skipped. No output is provided. 594 + 595 + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR 596 + if no more input was provided, Z_DATA_ERROR if no flush point has been found, 597 + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success 598 + case, the application may save the current current value of total_in which 599 + indicates where valid compressed data was found. In the error case, the 600 + application may repeatedly call inflateSync, providing more input each time, 601 + until success or end of the input data. 602 +*/ 603 + 604 +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); 605 +/* 606 + This function is equivalent to inflateEnd followed by inflateInit, 607 + but does not free and reallocate all the internal decompression state. 608 + The stream will keep attributes that may have been set by inflateInit2. 609 + 610 + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 611 + stream state was inconsistent (such as zalloc or state being NULL). 612 +*/ 613 + 614 + 615 + /* utility functions */ 616 + 617 +/* 618 + The following utility functions are implemented on top of the 619 + basic stream-oriented functions. To simplify the interface, some 620 + default options are assumed (compression level and memory usage, 621 + standard memory allocation functions). The source code of these 622 + utility functions can easily be modified if you need special options. 623 +*/ 624 + 625 +#ifndef KI_GZ_NO_COMPRESSION 626 + 627 +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, 628 + const Bytef *source, uLong sourceLen)); 629 +/* 630 + Compresses the source buffer into the destination buffer. sourceLen is 631 + the byte length of the source buffer. Upon entry, destLen is the total 632 + size of the destination buffer, which must be at least 0.1% larger than 633 + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the 634 + compressed buffer. 635 + This function can be used to compress a whole file at once if the 636 + input file is mmap'ed. 637 + compress returns Z_OK if success, Z_MEM_ERROR if there was not 638 + enough memory, Z_BUF_ERROR if there was not enough room in the output 639 + buffer. 640 +*/ 641 + 642 +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, 643 + const Bytef *source, uLong sourceLen, 644 + int level)); 645 +/* 646 + Compresses the source buffer into the destination buffer. The level 647 + parameter has the same meaning as in deflateInit. sourceLen is the byte 648 + length of the source buffer. Upon entry, destLen is the total size of the 649 + destination buffer, which must be at least 0.1% larger than sourceLen plus 650 + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 651 + 652 + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 653 + memory, Z_BUF_ERROR if there was not enough room in the output buffer, 654 + Z_STREAM_ERROR if the level parameter is invalid. 655 +*/ 656 + 657 +#endif /* KI_GZ_NO_COMPRESSION */ 658 + 659 +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, 660 + const Bytef *source, uLong sourceLen)); 661 +/* 662 + Decompresses the source buffer into the destination buffer. sourceLen is 663 + the byte length of the source buffer. Upon entry, destLen is the total 664 + size of the destination buffer, which must be large enough to hold the 665 + entire uncompressed data. (The size of the uncompressed data must have 666 + been saved previously by the compressor and transmitted to the decompressor 667 + by some mechanism outside the scope of this compression library.) 668 + Upon exit, destLen is the actual size of the compressed buffer. 669 + This function can be used to decompress a whole file at once if the 670 + input file is mmap'ed. 671 + 672 + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not 673 + enough memory, Z_BUF_ERROR if there was not enough room in the output 674 + buffer, or Z_DATA_ERROR if the input data was corrupted. 675 +*/ 676 + 677 + 678 +typedef voidp gzFile; 679 + 680 +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); 681 +/* 682 + Opens a gzip (.gz) file for reading or writing. The mode parameter 683 + is as in fopen ("rb" or "wb") but can also include a compression level 684 + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for 685 + Huffman only compression as in "wb1h". (See the description 686 + of deflateInit2 for more information about the strategy parameter.) 687 + 688 + gzopen can be used to read a file which is not in gzip format; in this 689 + case gzread will directly read from the file without decompression. 690 + 691 + gzopen returns NULL if the file could not be opened or if there was 692 + insufficient memory to allocate the (de)compression state; errno 693 + can be checked to distinguish the two cases (if errno is zero, the 694 + zlib error is Z_MEM_ERROR). */ 695 + 696 +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); 697 +/* 698 + gzdopen() associates a gzFile with the file descriptor fd. File 699 + descriptors are obtained from calls like open, dup, creat, pipe or 700 + fileno (in the file has been previously opened with fopen). 701 + The mode parameter is as in gzopen. 702 + The next call of gzclose on the returned gzFile will also close the 703 + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file 704 + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). 705 + gzdopen returns NULL if there was insufficient memory to allocate 706 + the (de)compression state. 707 +*/ 708 + 709 +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); 710 +/* 711 + Dynamically update the compression level or strategy. See the description 712 + of deflateInit2 for the meaning of these parameters. 713 + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not 714 + opened for writing. 715 +*/ 716 + 717 +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); 718 +/* 719 + Reads the given number of uncompressed bytes from the compressed file. 720 + If the input file was not in gzip format, gzread copies the given number 721 + of bytes into the buffer. 722 + gzread returns the number of uncompressed bytes actually read (0 for 723 + end of file, -1 for error). */ 724 + 725 +#ifndef KI_GZ_NO_COMPRESSION 726 + 727 +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, 728 + const voidp buf, unsigned len)); 729 +/* 730 + Writes the given number of uncompressed bytes into the compressed file. 731 + gzwrite returns the number of uncompressed bytes actually written 732 + (0 in case of error). 733 +*/ 734 + 735 +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); 736 +/* 737 + Converts, formats, and writes the args to the compressed file under 738 + control of the format string, as in fprintf. gzprintf returns the number of 739 + uncompressed bytes actually written (0 in case of error). 740 +*/ 741 + 742 +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); 743 +/* 744 + Writes the given null-terminated string to the compressed file, excluding 745 + the terminating null character. 746 + gzputs returns the number of characters written, or -1 in case of error. 747 +*/ 748 + 749 +#endif /* KI_GZ_NO_COMPRESSION */ 750 + 751 +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); 752 +/* 753 + Reads bytes from the compressed file until len-1 characters are read, or 754 + a newline character is read and transferred to buf, or an end-of-file 755 + condition is encountered. The string is then terminated with a null 756 + character. 757 + gzgets returns buf, or Z_NULL in case of error. 758 +*/ 759 + 760 +#ifdef KI_GZ_NO_COMPRESSION 761 + 762 +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); 763 +/* 764 + Writes c, converted to an unsigned char, into the compressed file. 765 + gzputc returns the value that was written, or -1 in case of error. 766 +*/ 767 + 768 +#endif /* KI_GZ_NO_COMPRESSION */ 769 + 770 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); 771 +/* 772 + Reads one byte from the compressed file. gzgetc returns this byte 773 + or -1 in case of end of file or error. 774 +*/ 775 + 776 +#ifndef KI_GZ_NO_COMPRESSION 777 +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); 778 +/* 779 + Flushes all pending output into the compressed file. The parameter 780 + flush is as in the deflate() function. The return value is the zlib 781 + error number (see function gzerror below). gzflush returns Z_OK if 782 + the flush parameter is Z_FINISH and all output could be flushed. 783 + gzflush should be called only when strictly necessary because it can 784 + degrade compression. 785 +*/ 786 +#endif /* KI_GZ_NO_COMPRESSION */ 787 + 788 +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, 789 + z_off_t offset, int whence)); 790 +/* 791 + Sets the starting position for the next gzread or gzwrite on the 792 + given compressed file. The offset represents a number of bytes in the 793 + uncompressed data stream. The whence parameter is defined as in lseek(2); 794 + the value SEEK_END is not supported. 795 + If the file is opened for reading, this function is emulated but can be 796 + extremely slow. If the file is opened for writing, only forward seeks are 797 + supported; gzseek then compresses a sequence of zeroes up to the new 798 + starting position. 799 + 800 + gzseek returns the resulting offset location as measured in bytes from 801 + the beginning of the uncompressed stream, or -1 in case of error, in 802 + particular if the file is opened for writing and the new starting position 803 + would be before the current position. 804 +*/ 805 + 806 +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); 807 +/* 808 + Rewinds the given file. This function is supported only for reading. 809 + 810 + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) 811 +*/ 812 + 813 +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); 814 +/* 815 + Returns the starting position for the next gzread or gzwrite on the 816 + given compressed file. This position represents a number of bytes in the 817 + uncompressed data stream. 818 + 819 + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) 820 +*/ 821 + 822 +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); 823 +/* 824 + Returns 1 when EOF has previously been detected reading the given 825 + input stream, otherwise zero. 826 +*/ 827 + 828 +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); 829 +/* 830 + Flushes all pending output if necessary, closes the compressed file 831 + and deallocates all the (de)compression state. The return value is the zlib 832 + error number (see function gzerror below). 833 +*/ 834 + 835 +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); 836 +/* 837 + Returns the error message for the last error which occurred on the 838 + given compressed file. errnum is set to zlib error number. If an 839 + error occurred in the file system and not in the compression library, 840 + errnum is set to Z_ERRNO and the application may consult errno 841 + to get the exact error code. 842 +*/ 843 + 844 + /* checksum functions */ 845 + 846 +/* 847 + These functions are not related to compression but are exported 848 + anyway because they might be useful in applications using the 849 + compression library. 850 +*/ 851 + 852 +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); 853 + 854 +/* 855 + Update a running Adler-32 checksum with the bytes buf[0..len-1] and 856 + return the updated checksum. If buf is NULL, this function returns 857 + the required initial value for the checksum. 858 + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed 859 + much faster. Usage example: 860 + 861 + uLong adler = adler32(0L, Z_NULL, 0); 862 + 863 + while (read_buffer(buffer, length) != EOF) { 864 + adler = adler32(adler, buffer, length); 865 + } 866 + if (adler != original_adler) error(); 867 +*/ 868 + 869 +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); 870 +/* 871 + Update a running crc with the bytes buf[0..len-1] and return the updated 872 + crc. If buf is NULL, this function returns the required initial value 873 + for the crc. Pre- and post-conditioning (one's complement) is performed 874 + within this function so it shouldn't be done by the application. 875 + Usage example: 876 + 877 + uLong crc = crc32(0L, Z_NULL, 0); 878 + 879 + while (read_buffer(buffer, length) != EOF) { 880 + crc = crc32(crc, buffer, length); 881 + } 882 + if (crc != original_crc) error(); 883 +*/ 884 + 885 + 886 + /* various hacks, don't look :) */ 887 + 888 +/* deflateInit and inflateInit are macros to allow checking the zlib version 889 + * and the compiler's view of z_stream: 890 + */ 891 +#ifndef KI_GZ_NO_COMPRESSION 892 +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, 893 + const char *version, int stream_size)); 894 +#endif /* KI_GZ_NO_COMPRESSION */ 895 +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, 896 + const char *version, int stream_size)); 897 +#ifndef KI_GZ_NO_COMPRESSION 898 +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, 899 + int windowBits, int memLevel, 900 + int strategy, const char *version, 901 + int stream_size)); 902 +#endif /* KI_GZ_NO_COMPRESSION */ 903 +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, 904 + const char *version, int stream_size)); 905 +#define deflateInit(strm, level) \ 906 + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) 907 +#define inflateInit(strm) \ 908 + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) 909 +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ 910 + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ 911 + (strategy), ZLIB_VERSION, sizeof(z_stream)) 912 +#define inflateInit2(strm, windowBits) \ 913 + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) 914 + 915 + 916 +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) 917 + struct internal_state {int dummy;}; /* hack for buggy compilers */ 918 +#endif 919 + 920 +ZEXTERN const char * ZEXPORT zError OF((int err)); 921 +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); 922 +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); 923 + 924 +#ifdef __cplusplus 925 +} 926 +#endif 927 + 928 +#endif /* _ZLIB_H */
Added zlib/zutil.c version [2109a9eb71192ab0]
1 +/* zutil.c -- target dependent utility functions for the compression library 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* @(#) $Id$ */ 7 + 8 +#include "zutil.h" 9 + 10 +struct internal_state {int dummy;}; /* for buggy compilers */ 11 + 12 +#ifndef STDC 13 +extern void exit OF((int)); 14 +#endif 15 + 16 +const char *z_errmsg[10] = { 17 +"need dictionary", /* Z_NEED_DICT 2 */ 18 +"stream end", /* Z_STREAM_END 1 */ 19 +"", /* Z_OK 0 */ 20 +"file error", /* Z_ERRNO (-1) */ 21 +"stream error", /* Z_STREAM_ERROR (-2) */ 22 +"data error", /* Z_DATA_ERROR (-3) */ 23 +"insufficient memory", /* Z_MEM_ERROR (-4) */ 24 +"buffer error", /* Z_BUF_ERROR (-5) */ 25 +"incompatible version",/* Z_VERSION_ERROR (-6) */ 26 +""}; 27 + 28 + 29 +const char * ZEXPORT zlibVersion() 30 +{ 31 + return ZLIB_VERSION; 32 +} 33 + 34 +#ifdef DEBUG 35 + 36 +# ifndef verbose 37 +# define verbose 0 38 +# endif 39 +int z_verbose = verbose; 40 + 41 +void z_error (m) 42 + char *m; 43 +{ 44 + fprintf(stderr, "%s\n", m); 45 + exit(1); 46 +} 47 +#endif 48 + 49 +/* exported to allow conversion of error code to string for compress() and 50 + * uncompress() 51 + */ 52 +const char * ZEXPORT zError(err) 53 + int err; 54 +{ 55 + return ERR_MSG(err); 56 +} 57 + 58 + 59 +#ifndef HAVE_MEMCPY 60 + 61 +void zmemcpy(dest, source, len) 62 + Bytef* dest; 63 + const Bytef* source; 64 + uInt len; 65 +{ 66 + if (len == 0) return; 67 + do { 68 + *dest++ = *source++; /* ??? to be unrolled */ 69 + } while (--len != 0); 70 +} 71 + 72 +int zmemcmp(s1, s2, len) 73 + const Bytef* s1; 74 + const Bytef* s2; 75 + uInt len; 76 +{ 77 + uInt j; 78 + 79 + for (j = 0; j < len; j++) { 80 + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; 81 + } 82 + return 0; 83 +} 84 + 85 +void zmemzero(dest, len) 86 + Bytef* dest; 87 + uInt len; 88 +{ 89 + if (len == 0) return; 90 + do { 91 + *dest++ = 0; /* ??? to be unrolled */ 92 + } while (--len != 0); 93 +} 94 +#endif 95 + 96 +#ifdef __TURBOC__ 97 +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) 98 +/* Small and medium model in Turbo C are for now limited to near allocation 99 + * with reduced MAX_WBITS and MAX_MEM_LEVEL 100 + */ 101 +# define MY_ZCALLOC 102 + 103 +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes 104 + * and farmalloc(64K) returns a pointer with an offset of 8, so we 105 + * must fix the pointer. Warning: the pointer must be put back to its 106 + * original form in order to free it, use zcfree(). 107 + */ 108 + 109 +#define MAX_PTR 10 110 +/* 10*64K = 640K */ 111 + 112 +local int next_ptr = 0; 113 + 114 +typedef struct ptr_table_s { 115 + voidpf org_ptr; 116 + voidpf new_ptr; 117 +} ptr_table; 118 + 119 +local ptr_table table[MAX_PTR]; 120 +/* This table is used to remember the original form of pointers 121 + * to large buffers (64K). Such pointers are normalized with a zero offset. 122 + * Since MSDOS is not a preemptive multitasking OS, this table is not 123 + * protected from concurrent access. This hack doesn't work anyway on 124 + * a protected system like OS/2. Use Microsoft C instead. 125 + */ 126 + 127 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) 128 +{ 129 + voidpf buf = opaque; /* just to make some compilers happy */ 130 + ulg bsize = (ulg)items*size; 131 + 132 + /* If we allocate less than 65520 bytes, we assume that farmalloc 133 + * will return a usable pointer which doesn't have to be normalized. 134 + */ 135 + if (bsize < 65520L) { 136 + buf = farmalloc(bsize); 137 + if (*(ush*)&buf != 0) return buf; 138 + } else { 139 + buf = farmalloc(bsize + 16L); 140 + } 141 + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; 142 + table[next_ptr].org_ptr = buf; 143 + 144 + /* Normalize the pointer to seg:0 */ 145 + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; 146 + *(ush*)&buf = 0; 147 + table[next_ptr++].new_ptr = buf; 148 + return buf; 149 +} 150 + 151 +void zcfree (voidpf opaque, voidpf ptr) 152 +{ 153 + int n; 154 + if (*(ush*)&ptr != 0) { /* object < 64K */ 155 + farfree(ptr); 156 + return; 157 + } 158 + /* Find the original pointer */ 159 + for (n = 0; n < next_ptr; n++) { 160 + if (ptr != table[n].new_ptr) continue; 161 + 162 + farfree(table[n].org_ptr); 163 + while (++n < next_ptr) { 164 + table[n-1] = table[n]; 165 + } 166 + next_ptr--; 167 + return; 168 + } 169 + ptr = opaque; /* just to make some compilers happy */ 170 + Assert(0, "zcfree: ptr not found"); 171 +} 172 +#endif 173 +#endif /* __TURBOC__ */ 174 + 175 + 176 +#if defined(M_I86) && !defined(__32BIT__) 177 +/* Microsoft C in 16-bit mode */ 178 + 179 +# define MY_ZCALLOC 180 + 181 +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) 182 +# define _halloc halloc 183 +# define _hfree hfree 184 +#endif 185 + 186 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) 187 +{ 188 + if (opaque) opaque = 0; /* to make compiler happy */ 189 + return _halloc((long)items, size); 190 +} 191 + 192 +void zcfree (voidpf opaque, voidpf ptr) 193 +{ 194 + if (opaque) opaque = 0; /* to make compiler happy */ 195 + _hfree(ptr); 196 +} 197 + 198 +#endif /* MSC */ 199 + 200 + 201 +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ 202 + 203 +#ifndef STDC 204 +extern voidp calloc OF((uInt items, uInt size)); 205 +extern void free OF((voidpf ptr)); 206 +#endif 207 + 208 +voidpf zcalloc (opaque, items, size) 209 + voidpf opaque; 210 + unsigned items; 211 + unsigned size; 212 +{ 213 + if (opaque) items += size - size; /* make compiler happy */ 214 + return (voidpf)calloc(items, size); 215 +} 216 + 217 +void zcfree (opaque, ptr) 218 + voidpf opaque; 219 + voidpf ptr; 220 +{ 221 + free(ptr); 222 + if (opaque) return; /* make compiler happy */ 223 +} 224 + 225 +#endif /* MY_ZCALLOC */
Added zlib/zutil.h version [fc044b10a7abc5e4]
1 +/* zutil.h -- internal interface and configuration of the compression library 2 + * Copyright (C) 1995-1998 Jean-loup Gailly. 3 + * For conditions of distribution and use, see copyright notice in zlib.h 4 + */ 5 + 6 +/* WARNING: this file should *not* be used by applications. It is 7 + part of the implementation of the compression library and is 8 + subject to change. Applications should only use zlib.h. 9 + */ 10 + 11 +/* @(#) $Id$ */ 12 + 13 +#ifndef _Z_UTIL_H 14 +#define _Z_UTIL_H 15 + 16 +#include "zlib.h" 17 + 18 +#ifdef STDC 19 +# include <stddef.h> 20 +# include <string.h> 21 +# include <stdlib.h> 22 +#endif 23 +#ifdef NO_ERRNO_H 24 + extern int errno; 25 +#else 26 +# include <errno.h> 27 +#endif 28 + 29 +#ifndef local 30 +# define local static 31 +#endif 32 +/* compile with -Dlocal if your debugger can't find static symbols */ 33 + 34 +typedef unsigned char uch; 35 +typedef uch FAR uchf; 36 +typedef unsigned short ush; 37 +typedef ush FAR ushf; 38 +typedef unsigned long ulg; 39 + 40 +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ 41 +/* (size given to avoid silly warnings with Visual C++) */ 42 + 43 +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] 44 + 45 +#define ERR_RETURN(strm,err) \ 46 + return (strm->msg = (char*)ERR_MSG(err), (err)) 47 +/* To be used only when the state is known to be valid */ 48 + 49 + /* common constants */ 50 + 51 +#ifndef DEF_WBITS 52 +# define DEF_WBITS MAX_WBITS 53 +#endif 54 +/* default windowBits for decompression. MAX_WBITS is for compression only */ 55 + 56 +#if MAX_MEM_LEVEL >= 8 57 +# define DEF_MEM_LEVEL 8 58 +#else 59 +# define DEF_MEM_LEVEL MAX_MEM_LEVEL 60 +#endif 61 +/* default memLevel */ 62 + 63 +#define STORED_BLOCK 0 64 +#define STATIC_TREES 1 65 +#define DYN_TREES 2 66 +/* The three kinds of block type */ 67 + 68 +#define MIN_MATCH 3 69 +#define MAX_MATCH 258 70 +/* The minimum and maximum match lengths */ 71 + 72 +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ 73 + 74 + /* target dependencies */ 75 + 76 +#ifdef MSDOS 77 +# define OS_CODE 0x00 78 +# if defined(__TURBOC__) || defined(__BORLANDC__) 79 +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) 80 + /* Allow compilation with ANSI keywords only enabled */ 81 + void _Cdecl farfree( void *block ); 82 + void *_Cdecl farmalloc( unsigned long nbytes ); 83 +# else 84 +# include <alloc.h> 85 +# endif 86 +# else /* MSC or DJGPP */ 87 +# include <malloc.h> 88 +# endif 89 +#endif 90 + 91 +#ifdef OS2 92 +# define OS_CODE 0x06 93 +#endif 94 + 95 +#ifdef WIN32 /* Window 95 & Windows NT */ 96 +# define OS_CODE 0x0b 97 +#endif 98 + 99 +#if defined(VAXC) || defined(VMS) 100 +# define OS_CODE 0x02 101 +# define F_OPEN(name, mode) \ 102 + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") 103 +#endif 104 + 105 +#ifdef AMIGA 106 +# define OS_CODE 0x01 107 +#endif 108 + 109 +#if defined(ATARI) || defined(atarist) 110 +# define OS_CODE 0x05 111 +#endif 112 + 113 +#if defined(MACOS) || defined(TARGET_OS_MAC) 114 +# define OS_CODE 0x07 115 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 116 +# include <unix.h> /* for fdopen */ 117 +# else 118 +# ifndef fdopen 119 +# define fdopen(fd,mode) NULL /* No fdopen() */ 120 +# endif 121 +# endif 122 +#endif 123 + 124 +#ifdef __50SERIES /* Prime/PRIMOS */ 125 +# define OS_CODE 0x0F 126 +#endif 127 + 128 +#ifdef TOPS20 129 +# define OS_CODE 0x0a 130 +#endif 131 + 132 +#if defined(_BEOS_) || defined(RISCOS) 133 +# define fdopen(fd,mode) NULL /* No fdopen() */ 134 +#endif 135 + 136 +#if (defined(_MSC_VER) && (_MSC_VER > 600)) 137 +# define fdopen(fd,type) _fdopen(fd,type) 138 +#endif 139 + 140 + 141 + /* Common defaults */ 142 + 143 +#ifndef OS_CODE 144 +# define OS_CODE 0x03 /* assume Unix */ 145 +#endif 146 + 147 +#ifndef F_OPEN 148 +# define F_OPEN(name, mode) fopen((name), (mode)) 149 +#endif 150 + 151 + /* functions */ 152 + 153 +#ifdef HAVE_STRERROR 154 + extern char *strerror OF((int)); 155 +# define zstrerror(errnum) strerror(errnum) 156 +#else 157 +# define zstrerror(errnum) "" 158 +#endif 159 + 160 +#if defined(pyr) 161 +# define NO_MEMCPY 162 +#endif 163 +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) 164 + /* Use our own functions for small and medium model with MSC <= 5.0. 165 + * You may have to use the same strategy for Borland C (untested). 166 + * The __SC__ check is for Symantec. 167 + */ 168 +# define NO_MEMCPY 169 +#endif 170 +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) 171 +# define HAVE_MEMCPY 172 +#endif 173 +#ifdef HAVE_MEMCPY 174 +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ 175 +# define zmemcpy _fmemcpy 176 +# define zmemcmp _fmemcmp 177 +# define zmemzero(dest, len) _fmemset(dest, 0, len) 178 +# else 179 +# define zmemcpy memcpy 180 +# define zmemcmp memcmp 181 +# define zmemzero(dest, len) memset(dest, 0, len) 182 +# endif 183 +#else 184 + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); 185 + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); 186 + extern void zmemzero OF((Bytef* dest, uInt len)); 187 +#endif 188 + 189 +/* Diagnostic functions */ 190 +#ifdef DEBUG 191 +# include <stdio.h> 192 + extern int z_verbose; 193 + extern void z_error OF((char *m)); 194 +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} 195 +# define Trace(x) {if (z_verbose>=0) fprintf x ;} 196 +# define Tracev(x) {if (z_verbose>0) fprintf x ;} 197 +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} 198 +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} 199 +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} 200 +#else 201 +# define Assert(cond,msg) 202 +# define Trace(x) 203 +# define Tracev(x) 204 +# define Tracevv(x) 205 +# define Tracec(c,x) 206 +# define Tracecv(c,x) 207 +#endif 208 + 209 + 210 +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, 211 + uInt len)); 212 +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); 213 +void zcfree OF((voidpf opaque, voidpf ptr)); 214 + 215 +#define ZALLOC(strm, items, size) \ 216 + (*((strm)->zalloc))((strm)->opaque, (items), (size)) 217 +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) 218 +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} 219 + 220 +#endif /* _Z_UTIL_H */