public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) => throw new FeatureUnsupportedImageException("Feature not supported by image format");
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) { ErrorMessage = "Unsupported feature"; return(false); }
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } Track track = Tracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector && sectorAddress <= trk.TrackEndSector); if (track.TrackSequence == 0) { ErrorMessage = $"Can't found track containing {sectorAddress}"; return(false); } switch (tag) { case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackIsrc: return(WriteSectorTag(data, sectorAddress, tag)); case SectorTagType.CdSectorSubchannel: { if (track.TrackSubchannelType == 0) { ErrorMessage = $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel"; return(false); } if (data.Length % 96 != 0) { ErrorMessage = "Incorrect data size for subchannel"; return(false); } if (subStream == null) { try { subStream = new FileStream(writingBaseName + ".sub", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } catch (IOException e) { ErrorMessage = $"Could not create subchannel file, exception {e.Message}"; return(false); } } subStream.Seek((long)(track.TrackSubchannelOffset + (sectorAddress - track.TrackStartSector) * 96), SeekOrigin.Begin); subStream.Write(data, 0, data.Length); return(true); } default: ErrorMessage = $"Unsupported tag type {tag}"; return(false); } }
public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } Track track = writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector && sectorAddress <= trk.TrackEndSector); if (track.TrackSequence == 0) { ErrorMessage = $"Can't found track containing {sectorAddress}"; return(false); } switch (tag) { case SectorTagType.CdTrackFlags: { if (data.Length != 1) { ErrorMessage = "Incorrect data size for track flags"; return(false); } trackFlags.Add((byte)track.TrackSequence, data[0]); return(true); } case SectorTagType.CdSectorSubchannel: { if (track.TrackSubchannelType == 0) { ErrorMessage = $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel"; return(false); } if (data.Length != 96) { ErrorMessage = "Incorrect data size for subchannel"; return(false); } imageStream .Seek((long)(track.TrackFileOffset + (sectorAddress - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96)) + track.TrackRawBytesPerSector, SeekOrigin.Begin); imageStream.Write(data, 0, data.Length); return(true); } default: ErrorMessage = $"Unsupported tag type {tag}"; return(false); } }
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) => throw new NotImplementedException("Flux decoding is not yet implemented.");
public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) { return(ReadSectorsTag(sectorAddress, 1, tag)); }
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } Track track = writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector && sectorAddress <= trk.TrackEndSector); if (track.TrackSequence == 0) { ErrorMessage = $"Can't found track containing {sectorAddress}"; return(false); } switch (tag) { case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackIsrc: return(WriteSectorTag(data, sectorAddress, tag)); case SectorTagType.CdSectorSubchannel: { if (track.TrackSubchannelType == 0) { ErrorMessage = $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel"; return(false); } if (data.Length % 96 != 0) { ErrorMessage = "Incorrect data size for subchannel"; return(false); } FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value; if (trackStream == null) { ErrorMessage = $"Can't found file containing {sectorAddress}"; return(false); } for (uint i = 0; i < length; i++) { trackStream. Seek((long)(track.TrackFileOffset + (((i + sectorAddress) - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96))) + track.TrackRawBytesPerSector, SeekOrigin.Begin); trackStream.Write(data, (int)(i * 96), 96); } return(true); } default: ErrorMessage = $"Unsupported tag type {tag}"; return(false); } }
public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag);
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) => WriteSectorTag(data, sectorAddress, tag);
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag) { if (track == 0) { if (sectorAddress + length > densitySeparationSectors) { throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than present in track, won't cross tracks"); } if (tag == SectorTagType.CdTrackFlags) { return new byte[] { 0x00 } } ; throw new ArgumentException("Unsupported tag requested for this track", nameof(tag)); } GdiTrack dicTrack = new GdiTrack { Sequence = 0 }; foreach (GdiTrack gdiTrack in discimage.Tracks.Where(gdiTrack => gdiTrack.Sequence == track)) { dicTrack = gdiTrack; break; } if (dicTrack.Sequence == 0) { throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); } if (length > dicTrack.Sectors) { throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than present in track, won't cross tracks"); } uint sectorOffset; uint sectorSize; uint sectorSkip; switch (tag) { case SectorTagType.CdSectorEcc: case SectorTagType.CdSectorEccP: case SectorTagType.CdSectorEccQ: case SectorTagType.CdSectorEdc: case SectorTagType.CdSectorHeader: case SectorTagType.CdSectorSync: break; case SectorTagType.CdTrackFlags: { byte[] flags = new byte[1]; flags[0] += dicTrack.Flags; return(flags); } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } switch (dicTrack.Tracktype) { case TrackType.Audio: throw new ArgumentException("There are no tags on audio tracks", nameof(tag)); case TrackType.CdMode1: { if (dicTrack.Bps != 2352) { throw new FeatureNotPresentImageException("Image does not include tags for mode 1 sectors"); } switch (tag) { case SectorTagType.CdSectorSync: { sectorOffset = 0; sectorSize = 12; sectorSkip = 2340; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; sectorSize = 4; sectorSkip = 2336; break; } case SectorTagType.CdSectorSubchannel: case SectorTagType.CdSectorSubHeader: throw new ArgumentException("Unsupported tag requested for this track", nameof(tag)); case SectorTagType.CdSectorEcc: { sectorOffset = 2076; sectorSize = 276; sectorSkip = 0; break; } case SectorTagType.CdSectorEccP: { sectorOffset = 2076; sectorSize = 172; sectorSkip = 104; break; } case SectorTagType.CdSectorEccQ: { sectorOffset = 2248; sectorSize = 104; sectorSkip = 0; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2064; sectorSize = 4; sectorSkip = 284; break; } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } break; } default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); } byte[] buffer = new byte[sectorSize * length]; ulong remainingSectors = length; if (dicTrack.Pregap > 0 && sectorAddress < dicTrack.Pregap) { ulong remainingPregap = dicTrack.Pregap - sectorAddress; byte[] zero; if (length > remainingPregap) { zero = new byte[remainingPregap * sectorSize]; remainingSectors -= remainingPregap; } else { zero = new byte[length * sectorSize]; remainingSectors -= length; } Array.Copy(zero, 0, buffer, 0, zero.Length); } if (remainingSectors == 0) { return(buffer); } imageStream = dicTrack.Trackfilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream .Seek(dicTrack.Offset + (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip) + dicTrack.Pregap * dicTrack.Bps), SeekOrigin.Begin); if (sectorOffset == 0 && sectorSkip == 0) { buffer = br.ReadBytes((int)(sectorSize * remainingSectors)); } else { for (ulong i = 0; i < remainingSectors; i++) { br.BaseStream.Seek(sectorOffset, SeekOrigin.Current); byte[] sector = br.ReadBytes((int)sectorSize); br.BaseStream.Seek(sectorSkip, SeekOrigin.Current); Array.Copy(sector, 0, buffer, (int)(i * sectorSize), sectorSize); } } return(buffer); }
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) { ErrorMessage = "Writing sectors with tags is not supported."; return(false); }
public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } Track track = _writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector && sectorAddress <= trk.TrackEndSector); if (track is null) { ErrorMessage = $"Can't found track containing {sectorAddress}"; return(false); } switch (tag) { case SectorTagType.CdTrackFlags: { if (data.Length != 1) { ErrorMessage = "Incorrect data size for track flags"; return(false); } _trackFlags[(byte)sectorAddress] = data[0]; return(true); } case SectorTagType.CdTrackIsrc: { if (data != null) { _trackIsrcs[(byte)sectorAddress] = Encoding.UTF8.GetString(data); } return(true); } case SectorTagType.CdSectorSubchannel: { if (track.TrackSubchannelType == 0) { ErrorMessage = $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel"; return(false); } if (data.Length != 96) { ErrorMessage = "Incorrect data size for subchannel"; return(false); } FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value; if (trackStream == null) { ErrorMessage = $"Can't found file containing {sectorAddress}"; return(false); } trackStream. Seek((long)(track.TrackFileOffset + ((sectorAddress - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96))) + track.TrackRawBytesPerSector, SeekOrigin.Begin); trackStream.Write(data, 0, data.Length); return(true); } default: ErrorMessage = $"Unsupported tag type {tag}"; return(false); } }