jfile.hpp 27 KB

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