1. --****************************************************************************
  2. -- Software: BINARY FILE INTERFACE (fileIO Xtra version)
  3. -- Version:  0.4 - D10 version based on binary strings
  4. -- Date:     2015-02-03
  5. -- Author:   Valentin Schmidt
  6. --
  7. -- Requirements/Dependencies:
  8. -- - Xtra "fileIO"
  9. --
  10. -- Interface for binary file operations
  11. --
  12. -- ************************************************************************
  13.  
  14. --------------------------------------
  15. -- Opens file with specified mode, returns file pointer (xtra instance) or false
  16. -- @param {string} tFile
  17. -- @param {string} tMode - r, w, a, r+, w+, a+ (,rw, wr)
  18. -- @return {instance|false}
  19. --------------------------------------
  20. on fopen (tFile, tMode)
  21.   fp = xtra("fileIO").new()
  22.  
  23.   --  'r' Open for reading only; place the file pointer at the beginning of the file.  
  24.   --  'r+' Open for reading and writing; place the file pointer at the beginning of the file.  
  25.   --  '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.  
  26.   --  '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.  
  27.   --  '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.  
  28.   --  '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.
  29.  
  30.   case (tMode) of
  31.     "r":
  32.       fp.openFile(tFile, 1)
  33.     "r+","rw","wr":
  34.       fp.openFile(tFile, 0)
  35.     "w":
  36.       fp.createFile(tFile)
  37.       fp.openFile(tFile, 2)
  38.     "w+":
  39.       fp.createFile(tFile)
  40.       fp.openFile(tFile, 0)
  41.     "a":
  42.       fp.openFile(tFile, 2)
  43.       fp.setPosition(fp.getLength())
  44.     "a+":
  45.       fp.openFile(tFile, 0)
  46.       fp.setPosition(fp.getLength())
  47.      
  48.     otherwise:
  49.       return false
  50.   end case
  51.  
  52.   if (fp.status()<>0) then fp = 0
  53.   return fp
  54. end
  55.  
  56. --------------------------------------
  57. -- Closes open file
  58. -- @param {instance} fp
  59. --------------------------------------
  60. on fclose (fp)
  61.   fp.closeFile()
  62.   fp = 0
  63. end
  64.  
  65. --------------------------------------
  66. -- Reads n (non-binary) bytes from open file, returns string
  67. -- @param {instance} fp
  68. -- @param {integer} n
  69. -- @return {string}
  70. --------------------------------------
  71. on freadstring(fp, n)
  72.   if voidP(n) then n = fp.getLength() - fp.getPosition()
  73.   data = ""
  74.   repeat with i = 1 to n
  75.     c = fp.readChar()
  76.     if fp.status()<>0 then exit repeat
  77.     put c after data
  78.   end repeat
  79.   return data
  80. end
  81.  
  82. --------------------------------------
  83. -- Writes string to open file
  84. -- @param {instance} fp
  85. -- @param {string} str
  86. --------------------------------------
  87. on fwritestring (fp, str)
  88.   fp.writeString(str)
  89. end
  90.  
  91. --------------------------------------
  92. -- Reads n bytes from open file, returns (binary) string
  93. -- @param {instance} fp
  94. -- @param {integer} n
  95. -- @return {string}
  96. --------------------------------------
  97. on freadbytes(fp, n)
  98.   if voidP(n) then n = fp.getLength() - fp.getPosition()
  99.   data = ""
  100.   repeat with i = 1 to n
  101.     c = fp.readChar()
  102.     if fp.status()<>0 then exit repeat
  103.     put numtochar(chartonum(c)) after data
  104.   end repeat
  105.   return data
  106. end
  107.  
  108. --------------------------------------
  109. -- Writes (binary) string to open file (alias of fwritestring)
  110. -- @param {instance} fp
  111. -- @param {string} str
  112. --------------------------------------
  113. on fwritebytes (fp, str)
  114.   fp.writeString(str)
  115. end
  116.  
  117. --------------------------------------
  118. -- Returns position in open file
  119. -- @param {instance} fp
  120. -- @return {integer}
  121. --------------------------------------
  122. on ftell (fp)
  123.   return fp.getPosition()
  124. end
  125.  
  126. --------------------------------------
  127. -- Sets position in open file
  128. -- whence: either integer or symbol
  129. -- 0 or #SEEK_SET: set position to offset bytes. (default)
  130. -- 1 or #SEEK_CUR: set position to current position plus offset.
  131. -- 2 or #SEEK_END: set position to end of file plus offset.
  132. -- @param {instance} fp
  133. -- @param {integer} pos
  134. -- @param {integer|symbol} whence - optional, default = 0
  135. -- @return {bool} success
  136. --------------------------------------
  137. on fseek (fp, pos, whence)
  138.   if voidP(whence) then whence = 0
  139.   else if ilk(whence)=#symbol then
  140.     whence = [#SEEK_SET, #SEEK_CUR, #SEEK_END].getPos(whence)
  141.     if whence>0 then whence=whence-1
  142.   end if
  143.  
  144.   case (whence) of
  145.     0: fp.setPosition(pos)  
  146.     1: fp.setPosition(fp.getPosition() + pos)
  147.     2: fp.setPosition(fp.getLength() + pos)
  148.   end case
  149.  
  150.   return (fp.status()=0)
  151. end
  152.  
  153. --------------------------------------
  154. -- Returns size of open file
  155. -- @param {instance} fp
  156. -- @return {integer}
  157. --------------------------------------
  158. on fsize (fp)
  159.   return fp.getLength()
  160. end
  161.  
  162. --**************************************
  163. -- global functions, no file pointer passed
  164. --**************************************
  165.  
  166. ----------------------------------------
  167. -- Returns file size
  168. -- @param {string} tFile
  169. -- @return {integer|false}
  170. ----------------------------------------
  171. on file_size (tFile)
  172.   fp = xtra("fileIO").new()
  173.   fp.openFile(tFile, 1)
  174.   err = fp.status()
  175.   if err<>0 then return false
  176.   len = fp.getLength()
  177.   fp.closeFile()
  178.   fp = 0
  179.   return len
  180. end
  181.  
  182. ----------------------------------------
  183. -- Truncates file
  184. -- WARNING: only suited for smaller files, reads complete file into RAM!
  185. -- @param {string} tFile
  186. -- @param {integer} tSize
  187. -- @return {bool} success
  188. ----------------------------------------
  189. on file_truncate (tFile, tSize)
  190.   fp = xtra("fileIO").new()
  191.   fp.openFile(tFile, 0)
  192.   data = ""
  193.   repeat with i = 1 to tSize
  194.     c = fp.readChar()
  195.     if fp.status()<>0 then exit repeat
  196.     put numtochar(chartonum(c)) after data
  197.   end repeat
  198.  
  199.   fn = fp.fileName()
  200.   fp.delete()
  201.   fp.createFile(fn)
  202.   fp.openFile(fn, 2)
  203.   fp.writeString(data)
  204.   err = fp.status()
  205.   fp.closeFile()
  206.   fp=0
  207.  
  208.   return (err=0)
  209. end
  210.  
  211. ----------------------------------------
  212. -- Deletes file
  213. -- @param {string} tFile
  214. -- @return {bool} success
  215. ----------------------------------------
  216. on file_delete (tFile)
  217.   fp = xtra("fileIO").new()
  218.   fp.openFile(tFile, 0)
  219.   err = fp.status()
  220.   if (err=0) then err = fp.delete()
  221.   fp = 0
  222.   return (err=0)
  223. end
  224.  
  225. ----------------------------------------
  226. -- @param {string} tFile
  227. -- @return {bool} exists
  228. ----------------------------------------
  229. on file_exists (tFile)
  230.   fp = xtra("fileIO").new()
  231.   fp.openFile(tFile, 1)
  232.   stat = fp.status()
  233.   fp.closeFile()
  234.   fp = 0
  235.   return (stat<>-37)
  236. end
  237.  
  238. ----------------------------------------
  239. -- Reads whole (non-binary) file, returns string
  240. -- @param {string} tFile
  241. -- @return {string|false}
  242. ----------------------------------------
  243. on file_get_string (tFile)
  244.   fp = xtra("fileIO").new()
  245.   fp.openFile(tFile,1)
  246.   err = fp.status()
  247.   if (err) then return false
  248.   ret = fp.readFile()
  249.   fp.closeFile()
  250.   fp = 0
  251.   return ret
  252. end
  253.  
  254. ----------------------------------------
  255. -- Saves string as file
  256. -- @param {string} tFile
  257. -- @param {string} tString
  258. -- @return {bool} success
  259. ----------------------------------------
  260. on file_put_string (tFile, tString)
  261.  
  262.   fp = xtra("fileIO").new()  
  263.   fp.openFile(tFile, 1)
  264.   err = fp.status()
  265.   if (err=0) then fp.delete()
  266.   else if (err and not (err = -37)) then return false
  267.  
  268.   fp.createFile(tFile)
  269.   err = fp.status()
  270.   if (err<>0) then return false
  271.  
  272.   fp.openFile(tFile, 2)
  273.   err = fp.status()
  274.   if (err<>0) then return false
  275.    
  276.   fp.writeString(tString)
  277.   fp.closeFile()
  278.   fp=0
  279.  
  280.   return (err=0)
  281. end
  282.  
  283. ----------------------------------------
  284. -- Reads whole binary file, returns binary string
  285. -- Includes optimization for dealing with large strings
  286. -- @param {string} tFile
  287. -- @return {string|false}
  288. ----------------------------------------
  289. on file_get_bytes (tFile)
  290.  
  291.   fp = xtra("fileIO").new()
  292.   fp.openFile(tFile, 1)
  293.   err = fp.status()
  294.   if (err<>0) then return false
  295.    
  296.   subLengthLim = 5000 -- adjust!
  297.   chunks = []
  298.   tmp = ""
  299.  
  300.   repeat while true
  301.     c=fp.readChar()
  302.     if fp.status()<>0 then exit repeat
  303.     put numtochar(chartonum(c)) after tmp
  304.     if length(tmp) > subLengthLim then
  305.       chunks.append(tmp)
  306.       tmp = ""
  307.     end if
  308.   end repeat
  309.  
  310.   -- assemble as large string
  311.   data = ""
  312.   repeat with str in chunks
  313.     put str after data
  314.   end repeat
  315.   put tmp after data
  316.  
  317.   fp.closeFile()
  318.   fp = 0
  319.   return data
  320.  
  321. end
  322.  
  323. ----------------------------------------
  324. -- Saves (binary) string as file (alias of file_put_string)
  325. -- @param {string} tFile
  326. -- @param {string} tString
  327. -- @return {bool} success
  328. ----------------------------------------
  329. on file_put_bytes (tFile, tString)
  330.   return file_put_string(tFile, tString)
  331. end
  332.  
  333. ----------------------------------------
  334. -- Display open file dialog
  335. -- @param {string} title - optional, ignored in fileIO version
  336. -- @param {string} filterMask - optional
  337. -- @param {string} defaultFileName - optional, ignored in fileIO version
  338. -- @return {string} filename
  339. ----------------------------------------
  340. on display_open (title, filterMask, defaultFileName)  
  341.   fio=xtra("fileIO").new()  
  342.   fio.setFilterMask(filterMask)
  343.   fn=fio.displayOpen()
  344.   fio=0
  345.   return string(fn)
  346. end
  347.  
  348. ----------------------------------------
  349. -- Display save file dialog
  350. -- @param {string} title
  351. -- @param {string} filterMask - optional
  352. -- @param {string} defaultFileName
  353. -- @return {string} filename
  354. ----------------------------------------
  355. on display_save (title, filterMask, defaultFileName)  
  356.   fio=xtra("fileIO").new()  
  357.   fio.setFilterMask(filterMask)
  358.   fn=fio.displaySave(title, defaultFileName)
  359.   fio=0
  360.   return string(fn)
  361. end
  362.  
[raw code]