]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/BamIndexFactory_p.cpp
Major update to BamTools version 1.0
[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: 21 March 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 + BAI_EXTENSION );
28         case ( BamIndex::BAMTOOLS ) : return ( bamFilename + BTI_EXTENSION );
29         default :
30             fprintf(stderr, "BamIndexFactory ERROR: unknown index type %u\n", type);
31             return string();
32     }
33 }
34
35 // creates a new BamIndex object, depending on extension of @indexFilename
36 BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename) {
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 == BAI_EXTENSION ) return new BamStandardIndex;
50     else if ( extension == BTI_EXTENSION ) return new BamToolsIndex;
51     else                                   return 0;
52 }
53
54 // creates a new BamIndex, object of requested @type
55 BamIndex* BamIndexFactory::CreateIndexOfType(const BamIndex::IndexType& type) {
56     switch ( type ) {
57         case ( BamIndex::STANDARD ) : return new BamStandardIndex;
58         case ( BamIndex::BAMTOOLS ) : return new BamToolsIndex;
59         default :
60             fprintf(stderr, "BamIndexFactory ERROR: unknown index type %u\n", type);
61             return 0;
62     }
63 }
64
65 // retrieves file extension (including '.')
66 const string BamIndexFactory::FileExtension(const string& filename) {
67
68     // if filename cannot contain valid path + extension, return empty string
69     if ( filename.empty() || filename.length() <= 4 )
70         return string();
71
72     // look for last dot in filename
73     size_t lastDotPosition = filename.find_last_of('.');
74
75     // if none found, return empty string
76     if ( lastDotPosition == string::npos )
77         return string();
78
79     // return substring from last dot position
80     return filename.substr(lastDotPosition);
81 }
82
83 // returns name of existing index file that corresponds to @bamFilename
84 // will defer to @preferredType if possible, if not will attempt to load any supported type
85 // returns empty string if not found
86 const string BamIndexFactory::FindIndexFilename(const string& bamFilename,
87                                                 const BamIndex::IndexType& preferredType)
88 {
89     // try to find index of preferred type first
90     // return index filename if found
91     string indexFilename = CreateIndexFilename(bamFilename, preferredType);
92     if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
93         return indexFilename;
94
95     // couldn't find preferred type, try the other supported types
96     // return index filename if found
97     if ( preferredType != BamIndex::STANDARD ) {
98         indexFilename = CreateIndexFilename(bamFilename, BamIndex::STANDARD);
99         if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
100             return indexFilename;
101     }
102     if ( preferredType != BamIndex::BAMTOOLS ) {
103         indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
104         if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
105             return indexFilename;
106     }
107
108     // otherwise couldn't find any index matching this filename
109     return string();
110 }