]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/BamIndexFactory_p.cpp
c91f43374f1fc0318c43c46e869fe0619afa4b1d
[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: 5 April 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
17 #include <cstdio>
18 using namespace std;
19
20 // generates index filename from BAM filename (depending on requested type)
21 // if type is unknown, returns empty string
22 const string BamIndexFactory::CreateIndexFilename(const string& bamFilename,
23                                                   const BamIndex::IndexType& type)
24 {
25     switch ( type ) {
26         case ( BamIndex::STANDARD ) : return ( bamFilename + BamStandardIndex::Extension() );
27         case ( BamIndex::BAMTOOLS ) : return ( bamFilename + BamToolsIndex::Extension() );
28         default :
29             cerr << "BamIndexFactory ERROR: unknown index type" << type << endl;
30             return string();
31     }
32 }
33
34 // creates a new BamIndex object, depending on extension of @indexFilename
35 BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename, BamReaderPrivate* reader) {
36
37     // if file doesn't exist, return null index
38     if ( !BamTools::FileExists(indexFilename) )
39         return 0;
40
41     // get file extension from index filename, including dot (".EXT")
42     // if can't get file extension, return null index
43     const string extension = FileExtension(indexFilename);
44     if ( extension.empty() )
45         return 0;
46
47     // create index based on extension
48     if      ( extension == BamStandardIndex::Extension() ) return new BamStandardIndex(reader);
49     else if ( extension == BamToolsIndex::Extension()    ) return new BamToolsIndex(reader);
50     else
51         return 0;
52 }
53
54 // creates a new BamIndex, object of requested @type
55 BamIndex* BamIndexFactory::CreateIndexOfType(const BamIndex::IndexType& type,
56                                              BamReaderPrivate* reader)
57 {
58     switch ( type ) {
59         case ( BamIndex::STANDARD ) : return new BamStandardIndex(reader);
60         case ( BamIndex::BAMTOOLS ) : return new BamToolsIndex(reader);
61         default :
62             cerr << "BamIndexFactory ERROR: unknown index type " << type << endl;
63             return 0;
64     }
65 }
66
67 // retrieves file extension (including '.')
68 const string BamIndexFactory::FileExtension(const string& filename) {
69
70     // if filename cannot contain valid path + extension, return empty string
71     if ( filename.empty() || filename.length() <= 4 )
72         return string();
73
74     // look for last dot in filename
75     size_t lastDotPosition = filename.find_last_of('.');
76
77     // if none found, return empty string
78     if ( lastDotPosition == string::npos )
79         return string();
80
81     // return substring from last dot position
82     return filename.substr(lastDotPosition);
83 }
84
85 // returns name of existing index file that corresponds to @bamFilename
86 // will defer to @preferredType if possible, if not will attempt to load any supported type
87 // returns empty string if not found
88 const string BamIndexFactory::FindIndexFilename(const string& bamFilename,
89                                                 const BamIndex::IndexType& preferredType)
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 }