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_SEQUENT > 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,&er > 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]== > 105 hdr[i+3]=='F' && hdr[i+4]== 0 && hdr[i+ > 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,&er > 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_UNTI > 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'< > 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_p > 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 ); }brea > 195 case e_zip:{ CZipTool().Extract( arcname, dllname, dll_rel_path ); }brea > 196 case e_cab:{ CCabTool().Extract( arcname, dllname, dll_rel_path ); }brea > 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] デフォルト > 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", > 478 if( DoCheck[UNZIP] ) > 479 List.add( new DLLInfo( "UnZip32.dll", "unzip32.html", > 480 if( DoCheck[ZIP] ) > 481 List.add( new DLLInfo( "Zip32j.dll", "zip32j.html", > 482 List.add( new DLLInfo( "Zip32.dll", "zip32j.html", > 483 List.add( new DLLInfo( "Sfx32gui.dat", "sfx32gui.html", > 484 if( DoCheck[CAB] ) > 485 List.add( new DLLInfo( "Cab32.dll", "cab32.html", > 486 if( DoCheck[TAR] ) > 487 List.add( new DLLInfo( "Tar32.dll", "tar32.html", > 488 if( DoCheck[UNRAR] ) > 489 List.add( new DLLInfo( "Unrar32.dll", "unrar32.html", > 490 if( DoCheck[UNGCA] ) > 491 List.add( new DLLInfo( "UnGCA32.dll", "ungca32.html", > 492 if( DoCheck[UNARJ] ) > 493 List.add( new DLLInfo( "Unarj32j.dll", "unarj32.html", > 494 if( DoCheck[YZ1] ) > 495 List.add( new DLLInfo( "Yz1.dll", "yz1.html", > 496 if( DoCheck[BGA] ) > 497 List.add( new DLLInfo( "Bga32.dll", "bga32.html", > 498 if( DoCheck[JACK] ) > 499 List.add( new DLLInfo( "Jack32.dll", "jack32.html", > 500 if( DoCheck[AISH] ) > 501 List.add( new DLLInfo( "Aish32.dll", "aish32.html", > 502 if( DoCheck[ISH] ) > 503 List.add( new DLLInfo( "Ish32.dll", "ish32.html", > 504 if( DoCheck[UNBEL] ) > 505 List.add( new DLLInfo( "Unbel32.dll", "unbel32.html", > 506 if( DoCheck[SvZIP] ) > 507 List.add( new DLLInfo( "7-zip32.dll", "7-zip32.html", > 508 if( DoCheck[UNIMP] ) > 509 List.add( new DLLInfo( "UnImp32.dll", "unimp32.html", > 510 if( DoCheck[BH] ) > 511 List.add( new DLLInfo( "Bh32.dll", "bh32.html", > 512 if( DoCheck[YZ2] ) > 513 List.add( new DLLInfo( "Yz2.dll", "yz2.html", > 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.patchleve > 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 && StLoc > 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/1 > 658 else > 659 ::wsprintf( verstr, "%d.%02d%c", ver/100, ver%100, sub+' > 660 else if( dllName=="7-zip32.dll" ) // 7-zipだけは無条件でSubVersionも数値で入れ > 661 ::wsprintf( verstr, "%d.%02d.%02d.%02d", ver/100, ver%100, sub/1 > 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_S > 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_DEF > 786 updatable = CheckDateTime( kiPath(dlldir)+="Unra > 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_GETCHEC > 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*)( > 856 sendMsgToItem( IDC_CONNECTTO1+cfg->CheckServer, BM_SETCHECK, BST > 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) > 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)st > 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_G > 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, > 907 if( cfg->ShowReadMe ) > 908 sendMsgToItem( IDC_SHOW_README, BM_SETCHECK, BST > 909 if( cfg->UseCustomDir ) > 910 sendMsgToItem( IDC_SAVE_DESTDIR, BM_SETCHECK, BS > 911 for( int i=0; i<DLLID_NUM; ++i ) > 912 if( cfg->DoCheck[i] ) > 913 sendMsgToItem( IDC_DLHA+i, BM_SETCHECK, > 914 // 挿入caldixF > 915 sendMsgToItem( IDC_FILERPATH, WM_SETTEXT, 0, (LPARAM)(co > 916 sendMsgToItem( IDC_FILEROPT, WM_SETTEXT, 0, (LPARAM)(con > 917 sendMsgToItem( IDC_FILEROPT2, WM_SETTEXT, 0, (LPARAM)(co > 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_FI > 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, > 939 cfg->ShowReadMe = > 940 (BST_CHECKED==sendMsgToItem( IDC_SHOW_README, BM > 941 cfg->UseCustomDir = > 942 (BST_CHECKED==sendMsgToItem( IDC_SAVE_DESTDIR, B > 943 for( int i=0; i<DLLID_NUM; ++i ) > 944 cfg->DoCheck[i] = > 945 (BST_CHECKED==sendMsgToItem( IDC_DLHA+i, > 946 // 挿入caldixF > 947 char str[500]; > 948 > 949 sendMsgToItem( IDC_FILERPATH, WM_GETTEXT, sizeof(str)-1, > 950 cfg->Filer = str; > 951 sendMsgToItem( IDC_FILEROPT, WM_GETTEXT, sizeof(str)-1, > 952 cfg->F_Prefix = str; > 953 sendMsgToItem( IDC_FILEROPT2, WM_GETTEXT, sizeof(str)-1, > 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_CH > 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->ProxyPor > 975 } > 976 else > 977 ::SetDlgItemInt( hwnd(), IDC_PORT, -cfg->ProxyPo > 978 sendMsgToItem( IDC_HOST, WM_SETTEXT, 0, (LPARAM)(const c > 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( I > 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, (LPA > 999 cfg->ProxyServer = str; > 1000 cfg->ProxyPort = ::GetDlgItemInt( hwnd(), IDC_PORT, NULL > 1001 if( BST_CHECKED!=sendMsgToItem( IDC_USEPROXY, BM_GETCHEC > 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. > 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_ > 1147 #define RETRY_() ::InternetCloseHandle( http ); http=NULL; go > 1148 #define RETRY_error() do{ ++Mir; RETRY_() }while(0) > 1149 #define RETRY_serverdown() do{ mirrorMan.server_is_down(Mir); RETRY_() > 1150 #define INET_CONNECT( __s ) ::InternetConnect( h, __s, INTERNET_DEFAULT_ > 1151 #define HTTP_REQ( __n ) ::HttpOpenRequest( http, "GET", __n, "HTTP/1 > 1152 #define HTTP_SEND() status=0,::HttpSendRequest( ss, NULL, 0, NUL > 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 Authentica > 1212 { > 1213 // パスワードを打たせてもう一度 > 1214 DWORD dwRet = ::InternetErrorDlg( > 1215 hwnd(), ss, GetLastError(), > 1216 FLAGS_ERROR_UI_FILTER_FOR_ERRORS > 1217 FLAGS_ERROR_UI_FLAGS_CHANGE_OPTI > 1218 FLAGS_ERROR_UI_FLAGS_GENERATE_DA > 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, &rea > 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( "dl > 1293 list.setSubItem( i, 1, m_upd[i]->getState() ); > 1294 } > 1295 sendMsgToItem( IDC_UPDATELIST,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_E > 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->InstM > 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_GE > 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( > 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 > 1374 break; > 1375 } > 1376 > 1377 // "○○をダウンロード中..." のテキストを更新 > 1378 char msg[300]; > 1379 ::wsprintf( msg, kiStr().loadRsrc(IDS_DOWNLOADING), > 1380 (const char*)m_lst[i]->getName() > 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]->getArchiv > 1387 fil = m_pth, fil += m_lst[i]->getArchiv > 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_startT > 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* ) { r > 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_IB > 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)) > 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& wor > 1473 : kiDialog( IDD_INSTALL ), m_upd( upd ), m_arcdir( arcdir ), m_w > 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_up > 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_PRECON > 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,(cons > 1626 ::InternetSetOption( h, INTERNET_OPTION_PROXY, (void*)& > 1627 ::UrlMkSetSessionOption( INTERNET_OPTION_PROXY, (void*)& > 1628 } > 1629 > 1630 // タイムアウトは5秒 > 1631 DWORD TimeOut = 5*1000; > 1632 ::InternetSetOption( h, INTERNET_OPTION_RECEIVE_TIMEOUT, &TimeOu > 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_ICO > 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.beBackSlas > 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 ), "ca > 1724 askRasHangUp(); > 1725 } > 1726 else > 1727 if( IDYES!=msgBox( kiStr(1000).loadRsrc( IDS_REBOOT ), " > 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*)wor > 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\"% > 1783 (const char*)cfg->Filer, > 1784 (const char*)cfg->F_Prefix, wdir, (const char*)c > 1785 > 1786 // ファイラ起動( modified by k.inaba ) > 1787 STARTUPINFO si = {sizeof(si)}; > 1788 PROCESS_INFORMATION pi; > 1789 { > 1790 kiPath original_cur(kiPath::Cur), sys(kiPath::Sy > 1791 ::SetCurrentDirectory(sys); > 1792 ::CreateProcess( NULL, cmdline, NULL, NULL, FALS > 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, "RasEnumCo > 1818 rH RasHangUp = (rH)::GetProcAddress( rasdll, "RasHangUp > 1819 rS RasGetConnectStatus= (rS)::GetProcAddress( rasdll, "RasGetCon > 1820 if( RasEnumConnections!=NULL && RasHangUp!=NULL && RasGetConnect > 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_ENO > 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_RAS > 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( RasC > 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 "_MBC > 46 # ADD CPP /nologo /W3 /O1 /Oy /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBC > 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 ad > 56 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi3 > 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" > 73 # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_ > 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 ad > 83 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi3 > 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\ > 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 Archive > 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 t > 554 IDS_FINISHED "Installation finished. Document of each DLL is in ' > 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. A > 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 > 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,W > 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,DW > 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 ) ) // D > 41 dll_rel_path = name; > 42 > 43 // デコード > 44 CLzhDecoder2 dec; > 45 lzh_method mhd = UNKNOWN; > 46 if( 0==strcmp(h_Method,"-lh0-") )mhd=LH > 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_OrigSiz > 51 > 52 // 属性など設定 > 53 fclose( out ); > 54 > 55 SetFileAttributes( name,h_Attrib ); > 56 if( h_Level<2 ) > 57 kiutil::timeSet( name, (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: > 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:eh > 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: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]
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, 0xe963a5 > 63 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d > 64 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b5 > 65 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d > 66 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85 > 67 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60d > 68 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba95 > 69 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611d > 70 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4 > 71 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c > 72 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4 > 73 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37c > 74 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c4 > 75 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c > 76 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d4 > 77 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c > 78 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db26 > 79 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae > 80 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c36 > 81 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be > 82 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506 > 83 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8e > 84 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216 > 85 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e > 86 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x720767 > 87 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcef > 88 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077 > 89 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bff > 90 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x496947 > 91 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf > 92 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de57 > 93 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df > 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 > 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); /* pfnfdi > 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]
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,"Seven > 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_SUPPO > 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 > 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( > 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 firstc > 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_ > 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_EXISTI > 33 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCA > 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_SCA > 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=0xfff > 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_ > 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_ACCES > 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_RE > 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 > 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 > 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& arg > 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 : sl > 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 ); > 177 case Cur: ::GetCurrentDirectory( m_ALen, m_pBuf ); break; > 178 case Exe_name: > 179 ::GetModuleFileName( NULL, m_pBuf, m_ALen );brea > 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, > 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 > 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* > 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 | SHGF > 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 > 63 NULL,::GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),( > 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_SE > 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 > 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, ::GetCurrentThrea > 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_pCurIn > 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_ > 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.d > 93 { > 94 DWORD pid; > 95 DWORD th1 = ::GetWindowThreadProcessId( ::GetForegroundWindow(), > 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, LPAR > 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) : > 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_WND > 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_USERD > 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 pp > 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_USE > 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 ) {re > 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, LP > 284 static BOOL CALLBACK page_cmmnProc( HWND dlg, UINT msg, WPARAM wp, LPARA > 285 static UINT CALLBACK page_initProc( HWND dlg, UINT msg, LPPROPSHEETPAGE > 286 > 287 protected: > 288 kiPropSheet(); > 289 public: > 290 ~kiPropSheet() > 291 { for( unsigned int i=0; i!=m_Pages.len(); i++ ) delete m_Pages[ > 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_LE > 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_ > 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, ( > 341 ::SendMessage( m_hWnd, LVM_SETIMAGELIST, LVSIL_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_ > 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))> > 61 (!(Ver&0x80000000) && LOBYTE(LOWORD(Ver))>=5 )) // 新しいWindows > 62 { > 63 DWORD pid; > 64 DWORD thread1 = GetWindowThreadProcessId( GetForegroundWindow(), > 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 ) ) || st > 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="KI > 4 <description>DnD Melter/Freezer</description> > 5 <dependency><dependentAssembly> > 6 <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Co > 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 */