/[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 1424 - (hide annotations) (download)
Sun Oct 14 22:00:17 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 22387 byte(s)
* code cleanup:
- global.h now only covers global definitions that are needed for the C++
  API header files, all implementation internal global definitions are now
  in global_private.h
- atomic.h is not exposed to the C++ API anymore (replaced the references
  in SynchronizedConfig.h for this with local definitions)
- no need to include config.h anymore for using LS's API header files
- DB instruments classes are not exposed to the C++ API
- POSIX callback functions of Thread.h are hidden
- the (optional) gig Engine benchmark compiles again
- updated Doxyfile.in
- fixed warnings in API doc generation
* preparations for release 0.5.0

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 schoenebeck 1424 #include "../common/global_private.h"
24 iliev 1200
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 iliev 1345 pDirectories->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
258 iliev 1200 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 iliev 1345 pInstruments->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
343 iliev 1200 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 iliev 1345 if(dstDirId == -1) {
395     throw Exception("Unkown DB directory: " + InstrumentsDb::toEscapedPath(dir));
396     }
397 iliev 1200 IntListPtr ids = db->GetInstrumentIDs(DirId);
398     for (int i = 0; i < ids->size(); i++) {
399     String name = db->GetInstrumentName(ids->at(i));
400     db->CopyInstrument(ids->at(i), name, dstDirId, dir);
401     }
402     }
403    
404     ScanProgress::ScanProgress() {
405     TotalFileCount = ScannedFileCount = Status = 0;
406     CurrentFile = "";
407     GigFileProgress.custom = this;
408     GigFileProgress.callback = GigFileProgressCallback;
409     }
410    
411     void ScanProgress::StatusChanged() {
412     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
413     db->Jobs.GetJobById(JobId).FilesTotal = GetTotalFileCount();
414     db->Jobs.GetJobById(JobId).FilesScanned = GetScannedFileCount();
415     db->Jobs.GetJobById(JobId).Scanning = CurrentFile;
416     db->Jobs.GetJobById(JobId).Status = GetStatus();
417    
418     InstrumentsDb::GetInstrumentsDb()->FireJobStatusChanged(JobId);
419     }
420    
421     int ScanProgress::GetTotalFileCount() {
422     return TotalFileCount;
423     }
424    
425     void ScanProgress::SetTotalFileCount(int Count) {
426     if (TotalFileCount == Count) return;
427     TotalFileCount = Count;
428     StatusChanged();
429     }
430    
431     int ScanProgress::GetScannedFileCount() {
432     return ScannedFileCount;
433     }
434    
435     void ScanProgress::SetScannedFileCount(int Count) {
436     if (ScannedFileCount == Count) return;
437     ScannedFileCount = Count;
438     if (Count > TotalFileCount) TotalFileCount = Count;
439     StatusChanged();
440     }
441    
442     int ScanProgress::GetStatus() {
443     return Status;
444     }
445    
446     void ScanProgress::SetStatus(int Status) {
447     if (this->Status == Status) return;
448     if (Status < 0) this->Status = 0;
449     else if (Status > 100) this->Status = 100;
450     else this->Status = Status;
451     StatusChanged();
452     }
453    
454     void ScanProgress::SetErrorStatus(int Err) {
455     if (Err > 0) Err *= -1;
456     Status = Err;
457     StatusChanged();
458     }
459    
460     void ScanProgress::GigFileProgressCallback(gig::progress_t* pProgress) {
461     if (pProgress == NULL) return;
462     ScanProgress* sp = static_cast<ScanProgress*> (pProgress->custom);
463    
464     sp->SetStatus((int)(pProgress->factor * 100));
465     }
466    
467     AddInstrumentsJob::AddInstrumentsJob(int JobId, ScanMode Mode, String DbDir, String FsDir) {
468     this->JobId = JobId;
469     Progress.JobId = JobId;
470     this->Mode = Mode;
471     this->DbDir = DbDir;
472     this->FsDir = FsDir;
473     }
474    
475     void AddInstrumentsJob::Run() {
476     try {
477     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
478    
479     switch (Mode) {
480     case NON_RECURSIVE:
481     Progress.SetTotalFileCount(GetFileCount());
482     db->AddInstrumentsNonrecursive(DbDir, FsDir, &Progress);
483     break;
484     case RECURSIVE:
485     db->AddInstrumentsRecursive(DbDir, FsDir, false, &Progress);
486     break;
487     case FLAT:
488     db->AddInstrumentsRecursive(DbDir, FsDir, true, &Progress);
489     break;
490     default:
491     throw Exception("Unknown scan mode");
492     }
493 iliev 1208
494     // Just to be sure that the frontends will be notified about the job completion
495     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
496     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
497     }
498     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
499 iliev 1200 } catch(Exception e) {
500     Progress.SetErrorStatus(-1);
501     throw e;
502     }
503     }
504    
505     int AddInstrumentsJob::GetFileCount() {
506     int count = 0;
507    
508     DIR* pDir = opendir(FsDir.c_str());
509     if (pDir == NULL) {
510     std::stringstream ss;
511     ss << "The scanning of directory `" << FsDir << "` failed: ";
512     ss << strerror(errno);
513     std::cerr << ss.str();
514     return 0;
515     }
516    
517     struct dirent* pEnt = readdir(pDir);
518     while (pEnt != NULL) {
519     if (pEnt->d_type != DT_REG) {
520     pEnt = readdir(pDir);
521     continue;
522     }
523    
524 iliev 1208 String s(pEnt->d_name);
525     if(s.length() < 4) {
526     pEnt = readdir(pDir);
527     continue;
528     }
529     if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) count++;
530    
531 iliev 1200 pEnt = readdir(pDir);
532     }
533    
534     if (closedir(pDir)) {
535     std::stringstream ss;
536     ss << "Failed to close directory `" << FsDir << "`: ";
537     ss << strerror(errno);
538     std::cerr << ss.str();
539     }
540    
541     return count;
542     }
543    
544     AddInstrumentsFromFileJob::AddInstrumentsFromFileJob(int JobId, String DbDir, String FilePath, int Index) {
545     this->JobId = JobId;
546     Progress.JobId = JobId;
547     Progress.SetTotalFileCount(1);
548    
549     this->DbDir = DbDir;
550     this->FilePath = FilePath;
551     this->Index = Index;
552     }
553    
554     void AddInstrumentsFromFileJob::Run() {
555 iliev 1208 try {
556     InstrumentsDb::GetInstrumentsDb()->AddInstruments(DbDir, FilePath, Index, &Progress);
557    
558     // Just to be sure that the frontends will be notified about the job completion
559     if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
560     Progress.SetTotalFileCount(Progress.GetScannedFileCount());
561     }
562     if (Progress.GetStatus() != 100) Progress.SetStatus(100);
563     } catch(Exception e) {
564     Progress.SetErrorStatus(-1);
565     throw e;
566     }
567 iliev 1200 }
568    
569    
570     String DirectoryScanner::DbDir;
571     String DirectoryScanner::FsDir;
572     bool DirectoryScanner::Flat;
573     ScanProgress* DirectoryScanner::pProgress;
574    
575     void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {
576     dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat));
577     if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected");
578    
579     struct stat statBuf;
580     int res = stat(FsDir.c_str(), &statBuf);
581     if (res) {
582     std::stringstream ss;
583     ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);
584     throw Exception(ss.str());
585     }
586    
587     if (!S_ISDIR(statBuf.st_mode)) {
588     throw Exception("Directory expected");
589     }
590    
591     DirectoryScanner::DbDir = DbDir;
592     DirectoryScanner::FsDir = FsDir;
593     if (DbDir.at(DbDir.length() - 1) != '/') {
594     DirectoryScanner::DbDir.append("/");
595     }
596     if (FsDir.at(FsDir.length() - 1) != '/') {
597     DirectoryScanner::FsDir.append("/");
598     }
599     DirectoryScanner::Flat = Flat;
600     DirectoryScanner::pProgress = pProgress;
601    
602     ftw(FsDir.c_str(), FtwCallback, 10);
603     }
604    
605     int DirectoryScanner::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
606     dmsg(2,("DirectoryScanner: FtwCallback(fpath=%s)\n", fpath));
607     if (typeflag != FTW_D) return 0;
608    
609     String dir = DbDir;
610     if (!Flat) {
611     String subdir = fpath;
612     if(subdir.length() > FsDir.length()) {
613     subdir = subdir.substr(FsDir.length());
614     dir += subdir;
615     }
616     }
617    
618     InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
619    
620 iliev 1208 if (HasInstrumentFiles(String(fpath))) {
621     if (!db->DirectoryExist(dir)) db->AddDirectory(dir);
622     db->AddInstrumentsNonrecursive(dir, String(fpath), pProgress);
623     }
624 iliev 1200
625     return 0;
626     };
627    
628 iliev 1208 bool DirectoryScanner::HasInstrumentFiles(String Dir) {
629     return InstrumentFileCounter::Count(Dir) > 0;
630     }
631    
632 iliev 1200 int InstrumentFileCounter::FileCount;
633    
634     int InstrumentFileCounter::Count(String FsDir) {
635     dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str()));
636     if (FsDir.empty()) throw Exception("Directory expected");
637     FileCount = 0;
638    
639     struct stat statBuf;
640     int res = stat(FsDir.c_str(), &statBuf);
641     if (res) {
642     std::stringstream ss;
643     ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);
644     throw Exception(ss.str());
645     }
646    
647     if (!S_ISDIR(statBuf.st_mode)) {
648     throw Exception("Directory expected");
649     }
650    
651     ftw(FsDir.c_str(), FtwCallback, 10);
652     return FileCount;
653     }
654    
655     int InstrumentFileCounter::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
656     if (typeflag != FTW_F) return 0;
657     String s = fpath;
658     if(s.length() < 4) return 0;
659     if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) FileCount++;
660 iliev 1208
661 iliev 1200 return 0;
662     };
663    
664     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC