Added a TAR Object Storage.
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 4m18s

This commit is contained in:
feyris-tan 2026-02-02 21:29:33 +01:00
parent 6d3f352bc5
commit 08abdb0fb6
7 changed files with 2308 additions and 1997 deletions

View File

@ -40,17 +40,17 @@
<Assembly Path="/home/schiemas/.nuget/packages/allure.net.commons/2.14.1/lib/netstandard2.0/Allure.Net.Commons.dll" />
&lt;/AssemblyExplorer&gt;</s:String>
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">/home/schiemas/.cache/JetBrains/Rider2025.1/resharper-host/temp/Rider/vAny/CoverageData/_skyscraper8.1808907683/Snapshot/snapshot.utdcvr</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=145b05c0_002D83b0_002D4386_002Db9fb_002De55ec3152557/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;And&gt;
&lt;Namespace&gt;skyscraper8.Tests&lt;/Namespace&gt;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;
&lt;/And&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=145b05c0_002D83b0_002D4386_002Db9fb_002De55ec3152557/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Namespace&gt;skyscraper8.Tests&lt;/Namespace&gt;&#xD;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=58c56b00_002Df81e_002D48fd_002Da74f_002Dc8e84271fcf4/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="Continuous Testing" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=58c56b00_002Df81e_002D48fd_002Da74f_002Dc8e84271fcf4/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="Continuous Testing" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=ce70f33b_002D9024_002D4750_002Da24e_002D78f4e8e5e879/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=ce70f33b_002D9024_002D4750_002Da24e_002D78f4e8e5e879/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>

View File

@ -286,6 +286,14 @@ namespace skyscraper8.Experimentals.NdsSsu
}
}
public byte[] WriteToByteArray()
{
byte[] buffer = new byte[CalculateLength()];
MemoryStream ms = new MemoryStream(buffer);
WriteToStream(ms);
return ms.GetBuffer();
}
public void Dispose()
{
for (int x = 0; x < superblocks.Length; x++)

View File

@ -101,6 +101,13 @@ namespace skyscraper8.Skyscraper.Drawing
}
}
public byte[] SaveToBytes()
{
MemoryStream ms = new MemoryStream();
SaveTo(ms);
return ms.GetBuffer();
}
private bool scaled;
public void AutoScale()
{

View File

@ -53,6 +53,13 @@ namespace skyscraper8.Skyscraper.Drawing
stream.WriteUInt8(0x4f);
}
public byte[] SaveToBytes()
{
MemoryStream ms = new MemoryStream();
SaveTo(ms);
return ms.GetBuffer();
}
}
public class RfSpectrumDataBlock

View File

@ -1,3 +1,5 @@
using skyscraper5.Skyscraper.IO;
namespace skyscraper8.Skyscraper.Scraper.Storage.Tar;
public class TarArchive : IDisposable, IAsyncDisposable
@ -17,7 +19,7 @@ public class TarArchive : IDisposable, IAsyncDisposable
stream.Read(headerBuffer, 0, 512);
TarHeader header = TarHeader.Deserialize(headerBuffer);
TarArchiveEntry entry = new TarArchiveEntry();
TarArchiveEntry entry = new TarArchiveEntry(header.Filename, header.Size, stream.Position);
entry.FileName = header.Filename;
entry.FileSize = header.Size;
entry.Offset = stream.Position;
@ -32,7 +34,14 @@ public class TarArchive : IDisposable, IAsyncDisposable
struct TarArchiveEntry
{
public string FileName;
public TarArchiveEntry(string fileName, long fileSize, long offset)
{
FileName = fileName;
FileSize = fileSize;
Offset = offset;
}
public string FileName;
public long FileSize;
public long Offset;
}
@ -42,12 +51,15 @@ public class TarArchive : IDisposable, IAsyncDisposable
public void WriteEntry(string filename, byte[] buffer)
{
backend.Position = backend.Length;
backend.Position = backend.Length;
//Write header
TarHeader header = new TarHeader(filename, buffer.Length);
byte[] serialize = header.Serialize();
backend.Write(serialize);
//Remember Entry
TarArchiveEntry entry = new TarArchiveEntry(filename, buffer.Length, backend.Position);
//Write actual data
backend.Write(buffer, 0, buffer.Length);
@ -61,9 +73,37 @@ public class TarArchive : IDisposable, IAsyncDisposable
backend.Write(stuffingBuffer, 0, (int)stuffingLength64);
}
backend.Flush();
entries.Add(entry);
}
public void Dispose()
public void WriteEntry(string filename, Stream source)
{
backend.Position = backend.Length;
//Write header
TarHeader header = new TarHeader(filename, source.Length);
byte[] serialize = header.Serialize();
backend.Write(serialize);
//Remember Entry
TarArchiveEntry entry = new TarArchiveEntry(filename, source.Length, backend.Position);
//Write actual data
source.CopyTo(backend);
//Write stuffing
long stuffingLength64 = header.GetSizeOnTape();
stuffingLength64 -= header.Size;
if (stuffingLength64 > 0)
{
byte[] stuffingBuffer = new byte[stuffingLength64];
backend.Write(stuffingBuffer, 0, (int)stuffingLength64);
}
backend.Flush();
entries.Add(entry);
}
public void Dispose()
{
backend.Close();
backend.Dispose();
@ -74,4 +114,39 @@ public class TarArchive : IDisposable, IAsyncDisposable
backend.Close();
await backend.DisposeAsync();
}
public bool HasEntry(string filename)
{
if (entries == null)
return false;
if (entries.Count == 0)
return false;
foreach (TarArchiveEntry entry in entries)
{
if (entry.FileName.Equals(filename))
return true;
}
return false;
}
public byte[] ReadEntry(string filename)
{
if (entries == null)
return null;
if (entries.Count == 0)
return null;
foreach (TarArchiveEntry entry in entries)
{
if (entry.FileName.Equals(filename))
{
backend.Position = entry.Offset;
return backend.ReadBytes(entry.FileSize);
}
}
return null;
}
}

