]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/BamIndexFactory_p.cpp
4e9d1f28a4040aee6bc6140ffa23a61fad53f477
[bamtools.git] / src / api / internal / BamIndexFactory_p.cpp
1 // ***************************************************************************
2 // BamIndexFactory_p.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 6 October 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides interface for generating BamIndex implementations
8 // ***************************************************************************
9
10 #include <api/BamAux.h>
11 #include <api/internal/BamIndexFactory_p.h>
12 #include <api/internal/BamStandardIndex_p.h>
13 #include <api/internal/BamToolsIndex_p.h>
14 using namespace BamTools;
15 using namespace BamTools::Internal;
16 using namespace std;
17
18 // generates index filename from BAM filename (depending on requested type)
19 // if type is unknown, returns empty string
20 const string BamIndexFactory::CreateIndexFilename(const string& bamFilename,
21                                                   const BamIndex::IndexType& type)
22 {
23     switch ( type ) {
24         case ( BamIndex::STANDARD ) : return ( bamFilename + BamStandardIndex::Extension() );
25         case ( BamIndex::BAMTOOLS ) : return ( bamFilename + BamToolsIndex::Extension() );
26         default :
27             return string();
28     }
29 }
30
31 // creates a new BamIndex object, depending on extension of @indexFilename
32 BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename, BamReaderPrivate* reader) {
33
34     // if file doesn't exist, return null index
35     if ( !BamTools::FileExists(indexFilename) )
36         return 0;
37
38     // get file extension from index filename, including dot (".EXT")
39     // if can't get file extension, return null index
40     const string extension = FileExtension(indexFilename);
41     if ( extension.empty() )
42         return 0;
43
44     // create index based on extension
45     if      ( extension == BamStandardIndex::Extension() ) return new BamStandardIndex(reader);
46     else if ( extension == BamToolsIndex::Extension()    ) return new BamToolsIndex(reader);
47     else
48         return 0;
49 }
50
51 // creates a new BamIndex, object of requested @type
52 BamIndex* BamIndexFactory::CreateIndexOfType(const BamIndex::IndexType& type,
53                                              BamReaderPrivate* reader)
54 {
55     switch ( type ) {
56         case ( BamIndex::STANDARD ) : return new BamStandardIndex(reader);
57         case ( BamIndex::BAMTOOLS ) : return new BamToolsIndex(reader);
58         default :
59             return 0;
60     }
61 }
62
63 // retrieves file extension (including '.')
64 const string BamIndexFactory::FileExtension(const string& filename) {
65
66     // if filename cannot contain valid path + extension, return empty string
67     if ( filename.empty() || filename.length() <= 4 )
68         return string();
69
70     // look for last dot in filename
71     const size_t lastDotPosition = filename.find_last_of('.');
72
73     // if none found, return empty string
74     if ( lastDotPosition == string::npos )
75         return string();
76
77     // return substring from last dot position
78     return filename.substr(lastDotPosition);
79 }
80
81 // returns name of existing index file that corresponds to @bamFilename
82 // will defer to @preferredType if possible, if not will attempt to load any supported type
83 // returns empty string if not found
84 const string BamIndexFactory::FindIndexFilename(const string& bamFilename,
85                                                 const BamIndex::IndexType& preferredType)
86 {
87     // skip if BAM filename provided is empty
88     if ( bamFilename.empty() )
89         return string();
90
91     // try to find index of preferred type first
92     // return index filename if found
93     string indexFilename = CreateIndexFilename(bamFilename, preferredType);
94     if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
95         return indexFilename;
96
97     // couldn't find preferred type, try the other supported types
98     // return index filename if found
99     if ( preferredType != BamIndex::STANDARD ) {
100         indexFilename = CreateIndexFilename(bamFilename, BamIndex::STANDARD);
101         if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
102             return indexFilename;
103     }
104     if ( preferredType != BamIndex::BAMTOOLS ) {
105         indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
106         if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
107             return indexFilename;
108     }
109
110     // otherwise couldn't find any index matching this filename
111     return string();
112 }