/[svn]/linuxsampler/trunk/src/db/InstrumentsDbUtilities.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/db/InstrumentsDbUtilities.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3705 - (hide annotations) (download)
Wed Jan 8 20:26:53 2020 UTC (4 years, 3 months ago) by schoenebeck
File size: 28074 byte(s)
Fixed compiler warnings about exception handling:

Use re-throw semantic instead of copying exception objects.

1 iliev 1200 /***************************************************************************
2     * *
3 persson 1908 * Copyright (C) 2007 - 2009 Grigor Iliev *
4 iliev 1200 * *
5     * This program is free software; you can redistribute it and/or modify *
6     * it under the terms of the GNU General Public License as published by *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This program is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this program; if not, write to the Free Software *
17     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18     * MA 02110-1301 USA *
19     ***************************************************************************/
20    
21     #include "InstrumentsDbUtilities.h"
22    
23 iliev 1717 #include "../common/File.h"
24 schoenebeck 1424 #include "../common/global_private.h"
25 iliev 1200
26 persson 1943 #include <algorithm>
27 iliev 1200 #include <errno.h>
28    
29     #include "../common/Exception.h"
30     #include "InstrumentsDb.h"
31 schoenebeck 3092 #include "../engines/sfz/sfz.h"
32     #if HAVE_SF2
33     # if AC_APPLE_UNIVERSAL_BUILD
34     # include <libgig/SF.h>
35     # else
36     # include <SF.h>
37     # endif
38     #endif // HAVE_SF2
39 iliev 1200
40     namespace LinuxSampler {
41    
42 schoenebeck 3092 class GigFileInfo : public InstrumentFileInfo {
43     public:
44     GigFileInfo(String fileName) : InstrumentFileInfo(fileName) {
45     m_gig = NULL;
46     m_riff = NULL;
47     try {
48     m_riff = new RIFF::File(fileName);
49     m_gig = new gig::File(m_riff);
50     m_gig->SetAutoLoad(false); // avoid time consuming samples scanning
51     } catch (RIFF::Exception e) {
52     throw Exception(e.Message);
53     } catch (...) {
54     throw Exception("Unknown exception while accessing gig file");
55     }
56     }
57    
58     virtual ~GigFileInfo() {
59     if (m_gig) delete m_gig;
60     if (m_riff) delete m_riff;
61     }
62    
63     String formatName() OVERRIDE {
64     return "GIG";
65     }
66    
67     String formatVersion() OVERRIDE {
68     return (m_gig->pVersion) ? ToString(m_gig->pVersion->major) : "";
69     }
70    
71     optional<InstrumentInfo> getInstrumentInfo(int index, ScanProgress* pProgress) OVERRIDE {
72     InstrumentInfo info;
73     try {
74     ::gig::progress_t* progress = (pProgress) ? &pProgress->GigFileProgress : NULL;
75     ::gig::Instrument* pInstrument = m_gig->GetInstrument(index, progress);
76     if (!pInstrument)
77     return optional<InstrumentInfo>::nothing;
78    
79     info.instrumentName = pInstrument->pInfo->Name;
80     info.product = (!pInstrument->pInfo->Product.empty()) ? pInstrument->pInfo->Product : m_gig->pInfo->Product;
81     info.artists = (!pInstrument->pInfo->Artists.empty()) ? pInstrument->pInfo->Artists : m_gig->pInfo->Artists;
82     info.keywords = (!pInstrument->pInfo->Keywords.empty()) ? pInstrument->pInfo->Keywords : m_gig->pInfo->Keywords;
83     info.comments = (!pInstrument->pInfo->Comments.empty()) ? pInstrument->pInfo->Comments : m_gig->pInfo->Comments;
84     info.isDrum = pInstrument->IsDrum;
85     } catch (RIFF::Exception e) {
86     throw Exception(e.Message);
87     } catch (...) {
88     throw Exception("Unknown exception while accessing gig file");
89     }
90     return info;
91     }
92     private:
93     ::RIFF::File* m_riff;
94     ::gig::File* m_gig;
95     };
96    
97     class SFZFileInfo : public InstrumentFileInfo {
98     public:
99     SFZFileInfo(String fileName) : InstrumentFileInfo(fileName) {
100     m_sfz = NULL;
101     try {
102     m_sfz = new ::sfz::File(fileName);
103     } catch (sfz::Exception e) {
104     throw Exception(e.Message());
105     } catch (...) {
106     throw Exception("Unknown exception while accessing sfz file");
107     }
108     }
109    
110     virtual ~SFZFileInfo() {
111     if (m_sfz) delete m_sfz;
112     }
113    
114     String formatName() OVERRIDE {
115     return "SFZ";
116     }
117    
118     String formatVersion() OVERRIDE {
119     return "";
120     }
121    
122     optional<InstrumentInfo> getInstrumentInfo(int index, ScanProgress* pProgress) OVERRIDE {
123     if (index != 0)
124     return optional<InstrumentInfo>::nothing;
125    
126     InstrumentInfo info;
127     // yeah, lousy info, but SFZ does not provide any meta info unfortunately yet
128     return info;
129     }
130     private:
131     ::sfz::File* m_sfz;
132     };
133    
134     #if HAVE_SF2
135    
136     class Sf2FileInfo : public InstrumentFileInfo {
137     public:
138     Sf2FileInfo(String fileName) : InstrumentFileInfo(fileName) {
139     m_sf2 = NULL;
140     m_riff = NULL;
141     try {
142     m_riff = new RIFF::File(fileName);
143     m_sf2 = new sf2::File(m_riff);
144     } catch (RIFF::Exception e) {
145     throw Exception(e.Message);
146     } catch (...) {
147     throw Exception("Unknown exception while accessing sf2 file");
148     }
149     }
150    
151     virtual ~Sf2FileInfo() {
152     if (m_sf2) delete m_sf2;
153     if (m_riff) delete m_riff;
154     }
155    
156     String formatName() OVERRIDE {
157     return "SF2";
158     }
159    
160     String formatVersion() OVERRIDE {
161     if (!m_sf2->pInfo || !m_sf2->pInfo->pVer) return "";
162     String major = ToString(m_sf2->pInfo->pVer->Major);
163     //String minor = ToString(m_sf2->pInfo->pVer->Minor);
164     //return major + "." + minor;
165     return major;
166     }
167    
168     optional<InstrumentInfo> getInstrumentInfo(int index, ScanProgress* pProgress) OVERRIDE {
169     if (index >= m_sf2->GetPresetCount())
170     return optional<InstrumentInfo>::nothing;
171    
172     InstrumentInfo info;
173     try {
174     ::sf2::Preset* preset = m_sf2->GetPreset(index);
175     if (!preset)
176     return optional<InstrumentInfo>::nothing;
177    
178     info.instrumentName = preset->Name;
179     if (m_sf2->pInfo) {
180     info.product = m_sf2->pInfo->Product;
181     info.comments = m_sf2->pInfo->Comments;
182     info.artists = m_sf2->pInfo->Engineers;
183     }
184     } catch (RIFF::Exception e) {
185     throw Exception(e.Message);
186     } catch (...) {
187     throw Exception("Unknown exception while accessing gig file");
188     }
189     return info;
190     }
191     private:
192     ::RIFF::File* m_riff;
193     ::sf2::File* m_sf2;
194     };
195    
196     #endif // #if HAVE_SF2
197    
198 iliev 1200 void DbInstrument::Copy(const DbInstrument& Instr) {
199     if (this == &Instr) return;
200    
201     InstrFile = Instr.InstrFile;
202     InstrNr = Instr.InstrNr;
203     FormatFamily = Instr.FormatFamily;
204     FormatVersion = Instr.FormatVersion;
205     Size = Instr.Size;
206     Created = Instr.Created;
207     Modified = Instr.Modified;
208     Description = Instr.Description;
209     IsDrum = Instr.IsDrum;
210     Product = Instr.Product;
211     Artists = Instr.Artists;
212     Keywords = Instr.Keywords;
213     }
214    
215    
216     void DbDirectory::Copy(const DbDirectory& Dir) {
217     if (this == &Dir) return;
218    
219     Created = Dir.Created;
220     Modified = Dir.Modified;
221     Description = Dir.Description;
222     }
223    
224     SearchQuery::SearchQuery() {
225     MinSize = -1;
226     MaxSize = -1;
227     InstrType = BOTH;
228     }
229    
230     void SearchQuery::SetFormatFamilies(String s) {
231     if (s.length() == 0) return;
232     int i = 0;
233 schoenebeck 3101 int j = (int) s.find(',', 0);
234 iliev 1200
235     while (j != std::string::npos) {
236     FormatFamilies.push_back(s.substr(i, j - i));
237     i = j + 1;
238 schoenebeck 3101 j = (int) s.find(',', i);
239 iliev 1200 }
240    
241     if (i < s.length()) FormatFamilies.push_back(s.substr(i));
242     }
243    
244     void SearchQuery::SetSize(String s) {
245     String s2 = GetMin(s);
246     if (s2.length() > 0) MinSize = atoll(s2.c_str());
247     else MinSize = -1;
248    
249     s2 = GetMax(s);
250     if (s2.length() > 0) MaxSize = atoll(s2.c_str());
251     else MaxSize = -1;
252     }
253    
254     void SearchQuery::SetCreated(String s) {
255     CreatedAfter = GetMin(s);
256     CreatedBefore = GetMax(s);
257     }
258    
259     void SearchQuery::SetModified(String s) {
260     ModifiedAfter = GetMin(s);
261     ModifiedBefore = GetMax(s);
262     }
263    
264     String SearchQuery::GetMin(String s) {
265     if (s.length() < 3) return "";
266     if (s.at(0) == '.' && s.at(1) == '.') return "";
267 schoenebeck 3101 int i = (int) s.find("..");
268 iliev 1200 if (i == std::string::npos) return "";
269     return s.substr(0, i);
270     }
271    
272     String SearchQuery::GetMax(String s) {
273     if (s.length() < 3) return "";
274     if (s.find("..", s.length() - 2) != std::string::npos) return "";
275 schoenebeck 3101 int i = (int) s.find("..");
276 iliev 1200 if (i == std::string::npos) return "";
277     return s.substr(i + 2);
278     }
279    
280     void ScanJob::Copy(const ScanJob& Job) {
281     if (this == &Job) return;
282    
283     JobId = Job.JobId;
284     FilesTotal = Job.FilesTotal;
285     FilesScanned = Job.FilesScanned;
286     Scanning = Job.Scanning;
287     Status = Job.Status;
288     }
289    
290     int JobList::AddJob(ScanJob Job) {
291     if (Counter + 1 < Counter) Counter = 0;
292     else Counter++;
293     Job.JobId = Counter;
294     Jobs.push_back(Job);
295     if (Jobs.size() > 3) {
296     std::vector<ScanJob>::iterator iter = Jobs.begin();
297     Jobs.erase(iter);
298     }
299     return Job.JobId;
300     }
301    
302     ScanJob& JobList::GetJobById(int JobId) {
303     for (int i = 0; i < Jobs.size(); i++) {
304     if (Jobs.at(i).JobId == JobId) return Jobs.at(i);
305     }
306    
307     throw Exception("Invalid job ID: " + ToString(JobId));
308     }
309    
310     bool AbstractFinder::IsRegex(String Pattern) {
311     if(Pattern.find('?') != String::npos) return true;
312     if(Pattern.find('*') != String::npos) return true;
313     return false;
314     }
315    
316     void AbstractFinder::AddSql(String Col, String Pattern, std::stringstream& Sql) {
317     if (Pattern.length() == 0) return;
318    
319     if (IsRegex(Pattern)) {
320 persson 1908 #ifndef WIN32
321 iliev 1200 Sql << " AND " << Col << " regexp ?";
322 persson 1908 #else
323     for (int i = 0; i < Pattern.length(); i++) {
324     if (Pattern.at(i) == '?') Pattern.at(i) = '_';
325     else if (Pattern.at(i) == '*') Pattern.at(i) = '%';
326     }
327     Sql << " AND " << Col << " LIKE ?";
328     #endif
329 iliev 1200 Params.push_back(Pattern);
330     return;
331     }
332    
333     String buf;
334     std::vector<String> tokens;
335     std::vector<String> tokens2;
336     std::stringstream ss(Pattern);
337     while (ss >> buf) tokens.push_back(buf);
338    
339     if (tokens.size() == 0) {
340     Sql << " AND " << Col << " LIKE ?";
341     Params.push_back("%" + Pattern + "%");
342     return;
343     }
344    
345     bool b = false;
346     for (int i = 0; i < tokens.size(); i++) {
347     Sql << (i == 0 ? " AND (" : "");
348    
349     for (int j = 0; j < tokens.at(i).length(); j++) {
350     if (tokens.at(i).at(j) == '+') tokens.at(i).at(j) = ' ';
351     }
352    
353     ss.clear();
354     ss.str("");
355     ss << tokens.at(i);
356    
357     tokens2.clear();
358     while (ss >> buf) tokens2.push_back(buf);
359    
360     if (b && tokens2.size() > 0) Sql << " OR ";
361     if (tokens2.size() > 1) Sql << "(";
362     for (int j = 0; j < tokens2.size(); j++) {
363     if (j != 0) Sql << " AND ";
364     Sql << Col << " LIKE ?";
365     Params.push_back("%" + tokens2.at(j) + "%");
366     b = true;
367     }
368     if (tokens2.size() > 1) Sql << ")";
369     }
370     if (!b) Sql << "0)";
371     else Sql << ")";
372     }
373    
374     DirectoryFinder::DirectoryFinder(SearchQuery* pQuery) : pDirectories(new std::vector<String>) {
375     pStmt = NULL;
376     this->pQuery = pQuery;
377     std::stringstream sql;
378     sql << "SELECT dir_name from instr_dirs WHERE dir_id!=0 AND parent_dir_id=?";
379    
380     if (pQuery->CreatedAfter.length() != 0) {
381     sql << " AND created > ?";
382     Params.push_back(pQuery->CreatedAfter);
383     }
384     if (pQuery->CreatedBefore.length() != 0) {
385     sql << " AND created < ?";
386     Params.push_back(pQuery->CreatedBefore);
387     }
388     if (pQuery->ModifiedAfter.length() != 0) {
389     sql << " AND modified > ?";
390     Params.push_back(pQuery->ModifiedAfter);
391     }
392     if (pQuery->ModifiedBefore.length() != 0) {
393     sql << " AND modified < ?";
394     Params.push_back(pQuery->ModifiedBefore);
395     }
396    
397     AddSql("dir_name", pQuery->Name, sql);
398     AddSql("description", pQuery->Description, sql);
399     SqlQuery = sql.str();
400    
401     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
402    
403     int res = sqlite3_prepare(idb->GetDb(), SqlQuery.c_str(), -1, &pStmt, NULL);
404     if (res != SQLITE_OK) {
405     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
406     }
407    
408     for(int i = 0; i < Params.size(); i++) {
409     idb->BindTextParam(pStmt, i + 2, Params.at(i));
410     }
411     }
412    
413     DirectoryFinder::~DirectoryFinder() {
414     if (pStmt != NULL) sqlite3_finalize(pStmt);
415     }
416    
417     StringListPtr DirectoryFinder::GetDirectories() {
418 schoenebeck 3091 #if __cplusplus >= 201103L && !CONFIG_NO_CPP11STL
419 persson 2840 return std::move(pDirectories);
420     #else
421 iliev 1200 return pDirectories;
422 persson 2840 #endif
423 iliev 1200 }
424    
425     void DirectoryFinder::ProcessDirectory(String Path, int DirId) {
426     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
427     idb->BindIntParam(pStmt, 1, DirId);
428    
429     String s = Path;
430     if(Path.compare("/") != 0) s += "/";
431     int res = sqlite3_step(pStmt);
432     while(res == SQLITE_ROW) {
433 iliev 1345 pDirectories->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
434 iliev 1200 res = sqlite3_step(pStmt);
435     }
436    
437     if (res != SQLITE_DONE) {
438     sqlite3_finalize(pStmt);
439     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
440     }
441    
442     res = sqlite3_reset(pStmt);
443     if (res != SQLITE_OK) {
444     sqlite3_finalize(pStmt);
445     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
446     }
447     }
448    
449     InstrumentFinder::InstrumentFinder(SearchQuery* pQuery) : pInstruments(new std::vector<String>) {
450     pStmt = NULL;
451     this->pQuery = pQuery;
452     std::stringstream sql;
453     sql << "SELECT instr_name from instruments WHERE dir_id=?";
454    
455     if (pQuery->CreatedAfter.length() != 0) {
456     sql << " AND created > ?";
457     Params.push_back(pQuery->CreatedAfter);
458     }
459     if (pQuery->CreatedBefore.length() != 0) {
460     sql << " AND created < ?";
461     Params.push_back(pQuery->CreatedBefore);
462     }
463     if (pQuery->ModifiedAfter.length() != 0) {
464     sql << " AND modified > ?";
465     Params.push_back(pQuery->ModifiedAfter);
466     }
467     if (pQuery->ModifiedBefore.length() != 0) {
468     sql << " AND modified < ?";
469     Params.push_back(pQuery->ModifiedBefore);
470     }
471     if (pQuery->MinSize != -1) sql << " AND instr_size > " << pQuery->MinSize;
472     if (pQuery->MaxSize != -1) sql << " AND instr_size < " << pQuery->MaxSize;
473    
474     if (pQuery->InstrType == SearchQuery::CHROMATIC) sql << " AND is_drum = 0";
475     else if (pQuery->InstrType == SearchQuery::DRUM) sql << " AND is_drum != 0";
476    
477     if (pQuery->FormatFamilies.size() > 0) {
478     sql << " AND (format_family=?";
479     Params.push_back(pQuery->FormatFamilies.at(0));
480     for (int i = 1; i < pQuery->FormatFamilies.size(); i++) {
481     sql << "OR format_family=?";
482     Params.push_back(pQuery->FormatFamilies.at(i));
483     }
484     sql << ")";
485     }
486    
487     AddSql("instr_name", pQuery->Name, sql);
488     AddSql("description", pQuery->Description, sql);
489     AddSql("product", pQuery->Product, sql);
490     AddSql("artists", pQuery->Artists, sql);
491     AddSql("keywords", pQuery->Keywords, sql);
492     SqlQuery = sql.str();
493    
494     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
495    
496     int res = sqlite3_prepare(idb->GetDb(), SqlQuery.c_str(), -1, &pStmt, NULL);
497     if (res != SQLITE_OK) {
498     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
499     }
500    
501     for(int i = 0; i < Params.size(); i++) {
502     idb->BindTextParam(pStmt, i + 2, Params.at(i));
503     }
504     }
505    
506     InstrumentFinder::~InstrumentFinder() {
507     if (pStmt != NULL) sqlite3_finalize(pStmt);
508     }
509    
510     void InstrumentFinder::ProcessDirectory(String Path, int DirId) {
511     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
512     idb->BindIntParam(pStmt, 1, DirId);
513    
514     String s = Path;
515     if(Path.compare("/") != 0) s += "/";
516     int res = sqlite3_step(pStmt);
517     while(res == SQLITE_ROW) {
518 iliev 1345 pInstruments->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
519 iliev 1200 res = sqlite3_step(pStmt);
520     }
521    
522     if (res != SQLITE_DONE) {
523     sqlite3_finalize(pStmt);
524     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
525     }
526    
527     res = sqlite3_reset(pStmt);
528     if (res != SQLITE_OK) {
529     sqlite3_finalize(pStmt);
530     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
531     }
532     }
533    
534     StringListPtr InstrumentFinder::GetInstruments() {
535 schoenebeck 3091 #if __cplusplus >= 201103L && !CONFIG_NO_CPP11STL
536 persson 2840 return std::move(pInstruments);
537     #else
538 iliev 1200 return pInstruments;
539 persson 2840 #endif
540 iliev 1200 }
541    
542     void DirectoryCounter::ProcessDirectory(String Path, int DirId) {
543     count += InstrumentsDb::GetInstrumentsDb()->GetDirectoryCount(DirId);
544     }
545    
546     void InstrumentCounter::ProcessDirectory(String Path, int DirId) {
547     count += InstrumentsDb::GetInstrumentsDb()->GetInstrumentCount(DirId);
548     }
549    
550     DirectoryCopier::DirectoryCopier(String SrcParentDir, String DestDir) {
551     this->SrcParentDir = SrcParentDir;
552     this->DestDir = DestDir;
553    
554     if (DestDir.at(DestDir.length() - 1) != '/') {
555     this->DestDir.append("/");
556     }
557     if (SrcParentDir.at(SrcParentDir.length() - 1) != '/') {
558     this->SrcParentDir.append("/");
559     }
560     }
561    
562     void DirectoryCopier::ProcessDirectory(String Path, int DirId) {
563     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
564    
565     String dir = DestDir;
566     String subdir = Path;
567     if(subdir.length() > SrcParentDir.length()) {
568     subdir = subdir.substr(SrcParentDir.length());
569     dir += subdir;
570     db->AddDirectory(dir);
571     }
572    
573     int dstDirId = db->GetDirectoryId(dir);
574 iliev 1345 if(dstDirId == -1) {
575     throw Exception("Unkown DB directory: " + InstrumentsDb::toEscapedPath(dir));
576     }
577 iliev 1200 IntListPtr ids = db->GetInstrumentIDs(DirId);
578     for (int i = 0; i < ids->size(); i++) {
579     String name = db->GetInstrumentName(ids->at(i));
580     db->CopyInstrument(ids->at(i), name, dstDirId, dir);
581     }
582     }
583    
584     ScanProgress::ScanProgress() {
585     TotalFileCount = ScannedFileCount = Status = 0;
586     CurrentFile = "";
587     GigFileProgress.custom = this;
588     GigFileProgress.callback = GigFileProgressCallback;
589     }
590    
591     void ScanProgress::StatusChanged() {
592     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
593     db->Jobs.GetJobById(JobId).FilesTotal = GetTotalFileCount();
594     db->Jobs.GetJobById(JobId).FilesScanned = GetScannedFileCount();
595     db->Jobs.GetJobById(JobId).Scanning = CurrentFile;
596     db->Jobs.GetJobById(JobId).Status = GetStatus();
597    
598     InstrumentsDb::GetInstrumentsDb()->FireJobStatusChanged(JobId);
599     }
600    
601     int ScanProgress::GetTotalFileCount() {
602     return TotalFileCount;
603     }
604    
605     void ScanProgress::SetTotalFileCount(int Count) {
606     if (TotalFileCount == Count) return;
607     TotalFileCount = Count;
608     StatusChanged();
609     }
610    
611     int ScanProgress::GetScannedFileCount() {
612     return ScannedFileCount;
613     }
614    
615     void ScanProgress::SetScannedFileCount(int Count) {
616     if (ScannedFileCount == Count) return;
617     ScannedFileCount = Count;
618     if (Count > TotalFileCount) TotalFileCount = Count;
619     StatusChanged();
620     }
621    
622     int ScanProgress::GetStatus() {
623     return Status;
624     }
625    
626     void ScanProgress::SetStatus(int Status) {
627     if (this->Status == Status) return;
628     if (Status < 0) this->Status = 0;
629     else if (Status > 100) this->Status = 100;
630     else this->Status = Status;
631     StatusChanged();
632     }
633    
634     void ScanProgress::SetErrorStatus(int Err) {
635     if (Err > 0) Err *= -1;
636     Status = Err;
637     StatusChanged();
638     }
639    
640     void ScanProgress::GigFileProgressCallback(gig::progress_t* pProgress) {
641     if (pProgress == NULL) return;
642     ScanProgress* sp = static_cast<ScanProgress*> (pProgress->custom);
643    
644     sp->SetStatus((int)(pProgress->factor * 100));
645     }
646    
647 iliev 1781 AddInstrumentsJob::AddInstrumentsJob(int JobId, ScanMode Mode, String DbDir, String FsDir, bool insDir) {
648 iliev 1200 this->JobId = JobId;
649     Progress.JobId = JobId;
650     this->Mode = Mode;
651     this->DbDir = DbDir;
652     this->FsDir = FsDir;
653 iliev 1781 this->insDir = insDir;
654 iliev 1200 }
655    
656     void AddInstrumentsJob::Run() {
657     try {
658     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
659    
660     switch (Mode) {
661     case NON_RECURSIVE:
662     Progress.SetTotalFileCount(GetFileCount());
663 iliev 1781 db->AddInstrumentsNonrecursive(DbDir, FsDir, insDir, &Progress);
664 iliev 1200 break;
665     case RECURSIVE:
666 iliev 1781 db->AddInstrumentsRecursive(DbDir, FsDir, false, insDir, &Progress);
667 iliev 1200 break;
668     case FLAT:
669 iliev 1781 db->AddInstrumentsRecursive(DbDir, FsDir, true, insDir, &Progress);
670 iliev 1200 break;
671     default:
672     throw Exception("Unknown scan mode");
673     }
674 iliev 1208
675     // Just to be sure that the frontends will be notified about the job completion
676     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
677     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
678     }
679     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
680 iliev 1200 } catch(Exception e) {
681     Progress.SetErrorStatus(-1);
682 schoenebeck 3705 throw; // re-throw
683 iliev 1200 }
684     }
685    
686     int AddInstrumentsJob::GetFileCount() {
687     int count = 0;
688    
689 iliev 1717 try {
690     FileListPtr fileList = File::GetFiles(FsDir);
691 iliev 1200
692 iliev 1717 for (int i = 0; i < fileList->size(); i++) {
693     String s = fileList->at(i);
694 schoenebeck 3092 if (InstrumentFileInfo::isSupportedFile(s)) count++;
695 iliev 1200 }
696 iliev 1717 } catch(Exception e) {
697     e.PrintMessage();
698     return 0;
699 iliev 1200 }
700    
701     return count;
702     }
703    
704 iliev 1781 AddInstrumentsFromFileJob::AddInstrumentsFromFileJob(int JobId, String DbDir, String FilePath, int Index, bool insDir) {
705 iliev 1200 this->JobId = JobId;
706     Progress.JobId = JobId;
707     Progress.SetTotalFileCount(1);
708    
709     this->DbDir = DbDir;
710     this->FilePath = FilePath;
711     this->Index = Index;
712 iliev 1781 this->insDir = insDir;
713 iliev 1200 }
714    
715     void AddInstrumentsFromFileJob::Run() {
716 iliev 1208 try {
717 iliev 1781 InstrumentsDb::GetInstrumentsDb()->AddInstruments(DbDir, insDir, FilePath, Index, &Progress);
718 iliev 1208
719     // Just to be sure that the frontends will be notified about the job completion
720     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
721     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
722     }
723     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
724     } catch(Exception e) {
725     Progress.SetErrorStatus(-1);
726 schoenebeck 3705 throw; // re-throw
727 iliev 1208 }
728 iliev 1200 }
729    
730    
731 iliev 1781 void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {
732     dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat, insDir));
733 iliev 1200 if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected");
734    
735 iliev 1717 this->DbDir = DbDir;
736     this->FsDir = FsDir;
737 iliev 1781 this->insDir = insDir;
738 iliev 1200 if (DbDir.at(DbDir.length() - 1) != '/') {
739 iliev 1717 this->DbDir.append("/");
740 iliev 1200 }
741 iliev 1717 if (FsDir.at(FsDir.length() - 1) != File::DirSeparator) {
742     this->FsDir.push_back(File::DirSeparator);
743 iliev 1200 }
744 iliev 1717 this->Flat = Flat;
745     this->pProgress = pProgress;
746 iliev 1200
747 iliev 1717 File::WalkDirectoryTree(FsDir, this);
748 iliev 1200 }
749    
750 iliev 1717 void DirectoryScanner::DirectoryEntry(std::string Path) {
751     dmsg(2,("DirectoryScanner: DirectoryEntry(Path=%s)\n", Path.c_str()));
752 iliev 1200
753     String dir = DbDir;
754     if (!Flat) {
755 iliev 1717 String subdir = Path;
756 iliev 1200 if(subdir.length() > FsDir.length()) {
757     subdir = subdir.substr(FsDir.length());
758 persson 1943 #ifdef WIN32
759     replace(subdir.begin(), subdir.end(), '\\', '/');
760     #endif
761 iliev 1200 dir += subdir;
762     }
763     }
764    
765     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
766    
767 iliev 1717 if (HasInstrumentFiles(Path)) {
768 iliev 1208 if (!db->DirectoryExist(dir)) db->AddDirectory(dir);
769 iliev 1781 db->AddInstrumentsNonrecursive(dir, Path, insDir, pProgress);
770 iliev 1208 }
771 iliev 1200 };
772    
773 iliev 1208 bool DirectoryScanner::HasInstrumentFiles(String Dir) {
774 iliev 1717 InstrumentFileCounter c;
775     return c.Count(Dir) > 0;
776 iliev 1208 }
777    
778 iliev 1200 int InstrumentFileCounter::Count(String FsDir) {
779     dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str()));
780     if (FsDir.empty()) throw Exception("Directory expected");
781     FileCount = 0;
782    
783 iliev 1717 File::WalkDirectoryTree(FsDir, this);
784 iliev 1200 return FileCount;
785     }
786    
787 iliev 1717 void InstrumentFileCounter::FileEntry(std::string Path) {
788 iliev 1781 dmsg(2,("InstrumentFileCounter: FileEntry(Path=%s)\n", Path.c_str()));
789 schoenebeck 3092 if (InstrumentFileInfo::isSupportedFile(Path)) FileCount++;
790 iliev 1200 };
791    
792 schoenebeck 3092
793     InstrumentFileInfo* InstrumentFileInfo::getFileInfoFor(String filename) {
794     if (filename.length() < 4) return NULL;
795     String fileExtension = filename.substr(filename.length() - 4);
796     if (!strcasecmp(".gig", fileExtension.c_str()))
797     return new GigFileInfo(filename);
798     if (!strcasecmp(".sfz", fileExtension.c_str()))
799     return new SFZFileInfo(filename);
800     #if HAVE_SF2
801     if (!strcasecmp(".sf2", fileExtension.c_str()))
802     return new Sf2FileInfo(filename);
803     #endif
804     return NULL;
805     }
806    
807     bool InstrumentFileInfo::isSupportedFile(String filename) {
808     if (filename.length() < 4) return false;
809     String fileExtension = filename.substr(filename.length() - 4);
810     if (!strcasecmp(".gig", fileExtension.c_str())) return true;
811     if (!strcasecmp(".sfz", fileExtension.c_str())) return true;
812     #if HAVE_SF2
813     if (!strcasecmp(".sf2", fileExtension.c_str())) return true;
814     #endif
815     return false;
816     }
817    
818 iliev 1200 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC