/[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 1208 - (hide annotations) (download)
Sat May 26 22:20:46 2007 UTC (16 years, 10 months ago) by iliev
File size: 22294 byte(s)
* added --instruments-db-location command line switch
* fixed bug regarding the scanning progress notifications
* directories containing no instrument files are now not re-created
  in the instruments databese when recursive scan is performed

1 iliev 1200 /***************************************************************************
2     * *
3     * Copyright (C) 2007 Grigor Iliev *
4     * *
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     #if HAVE_SQLITE3
24    
25     #include <dirent.h>
26     #include <errno.h>
27     #include <ftw.h>
28    
29     #include "../common/Exception.h"
30     #include "InstrumentsDb.h"
31    
32     namespace LinuxSampler {
33    
34     void DbInstrument::Copy(const DbInstrument& Instr) {
35     if (this == &Instr) return;
36    
37     InstrFile = Instr.InstrFile;
38     InstrNr = Instr.InstrNr;
39     FormatFamily = Instr.FormatFamily;
40     FormatVersion = Instr.FormatVersion;
41     Size = Instr.Size;
42     Created = Instr.Created;
43     Modified = Instr.Modified;
44     Description = Instr.Description;
45     IsDrum = Instr.IsDrum;
46     Product = Instr.Product;
47     Artists = Instr.Artists;
48     Keywords = Instr.Keywords;
49     }
50    
51    
52     void DbDirectory::Copy(const DbDirectory& Dir) {
53     if (this == &Dir) return;
54    
55     Created = Dir.Created;
56     Modified = Dir.Modified;
57     Description = Dir.Description;
58     }
59    
60     SearchQuery::SearchQuery() {
61     MinSize = -1;
62     MaxSize = -1;
63     InstrType = BOTH;
64     }
65    
66     void SearchQuery::SetFormatFamilies(String s) {
67     if (s.length() == 0) return;
68     int i = 0;
69     int j = s.find(',', 0);
70    
71     while (j != std::string::npos) {
72     FormatFamilies.push_back(s.substr(i, j - i));
73     i = j + 1;
74     j = s.find(',', i);
75     }
76    
77     if (i < s.length()) FormatFamilies.push_back(s.substr(i));
78     }
79    
80     void SearchQuery::SetSize(String s) {
81     String s2 = GetMin(s);
82     if (s2.length() > 0) MinSize = atoll(s2.c_str());
83     else MinSize = -1;
84    
85     s2 = GetMax(s);
86     if (s2.length() > 0) MaxSize = atoll(s2.c_str());
87     else MaxSize = -1;
88     }
89    
90     void SearchQuery::SetCreated(String s) {
91     CreatedAfter = GetMin(s);
92     CreatedBefore = GetMax(s);
93     }
94    
95     void SearchQuery::SetModified(String s) {
96     ModifiedAfter = GetMin(s);
97     ModifiedBefore = GetMax(s);
98     }
99    
100     String SearchQuery::GetMin(String s) {
101     if (s.length() < 3) return "";
102     if (s.at(0) == '.' && s.at(1) == '.') return "";
103     int i = s.find("..");
104     if (i == std::string::npos) return "";
105     return s.substr(0, i);
106     }
107    
108     String SearchQuery::GetMax(String s) {
109     if (s.length() < 3) return "";
110     if (s.find("..", s.length() - 2) != std::string::npos) return "";
111     int i = s.find("..");
112     if (i == std::string::npos) return "";
113     return s.substr(i + 2);
114     }
115    
116     void ScanJob::Copy(const ScanJob& Job) {
117     if (this == &Job) return;
118    
119     JobId = Job.JobId;
120     FilesTotal = Job.FilesTotal;
121     FilesScanned = Job.FilesScanned;
122     Scanning = Job.Scanning;
123     Status = Job.Status;
124     }
125    
126     int JobList::AddJob(ScanJob Job) {
127     if (Counter + 1 < Counter) Counter = 0;
128     else Counter++;
129     Job.JobId = Counter;
130     Jobs.push_back(Job);
131     if (Jobs.size() > 3) {
132     std::vector<ScanJob>::iterator iter = Jobs.begin();
133     Jobs.erase(iter);
134     }
135     return Job.JobId;
136     }
137    
138     ScanJob& JobList::GetJobById(int JobId) {
139     for (int i = 0; i < Jobs.size(); i++) {
140     if (Jobs.at(i).JobId == JobId) return Jobs.at(i);
141     }
142    
143     throw Exception("Invalid job ID: " + ToString(JobId));
144     }
145    
146     bool AbstractFinder::IsRegex(String Pattern) {
147     if(Pattern.find('?') != String::npos) return true;
148     if(Pattern.find('*') != String::npos) return true;
149     return false;
150     }
151    
152     void AbstractFinder::AddSql(String Col, String Pattern, std::stringstream& Sql) {
153     if (Pattern.length() == 0) return;
154    
155     if (IsRegex(Pattern)) {
156     Sql << " AND " << Col << " regexp ?";
157     Params.push_back(Pattern);
158     return;
159     }
160    
161     String buf;
162     std::vector<String> tokens;
163     std::vector<String> tokens2;
164     std::stringstream ss(Pattern);
165     while (ss >> buf) tokens.push_back(buf);
166    
167     if (tokens.size() == 0) {
168     Sql << " AND " << Col << " LIKE ?";
169     Params.push_back("%" + Pattern + "%");
170     return;
171     }
172    
173     bool b = false;
174     for (int i = 0; i < tokens.size(); i++) {
175     Sql << (i == 0 ? " AND (" : "");
176    
177     for (int j = 0; j < tokens.at(i).length(); j++) {
178     if (tokens.at(i).at(j) == '+') tokens.at(i).at(j) = ' ';
179     }
180    
181     ss.clear();
182     ss.str("");
183     ss << tokens.at(i);
184    
185     tokens2.clear();
186     while (ss >> buf) tokens2.push_back(buf);
187    
188     if (b && tokens2.size() > 0) Sql << " OR ";
189     if (tokens2.size() > 1) Sql << "(";
190     for (int j = 0; j < tokens2.size(); j++) {
191     if (j != 0) Sql << " AND ";
192     Sql << Col << " LIKE ?";
193     Params.push_back("%" + tokens2.at(j) + "%");
194     b = true;
195     }
196     if (tokens2.size() > 1) Sql << ")";
197     }
198     if (!b) Sql << "0)";
199     else Sql << ")";
200     }
201    
202     DirectoryFinder::DirectoryFinder(SearchQuery* pQuery) : pDirectories(new std::vector<String>) {
203     pStmt = NULL;
204     this->pQuery = pQuery;
205     std::stringstream sql;
206     sql << "SELECT dir_name from instr_dirs WHERE dir_id!=0 AND parent_dir_id=?";
207    
208     if (pQuery->CreatedAfter.length() != 0) {
209     sql << " AND created > ?";
210     Params.push_back(pQuery->CreatedAfter);
211     }
212     if (pQuery->CreatedBefore.length() != 0) {
213     sql << " AND created < ?";
214     Params.push_back(pQuery->CreatedBefore);
215     }
216     if (pQuery->ModifiedAfter.length() != 0) {
217     sql << " AND modified > ?";
218     Params.push_back(pQuery->ModifiedAfter);
219     }
220     if (pQuery->ModifiedBefore.length() != 0) {
221     sql << " AND modified < ?";
222     Params.push_back(pQuery->ModifiedBefore);
223     }
224    
225     AddSql("dir_name", pQuery->Name, sql);
226     AddSql("description", pQuery->Description, sql);
227     SqlQuery = sql.str();
228    
229     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
230    
231     int res = sqlite3_prepare(idb->GetDb(), SqlQuery.c_str(), -1, &pStmt, NULL);
232     if (res != SQLITE_OK) {
233     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
234     }
235    
236     for(int i = 0; i < Params.size(); i++) {
237     idb->BindTextParam(pStmt, i + 2, Params.at(i));
238     }
239     }
240    
241     DirectoryFinder::~DirectoryFinder() {
242     if (pStmt != NULL) sqlite3_finalize(pStmt);
243     }
244    
245     StringListPtr DirectoryFinder::GetDirectories() {
246     return pDirectories;
247     }
248    
249     void DirectoryFinder::ProcessDirectory(String Path, int DirId) {
250     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
251     idb->BindIntParam(pStmt, 1, DirId);
252    
253     String s = Path;
254     if(Path.compare("/") != 0) s += "/";
255     int res = sqlite3_step(pStmt);
256     while(res == SQLITE_ROW) {
257     pDirectories->push_back(s + ToString(sqlite3_column_text(pStmt, 0)));
258     res = sqlite3_step(pStmt);
259     }
260    
261     if (res != SQLITE_DONE) {
262     sqlite3_finalize(pStmt);
263     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
264     }
265    
266     res = sqlite3_reset(pStmt);
267     if (res != SQLITE_OK) {
268     sqlite3_finalize(pStmt);
269     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
270     }
271     }
272    
273     InstrumentFinder::InstrumentFinder(SearchQuery* pQuery) : pInstruments(new std::vector<String>) {
274     pStmt = NULL;
275     this->pQuery = pQuery;
276     std::stringstream sql;
277     sql << "SELECT instr_name from instruments WHERE dir_id=?";
278    
279     if (pQuery->CreatedAfter.length() != 0) {
280     sql << " AND created > ?";
281     Params.push_back(pQuery->CreatedAfter);
282     }
283     if (pQuery->CreatedBefore.length() != 0) {
284     sql << " AND created < ?";
285     Params.push_back(pQuery->CreatedBefore);
286     }
287     if (pQuery->ModifiedAfter.length() != 0) {
288     sql << " AND modified > ?";
289     Params.push_back(pQuery->ModifiedAfter);
290     }
291     if (pQuery->ModifiedBefore.length() != 0) {
292     sql << " AND modified < ?";
293     Params.push_back(pQuery->ModifiedBefore);
294     }
295     if (pQuery->MinSize != -1) sql << " AND instr_size > " << pQuery->MinSize;
296     if (pQuery->MaxSize != -1) sql << " AND instr_size < " << pQuery->MaxSize;
297    
298     if (pQuery->InstrType == SearchQuery::CHROMATIC) sql << " AND is_drum = 0";
299     else if (pQuery->InstrType == SearchQuery::DRUM) sql << " AND is_drum != 0";
300    
301     if (pQuery->FormatFamilies.size() > 0) {
302     sql << " AND (format_family=?";
303     Params.push_back(pQuery->FormatFamilies.at(0));
304     for (int i = 1; i < pQuery->FormatFamilies.size(); i++) {
305     sql << "OR format_family=?";
306     Params.push_back(pQuery->FormatFamilies.at(i));
307     }
308     sql << ")";
309     }
310    
311     AddSql("instr_name", pQuery->Name, sql);
312     AddSql("description", pQuery->Description, sql);
313     AddSql("product", pQuery->Product, sql);
314     AddSql("artists", pQuery->Artists, sql);
315     AddSql("keywords", pQuery->Keywords, sql);
316     SqlQuery = sql.str();
317    
318     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
319    
320     int res = sqlite3_prepare(idb->GetDb(), SqlQuery.c_str(), -1, &pStmt, NULL);
321     if (res != SQLITE_OK) {
322     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
323     }
324    
325     for(int i = 0; i < Params.size(); i++) {
326     idb->BindTextParam(pStmt, i + 2, Params.at(i));
327     }
328     }
329    
330     InstrumentFinder::~InstrumentFinder() {
331     if (pStmt != NULL) sqlite3_finalize(pStmt);
332     }
333    
334     void InstrumentFinder::ProcessDirectory(String Path, int DirId) {
335     InstrumentsDb* idb = InstrumentsDb::GetInstrumentsDb();
336     idb->BindIntParam(pStmt, 1, DirId);
337    
338     String s = Path;
339     if(Path.compare("/") != 0) s += "/";
340     int res = sqlite3_step(pStmt);
341     while(res == SQLITE_ROW) {
342     pInstruments->push_back(s + ToString(sqlite3_column_text(pStmt, 0)));
343     res = sqlite3_step(pStmt);
344     }
345    
346     if (res != SQLITE_DONE) {
347     sqlite3_finalize(pStmt);
348     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
349     }
350    
351     res = sqlite3_reset(pStmt);
352     if (res != SQLITE_OK) {
353     sqlite3_finalize(pStmt);
354     throw Exception("DB error: " + ToString(sqlite3_errmsg(idb->GetDb())));
355     }
356     }
357    
358     StringListPtr InstrumentFinder::GetInstruments() {
359     return pInstruments;
360     }
361    
362     void DirectoryCounter::ProcessDirectory(String Path, int DirId) {
363     count += InstrumentsDb::GetInstrumentsDb()->GetDirectoryCount(DirId);
364     }
365    
366     void InstrumentCounter::ProcessDirectory(String Path, int DirId) {
367     count += InstrumentsDb::GetInstrumentsDb()->GetInstrumentCount(DirId);
368     }
369    
370     DirectoryCopier::DirectoryCopier(String SrcParentDir, String DestDir) {
371     this->SrcParentDir = SrcParentDir;
372     this->DestDir = DestDir;
373    
374     if (DestDir.at(DestDir.length() - 1) != '/') {
375     this->DestDir.append("/");
376     }
377     if (SrcParentDir.at(SrcParentDir.length() - 1) != '/') {
378     this->SrcParentDir.append("/");
379     }
380     }
381    
382     void DirectoryCopier::ProcessDirectory(String Path, int DirId) {
383     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
384    
385     String dir = DestDir;
386     String subdir = Path;
387     if(subdir.length() > SrcParentDir.length()) {
388     subdir = subdir.substr(SrcParentDir.length());
389     dir += subdir;
390     db->AddDirectory(dir);
391     }
392    
393     int dstDirId = db->GetDirectoryId(dir);
394     if(dstDirId == -1) throw Exception("Unkown DB directory: " + dir);
395     IntListPtr ids = db->GetInstrumentIDs(DirId);
396     for (int i = 0; i < ids->size(); i++) {
397     String name = db->GetInstrumentName(ids->at(i));
398     db->CopyInstrument(ids->at(i), name, dstDirId, dir);
399     }
400     }
401    
402     ScanProgress::ScanProgress() {
403     TotalFileCount = ScannedFileCount = Status = 0;
404     CurrentFile = "";
405     GigFileProgress.custom = this;
406     GigFileProgress.callback = GigFileProgressCallback;
407     }
408    
409     void ScanProgress::StatusChanged() {
410     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
411     db->Jobs.GetJobById(JobId).FilesTotal = GetTotalFileCount();
412     db->Jobs.GetJobById(JobId).FilesScanned = GetScannedFileCount();
413     db->Jobs.GetJobById(JobId).Scanning = CurrentFile;
414     db->Jobs.GetJobById(JobId).Status = GetStatus();
415    
416     InstrumentsDb::GetInstrumentsDb()->FireJobStatusChanged(JobId);
417     }
418    
419     int ScanProgress::GetTotalFileCount() {
420     return TotalFileCount;
421     }
422    
423     void ScanProgress::SetTotalFileCount(int Count) {
424     if (TotalFileCount == Count) return;
425     TotalFileCount = Count;
426     StatusChanged();
427     }
428    
429     int ScanProgress::GetScannedFileCount() {
430     return ScannedFileCount;
431     }
432    
433     void ScanProgress::SetScannedFileCount(int Count) {
434     if (ScannedFileCount == Count) return;
435     ScannedFileCount = Count;
436     if (Count > TotalFileCount) TotalFileCount = Count;
437     StatusChanged();
438     }
439    
440     int ScanProgress::GetStatus() {
441     return Status;
442     }
443    
444     void ScanProgress::SetStatus(int Status) {
445     if (this->Status == Status) return;
446     if (Status < 0) this->Status = 0;
447     else if (Status > 100) this->Status = 100;
448     else this->Status = Status;
449     StatusChanged();
450     }
451    
452     void ScanProgress::SetErrorStatus(int Err) {
453     if (Err > 0) Err *= -1;
454     Status = Err;
455     StatusChanged();
456     }
457    
458     void ScanProgress::GigFileProgressCallback(gig::progress_t* pProgress) {
459     if (pProgress == NULL) return;
460     ScanProgress* sp = static_cast<ScanProgress*> (pProgress->custom);
461    
462     sp->SetStatus((int)(pProgress->factor * 100));
463     }
464    
465     AddInstrumentsJob::AddInstrumentsJob(int JobId, ScanMode Mode, String DbDir, String FsDir) {
466     this->JobId = JobId;
467     Progress.JobId = JobId;
468     this->Mode = Mode;
469     this->DbDir = DbDir;
470     this->FsDir = FsDir;
471     }
472    
473     void AddInstrumentsJob::Run() {
474     try {
475     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
476    
477     switch (Mode) {
478     case NON_RECURSIVE:
479     Progress.SetTotalFileCount(GetFileCount());
480     db->AddInstrumentsNonrecursive(DbDir, FsDir, &Progress);
481     break;
482     case RECURSIVE:
483     db->AddInstrumentsRecursive(DbDir, FsDir, false, &Progress);
484     break;
485     case FLAT:
486     db->AddInstrumentsRecursive(DbDir, FsDir, true, &Progress);
487     break;
488     default:
489     throw Exception("Unknown scan mode");
490     }
491 iliev 1208
492     // Just to be sure that the frontends will be notified about the job completion
493     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
494     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
495     }
496     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
497 iliev 1200 } catch(Exception e) {
498     Progress.SetErrorStatus(-1);
499     throw e;
500     }
501     }
502    
503     int AddInstrumentsJob::GetFileCount() {
504     int count = 0;
505    
506     DIR* pDir = opendir(FsDir.c_str());
507     if (pDir == NULL) {
508     std::stringstream ss;
509     ss << "The scanning of directory `" << FsDir << "` failed: ";
510     ss << strerror(errno);
511     std::cerr << ss.str();
512     return 0;
513     }
514    
515     struct dirent* pEnt = readdir(pDir);
516     while (pEnt != NULL) {
517     if (pEnt->d_type != DT_REG) {
518     pEnt = readdir(pDir);
519     continue;
520     }
521    
522 iliev 1208 String s(pEnt->d_name);
523     if(s.length() < 4) {
524     pEnt = readdir(pDir);
525     continue;
526     }
527     if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) count++;
528    
529 iliev 1200 pEnt = readdir(pDir);
530     }
531    
532     if (closedir(pDir)) {
533     std::stringstream ss;
534     ss << "Failed to close directory `" << FsDir << "`: ";
535     ss << strerror(errno);
536     std::cerr << ss.str();
537     }
538    
539     return count;
540     }
541    
542     AddInstrumentsFromFileJob::AddInstrumentsFromFileJob(int JobId, String DbDir, String FilePath, int Index) {
543     this->JobId = JobId;
544     Progress.JobId = JobId;
545     Progress.SetTotalFileCount(1);
546    
547     this->DbDir = DbDir;
548     this->FilePath = FilePath;
549     this->Index = Index;
550     }
551    
552     void AddInstrumentsFromFileJob::Run() {
553 iliev 1208 try {
554     InstrumentsDb::GetInstrumentsDb()->AddInstruments(DbDir, FilePath, Index, &Progress);
555    
556     // Just to be sure that the frontends will be notified about the job completion
557     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
558     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
559     }
560     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
561     } catch(Exception e) {
562     Progress.SetErrorStatus(-1);
563     throw e;
564     }
565 iliev 1200 }
566    
567    
568     String DirectoryScanner::DbDir;
569     String DirectoryScanner::FsDir;
570     bool DirectoryScanner::Flat;
571     ScanProgress* DirectoryScanner::pProgress;
572    
573     void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {
574     dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat));
575     if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected");
576    
577     struct stat statBuf;
578     int res = stat(FsDir.c_str(), &statBuf);
579     if (res) {
580     std::stringstream ss;
581     ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);
582     throw Exception(ss.str());
583     }
584    
585     if (!S_ISDIR(statBuf.st_mode)) {
586     throw Exception("Directory expected");
587     }
588    
589     DirectoryScanner::DbDir = DbDir;
590     DirectoryScanner::FsDir = FsDir;
591     if (DbDir.at(DbDir.length() - 1) != '/') {
592     DirectoryScanner::DbDir.append("/");
593     }
594     if (FsDir.at(FsDir.length() - 1) != '/') {
595     DirectoryScanner::FsDir.append("/");
596     }
597     DirectoryScanner::Flat = Flat;
598     DirectoryScanner::pProgress = pProgress;
599    
600     ftw(FsDir.c_str(), FtwCallback, 10);
601     }
602    
603     int DirectoryScanner::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
604     dmsg(2,("DirectoryScanner: FtwCallback(fpath=%s)\n", fpath));
605     if (typeflag != FTW_D) return 0;
606    
607     String dir = DbDir;
608     if (!Flat) {
609     String subdir = fpath;
610     if(subdir.length() > FsDir.length()) {
611     subdir = subdir.substr(FsDir.length());
612     dir += subdir;
613     }
614     }
615    
616     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
617    
618 iliev 1208 if (HasInstrumentFiles(String(fpath))) {
619     if (!db->DirectoryExist(dir)) db->AddDirectory(dir);
620     db->AddInstrumentsNonrecursive(dir, String(fpath), pProgress);
621     }
622 iliev 1200
623     return 0;
624     };
625    
626 iliev 1208 bool DirectoryScanner::HasInstrumentFiles(String Dir) {
627     return InstrumentFileCounter::Count(Dir) > 0;
628     }
629    
630 iliev 1200 int InstrumentFileCounter::FileCount;
631    
632     int InstrumentFileCounter::Count(String FsDir) {
633     dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str()));
634     if (FsDir.empty()) throw Exception("Directory expected");
635     FileCount = 0;
636    
637     struct stat statBuf;
638     int res = stat(FsDir.c_str(), &statBuf);
639     if (res) {
640     std::stringstream ss;
641     ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);
642     throw Exception(ss.str());
643     }
644    
645     if (!S_ISDIR(statBuf.st_mode)) {
646     throw Exception("Directory expected");
647     }
648    
649     ftw(FsDir.c_str(), FtwCallback, 10);
650     return FileCount;
651     }
652    
653     int InstrumentFileCounter::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
654     if (typeflag != FTW_F) return 0;
655     String s = fpath;
656     if(s.length() < 4) return 0;
657     if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) FileCount++;
658 iliev 1208
659 iliev 1200 return 0;
660     };
661    
662     } // namespace LinuxSampler
663    
664     #endif // HAVE_SQLITE3

  ViewVC Help
Powered by ViewVC