Remove unused nullStream
[alure.git] / src / streamdec.cpp
blob44827e8733643cfd9363821242908cac2bc98ac0
1 /*
2 * ALURE OpenAL utility library
3 * Copyright (c) 2009-2010 by Chris Robinson.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 #include "config.h"
26 #include "main.h"
28 #include <string.h>
29 #include <assert.h>
31 #include <algorithm>
32 #include <vector>
33 #include <memory>
34 #include <string>
35 #include <istream>
36 #include <fstream>
37 #include <iostream>
38 #include <sstream>
41 const Decoder::ListType& Decoder::GetList()
42 { return AddList(); }
44 Decoder::ListType& Decoder::AddList(Decoder::FactoryType func, ALint prio)
46 static ListType FuncList;
47 if(func)
49 assert(SearchSecond(FuncList.begin(), FuncList.end(), func) == FuncList.end());
50 FuncList.insert(std::make_pair(prio, func));
52 return FuncList;
56 struct customStream : public alureStream {
57 void *usrFile;
58 ALenum format;
59 ALuint samplerate;
60 ALuint blockAlign;
61 MemDataInfo memInfo;
63 UserCallbacks cb;
65 virtual bool IsValid()
66 { return usrFile != NULL; }
68 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
70 if(format == AL_NONE)
72 if(!cb.get_fmt || !cb.get_fmt(usrFile, &format, &samplerate, &blockAlign))
73 return false;
75 if(DetectBlockAlignment(format) != blockAlign)
76 blockAlign = 0;
78 *fmt = format;
79 *frequency = samplerate;
80 *blockalign = blockAlign;
81 return true;
84 virtual ALuint GetData(ALubyte *data, ALuint bytes)
85 { return cb.decode(usrFile, data, bytes); }
87 virtual bool Rewind()
89 if(cb.rewind && cb.rewind(usrFile))
90 return true;
91 SetError("Rewind failed");
92 return false;
95 customStream(const char *fname, const UserCallbacks &callbacks)
96 : alureStream(NULL), usrFile(NULL), format(0), samplerate(0),
97 blockAlign(0), cb(callbacks)
98 { if(cb.open_file) usrFile = cb.open_file(fname); }
100 customStream(const MemDataInfo &memData, const UserCallbacks &callbacks)
101 : alureStream(NULL), usrFile(NULL), format(0), samplerate(0),
102 blockAlign(0), memInfo(memData), cb(callbacks)
103 { if(cb.open_mem) usrFile = cb.open_mem(memInfo.Data, memInfo.Length); }
105 customStream(void *userdata, ALenum fmt, ALuint srate, const UserCallbacks &callbacks)
106 : alureStream(NULL), usrFile(userdata), format(fmt), samplerate(srate),
107 blockAlign(DetectBlockAlignment(format)), cb(callbacks)
110 virtual ~customStream()
112 if(cb.close && usrFile)
113 cb.close(usrFile);
114 usrFile = NULL;
119 template <typename T>
120 static alureStream *get_stream_decoder(const T &fdata)
122 std::map<ALint,UserCallbacks>::iterator i = InstalledCallbacks.begin();
123 while(i != InstalledCallbacks.end() && i->first < 0)
125 std::auto_ptr<alureStream> stream(new customStream(fdata, i->second));
126 if(stream->IsValid()) return stream.release();
127 i++;
130 std::istream *file = new InStream(fdata);
131 if(!file->fail())
133 const Decoder::ListType Factories = Decoder::GetList();
134 Decoder::ListType::const_reverse_iterator factory = Factories.rbegin();
135 Decoder::ListType::const_reverse_iterator end = Factories.rend();
136 while(factory != end)
138 file->clear();
139 file->seekg(0, std::ios_base::beg);
141 std::auto_ptr<alureStream> stream(factory->second(file));
142 if(stream.get() != NULL) return stream.release();
144 factory++;
147 SetError("Unsupported type");
148 delete file;
150 else
152 SetError("Failed to open file");
153 delete file;
156 while(i != InstalledCallbacks.end())
158 std::auto_ptr<alureStream> stream(new customStream(fdata, i->second));
159 if(stream->IsValid()) return stream.release();
160 i++;
163 return NULL;
166 alureStream *create_stream(const char *fname)
167 { return get_stream_decoder(fname); }
168 alureStream *create_stream(const MemDataInfo &memData)
169 { return get_stream_decoder(memData); }
171 alureStream *create_stream(ALvoid *userdata, ALenum format, ALuint rate, const UserCallbacks &cb)
172 { return new customStream(userdata, format, rate, cb); }