jfile.hpp 26 KB

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