View File

@ -0,0 +1,214 @@
using moe.yo3explorer.skyscraper8.DVBI.Model;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Skyscraper;
using skyscraper8.DvbNip;
using skyscraper8.Experimentals.NdsSsu;
using skyscraper8.Ietf.FLUTE;
using skyscraper8.SimpleServiceDiscoveryProtocol;
using skyscraper8.Skyscraper.Drawing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace skyscraper8.Skyscraper.Scraper.Storage.Tar
{
public class TarObjectStorage : ObjectStorage
{
public TarObjectStorage(FileInfo fi)
{
tarFileInfo = fi;
tarStream = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
tarArchive = new TarArchive(tarStream);
}
private FileInfo tarFileInfo;
private Stream tarStream;
private TarArchive tarArchive;
public bool SsdpDeviceKnown(SsdpDevice ssdpDevice)
{
string filename = string.Format("ssdp/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName());
return tarArchive.HasEntry(filename);
}
public void SsdpStoreMetadata(SsdpDevice ssdpDevice, byte[] ssdpMetadataByteArray)
{
string filename = string.Format("ssdp/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName());
tarArchive.WriteEntry(filename, ssdpMetadataByteArray);
}
public byte[] SsdpGetMetadata(SsdpDevice ssdpDevice)
{
string filename = string.Format("ssdp/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName());
return tarArchive.ReadEntry(filename);
}
public bool ObjectCarouselFileArrival(VfsFile vfsFile, int transportStreamId, int networkId)
{
string filename = string.Format("dsm-cc/objects/{0}/{1}/{2}/{3}", networkId, transportStreamId, vfsFile.SourcePid, vfsFile.ToString());
if (tarArchive.HasEntry(filename))
{
return false;
}
else
{
tarArchive.WriteEntry(filename, vfsFile.FileContent);
return true;
}
}
public void DataCarouselModuleArrival(int currentNetworkId, int currentTransportStreamId, int elementaryPid,
ushort moduleModuleId, byte moduleModuleVersion, Stream result)
{
string filename = string.Format("dsm-ccc/{0}/{1}/{2}/{3}_V{4}.bin", currentNetworkId, currentTransportStreamId, elementaryPid, moduleModuleId, moduleModuleVersion);
tarArchive.WriteEntry(filename, result);
}
public bool IsDsmCcModuleWanted(int currentNetworkId, int currentTransportStreamId, int elementaryPid, ushort moduleId,
byte moduleVersion)
{
string filename = string.Format("dsm-ccc/{0}/{1}/{2}/{3}_V{4}.bin", currentNetworkId, currentTransportStreamId, elementaryPid, moduleId, moduleVersion);
return !tarArchive.HasEntry(filename);
}
public bool TestForFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber,
int mappingStreamElementaryPid)
{
string filename = string.Format("screenshots/master/{0}/{1}/{2}_{3}.jpg", currentNetworkId, transportStreamId, mappingProgramNumber, mappingStreamElementaryPid);
return tarArchive.HasEntry(filename);
}
public void StoreFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, ushort pid,
byte[] imageData)
{
string filename = string.Format("screenshots/master/{0}/{1}/{2}_{3}.jpg", currentNetworkId, transportStreamId, mappingProgramNumber, pid);
tarArchive.WriteEntry(filename, imageData);
}
public void WaitForCompletion()
{
}
public void UiSetVersion(int version)
{
throw new NotImplementedException();
}
public object[] GetPluginConnector()
{
return new object[] { tarArchive };
}
public void Ping()
{
byte[] buffer = new byte[4096];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = (byte)i;
}
string filename = string.Format("test_write1.dvr");
if (!tarArchive.HasEntry(filename))
{
tarArchive.WriteEntry(filename, buffer);
}
byte[] cmpBuffer = tarArchive.ReadEntry(filename);
if (buffer.Length != cmpBuffer.Length)
{
throw new Exception("readback produced invalid length");
}
for (int i = 0; i < cmpBuffer.Length; i++)
{
if (buffer[i] != cmpBuffer[i])
{
throw new Exception("readback produced unexpected result");
}
}
}
public bool DvbNipTestForFile(string announcedFileContentLocation)
{
string filename = "/nip/" + DvbNipUtilities.MakeFilename(announcedFileContentLocation);
return tarArchive.HasEntry(filename);
}
public void DvbNipFileArrival(NipActualCarrierInformation carrier, FluteListener listener)
{
string filename = "/nip/" + DvbNipUtilities.MakeFilename(listener.FileAssociation.ContentLocation);
tarArchive.WriteEntry(filename, listener.ToStream());
}
public void StoreIqGraph(Guid jobGuid, long frequency, char polarity, IqChartData plot)
{
string filename = String.Format("scandata/{0}/{1}_{2}.iq", jobGuid, frequency, polarity);
byte[] plotBuffer = plot.SaveToBytes();
tarArchive.WriteEntry(filename, plotBuffer);
}
public void StoreRfSpectrum(Guid jobGuid, RfSpectrumData rfSpectrum)
{
string filename = String.Format("scandata/{0}/index.rf", jobGuid);
byte[] plotBuffer = rfSpectrum.SaveToBytes();
tarArchive.WriteEntry(filename, plotBuffer);
}
public void DeleteIqGraph(Guid jobGuid, int frequency, SatelliteDeliverySystemDescriptor.PolarizationEnum frequencyItem2)
{
char polarity = frequencyItem2.ToString()[0];
string filename = String.Format("scandata/{0}/{1}_{2}.iq.deleted", jobGuid, frequency, polarity);
tarArchive.WriteEntry(filename, new byte[1]);
}
public void DeleteRfSpectrum(Guid selectedGuid)
{
string filename = String.Format("scandata/{0}/index.rf.deleted", selectedGuid);
tarArchive.WriteEntry(filename, new byte[1]);
}
public bool OtvSsuTestFile(int? currentNetworkId, int? currentTransportStreamId, int sourcePid, ushort tableIdExtension,
uint fileId, uint unknown1, uint length)
{
string filename = String.Format("otv-ssu/{0}/{1}/{2}/{3}.bin", currentNetworkId, currentTransportStreamId, sourcePid, tableIdExtension);
return tarArchive.HasEntry(filename);
}
public void OnOtvSsuComplete(int? currentNetworkId, int? currentTransportStreamId, int sourcePid, Stream getStream,
ushort tableIdExtension, uint fileId, uint unknown1, uint length)
{
string filename = String.Format("otv-ssu/{0}/{1}/{2}/{3}.bin", currentNetworkId, currentTransportStreamId, sourcePid, tableIdExtension);
tarArchive.WriteEntry(filename, getStream);
}
public void OnNdsSsuComplete(int? currentNetworkId, int? currentTransportStreamId, int pid, ushort tableIdExtension,
NdsSsuDataMap dataMap)
{
string filename = String.Format("nds-ssu/{0}/{1}/{2}/{3}.bin", currentNetworkId, currentTransportStreamId, pid, tableIdExtension);
tarArchive.WriteEntry(filename, dataMap.WriteToByteArray());
}
public bool NdsSsuTestFile(int? currentNetworkId, int? currentTransportStreamId, int pid, ushort tableIdExtension)
{
string filename = String.Format("nds-ssu/{0}/{1}/{2}/{3}.bin", currentNetworkId, currentTransportStreamId, pid, tableIdExtension);
return tarArchive.HasEntry(filename);
}
public bool TestForSisDsaci(int nid, int tsid, ushort groupId, int versionNumber)
{
string filename = String.Format("dvb-sis/{0}/{1}/Group{2}_Version{3}.xml", nid, tsid, groupId, versionNumber);
return tarArchive.HasEntry(filename);
}
public void StoreSisDsaci(int nid, int tsid, ushort currentDsaGroupId, int versionNumber, Stream dsaci)
{
string filename = String.Format("dvb-sis/{0}/{1}/Group{2}_Version{3}.xml", nid, tsid, currentDsaGroupId, versionNumber);
tarArchive.WriteEntry(filename, dsaci);
}
}
}