-- ************************************************************************
-- Software: BINARY FILE INTERFACE (fileIO Xtra version)
-- Version: 0.6 - D11.5+ version based on bytearray
-- Date: 2014-11-10
-- Author: Valentin Schmidt
--
-- Requirements/Dependencies:
-- - Xtra "fileIO"
--
-- Interface for binary file operations
--
-- ************************************************************************
----------------------------------------
-- Opens file with specified mode, returns file pointer (xtra instance) or 0
-- @param {string} tFile
-- @param {string} tMode - r, w, a, r+, w+, a+ (,rw, wr)
-- @return {instance|false}
----------------------------------------
on fopen (tFile, tMode)
fp = xtra("fileIO").new()
-- 'r' Open for reading only; place the file pointer at the beginning of the file.
-- 'r+' Open for reading and writing; place the file pointer at the beginning of the file.
-- 'w' Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
-- 'w+' Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
-- 'a' Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
-- 'a+' Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
pos = offset("b", tMode)
is_binary = false -- currently not used
if pos then
is_binary = true
delete char pos of tMode
end if
case (tMode) of
"r":
fp.openFile(tFile, 1)
"r+","rw","wr":
fp.openFile(tFile, 0)
"w":
fp.createFile(tFile)
fp.openFile(tFile, 2)
"w+":
fp.createFile(tFile)
fp.openFile(tFile, 0)
"a":
fp.openFile(tFile, 2)
fp.setPosition(fp.getLength())
"a+":
fp.openFile(tFile, 0)
fp.setPosition(fp.getLength())
otherwise:
return false
end case
if (fp.status()<>0) then fp = 0
return fp
end
----------------------------------------
-- Closes open file
-- @param {instance} fp
----------------------------------------
on fclose (fp)
fp.closeFile()
fp = 0
end
----------------------------------------
-- Reads n bytes from open file, returns bytearray
-- @param {instance} fp
-- @param {integer} n
-- @return {bytearray}
----------------------------------------
on freadbytes(fp, n)
ba = fp.readByteArray(n)
ba.position = 1
return ba
end
----------------------------------------
-- Writes byteArray to open file
-- @param {instance} fp
-- @param {bytearray} ba
----------------------------------------
on fwritebytes (fp, ba)
return fp.writeByteArray(ba)
end
----------------------------------------
-- Reads n bytes from open file, returns string
-- @param {instance} fp
-- @param {integer} n
-- @return {string}
----------------------------------------
on freadstring(fp, n)
ba = freadbytes(fp, n)
ba.position = 1
return ba.readRawString(ba.length)
end
----------------------------------------
-- Writes string to open file
-- @param {instance} fp
-- @param {string} str
----------------------------------------
on fwritestring (fp, str)
fp.writeString(str)
end
----------------------------------------
-- Returns position in open file
-- @param {instance} fp
-- @return {integer}
----------------------------------------
on ftell (fp)
return fp.getPosition()
end
----------------------------------------
-- Sets position in open file
-- whence: either integer or symbol
-- 0 or #SEEK_SET: set position to offset bytes. (default)
-- 1 or #SEEK_CUR: set position to current position plus offset.
-- 2 or #SEEK_END: set position to end of file plus offset.
-- @param {instance} fp
-- @param {integer} pos
-- @param {integer|symbol} whence - optional, default = 0
-- @return {bool} success
----------------------------------------
on fseek (fp, pos, whence)
if voidP(whence) then whence = 0
else if ilk(whence)=#symbol then
whence = [#SEEK_SET, #SEEK_CUR, #SEEK_END].getPos(whence)
if whence>0 then whence=whence-1
end if
case (whence) of
0: fp.setPosition(pos)
1: fp.setPosition(fp.getPosition() + pos)
2: fp.setPosition(fp.getLength() + pos)
end case
return (fp.status()=0)
end
----------------------------------------
-- Returns size of open file
-- @param {instance} fp
-- @return {integer}
----------------------------------------
on fsize (fp)
return fp.getLength()
end
--**************************************
-- global functions, no file pointer passed
--**************************************
----------------------------------------
-- Returns file size
-- @param {string} tFile
-- @return {integer}
----------------------------------------
on file_size (tFile)
fp = xtra("fileIO").new()
fp.openFile(tFile, 1)
err = fp.status()
if err<>0 then return false
len = fp.getLength()
fp.closeFile()
fp = 0
return len
end
----------------------------------------
-- Truncates file
-- WARNING: only suited for smaller files, reads complete file into RAM!
-- @param {string} tFile
-- @param {integer} tSize
-- @return {bool} success
----------------------------------------
on file_truncate (tFile, tSize)
fp = xtra("fileIO").new()
fp.openFile(tFile, 0)
data = fp.readByteArray(tSize)
fp.delete()
err = fp.status()
if err<>0 then return false
fp.createFile(tFile)
fp.openFile(tFile, 2)
fp.writeByteArray(data)
err = fp.status()
fp.closeFile()
fp=0
return (err=0)
end
----------------------------------------
-- Deletes file
-- @param {string} tFile
-- @return {bool} success
----------------------------------------
on file_delete (tFile)
fp = xtra("fileIO").new()
fp.openFile(tFile, 0)
err = fp.status()
if (err=0) then err = fp.delete()
fp = 0
return (err=0)
end
----------------------------------------
-- Check if file exists
-- @param {string} tFile
-- @return {bool} exists
----------------------------------------
on file_exists (tFile)
fp = xtra("fileIO").new()
fp.openFile(tFile, 1)
stat = fp.status()
fp.closeFile()
fp = 0
return (stat<>-37)
end
----------------------------------------
-- Reads whole file, returns UTF-8 string
-- @param {string} tFile
-- @return {string|false}
----------------------------------------
on file_get_string (tFile)
fp = xtra("fileIO").new()
fp.openFile(tFile,1)
err = fp.status()
if (err) then return false
ret = fp.readFile()
fp.closeFile()
fp = 0
if chartonum(ret.char[1]) = 65279 then
delete char 1 of ret -- remove UTF-8 BOM
end if
return ret
end
----------------------------------------
-- Saves UTF-8 string as file
-- @param {string} tFile
-- @param {string} tString
-- @param {bool} [tAddBOM]
-- @return {bool} success
----------------------------------------
on file_put_string (tFile, tString, tAddBOM)
fp = xtra("fileIO").new()
fp.openFile(tFile, 1)
err = fp.status()
if (err=0) then fp.delete()
else if (err<> -37) then return false
fp.createFile(tFile)
err = fp.status()
if (err<>0) then return false
fp.openFile(tFile, 2)
err = fp.status()
if (err<>0) then return false
if tAddBOM then
fp.writeString(numtochar(65279)) -- add UTF-8 BOM
end if
err = fp.writeString(tString)
fp.closeFile()
fp=0
return (err=0)
end
----------------------------------------
-- Returns whole file, returns byteArray
-- @param {string} tFile
-- @return {bytearray|false}
----------------------------------------
on file_get_bytes (tFile)
fp = xtra("fileIO").new()
fp.openFile(tFile, 1)
err = fp.status()
if (err<>0) then return false
data = fp.readByteArray(fp.getLength())
fp.closeFile()
fp = 0
return data
end
----------------------------------------
-- Saves byteArray as file
-- @param {string} tFile
-- @param {byteArray} tByteArray
-- @return {bool} success
----------------------------------------
on file_put_bytes (tFile, tByteArray)
fp = xtra("fileIO").new()
fp.openFile(tFile, 1)
err = fp.status()
if (err=0) then fp.delete()
else if (err <> -37) then return false
fp.createFile(tFile)
err = fp.status()
if (err<>0) then return false
fp.openFile(tFile, 2)
err = fp.status()
if (err<>0) then return false
ok = fp.writeByteArray(tByteArray)
fp.closeFile()
fp=0
return (err=0)
end
----------------------------------------
-- Display open file dialog
-- @param {string} title - optional, ignored in fileIO version
-- @param {string} filterMask - optional
-- @param {string} defaultFileName - optional, ignored in fileIO version
-- @return {string} filename
----------------------------------------
on display_open (title, filterMask, defaultFileName)
fio=xtra("fileIO").new()
if stringP(filterMask) then fio.setFilterMask(filterMask)
fn=fio.displayOpen()
fio=0
return string(fn)
end
----------------------------------------
-- Display save file dialog
-- @param {string} title
-- @param {string} filterMask - optional
-- @param {string} defaultFileName
-- @return {string} filename
----------------------------------------
on display_save (title, filterMask, defaultFileName)
fio=xtra("fileIO").new()
if stringP(filterMask) then fio.setFilterMask(filterMask)
fn=fio.displaySave(title, defaultFileName)
fio=0
return string(fn)
end