2020-01-04 16:38:18 +00:00
namespace UglyToad.PdfPig.PdfFonts.CompactFontFormat
2018-11-16 21:30:59 +00:00
{
using System ;
2018-11-24 19:02:06 +00:00
using System.Collections.Generic ;
2018-11-18 13:53:43 +00:00
using System.Diagnostics ;
2018-11-16 21:30:59 +00:00
using System.Text ;
2020-01-04 16:38:18 +00:00
using Core ;
2018-11-16 21:30:59 +00:00
/// <summary>
/// Provides access to the raw bytes of this Compact Font Format file with utility methods for reading data types from it.
/// </summary>
internal class CompactFontFormatData
{
2018-11-24 19:02:06 +00:00
private readonly IReadOnlyList < byte > dataBytes ;
2018-11-16 21:30:59 +00:00
public int Position { get ; private set ; } = - 1 ;
2018-11-24 19:02:06 +00:00
public int Length = > dataBytes . Count ;
2018-11-18 13:53:43 +00:00
[DebuggerStepThrough]
2018-11-24 19:02:06 +00:00
public CompactFontFormatData ( IReadOnlyList < byte > dataBytes )
2018-11-16 21:30:59 +00:00
{
this . dataBytes = dataBytes ;
}
public string ReadString ( int length , Encoding encoding )
{
var bytes = new byte [ length ] ;
for ( var i = 0 ; i < bytes . Length ; i + + )
{
bytes [ i ] = ReadByte ( ) ;
}
return encoding . GetString ( bytes ) ;
}
public byte ReadCard8 ( )
{
return ReadByte ( ) ;
}
public ushort ReadCard16 ( )
{
return ( ushort ) ( ReadByte ( ) < < 8 | ReadByte ( ) ) ;
}
public byte ReadOffsize ( )
{
return ReadByte ( ) ;
}
public int ReadOffset ( int offsetSize )
{
var value = 0 ;
for ( var i = 0 ; i < offsetSize ; i + + )
{
value = value < < 8 | ReadByte ( ) ;
}
return value ;
}
public byte ReadByte ( )
{
Position + + ;
2018-11-24 19:02:06 +00:00
if ( Position > = dataBytes . Count )
2018-11-16 21:30:59 +00:00
{
2018-11-24 19:02:06 +00:00
throw new IndexOutOfRangeException ( $"Cannot read byte at position {Position} of an array which is {dataBytes.Count} bytes long." ) ;
2018-11-16 21:30:59 +00:00
}
return dataBytes [ Position ] ;
}
public byte Peek ( )
{
return dataBytes [ Position + 1 ] ;
}
public bool CanRead ( )
{
2018-11-24 19:02:06 +00:00
return Position < dataBytes . Count - 1 ;
2018-11-16 21:30:59 +00:00
}
public void Seek ( int offset )
{
Position = offset - 1 ;
}
public long ReadLong ( )
{
return ( ReadCard16 ( ) < < 16 ) | ReadCard16 ( ) ;
}
2018-11-16 23:32:18 +00:00
public int ReadSid ( )
{
return ReadByte ( ) < < 8 | ReadByte ( ) ;
}
2018-11-16 21:30:59 +00:00
public byte [ ] ReadBytes ( int length )
{
var result = new byte [ length ] ;
for ( int i = 0 ; i < length ; i + + )
{
result [ i ] = ReadByte ( ) ;
}
return result ;
}
2018-11-18 13:53:43 +00:00
public CompactFontFormatData SnapshotPortion ( int startLocation , int length )
{
2019-05-11 10:00:04 +01:00
if ( length = = 0 )
{
return new CompactFontFormatData ( EmptyArray < byte > . Instance ) ;
}
2018-11-24 19:02:06 +00:00
if ( startLocation > dataBytes . Count - 1 | | startLocation + length > dataBytes . Count )
2018-11-18 13:53:43 +00:00
{
2018-11-24 19:02:06 +00:00
throw new ArgumentException ( $"Attempted to create a snapshot of an invalid portion of the data. Length was {dataBytes.Count}, requested start: {startLocation} and requested length: {length}." ) ;
2018-11-18 13:53:43 +00:00
}
var newData = new byte [ length ] ;
2018-11-24 19:02:06 +00:00
var newI = 0 ;
for ( var i = startLocation ; i < startLocation + length ; i + + )
{
newData [ newI ] = dataBytes [ i ] ;
newI + + ;
}
2018-11-18 13:53:43 +00:00
return new CompactFontFormatData ( newData ) ;
}
2018-11-16 21:30:59 +00:00
}
}