diff options
Diffstat (limited to 'soundserver/samplestorage_impl.cpp')
-rw-r--r-- | soundserver/samplestorage_impl.cpp | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/soundserver/samplestorage_impl.cpp b/soundserver/samplestorage_impl.cpp new file mode 100644 index 0000000..b7e07f1 --- /dev/null +++ b/soundserver/samplestorage_impl.cpp @@ -0,0 +1,202 @@ + /* + + Copyright (C) 2001 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <dirent.h> +#include "soundserver.h" +#include "debug.h" + +using namespace Arts; +using namespace std; + +namespace Arts { + +class SampleStorageEntry_impl : public SampleStorageEntry_skel { +protected: + string _name, _filename; + bool _completed; + FILE *file; + +public: + SampleStorageEntry_impl(const string& name, const string& filename) + { + _name = name; + _filename = filename; + _completed = false; + file = fopen(_filename.c_str(),"w"); + } + ~SampleStorageEntry_impl() + { + if(file) + { + fclose(file); + file = 0; + } + unlink(_filename.c_str()); + } + + string name() { return _name; } + string filename() { return _filename; } + bool completed() { return _completed; } + + void write(const vector<mcopbyte>& data) + { + arts_return_if_fail(file != 0); + + fwrite(&data[0],1,data.size(),file); + } + void finish() + { + arts_return_if_fail(file != 0); + + fclose(file); + file = 0; + _completed = true; + } +}; + +class SampleStorage_impl : public SampleStorage_skel { +protected: + string directory; + long uniqueID; + vector<SampleStorageEntry> entries; + +public: + SampleStorage_impl() + { + uniqueID = 1; + } + + void constructor(const string& newDirectory, bool clearOnInit) + { + arts_return_if_fail(directory.empty()); + + directory = newDirectory; + mkdir(directory.c_str(),0700); + + if(clearOnInit) clear(); + } + + void clear() + { + DIR *dir = opendir(directory.c_str()); + if(!dir) return; + + struct dirent *de; + while((de = readdir(dir)) != 0) + { + string currentEntry = directory + "/" + de->d_name; + + if(de->d_name[0] != '.') + { + unlink(currentEntry.c_str()); + } + } + closedir(dir); + } + + string encodeName(const string& name) + { + string::const_iterator i; + string result; + + for(i = name.begin(); i != name.end(); i++) + { + unsigned char c = *i; + + if ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '_' || c == '-') + { + result += c; + } + else + { + char hex[17] = "0123456789ABCDEF"; + + result += '='; + result += hex[(c >> 4) & 0xf]; + result += hex[c & 0xf]; + } + } + return result; + } + + SampleStorageEntry createEntry(const string& name) + { + char uniqueprefix[32]; + sprintf(uniqueprefix,"s%ld-",uniqueID++); + string filename = directory + string("/") + + uniqueprefix + encodeName(name); + + return SampleStorageEntry::_from_base( + new SampleStorageEntry_impl(name, filename) + ); + } + + SampleStorageEntry findEntry(const string& name) + { + vector<SampleStorageEntry>::iterator i; + + for(i = entries.begin(); i != entries.end(); i++) + if(i->name() == name) return *i; + + return SampleStorageEntry::null(); + } + + void addEntry(SampleStorageEntry entry) + { + arts_return_if_fail(!entry.isNull()); + + /* remove the old entry for that name, if any */ + SampleStorageEntry oldEntry = findEntry(entry.name()); + if(!oldEntry.isNull()) + removeEntry(oldEntry); + + /* add the new entry */ + entries.push_back(entry); + } + + void removeEntry(SampleStorageEntry entry) + { + arts_return_if_fail(!entry.isNull()); + + vector<SampleStorageEntry>::iterator i; + for(i = entries.begin(); i != entries.end(); i++) + { + if(i->name() == entry.name()) + { + entries.erase(i); + return; + } + } + arts_warning("SampleStorage::removeEntry(%s) failed\n", + entry.name().c_str()); + } + +}; +REGISTER_IMPLEMENTATION(SampleStorage_impl); + +} |