filesystem.monkey2 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. Namespace std.filesystem
  2. Using libc
  3. #Import "native/filesystem.h"
  4. #Import "native/filesystem.cpp"
  5. Extern
  6. #rem monkeydoc Gets application directory.
  7. @return The directory containing the application executable.
  8. #end
  9. Function AppDir:String()="bbFileSystem::appDir"
  10. #rem monkeydoc Gets the application file path.
  11. @return The path of the application executable.
  12. #end
  13. Function AppPath:String()="bbFileSystem::appPath"
  14. #rem monkeydoc Gets application command line arguments.
  15. @return The application command line arguments.
  16. #end
  17. Function AppArgs:String[]()="bbFileSystem::appArgs"
  18. #rem monkeydoc Copies a file.
  19. @return True if the file was successfully copied.
  20. #end
  21. Function CopyFile:Bool( srcPath:String,dstPath:String )="bbFileSystem::copyFile"
  22. Public
  23. #rem monkeydoc FileType enumeration.
  24. | FileType | Description
  25. |:--------------|:-----------
  26. | `None` | File does not exist.
  27. | `File` | File is a normal file.
  28. | `Directory` | File is a directory.
  29. | `Unknown` | File is of unknown type.
  30. #end
  31. Enum FileType
  32. None=0
  33. File=1
  34. Directory=2
  35. Unknown=3
  36. End
  37. 'For backward compatibility - don't use!
  38. '
  39. #rem monkeydoc @hidden
  40. #end
  41. Const FILETYPE_NONE:=FileType.None
  42. #rem monkeydoc @hidden
  43. #end
  44. Const FILETYPE_FILE:=FileType.File
  45. #rem monkeydoc @hidden
  46. #end
  47. Const FILETYPE_DIR:=FileType.Directory
  48. #rem monkeydoc @hidden
  49. #end
  50. Const FILETYPE_UNKNOWN:=FileType.Unknown
  51. #rem monkeydoc Gets the filesystem directory of the assets folder.
  52. @return The directory app assets are stored in.
  53. #end
  54. Function AssetsDir:String()
  55. #If __TARGET__="desktop" And __HOSTOS__="macos"
  56. Return AppDir()+"../Resources/"
  57. #Else
  58. Return AppDir()+"assets/"
  59. #Endif
  60. End
  61. #rem monkeydoc Extracts the root directory from a file system path.
  62. @param path The filesystem path.
  63. @return The root directory of `path`, or an empty string if `path` is not an absolute path.
  64. #end
  65. Function ExtractRootDir:String( path:String )
  66. If path.StartsWith( "//" ) Return "//"
  67. Local i:=path.Find( "/" )
  68. If i=0 Return "/"
  69. If i=-1 i=path.Length
  70. Local j:=path.Find( "://" )
  71. If j>0 And j<i Return path.Slice( 0,j+3 )
  72. j=path.Find( ":/" )
  73. If j>0 And j<i Return path.Slice( 0,j+2 )
  74. j=path.Find( "::" )
  75. If j>0 And j<i Return path.Slice( 0,j+2 )
  76. Return ""
  77. End
  78. #rem monkeydoc Checks if a path is a root directory.
  79. @param path The filesystem path to check.
  80. @return True if `path` is a root directory path.
  81. #end
  82. Function IsRootDir:Bool( path:String )
  83. If path="//" Return True
  84. If path="/" Return True
  85. Local i:=path.Find( "/" )
  86. If i=-1 i=path.Length
  87. Local j:=path.Find( "://" )
  88. If j>0 And j<i Return j+3=path.Length
  89. j=path.Find( ":/" )
  90. If j>0 And j<i Return j+2=path.Length
  91. j=path.Find( "::" )
  92. If j>0 And j<i Return j+2=path.Length
  93. Return False
  94. End
  95. #rem monkeydoc Strips any trailing slashes from a filesystem path.
  96. This function will not strip slashes from a root directory path.
  97. @param path The filesystem path.
  98. @return The path stripped of trailing slashes.
  99. #end
  100. Function StripSlashes:String( path:String )
  101. If Not path.EndsWith( "/" ) Return path
  102. Local root:=ExtractRootDir( path )
  103. Repeat
  104. If path=root Return path
  105. path=path.Slice( 0,-1 )
  106. Until Not path.EndsWith( "/" )
  107. Return path
  108. End
  109. #rem monkeydoc Extracts the directory component from a filesystem path.
  110. If `path` is a root directory it is returned without modification.
  111. If `path` does not contain a directory component, an empty string is returned.
  112. @param path The filesystem path.
  113. @return The directory component of `path`.
  114. #end
  115. Function ExtractDir:String( path:String )
  116. path=StripSlashes( path )
  117. If IsRootDir( path ) Return path
  118. Local i:=path.FindLast( "/" )
  119. If i>=0 Return path.Slice( 0,i+1 )
  120. Return ""
  121. End
  122. #rem monkeydoc Strips the directory component from a filesystem path.
  123. If `path` is a root directory an empty string is returned.
  124. If `path` does not contain a directory component, `path` is returned without modification.
  125. @param path The filesystem path.
  126. @return The path with the directory component stripped.
  127. #end
  128. Function StripDir:String( path:String )
  129. path=StripSlashes( path )
  130. If IsRootDir( path ) Return ""
  131. Local i:=path.FindLast( "/" )
  132. If i>=0 Return path.Slice( i+1 )
  133. Return path
  134. End
  135. #rem monkeydoc Extracts the extension component from a filesystem path.
  136. @param path The filesystem path.
  137. @return The extension component of `path` including the '.' if any.
  138. #end
  139. Function ExtractExt:String( path:String )
  140. Local i:=path.FindLast( "." )
  141. If i=-1 Return ""
  142. Local j:=path.Find( "/",i+1 )
  143. If j=-1 Return path.Slice( i )
  144. Return ""
  145. End
  146. #rem monkeydoc Strips the extension component from a filesystem path
  147. @param path The filesystem path.
  148. @return The path with the extension stripped.
  149. #end
  150. Function StripExt:String( path:String )
  151. Local i:=path.FindLast( "." )
  152. If i=-1 Return path
  153. Local j:=path.Find( "/",i+1 )
  154. If j=-1 Return path.Slice( 0,i )
  155. Return path
  156. End
  157. #rem monkeydoc Converts a path to a real path.
  158. If `path` is a relative path, it is first converted into an absolute path by prefixing the current directory.
  159. Then, any internal './' or '../' references in the path are collapsed.
  160. @param path The filesystem path.
  161. @return An absolute path with any './', '../' references collapsed.
  162. #end
  163. Function RealPath:String( path:String )
  164. Local rpath:=ExtractRootDir( path )
  165. If rpath
  166. path=path.Slice( rpath.Length )
  167. Else
  168. rpath=CurrentDir()
  169. Endif
  170. While path
  171. Local i:=path.Find( "/" )
  172. If i=-1 Return rpath+path
  173. Local t:=path.Slice( 0,i )
  174. path=path.Slice( i+1 )
  175. Select t
  176. Case ""
  177. Case "."
  178. Case ".."
  179. If Not rpath rpath=CurrentDir()
  180. rpath=ExtractDir( rpath )
  181. Default
  182. rpath+=t+"/"
  183. End
  184. Wend
  185. Return rpath
  186. End
  187. #rem monkeydoc Gets the time a file was most recently modified.
  188. @param path The filesystem path.
  189. @return The time the file at `path` was most recently modified.
  190. #end
  191. Function GetFileTime:Long( path:String )
  192. path=StripSlashes( path )
  193. Local st:stat_t
  194. If stat( path,Varptr st )<0 Return 0
  195. Return libc.tolong( st.st_mtime )
  196. End
  197. #rem monkeydoc Gets the type of the file at a filesystem path.
  198. @param path The filesystem path.
  199. @return The file type of the file at `path`, one of: FileType.None, FileType.File or FileType.Directory.
  200. #end
  201. Function GetFileType:FileType( path:String )
  202. path=StripSlashes( path )
  203. Local st:stat_t
  204. If stat( path,Varptr st )<0 Return FileType.None
  205. Select st.st_mode & S_IFMT
  206. Case S_IFREG Return FileType.File
  207. Case S_IFDIR Return FileType.Directory
  208. End
  209. Return FileType.Unknown
  210. End
  211. #rem monkeydoc Gets the process current directory.
  212. @return The current directory for the running process.
  213. #end
  214. Function CurrentDir:String()
  215. Local sz:=4096
  216. Local buf:=Cast<char_t Ptr>( malloc( sz ) )
  217. getcwd( buf,sz )
  218. Local path:=String.FromCString( buf )
  219. free( buf )
  220. path=path.Replace( "\","/" )
  221. If path.EndsWith( "/" ) Return path
  222. Return path+"/"
  223. End
  224. #rem monkeydoc Changes the process current directory.
  225. @param path The filesystem path of the directory to make current.
  226. #end
  227. Function ChangeDir( path:String )
  228. path=StripSlashes( path )
  229. chdir( path )
  230. End
  231. #rem monkeydoc Loads a directory.
  232. @param path The filesystem path of the directory to load.
  233. @return An array containing all filenames in the `path`, excluding '.' and '..' entries.
  234. #end
  235. Function LoadDir:String[]( path:String )
  236. path=StripSlashes( path )
  237. Local dir:=opendir( path )
  238. If Not dir Return Null
  239. Local files:=New StringStack
  240. Repeat
  241. Local ent:=readdir( dir )
  242. If Not ent Exit
  243. Local file:=String.FromCString( ent[0].d_name )
  244. If file="." Or file=".." Continue
  245. files.Push( file )
  246. Forever
  247. closedir( dir )
  248. Return files.ToArray()
  249. End
  250. #rem monkeydoc Creates a directory at a filesystem path.
  251. @param path The filesystem path of ther directory to create.
  252. @param recursive If true, any required parent directories are also created.
  253. @return True if a directory at `path` was successfully created or already existed.
  254. #end
  255. Function CreateDir:Bool( path:String,recursive:Bool=True )
  256. path=StripSlashes( path )
  257. If recursive
  258. Local parent:=ExtractDir( path )
  259. If parent And Not IsRootDir( parent )
  260. Select GetFileType( parent )
  261. Case FileType.None
  262. If Not CreateDir( parent,True ) Return False
  263. Case FileType.File
  264. Return False
  265. Case FileType.Directory
  266. End
  267. Endif
  268. Endif
  269. mkdir( path,$1ff )
  270. Return GetFileType( path )=FileType.Directory
  271. End
  272. Private
  273. Function DeleteAll:Bool( path:String )
  274. Select GetFileType( path )
  275. Case FileType.None
  276. Return True
  277. Case FileType.File
  278. Return DeleteFile( path )
  279. Case FileType.Directory
  280. For Local f:=Eachin LoadDir( path )
  281. If Not DeleteAll( path+"/"+f ) Return False
  282. Next
  283. rmdir( path )
  284. Return GetFileType( path )=FileType.None
  285. End
  286. Return False
  287. End
  288. Public
  289. #rem monkeydoc Deletes a directory at a filesystem path.
  290. @param path The filesystem path.
  291. @param recursive True to delete subdirectories too.
  292. @return True if the directory was successfully deleted or never existed.
  293. #end
  294. Function DeleteDir:Bool( path:String,recursive:Bool=False )
  295. path=StripSlashes( path )
  296. Select GetFileType( path )
  297. Case FileType.None
  298. Return True
  299. Case FileType.File
  300. Return False
  301. Case FileType.Directory
  302. If recursive Return DeleteAll( path )
  303. rmdir( path )
  304. Return GetFileType( path )=FileType.None
  305. End
  306. Return False
  307. End
  308. #rem monkeydoc Deletes a file at a filesystem path.
  309. @param path The filesystem path.
  310. @return True if the file was successfully deleted.
  311. #end
  312. Function DeleteFile:Bool( path:String )
  313. remove( path )
  314. Return GetFileType( path )=FileType.None
  315. End