root/HTTP/File.lua

Revision 1445 (checked in by rsz, 2 months ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               File.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       January 30, 2007
6 -- Legal:               Copyright (C) 2007 Raphaël Szwarc
7 --                      Under the terms of the MIT License
8 --                      http://www.opensource.org/licenses/mit-license.html
9 --------------------------------------------------------------------------------
10
11 -- import dependencies
12 local io = require( 'io' )
13 local lfs = require( 'lfs' )
14 local os = require( 'os' )
15 local table = require( 'table' )
16
17 local assert = assert
18 local getmetatable = getmetatable
19 local package = package
20 local pairs = pairs
21 local require = require
22 local setmetatable = setmetatable
23 local tostring = tostring
24
25 --------------------------------------------------------------------------------
26 -- File
27 --------------------------------------------------------------------------------
28
29 module( 'File' )
30 _VERSION = '1.0'
31
32 local self = setmetatable( _M, {} )
33 local meta = getmetatable( self )
34
35 self.separator = package.path:match( '(%p)%?%.' ) or '/'
36
37 --------------------------------------------------------------------------------
38 -- Utilities
39 --------------------------------------------------------------------------------
40
41 local function Reader( aPath )
42     return assert( io.open( aPath, 'rb' ) )
43 end
44
45 local function Writer( aPath )
46     return assert( io.open( aPath, 'wb' ) )
47 end
48
49 local function ReadContent( aPath )
50     local aReader = Reader( aPath )
51     local aContent = assert( aReader:read( '*a' ) )
52    
53     aReader:close()
54        
55     return aContent
56 end
57
58 local function WriteContent( aPath, aContent )
59     local aWriter = Writer( aPath )
60    
61     assert( aWriter:write( aContent ) )
62     assert( aWriter:close() )
63 end
64
65 local function Exists( aPath )
66     if lfs.attributes( aPath, 'size' ) then
67         return true
68     end
69    
70     return false
71 end
72
73 local function Name( aPath )
74     local anIndex = aPath:reverse():find( self.separator, 1, true )
75    
76     if anIndex == 1 then
77         return Name( aPath:sub( 1, aPath:len() - 1 ) )
78     end
79    
80     if anIndex then
81         return aPath:sub( aPath:len() - anIndex + 2 )
82     end
83    
84     return aPath
85 end
86
87 local function Extension( aPath )
88     local aName = Name( aPath )
89    
90     if aName then
91         local anIndex = aName:reverse():find( '.', 1, true )
92        
93         if anIndex then
94             return aName:sub( aName:len() - anIndex + 2 )
95         end
96     end
97 end
98
99 --------------------------------------------------------------------------------
100 -- Metamethods
101 --------------------------------------------------------------------------------
102
103 function meta:__call( ... )
104     local aPath = table.concat( { ... }, self.separator )
105     local aFile = { path = aPath }
106    
107     if aPath == '' then
108         aFile.path = lfs.currentdir()
109     end
110
111     setmetatable( aFile, self )
112    
113     return aFile
114 end
115
116 function meta:__concat( aValue )
117     return tostring( self ) .. tostring( aValue )
118 end
119
120 function meta:__tostring()
121     return ( '%s/%s' ):format( self._NAME, self._VERSION )
122 end
123
124 function self:__call( isDeep )
125     local File = require( 'File' )
126     local aPath = self.path
127     local anIterator = lfs.dir( aPath )
128     local somePaths = nil
129     local aPathIterator = nil
130    
131     aPathIterator = function()
132         local aName = anIterator()
133
134         while aName and ( aName == '.' or aName == '..' ) do
135             aName = anIterator()
136         end
137
138         if aName then
139             local aFile = File( aPath, aName )
140            
141             if isDeep == true and aFile.mode == 'directory' then
142                 somePaths = somePaths or {}
143                 somePaths[ #somePaths + 1 ] = aFile.path
144             end
145            
146             return aFile
147         end
148        
149         if isDeep and somePaths and #somePaths > 0 then
150             aPath = table.remove( somePaths )
151             anIterator = lfs.dir( aPath )
152            
153             return aPathIterator()
154         end
155     end
156    
157     return aPathIterator
158 end
159
160 function self:__index( aKey )
161     if aKey == 'content' then
162         return ReadContent( self.path )
163     elseif aKey == 'exists' then
164         return Exists( self.path )
165     elseif aKey == 'extension' then
166         return Extension( self.path )
167     elseif aKey == 'name' then
168         return Name( self.path )
169     elseif aKey == 'reader' then
170         return Reader( self.path )
171     elseif aKey == 'writer' then
172         return Writer( self.path )
173     end
174    
175     return lfs.attributes( self.path, aKey )
176 end
177
178 function self:__newindex( aKey, aValue )
179     if aKey == 'content' then
180         WriteContent( self.path, aValue )
181     elseif aKey == 'delete' and aValue == true then
182         assert( os.remove( self.path ) )
183     elseif aKey == 'modification' then
184         assert( lfs.touch( self.path, aValue ) )
185     end
186 end
187
188 function self:__concat( aValue )
189     return tostring( self ) .. tostring( aValue )
190 end
191
192 function self:__eq( aValue )
193     return tostring( self ) == tostring( aValue )
194 end
195
196 function self:__lt( aValue )
197     return tostring( self ) < tostring( aValue )
198 end
199
200 function self:__tostring()
201     return tostring( self.path )
202 end
203
204
Note: See TracBrowser for help on using the browser.