EnglishРусский  

   ..

   arr.g

   arrstr.g

   arrustr.g

   buf.g

   console.g

   fcopy.g

   ffind.g

   file.g

   hash.g

   math.g

   process.g

   search.g

   stack.g

   stdlib.g

   str.g

   stradv.g

   strfile.g

   system.g

   ustr.g

Реклама

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

source\lib\stdlib\fcopy.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2004-2007, 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 <export> {
 15 /*-----------------------------------------------------------------------------
 16 * Id: fcopyflags D
 17 * 
 18 * Summary: Flags for copyfiles.
 19 *
 20 -----------------------------------------------------------------------------*/
 21    COPYF_RO        = 0x0100    // Overwrite files with the attribute read-only.
 22    COPYF_SAVEPATH  = 0x0200    // Keep relative paths while copying files /
 23                                // from subdirectories.
 24    COPYF_ASK       = 0x0400    // Prompt before copying files already existing.
 25    
 26 /*-----------------------------------------------------------------------------
 27 * Id: fcopymode D
 28 * 
 29 * Summary: Mode for copyfiles.
 30 *
 31 -----------------------------------------------------------------------------*/
 32    COPY_OVER      = 0         // Overwrite.
 33    COPY_SKIP                  // Skip.
 34    COPY_NEWER                 // Overwrite if newer.
 35    COPY_MODIFIED              // Overwrite if modified.
 36    
 37 /*-----------------------------------------------------------------------------
 38 * Id: fcopymsg D
 39 * 
 40 * Summary: Message codes for copyfiles.
 41 *
 42 -----------------------------------------------------------------------------*/
 43    COPYN_FOUND    = 1         // The object for copying is found.
 44    COPYN_NEWDIR               // A directory is created.
 45    COPYN_ERRDIR               // Cannot create a directory.
 46    COPYN_ASK                  // Copy request.
 47    COPYN_ERRFILE              // Error while creating a file.
 48    COPYN_NEWFILE              // A file was created. 
 49    COPYN_BEGIN                // Start copying file.
 50    COPYN_PROCESS              // A file is being copied.
 51    COPYN_END                  // Copying is over.
 52    COPYN_ERRWRITE             // Error while writing a file.
 53 
 54 /*-----------------------------------------------------------------------------
 55 * Id: fcopyret D
 56 * 
 57 * Summary: Return codes for copyfiles.
 58 *
 59 -----------------------------------------------------------------------------*/
 60    COPYR_NOTHING  = 0         // Do nothing.
 61    COPYR_BREAK                // Break copying.
 62    COPYR_RETRY                // Retry.
 63    COPYR_SKIP                 // Skip.
 64    COPYR_OVER                 // Write over.
 65    COPYR_OVERALL              // Write over all files. 
 66    COPYR_SKIPALL              // Skip all files. 
 67 //-----------------------------------------------------------------------------
 68 }
 69 
 70 /*-----------------------------------------------------------------------------
 71 * Id: isequalfiles F
 72 *
 73 * Summary: Check if files are equal. The function compares two files. 
 74 *  
 75 * Params: left - The name of the first file to be compared.
 76           right - The name of the second file to be compared. 
 77 * 
 78 * Return: The function returns 1 if the files are equal, otherwise it 
 79           returns 0.
 80 *
 81 -----------------------------------------------------------------------------*/
 82 
 83 func  uint isequalfiles( str left, str right )
 84 {
 85    file  fleft fright
 86    uint  lsize result temp size
 87    buf   lbuf rbuf   
 88    
 89    if !fleft.open( left, $OP_READONLY ) : return 0
 90    lsize = fleft.getsize( )   
 91    size = 0x8000
 92    if fright.open( right, $OP_READONLY ) && lsize == fright.getsize()
 93    {
 94       while lsize
 95       {
 96          temp = min( lsize, size )//300000 )
 97          lbuf.use = 0
 98          rbuf.use = 0
 99          fleft.read( lbuf, temp )
100          fright.read( rbuf, temp )
101          if mcmp( lbuf.ptr(), rbuf.ptr(), temp ) : break
102          lsize -= temp
103          size = 0x80000
104       }
105       if !lsize : result = 1
106    }
107    fleft.close()
108    fright.close()
109    return result
110 }
111 
112 /*-----------------------------------------------------------------------------
113 * Id: copyfiles F
114 *
115 * Summary: Copying files and directories by mask. 
116 *  
117 * Params: src - The names of mask of the files or directories being copied. 
118           dir - The directory where files will be copied. 
119           flag - The combination of search and copy flags./
120                  $$[findflags]$$[fcopyflags]  
121           mode - What to do if the file being copied already /
122                  exists.$$[fcopymode] 
123           proccess - The identifier of the function handling messages. /
124                    You can use #b(&defcopyproc) as a default process function.  
125 * 
126 * Return: The function returns 1 if the copy operation is successful, 
127           otherwise it returns 0. 
128 *
129 -----------------------------------------------------------------------------*/
130 
131 func uint copyfiles( str src, str dir, uint flag, uint mode, uint process )
132 {
133    uint     notifyret
134    
135    subfunc uint notify( uint code, uint left right )
136    {
137       if process : notifyret = process->func( code, left, right )
138       return notifyret
139    }
140    
141    ffind  fd
142    str    destname srcdir temp wcard
143    arrstr    dirs 
144    uint   i
145 
146    src.ffullname( src )
147    dir.ffullname( dir )
148    srcdir.fgetdir( src )
149    wcard.fnameext( src )
150    
151    fd.init( src, flag )
152    
153    foreach finfo cur, fd
154    {
155       if flag & $COPYF_SAVEPATH : temp.copy( cur.fullname.ptr() + *srcdir + 1 )
156       else : temp = cur.name
157       ( destname = dir ).faddname( temp )
158          
159       if notify( $COPYN_FOUND, &cur, &destname ) == $COPYR_SKIP : continue
160       
161       if cur.attrib & $FILE_ATTRIBUTE_DIRECTORY : temp = destname
162       else : temp.fgetdir( destname )
163 
164       label dirretry      
165       if !verifypath( temp, dirs ) 
166       {
167          notify( $COPYN_ERRDIR, &dirs[*dirs - 1], 0 )
168          if notifyret == $COPYR_RETRY : goto dirretry
169          if notifyret == $COPYR_BREAK : return 0
170       }
171       
172       foreach str ndir, dirs : notify( $COPYN_NEWDIR, &ndir, 0 )
173       
174       if cur.attrib & $FILE_ATTRIBUTE_DIRECTORY
175       {
176          if !( flag & $FIND_RECURSE ) || wcard != "*.*" 
177          {
178             ( temp = cur.fullname ).faddname( "*.*" )
179             copyfiles( temp, destname, flag | $FIND_RECURSE, mode, process )
180          }
181       }
182       else
183       {
184          uint noexist
185          
186          if fileexist( destname )
187          {
188             finfo fi
189             
190             if mode == $COPY_SKIP : continue
191 
192             getfileinfo( destname, fi )
193             
194             if mode == $COPY_NEWER && 
195                 CompareFileTime( cur.lastwrite, fi.lastwrite ) <= 0 
196             {
197                continue
198             }
199             if mode == $COPY_MODIFIED && fi.sizelo == cur.sizelo && 
200                isequalfiles( cur.fullname, destname )
201             {
202                continue
203             }
204             if flag & $COPYF_ASK
205             {
206                notify( $COPYN_ASK, &cur, &fi )
207                switch notifyret
208                {
209                   case $COPYR_BREAK : return 0
210                   case $COPYR_SKIP : continue
211                   case $COPYR_OVERALL : flag &= ~$COPYF_ASK
212                   case $COPYR_SKIPALL 
213                   {
214                      mode = $COPY_SKIP
215                      continue
216                   }
217                }
218             }
219             if flag & $COPYF_RO && fi.attrib & $FILE_ATTRIBUTE_READONLY
220             {
221                setattribnormal( destname )
222             }
223          }
224          else : noexist = 1
225 
226          file fsrc fdest
227          uint size icopy
228          buf   cbuf
229          
230          label fileretry
231          
232          if !fsrc.open( cur.fullname, $OP_READONLY ) 
233          {
234             switch notify( $COPYN_ERRFILE, &cur.fullname, 0 )
235             {
236                case $COPYR_BREAK : return 0
237                case $COPYR_RETRY : goto fileretry
238                case $COPYR_SKIP : continue
239             }
240          }
241          
242          if !fdest.open( destname, $OP_CREATE ) 
243          {
244             fsrc.close( )
245             switch notify( $COPYN_ERRFILE, &destname, 0 )
246             {
247                case $COPYR_BREAK : return 0
248                case $COPYR_RETRY : goto fileretry
249                case $COPYR_SKIP : continue
250             }
251          }
252 
253          if noexist : notify( $COPYN_NEWFILE, &destname, 0 )
254 
255          notify( $COPYN_BEGIN, &cur, &destname )
256          size = cur.sizelo
257          
258          uint copied = 0
259          while size
260          {
261             icopy = min( size, 0x80000 )//300000 )
262             cbuf.use = 0
263             fsrc.read( cbuf, icopy )
264             label writeretry
265             if !fdest.write( cbuf )
266             {
267                switch notify( $COPYN_ERRWRITE, &destname, 0 )
268                {
269                   case $COPYR_BREAK : return 0
270                   case $COPYR_RETRY : goto writeretry
271                   case $COPYR_SKIP : break
272                }
273             }
274             notify( $COPYN_PROCESS, &destname, 
275                     uint( long( copied += icopy ) * 100L / long( cur.sizelo )))
276             size -= icopy
277          }
278          //SetFileTime( hdest, 0->filetime, 0->filetime, cur.lastwrite )
279          fdest.settime( cur.lastwrite )
280          fdest.close( )
281          fsrc.close( )
282          setfileattrib( destname, cur.attrib )
283          notify( $COPYN_END, &cur, &destname )         
284       }
285    }
286    return 1
287 }
288 
289 /*-----------------------------------------------------------------------------
290 ** Id: copyfiles_1 F8
291 *
292 * Summary: This is a default process function for #b(copyfiles). You can 
293            develop and use your own process function like it. 
294 *  
295 * Params: code - The message code.$$[fcopymsg] 
296           left - Additional parameter. 
297           right - Additional parameter. 
298 * 
299 * Return: You should return one of the following values: $$[fcopyret] 
300 *
301 -----------------------------------------------------------------------------*/
302 
303 func uint defcopyproc( uint code, uint left, uint right )
304 {
305    switch code
306    {
307 /*      case $COPYN_FOUND {
308          print("FOUND = \( left->finfo.fullname ) to \( right->str )\n")
309       }
310       case $COPYN_NEWDIR {
311          print("NEWDIR = \( left->str )\n")
312       }
313       case $COPYN_NEWFILE {
314          print("NEWFILE = \( left->str )\n")
315       }*/      
316       case $COPYN_BEGIN {
317          print("Copying \( right->str )  0%\r")
318       }
319       case $COPYN_PROCESS {
320          print("Copying \( left->str ) \( right )%\r")
321       }
322       case $COPYN_END {
323          print("Copied  \( right->str ) 100%\n")
324       }
325       case $COPYN_ERRDIR {
326          return ?( conrequest("Cannot create a directory \( left->str )!
327 Abort [A] | Retry [R] : ", "Aa|Rr" ), $COPYR_RETRY, $COPYR_BREAK )
328       }
329       case $COPYN_ASK {
330          str  edate etime
331          str  ndate ntime
332          uint ret
333 
334          getfiledatetime( right->finfo.lastwrite, edate, etime )
335          getfiledatetime( left->finfo.lastwrite, ndate, ntime )
336       
337          ret = conrequest("File already exists
338 Existing File: \( right->finfo.fullname )
339 Size: \( right->finfo.sizelo ) Date: \(edate) Time: \(etime)
340      New File: \( left->finfo.fullname )
341 Size: \( left->finfo.sizelo ) Date: \(ndate) Time: \(ntime)
342 
343 Overwrite [O] | Skip [S] | Overwrite All [V] | Skip All [K] | Abort [A] : ",
344 "Oo|Ss|Vv|Kk|Aa" )
345          switch ret 
346          {
347             case 0 : return $COPYR_OVER
348             case 1 : return $COPYR_SKIP
349             case 2 : return $COPYR_OVERALL
350             case 3 : return $COPYR_SKIPALL
351             case 4 : return $COPYR_BREAK
352          }
353       }
354       case $COPYN_ERRFILE, $COPYN_ERRWRITE {
355          switch conrequest( "Cannot \( ?( code == $COPYN_ERRFILE,"open/create a file","write to a file" )) \( left->str )!
356 Abort [A] | Retry [R] | Skip [S]: ", "Aa|Rr|Ss" )
357          {
358             case 0: return $COPYR_BREAK
359             case 1: return $COPYR_RETRY
360             case 2: return $COPYR_SKIP
361          }
362       }
363    }
364    return 0
365 }
366 
Редактировать