jfile.hpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JFILE_HPP
  14. #define JFILE_HPP
  15. #include "jiface.hpp"
  16. #include "jio.hpp"
  17. #include "jtime.hpp"
  18. #include "jsocket.hpp"
  19. interface IFile;
  20. interface IFileIO;
  21. interface IFileAsyncIO;
  22. interface IFileAsyncResult;
  23. interface IFileIOStream;
  24. interface IMemoryMappedFile;
  25. class MemoryBuffer;
  26. class Semaphore;
  27. enum IFOmode { IFOcreate, IFOread, IFOwrite, IFOreadwrite, IFOcreaterw }; // modes for open
  28. enum IFSHmode { IFSHnone, IFSHread=0x8, IFSHfull=0x10}; // sharing modes
  29. enum IFSmode { IFScurrent = FILE_CURRENT, IFSend = FILE_END, IFSbegin = FILE_BEGIN }; // seek mode
  30. enum CFPmode { CFPcontinue, CFPcancel, CFPstop }; // modes for ICopyFileProgress::onProgress return
  31. enum IFEflags { IFEnone=0x0, IFEnocache=0x1, IFEcache=0x2 }; // mask
  32. class CDateTime;
  33. interface IDirectoryIterator : extends IIteratorOf<IFile>
  34. {
  35. virtual StringBuffer &getName(StringBuffer &buf)=0;
  36. virtual bool isDir()=0;
  37. virtual __int64 getFileSize()=0;
  38. virtual bool getModifiedTime(CDateTime &ret)=0;
  39. };
  40. #define PGCFLUSH_BLKSIZE 0x400000
  41. #define DEFAULT_COPY_BLKSIZE 0x100000
  42. enum CFflags { CFnone=0x0, CFflush_read=0x1, CFflush_write=0x2, CFflush_rdwr=0x3 };
  43. #define IDDIunchanged 1
  44. #define IDDImodified 2
  45. #define IDDIadded 4
  46. #define IDDIdeleted 8
  47. #define IDDIstandard (IDDIunchanged|IDDImodified|IDDIadded)
  48. #define IDDIchanged (IDDImodified|IDDIadded|IDDIdeleted)
  49. interface IDirectoryDifferenceIterator : extends IDirectoryIterator
  50. {
  51. virtual void setMask(unsigned mask)=0; // called before first (combination of IDDI*)
  52. virtual unsigned getFlags()=0; // called on each iteration returns IDDI*
  53. };
  54. interface ICopyFileProgress
  55. {
  56. virtual CFPmode onProgress(offset_t sizeDone, offset_t totalSize) = 0;
  57. };
  58. class RemoteFilename;
  59. enum fileBool { foundNo = false, foundYes = true, notFound = 2 };
  60. interface IFile :extends IInterface
  61. {
  62. virtual bool exists() = 0; // NB this can raise exceptions if the machine doesn't exist or other fault
  63. virtual bool getTime(CDateTime * createTime, CDateTime * modifiedTime, CDateTime * accessedTime) = 0;
  64. virtual bool setTime(const CDateTime * createTime, const CDateTime * modifiedTime, const CDateTime * accessedTime) = 0;
  65. virtual fileBool isDirectory() = 0;
  66. virtual fileBool isFile() = 0;
  67. virtual fileBool isReadOnly() = 0;
  68. virtual IFileIO * open(IFOmode mode,IFEflags extraFlags=IFEnone) = 0;
  69. virtual IFileAsyncIO * openAsync(IFOmode mode) = 0;
  70. virtual IFileIO * openShared(IFOmode mode,IFSHmode shmode,IFEflags extraFlags=IFEnone) = 0;
  71. virtual const char * queryFilename() = 0;
  72. virtual bool remove() = 0;
  73. virtual void rename(const char *newTail) = 0; // tail only preferred but can have full path if exactly matches existing dir
  74. virtual void move(const char *newName) = 0; // can move between directories on same node (NB currently not always supported on remote files!)
  75. virtual void setReadOnly(bool ro) = 0;
  76. virtual void setFilePermissions(unsigned fPerms) = 0;
  77. virtual offset_t size() = 0;
  78. virtual bool setCompression(bool set) = 0;
  79. virtual offset_t compressedSize() = 0;
  80. virtual unsigned getCRC() = 0;
  81. virtual void setCreateFlags(unsigned cflags) =0; // I_S*
  82. virtual void setShareMode(IFSHmode shmode) =0;
  83. // Directory functions
  84. virtual bool createDirectory() = 0;
  85. virtual IDirectoryIterator *directoryFiles(const char *mask=NULL,bool sub=false,bool includedirs=false)=0;
  86. virtual IDirectoryDifferenceIterator *monitorDirectory(
  87. IDirectoryIterator *prev=NULL, // in (NULL means use current as baseline)
  88. const char *mask=NULL,
  89. bool sub=false,
  90. bool includedirs=false,
  91. unsigned checkinterval=60*1000,
  92. unsigned timeout=(unsigned)-1,
  93. Semaphore *abortsem=NULL)=0; // returns NULL if timed out or abortsem signalled
  94. virtual bool getInfo(bool &isdir,offset_t &size,CDateTime &modtime) = 0; // return false if doesn't exist
  95. // size is undefined if directory
  96. virtual void copySection(const RemoteFilename &dest, offset_t toOfs=(offset_t)-1, offset_t fromOfs=0, offset_t size=(offset_t)-1, ICopyFileProgress *progress=NULL, CFflags copyFlags=CFnone) = 0;
  97. // if toOfs is (offset_t)-1 then copies entire file
  98. virtual void copyTo(IFile *dest, size32_t buffersize=DEFAULT_COPY_BLKSIZE, ICopyFileProgress *progress=NULL, bool usetmp=false, CFflags copyFlags=CFnone)=0;
  99. virtual IMemoryMappedFile *openMemoryMapped(offset_t ofs=0, memsize_t len=(memsize_t)-1, bool write=false)=0;
  100. virtual void treeCopyTo(IFile *dest,IpSubNet &subnet,IpAddress &resfrom,bool usetmp=false,CFflags copyFlags=CFnone) = 0;
  101. };
  102. struct CDirectoryEntry: public CInterface
  103. { // for cloning IDirectoryIterator iterator
  104. public:
  105. IMPLEMENT_IINTERFACE;
  106. CDirectoryEntry() {}
  107. CDirectoryEntry(IDirectoryIterator &iter)
  108. : file(&iter.query()), isdir(iter.isDir()), size(iter.getFileSize())
  109. {
  110. StringBuffer tmp;
  111. name.set(iter.getName(tmp));
  112. iter.getModifiedTime(modifiedTime);
  113. }
  114. Linked<IFile> file;
  115. StringAttr name;
  116. bool isdir;
  117. __int64 size;
  118. CDateTime modifiedTime;
  119. };
  120. typedef enum { SD_nosort, SD_byname, SD_bynameNC, SD_bydate, SD_bysize } SortDirectoryMode;
  121. extern jlib_decl unsigned sortDirectory(
  122. CIArrayOf<CDirectoryEntry> &sortedfiles, // returns sorted directory
  123. IDirectoryIterator &iter,
  124. SortDirectoryMode mode,
  125. bool rev=false, // reverse sort
  126. bool includedirs=false
  127. );
  128. //This is closed by releasing the interface
  129. interface IFileIO : public IInterface
  130. {
  131. virtual size32_t read(offset_t pos, size32_t len, void * data) = 0;
  132. virtual offset_t size() = 0;
  133. virtual size32_t write(offset_t pos, size32_t len, const void * data) = 0;
  134. virtual offset_t appendFile(IFile *file,offset_t pos=0,offset_t len=(offset_t)-1) =0;
  135. virtual void setSize(offset_t size) = 0;
  136. virtual void flush() = 0;
  137. virtual void close() = 0; // no other access is allowed after this call
  138. };
  139. interface IFileIOCache : extends IInterface
  140. {
  141. virtual IFileIO *addFile( RemoteFilename &filename, IFOmode mode ) = 0;
  142. };
  143. interface IMemoryMappedFile: extends IInterface
  144. {
  145. virtual byte *base()=0; // address of currently mapped section
  146. virtual offset_t offset()=0; // offset in file of currently mapped section
  147. virtual memsize_t length()=0; // size of currently mapped section
  148. virtual offset_t fileSize()=0; // size of total file
  149. virtual int compareWithin(const void *p)=0; // return 0 if pointer within mapped section -1 if lt +1 if gt
  150. virtual bool writeAccess()=0; // true if write enabled map
  151. virtual void flush()=0; // flushed written buffers
  152. virtual byte *nextPtr(const void *ptr,offset_t skip, memsize_t extent, memsize_t &got)=0; // used to move about in partially mapped file
  153. virtual void reinit(offset_t ofs, memsize_t len=(memsize_t)-1, bool write=false)=0; // move map
  154. };
  155. interface IFileAsyncResult: extends IInterface
  156. {
  157. virtual bool getResult(size32_t &result,bool wait) =0 ; // returns false if wait false and not finished
  158. };
  159. interface IFileAsyncIO : extends IFileIO
  160. {
  161. virtual IFileAsyncResult *readAsync(offset_t pos, size32_t len, void * data) = 0; // data must be available until getResult returns true
  162. virtual IFileAsyncResult *writeAsync(offset_t pos, size32_t len, const void * data) = 0; // data must be available until getResult returns true
  163. };
  164. interface IFileIOStream : extends IIOStream
  165. {
  166. virtual void seek(offset_t pos, IFSmode origin) = 0;
  167. virtual offset_t size() = 0;
  168. virtual offset_t tell() = 0;
  169. };
  170. interface IDiscretionaryLock: extends IInterface
  171. {
  172. virtual bool lock(bool exclusive=true, unsigned timeout=INFINITE) = 0; // overrides previous setting
  173. virtual void unlock() = 0;
  174. virtual bool isLocked() = 0;
  175. virtual bool isExclusiveLocked() = 0;
  176. };
  177. //-- Interfaces/functions used for managing passwords needed to access remote machines.
  178. class IpAddress;
  179. interface IPasswordProvider : public IInterface
  180. {
  181. virtual bool getPassword(const IpAddress & ip, StringBuffer & username, StringBuffer & password) = 0;
  182. };
  183. #ifndef _WIN32
  184. #define _MAX_DRIVE 4
  185. #define _MAX_DIR 256
  186. #define _MAX_FNAME 256
  187. #define _MAX_EXT 256
  188. void jlib_decl _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext);
  189. #endif
  190. extern jlib_decl void setDefaultUser(const char * username,const char *password);
  191. extern jlib_decl IPasswordProvider * queryPasswordProvider();
  192. extern jlib_decl void setPasswordProvider(IPasswordProvider * provider);
  193. //-- Helper routines
  194. extern jlib_decl size32_t read(IFileIO * in, offset_t pos, size32_t len, MemoryBuffer & buffer);
  195. extern jlib_decl void copyFile(const char *target, const char *source, size32_t buffersize=DEFAULT_COPY_BLKSIZE, ICopyFileProgress *progress=NULL,CFflags copyFlags=CFnone);
  196. extern jlib_decl void copyFile(IFile * target, IFile * source,size32_t buffersize=DEFAULT_COPY_BLKSIZE, ICopyFileProgress *progress=NULL,CFflags copyFlags=CFnone);
  197. extern jlib_decl bool recursiveCreateDirectory(const char * path);
  198. extern jlib_decl bool recursiveCreateDirectoryForFile(const char *filename);
  199. extern jlib_decl void splitFilename(const char * filename, StringBuffer * drive, StringBuffer * path, StringBuffer * tail, StringBuffer * ext, bool longExt = false);
  200. extern jlib_decl bool splitUNCFilename(const char * filename, StringBuffer * machine, StringBuffer * path, StringBuffer * tail, StringBuffer * ext);
  201. extern jlib_decl StringBuffer& createUNCFilename(const char * localfilename, StringBuffer &UNC, bool useHostNames=true);
  202. extern jlib_decl bool ensureFileExtension(StringBuffer& filename, const char* desiredExtension);
  203. extern jlib_decl StringBuffer& getFullFileName(StringBuffer& filename, bool noExtension = false);
  204. extern jlib_decl StringBuffer& getFileNameOnly(StringBuffer& filename, bool noExtension = true);
  205. extern jlib_decl offset_t filesize(const char *fname);
  206. extern jlib_decl offset_t getFreeSpace(const char* name);
  207. extern jlib_decl void createHardLink(const char* fileName, const char* existingFileName);
  208. //-- Creation routines for implementations of the interfaces above
  209. extern jlib_decl IFile * createIFile(const char * filename);
  210. extern jlib_decl IFile * createIFile(MemoryBuffer & buffer);
  211. extern jlib_decl IFileIO * createIFileIO(HANDLE handle,IFOmode=IFOreadwrite,IFEflags extraFlags=IFEnone);
  212. extern jlib_decl IDirectoryIterator * createDirectoryIterator(const char * path = NULL, const char * wildcard = NULL);
  213. extern jlib_decl IDirectoryIterator * createNullDirectoryIterator();
  214. extern jlib_decl IFileIO * createIORange(IFileIO * file, offset_t header, offset_t length); // restricts input/output to a section of a file.
  215. extern jlib_decl IFileIOStream * createIOStream(IFileIO * file); // links argument
  216. extern jlib_decl IFileIOStream * createBufferedIOStream(IFileIO * file, unsigned bufsize=(unsigned)-1);// links argument
  217. extern jlib_decl IFileIOStream * createBufferedAsyncIOStream(IFileAsyncIO * file, unsigned bufsize=(unsigned)-1);// links argument
  218. // Useful for commoning up file and string based processing
  219. extern jlib_decl IFileIO * createIFileI(unsigned len, const void * buffer); // input only...
  220. extern jlib_decl IFileIO * createIFileIO(unsigned len, void * buffer);
  221. extern jlib_decl IFileIO * createIFileIO(StringBuffer & buffer);
  222. extern jlib_decl IFileIO * createIFileIO(MemoryBuffer & buffer);
  223. //-- Creation of routines to implement other interfaces on the interfaces above.
  224. interface IReadSeq;
  225. interface IWriteSeq;
  226. // NB the following are unbuffered
  227. extern jlib_decl IReadSeq *createReadSeq(IFileIOStream * stream, offset_t _offset, size32_t size); // no buffering
  228. extern jlib_decl IWriteSeq *createWriteSeq(IFileIOStream * stream, size32_t size); // no buffering
  229. extern jlib_decl IDiscretionaryLock *createDiscretionaryLock(IFile *file);
  230. extern jlib_decl IDiscretionaryLock *createDiscretionaryLock(IFileIO *fileio);
  231. // useful stream based reader
  232. interface ISerialStream: extends IInterface
  233. {
  234. virtual const void * peek(size32_t wanted,size32_t &got) = 0; // try and ensure wanted bytes are available.
  235. // if got<wanted then approaching eof
  236. // if got>wanted then got is size available in buffer
  237. virtual void get(size32_t len, void * ptr) = 0; // exception if no data available
  238. virtual bool eos() = 0; // no more data
  239. virtual void skip(size32_t sz) = 0;
  240. virtual offset_t tell() = 0;
  241. virtual void reset(offset_t _offset,offset_t _flen=(offset_t)-1) = 0; // input stream has changed - restart reading
  242. };
  243. /* example of reading a nul terminated string using ISerialStream peek and skip
  244. {
  245. loop {
  246. const char *s = peek(1,got);
  247. if (!s)
  248. break; // eof before nul detected;
  249. const char *p = s;
  250. const char *e = p+got;
  251. while (p!=e) {
  252. if (!*p) {
  253. out.append(p-s,s);
  254. skip(p-s+1); // include nul
  255. return;
  256. }
  257. p++;
  258. }
  259. out.append(got,s);
  260. skip(got);
  261. }
  262. }
  263. */
  264. interface IFileSerialStreamCallback // used for CRC tallying
  265. {
  266. virtual void process(offset_t ofs, size32_t sz, const void *buf) = 0;
  267. };
  268. extern jlib_decl ISerialStream *createSimpleSerialStream(ISimpleReadStream * in, size32_t bufsize = (size32_t)-1, IFileSerialStreamCallback *callback=NULL);
  269. extern jlib_decl ISerialStream *createSocketSerialStream(ISocket * in, unsigned timeoutms, size32_t bufsize = (size32_t)-1, IFileSerialStreamCallback *callback=NULL);
  270. extern jlib_decl ISerialStream *createFileSerialStream(IFileIOStream * in, size32_t bufsize = (size32_t)-1, IFileSerialStreamCallback *callback=NULL);
  271. extern jlib_decl ISerialStream *createFileSerialStream(IFileIO *fileio, offset_t ofs=0, offset_t flen=(offset_t)-1,size32_t bufsize = (size32_t)-1, IFileSerialStreamCallback *callback=NULL);
  272. extern jlib_decl ISerialStream *createFileSerialStream(IMemoryMappedFile *mmapfile, offset_t ofs=0, offset_t flen=(offset_t)-1, IFileSerialStreamCallback *callback=NULL);
  273. extern jlib_decl ISerialStream *createMemorySerialStream(const void *buffer, memsize_t len, IFileSerialStreamCallback *callback=NULL);
  274. extern jlib_decl ISerialStream *createMemoryBufferSerialStream(MemoryBuffer & buffer, IFileSerialStreamCallback *callback=NULL);
  275. typedef Linked<IFile> IFileAttr;
  276. typedef Linked<IFileIO> IFileIOAttr;
  277. typedef Linked<IFileIOStream> IFileIOStreamAttr;
  278. typedef Owned<IFile> OwnedIFile;
  279. typedef Owned<IFileIO> OwnedIFileIO;
  280. typedef Owned<IFileIOStream> OwnedIFileIOStream;
  281. //-- RemoteFilename class (file location encapsulation)
  282. class jlib_decl RemoteFilename
  283. {
  284. void badFilename(const char * filename);
  285. SocketEndpoint ep; // node for file (port is used for daliservix and user defined ports)
  286. StringAttr localhead; // local base directory
  287. StringAttr sharehead; // remote share equvalent to localbase (always starts with separator if present)
  288. StringAttr tailpath; // tail directory and filename appended to one of the above (always starts with separator)
  289. public:
  290. void clear();
  291. StringBuffer & getTail(StringBuffer &name) const; // Tail Name (e.g. "test.d00._1_of_3")
  292. StringBuffer & getPath(StringBuffer & name) const; // Either local or full depending on location
  293. StringBuffer & getLocalPath(StringBuffer &name) const; // Local Path (e.g. "c:\dfsdata\test.d00._1_of_3")
  294. StringBuffer & getRemotePath(StringBuffer &name) const; // Full Remote Path (e.g. "\\192.168.0.123\c$\dfsdata\test.d00._1_of_3")
  295. bool isLocal() const; // on calling node
  296. bool isUnixPath() const; // a unix filename
  297. char getPathSeparator() const; // separator for this path
  298. const SocketEndpoint & queryEndpoint() const { return ep; } // node containing file
  299. const IpAddress & queryIP() const { return ep; }
  300. unsigned short getPort() const { return ep.port; }
  301. bool isNull() const;
  302. // the following overwrite previous contents
  303. void set(const RemoteFilename & other);
  304. void setPath(const SocketEndpoint & _ep, const char * filename); // filename should be full windows or unix path (local)
  305. void setLocalPath(const char *name); // local path - can partial but on linux must be under \c$ or \d$
  306. void setRemotePath(const char * url,const char *local=NULL); // url should be full (share) path including ep
  307. // the following modify existing
  308. void setIp(const IpAddress & ip) { ep.ipset(ip); }
  309. void setEp(const SocketEndpoint & _ep) { ep.set(_ep); }
  310. void setPort(unsigned short port) { ep.port=port; }
  311. void setShareHead(const char *name) { sharehead.set(name); }
  312. void setLocalHead(const char *name) { localhead.set(name); }
  313. void setTailPath(const char *name) { tailpath.set(name); }
  314. void setExtension(const char * newext);
  315. void split(StringBuffer * drive, StringBuffer * path, StringBuffer * tail, StringBuffer * ext) const;
  316. // same buffer can be passed to several
  317. // note that this is for a *local* file
  318. void deserialize(MemoryBuffer & in);
  319. void serialize(MemoryBuffer & out);
  320. bool equals(const RemoteFilename & other) const;
  321. };
  322. class RemoteFilenameArray : public StructArrayOf<RemoteFilename> { };
  323. class jlib_decl RemoteMultiFilename: public RemoteFilenameArray
  324. { // NB all entries must be on on the same node
  325. SocketEndpoint ep;
  326. Int64Array sizescache;
  327. public:
  328. static void expand(const char *mpath, StringArray &array);
  329. static void tostr(StringArray &array,StringBuffer &out);
  330. void append(const char *path,const char *defaultdir=NULL);
  331. // can be local or remote URL path (though urls must point at same machine)
  332. // can contain comma separated entries including wildcards
  333. // if no directory then uses defaultdir if present
  334. void append(const RemoteFilename &filename);
  335. void deserialize(MemoryBuffer & in);
  336. void serialize(MemoryBuffer & out);
  337. bool isWild(unsigned idx=(unsigned)-1) const; // true if component wild (if -1 then if *any* component wild)
  338. void expandWild();
  339. const SocketEndpoint & queryEndpoint() const { return ep; } // node containing file
  340. const IpAddress & queryIP() const { return ep; }
  341. unsigned short getPort() const { return ep.port; }
  342. void setIp(const IpAddress & ip);
  343. void setEp(const SocketEndpoint & _ep);
  344. void setPort(unsigned short port);
  345. void clear() { ep.set(NULL,0); RemoteFilenameArray::kill(); sizescache.kill(); }
  346. void set(const RemoteMultiFilename & other);
  347. bool equals(const RemoteMultiFilename & other);
  348. offset_t getSize(unsigned i); // returns file size (optimizes if loaded via wild card)
  349. };
  350. interface IReplicatedFile: extends IInterface
  351. {
  352. virtual RemoteFilenameArray &queryCopies()=0;
  353. virtual IFile *open()=0;
  354. };
  355. extern jlib_decl IReplicatedFile *createReplicatedFile();
  356. interface IRemoteFileCreateHook: extends IInterface
  357. {
  358. virtual IFile * createIFile(const RemoteFilename & filename)=0;
  359. };
  360. extern jlib_decl void addIFileCreateHook(IRemoteFileCreateHook *);
  361. extern jlib_decl void removeIFileCreateHook(IRemoteFileCreateHook *);
  362. extern jlib_decl IFile * createIFile(const RemoteFilename & filename);
  363. // Hook mechanism for accessing files inside containers (eg zipfiles)
  364. interface IContainedFileHook: extends IInterface
  365. {
  366. virtual IFile * createIFile(const char *fileName) = 0;
  367. };
  368. extern jlib_decl void addContainedFileHook(IContainedFileHook *);
  369. extern jlib_decl void removeContainedFileHook(IContainedFileHook *);
  370. // Useful set of path inlines that work with '/' and '\'
  371. inline bool isPathSepChar(char sep)
  372. {
  373. return (sep=='\\')||(sep=='/');
  374. }
  375. inline const char *findPathSepChar(const char *s)
  376. {
  377. if (s) while (*s) {
  378. if (isPathSepChar(*s))
  379. return s;
  380. s++;
  381. }
  382. return NULL;
  383. }
  384. inline char getPathSepChar(const char *dir)
  385. {
  386. const char *s=findPathSepChar(dir);
  387. return s?(*s):((*dir&&(dir[1]==':'))?'\\':PATHSEPCHAR);
  388. }
  389. inline bool containsPathSepChar(const char *s)
  390. {
  391. return findPathSepChar(s)!=NULL;
  392. }
  393. inline StringBuffer &addPathSepChar(StringBuffer &path,char sepchar=0)
  394. {
  395. if (!path.length() || !isPathSepChar(path.charAt(path.length()-1)))
  396. path.append(sepchar?sepchar:getPathSepChar(path.str()));
  397. return path;
  398. }
  399. inline StringBuffer &removeTrailingPathSepChar(StringBuffer &path)
  400. {
  401. if (path.length()>1 && isPathSepChar(path.charAt(path.length()-1)))
  402. {
  403. #ifdef _WIN32
  404. // In addition to not removing / if it's the only char in the path, you should not remove it the path
  405. // is of the form "c:\"
  406. if (path.length()>3 || path.charAt(1) != ':')
  407. #endif
  408. path.remove(path.length()-1, 1);
  409. }
  410. return path;
  411. }
  412. inline StringBuffer &addNonEmptyPathSepChar(StringBuffer &path,char sepchar=0)
  413. {
  414. size32_t len = path.length();
  415. if (len && !isPathSepChar(path.charAt(len-1)))
  416. path.append(sepchar?sepchar:getPathSepChar(path.str()));
  417. return path;
  418. }
  419. inline StringBuffer & addDirectoryPrefix(StringBuffer & target, const char * source, char sepchar=0)
  420. {
  421. if (source && *source)
  422. addPathSepChar(target.append(source), sepchar);
  423. return target;
  424. }
  425. extern jlib_decl const char *pathTail(const char *path);
  426. extern jlib_decl const char *pathExtension(const char * path);
  427. inline const char *splitDirTail(const char *path,StringBuffer &dir)
  428. {
  429. const char *tail=pathTail(path);
  430. if (tail)
  431. dir.append((size32_t)(tail-path),path);
  432. return tail;
  433. }
  434. inline bool isAbsolutePath(const char *path)
  435. {
  436. if (!path||!*path)
  437. return false;
  438. return isPathSepChar(path[0])||((path[1]==':')&&(isPathSepChar(path[2])));
  439. }
  440. extern jlib_decl StringBuffer &makeAbsolutePath(const char *relpath,StringBuffer &out,bool mustExist=false);
  441. extern jlib_decl StringBuffer &makeAbsolutePath(StringBuffer &relpath,bool mustExist=false);
  442. extern jlib_decl StringBuffer &makeAbsolutePath(const char *relpath, const char *basedir, StringBuffer &out);
  443. extern jlib_decl StringBuffer &makePathUniversal(const char *path, StringBuffer &out);
  444. extern jlib_decl const char *splitRelativePath(const char *full,const char *basedir,StringBuffer &reldir); // removes basedir if matches, returns tail and relative dir
  445. extern jlib_decl const char *splitDirMultiTail(const char *multipath,StringBuffer &dir,StringBuffer &tail);
  446. extern jlib_decl StringBuffer &mergeDirMultiTail(const char *dir,const char *tail, StringBuffer &multipath);
  447. extern jlib_decl StringBuffer &removeRelativeMultiPath(const char *full,const char *dir,StringBuffer &reltail); // removes dir if matches, returns relative multipath
  448. extern jlib_decl bool isSpecialPath(const char *path);
  449. inline const char * skipSpecialPath(const char *path)
  450. {
  451. if (path&&(*path=='/')&&(path[1]=='>'))
  452. return path+2;
  453. return path;
  454. }
  455. extern jlib_decl int stdIoHandle(const char *path);
  456. extern jlib_decl bool checkFileExists(const char * filename); // note only local files
  457. extern jlib_decl bool checkDirExists(const char * filename); // note only local files
  458. extern jlib_decl bool isShareChar(char c);
  459. extern jlib_decl char getShareChar();
  460. extern jlib_decl void setShareChar(char c);
  461. extern jlib_decl StringBuffer &setPathDrive(StringBuffer &filename,unsigned drvnum); // 0=c, 1=d etc filename can be url or local
  462. extern jlib_decl unsigned getPathDrive(const char *filename); // 0=c, 1=d etc filename can be url or local
  463. extern jlib_decl StringBuffer &swapPathDrive(StringBuffer &filename,unsigned fromdrvnum,unsigned todrvnum,const char *frommask=NULL,const char *tomask=NULL);
  464. class jlib_decl ExtractedBlobInfo : public CInterface
  465. {
  466. public:
  467. ExtractedBlobInfo(const char * _filename, offset_t _length, offset_t _offset);
  468. ExtractedBlobInfo() {}
  469. void serialize(MemoryBuffer & buffer);
  470. void deserialize(MemoryBuffer & buffer);
  471. public:
  472. StringAttr filename;
  473. offset_t length;
  474. offset_t offset;
  475. };
  476. typedef CIArrayOf<ExtractedBlobInfo> ExtractedBlobArray;
  477. extern jlib_decl void extractBlobElements(const char * prefix, const RemoteFilename &filename, ExtractedBlobArray & extracted);
  478. extern jlib_decl bool mountDrive(const char *drv,const RemoteFilename &rfn); // linux only currently
  479. extern jlib_decl bool unmountDrive(const char *drv); // linux only currently
  480. extern jlib_decl IFileIO *createUniqueFile(const char *dir, const char *prefix, const char *ext, StringBuffer &tmpName);
  481. // used by remote copy
  482. interface ICopyFileIntercept
  483. {
  484. virtual offset_t copy(IFileIO *from, IFileIO *to, offset_t ofs, size32_t sz)=0;
  485. };
  486. extern jlib_decl void doCopyFile(IFile * target, IFile * source, size32_t buffersize, ICopyFileProgress *progress, ICopyFileIntercept *copyintercept, bool usetmp, CFflags copyFlags=CFnone);
  487. extern jlib_decl void makeTempCopyName(StringBuffer &tmpname,const char *destname);
  488. extern jlib_decl size32_t SendFile(ISocket *target, IFileIO *fileio,offset_t start,size32_t len);
  489. extern jlib_decl void asyncClose(IFileIO *io);
  490. extern jlib_decl bool containsFileWildcard(const char * path);
  491. extern jlib_decl bool isDirectory(const char * path);
  492. extern jlib_decl IFileIOCache* createFileIOCache(unsigned max);
  493. extern jlib_decl IFile * createSentinelTarget();
  494. extern jlib_decl void writeSentinelFile(IFile * file);
  495. extern jlib_decl void removeSentinelFile(IFile * file);
  496. extern jlib_decl StringBuffer & appendCurrentDirectory(StringBuffer & target, bool blankIfFails);
  497. #endif