2024-11-25 17:09:33 -05:00
using System ;
using System.IO ;
2025-08-25 12:44:04 -04:00
using System.Text ;
2026-03-24 09:05:23 -04:00
using SabreTools.Matching ;
2024-11-25 17:09:33 -05:00
using Xunit ;
2026-01-27 08:51:29 -05:00
#pragma warning disable IDE0017 // Object initialization can be simplified
2026-03-24 09:05:23 -04:00
#pragma warning disable IDE0230 // Use UTF-8 string literal
2026-03-18 15:47:44 -04:00
namespace SabreTools.IO.Extensions.Test
2024-11-25 17:09:33 -05:00
{
public class StreamExtensionsTests
{
2025-08-25 10:50:16 -04:00
#region AlignToBoundary
2024-11-28 21:31:38 -05:00
[Fact]
public void AlignToBoundary_Null_False ( )
{
Stream ? stream = null ;
byte alignment = 4 ;
bool actual = stream . AlignToBoundary ( alignment ) ;
Assert . False ( actual ) ;
}
[Fact]
public void AlignToBoundary_Empty_False ( )
{
Stream ? stream = new MemoryStream ( [ ] ) ;
byte alignment = 4 ;
bool actual = stream . AlignToBoundary ( alignment ) ;
Assert . False ( actual ) ;
}
[Fact]
public void AlignToBoundary_EOF_False ( )
{
Stream ? stream = new MemoryStream ( [ 0x01 , 0x02 ] ) ;
byte alignment = 4 ;
stream . Position = 1 ;
bool actual = stream . AlignToBoundary ( alignment ) ;
Assert . False ( actual ) ;
}
[Fact]
public void AlignToBoundary_TooShort_False ( )
{
Stream ? stream = new MemoryStream ( [ 0x01 , 0x02 ] ) ;
byte alignment = 4 ;
stream . Position = 1 ;
bool actual = stream . AlignToBoundary ( alignment ) ;
Assert . False ( actual ) ;
}
[Fact]
public void AlignToBoundary_CanAlign_True ( )
{
Stream ? stream = new MemoryStream ( [ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 ] ) ;
byte alignment = 4 ;
stream . Position = 1 ;
bool actual = stream . AlignToBoundary ( alignment ) ;
Assert . True ( actual ) ;
}
#endregion
2026-03-23 20:47:49 -04:00
#region BlockCopy
[Fact]
public void BlockCopy_NullInput_False ( )
{
Stream ? input = null ;
Stream ? output = new MemoryStream ( ) ;
int blockSize = 8192 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . False ( actual ) ;
}
[Fact]
public void BlockCopy_NullOutput_False ( )
{
Stream ? input = new MemoryStream ( ) ;
Stream ? output = null ;
int blockSize = 8192 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . False ( actual ) ;
}
[Fact]
public void BlockCopy_UnreadableInput_False ( )
{
Stream ? input = new MemoryStream ( ) ;
input . Close ( ) ;
Stream ? output = new MemoryStream ( ) ;
int blockSize = 8192 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . False ( actual ) ;
}
[Fact]
public void BlockCopy_UnwritableOutput_False ( )
{
Stream ? input = new MemoryStream ( ) ;
Stream ? output = new MemoryStream ( [ ] , writable : false ) ;
int blockSize = 8192 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . False ( actual ) ;
}
[Fact]
public void BlockCopy_InvalidBlockSize_False ( )
{
Stream ? input = new MemoryStream ( ) ;
Stream ? output = new MemoryStream ( ) ;
int blockSize = - 1 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . False ( actual ) ;
}
[Fact]
public void BlockCopy_ValidInputs_True ( )
{
byte [ ] inputBytes = [ 0x00 , 0x01 , 0x02 , 0x03 ] ;
Stream ? input = new MemoryStream ( inputBytes ) ;
MemoryStream ? output = new MemoryStream ( ) ;
int blockSize = 8192 ;
bool actual = input . BlockCopy ( output , blockSize ) ;
Assert . True ( actual ) ;
byte [ ] actualBytes = output . ToArray ( ) ;
Assert . True ( actualBytes . SequenceEqual ( inputBytes ) ) ;
}
#endregion
2026-03-24 09:05:23 -04:00
#region InterleaveWith
[Fact]
public void Interleave_EvenNotExists_False ( )
{
string even = "NOT A REAL PATH" ;
2026-07-09 15:58:03 -04:00
string odd = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = even . InterleaveWith ( odd , output , 1 ) ;
Assert . False ( actual ) ;
}
[Fact]
public void Interleave_OddNotExists_False ( )
{
2026-07-09 15:58:03 -04:00
string even = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string odd = "NOT A REAL PATH" ;
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = even . InterleaveWith ( odd , output , 1 ) ;
Assert . False ( actual ) ;
}
[Fact]
public void Interleave_InvalidValue_False ( )
{
2026-07-09 15:58:03 -04:00
string even = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
string odd = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = even . InterleaveWith ( odd , output , - 1 ) ;
Assert . False ( actual ) ;
}
[Theory]
[InlineData(1, "TThhiiss ddooeessnn''tt mmaattcchh aannyytthhiinngg")]
[InlineData(2, "ThThisis d doeoesnsn't't m matatchch a anynyththiningg")]
[InlineData(4, "ThisThis doe doesn'tsn't mat match ach anythnythinging")]
[InlineData(8, "This doeThis doesn't matsn't match anythch anythinging")]
public void Interleave_SameLength_True ( int blockSize , string expected )
{
2026-07-09 15:58:03 -04:00
string even = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
string odd = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = even . InterleaveWith ( odd , output , blockSize ) ;
Assert . True ( actual ) ;
string text = File . ReadAllText ( output ) ;
Assert . Equal ( expected , text ) ;
File . Delete ( output ) ;
}
[Fact]
public void Interleave_DifferentLength_True ( )
{
2026-07-09 15:58:03 -04:00
string even = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
string odd = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "file-to-compress.bin" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = even . InterleaveWith ( odd , output , 1 ) ;
Assert . True ( actual ) ;
string text = File . ReadAllText ( output ) ;
Assert . Equal ( "TThhiiss diose sjnu'stt maa tfcihl ea ntyhtahti nhgas a known set of hashes to make sure that everything with hashing is still working as anticipated." , text ) ;
File . Delete ( output ) ;
}
#endregion
2025-08-25 10:50:16 -04:00
#region ReadFrom
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadFrom_Null_Null ( bool retainPosition )
{
Stream ? stream = null ;
byte [ ] ? actual = stream . ReadFrom ( 0 , 1 , retainPosition ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadFrom_NonSeekable_Null ( bool retainPosition )
{
Stream ? stream = new NonSeekableStream ( ) ;
byte [ ] ? actual = stream . ReadFrom ( 0 , 1 , retainPosition ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadFrom_Empty_Null ( bool retainPosition )
{
Stream ? stream = new MemoryStream ( [ ] ) ;
byte [ ] ? actual = stream . ReadFrom ( 0 , 1 , retainPosition ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(-1, true)]
[InlineData(2048, true)]
[InlineData(-1, false)]
[InlineData(2048, false)]
public void ReadFrom_InvalidOffset_Null ( long offset , bool retainPosition )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
byte [ ] ? actual = stream . ReadFrom ( offset , 1 , retainPosition ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(-1, true)]
[InlineData(2048, true)]
[InlineData(-1, false)]
[InlineData(2048, false)]
public void ReadFrom_InvalidLength_Null ( int length , bool retainPosition )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
byte [ ] ? actual = stream . ReadFrom ( 0 , length , retainPosition ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadFrom_Valid_Filled ( bool retainPosition )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
byte [ ] ? actual = stream . ReadFrom ( 0 , 512 , retainPosition ) ;
Assert . NotNull ( actual ) ;
Assert . Equal ( 512 , actual . Length ) ;
if ( retainPosition )
Assert . Equal ( 0 , stream . Position ) ;
else
Assert . Equal ( 512 , stream . Position ) ;
}
#endregion
2025-08-25 12:44:04 -04:00
#region ReadStringsFrom
[Fact]
public void ReadStringsFrom_Null_Null ( )
{
Stream ? stream = null ;
var actual = stream . ReadStringsFrom ( 0 , 1 , 3 ) ;
Assert . Null ( actual ) ;
}
[Fact]
public void ReadStringsFrom_NonSeekable_Null ( )
{
Stream ? stream = new NonSeekableStream ( ) ;
var actual = stream . ReadStringsFrom ( 0 , 1 , 3 ) ;
Assert . Null ( actual ) ;
}
[Fact]
public void ReadStringsFrom_Empty_Null ( )
{
Stream ? stream = new MemoryStream ( [ ] ) ;
var actual = stream . ReadStringsFrom ( 0 , 1 , 3 ) ;
Assert . Null ( actual ) ;
}
[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(2048)]
public void ReadStringsFrom_InvalidLimit_Empty ( int charLimit )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
var actual = stream . ReadStringsFrom ( 0 , 1024 , charLimit ) ;
Assert . NotNull ( actual ) ;
Assert . Empty ( actual ) ;
}
[Fact]
public void ReadStringsFrom_NoValidStrings_Empty ( )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
var actual = stream . ReadStringsFrom ( 0 , 1024 , 4 ) ;
Assert . NotNull ( actual ) ;
Assert . Empty ( actual ) ;
}
[Fact]
public void ReadStringsFrom_AsciiStrings_Filled ( )
{
byte [ ] ? bytes =
[
. . Encoding . ASCII . GetBytes ( "TEST" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . ASCII . GetBytes ( "TWO" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . ASCII . GetBytes ( "DATA" ) ,
. . new byte [ ] { 0x00 } ,
] ;
Stream ? stream = new MemoryStream ( bytes ) ;
var actual = stream . ReadStringsFrom ( 0 , bytes . Length , 4 ) ;
Assert . NotNull ( actual ) ;
2025-09-21 14:03:45 -04:00
Assert . Equal ( 2 , actual . Count ) ;
2025-08-25 12:44:04 -04:00
}
2025-09-21 15:12:16 -04:00
[Fact]
public void ReadStringsFrom_Latin1Strings_Filled ( )
{
byte [ ] ? bytes =
[
. . Encoding . Latin1 . GetBytes ( "TEST" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Latin1 . GetBytes ( "TWO" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Latin1 . GetBytes ( "DATA" ) ,
. . new byte [ ] { 0x00 } ,
] ;
Stream ? stream = new MemoryStream ( bytes ) ;
var actual = stream . ReadStringsFrom ( 0 , bytes . Length , 4 ) ;
Assert . NotNull ( actual ) ;
Assert . Equal ( 2 , actual . Count ) ;
}
2025-08-25 12:44:04 -04:00
[Fact]
public void ReadStringsFrom_UTF16_Filled ( )
{
byte [ ] ? bytes =
[
. . Encoding . Unicode . GetBytes ( "TEST" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Unicode . GetBytes ( "TWO" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Unicode . GetBytes ( "DATA" ) ,
. . new byte [ ] { 0x00 } ,
] ;
Stream ? stream = new MemoryStream ( bytes ) ;
var actual = stream . ReadStringsFrom ( 0 , bytes . Length , 4 ) ;
Assert . NotNull ( actual ) ;
Assert . Equal ( 2 , actual . Count ) ;
}
[Fact]
public void ReadStringsFrom_Mixed_Filled ( )
{
byte [ ] ? bytes =
[
. . Encoding . ASCII . GetBytes ( "TEST1" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . ASCII . GetBytes ( "TWO1" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . ASCII . GetBytes ( "DATA1" ) ,
. . new byte [ ] { 0x00 } ,
2025-09-21 15:12:16 -04:00
. . Encoding . Latin1 . GetBytes ( "TEST2" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Latin1 . GetBytes ( "TWO2" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Latin1 . GetBytes ( "DATA2" ) ,
. . new byte [ ] { 0x00 } ,
. . Encoding . Unicode . GetBytes ( "TEST3" ) ,
2025-08-25 12:44:04 -04:00
. . new byte [ ] { 0x00 } ,
2025-09-21 15:12:16 -04:00
. . Encoding . Unicode . GetBytes ( "TWO3" ) ,
2025-08-25 12:44:04 -04:00
. . new byte [ ] { 0x00 } ,
2025-09-21 15:12:16 -04:00
. . Encoding . Unicode . GetBytes ( "DATA3" ) ,
2025-08-25 12:44:04 -04:00
. . new byte [ ] { 0x00 } ,
] ;
Stream ? stream = new MemoryStream ( bytes ) ;
var actual = stream . ReadStringsFrom ( 0 , bytes . Length , 5 ) ;
Assert . NotNull ( actual ) ;
2025-09-21 15:12:16 -04:00
Assert . Equal ( 6 , actual . Count ) ;
2025-08-25 12:44:04 -04:00
}
#endregion
2025-08-25 10:50:16 -04:00
#region SeekIfPossible
2024-11-28 21:31:38 -05:00
2024-11-25 17:09:33 -05:00
[Fact]
public void SeekIfPossible_NonSeekable_CurrentPosition ( )
{
var stream = new NonSeekableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 ) ;
Assert . Equal ( 8 , actual ) ;
}
[Fact]
public void SeekIfPossible_NonPositionable_InvalidPosition ( )
{
var stream = new NonPositionableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 ) ;
Assert . Equal ( - 1 , actual ) ;
}
[Fact]
public void SeekIfPossible_HiddenNonSeekable_InvalidPosition ( )
{
var stream = new HiddenNonSeekableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 ) ;
Assert . Equal ( - 1 , actual ) ;
}
[Fact]
public void SeekIfPossible_NonNegative_ValidPosition ( )
{
var stream = new MemoryStream ( new byte [ 16 ] , 0 , 16 , false , true ) ;
long actual = stream . SeekIfPossible ( 5 ) ;
Assert . Equal ( 5 , actual ) ;
}
[Fact]
public void SeekIfPossible_Negative_ValidPosition ( )
{
var stream = new MemoryStream ( new byte [ 16 ] , 0 , 16 , false , true ) ;
long actual = stream . SeekIfPossible ( - 3 ) ;
Assert . Equal ( 13 , actual ) ;
}
2025-10-15 09:37:41 -04:00
[Theory]
[InlineData(SeekOrigin.Begin)]
[InlineData(SeekOrigin.Current)]
[InlineData(SeekOrigin.End)]
public void SeekIfPossible_NonSeekable_OriginTest ( SeekOrigin origin )
{
var stream = new NonSeekableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 , origin ) ;
Assert . Equal ( 8 , actual ) ;
}
2025-11-13 08:56:30 -05:00
2025-10-15 09:37:41 -04:00
[Theory]
[InlineData(SeekOrigin.Begin)]
[InlineData(SeekOrigin.Current)]
[InlineData(SeekOrigin.End)]
public void SeekIfPossible_NonPositionable_OriginTest ( SeekOrigin origin )
{
var stream = new NonPositionableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 , origin ) ;
Assert . Equal ( - 1 , actual ) ;
}
2025-11-13 08:56:30 -05:00
2025-10-15 09:37:41 -04:00
[Theory]
[InlineData(SeekOrigin.Begin)]
[InlineData(SeekOrigin.Current)]
[InlineData(SeekOrigin.End)]
public void SeekIfPossible_HiddenNonSeekable_OriginTest ( SeekOrigin origin )
{
var stream = new HiddenNonSeekableStream ( ) ;
long actual = stream . SeekIfPossible ( 0 , origin ) ;
Assert . Equal ( - 1 , actual ) ;
}
2025-11-13 08:56:30 -05:00
2025-10-15 09:37:41 -04:00
[Theory]
[InlineData(SeekOrigin.Begin, 5, 5)]
[InlineData(SeekOrigin.Current, 5, 7)]
[InlineData(SeekOrigin.End, -5, 11)]
public void SeekIfPossible_Seekable_OriginTest ( SeekOrigin origin , long offset , long expected )
{
var stream = new MemoryStream ( new byte [ 16 ] , 0 , 16 , false , true ) ;
stream . Position = 2 ;
long actual = stream . SeekIfPossible ( offset , origin ) ;
Assert . Equal ( expected , actual ) ;
}
2024-11-28 21:31:38 -05:00
#endregion
2025-08-25 10:50:16 -04:00
#region SegmentValid
[Fact]
public void SegmentValid_Null_False ( )
{
Stream ? stream = null ;
bool actual = stream . SegmentValid ( 0 , 1 ) ;
Assert . False ( actual ) ;
}
[Theory]
[InlineData(-1)]
[InlineData(2048)]
public void SegmentValid_InvalidOffset_False ( long offset )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
bool actual = stream . SegmentValid ( offset , 1 ) ;
Assert . False ( actual ) ;
}
[Theory]
[InlineData(-1)]
[InlineData(2048)]
public void SegmentValid_InvalidLength_False ( int length )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
bool actual = stream . SegmentValid ( 0 , length ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SegmentValid_ValidSegment_True ( )
{
Stream ? stream = new MemoryStream ( new byte [ 1024 ] ) ;
bool actual = stream . SegmentValid ( 0 , 1024 ) ;
Assert . True ( actual ) ;
}
#endregion
2026-03-24 10:12:38 -04:00
#region SplitToChunks
[Fact]
public void SplitToChunks_EmptyFileName_False ( )
{
string input = string . Empty ;
string outputDir = string . Empty ;
int size = 1 ;
bool actual = input . SplitToChunks ( outputDir , size ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SplitToChunks_InvalidFile_False ( )
{
string input = "INVALID" ;
string outputDir = string . Empty ;
int size = 1 ;
bool actual = input . SplitToChunks ( outputDir , size ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SplitToChunks_InvalidSize_False ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 10:12:38 -04:00
string outputDir = string . Empty ;
int size = 0 ;
bool actual = input . SplitToChunks ( outputDir , size ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SplitToChunks_Valid_True ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 10:12:38 -04:00
string outputDir = Guid . NewGuid ( ) . ToString ( ) ;
int size = 16 ;
bool actual = input . SplitToChunks ( outputDir , size ) ;
Assert . True ( actual ) ;
Assert . Equal ( 2 , Directory . GetFiles ( outputDir ) . Length ) ;
string baseFilename = Path . GetFileName ( input ) ;
string text = File . ReadAllText ( Path . Combine ( outputDir , $"{baseFilename}.0" ) ) ;
Assert . Equal ( "This doesn't mat" , text ) ;
text = File . ReadAllText ( Path . Combine ( outputDir , $"{baseFilename}.1" ) ) ;
Assert . Equal ( "ch anything" , text ) ;
File . Delete ( $"{baseFilename}.0" ) ;
File . Delete ( $"{baseFilename}.1" ) ;
}
#endregion
2026-03-24 09:53:19 -04:00
#region SplitToEvenOdd
[Fact]
public void SplitToEvenOdd_EmptyFileName_False ( )
{
string input = string . Empty ;
string even = string . Empty ;
string odd = string . Empty ;
bool actual = input . SplitToEvenOdd ( even , odd , 1 ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SplitToEvenOdd_InvalidFile_False ( )
{
string input = "INVALID" ;
string even = string . Empty ;
string odd = string . Empty ;
bool actual = input . SplitToEvenOdd ( even , odd , 1 ) ;
Assert . False ( actual ) ;
}
[Fact]
public void SplitToEvenOdd_InvalidValue_False ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:53:19 -04:00
string baseFileName = Guid . NewGuid ( ) . ToString ( ) ;
string even = $"{baseFileName}.even" ;
string odd = $"{baseFileName}.odd" ;
bool actual = input . SplitToEvenOdd ( even , odd , - 1 ) ;
Assert . False ( actual ) ;
}
[Theory]
[InlineData(1, "Ti os' ac ntig", "hsdentmthayhn")]
[InlineData(2, "Th dsn mchnyin", "isoe'tat athg")]
[InlineData(4, "Thissn'tch aing", " doe matnyth")]
[InlineData(8, "This doech anyth", "sn't mating")]
public void SplitToEvenOdd_ValidFile_True ( int blockSize , string expectedEven , string expectedOdd )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:53:19 -04:00
string baseFileName = Guid . NewGuid ( ) . ToString ( ) ;
string even = $"{baseFileName}.even" ;
string odd = $"{baseFileName}.odd" ;
bool actual = input . SplitToEvenOdd ( even , odd , blockSize ) ;
Assert . True ( actual ) ;
string text = File . ReadAllText ( even ) ;
Assert . Equal ( expectedEven , text ) ;
text = File . ReadAllText ( odd ) ;
Assert . Equal ( expectedOdd , text ) ;
File . Delete ( even ) ;
File . Delete ( odd ) ;
}
[Fact]
public void SplitToEvenOdd_ValidFile_SameEvenOdd_False ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:53:19 -04:00
string baseFileName = Guid . NewGuid ( ) . ToString ( ) ;
string evenOdd = $"{baseFileName}.all" ;
bool actual = input . SplitToEvenOdd ( evenOdd , evenOdd , 4 ) ;
Assert . False ( actual ) ;
File . Delete ( evenOdd ) ;
}
#endregion
2026-03-24 09:05:23 -04:00
#region Swap
[Fact]
public void Swap_EmptyFileName_False ( )
{
string input = string . Empty ;
string output = string . Empty ;
bool actual = input . Swap ( output , SwapOperation . Byteswap ) ;
Assert . False ( actual ) ;
}
[Fact]
public void Swap_InvalidFile_False ( )
{
string input = "INVALID" ;
string output = string . Empty ;
bool actual = input . Swap ( output , SwapOperation . Byteswap ) ;
Assert . False ( actual ) ;
}
[Fact]
public void Swap_InvalidType_False ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
bool actual = input . Swap ( output , ( SwapOperation ) int . MaxValue ) ;
Assert . False ( actual ) ;
}
[Fact]
public void Swap_Valid_True ( )
{
2026-07-09 15:58:03 -04:00
string input = Path . Combine ( Environment . CurrentDirectory , "TestData" , "Path" , "ascii.txt" ) ;
2026-03-24 09:05:23 -04:00
string output = Guid . NewGuid ( ) . ToString ( ) ;
// Bitswap
bool actual = input . Swap ( output , SwapOperation . Bitswap ) ;
Assert . True ( actual ) ;
byte [ ] actualBytes = File . ReadAllBytes ( output ) ;
Assert . True ( new byte [ ] { 0x2A , 0x16 , 0x96 , 0xCE , 0x04 , 0x26 , 0xF6 , 0xA6 , 0xCE , 0x76 , 0xE4 , 0x2E , 0x04 , 0xB6 , 0x86 , 0x2E , 0xC6 , 0x16 , 0x04 , 0x86 , 0x76 , 0x9E , 0x2E , 0x16 , 0x96 , 0x76 , 0xE6 } . EqualsExactly ( actualBytes ) ) ;
// Byteswap
actual = input . Swap ( output , SwapOperation . Byteswap ) ;
Assert . True ( actual ) ;
actualBytes = File . ReadAllBytes ( output ) ;
Assert . True ( new byte [ ] { 0x68 , 0x54 , 0x73 , 0x69 , 0x64 , 0x20 , 0x65 , 0x6F , 0x6E , 0x73 , 0x74 , 0x27 , 0x6D , 0x20 , 0x74 , 0x61 , 0x68 , 0x63 , 0x61 , 0x20 , 0x79 , 0x6E , 0x68 , 0x74 , 0x6E , 0x69 , 0x67 } . EqualsExactly ( actualBytes ) ) ;
// Wordswap
actual = input . Swap ( output , SwapOperation . Wordswap ) ;
Assert . True ( actual ) ;
actualBytes = File . ReadAllBytes ( output ) ;
Assert . True ( new byte [ ] { 0x69 , 0x73 , 0x54 , 0x68 , 0x6F , 0x65 , 0x20 , 0x64 , 0x27 , 0x74 , 0x73 , 0x6E , 0x61 , 0x74 , 0x20 , 0x6D , 0x20 , 0x61 , 0x63 , 0x68 , 0x74 , 0x68 , 0x6E , 0x79 , 0x69 , 0x6E , 0x67 } . EqualsExactly ( actualBytes ) ) ;
// WordByteswap
actual = input . Swap ( output , SwapOperation . WordByteswap ) ;
Assert . True ( actual ) ;
actualBytes = File . ReadAllBytes ( output ) ;
Assert . True ( new byte [ ] { 0x73 , 0x69 , 0x68 , 0x54 , 0x65 , 0x6F , 0x64 , 0x20 , 0x74 , 0x27 , 0x6E , 0x73 , 0x74 , 0x61 , 0x6D , 0x20 , 0x61 , 0x20 , 0x68 , 0x63 , 0x68 , 0x74 , 0x79 , 0x6E , 0x69 , 0x6E , 0x67 } . EqualsExactly ( actualBytes ) ) ;
File . Delete ( output ) ;
}
#endregion
2024-11-25 17:09:33 -05:00
/// <summary>
/// Represents a hidden non-seekable stream
/// </summary>
private class HiddenNonSeekableStream : Stream
{
public override bool CanRead = > true ;
public override bool CanSeek = > true ;
public override bool CanWrite = > true ;
public override long Length = > 16 ;
public override long Position { get = > 8 ; set = > throw new NotSupportedException ( ) ; }
public override void Flush ( )
{
throw new NotImplementedException ( ) ;
}
public override int Read ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
public override long Seek ( long offset , SeekOrigin origin )
{
throw new NotImplementedException ( ) ;
}
public override void SetLength ( long value )
{
throw new NotImplementedException ( ) ;
}
public override void Write ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// Represents a non-seekable stream
/// </summary>
private class NonSeekableStream : Stream
{
public override bool CanRead = > true ;
public override bool CanSeek = > false ;
public override bool CanWrite = > true ;
public override long Length = > 16 ;
public override long Position { get = > 8 ; set = > throw new NotSupportedException ( ) ; }
public override void Flush ( )
{
throw new NotImplementedException ( ) ;
}
public override int Read ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
public override long Seek ( long offset , SeekOrigin origin )
{
throw new NotImplementedException ( ) ;
}
public override void SetLength ( long value )
{
throw new NotImplementedException ( ) ;
}
public override void Write ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// Represents a non-seekable, non-positionable stream
/// </summary>
private class NonPositionableStream : Stream
{
public override bool CanRead = > true ;
public override bool CanSeek = > false ;
public override bool CanWrite = > true ;
public override long Length = > 16 ;
public override long Position { get = > throw new NotSupportedException ( ) ; set = > throw new NotSupportedException ( ) ; }
public override void Flush ( )
{
throw new NotImplementedException ( ) ;
}
public override int Read ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
public override long Seek ( long offset , SeekOrigin origin )
{
throw new NotImplementedException ( ) ;
}
public override void SetLength ( long value )
{
throw new NotImplementedException ( ) ;
}
public override void Write ( byte [ ] buffer , int offset , int count )
{
throw new NotImplementedException ( ) ;
}
}
}
2025-07-23 10:25:19 -04:00
}