diff --git a/skyscraper8/Skyscraper/Drawing/IqChartData.cs b/skyscraper8/Skyscraper/Drawing/IqChartData.cs index 515cec5..db9b404 100644 --- a/skyscraper8/Skyscraper/Drawing/IqChartData.cs +++ b/skyscraper8/Skyscraper/Drawing/IqChartData.cs @@ -8,7 +8,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -using skyscraper5.src.Sophtainer; +using skyscraper8.SophtainerIO; namespace skyscraper8.Skyscraper.Drawing { diff --git a/skyscraper8/Skyscraper/Drawing/RfFrequencyChartData.cs b/skyscraper8/Skyscraper/Drawing/RfFrequencyChartData.cs index 3884e2d..2a13e01 100644 --- a/skyscraper8/Skyscraper/Drawing/RfFrequencyChartData.cs +++ b/skyscraper8/Skyscraper/Drawing/RfFrequencyChartData.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using skyscraper5.Dvb.Descriptors; using skyscraper5.Skyscraper.IO; -using skyscraper5.src.Sophtainer; +using skyscraper8.SophtainerIO; namespace skyscraper8.Skyscraper.Drawing { @@ -60,6 +60,39 @@ namespace skyscraper8.Skyscraper.Drawing SaveTo(ms); return ms.GetBuffer(); } + + public static RfSpectrumData LoadFromStream(Stream fileStream) + { + Sophtainer sophtainer = Sophtainer.LoadSophtainer(fileStream); + if (sophtainer.Application.Value != 538986066u) + throw new WrongApplicationException(538986066u, sophtainer.Application.Value); + + OffsetStream stream = sophtainer.GetStream(); + + RfSpectrumData result = new RfSpectrumData(); + + byte currentBlockType; + while ((currentBlockType = stream.ReadUInt8()) == 0x58) + { + int minFreq = stream.ReadInt32LE(); + int maxFreq = stream.ReadInt32LE(); + int step = stream.ReadInt32LE(); + SatelliteDeliverySystemDescriptor.PolarizationEnum polarizazion = (SatelliteDeliverySystemDescriptor.PolarizationEnum)stream.ReadUInt8(); + RfSpectrumDataBlock block = result.CreateBlock(minFreq, maxFreq, step, polarizazion); + for (int i = 0; i < block.Data.Length; i++) + block.Data[i] = stream.ReadFloat64LE(); + } + + stream.Close(); + sophtainer.Dispose(); + + return result; + } + + public IEnumerable GetBlocks() + { + return blocks.AsReadOnly(); + } } public class RfSpectrumDataBlock diff --git a/skyscraper8/Skyscraper/IO/StreamExtensions.cs b/skyscraper8/Skyscraper/IO/StreamExtensions.cs index d0af726..f1ffa6b 100644 --- a/skyscraper8/Skyscraper/IO/StreamExtensions.cs +++ b/skyscraper8/Skyscraper/IO/StreamExtensions.cs @@ -331,6 +331,16 @@ namespace skyscraper5.Skyscraper.IO return result; } + public static double ReadFloat64LE(this Stream stream) + { + byte[] buffer = new byte[8]; + if (stream.Read(buffer, 0, 8) != 8) + throw new EndOfStreamException(); + if (!BitConverter.IsLittleEndian) + Array.Reverse(buffer); + return BitConverter.ToDouble(buffer, 0); + } + public static void WriteFloat64LE(this Stream stream, double value) { byte[] buffer = BitConverter.GetBytes(value); @@ -359,5 +369,23 @@ namespace skyscraper5.Skyscraper.IO fileStream.Close(); fileStream.Dispose(); } + + public static int TryReadExactly(this Stream stream, byte[] buffer, int offset, int count) + { + int totalRead = 0; + + while (totalRead < count) + { + int bytesRead = stream.Read(buffer, offset + totalRead, count - totalRead); + if (bytesRead == 0) + { + // End of stream + break; + } + + totalRead += bytesRead; + } + return totalRead; + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index 92e4d3e..739e2c5 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -1776,5 +1776,17 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem { throw new NotImplementedException(); } + + public RfSpectrumData GetRfSpectrum(Guid jobGuid) + { + string filename = Path.Combine(rootDirectory.FullName, "rf", jobGuid.ToString() + ".rf"); + FileInfo fi = new FileInfo(filename); + if (!fi.Exists) + throw new FileNotFoundException(fi.FullName); + + FileStream fileStream = fi.OpenRead(); + RfSpectrumData result = RfSpectrumData.LoadFromStream(fileStream); + return result; + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs index 5c9e9f5..c366a02 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs @@ -163,5 +163,10 @@ namespace skyscraper8.Skyscraper.Scraper.Storage { return new byte[0] { }; } + + public RfSpectrumData GetRfSpectrum(Guid selectedGuid) + { + throw new NotImplementedException(); + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs index 8ffbfd1..4535af9 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs @@ -36,6 +36,8 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void StoreRfSpectrum(Guid jobGuid, RfSpectrumData rfSpectrum); void DeleteIqGraph(Guid selectedGuid, int frequencyItem1, SatelliteDeliverySystemDescriptor.PolarizationEnum frequencyItem2); void DeleteRfSpectrum(Guid selectedGuid); + + RfSpectrumData GetRfSpectrum(Guid selectedGuid); bool OtvSsuTestFile(int? currentNetworkId, int? currentTransportStreamId, int sourcePid, ushort tableIdExtension, uint fileId, uint unknown1, uint length); void OnOtvSsuComplete(int? currentNetworkId, int? currentTransportStreamId, int sourcePid, Stream getStream, ushort tableIdExtension, uint fileId, uint unknown1, uint length); void OnNdsSsuComplete(int? currentNetworkId, int? currentTransportStreamId, int pid, ushort tableIdExtension, NdsSsuDataMap dataMap); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Tar/TarObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Tar/TarObjectStorage.cs index 4799f6f..f6f9435 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Tar/TarObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Tar/TarObjectStorage.cs @@ -228,5 +228,13 @@ namespace skyscraper8.Skyscraper.Scraper.Storage.Tar string filename = "/nip/" + DvbNipUtilities.MakeFilename(path); return tarArchive.ReadEntry(filename); } + + public RfSpectrumData GetRfSpectrum(Guid selectedGuid) + { + string filename = String.Format("scandata/{0}/index.rf", selectedGuid); + byte[] buffer = tarArchive.ReadEntry(filename); + RfSpectrumData rfSpectrumData = RfSpectrumData.LoadFromStream(new MemoryStream(buffer)); + return rfSpectrumData; + } } } diff --git a/skyscraper8/Sophtainer/IDisposer.cs b/skyscraper8/Sophtainer/IDisposer.cs index 1901092..e61f898 100644 --- a/skyscraper8/Sophtainer/IDisposer.cs +++ b/skyscraper8/Sophtainer/IDisposer.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace skyscraper5.src.Sophtainer +namespace skyscraper8.SophtainerIO { public interface IDisposer { diff --git a/skyscraper8/Sophtainer/OffsetStream.cs b/skyscraper8/Sophtainer/OffsetStream.cs index f7b2fad..7fc7194 100644 --- a/skyscraper8/Sophtainer/OffsetStream.cs +++ b/skyscraper8/Sophtainer/OffsetStream.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace skyscraper5.src.Sophtainer +namespace skyscraper8.SophtainerIO { internal class OffsetStream : Stream { diff --git a/skyscraper8/Sophtainer/Sophtainer.cs b/skyscraper8/Sophtainer/Sophtainer.cs index cda3a71..b24d0f0 100644 --- a/skyscraper8/Sophtainer/Sophtainer.cs +++ b/skyscraper8/Sophtainer/Sophtainer.cs @@ -8,7 +8,7 @@ using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; -namespace skyscraper5.src.Sophtainer +namespace skyscraper8.SophtainerIO { internal class Sophtainer : IDisposable, IDisposer { diff --git a/skyscraper8/Sophtainer/SophtainerException.cs b/skyscraper8/Sophtainer/SophtainerException.cs index 9c8e315..9df709d 100644 --- a/skyscraper8/Sophtainer/SophtainerException.cs +++ b/skyscraper8/Sophtainer/SophtainerException.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace skyscraper5.src.Sophtainer +namespace skyscraper8.SophtainerIO { [Serializable] diff --git a/skyscraper8/Sophtainer/SplitFileStream.cs b/skyscraper8/Sophtainer/SplitFileStream.cs index a0c395d..f7df116 100644 --- a/skyscraper8/Sophtainer/SplitFileStream.cs +++ b/skyscraper8/Sophtainer/SplitFileStream.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using System.IO; -namespace skyscraper5.src.Sophtainer +namespace skyscraper8.SophtainerIO { public delegate void FileStreamPartSwitchDelegate(int readSoFar, int currentOffset, int remaining); diff --git a/skyscraper8/Sophtainer/WrongApplicationException.cs b/skyscraper8/Sophtainer/WrongApplicationException.cs new file mode 100644 index 0000000..5ca71b6 --- /dev/null +++ b/skyscraper8/Sophtainer/WrongApplicationException.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.SophtainerIO +{ + internal class WrongApplicationException : Exception + { + public WrongApplicationException(uint expected, uint actual) + : base(String.Format("The loaded Sophtainer file was written with application ID {0}, but we need one for application ID {1}", actual, expected)) + { + + } + } +}