EnglishРусский  

   ..

   cab.g

   cab2g.dll

   cabdemo.g

   cabencode.g

   cab-x.g

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

source\lib\cab\cabencode.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2009, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * Author: Alexey Krivonogov ( gentee )
 11 *
 12 ******************************************************************************/
 13 
 14 include : $"..\other\random.g"
 15 include : $"..\gea\filelist.g"
 16 
 17 define
 18 {
 19    tcompTYPE_NONE         = 0x0000  // No compression
 20    tcompTYPE_MSZIP        = 0x0001  // MSZIP
 21    tcompTYPE_QUANTUM      = 0x0002  // Quantum
 22    tcompTYPE_LZX          = 0x0003  // LZX
 23 
 24    CB_MAX_FILENAME          =  256
 25    CB_MAX_CABINET_NAME      =  256
 26    CB_MAX_CAB_PATH          =  256
 27    CB_MAX_DISK_NAME         =  256
 28    FOLDER_THRESHOLD         =  1000000 // 900000
 29 
 30    // Level
 31    LZX_HI      = 0
 32    LZX_NORMAL  = 1
 33    LZX_LOW     = 2
 34       
 35    FCIERR_NONE = 0  
 36    FCIERR_OPEN_SRC
 37    FCIERR_READ_SRC
 38    FCIERR_ALLOC_FAIL 
 39    FCIERR_TEMP_FILE 
 40    FCIERR_BAD_COMPR_TYPE 
 41    FCIERR_CAB_FILE
 42    FCIERR_USER_ABORT 
 43    FCIERR_MCI_FAIL 
 44 
 45 }
 46 
 47 type CCAB {
 48 // LONG
 49     uint  cb                  // size available for cabinet on this media
 50     uint  cbFolderThresh      // Thresshold for forcing a new Folder
 51 // UINT
 52     uint  cbReserveCFHeader   // Space to reserve in CFHEADER
 53     uint  cbReserveCFFolder   // Space to reserve in CFFOLDER
 54     uint  cbReserveCFData     // Space to reserve in CFDATA
 55     int   iCab                // sequential numbers for cabinets
 56     int   iDisk               // Disk number
 57 //ifndef REMOVE_CHICAGO_M6_HACK
 58     int   fFailOnIncompressible // TRUE => Fail if a block is incompressible
 59 //endif
 60     ushort setID                // Cabinet set ID
 61 
 62     reserved   szDisk[ $CB_MAX_DISK_NAME ]    // current disk name
 63     reserved   szCab[ $CB_MAX_CABINET_NAME ]  // current cabinet name
 64     reserved   szCabPath[ $CB_MAX_CAB_PATH ]  // path for creating cabinet
 65 } 
 66 
 67 type cabinit
 68 {
 69    uint   volumesize
 70 //   uint   flags
 71    str    disk
 72    arrstr exclude
 73    uint   notify
 74    uint   level
 75 }
 76 
 77 method str str.gettempfile( str dir prefix ) 
 78 { 
 79    random rnd 
 80    
 81    rnd.init()
 82    rnd.randseed( 'A', 'Z' ) 
 83    do 
 84    { 
 85       str  name
 86       uint i 
 87       fornum i, 6 : name.appendch( rnd.randseed() ) 
 88       ( this = dir ).faddname( "\( prefix )\( name ).tmp" ) 
 89    } while fileexist( this )
 90    
 91    return this 
 92 }
 93 
 94 func uint cab_gettempfile( uint ret, int length, uint pv )
 95 {
 96    str dir filename
 97    
 98    gettempdir( dir )
 99    filename.gettempfile( dir, "cab_" )
100 /*   uint i
101    do 
102    {
103       ( filename = dir ).faddname( "cab_\(i++).tmp" )      
104    } while fileexist( filename )*/
105    if ( *filename + 1 ) < length 
106    {
107       mcopy( ret, filename.ptr(), *filename + 1 )
108       return 1
109    }
110    return 0 
111 }                                       
112 
113 // -----------------------------------------------------------------
114 
115 func cab_error( cabinfo cabi, str prefix )
116 {
117    str strerr
118    
119    switch cabi.erf.erfOper
120 	{
121 		case $FCIERR_NONE : strerr = "No error"
122 		case $FCIERR_OPEN_SRC: strerr = "Failure opening file to be stored in cabinet"
123 		case $FCIERR_READ_SRC: strerr = "Failure reading file to be stored in cabinet"
124 		case $FCIERR_ALLOC_FAIL:	strerr = "Insufficient memory in FCI"
125 		case $FCIERR_TEMP_FILE: strerr = "Could not create a temporary file"
126 		case $FCIERR_BAD_COMPR_TYPE: strerr = "Unknown compression type"
127 		case $FCIERR_CAB_FILE: strerr = "Could not create cabinet file"
128 		case $FCIERR_USER_ABORT: strerr = "Client requested abort"
129 		case $FCIERR_MCI_FAIL: strerr = "Failure compressing data"
130 		default : strerr = "Unknown error"
131 	}
132    cabi.fncnotify->func( $FLN_ERROR, 
133                  "\(prefix) failed: \(cabi.erf.erfOper) [\(strerr)]", cabi )
134 }
135 
136 func uint cab_notify( uint code, str param, cabinfo cabi )
137 {
138    return 0
139 }
140 
141 func uint cab_sysnotify( uint code, uint param, cabinfo cabi )
142 {
143    str stemp
144    
145    stemp.copy( param )
146    return cabi.fncnotify->func( code, stemp, cabi )
147 }
148 
149 // -----------------------------------------------------------------
150 
151 func uint cab_create( str cabfile, arrstr files, arr flags of uint, cabinit cabini )
152 {
153    CCAB    ccab
154    cabinfo cabi
155    str  stemp pattern ext
156    uint hfci ret
157    uint i
158    arrstr  exeext = %{ "exe", "dll" }
159    
160    if !cabini.volumesize : cabini.volumesize = 0xFFFFFFF
161 
162    cabi.finish = 0
163    cabi.cabsize = 0
164    cabi.filesize = 0
165    cabi.call = gentee_ptr( 4 ); // GPTR_CALL
166     
167    cabi.fnctempfile = &cab_gettempfile;
168     
169    cabi.fncnotify = cabini.notify;
170    if !cabi.fncnotify : cabi.fncnotify = &cab_notify;
171    cabi.fncsysnotify = &cab_sysnotify;
172     
173    callback( &cab_gettempfile, 1 )
174    
175    ccab.cb = cabini.volumesize
176 	ccab.cbFolderThresh = $FOLDER_THRESHOLD
177 	ccab.cbReserveCFHeader = 0
178 	ccab.cbReserveCFFolder = 0
179 	ccab.cbReserveCFData   = 0
180 	ccab.iCab = 1
181 	ccab.iDisk = 0
182 	ccab.setID = 777
183 
184    switch cabini.level
185    { 
186       case 2  : cabini.level = 15 
187       case 1  : cabini.level = 18
188       default : cabini.level = 21 
189    } 
190    cabi.lztype = $tcompTYPE_LZX | ( cabini.level << 8 )   
191       
192 	mcopy( &ccab.szDisk, cabini.disk.ptr(), *cabini.disk + 1 )
193    stemp.fnameext( cabfile )
194    mcopy( &ccab.szCab, stemp.ptr(), *stemp + 1 )
195    cabfile.fgetparts( stemp, pattern, ext )
196    stemp.fappendslash()
197    mcopy( &ccab.szCabPath, stemp.ptr(), *stemp + 1 )
198    pattern += "%i.\(ext)"
199    
200    cabi.pattern = pattern.ptr()
201       
202    if !( hfci = gcabe_create( &ccab, &cabi ))
203    {
204       cab_error( cabi, "FCICreate" )
205       goto end
206    }
207 
208    filelist fl 
209    str root folder
210  
211    fl.addfiles( files, cabini.exclude, flags )
212    foreach curfl, fl
213    {
214       str fullname filename ext
215       
216       switch curfl.itype
217       {
218          case $FL_FOLDER
219          { 
220             folder = curfl.name
221             if !gcabe_flushfolder( hfci ) 
222             {
223                cab_error( cabi, "FCIFlushFolder" )
224                goto end
225             }
226          }
227          case $FL_ROOT : root = curfl.name
228          case $FL_FILE
229          {
230             (fullname = root ).faddname( folder ).faddname( curfl.name )
231             filename.copy( fullname.ptr() + *root + 1 )
232             cabi.fncnotify->func( $FLN_FILEBEGIN, fullname, cabi )
233 //            ext = filename.fgetext()
234             if !gcabe_addfile( hfci, fullname.ptr(), filename.ptr(), 
235                /*ext %== exeext[0] || ext %== exeext[1],*/ cabi )
236             {
237                cab_error( cabi, "FCIAddFile" )
238                goto end
239             }
240             cabi.fncnotify->func( $FLN_FILEEND, fullname, cabi )
241          }
242       }
243    }
244    cabi.finish = 1
245    if !gcabe_close( hfci )
246    {
247       cab_error( cabi, "FCIFlushCabinet" )
248       goto end
249    }
250    ret = 1
251 label end:
252    return ret
253 }
254 
Редактировать