disable the unrecognized nls and x flags
[AROS-Contrib.git] / FryingPan / DTLib / rCUESession.cpp
blobc93c0fbad9f529abc23997d59d635e6cfd714e7a
1 /*
2 * FryingPan - Amiga CD/DVD Recording Software (User Interface and supporting Libraries only)
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (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 Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "rCUESession.h"
21 #include <Generic/LibrarySpool.h>
22 #include <libclass/dos.h>
23 #include <Optical/IOptItem.h>
24 #include "Main.h"
27 class file
29 public:
30 enum filetype
32 Type_Unknown,
33 Type_Intel,
34 Type_Motorola,
35 Type_Wave,
36 Type_AIFF,
37 Type_MP3
40 protected:
41 String filename;
42 uint32 length;
43 filetype type;
44 BPTR fileptr;
46 private:
47 file()
49 fileptr = 0;
50 type = Type_Unknown;
51 length = 0;
52 filename = "";
55 file(const file&) {};
57 public:
59 static file *newFile(const String &cue_location, const String &filename, const String &type)
61 BPTR fileptr;
62 String path;
63 FileInfoBlock *fib;
64 file *f;
66 path = cue_location;
67 path.AddPath(filename);
69 fileptr = DOS->Open(path.Data(), MODE_OLDFILE);
70 if (fileptr == 0)
71 return 0;
73 f = new file;
74 f->filename = path;
75 f->fileptr = fileptr;
77 fib = new FileInfoBlock;
78 DOS->ExamineFH(fileptr, fib);
79 f->length = fib->fib_Size;
80 delete fib;
82 if (type == "BINARY")
83 f->type = Type_Intel;
84 else if (type == "MOTOROLA")
85 f->type = Type_Motorola;
86 else if (type == "AIFF")
87 f->type = Type_AIFF;
88 else if (type == "WAVE")
89 f->type = Type_Wave;
90 else if (type == "MP3")
91 f->type = Type_MP3;
92 else
93 f->type = Type_Unknown;
95 return f;
98 ~file()
100 if (fileptr != 0)
101 DOS->Close(fileptr);
102 fileptr = 0;
105 const String& getFileName() const
107 return filename;
110 uint32 getFileSize() const
112 return length;
115 file::filetype getFileType() const
117 return type;
120 BPTR getFile() const
122 return fileptr;
125 void seek(uint32 offset) const
127 DOS->Seek(fileptr, offset, OFFSET_BEGINNING);
130 uint32 read(void* mem, uint32 len) const
132 return DOS->Read(fileptr, mem, len);
136 class index
138 uint16 num; // index number
139 uint32 loc; // boundary: start
140 uint32 cnt; // and count
142 file* f;
143 uint32 fileoffset;
144 uint32 datalength;
145 uint32 currpos;
148 index()
150 num = 0;
151 loc = 0;
152 cnt = 0;
153 currpos = 0;
155 public:
157 static index *newIndex(uint16 number, uint32 location)
159 index *i = new index();
161 i->num = number;
162 i->loc = location;
163 i->cnt = 0xffffffff;
165 return i;
168 void setSecCnt(uint32 scnt)
170 cnt = scnt;
173 uint32 getSecCnt() const
175 return cnt;
178 uint32 getLocation() const
180 return loc;
183 void setLocation(uint32 l)
185 loc = l;
188 void debug(DbgHandler *__dbg)
190 if (__dbg == 0)
191 return;
193 _D(Lvl_Info, "---");
194 _D(Lvl_Info, "Number: %ld", num);
195 _D(Lvl_Info, "Location: %ld", loc);
196 _D(Lvl_Info, "Sector Count: %ld", cnt);
199 void setFile(file* fl)
201 f = fl;
204 file *getFile() const
206 return f;
209 void setFileOffset(uint32 fo)
211 fileoffset = fo;
214 void setDataLength(uint32 dl)
216 datalength = dl;
219 uint32 getFileOffset() const
221 return fileoffset;
224 uint32 getDataLength() const
226 return datalength;
229 uint32 getNumber() const
231 return num;
234 void fillItem(IOptItem* item)
236 item->setStartAddress(loc);
237 item->setItemNumber(num);
238 item->setDataBlockCount(cnt);
241 void setUp()
243 currpos = 0xffffffff;
246 uint32 read(void* mem, uint32 len)
248 if (currpos == datalength)
249 return 0;
250 if (currpos == 0xffffffff)
252 f->seek(fileoffset);
253 currpos = 0;
256 len = len < (datalength - currpos) ? len : (datalength - currpos);
257 f->read(mem, len); // i don't care if data is valid
258 currpos += len; // if it's not, i won't interrupt the process
259 return len;
263 class track
265 EDataType type; // type of data
266 uint32 flags; // additional flags (like "RAW")
267 uint16 secsize; // resulting from the two above fields
268 uint16 pregap; // in sectors
269 uint16 postgap; // in sectors
270 String isrc; // ISRC number
271 int16 number; // track number
272 VectorT<index*> indices; // indices
274 int16 curridx;
276 String arranger; // CDText
277 String composer;
278 String performer;
279 String message;
280 String title;
281 String songwriter;
283 track()
285 type = Data_Unknown;
286 flags = 0;
287 secsize = 0;
288 pregap = 0;
289 postgap= 0;
290 number = 0;
291 curridx = 0;
294 public:
295 static track* newTrack(int32 num, const String &mode)
297 track *nt = new track;
299 nt->number = num;
301 if (mode == "AUDIO")
302 nt->type = Data_Audio, nt->flags = 0, nt->secsize = 2352;
303 else if (mode == "MDOE1/2048")
304 nt->type = Data_Mode1, nt->flags = 0, nt->secsize = 2048;
305 else if (mode == "MODE2/2336")
306 nt->type = Data_Mode2, nt->flags = 0, nt->secsize = 2336;
307 else if (mode == "MODE1/2352")
308 nt->type = Data_Mode1, nt->flags = DIF_Common_RawData, nt->secsize = 2352;
309 else if (mode == "MODE2/2352")
310 nt->type = Data_Mode2, nt->flags = DIF_Common_RawData, nt->secsize = 2352;
311 else
313 delete nt;
314 return 0;
317 return nt;
320 void debug(DbgHandler *__dbg)
322 if (__dbg == 0)
323 return;
325 _D(Lvl_Info, "Number: %ld", number);
326 _D(Lvl_Info, "File type: %ld", type);
327 _D(Lvl_Info, "Flags: %ld", flags);
328 _D(Lvl_Info, "Sector Size: %ld", secsize);
329 _D(Lvl_Info, "PreGap: %ld", pregap);
330 _D(Lvl_Info, "PostGap: %ld", postgap);
331 _D(Lvl_Info, "ISRC: %s", (int32)isrc.Data());
332 _D(Lvl_Info, "Arranger: %s", (int32)arranger.Data());
333 _D(Lvl_Info, "Composer: %s", (int32)composer.Data());
334 _D(Lvl_Info, "Performer: %s", (int32)performer.Data());
335 _D(Lvl_Info, "Message: %s", (int32)message.Data());
336 _D(Lvl_Info, "Title: %s", (int32)title.Data());
337 _D(Lvl_Info, "Song Writer: %s", (int32)songwriter.Data());
339 for (int32 i=0; i<indices.Count(); i++)
340 indices[i]->debug(__dbg);
342 _D(Lvl_Info, "===");
345 void setArranger(const String &s)
347 arranger = s;
350 void setComposer(const String &s)
352 composer = s;
355 void setPerformer(const String &s)
357 performer = s;
360 void setMessage(const String &s)
362 message = s;
365 void setTitle(const String &s)
367 title = s;
370 void setSongWriter(const String &s)
372 songwriter = s;
375 void setPreGap(int32 gap)
377 pregap = gap;
380 void setPostGap(int32 gap)
382 postgap = gap;
385 int32 getPreGap() const
387 return pregap;
390 int32 getPostGap() const
392 return postgap;
395 int32 getNumber() const
397 return number;
400 void setISRC(const String &s)
402 isrc = s;
405 void addIndex(index *i)
407 indices << i;
410 index *getIndex(int32 i)
412 return indices[i];
415 int32 getIndexCount()
417 return indices.Count();
420 int32 getSectorSize() const
422 return secsize;
425 void fillItem(IOptItem *item)
427 uint32 len = 0;
429 item->setCDTDirector(arranger);
430 item->setCDTComposer(composer);
431 item->setCDTArtist(performer);
432 item->setCDTMessage(message);
433 item->setCDTTitle(title);
434 item->setCDTLyrics(songwriter);
435 item->setFlags(flags);
436 item->setSectorSize(secsize);
437 item->setPreGapSize(pregap);
438 item->setItemNumber(number);
439 item->setDataType(type);
441 item->setStartAddress(indices[0]->getLocation() - pregap);
442 for (int32 i=0; i<indices.Count(); i++)
444 IOptItem *indx = item->addChild();
446 indices[i]->fillItem(indx);
447 len += indices[i]->getSecCnt();
449 item->setDataBlockCount(len);
451 // FIXME: no postgap
453 // uint16 postgap; // in sectors
454 // String isrc; // ISRC number
457 void setUp()
459 for (int i=0; i<indices.Count(); i++)
460 indices[i]->setUp();
462 curridx = 0;
465 uint32 read(void* &mem, uint32 len)
467 uint32 ret = 0;
469 len *= secsize;
471 while (curridx < indices.Count())
473 ret += indices[curridx]->read(mem, len - ret);
475 mem = &((char*)mem)[ret];
477 if (ret == len)
478 break;
480 curridx++;
483 return ret / secsize;
489 // TODO:
490 // - use 'cdtextfile' parameter some day
491 // - apply params such as 'isrc', 'upc_ean', 'disc_id'
492 // - make class track return the data to the reader!!!!
496 rCUESession::rCUESession(const char* sFileName, EDtError &rc)
498 _createDebug(true, "rCUESession");
499 name = sFileName;
500 analyse(sFileName, rc);
503 rCUESession::~rCUESession()
505 tracks.ForEach(&freeTrack);
506 for (int i=0; i<files.Count(); i++)
507 delete files[i];
508 files.Empty();
511 _destroyDebug();
514 bool rCUESession::freeTrack(track* const& t)
516 delete t;
517 return true;
520 IFileReader* rCUESession::openRead(const char* sFile, EDtError &rc)
522 IFileReader *out = 0;
524 checkFile(sFile, rc);
525 if (rc == DT_OK)
527 out = new rCUESession(sFile, rc);
528 if (rc != DT_OK)
530 out->dispose();
531 out = 0;
534 return out;
537 const char* rCUESession::getName()
539 return static_getName();
542 bool rCUESession::readData(const IOptItem* item, void* mem, int len)
544 if (item->getItemType() != Item_Track)
546 int32 ret;
548 if (currtrk == tracks.Count())
549 return false;
551 ret = tracks[currtrk]->read(mem, len);
552 if (ret == len)
553 return true;
555 currtrk++;
556 ret += readData(item, mem, len-ret);
558 return true;
560 else
562 ASSERTS(false, "Functionality not yet implemented, sorry.");
563 return false;
567 bool rCUESession::setUp()
569 _d(Lvl_Info, "%s: seeking all items to the start position...", (int)__PRETTY_FUNCTION__);
571 for (int i=0; i<tracks.Count(); i++)
572 tracks[i]->setUp();
574 for (int i=0; i<files.Count(); i++)
575 DOS->Seek(files[i]->getFile(), 0, OFFSET_BEGINNING);
577 currtrk = 0;
579 return true;
582 bool rCUESession::analyse(const char* name, EDtError &rc)
584 BPTR fh;
585 uint8 s[1024];
586 String path;
587 bool res = true;
588 String fileName;
589 track *nt = 0; // new track
590 index *idx = 0;
592 rc = DT_UnableToOpenFile;
594 _d(Lvl_Info, "%s: starting analysis. File name: %s", (int)__PRETTY_FUNCTION__, (int)name);
596 fh = DOS->Open(const_cast<char*>(name), MODE_OLDFILE);
597 if (0 == fh)
598 return false;
600 BPTR lock = DOS->ParentOfFH(fh);
601 DOS->NameFromLock(lock, (char*)s, sizeof(s));
602 path = (char*)s;
604 _d(Lvl_Info, "%s: current path for binaries: %s", (int)__PRETTY_FUNCTION__, (int)path.Data());
606 rc = DT_OK;
608 while (DOS->FGets(fh, (char*)s, sizeof(s)) != 0)
610 for (int i=0; s[i] != 0; i++)
612 if ((s[i] != 10) && (s[i] != 13) && (s[i] != '\t') && (s[i]<' '))
614 DOS->Close(fh);
615 return false;
617 if ((s[i] >=128) && (s[i]<160))
619 DOS->Close(fh);
620 return false;
624 String str((char*)s);
625 VectorT<String> v = str.Explode();
627 if (v.Count() > 0)
629 str = v[0].UpperCase();
631 if (str == "TRACK")
633 int32 tn;
635 _d(Lvl_Info, "%s: parsing track", (int)__PRETTY_FUNCTION__);
636 if (v[1][0] == '0')
637 tn = v[1].SubString(1, -1).ToLong();
638 else
639 tn = v[1].ToLong();
641 nt = track::newTrack(tn, v[2]);
643 if (nt == 0)
645 _d(Lvl_Info, "%s: failed to create track", (int)__PRETTY_FUNCTION__);
646 rc = DT_FileMalformed;
647 res = false;
648 break;
651 tracks << nt;
653 else if (str == "INDEX")
655 int32 tn;
657 _d(Lvl_Info, "%s: parsing index", (int)__PRETTY_FUNCTION__);
658 if ((files.Count() == 0) || (nt == 0))
660 _d(Lvl_Info, "%s: files or tracks not defined yet", (int)__PRETTY_FUNCTION__);
661 rc = DT_FileMalformed;
662 res = false;
663 break;
666 uint32 pos = parseLocation(v[2]);
667 if (idx != 0)
668 idx->setSecCnt(pos-idx->getLocation());
670 if (v[1][0] == '0')
671 tn = v[1].SubString(1, -1).ToLong();
672 else
673 tn = v[1].ToLong();
675 idx = index::newIndex(tn, pos);
676 nt->addIndex(idx);
678 else if (str == "FILE")
680 file *f;
681 _d(Lvl_Info, "%s: parsing file", (int)__PRETTY_FUNCTION__);
683 f = file::newFile(path, v[1], v[2]);
684 if (f == 0)
686 _d(Lvl_Info, "%s: failed to create file entry for %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
687 rc = DT_UnableToOpenFile;
688 res = false;
689 break;
692 files << f;
693 idx = 0;
695 if (f->getFileType() != file::Type_Intel)
697 _d(Lvl_Warning, "%s: Unsupported file format: %s", (int)__PRETTY_FUNCTION__, (int)v[2].Data());
698 rc = DT_FileFormatNotSupported;
699 res = false;
700 break;
703 else if (str == "FLAGS")
705 _d(Lvl_Info, "%s: flags are not supported at the moment.", (int)__PRETTY_FUNCTION__);
706 rc = DT_FileFormatNotSupported;
707 res = false;
708 break;
710 else if (str == "REM")
712 _d(Lvl_Info, "%s: %s", (int)__PRETTY_FUNCTION__, (int)str.Data());
714 else if (str == "CATALOG")
716 _d(Lvl_Info, "%s: parsing catalog", (int)__PRETTY_FUNCTION__);
717 catalog = v[1].ToQuad();
719 else if (str == "CDTEXTFILE")
721 _d(Lvl_Warning, "%s: CDTEXTFILE TAG IS NOT SUPPORTED!", (int)__PRETTY_FUNCTION__);
723 else if (str == "ISRC")
725 _d(Lvl_Info, "%s: reading ISRC", (int)__PRETTY_FUNCTION__);
726 if (0 == nt)
728 rc = DT_FileMalformed;
729 res = false;
730 break;
732 nt->setISRC(v[1]);
734 else if (str == "PREGAP")
736 _d(Lvl_Info, "%s: parsing pregap", (int)__PRETTY_FUNCTION__);
737 if (0 == nt)
739 rc = DT_FileMalformed;
740 res = false;
741 break;
743 nt->setPreGap(v[1].ToLong());
744 _d(Lvl_Info, "%s: pregap size: %ld", (int)__PRETTY_FUNCTION__, v[1].ToLong());
746 else if (str == "POSTGAP")
748 _d(Lvl_Warning, "%s: postgaps not supported", (int)__PRETTY_FUNCTION__);
749 rc = DT_FileFormatNotSupported;
750 res = false;
751 break;
753 else if (str == "ARRANGER")
755 _d(Lvl_Info, "%s: read arranger: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
756 if (0 != nt)
757 nt->setArranger(v[1]);
758 else
759 arranger = v[1];
761 else if (str == "COMPOSER")
763 _d(Lvl_Info, "%s: read composer: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
764 if (0 != nt)
765 nt->setComposer(v[1]);
766 else
767 composer = v[1];
769 else if (str == "DISC_ID")
771 _d(Lvl_Warning, "%s: ignoring disc id", (int)__PRETTY_FUNCTION__);
772 disc_id = v[1];
774 else if (str == "GENRE")
776 _d(Lvl_Warning, "%s: ignoring genre", (int)__PRETTY_FUNCTION__);
778 // safe to skip this one.
780 else if (str == "MESSAGE")
782 _d(Lvl_Info, "%s: read message: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
783 if (0 != nt)
784 nt->setMessage(v[1]);
785 else
786 message = v[1];
788 else if (str == "PERFORMER")
790 _d(Lvl_Info, "%s: read performer: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
791 if (0 != nt)
792 nt->setPerformer(v[1]);
793 else
794 performer = v[1];
796 else if (str == "SONGWRITER")
798 _d(Lvl_Info, "%s: read songwriter: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
799 if (0 != nt)
800 nt->setSongWriter(v[1]);
801 else
802 songwriter = v[1];
804 else if (str == "TITLE")
806 _d(Lvl_Info, "%s: read title: %s", (int)__PRETTY_FUNCTION__, (int)v[1].Data());
807 if (0 != nt)
808 nt->setTitle(v[1]);
809 else
810 title = v[1];
812 else if (str == "TOC_INFO")
814 _d(Lvl_Warning, "%s: TOC INFO not supported", (int)__PRETTY_FUNCTION__);
815 rc = DT_FileFormatNotSupported;
816 res = false;
817 break;
819 else if (str == "TOC_INFO2")
821 _d(Lvl_Warning, "%s: TOC INFO not supported", (int)__PRETTY_FUNCTION__);
822 rc = DT_FileFormatNotSupported;
823 res = false;
824 break;
826 else if (str == "UPC_EAN")
828 _d(Lvl_Warning, "%s: ignoring UPC", (int)__PRETTY_FUNCTION__);
829 upc_ean = v[1];
831 else if (str == "SIZE_INFO")
833 _d(Lvl_Warning, "%s: alien SIZE INFO not supported", (int)__PRETTY_FUNCTION__);
834 rc = DT_FileFormatNotSupported;
835 res = false;
836 break;
838 else
840 _d(Lvl_Error, "%s: Malformed tag %s. Aborting.", (int)__PRETTY_FUNCTION__, (int)v[0].Data());
841 rc = DT_FileMalformed;
842 res = false;
843 break;
849 if (tracks.Count() == 0)
851 rc = DT_FileMalformed;
852 res = false;
855 for (int32 i=0; i<tracks.Count(); i++)
857 if (tracks[i]->getIndexCount() == 0)
859 res = false;
860 rc = DT_FileMalformed;
861 break;
865 _d(Lvl_Info, "%s: fixing references...", (int)__PRETTY_FUNCTION__);
867 if (res == true)
869 uint32 len_so_far = 0;
870 int32 sec_so_far = -150;
871 int32 fno = 0;
873 if ((tracks[0]->getIndex(0)->getNumber() != 0) && (tracks[0]->getPreGap() < 150))
874 tracks[0]->setPreGap(150);
876 for (int32 i=0; i<tracks.Count(); i++)
878 _d(Lvl_Info, "%s: Advancing to track %ld", (int)__PRETTY_FUNCTION__, i+1);
879 track *t = tracks[i];
881 sec_so_far += t->getPreGap();
883 for (int32 j=0; j<t->getIndexCount(); j++)
885 _d(Lvl_Info, "%s: Checking index %ld", (int)__PRETTY_FUNCTION__, j+1);
886 index *x = t->getIndex(j);
888 if ((x->getNumber() == 0) && (t->getPreGap() != 0))
890 _d(Lvl_Warning, "%s: CUE specifies both pregap and index 0, it's a nonsense.", (int32)__PRETTY_FUNCTION__);
891 rc = DT_FileMalformed;
892 res = false;
893 break;
896 x->setLocation(sec_so_far);
897 x->setFile(files[fno]);
898 x->setFileOffset(len_so_far);
900 if (x->getSecCnt() == 0xffffffff)
902 _d(Lvl_Info, "%s: Altering index accordingly to track %ld", (int)__PRETTY_FUNCTION__, fno+1);
903 x->setSecCnt((files[fno]->getFileSize() - len_so_far) / t->getSectorSize());
904 x->setDataLength(x->getSecCnt() * t->getSectorSize());
906 fno++;
907 len_so_far = 0;
909 else
911 x->setDataLength(x->getSecCnt() * t->getSectorSize());
912 len_so_far += x->getSecCnt() * t->getSectorSize();
915 sec_so_far += x->getSecCnt();
918 sec_so_far += t->getPostGap();
920 if (res == false)
921 break;
925 for (int32 i=0; i<tracks.Count(); i++)
926 tracks[i]->debug(getDebug());
928 DOS->Close(fh);
929 return res;
932 uint32 rCUESession::parseLocation(String &s)
935 * NOTE:
936 * despite MSF holds LBA+150 in normal case,
937 * we are actually referring to data stored in a file
938 * thus there is no decrement!
941 String c = s;
942 int i = 0;
943 uint32 loc = 0;
944 uint32 tot = 0;
946 while ((c[i] != ':') && (i < c.Length()))
948 loc = 10 * loc + c[i]-'0';
949 i++;
952 tot = loc * 60;
953 loc = 0;
954 i++;
956 while ((c[i] != ':') && (i < c.Length()))
958 loc = 10 * loc + c[i]-'0';
959 i++;
962 tot = (tot + loc) * 75;
963 loc = 0;
964 i++;
966 while ((c[i] != ':') && (i < c.Length()))
968 loc = 10 * loc + c[i]-'0';
969 i++;
972 tot = tot + loc;
974 _d(Lvl_Info, "%s: Location parsed - %s = %ld", (int)__PRETTY_FUNCTION__, (int)s.Data(), tot);
976 return tot;
979 void rCUESession::cleanUp()
983 void rCUESession::dispose()
985 delete this;
988 bool rCUESession::isAudio()
990 return static_isAudio();
993 bool rCUESession::isData()
995 return static_isData();
998 bool rCUESession::fillOptItem(IOptItem *disc)
1001 if (disc->getItemType() != Item_Disc)
1002 return false;
1004 disc->setFlags(DIF_Disc_MasterizeCD | DIF_Disc_CloseDisc);
1005 IOptItem *sess = disc->addChild();
1007 sess->setCDTDirector(arranger);
1008 sess->setCDTComposer(composer);
1009 sess->setCDTArtist(performer);
1010 sess->setCDTMessage(message);
1011 sess->setCDTTitle(title);
1012 sess->setCDTLyrics(songwriter);
1014 for (int i=0; i<tracks.Count(); i++)
1016 IOptItem *trak = sess->addChild();
1017 tracks[i]->fillItem(trak);
1019 return true;
1022 const char *rCUESession::getTrackName()
1024 return static_getName();
1027 uint32 rCUESession::getBlockCount()
1029 return blockCount;
1032 uint16 rCUESession::getBlockSize()
1034 return blockSize;
1037 const char *rCUESession::static_getName()
1039 return "CUE Sheet Session";
1042 bool rCUESession::static_isAudio()
1044 return false;
1047 bool rCUESession::static_isData()
1049 return false;
1052 bool rCUESession::static_isSession()
1054 return true;
1057 bool rCUESession::checkFile(const char* file, EDtError &rc)
1059 BPTR fh;
1060 uint8 s[1024];
1061 int res = true;
1063 rc = DT_UnableToOpenFile;
1065 fh = DOS->Open(const_cast<char*>(file), MODE_OLDFILE);
1066 if (0 == fh)
1067 return false;
1069 rc = DT_OK;
1071 while (DOS->FGets(fh, (char*)s, sizeof(s)) != 0)
1073 for (int i=0; s[i] != 0; i++)
1075 if ((s[i] != 10) && (s[i] != 13) && (s[i] != '\t') && (s[i]<' '))
1077 DOS->Close(fh);
1078 rc = DT_FileMalformed;
1079 return false;
1081 if ((s[i] >=128) && (s[i]<160))
1083 DOS->Close(fh);
1084 rc = DT_FileMalformed;
1085 return false;
1089 String str((char*)s);
1090 VectorT<String> v = str.Explode();
1092 if (v.Count() > 0)
1094 str = v[0].UpperCase();
1096 if ((str == "TRACK") ||
1097 (str == "INDEX") ||
1098 (str == "FILE") ||
1099 (str == "FLAGS") ||
1100 (str == "REM") ||
1101 (str == "CATALOG") ||
1102 (str == "CDTEXTFILE") ||
1103 (str == "ISRC") ||
1104 (str == "POSTGAP") ||
1105 (str == "PREGAP") ||
1106 (str == "ARRANGER") ||
1107 (str == "COMPOSER") ||
1108 (str == "DISC_ID") ||
1109 (str == "GENRE") ||
1110 (str == "MESSAGE") ||
1111 (str == "PERFORMER") ||
1112 (str == "SONGWRITER") ||
1113 (str == "TITLE") ||
1114 (str == "TOC_INFO") ||
1115 (str == "TOC_INFO2") ||
1116 (str == "UPC_EAN") ||
1117 (str == "SIZE_INFO"))
1119 continue;
1121 else
1123 rc = DT_FileMalformed;
1124 res = false;
1125 break;
1131 DOS->Close(fh);
1132 return res;
1135 DbgHandler* rCUESession::getDebug()
1137 return dbg;
1140 void rCUESession::setDebug(DbgHandler* nd)
1142 dbg = nd;