EnglishРусский  

   ..

   gea.g

   gead.g

   geademo.g

   geae.g

   geafile.g

Реклама

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

source\lib\gea\gead.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 define 
 15 {
 16    GEAD_TEST = 0    // Testing
 17    GEAD_MEM         // Writing to buf
 18    GEAD_FILE        // Writing to file
 19 }
 20 
 21 type gead 
 22 {
 23    geavolume  volume    // GEA volume
 24    geahead    head      // GEA header
 25    uint       userfunc  // user function
 26    str        filename  // The main filename
 27    str        lastpath  // The last path to GEA files
 28    str        curfilename  // The current filename
 29    uint       geaoff    // The offset of GEA data
 30    buf        moved     // The last data
 31    str        pattern   // The pattern of the volume
 32    arr        passcrc   // CRC of passwords
 33    arr        fileinfo of geafile // The array of file descriptions
 34    arr        offset of long      // The offsets of the beginning of the files
 35    buf        input               // The input buffer
 36    long       inoff               // The offset of the read input 
 37    uint       insize              // The size of the read input
 38    buf        output              // The output buffer
 39    
 40    uint       handle              // Текущий открытый файл
 41    uint       curdisk             // Номер текущего открытого тома
 42    
 43    arr        voloff of long      // The offset of volumes
 44    arr        volsize of long     // The size of volumes
 45    
 46    uint       blocksize
 47    uint       solidsize
 48    uint       lastsolid           // The last unpacked solid file
 49    uint       demode              // See GEAD_* defines 
 50    arrstr     passwords         // Passwords
 51    arr        passbufs of buf  // Long passwords
 52 //   uint       storesize
 53 //   uint       handle    // The handle of the main file
 54 /*   uint       flags
 55    str        pattern   // The pattern of the volume
 56    long       volsize   // 0 - one volume otherwise the size of the volume
 57    uint       userparam // user parameter
 58 //   uint       numvol    // The number of the current volume
 59    arr        fileinfo of geafile // The array of file descriptions
 60    hash       addedfiles       // Added files
 61    str        volpath          // Path to volumes
 62    arr        volnames of str  // Volume names
 63    arr        volumes of long  // Volume sizes
 64 */
 65 }
 66 
 67 type geadinit
 68 {
 69    uint userfunc  // user function
 70    uint geaoff    // the offset of GEA data 
 71 //   uint userparam // user parameter 
 72 }
 73 
 74 method  uint gead.validatepass( uint id, str password )
 75 {
 76    uint ret i
 77    
 78    if id > *this.passcrc : return 1
 79    
 80    fornum i, *this.passcrc
 81    {
 82       if !id || id == i + 1
 83       {
 84          if this.passcrc[ i ] == password.crc()
 85          {
 86             this.passwords[ i ] = password
 87             gea_passgen( this.passbufs[ i ], password )
 88             ret = 1
 89          }
 90       }  
 91    }
 92    return ret
 93 }
 94 
 95 method  uint gead.mess( uint code, collection cl )
 96 {
 97    return geafunc( this.userfunc, code, cl )
 98 }
 99 
