EnglishРусский  

   ..

   gea.g

   gead.g

   geademo.g

   geadfile.g

   geae.g

   geafile.g

The project is closed! You can look at a new scripting language. It is available on GitHub.
Also, try our open source cross-platform automation software.

Ads

Installer and installation software
Commercial and Freeware installers.

source\lib\gea\geadfile.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 method str gead.getdiskname( uint num, str result )
 15 {
 16    str stemp
 17 
 18    if !num : return result = this.filename
 19 
 20 //   int2str( stemp, this.pattern, num )
 21    stemp.out4( this.pattern, num )
 22 
 23    return ( result = this.lastpath ).faddname( stemp )   
 24 }
 25 
 26 //--------------------------------------------------------------------------
 27 
 28 method uint gead.opendisk( uint num )
 29 {
 30    str  diskname dir 
 31    buf  head      
 32 
 33    if this.curdisk == num : return 1
 34 
 35    close( this.handle )
 36 
 37    getcurdir( dir )   
 38    // Существует ли файл
 39    while 1
 40    {
 41       this.getdiskname( num + 1, diskname )
 42 //      print( "\(num) \(this.curdisk) Disk = \(diskname) \(this.lastpath)\n")
 43       if !fileexist( diskname )
 44       {
 45          if this.mess( $GEAMESS_GETVOLUME, %{ diskname, num + 1 }) ==
 46              $GEA_ABORT : return 0
 47          getcurdir( this.lastpath ) 
 48       }
 49       else : break            
 50    }
 51    setcurdir( dir ) 
 52    this.curfilename = diskname           
 53    if !( this.handle = gea_fileopen( diskname, $OP_READONLY, 
 54       this.userfunc )) : return 0
 55    this.curdisk = num
 56    
 57    if num
 58    {  // Проверка на правильность тома
 59       uint gv
 60       long size
 61       
 62       read( this.handle, head, sizeof( geavolume ))
 63       gv as head.ptr()->geavolume
 64       if gv.name != $GEA_NAME
 65       {
 66          return this.mess( $GEAERR_NOTGEA, %{ diskname })   
 67       }
 68       if gv.unique != this.volume.unique
 69       {
 70          return this.mess( $GEAERR_WRONGVOLUME, %{ diskname })   
 71       }
 72       if num == this.head.count - 1 : size = this.head.lastsize
 73       else : size = this.head.volsize
 74       if getlongsize( this.handle ) < size
 75       {
 76          return this.mess( $GEAERR_WRONGSIZE, %{ diskname })   
 77       }       
 78    }
 79    return 1      
 80 }
 81 
 82 //--------------------------------------------------------------------------
 83 
 84 method uint gead.read( long off, uint size )
 85 {  // Метод читает и возвращает указатель на данные
 86    uint ptr = this.input.ptr()
 87    uint curoff
 88 
 89 //   print("Enter = \(off) \(size) \( this.inoff ) \( this.insize )\n")
 90    // Данные уже прочитаны
 91    if off >= this.inoff && off + long( size ) <= this.inoff + long( this.insize )
 92    {
 93 //      print("Ooops\n")
 94       return ptr + uint( off - this.inoff )
 95    }
 96 //   print("Read 1 \(uint( off - this.inoff )) \(uint( this.inoff + 
 97 //             long( this.insize ) - off ))\n")
 98    // Данные прочитаны частично
 99    if off >= this.inoff && off < this.inoff + long( this.insize )
100    {
101       mmove( ptr, ptr + uint( off - this.inoff ), uint( this.inoff + 
102              long( this.insize ) - off ))
103 //      print("Move = \(off - this.inoff) size \(this.inoff + long( this.insize ) - off)\n")
104       this.insize -= uint( off - this.inoff )
105       size -= this.insize
106       curoff = this.insize      
107    }
108    else : this.insize = 0
109    
110    this.inoff = off
111    off += long( this.insize )
112 
113    if off + long( size ) > this.head.summary
114    {
115       return this.mess( $GEAERR_INTERNAL, %{ this.filename, 1 }) 
116    }
117 //   print("0 = \(curoff) \(this.insize) off=\(off) \( size )\n")
118    while size
119    {
120       uint i canread
121       long moveoff 
122 
123       moveoff = this.voloff[ this.head.count ]
124       // Если перемещенные данные
125       if this.head.movedsize && off >= moveoff 
126       {
127 //         print("Moved off = \( off ) \(uint( off - moveoff )) size = \(size) curoff = \(curoff)\n")
128          mcopy( ptr + curoff, this.moved.ptr() + uint( off - moveoff ), 
129                 size )
130          curoff += size
131 //         this.insize += size
132          break
133       } 
134       // Определяем требуемый том
135       fornum i, *this.voloff - 1
136       {
137          if !this.volsize[i] : continue
138          if off < this.voloff[ i + 1 ] : break    
139       }
140       if i >= this.head.count : i = this.head.count - 1
141       if !this.opendisk( i ) : return 0
142       moveoff = off - this.voloff[ i ]
143       canread = min( size, uint( this.volsize[i] - moveoff ))
144       if !i
145       {
146          moveoff += long( this.head.size + this.head.movedsize + this.geaoff )
147       }
148       else : moveoff += long( sizeof( geavolume ))
149 
150       setlongpos( this.handle, moveoff, $FILE_BEGIN )
151 //      print("Read 3 \( moveoff ) Off=\( this.voloff[ i ] ) size=\(this.volsize[i]) \(canread) \(size)\n")
152       size -= canread  
153       off += long( canread )
154 /*      if uint( this.volsize[i] - moveoff ) > canread
155       {
156          canread = min( 0x80000, uint( this.volsize[i] - moveoff + 10L)) 
157       }*/       
158       canread = max( canread, min( this.input.size - curoff, 0x80000 ))
159 //      print("Read \( this.curfilename) fileoff = \(setpos(this.handle, 0, $FILE_CURRENT )) \( canread )\n ")
160       uint ri rw
161       ri = ReadFile( this.handle, ptr + curoff, canread, &canread, 0  )
162       if !i && moveoff + long( canread ) > this.head.geasize
163       {  // Дать возможность добавлять Digital Signature
164          canread = uint( this.head.geasize - moveoff )  
165       }   
166 /*      if !ri
167       {
168          ri = ReadFile( this.handle, ptr + curoff, canread, &rw, 0  )
169          print("Read ERR \(ri) \(rw) \(getsize( this.handle )) \(setpos(this.handle, 0, $FILE_CURRENT )) \( curoff)\n")
170       }*/
171 //      print("Read 4 \(ri) \(off) \(canread) \(ptr + curoff) \(setpos(this.handle, 0, $FILE_CURRENT ))\n")
172       curoff += canread                  
173 //      print("Read 5 \(curoff) \(canread) \(size) \n")
174    }
175 //   print("Read 6 \(curoff) \(ptr) \n")
176    this.insize = curoff                  
177    return ptr      
178 }
179 
180 //--------------------------------------------------------------------------
181 
182 /*func  uint  geacrc( uint ptr size param )
183 {
184    param->uint = crc( ptr, size, param->uint )
185    return 1 
186 }*/
187 
188 //--------------------------------------------------------------------------
189 
190 //method uint gead.unpack( uint off, uint size )
191 method uint gead.unpack( uint id out )
192 {
193    uint  gf  ctype corder 
194    uint  input
195    uint  ptr size 
196    geadata    gd 
197    long       off
198    geaparam   gp
199    uint       icrc = 0xFFFFFFFF
200    
201 //   this.output.clear()
202    if id >= *this.fileinfo : return 0
203 
204 //   binput.expand( this.head.blocksize )
205    gf as this.fileinfo[ id ]
206    if gf.flags & $GEAF_SOLID && id - 1 != this.lastsolid
207    {
208       uint demode ptemp = this.userfunc
209       this.userfunc = 0
210 //      print("------------ \(id - 1) \(this.lastsolid)\n")
211       this.unpack( id - 1, 0 )
212       this.userfunc = ptemp   
213 //      print("============\n")
214    }
215    this.mess( $GEAMESS_DEBEGIN, %{ this.filename, &gf })
216 //   print("Name=\(gf.name) \(id)\n")
217    
218    size = gf.size
219    off = this.offset[ id ]
220 
221 //   print( "size 0 =\(size)\n")
222    subfunc uint readdata
223    {
224       uint solidoff
225         
226       input = this.read( off, sizeof( geadata ))
227          
228       gd.order = uint( input->geadata.order ) & ~0x80
229       gd.size = input->geadata.size
230       off += long( sizeof( geadata ))
231       ctype = gd.order >> 4
232       corder = ( uint( gd.order ) & 0x0F ) + 1
233 //      print( "corder = \( corder )\n")
234       // Обнуляем output
235       if ( ctype != $GEA_LZGE || corder > 1 )
236       {
237          this.output.clear()
238       }
239       else
240       {
241          // Сдвигаем данные для solid
242          if *this.output + min( size, this.blocksize ) > 
243                                this.blocksize + this.solidsize
244          {
245             this.output.del( 0, *this.output - this.solidsize )
246          }
247          solidoff = *this.output
248       }
249       return solidoff 
250    }    
251    gp.done = 0
252    gp.name = ""//fullname
253    gp.info = &gf
254    gp.mode = 1
255 
256    if gf.idpass  // разшифровываем  
257    {
258       label againpass
259       
260 //      print("ID=\(gf.idpass) \()\n")
261       if !*this.passwords[ gf.idpass - 1 ]
262       {
263          if this.mess( $GEAMESS_PASSWORD, %{ this.filename, gf })
264          {
265             goto againpass
266          }
267          else : return 0
268       }
269    }
270    
271    while size
272    {
273       lzge  lz
274       ppmd  ppm
275       
276       if !gd.size : lz.solidoff = readdata()
277    
278 //      print("1 =\( uint(off->long) + this.head.size ) \(gd.size + sizeof( geadata )) == \(size) \(gd.order) \(input->geadata.order)\n")       
279          
280       uint isize osize
281    
282       ptr = this.output.ptr()
283       isize = min( this.blocksize, gd.size )
284       input = this.read( off, isize )
285       if gf.idpass  // раcшифровываем  
286       {
287          gea_protect( input, isize, this.passbufs[ gf.idpass - 1 ] )
288       }
289       
290       off += long( isize )
291       osize = ?( ctype, min( this.blocksize, size ), isize )
292       switch ( ctype )
293       {
294          case $GEA_STORE
295          { 
296             ptr = input
297             this.mess( $GEAMESS_PROCESS, %{ this.filename, gf, osize + gp.done })
298          }
299          case $GEA_LZGE
300          {
301 //            print("Input=\(input - this.input.ptr()) Outsize=\( this.output.size) Out=\(*this.output) Solidoff=\(lz.solidoff ) osize=\( osize ) isize = \(isize)\n")
302             lz.userfunc = this.userfunc
303             lz.pgeaparam = &gp
304 //            print("\n1 \(lz.solidoff + osize) \( *this.output ) \( this.output.size )
305 //            Off = \( input - this.input.ptr() )\n") 
306             lzge_decode( input, ptr, lz.solidoff + osize, lz )
307             this.output.use = lz.solidoff + osize
308             ptr += lz.solidoff 
309 //            ptr += lz.solidoff 
310          }
311          case $GEA_PPMD
312          {
313             ppm.order = corder
314             ppm.userfunc = this.userfunc
315             ppm.pgeaparam = &gp 
316             ppmd_decode( input, gd.size, ptr, osize, ppm )
317    //         ptr = this.output.ptr()
318          }
319       }
320       gp.done += osize
321       gd.size -= isize
322       icrc = crc( ptr, osize, icrc )
323       if out 
324       {
325          if this.demode == $GEAD_MEM : out->buf.append( ptr, osize )
326          elif this.demode == $GEAD_FILE
327          { 
328             uint iw
329             if !WriteFile( out, ptr, osize, &iw, 0 ) || iw != osize
330             {
331                this.mess( $GEAERR_FILEWRITE, %{ gf.name })
332                return 0
333             }
334          }
335       }
336 //      print( "SS = 6 \( osize ) \(*( out->buf ))\n")
337 //      geacrc( ptr, osize, param )
338       size -= osize
339    }
340    if icrc != gf.crc
341    { 
342       this.mess( $GEAERR_CRC, %{ this.filename, &gf } ) 
343    }  
344    this.mess( $GEAMESS_DEEND, %{ this.filename, &gf })
345 
346    this.lastsolid = id
347    return 1
348 }
349 
350 //--------------------------------------------------------------------------
351 
352 method uint gead.test( uint id )
353 {
354    this.demode = $GEAD_TEST
355    return this.unpack( id, 0 )
356 }
357 
358 //--------------------------------------------------------------------------
359 
360 method uint gead.file2mem( uint id, buf output )
361 {
362    this.demode = $GEAD_MEM
363    output.clear()
364    return this.unpack( id, &output )
365 }
366 
367 //--------------------------------------------------------------------------
368 
369 method uint gead.file2file( uint id handle )
370 {
371    this.demode = $GEAD_FILE
372    return this.unpack( id, handle )
373 }
374 
375 //--------------------------------------------------------------------------
376 
377 method long gead.summarysize
378 {
379    uint i
380    long result
381  
382    fornum i, *this.fileinfo
383    {
384 //      print("i =\(i) Name=\(this.fileinfo[ i ].name) Subfolder = \(this.fileinfo[ i ].subfolder) Size = \( this.fileinfo[ i ].size )\n")
385       result += long( this.fileinfo[ i ].size )
386    }
387    return result
388 }
389 
390 //--------------------------------------------------------------------------
391 
392 
393