Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CodecRegistry.cpp
Go to the documentation of this file.
1 //
2 // C++ Implementation: Audio::CodecRegistry, Audio::CodecRegistration
3 //
4 
5 #include "CodecRegistry.h"
6 #include "codecs/Codec.h"
7 #include "config.h"
8 
9 #include <algorithm>
10 #include <iostream>
11 
13 
14 namespace Audio {
15 
17  {
18  }
19 
21  {
22  nameCodec.clear();
23  universalCodecs.clear();
24  extensionCodecs.clear();
25 
26  for (CodecPriority::const_iterator it = codecPriority.begin(); it != codecPriority.end(); ++it)
27  delete it->first;
28  codecPriority.clear();
29  }
30 
31  void CodecRegistry::add(Codec* codec, int priority) throw()
32  {
33  if (codecPriority.find(codec) == codecPriority.end()) {
34  codecPriority[codec] = priority;
35  nameCodec[codec->getName()] = codec;
36 
37  std::cout << "Registering codec " << codec->getName().c_str();
38 
39  const Codec::Extensions *ext = codec->getExtensions();
40  if (ext) {
41  for (Codec::Extensions::const_iterator it = ext->begin(); it != ext->end(); ++it) {
42  std::cout << " " << it->c_str();
43  extensionCodecs[*it].insert(codec);
44  }
45  } else {
46  std::cout << " as universal";
47  universalCodecs.insert(codec);
48  }
49 
50  std::cout << "." << std::endl;
51  } else {
52  std::cout << "Codec " << codec->getName().c_str() << " already registered" << std::endl;
53  }
54  }
55 
56  void CodecRegistry::remove(Codec* codec) throw()
57  {
58  if (codecPriority.find(codec) != codecPriority.end()) {
59  codecPriority.erase(codec);
60  nameCodec.erase(codec->getName());
61  const Codec::Extensions *ext = codec->getExtensions();
62  if (ext) {
63  for (Codec::Extensions::const_iterator it = ext->begin(); it != ext->end(); ++it)
64  extensionCodecs[*it].erase(codec);
65  } else {
66  universalCodecs.erase(codec);
67  }
68  }
69  }
70 
71  Codec* CodecRegistry::findByName(const std::string& name) const throw(CodecNotFoundException)
72  {
73  NameCodec::const_iterator it = nameCodec.find(name);
74  if (it != nameCodec.end())
75  return it->second; else
77  std::string("No codec with name \"") + name + "\" has been registered");
78  }
79 
80  template<typename INDEX, typename T>
82  {
83  const INDEX& _index;
84  public:
85  MappedComparator(const INDEX& index) : _index(index) {}
86  bool operator()(const T& a, const T& b) const
87  {
88  typename INDEX::const_iterator ait = _index.find(a);
89  typename INDEX::const_iterator bit = _index.find(b);
90  if (ait == _index.end()) {
91  return (bit != _index.end());
92  } else {
93  if (bit == _index.end()) {
94  return false;
95  } else {
96  return (*ait < *bit);
97  }
98  }
99  }
100  };
101 
103  {
104  std::vector<Codec*> candidates;
105 
106  // NOTE: we'll assume that if they are including the specified extension, they'll return
107  // true if asked if they can handle the file with !canOpen.
108  size_t sep = path.find_last_of('.');
109  if (sep != std::string::npos && (sep+1) < path.length()) {
110  ExtensionCodecs::const_iterator eit = extensionCodecs.find(
111  path.substr(sep+1, std::string::npos));
112  if (eit != extensionCodecs.end())
113  for (CodecSet::const_iterator esit=eit->second.begin(); esit != eit->second.end(); ++esit)
114  candidates.push_back(*esit);
115  }
116 
117  for (CodecSet::const_iterator uit = universalCodecs.begin(); uit != universalCodecs.end(); ++uit)
118  if ((*uit)->canHandle(path, false, type))
119  candidates.push_back(*uit);
120 
121  // Now we'll sort candidates by priority, and return the first codec that can actually handle the file.
122  if (candidates.begin() != candidates.end()) {
123  std::sort(
124  candidates.begin(),
125  candidates.end(),
127 
128  // Why do we need an explicit cast *to* const?
129  // See http://www.mpi-inf.mpg.de/~hitoshi/otherprojects/tips/cpp-memo.shtml
130  for (std::vector<Codec*>::const_reverse_iterator it = candidates.rbegin();
131  it != reinterpret_cast<const std::vector<Codec*> &>(candidates).rend(); ++it)
132  if ((*it)->canHandle(path, true, type))
133  return *it;
134  }
135 
136  // No candidate is able to handle this one!
138  std::string("No registered codec can handle the file \"") + path + "\"");
139  }
140 
141  Stream* CodecRegistry::open(const std::string& path, VSFileSystem::VSFileType type) const
142  throw(Exception)
143  {
144  Codec *codec = findByFile(path, type);
145  return codec->open(path, type);
146  }
147 
148  CodecRegistration::CodecRegistration(Codec* _codec, int priority) throw()
149  : codec(_codec)
150  {
152  new CodecRegistry();
154  }
155 
157  {
158  CodecRegistry::getSingleton()->remove(codec);
159  }
160 
161 };