100 include : "geadfile.g" 
101 
102 method uint gead.open( str filename, geadinit gi )
103 {
104    uint handle cur i count
105    buf  head   btemp
106    
107    this.userfunc = gi.userfunc
108    this.geaoff = gi.geaoff
109    this.filename.ffullname( filename )
110    
111    // Открываем файл
112    if !( handle = gea_fileopen( this.filename, $OP_READONLY, 
113                        this.userfunc )) : return 0
114    this.lastpath.fgetdir( this.filename )
115    setpos( handle, this.geaoff, $FILE_BEGIN )
116    read( handle, head, $GEA_DESCRESERVE )
117    mcopy( &this.volume, head.ptr(), sizeof( geavolume ))
118    mcopy( &this.head, head.ptr() + sizeof( geavolume ), sizeof( geahead ))
119    if this.volume.name != $GEA_NAME
120    {
121       return this.mess( $GEAERR_NOTGEA, %{ this.filename })   
122    }
123    if this.head.majorver != $GEA_MAJOR || this.head.minorver != $GEA_MINOR 
124    {
125       if this.mess( $GEAMESS_WRONGVER, %{ this.filename }) != $GEA_IGNORE
126       { 
127          return 0
128       }   
129    }
130    if getlongsize( handle ) < this.head.geasize
131    {
132       return this.mess( $GEAERR_WRONGSIZE, %{ this.filename })   
133    }       
134    cur = head.ptr() + sizeof( geavolume ) + sizeof( geahead ) 
135    this.pattern.copy( cur )
136    cur += *this.pattern + 1
137    if this.head.flags & $GEAH_PASSWORD
138    {
139       count = cur->ushort
140       cur += sizeof( ushort )
141       fornum i = 0, count
142       {
143          this.passcrc[ this.passcrc.expand( 1 ) ] = cur->uint
144          this.passwords += ""
145          this.passbufs.expand( 1 )
146          cur += sizeof( uint )
147       }              
148    }
149    if this.head.flags & $GEAH_COMPRESS
150    {
151       lzge lz
152       
153       btemp.expand( this.head.infosize )
154       lzge_decode( cur, btemp.ptr(), this.head.infosize, lz )
155       btemp.use = this.head.infosize
156       cur = btemp.ptr() 
157    }
158    uint end = cur + this.head.infosize
159    uint curattrib curgroup curpass
160    str  curfolder
161    long curoff
162    
163    while cur < end
164    {
165       uint gf gc
166       
167       this.fileinfo.expand( 1 )
168       gf as this.fileinfo[ *this.fileinfo - 1 ]
169       gc as cur->geacompfile
170       gf.flags = gc.flags
171       gf.ft = gc.ft
172       gf.size = gc.size
173       gf.compsize = gc.compsize 
174       gf.crc = gc.crc    
175       cur += sizeof( geacompfile )
176       if gf.flags & $GEAF_ATTRIB
177       {
178          curattrib = gf.attrib = cur->uint
179          cur += 4
180       }
181       else : gf.attrib = curattrib   
182       if gf.flags & $GEAF_VERSION
183       {
184          gf.hiver = cur->uint
185          cur += 4
186          gf.lowver = cur->uint
187          cur += 4
188       }
189       if gf.flags & $GEAF_GROUP
190       {
191          curgroup = gf.idgroup = cur->uint
192          cur += 4
193       }
194       else : gf.idgroup = curgroup   
195       if gf.flags & $GEAF_PROTECT
196       {
197          curpass = gf.idpass = cur->uint
198          cur += 4
199       }
200       else : gf.idpass = curpass   
201       gf.name.copy( cur )
202       cur += *gf.name + 1
203       if gf.flags & $GEAF_FOLDER
204       {
205          curfolder = gf.subfolder.copy( cur )
206          cur += *gf.subfolder + 1  
207       }
208       else : gf.subfolder = curfolder
209       // Добавляем смещения
210       this.offset.expand( 1 )
211       this.offset[ *this.offset - 1 ] = curoff
212       curoff += long( gf.compsize )
213    }
214    if this.head.movedsize
215    {
216       this.moved.copy( head.ptr() + this.head.size, this.head.movedsize )
217    }
218    else
219    {  // Копируем данные в буфер
220       this.input.copy( head.ptr() + this.head.size, *head - this.head.size )
221       this.insize = *head - this.head.size
222    }
223    this.handle = handle
224    // Вычисляем смещения и размеры томов
225    long voloff
226    
227    this.volsize.expand( this.head.count + 1 )
228    this.voloff.expand( this.head.count + 1 )
229    fornum i = 0, this.head.count
230    {
231       long size
232       if !i
233       {
234          size = this.head.geasize - long( this.head.movedsize ) - 
235                 long( this.head.size ) - long( this.geaoff )
236       }
237       elif i == this.head.count - 1
238       {
239          size = this.head.lastsize - long( sizeof( geavolume ))
240       }
241       else : size = this.head.volsize - long( sizeof( geavolume ))
242       this.volsize[ i ] = size
243       this.voloff[ i ] = voloff
244       voloff += size
245    }
246    if this.head.movedsize
247    {
248       this.volsize[ this.head.count ] = long( this.head.movedsize )
249       this.voloff[ this.head.count ] = voloff
250    } 
251    this.blocksize = 0x40000 * this.head.blocksize
252    this.solidsize = 0x40000 * this.head.solidsize
253 
254    this.input.expand( this.blocksize + 64 )
255    this.output.expand( this.blocksize + this.solidsize + 64 )
256    this.lastsolid = 0xFFFFFFFF
257    ppmd_start( this.head.memory )
258 
259    return 1
260 }
261 
262 method uint gead.close
263 {
264    ppmd_stop()
265    close( this.handle )
266    return 1
267 }
Редактировать