1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: file_base.h,v 1.2 2009/02/19 01:51:23 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_FILE_BASE_H
22 #define SEQAN_HEADER_FILE_BASE_H
25 //////////////////////////////////////////////////////////////////////////////
27 namespace SEQAN_NAMESPACE_MAIN
30 // To override the system's default temporary directory use the following:
31 //#define SEQAN_DEFAULT_TMPDIR "/var/tmp"
33 // To use direct I/O access define SEQAN_DIRECTIO (not completely tested yet)
34 //#define SEQAN_DIRECTIO
41 ..summary:File structure supporting synchronous input/output access.
42 ..signature:File<Sync<> >
43 ..remarks:This class suports pseudo-asynchronous access methods, i.e. the methods to initiate a I/O request return after request completion.
46 template <typename TSpec = void>
53 ..summary:File structure supporting synchronous and asynchronous input/output access.
54 ..signature:File<Async<> >
57 template <typename TSpec = void>
64 ..summary:Represents a file.
65 ..signature:File<TSpec>
66 ..param.TSpec:The specializing type.
67 ...default:$Async<>$, see @Spec.Async@.
70 template <typename TSpec = Async<> >
77 ..summary:Splits a large file into a chain of smaller files.
78 ..signature:File<Chained<FileSize, TFile> >
79 ..param.FileSize:The maximal split file size in byte.
80 ...default:2^31-1 (~2GB)
81 ..param.TFile:Underlying @Class.File@ type.
82 ...default:$File<>$, see @Class.File@.
83 ..remarks:This file type uses a chain of $TFile$ files, whose file sizes are at most $FileSize$ bytes.
84 Chained Files should be used for file systems or $TFile$ types that don't support large files (e.g. FAT32, C-style FILE*).
85 ..remarks:The chain can be used as if it were one contiguous file.
88 // chained file's default filesize is 2gb-1byte (fat16 filesize limitation)
89 template < __int64 _FileSize = ~(((__int64)1) << 63), typename TFile = File<> >
96 ..summary:Stripes a file across multiple files.
97 ..signature:File<Chained<FileCount, TFile> >
98 ..param.FileCount:The number of files used for striping.
100 ..param.TFile:Underlying @Class.File@ type.
101 ...default:$File<>$, see @Class.File@.
102 ..remarks:This file type uses a software striping without redundance (see RAID0) to accelerate I/O access when using more than one disks.
103 ..remarks:Striped files should only be used in @Class.Pool@s or external Strings as they only support block operations and no random accesses.
106 template < unsigned _FileCount = 2, typename TFile = File<> >
121 template <typename T>
122 struct DefaultOpenMode {
123 enum { VALUE = (OPEN_RDWR + OPEN_CREATE) | OPEN_APPEND };
126 template <typename T>
127 struct DefaultOpenTempMode {
128 enum { VALUE = OPEN_RDWR + OPEN_CREATE };
140 //////////////////////////////////////////////////////////////////////////////
141 // result type of asynch. functions
142 // you have to call release(aRequest<T>) after a finished *event based* transfer
143 struct aDummyRequest {};
148 ..summary:Associated with an asynchronous I/O request.
149 ..signature:aRequest<TFile>
150 ..param.TFile:A File type.
151 ..remarks:This structure is used to identify asynchronous requests after their initiation.
154 template < typename T >
157 typedef aDummyRequest Type;
160 //////////////////////////////////////////////////////////////////////////////
161 // event to represent asynchronous transfers
162 // you can wait for it or test it
163 template < typename T >
166 typedef DummyEvent Type;
169 ////////////////////////////////////////////////////////////////////////////////
170 // callback hint parameter type
171 // hint lets you recognize the finished asynch. transfer in your own callback routine
172 template < typename T >
178 //////////////////////////////////////////////////////////////////////////////
179 // callback function interface
180 template < typename T >
183 typedef void Type(aHint<T> *);
186 //////////////////////////////////////////////////////////////////////////////
187 // file queue interface
188 template < typename T >
191 typedef Nothing Type;
195 //////////////////////////////////////////////////////////////////////////////
196 // generic open/close interface
200 ..summary:Opens a file.
202 ..signature:open(file, fileName[, openMode])
203 ..param.file:A File object.
205 ..param.fileName:C-style character string containing the file name.
206 ..param.openMode:The combination of flags defining how the file should be opened.
207 ...remarks:To open a file read-only, write-only or to read and write use $OPEN_RDONLY$, $OPEN_WRONLY$, or $OPEN_RDWR$.
208 ...remarks:To create or overwrite a file add $OPEN_CREATE$.
209 ...remarks:To append a file if existing add $OPEN_APPEND$.
210 ...default:$OPEN_RDWR | OPEN_CREATE | OPEN_APPEND$
211 ..returns:A $bool$ which is $true$ on success.
214 template < typename TSpec >
215 inline bool open(File<TSpec> &me, const char *fileName, int openMode) {
216 return me.open(fileName, openMode);
219 template < typename TSpec >
220 inline bool open(File<TSpec> &me, const char *fileName) {
221 return open(me, fileName, DefaultOpenMode<File<TSpec> >::VALUE);
226 ..summary:Opens a temporary file.
228 ..signature:openTemp(file)
229 ..param.file:A File object.
231 ..remarks:After closing this file will automatically be deleted.
232 ..remarks:The openmode (see @Function.open@) is $OPEN_RDWR | OPEN_CREATE$.
233 ..returns:A $bool$ which is $true$ on success.
236 template < typename TSpec >
237 inline bool openTemp(File<TSpec> &me) {
238 return me.openTemp();
241 template < typename TSpec >
242 inline bool openTemp(File<TSpec> &me, int openMode) {
243 return me.openTemp(openMode);
246 template < typename File >
247 inline void reopen(File &, int) {
253 ..summary:Closes a file.
254 ..signature:close(file)
255 ..param.file:A File object.
257 ..returns:A $bool$ which is $true$ on success.
260 template < typename TSpec >
261 inline bool close(File<TSpec> & me) {
265 template < typename TSpec >
266 inline unsigned sectorSize(File<TSpec> const & /*me*/) {
271 //////////////////////////////////////////////////////////////////////////////
272 // generic read(At)/write(At) interface
277 ..summary:Loads records from a file.
278 ..signature:read(file, memPtr, count)
279 ..param.file:A File object.
281 ..param.memPtr:A pointer to the first destination record in memory.
282 ..param.count:The amount of records to be read.
283 ..returns:A $bool$ which is $true$ on success.
284 ..remarks:The records are read from the position pointed by the current file pointer (see @Function.seek@).
287 template < typename TSpec, typename TValue, typename TSize >
288 inline bool read(File<TSpec> & me, TValue *memPtr, TSize const count) {
289 return me.read(memPtr, count * sizeof(TValue));
295 ..summary:Saves records to a file.
296 ..signature:write(file, memPtr, count)
297 ..param.file:A File object.
299 ..param.memPtr:A pointer to the first source record in memory.
300 ..param.count:The amount of records to be written.
301 ..returns:A $bool$ which is $true$ on success.
302 ..remarks:The records are written at the position pointed by the current file pointer (see @Function.seek@).
305 template < typename TSpec, typename TValue, typename TSize >
306 inline bool write(File<TSpec> & me, TValue const *memPtr, TSize const count) {
307 return me.write(memPtr, count * sizeof(TValue));
312 ..summary:Loads records from a specific position in a file.
314 ..signature:readAt(file, memPtr, count, fileOfs)
315 ..param.file:A File object.
317 ..param.memPtr:A pointer to the first destination record in memory.
318 ..param.count:The amount of records to be read.
319 ..param.fileOfs:The absolute file position in bytes measured from the beginning.
320 ..returns:A $bool$ which is $true$ on success.
323 template < typename TFile, typename TValue, typename TSize, typename TPos >
324 inline bool readAt(TFile & me, TValue *memPtr, TSize const count, TPos const fileOfs) {
325 typedef typename Position<TFile>::Type pos_t;
326 seek(me, (pos_t)fileOfs * (pos_t)sizeof(TValue));
327 return read(me, memPtr, count);
332 ..summary:Saves records to a specific position in a file.
334 ..signature:writeAt(file, memPtr, count, fileOfs)
335 ..param.file:A File object.
337 ..param.memPtr:A pointer to the first source record in memory.
338 ..param.count:The amount of records to be written.
339 ..param.fileOfs:The absolute file position in bytes measured from the beginning.
340 ..returns:A $bool$ which is $true$ on success.
343 template < typename TFile, typename TValue, typename TSize, typename TPos >
344 inline bool writeAt(TFile & me, TValue const *memPtr, TSize const count, TPos const fileOfs) {
345 typedef typename Position<TFile>::Type pos_t;
346 seek(me, (pos_t)fileOfs * (pos_t)sizeof(TValue));
347 return write(me, memPtr, count);
352 //////////////////////////////////////////////////////////////////////////////
353 // generic seek/tell/size/resize interface
357 ..summary:Changes the current file pointer.
359 ..signature:seek(file, fileOfs[, origin])
360 ..param.file:A File object.
362 ..param.fileOfs:A file offset measured in bytes relative to $origin$.
363 ..param.origin:Selects the origin from where to calculate the new position.
364 ...default:$SEEK_BEGIN$
365 ...remarks:For $SEEK_BEGIN$, $SEEK_CURRENT$, or $SEEK_END$ the origin is the beginning, the current pointer, or the end of the file.
366 ..returns:The new file position measured in bytes from the beginning.
369 template < typename TSpec, typename TPos >
370 inline typename Position< File<TSpec> >::Type seek(File<TSpec> &me, TPos const fileOfs, int origin) {
371 typedef typename Position< File<TSpec> >::Type TFilePos;
372 TFilePos newOfs = me.seek(fileOfs, origin);
373 #ifdef SEQAN_DEBUG_OR_TEST_
374 if (origin == SEEK_BEGIN && newOfs != (TFilePos)fileOfs) {
375 ::std::cerr << "seek returned " << ::std::hex << newOfs << " instead of " << fileOfs << ::std::dec << ::std::endl;
381 template < typename TSpec, typename TPos >
382 inline typename Position< File<TSpec> >::Type seek(File<TSpec> &me, TPos const fileOfs) {
383 return seek(me, fileOfs, SEEK_BEGIN);
387 ..summary:Gets the current file pointer.
389 ..signature:tell(file)
390 ..param.file:A File object.
392 ..returns:The current file position measured in bytes from the beginning.
395 template < typename TSpec >
396 inline typename Position< File<TSpec> >::Type tell(File<TSpec> &me) {
402 ..summary:Sets the current file pointer to the beginning.
404 ..signature:rewind(file)
405 ..param.file:A File object.
407 ..remarks:Calls @Function.seek@$(file, 0)$ by default.
410 template < typename File >
411 inline void rewind(File &me) {
417 ..summary:Gets the file size.
419 ..signature:size(file)
420 ..param.file:A File object.
422 ..returns:The file size measured in bytes.
425 template < typename TSpec >
426 inline typename Size<File<TSpec> >::Type size(File<TSpec> &me) {
427 typename Size<File<TSpec> >::Type old_pos = tell(me);
428 typename Size<File<TSpec> >::Type result = seek(me, 0, SEEK_END);
429 seek(me, old_pos, SEEK_BEGIN);
436 ..signature:resize(file, new_length)
437 ..param.file:A File object.
439 ..param.new_length:The new file size measured in bytes.
442 template < typename TSpec, typename TSize >
443 inline void resize(File<TSpec> &me, TSize new_length) {
444 typename Size<File<TSpec> >::Type old_pos = tell(me);
445 seek(me, new_length, SEEK_BEGIN);
447 seek(me, old_pos, SEEK_BEGIN);
452 ..summary:Sets the file end to the current pointer.
454 ..signature:setEOF(file)
455 ..param.file:A File object.
459 template < typename TSpec >
460 inline bool setEOF(File<TSpec> &/*me*/) {
465 //////////////////////////////////////////////////////////////////////
466 // Pseudo asynchronous Methods
467 //////////////////////////////////////////////////////////////////////
469 //////////////////////////////////////////////////////////////////////
470 // callback based read/write
472 template < typename File, typename TValue, typename TSize,
473 typename aCallback, typename aHint >
474 inline typename aRequest<File>::Type
475 aread(File & me, TValue *memPtr, TSize const count,
476 aCallback* cb, aHint* hint)
478 result = read(me, memPtr, count);
483 template < typename File, typename TValue, typename TSize,
484 typename aCallback, typename aHint >
485 inline typename aRequest<File>::Type
486 awrite(File & me, TValue const *memPtr, TSize const count,
487 aCallback* cb, aHint* hint)
489 write(me, memPtr, count);
494 template < typename File, typename TValue, typename TSize, typename TPos,
495 typename aCallback, typename aHint >
496 inline typename aRequest<File>::Type
497 areadAt(File & me, TValue *memPtr, TSize const count, TPos const fileOfs,
498 aCallback* cb, aHint* hint)
500 readAt(me, memPtr, count, fileOfs);
505 template < typename File, typename TValue, typename TSize, typename TPos,
506 typename aCallback, typename aHint >
507 inline typename aRequest<File>::Type
508 awriteAt(File & me, TValue const *memPtr, TSize const count, TPos const fileOfs,
509 aCallback* cb, aHint* hint)
511 result = writeAt(me, memPtr, count, fileOfs);
517 //////////////////////////////////////////////////////////////////////
518 // event based read/write
520 template < typename File, typename TValue, typename TSize,
522 inline typename aRequest<File>::Type
523 aread(File & me, TValue *memPtr, TSize const count,
526 read(me, memPtr, count);
531 template < typename File, typename TValue, typename TSize,
533 inline typename aRequest<File>::Type
534 awrite(File & me, TValue const *memPtr, TSize const count,
537 write(me, memPtr, count);
542 template < typename File, typename TValue, typename TSize, typename TPos,
544 inline typename aRequest<File>::Type
545 areadAt(File & me, TValue *memPtr, TSize const count, TPos const fileOfs,
548 readAt(me, memPtr, count, fileOfs);
553 template < typename File, typename TValue, typename TSize, typename TPos,
555 inline typename aRequest<File>::Type
556 awriteAt(File & me, TValue const *memPtr, TSize const count, TPos const fileOfs,
559 writeAt(me, memPtr, count, fileOfs);
565 //////////////////////////////////////////////////////////////////////
566 // queue-less request based pseudo asychronous read/write
570 ..summary:Asynchronously loads records from a specific position in a file.
572 ..signature:areadAt(file, memPtr, count, fileOfs, request)
573 ..param.file:A File object.
575 ..param.memPtr:A pointer to the first destination record in memory.
576 ..param.count:The amount of records to be read.
577 ..param.fileOfs:The absolute file position in bytes measured from the beginning.
578 ..param.request:Reference to a structure that will be associated with this asynchronous request.
579 ...type:Class.aRequest
580 ..returns:A $bool$ which is $true$ on success.
583 template < typename File, typename TValue, typename TSize, typename TPos,
586 areadAt(File & me, TValue *memPtr, TSize const count, TPos const fileOfs,
589 return readAt(me, memPtr, count, fileOfs);
594 ..summary:Asynchronously saves records to a specific position in a file.
596 ..signature:awriteAt(file, memPtr, count, fileOfs, request)
597 ..param.file:A File object.
599 ..param.memPtr:A pointer to the first source record in memory.
600 ..param.count:The amount of records to be written.
601 ..param.fileOfs:The absolute file position in bytes measured from the beginning.
602 ..param.request:Reference to a structure that will be associated with this asynchronous request.
603 ...type:Class.aRequest
604 ..returns:A $bool$ which is $true$ on success.
607 template < typename File, typename TValue, typename TSize, typename TPos,
610 awriteAt(File & me, TValue const *memPtr, TSize const count, TPos const fileOfs,
613 return writeAt(me, memPtr, count, fileOfs);
617 //////////////////////////////////////////////////////////////////////
618 // pseudo queue specific functions
622 ..summary:Waits for all open requests to complete.
624 ..signature:flush(file)
625 ..param.file:A File object.
627 ..remarks:$flush$ returns after all pending requests are completed.
630 template < typename TSpec >
631 inline void flush(File<TSpec> &) {
636 ..summary:Waits for an asynchronous request to complete.
638 ..signature:waitFor(request[, timeout_millis])
639 ..param.request:Reference to an aRequest object.
640 ...type:Class.aRequest
641 ..param.timeout_millis:Timout value in milliseconds.
642 ...remarks:A value of 0 can be used to test for completion without waiting.
644 ..returns:A $bool$ which is $true$ on completion and $false$ on timeout.
645 ..remarks:$waitFor$ suspends the calling process until $request$ is completed or after $timeout_millis$ milliseconds.
648 inline bool waitFor(aDummyRequest &) {
652 template < typename TTime >
653 inline bool waitFor(aDummyRequest &, TTime) {
658 template < typename TSpec, typename aRequest >
659 inline void release(File<TSpec> &, aRequest &) {
664 ..summary:Cancels an asynchronous request.
666 ..signature:cancel(file, request)
667 ..param.file:A File object.
669 ..param.request:Reference to an aRequest object.
670 ...type:Class.aRequest
671 ..returns:A $bool$ which is $true$ on success.
674 template < typename TSpec, typename aRequest >
675 inline bool cancel(File<TSpec> &, aRequest &) {
682 template <typename T1, typename T2> inline
683 T1 enclosingBlocks(T1 _size, T2 _blockSize) {
684 return (_size + _blockSize - 1) / _blockSize;
687 template <typename T1, typename T2> inline
688 T1 alignSize(T1 _size, T2 _aligning) {
689 if (_size < _aligning)
692 return (_size / _aligning) * (T1)_aligning;