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