EnglishРусский  

   ..

   filelist.g

   gea.g

   gead.g

   geademo.g

   geae.g

   geafile.g

Реклама

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

source\lib\gea\filelist.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    FL_FILES     = 0x0001  // Seek just files
 17    FL_RECURSIVE = 0x0002  // Recursive search
 18    FL_EMPTYFLD  = 0x0004  // Empty folders
 19    
 20    FL_BLOCKSIZE = 1000000
 21    
 22    FL_ROOT = 1
 23    FL_FOLDER
 24    FL_FILE
 25 }
 26 
 27 /* Block
 28    uint count of items
 29    [ 
 30       byte   type
 31       short  size
 32       строка 
 33    ]
 34 */
 35 
 36 type flinfo
 37 {
 38    uint itype
 39    str  name
 40 } 
 41 
 42 type filelist< index = flinfo>
 43 {
 44    uint flags
 45    uint files           // Count of files
 46    long summarysize
 47    uint bcount          // Count block - 1
 48    uint off             // current offset in the block
 49    str  root            // current root
 50    str  folder          // current folder
 51    arr  block of uint
 52    // Для foreach
 53    uint iblock          // Текущий блок
 54    uint icur            // Текущий элемент
 55    uint eof
 56    flinfo fl
 57 }
 58 
 59 method filelist.newblock
 60 {
 61    uint i = .block.expand(1)
 62    
 63    .block[ i ] = malloc( $FL_BLOCKSIZE )
 64    .block[ i ]->uint = 0
 65    .bcount = *.block - 1
 66    .off = sizeof( uint )       
 67 }
 68 
 69 method filelist filelist.init()
 70 {
 71    this.newblock()
 72    return this
 73 }
 74 
 75 method filelist filelist.delete()
 76 {
 77    uint i
 78    fornum i, *this.block : mfree( this.block[ i ] )
 79    
 80    return this
 81 }
 82 
 83 method uint str.isexclude( arrstr exclude )
 84 {
 85    if *exclude 
 86    {
 87        foreach cure, exclude
 88        {
 89           if this.fwildcard( cure ) : return 1
 90        }
 91    }
 92    return 0
 93 }
 94 
 95 method filelist.additem( uint itype, str value )
 96 {
 97    uint start
 98    uint ptr size = *value + 1 
 99    
100    if itype == $FL_FILE 
101    {
102       str folder
103       
104       folder.fgetdir( value )
105       if folder %!= this.folder : this.additem( $FL_FOLDER, folder )
106       start = *this.folder + 1  
107       this.files++  
108    }
109    elif itype == $FL_FOLDER
110    {
111       start = *this.root + ?( *value > *this.root, 1, 0 ) 
112       this.folder = value
113    }
114    
115    if .off + size + 16 > $FL_BLOCKSIZE : this.newblock()
116    
117    
118    ptr = .block[ .bcount ] + .off
119          
120 //   print("Add=\(itype) \( value )\n")
121    ptr->ubyte = itype
122    size -= start
123    ( ptr + 1 )->ushort = size
124    mcopy( ptr + 3, value.ptr() + start, size )
125    .off += size + 3  
126    .block[ .bcount ]->uint = .block[ .bcount ]->uint + 1
127 }
128 
129 method uint filelist.adddir( str src, arrstr exclude, uint flags )
130 {
131    str   wildcard dirsearch dirname = src 
132    ffind fd fdfile
133    uint  hasdirs
134    
135    if direxist( dirname )
136    {
137       hasdirs = 1 
138       dirname.faddname( "*.*" )
139       dirsearch = dirname
140       flags |= $FL_RECURSIVE      
141    }
142    else : dirsearch.fgetdir( src ).faddname( "*.*" )
143    
144    wildcard.fnameext( dirname )
145    
146    fd.init( dirsearch, $FIND_DIR ) 
147    foreach cur, fd
148    {
149       str stemp
150       
151       hasdirs = 2
152       if cur.name.isexclude( exclude ) : continue
153       if cur.name.fwildcard( wildcard )
154       { 
155          this.adddir( cur.fullname, exclude, flags | $FL_RECURSIVE )
156       }
157       elif flags & $FL_RECURSIVE
158       { 
159          this.adddir( ( stemp = cur.fullname ).faddname( wildcard ), exclude, flags )
160       }
161    }      
162    fdfile.init( dirname, $FIND_FILE ) 
163    foreach curf, fdfile
164    {
165       if curf.name.isexclude( exclude ) : continue
166       this.summarysize += long( curf.sizelo )
167 //      print("\(this.summarysize) \(cur.fullname)\n")
168       this.additem( $FL_FILE, curf.fullname )
169    }
170    if hasdirs == 1 && flags & $FL_EMPTYFLD
171    {
172       fdfile.init( dirsearch, $FIND_FILE ) 
173       foreach curf, fdfile
174       {
175          hasdirs = 0
176          break
177       }
178       if hasdirs : this.additem( $FL_FOLDER, src )
179    }      
180    return 1   
181 }
182 
183 method uint filelist.addfiles( arrstr src exclude, arr aflags of uint )
184 {
185    uint icur
186    uint recurse
187    
188    foreach cursrc, src
189    {
190       ffind fd
191       uint  dir
192       
193       if !*cursrc : continue
194 //      wcard.fnameext( cursrc )
195       .root.fgetdir( cursrc )  
196       .additem( $FL_ROOT, .root )
197       .folder = .root
198 //      .folder.clear()
199       if *aflags > icur
200       {
201          this.flags = aflags[ icur ]
202          recurse = ?( this.flags & $FL_RECURSIVE, $FIND_RECURSE, 0 ) 
203       } 
204       icur++
205       if this.flags & $FL_FILES
206       {
207          uint recok = recurse
208          
209          if recok
210          {
211             str rdir
212             
213             rdir.fgetdir( cursrc )
214             if *rdir > 1 && rdir[1] == ':' && cursrc.findch('*') >= *cursrc &&
215                cursrc.findch('?') >= *cursrc : recok = 0
216          }
217          
218          fd.init( cursrc, $FIND_FILE | recok ) 
219          foreach cur, fd
220          {
221             if cur.name.isexclude( exclude ) : continue
222             this.summarysize += long( cur.sizelo )
223 //            print("\(this.summarysize) \(cur.fullname)\n")
224             this.additem( $FL_FILE, cur.fullname )
225          }
226          continue
227       }
228       this.adddir( cursrc, exclude, this.flags )
229    }
230    return this.files
231 }
232 
233 method uint filelist.eof( fordata fd )
234 {
235    return .eof
236 }
237 
238 method uint filelist.first( fordata fd )
239 {  
240    uint off
241    
242    .iblock = 0
243    .icur = 0
244    fd.icur = sizeof( uint )
245    if !( .block[ .iblock ]->uint )
246    {
247       .eof = 1
248       return 0
249    }
250    .eof = 0
251    off = .block[ .iblock ] + fd.icur
252    this.fl.itype = off->ubyte
253    this.fl.name.copy( off + 3, (off + 1)->ushort - 1 ) 
254    fd.icur += (off + 1)->ushort + 3
255    return &this.fl
256 }
257 
258 method uint filelist.next( fordata fd )
259 {
260    uint off
261    
262    .icur++
263    if .icur == .block[.iblock]->uint
264    { 
265       .iblock++
266       if .iblock > .bcount
267       { 
268          .eof = 1
269          return 0
270       } 
271       .icur++
272       fd.icur = sizeof( uint )
273    }
274    off = .block[ .iblock ] + fd.icur
275    this.fl.itype = off->ubyte
276    this.fl.name.copy( off + 3, (off + 1)->ushort - 1 ) 
277    fd.icur += (off + 1)->ushort + 3 
278    return &this.fl
279 }
280 
281 
Редактировать