Commit patch to not break on spaces.
[bowtie.git] / SeqAn-1.1 / seqan / file / file_format.h
1  /*==========================================================================
2                 SeqAn - The Library for Sequence Analysis
3                           http://www.seqan.de 
4  ============================================================================
5   Copyright (C) 2007
6
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.
11
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.
16
17  ============================================================================
18   $Id: file_format.h,v 1.1 2008/08/25 16:20:03 langmead Exp $
19  ==========================================================================*/
20
21 #ifndef SEQAN_HEADER_FILE_FORMAT_H
22 #define SEQAN_HEADER_FILE_FORMAT_H
23
24 namespace SEQAN_NAMESPACE_MAIN
25 {
26
27 //////////////////////////////////////////////////////////////////////////////
28
29 /**
30 .Tag.File Format:
31 ..summary:A file format.
32 */
33
34
35 //////////////////////////////////////////////////////////////////////////////
36 // Metafunctions
37 //////////////////////////////////////////////////////////////////////////////
38
39 //////////////////////////////////////////////////////////////////////////////
40
41 //////////////////////////////////////////////////////////////////////////////
42 //Base Class for all FileFormat classes
43 //////////////////////////////////////////////////////////////////////////////
44
45 /**
46 .Class.FileFormat:
47 ..cat:Input/Output
48 ..summary:Object that stores a file format.
49 ..signature:FileFormat<File, Data [, Format [, Meta] ]>
50 ..see:Tag.File Format
51 */
52
53 template <
54         typename TFile, 
55         typename TData,
56         typename TMeta,
57         typename TFormat = void >
58 struct FileFormat:
59         public FileFormat<TFile, TData, TMeta, void>
60 {
61 public:
62         typedef typename Size<TData>::Type TSize;
63
64         FileFormat() {}
65         FileFormat(FileFormat const &) {}
66         ~FileFormat() {}
67         FileFormat const & operator =(FileFormat const &) {}
68
69         inline void * 
70         formatID_() const
71         {
72 SEQAN_CHECKPOINT
73                 return _ClassIdentifier<TFormat>::getID();
74         }
75
76         virtual void
77         read_(TFile & file, TData & data) const
78         {
79 SEQAN_CHECKPOINT
80                 read(file, data, TFormat());
81         }
82         virtual void
83         read_(TFile & file, TData & data, TSize limit) const
84         {
85 SEQAN_CHECKPOINT
86                 read(file, data, limit, TFormat());
87         }
88
89         virtual void
90         readMeta_(TFile & file, TMeta & meta) const
91         {
92 SEQAN_CHECKPOINT
93                 readMeta(file, meta, TFormat());
94         }
95
96         virtual void
97         goNext_(TFile & file) const
98         {
99 SEQAN_CHECKPOINT
100                 goNext(file, TFormat());
101         }
102
103         virtual TSize
104         length_(TFile & file) const
105         {
106 SEQAN_CHECKPOINT
107                 length(file, TFormat());
108         }
109
110         virtual void
111         write_(TFile & file, TData & data) const
112         {
113 SEQAN_CHECKPOINT
114                 write(file, data, TFormat());
115         }
116         virtual void
117         write_(TFile & file, TData & data, TMeta & meta) const
118         {
119 SEQAN_CHECKPOINT
120                 write(file, data, meta, TFormat());
121         }
122 };
123
124 //____________________________________________________________________________
125
126 //base class for all file format classes 
127
128 template <typename TFile, typename TData, typename TMeta>
129 struct FileFormat<TFile, TData, TMeta, void>
130 {
131 public:
132         typedef typename Size<TData>::Type TSize;
133
134         FileFormat() {}
135         FileFormat(FileFormat const &) {}
136         ~FileFormat() {};
137         FileFormat const & operator =(FileFormat const &) {}
138
139         virtual void *
140         formatID_() const = 0;
141
142         virtual void
143         read_(TFile & file, TData & data) const = 0;
144         virtual void
145         read_(TFile & file, TData & data, TSize limit) const = 0;
146
147         virtual void
148         readMeta_(TFile & file, TMeta & meta) const = 0;
149
150         virtual void
151         goNext_(TFile & file) const = 0;
152
153         virtual TSize
154         length_(TFile & file) const = 0;
155
156         virtual void
157         write_(TFile & file, TData & data) const = 0;
158         virtual void
159         write_(TFile & file, TData & data, TMeta & meta) const = 0;
160
161 };
162
163 //////////////////////////////////////////////////////////////////////////////
164 // Wrapper for functions to virtuals
165 //////////////////////////////////////////////////////////////////////////////
166
167
168 template <typename TFile, typename TData, typename TMeta, typename TFormat>
169 inline void *
170 formatID(FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
171 {
172 SEQAN_CHECKPOINT
173         return file_format.formatID_();
174 }
175
176 //////////////////////////////////////////////////////////////////////////////
177
178 /**
179 .Function.Fileformat#read:
180 ..cat:Input/Output
181 ..summary:Loads a record from file.
182 ..signature:read(file, data [, meta], format)
183 ..signature:read(file, data [, meta], tag)
184 ..param.file:An input file.
185 ..param.data:A container that gets the data read from $file$.
186 ..param.meta:A container that gets meta data from $file$. (optional)
187 ..param.format:A file format object.
188 ...type:Class.FileFormat.File Format object
189 ..param.tag:A file format tag.
190 ...type:Tag.File Format.File Format tag
191 ..remarks:The result of this operation is stored in $data$.
192 ..remarks:The function leaves $file$ at the position for reading the next record.
193 ..see:Function.assign
194 */
195 template <typename TFile, typename TData, typename TMeta, typename TFormat>
196 inline void
197 read(TFile & file,
198          TData & data,
199          FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
200 {
201 SEQAN_CHECKPOINT
202         file_format.read_(file, data);
203 }
204
205 template <typename TFile, typename TData, typename TMeta, typename TFormat, typename TSize>
206 inline void
207 read(TFile & file,
208          TData & data,
209          TSize limit,
210          FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
211 {
212 SEQAN_CHECKPOINT
213         file_format.read_(file, data, limit);
214 }
215
216 //////////////////////////////////////////////////////////////////////////////
217
218 /**
219 .Function.readMeta:
220 ..cat:Input/Output
221 ..summary:Read meta information from file.
222 ..signature:readMeta(file, meta, file_format)
223 ..param.file:A file that contains data in the format specified by $file_format$.
224 ..param.meta:A data structure that is able to store meta informations stored in $file$.
225 ..param.file_format:A file format.
226 ..returns.param.meta:The meta data read from $file$.
227 ...type:Tag.File Format
228 */
229
230 template <typename TFile, typename TData, typename TMeta, typename TFormat>
231 inline void
232 readMeta(TFile & file,
233                  TMeta & meta,
234                  FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
235 {
236 SEQAN_CHECKPOINT
237         file_format.readMeta_(file, meta);
238 }
239
240 //////////////////////////////////////////////////////////////////////////////
241
242 /**
243 .Function.goNext:
244 ..cat:Input/Output
245 */
246
247 template <typename TFile, typename TData, typename TMeta, typename TFormat>
248 inline void
249 goNext(TFile & file,
250            FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
251 {
252 SEQAN_CHECKPOINT
253         file_format.goNext_(file);
254 }
255
256 //////////////////////////////////////////////////////////////////////////////
257
258 /**
259 .Function.length:
260 ..cat:Input/Output
261 */
262
263 template <typename TFile, typename TData, typename TMeta, typename TFormat>
264 inline void
265 length(TFile & file,
266            FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
267 {
268 SEQAN_CHECKPOINT
269         file_format.length_(file);
270 }
271
272 //////////////////////////////////////////////////////////////////////////////
273
274 /**
275 .Function.Fileformat#write:
276 ..cat:Input/Output
277 ..summary:Writes to stream.
278 ..signature:write(stream, source)
279 ..signature:write(stream, begin, end)
280 ..param.stream: A stream object.
281 ...type:Adaption."std::iostream"
282 ..param.source: Container that is written to $stream$.
283 ..param.begin: Iterator to the first character of the range.
284 ..param.end: Iterator behind the last character of the range.
285 ..remarks:The content of $source$ is written 'as-is' to $stream$.
286 */
287
288 template <typename TFile, typename TData, typename TMeta, typename TFormat>
289 inline void
290 write(TFile & file,
291           TData & data,
292           FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
293 {
294 SEQAN_CHECKPOINT
295         file_format.write_(file, data);
296 }
297 template <typename TFile, typename TData, typename TMeta, typename TFormat>
298 inline void
299 write(TFile & file,
300           TData & data,
301           TMeta & meta,
302           FileFormat<TFile, TData, TMeta, TFormat> const & file_format)
303 {
304 SEQAN_CHECKPOINT
305         file_format.write_(file, data, meta);
306 }
307
308
309
310
311 //////////////////////////////////////////////////////////////////////////////
312 // Comparison of two FileFormat objects
313 //////////////////////////////////////////////////////////////////////////////
314
315 template <typename TFileLeft, typename TDataLeft, typename TMetaLeft, typename TFormatLeft, typename TFileRight, typename TDataRight, typename TMetaRight, typename TFormatRight>
316 inline bool
317 operator == (FileFormat<TFileLeft, TDataLeft, TMetaLeft, TFormatLeft> const & left, 
318                          FileFormat<TFileRight, TDataRight, TMetaRight, TFormatRight> const & right)
319 {
320 SEQAN_CHECKPOINT
321         return formatID(left) == formatID(right);
322 }
323
324 template <typename TFile, typename TData, typename TMeta, typename TFormat, typename TFormat2>
325 inline bool
326 operator == (FileFormat<TFile, TData, TMeta, TFormat> const & left, 
327                          Tag<TFormat2> const)
328 {
329 SEQAN_CHECKPOINT
330         return formatID(left) == _ClassIdentifier<Tag<TFormat2> const>::getID();
331 }
332
333 template <typename TFile, typename TData, typename TMeta, typename TFormat, typename TFormat2>
334 inline bool
335 operator == (Tag<TFormat2> const,
336                          FileFormat<TFile, TData, TMeta, TFormat> const & right)
337 {
338 SEQAN_CHECKPOINT
339         return _ClassIdentifier<Tag<TFormat2> const>::getID() == formatID(right);
340 }
341
342 //____________________________________________________________________________
343
344 template <typename TFileLeft, typename TDataLeft, typename TMetaLeft, typename TFormatLeft, typename TFileRight, typename TDataRight, typename TMetaRight, typename TFormatRight>
345 inline bool
346 operator != (FileFormat<TFileLeft, TDataLeft, TMetaLeft, TFormatLeft> const & left, 
347                          FileFormat<TFileRight, TDataRight, TMetaRight, TFormatRight> const & right)
348 {
349 SEQAN_CHECKPOINT
350         return formatID(left) != formatID(right);
351 }
352
353 template <typename TFile, typename TData, typename TMeta, typename TFormat, typename TFormat2>
354 inline bool
355 operator != (FileFormat<TFile, TData, TMeta, TFormat> const & left, 
356                          Tag<TFormat2> const)
357 {
358 SEQAN_CHECKPOINT
359         return formatID(left) != _ClassIdentifier<Tag<TFormat2> const>::getID();
360 }
361
362 template <typename TFile, typename TData, typename TMeta, typename TFormat, typename TFormat2>
363 inline bool
364 operator != (Tag<TFormat2> const,
365                          FileFormat<TFile, TData, TMeta, TFormat> const & right)
366 {
367 SEQAN_CHECKPOINT
368         return _ClassIdentifier<Tag<TFormat2> const>::getID() != formatID(right);
369 }
370
371 //////////////////////////////////////////////////////////////////////////////
372 // allgemeine Funktionen fuer Streams
373 //////////////////////////////////////////////////////////////////////////////
374 //TODO??? Das muss in eine extra Datei
375
376
377 /*
378 template <typename TStream, typename TIterator>
379 inline void
380 write(TStream & target,
381           TIterator begin_,
382           TIterator end_)
383 {
384         while (begin_ != end_)
385         {
386                 _streamPut(target, convert<char>(*begin_));
387                 ++begin_;
388         }
389 }
390
391 //____________________________________________________________________________
392
393 template <typename TStream, typename TSource>
394 inline void
395 write(TStream & target,
396           TSource const & source)
397 {
398         write(target, begin(source), end(source));
399 }
400 //TODO???: Spezialisierungen zum blockweise schreiben bei contiguous strings von char
401 //Anmerkungen: write wird nach dem zweiten Argument (source) spezialisiert!
402
403 //____________________________________________________________________________
404
405 template <typename TStream, typename TSource>
406 inline void
407 write(TStream & target,
408           TSource const & source,
409           typename Size<TSource>::Type limit_)
410 {
411         if (length(source) > limit_)
412         {
413                 write(target, begin(source), begin(source) + limit_);
414         }
415         else
416         {
417                 write(target, begin(source), end(source));
418         }
419 }
420
421 */
422 //////////////////////////////////////////////////////////////////////////////
423
424 // Helper function for scanning a stream
425 // c = next character, pass it to the next call of the function
426
427 template <typename TFile, typename TString, typename TChar>
428 inline void
429 _stream_appendLine(TFile & file,
430                                    TString & str,
431                                    TChar & c)
432 {
433         while (true)
434         {
435                 if (_streamEOF(file)) break;
436
437                 if (c == '\r')
438                 {
439                         c = _streamGet(file);
440                         if (c == '\n') 
441                         {
442                                 c = _streamGet(file);
443                         }
444                         break;
445                 }
446                 if (c == '\n')
447                 {
448                         c = _streamGet(file);
449                         break;
450                 }
451
452                 appendValue(str, c);
453
454                 c = _streamGet(file);
455         }
456 }
457 //____________________________________________________________________________
458
459 template <typename TFile, typename TChar>
460 inline void
461 _stream_countLine(TFile & file,
462                                   TChar & c)
463
464 {
465         while (true)
466         {
467                 if (_streamEOF(file)) break;
468
469                 if (c == '\r')
470                 {
471                         c = _streamGet(file);
472                         if (c == '\n') 
473                         {
474                                 c = _streamGet(file);
475                         }
476                         break;
477                 }
478                 if (c == '\n')
479                 {
480                         c = _streamGet(file);
481                         break;
482                 }
483
484                 c = _streamGet(file);
485         }
486 }
487
488 //____________________________________________________________________________
489
490 template <typename TFile, typename TChar>
491 inline typename Size<TFile>::Type
492 _stream_skipLine(TFile & file,
493                                  TChar & c)
494
495 {
496         typename Size<TFile>::Type count = 0;
497         while (true)
498         {
499                 if (_streamEOF(file)) break;
500
501                 if (c == '\r')
502                 {
503                         c = _streamGet(file);
504                         if (c == '\n') 
505                         {
506                                 c = _streamGet(file);
507                         }
508                         break;
509                 }
510                 if (c == '\n')
511                 {
512                         c = _streamGet(file);
513                         break;
514                 }
515
516                 ++count;
517
518                 c = _streamGet(file);
519         }
520
521         return count;
522 }
523
524
525
526
527 ////////////////////////////////////////////////////////////////////////////
528 //new ones
529
530 //new ones for streams
531 template<typename TFile, typename TChar>
532 inline void 
533 _stream_skipWhitespace(TFile& file, TChar& c)
534 {
535         if ((c!=' ') && (c != '\t')) return;
536         while (!_streamEOF(file)) {
537                 c = _streamGet(file);
538                 if ((c!=' ') && (c != '\t')) break;
539         }
540 }
541
542 ////////////////////////////////////////////////////////////////////////////
543
544
545 template<typename TFile, typename TChar>
546 inline String<char>
547 _stream_readWord(TFile & file, TChar& c)
548 {
549         // Read word
550         String<char> str(c);
551         while (!_streamEOF(file)) {
552                 c = _streamGet(file);
553                 if (!_stream_isLetter(c)) break;
554                 append(str, c);
555         }
556         return str;
557 }
558
559 ////////////////////////////////////////////////////////////////////////////
560
561 template<typename TChar>
562 inline bool
563 _stream_isLetter(TChar const c)
564 {
565         return ((c == 'a') || (c == 'b') || (c == 'c') || (c == 'd') || (c == 'e') || 
566                         (c == 'f') || (c == 'g') || (c == 'h') || (c == 'i') || (c == 'j') ||
567                         (c == 'k') || (c == 'l') || (c == 'm') || (c == 'n') || (c == 'o') || 
568                         (c == 'p') || (c == 'q') || (c == 'r') || (c == 's') || (c == 't') ||
569                         (c == 'u') || (c == 'v') || (c == 'w') || (c == 'x') || (c == 'y') || 
570                         (c == 'z') || (c == 'A') || (c == 'B') || (c == 'C') || (c == 'D') ||
571                         (c == 'E') || (c == 'F') || (c == 'G') || (c == 'H') || (c == 'I') || 
572                         (c == 'J') || (c == 'K') || (c == 'L') || (c == 'M') || (c == 'N') ||
573                         (c == 'O') || (c == 'P') || (c == 'Q') || (c == 'R') || (c == 'S') || 
574                         (c == 'T') || (c == 'U') || (c == 'V') || (c == 'W') || (c == 'X') ||
575                         (c == 'Y') || (c == 'Z'));
576 }
577
578
579 //////////////////////////////////////////////////////////////////////////////
580
581 //new ones for strings
582
583 template <typename TString, typename TIter>
584 inline typename Size<TString>::Type
585 _string_skipLine(TString & str,
586                                  TIter & it)
587
588 {
589         typename Size<TString>::Type count = 0;
590         typename Iterator<TString,Standard>::Type end_it = end(str,Standard());
591         while (true)
592         {
593                 if (it == end_it) break;
594
595                 if (*it == '\r')
596                 {
597                         ++it;
598                         if (*it == '\n') 
599                         {
600                                 ++it;
601                         }
602                         break;
603                 }
604                 if (*it == '\n')
605                 {
606                         ++it;
607                         break;
608                 }
609
610                 ++count;
611                 ++it;
612         }
613
614         return count;
615 }
616
617 /////////////////////////////////////////////////////////////////////////
618
619 template <typename TString1, typename TString2, typename TIter>
620 inline void
621 _string_appendLine(TString1 & str,
622                                    TString2 & a_str,
623                                    TIter & it)
624 {
625         typename Iterator<TString1,Standard>::Type end_it = end(str,Standard());
626         while (true)
627         {
628                 if (it == end_it) break;
629
630                 if (*it == '\r')
631                 {
632                         ++it; 
633                         if (*it == '\n') 
634                         {
635                                 ++it;
636                         }
637                         break;
638                 }
639                 if (*it == '\n')
640                 {
641                         ++it;
642                         break;
643                 }
644
645                 appendValue(a_str, getValue(it));
646                 ++it;
647         }
648 }
649
650 ////////////////////////////////////////////////////////////////////////////
651
652 template<typename TString, typename TIter>
653 inline void 
654 _string_skipWhitespace(TString& str, TIter& it)
655 {
656         typename Iterator<TString,Standard>::Type end_it = end(str,Standard())-1;
657         while (it != end_it) {
658                 if ((*it!=' ') && (*it != '\t')) break;
659                 ++it;
660         }
661 }
662
663 ////////////////////////////////////////////////////////////////////////////
664
665 template<typename TString, typename TIter>
666 inline int
667 _string_readNumber(TString & str, TIter& it)
668 {
669         // Read number
670         typename Iterator<TString,Standard>::Type end_it = end(str,Standard())-1;
671         String<char> numstr(getValue(it));
672         while (it != end_it) {
673                 ++it;
674                 if (!_parse_isDigit(*it)) break;
675                 append(numstr, getValue(it));
676         }
677         return atoi(toCString(numstr));
678 }
679
680 //////////////////////////////////////////////////////////////////////////////
681
682 } //namespace SEQAN_NAMESPACE_MAIN
683
684 //////////////////////////////////////////////////////////////////////////////
685
686 #endif //#ifndef SEQAN_HEADER_...