Esempio n. 1
0
        // Constructors

        /// <summary>
        /// DiskReader (multi tracks)
        /// </summary>
        /// <param name="fileUrl">Path to the CUE file to read</param>
        /// <param name="system">File system used for data track</param>
        private DiskReader(string fileUrl, DiskFileSystem system)
            : base(system)
        {
            try
            {
                var cueFile = new FileInfo(fileUrl);

                using (var cueFileStream = new FileStream(cueFile.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var cueStream = new StreamReader(cueFileStream))
                    {
                        var   tracksDic = new Dictionary <int, Track>();
                        var   indexOffsets = new List <long>();
                        Match match = null;
                        Track track = null;
                        int   trackNumber = 0;
                        int   m, s, b;

                        string line;
                        string keyWord;
                        while ((line = cueStream.ReadLine()) != null)
                        {
                            keyWord = _regCueKeyWord.Match(line).Groups[1].Value.ToUpper();

                            switch (keyWord)
                            {
                            case "FILE":
                                if (_fileOpen)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : framework does not support multi files per cue but only one file with multi tracks");
                                }

                                fileUrl = _regCueFile.Match(line).Groups[1].Value;

                                if (!(fileUrl.StartsWith("/") || fileUrl.StartsWith("\\") || fileUrl.Contains(":/") || fileUrl.Contains(":\\")))
                                {
                                    fileUrl = cueFile.DirectoryName + "/" + fileUrl;
                                }

                                _file = new FileInfo(fileUrl);

                                if (!_file.Exists)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : targeted file \"{0}\" not found", fileUrl);
                                }

                                string extension = _file.Extension.ToUpper();
                                if (!(extension == ".BIN" || extension == ".IMG" || extension == ".ISO"))
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : targeted file \"{0}\" is not a BIN/IMG/ISO file", fileUrl);
                                }


                                _fileStream = new FileStream(_file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                                _stream     = new CBinaryReader(_fileStream);
                                _fileOpen   = true;
                                break;

                            case "TRACK":
                                if (!_fileOpen)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : TRACK defined before FILE");
                                }

                                match = _regCueTrack.Match(line);

                                if (!int.TryParse(match.Groups[1].Value, out trackNumber))
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : track number invalid");
                                }

                                string mode = match.Groups[2].Value.ToUpper();

                                if ((!mode.StartsWith("MODE") && !_hasDataTrack))
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : only Mixed Mode multi tracks disks are supported, the first track must be a DATA track");
                                }
                                else if ((mode.StartsWith("MODE") && _hasDataTrack))
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : only Mixed Mode multi tracks disks are supported, it must contains only one DATA track");
                                }

                                switch (mode)
                                {
                                case "RAW":
                                case "RAW/2048":
                                case "MODE1/2048":
                                    track         = new DataTrackReader(_stream, trackNumber, _system, DataTrackMode.RAW, false, false);
                                    _hasDataTrack = true;
                                    break;

                                case "MODE1/2352":
                                    track         = new DataTrackReader(_stream, trackNumber, _system, DataTrackMode.MODE1, false, false);
                                    _hasDataTrack = true;
                                    break;

                                case "MODE2/2336":
                                    track         = new DataTrackReader(_stream, trackNumber, _system, DataTrackMode.MODE2, false, false);
                                    _hasDataTrack = true;
                                    break;

                                case "MODE2/2352":
                                    track         = new DataTrackReader(_stream, trackNumber, _system, DataTrackMode.MODE2_XA, false, false);
                                    _hasDataTrack = true;
                                    break;

                                case "AUDIO":
                                    track = new AudioTrackReader(_stream, trackNumber);
                                    break;

                                default:
                                    throw new FrameworkException("Error while parsing cue sheet : unknown/not supported track type \"{0}\"", mode);
                                }
                                tracksDic.Add(trackNumber, track);
                                _tracks.Add(track);
                                break;

                            case "INDEX":
                                track = tracksDic[trackNumber];

                                match = _regCueIndex.Match(line);

                                int indexNumber;
                                if (!int.TryParse(match.Groups[1].Value, out indexNumber) || indexNumber > 2)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : index number invalid");
                                }

                                if (!int.TryParse(match.Groups[2].Value, out m) ||
                                    !int.TryParse(match.Groups[3].Value, out s) || s > 59 ||
                                    !int.TryParse(match.Groups[4].Value, out b) || s > 74)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : index time code invalid");
                                }

                                uint offset = (uint)(((((m * 60) + s) * 75) + b) * track.SectorSize);
                                indexOffsets.Add(offset);

                                if (indexNumber == 0)
                                {
                                    track.HasPause = true;
                                }

                                break;

                            case "PREGAP":
                            case "POSTGAP":
                                track = tracksDic[trackNumber];

                                match = _regCueGap.Match(line);

                                if (!int.TryParse(match.Groups[1].Value, out m) ||
                                    !int.TryParse(match.Groups[2].Value, out s) || s > 59 ||
                                    !int.TryParse(match.Groups[3].Value, out b) || s > 74)
                                {
                                    throw new FrameworkException("Error while parsing cue sheet : gap size invalid");
                                }

                                uint gapSize = (uint)((((m * 60) + s) * 75) + b);

                                if (keyWord == "PREGAP")
                                {
                                    track.PregapSize = gapSize;
                                }
                                else
                                {
                                    track.PostgapSize = gapSize;
                                }

                                break;
                            }
                        }
                        indexOffsets.Add(_fileStream.Length);

                        for (int i = 0, u = 0, max = _tracks.Count; i < max; i++)
                        {
                            track = _tracks[i];
                            if (track.HasPause)
                            {
                                track.PauseOffset = indexOffsets[u];
                                track.PauseSize   = (uint)((indexOffsets[u + 1] - indexOffsets[u]) / track.SectorSize);
                                u++;
                            }

                            track.Offset = indexOffsets[u];
                            track.Size   = (uint)((indexOffsets[u + 1] - indexOffsets[u]) / track.SectorSize);
                            u++;
                        }
                    }
                _stream.Position = 0;
            }
            catch (FrameworkException ex)
            {
                throw ex;
            }
            catch (Exception)
            {
                throw new FrameworkException("Error while reading ISO : Unable to open the ISO File");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Récupère un index présent dans le SLUS
        /// </summary>
        /// <param name="dtr_track">Track 1 de l'iso</param>
        /// <param name="i_position">Adresse de l'index dans le fichier SLUS</param>
        /// <param name="nb">Nombre de pointeurs de l'index</param>
        /// <returns></returns>
        private static List<cGlobal.st_index> readSlusIndex(DataTrackReader dtr_track, int i_position, int nb)
        {
            List<cGlobal.st_index> index = new List<cGlobal.st_index>();

            Stream st_file = dtr_track.ReadFile("/SLUS_006.26");

            using (BinaryReader br_file = new BinaryReader(st_file))
            {
                br_file.BaseStream.Seek(i_position, SeekOrigin.Begin);

                cGlobal.st_index elem;

                for (int i = 0; i < nb; i++)
                {
                    elem.id = i;
                    elem.pos = br_file.ReadUInt32();
                    elem.size = br_file.ReadUInt32();

                    index.Add(elem);
                }
            }

            return index;
        }