Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- MIT License
- Copyright (c) 2016 Sewbacca
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- --]]
- -- Vars
- local FSector = {}
- -- Shortuct headers
- local patternToString;
- -- Shortcuts
- local string_gsub = string.gsub
- patternToString = function (sText)
- return sText:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', function(sMatch) return '%' .. sMatch end)
- end
- -- Install FSector API
- FSector.create = function (parent, sRootDir)
- -- Error providing
- if type(parent) ~= 'table' or type(sRootDir) ~= 'string' then
- error('object parent, string rootDir expected', 2)
- end
- sRootDir = parent.combine('/', sRootDir)
- if not parent.exists(sRootDir) then
- error('Invalid Path', 2)
- end
- -- Setup
- local fs = {}
- local tReadOnly = {}
- local tMountedPaths = {}
- -- Shortcut headers
- local resolveMounted;
- local resolve;
- local find;
- -- Shortucts
- resolveMounted = function (sResolved, bIsMounted, b)
- if tMountedPaths[sResolved] then
- return bIsMounted and true or resolveMounted(tMountedPaths[sResolved])
- end
- local sResolvedPath = sResolved .. '/'
- for sDestination, sSource in pairs(tMountedPaths) do
- if sResolvedPath:sub(1, #sDestination + 1) == sDestination .. '/' then
- return bIsMounted and true or resolveMounted(parent.combine(sSource, sResolved:sub(#sDestination + 1, -1)))
- end
- end
- return bIsMounted and false or sResolved
- end
- resolve = function (sPath, bRaw)
- if type(sPath) ~= 'string' then
- error('string expected, got ' .. type(sPath), 3)
- end
- local sCombined = parent.combine(sRootDir, sPath) .. '/'
- local sPrefix = sCombined:sub(1, #sRootDir + 1)
- if sRootDir ~= '' and sPrefix ~= sRootDir .. '/' then
- error('Invalid Path', 3)
- end
- sCombined = sCombined:sub(1, -2)
- return bRaw and sCombined or resolveMounted(sCombined)
- end
- find = function (sPos, sFullWildcard)
- -- work in progress
- end
- -- Install handle
- fs.combine = function (...)
- return parent.combine(...)
- end
- fs.complete = function (sPrefix, sDir, ...)
- sDir = resolve(sDir)
- return parent.complete(sPrefix, sDir, ...)
- end
- fs.copy = function (sSource, sDestination)
- if fs.isReadOnly(sDestination) then
- error('Access Denied', 2)
- end
- sSource, sDestination = resolve(sSource), resolve(sDestination)
- return parent.copy(sSource, sDestination)
- end
- fs.delete = function (sPath)
- if fs.isReadOnly(sPath) then
- error('Access Denied', 2)
- end
- if fs.isMounted(sPath, true) then
- fs.dismount(sPath)
- return
- end
- sPath = resolve(sPath)
- return parent.delete(sPath)
- end
- fs.exists = function (sPath)
- local sPath = resolve(sPath)
- return parent.exists(sPath)
- end
- fs.find = function (sWildcard)
- sWildcard = resolve(sWildcard, true)
- local ok, tRes = pcall(parent.find, sWildcard)
- if not ok then
- error(tRes, 2)
- end
- for i = 1, #tRes do
- tRes[i] = ('/' .. tRes[i]:sub(#sRootDir + 1, -1)):gsub('//?', '', 1)
- end
- -- work in progress
- return tRes
- end
- fs.getDir = function (...)
- return parent.getDir(...)
- end
- fs.getDrive = function (sPath)
- if fs.isReadOnly(sPath) then
- return 'rom'
- end
- sPath = resolve(sPath)
- return parent.getDrive(sPath)
- end
- fs.getFreeSpace = function (sPath)
- if fs.isReadOnly(sPath) then
- return 0
- end
- sPath = resolve(sPath)
- return parent.getFreeSpace(sPath)
- end
- fs.getName = function (...)
- return parent.getName(...)
- end
- fs.getSize = function (sPath)
- sPath = resolve(sPath)
- return parent.getSize(sPath)
- end
- fs.isDir = function (sPath)
- sPath = resolve(sPath)
- return parent.isDir(sPath)
- end
- fs.isReadOnly = function (sPath)
- sPath = resolve(sPath)
- local tmpPath = sPath .. '/'
- for sReadOnly in pairs(tReadOnly) do
- if tmpPath:sub(1, #sReadOnly + 1) == sReadOnly .. '/' then
- return true
- end
- end
- return parent.isReadOnly(sPath)
- end
- fs.setReadOnly = function (sPath, bReadOnly)
- sPath = resolve(sPath)
- bReadOnly = bReadOnly and true or false
- tReadOnly[sPath] = parent.isReadOnly(sPath) or bReadOnly and true or nil
- end
- fs.list = function (sDir)
- sDir = resolve(sDir)
- local ok, tRes = pcall(parent.list, sDir)
- if not ok then
- error(tRes, 2)
- end
- for sMounted in pairs(tMountedPaths) do
- if parent.getDir(sMounted) == sDir then
- tRes[#tRes + 1] = parent.getName(sMounted)
- end
- end
- table.sort(tRes)
- return tRes
- end
- fs.makeDir = function (sPath)
- sPath = resolve(sPath)
- return parent.makeDir(sPath)
- end
- fs.mount = function (sSource, sDestination)
- sSource, sDestination = resolve(sSource), resolve(sDestination)
- if not parent.exists(sSource) or parent.exists(sDestination) then
- return false
- end
- tMountedPaths[sDestination] = sSource
- return true
- end
- fs.dismount = function (sPath)
- sPath = resolve(sPath, true)
- tMountedPaths[sPath] = nil
- end
- fs.isMounted = function (sPath, bNotRaw)
- sPath = resolve(sPath, true)
- if not bNotRaw then
- return resolveMounted(sPath, true)
- end
- return tMountedPaths[sPath] and true or false
- end
- fs.move = function (sSource, sDestination)
- resolve(sSource)
- resolve(sDestination)
- if fs.isReadOnly(sSource) or fs.isReadOnly(sDestination) or fs.isMounted(sSource) or fs.isMounted(sDestination) then
- error('Access Denied', 2)
- end
- sSource, sDestination = resolve(sSource), resolve(sDestination)
- return parent.move(sSource, sDestination)
- end
- fs.open = function (sPath, sMode)
- if fs.isReadOnly(sPath) and sMode:match 'a' and sMode:match 'w' then
- return nil
- end
- sPath = resolve(sPath)
- return parent.open(sPath, sMode)
- end
- -- Return handle
- return fs
- end
- -- Add redirection
- do
- -- Code taken from rom/apis/term and modified by Sewbacca
- local native = (fs.native and fs.native()) or nil
- if not native then
- native = {}
- for key, value in pairs(fs) do
- native[key] = value
- end
- for key in pairs(native) do
- fs[key] = nil
- end
- end
- local redirectTarget = native
- local function wrap(_sFunction)
- return function(...)
- return redirectTarget[ _sFunction ](...)
- end
- end
- fs.redirect = function(target)
- if target == nil or type(target) ~= 'table' then
- error('Invalid redirect target', 2)
- end
- if target == fs then
- error('fs is not a recommended redirect target, try fs.current() instead', 2)
- end
- for k, v in pairs(native) do
- if type(k) == 'string' and type(v) == 'function' then
- if type(target[k]) ~= 'function' then
- target[k] = function ()
- error('Redirect object is missing method '..k..'.', 2)
- end
- end
- end
- end
- local oldRedirectTarget = redirectTarget
- redirectTarget = target
- return oldRedirectTarget
- end
- fs.current = function ()
- return redirectTarget
- end
- fs.native = function ()
- -- NOTE: please don't use this function unless you have to.
- -- If you're running in a redirected or multitasked enviorment, fs.native() will NOT be
- -- the current fs when your program starts up. It is far better to use fs.current()
- return native
- end
- for k, v in pairs(native) do
- if type(k) == 'string' and type(v) == 'function' then
- if fs[k] == nil then
- fs[k] = wrap(k)
- end
- end
- end
- end
- -- End adding redirection
- -- Return API
- return FSector
- -- End
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement