Fix up DataConverter...removed pack

This commit is contained in:
Adam Hathcock
2016-02-13 09:42:59 +00:00
parent ff22cd774e
commit 8367bff9fe
4 changed files with 14 additions and 761 deletions

View File

@@ -1,237 +0,0 @@
using System;
namespace SharpCompress.Converter
{
// This is a portable version of Mono's DataConverter class with just the small subset of functionality
// needed by SharpCompress. Portable in this case means that it contains no unsafe code.
//
// This class simply wraps BitConverter and reverses byte arrays when endianess doesn't match the host's.
//
// Everything public in this class must match signatures in Mono's DataConverter.
abstract class DataConverter
{
static readonly DataConverter copyConverter = new CopyConverter();
static readonly DataConverter swapConverter = new SwapConverter();
static readonly bool isLittleEndian = BitConverter.IsLittleEndian;
public static DataConverter LittleEndian
{
get { return isLittleEndian ? copyConverter : swapConverter; }
}
public static DataConverter BigEndian
{
get { return isLittleEndian ? swapConverter : copyConverter; }
}
public abstract Int16 GetInt16(byte[] data, int index);
public abstract UInt16 GetUInt16(byte[] data, int index);
public abstract Int32 GetInt32(byte[] data, int index);
public abstract UInt32 GetUInt32(byte[] data, int index);
public abstract Int64 GetInt64(byte[] data, int index);
public abstract UInt64 GetUInt64(byte[] data, int index);
public abstract byte[] GetBytes(Int16 value);
public abstract byte[] GetBytes(UInt16 value);
public abstract byte[] GetBytes(Int32 value);
public abstract byte[] GetBytes(UInt32 value);
public abstract byte[] GetBytes(Int64 value);
public abstract byte[] GetBytes(UInt64 value);
public void PutBytes(byte[] data, int index, Int16 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 2);
}
public void PutBytes(byte[] data, int index, UInt16 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 2);
}
public void PutBytes(byte[] data, int index, Int32 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 4);
}
public void PutBytes(byte[] data, int index, UInt32 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 4);
}
public void PutBytes(byte[] data, int index, Int64 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 8);
}
public void PutBytes(byte[] data, int index, UInt64 value)
{
byte[] temp = GetBytes(value);
Array.Copy(temp, 0, data, index, 8);
}
// CopyConverter wraps BitConverter making all conversions host endian
class CopyConverter : DataConverter
{
public override Int16 GetInt16(byte[] data, int index)
{
return BitConverter.ToInt16(data, index);
}
public override UInt16 GetUInt16(byte[] data, int index)
{
return BitConverter.ToUInt16(data, index);
}
public override Int32 GetInt32(byte[] data, int index)
{
return BitConverter.ToInt32(data, index);
}
public override UInt32 GetUInt32(byte[] data, int index)
{
return BitConverter.ToUInt32(data, index);
}
public override Int64 GetInt64(byte[] data, int index)
{
return BitConverter.ToInt64(data, index);
}
public override UInt64 GetUInt64(byte[] data, int index)
{
return BitConverter.ToUInt64(data, index);
}
public override byte[] GetBytes(Int16 value)
{
return BitConverter.GetBytes(value);
}
public override byte[] GetBytes(UInt16 value)
{
return BitConverter.GetBytes(value);
}
public override byte[] GetBytes(Int32 value)
{
return BitConverter.GetBytes(value);
}
public override byte[] GetBytes(UInt32 value)
{
return BitConverter.GetBytes(value);
}
public override byte[] GetBytes(Int64 value)
{
return BitConverter.GetBytes(value);
}
public override byte[] GetBytes(UInt64 value)
{
return BitConverter.GetBytes(value);
}
}
// SwapConverter wraps and reverses BitConverter making all conversions the opposite of host endian
class SwapConverter : DataConverter
{
public override Int16 GetInt16(byte[] data, int index)
{
byte[] temp = new byte[2];
Array.Copy(data, index, temp, 0, 2);
Array.Reverse(temp);
return BitConverter.ToInt16(temp, 0);
}
public override UInt16 GetUInt16(byte[] data, int index)
{
byte[] temp = new byte[2];
Array.Copy(data, index, temp, 0, 2);
Array.Reverse(temp);
return BitConverter.ToUInt16(temp, 0);
}
public override Int32 GetInt32(byte[] data, int index)
{
byte[] temp = new byte[4];
Array.Copy(data, index, temp, 0, 4);
Array.Reverse(temp);
return BitConverter.ToInt32(temp, 0);
}
public override UInt32 GetUInt32(byte[] data, int index)
{
byte[] temp = new byte[4];
Array.Copy(data, index, temp, 0, 4);
Array.Reverse(temp);
return BitConverter.ToUInt32(temp, 0);
}
public override Int64 GetInt64(byte[] data, int index)
{
byte[] temp = new byte[8];
Array.Copy(data, index, temp, 0, 8);
Array.Reverse(temp);
return BitConverter.ToInt64(temp, 0);
}
public override UInt64 GetUInt64(byte[] data, int index)
{
byte[] temp = new byte[8];
Array.Copy(data, index, temp, 0, 8);
Array.Reverse(temp);
return BitConverter.ToUInt64(temp, 0);
}
public override byte[] GetBytes(Int16 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
public override byte[] GetBytes(UInt16 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
public override byte[] GetBytes(Int32 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
public override byte[] GetBytes(UInt32 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
public override byte[] GetBytes(Int64 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
public override byte[] GetBytes(UInt64 value)
{
byte[] ret = BitConverter.GetBytes(value);
Array.Reverse(ret);
return ret;
}
}
}
}

View File

@@ -1,5 +1,6 @@
#if !NO_CRYPTO
using System;
using System.Security.Cryptography;
using SharpCompress.Converter;
using System.Text;

View File

@@ -36,6 +36,7 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Text;
@@ -227,286 +228,7 @@ namespace SharpCompress.Converter {
return buffer;
}
}
//
// Format includes:
// Control:
// ^ Switch to big endian encoding
// _ Switch to little endian encoding
// % Switch to host (native) encoding
// ! aligns the next data type to its natural boundary (for strings this is 4).
//
// Types:
// s Int16
// S UInt16
// i Int32
// I UInt32
// l Int64
// L UInt64
// f float
// d double
// b byte
// c 1-byte signed character
// C 1-byte unsigned character
// z8 string encoded as UTF8 with 1-byte null terminator
// z6 string encoded as UTF16 with 2-byte null terminator
// z7 string encoded as UTF7 with 1-byte null terminator
// zb string encoded as BigEndianUnicode with 2-byte null terminator
// z3 string encoded as UTF32 with 4-byte null terminator
// z4 string encoded as UTF32 big endian with 4-byte null terminator
// $8 string encoded as UTF8
// $6 string encoded as UTF16
// $7 string encoded as UTF7
// $b string encoded as BigEndianUnicode
// $3 string encoded as UTF32
// $4 string encoded as UTF-32 big endian encoding
// x null byte
//
// Repeats, these are prefixes:
// N a number between 1 and 9, indicates a repeat count (process N items
// with the following datatype
// [N] For numbers larger than 9, use brackets, for example [20]
// * Repeat the next data type until the arguments are exhausted
//
static public byte [] Pack (string description, params object [] args)
{
int argn = 0;
PackContext b = new PackContext ();
b.conv = CopyConv;
b.description = description;
for (b.i = 0; b.i < description.Length; ){
object oarg;
if (argn < args.Length)
oarg = args [argn];
else {
if (b.repeat != 0)
break;
oarg = null;
}
int save = b.i;
if (PackOne (b, oarg)){
argn++;
if (b.repeat > 0){
if (--b.repeat > 0)
b.i = save;
else
b.i++;
} else
b.i++;
} else
b.i++;
}
return b.Get ();
}
static public byte [] PackEnumerable (string description, IEnumerable args)
{
PackContext b = new PackContext ();
b.conv = CopyConv;
b.description = description;
IEnumerator enumerator = args.GetEnumerator ();
bool ok = enumerator.MoveNext ();
for (b.i = 0; b.i < description.Length; ){
object oarg;
if (ok)
oarg = enumerator.Current;
else {
if (b.repeat != 0)
break;
oarg = null;
}
int save = b.i;
if (PackOne (b, oarg)){
ok = enumerator.MoveNext ();
if (b.repeat > 0){
if (--b.repeat > 0)
b.i = save;
else
b.i++;
} else
b.i++;
} else
b.i++;
}
return b.Get ();
}
//
// Packs one datum `oarg' into the buffer `b', using the string format
// in `description' at position `i'
//
// Returns: true if we must pick the next object from the list
//
static bool PackOne (PackContext b, object oarg)
{
int n;
switch (b.description [b.i]){
case '^':
b.conv = BigEndian;
return false;
case '_':
b.conv = LittleEndian;
return false;
case '%':
b.conv = Native;
return false;
case '!':
b.align = -1;
return false;
case 'x':
b.Add (new byte [] { 0 });
return false;
// Type Conversions
case 'i':
b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg)));
break;
case 'I':
b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg)));
break;
case 's':
b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg)));
break;
case 'S':
b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg)));
break;
case 'l':
b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg)));
break;
case 'L':
b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg)));
break;
case 'f':
b.Add (b.conv.GetBytes (Convert.ToSingle (oarg)));
break;
case 'd':
b.Add (b.conv.GetBytes (Convert.ToDouble (oarg)));
break;
case 'b':
b.Add (new byte [] { Convert.ToByte (oarg) });
break;
case 'c':
b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) });
break;
case 'C':
b.Add (new byte [] { Convert.ToByte (oarg) });
break;
// Repeat acount;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
b.repeat = ((short) b.description [b.i]) - ((short) '0');
return false;
case '*':
b.repeat = Int32.MaxValue;
return false;
case '[':
int count = -1, j;
for (j = b.i+1; j < b.description.Length; j++){
if (b.description [j] == ']')
break;
n = ((short) b.description [j]) - ((short) '0');
if (n >= 0 && n <= 9){
if (count == -1)
count = n;
else
count = count * 10 + n;
}
}
if (count == -1)
throw new ArgumentException ("invalid size specification");
b.i = j;
b.repeat = count;
return false;
case '$': case 'z':
bool add_null = b.description [b.i] == 'z';
b.i++;
if (b.i >= b.description.Length)
throw new ArgumentException ("$ description needs a type specified", "description");
char d = b.description [b.i];
Encoding e;
switch (d){
case '8':
e = Encoding.UTF8;
n = 1;
break;
case '6':
e = Encoding.Unicode;
n = 2;
break;
case '7':
#if PCL
e = Encoding.GetEncoding ("utf-7");
#else
e = Encoding.UTF7;
#endif
n = 1;
break;
case 'b':
e = Encoding.BigEndianUnicode;
n = 2;
break;
case '3':
#if PCL
e = Encoding.GetEncoding ("utf-32");
#else
e = Encoding.GetEncoding (12000);
#endif
n = 4;
break;
case '4':
#if PCL
e = Encoding.GetEncoding ("utf-32BE");
#else
e = Encoding.GetEncoding (12001);
#endif
n = 4;
break;
default:
throw new ArgumentException ("Invalid format for $ specifier", "description");
}
if (b.align == -1)
b.align = 4;
b.Add (e.GetBytes (Convert.ToString (oarg)));
if (add_null)
b.Add (new byte [n]);
break;
default:
throw new ArgumentException (String.Format ("invalid format specified `{0}'",
b.description [b.i]));
}
return true;
}
static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
{
if (align){
@@ -520,246 +242,6 @@ namespace SharpCompress.Converter {
return true;
}
static public IList Unpack (string description, byte [] buffer, int startIndex)
{
DataConverter conv = CopyConv;
var result = new List<object> ();
int idx = startIndex;
bool align = false;
int repeat = 0, n;
for (int i = 0; i < description.Length && idx < buffer.Length; ){
int save = i;
switch (description [i]){
case '^':
conv = BigEndian;
break;
case '_':
conv = LittleEndian;
break;
case '%':
conv = Native;
break;
case 'x':
idx++;
break;
case '!':
align = true;
break;
// Type Conversions
case 'i':
if (Prepare (buffer, ref idx, 4, ref align)){
result.Add (conv.GetInt32 (buffer, idx));
idx += 4;
}
break;
case 'I':
if (Prepare (buffer, ref idx, 4, ref align)){
result.Add (conv.GetUInt32 (buffer, idx));
idx += 4;
}
break;
case 's':
if (Prepare (buffer, ref idx, 2, ref align)){
result.Add (conv.GetInt16 (buffer, idx));
idx += 2;
}
break;
case 'S':
if (Prepare (buffer, ref idx, 2, ref align)){
result.Add (conv.GetUInt16 (buffer, idx));
idx += 2;
}
break;
case 'l':
if (Prepare (buffer, ref idx, 8, ref align)){
result.Add (conv.GetInt64 (buffer, idx));
idx += 8;
}
break;
case 'L':
if (Prepare (buffer, ref idx, 8, ref align)){
result.Add (conv.GetUInt64 (buffer, idx));
idx += 8;
}
break;
case 'f':
if (Prepare (buffer, ref idx, 4, ref align)){
result.Add (conv.GetFloat (buffer, idx));
idx += 4;
}
break;
case 'd':
if (Prepare (buffer, ref idx, 8, ref align)){
result.Add (conv.GetDouble (buffer, idx));
idx += 8;
}
break;
case 'b':
if (Prepare (buffer, ref idx, 1, ref align)){
result.Add (buffer [idx]);
idx++;
}
break;
case 'c': case 'C':
if (Prepare (buffer, ref idx, 1, ref align)){
char c;
if (description [i] == 'c')
c = ((char) ((sbyte)buffer [idx]));
else
c = ((char) ((byte)buffer [idx]));
result.Add (c);
idx++;
}
break;
// Repeat acount;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
repeat = ((short) description [i]) - ((short) '0');
save = i + 1;
break;
case '*':
repeat = Int32.MaxValue;
break;
case '[':
int count = -1, j;
for (j = i+1; j < description.Length; j++){
if (description [j] == ']')
break;
n = ((short) description [j]) - ((short) '0');
if (n >= 0 && n <= 9){
if (count == -1)
count = n;
else
count = count * 10 + n;
}
}
if (count == -1)
throw new ArgumentException ("invalid size specification");
i = j;
save = i + 1;
repeat = count;
break;
case '$': case 'z':
// bool with_null = description [i] == 'z';
i++;
if (i >= description.Length)
throw new ArgumentException ("$ description needs a type specified", "description");
char d = description [i];
Encoding e;
if (align){
idx = Align (idx, 4);
align = false;
}
if (idx >= buffer.Length)
break;
switch (d){
case '8':
e = Encoding.UTF8;
n = 1;
break;
case '6':
e = Encoding.Unicode;
n = 2;
break;
case '7':
e = Encoding.UTF7;
n = 1;
break;
case 'b':
e = Encoding.BigEndianUnicode;
n = 2;
break;
case '3':
e = Encoding.GetEncoding (12000);
n = 4;
break;
case '4':
e = Encoding.GetEncoding (12001);
n = 4;
break;
default:
throw new ArgumentException ("Invalid format for $ specifier", "description");
}
int k = idx;
switch (n){
case 1:
for (; k < buffer.Length && buffer [k] != 0; k++)
;
result.Add (e.GetChars (buffer, idx, k-idx));
if (k == buffer.Length)
idx = k;
else
idx = k+1;
break;
case 2:
for (; k < buffer.Length; k++){
if (k+1 == buffer.Length){
k++;
break;
}
if (buffer [k] == 0 && buffer [k+1] == 0)
break;
}
result.Add (e.GetChars (buffer, idx, k-idx));
if (k == buffer.Length)
idx = k;
else
idx = k+2;
break;
case 4:
for (; k < buffer.Length; k++){
if (k+3 >= buffer.Length){
k = buffer.Length;
break;
}
if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
break;
}
result.Add (e.GetChars (buffer, idx, k-idx));
if (k == buffer.Length)
idx = k;
else
idx = k+4;
break;
}
break;
default:
throw new ArgumentException (String.Format ("invalid format specified `{0}'",
description [i]));
}
if (repeat > 0){
if (--repeat > 0)
i = save;
} else
i++;
}
return result;
}
internal void Check (byte [] dest, int destIdx, int size)
{
@@ -1846,4 +1328,4 @@ namespace SharpCompress.Converter {
#endif
}
}
}

View File

@@ -12,21 +12,26 @@
"frameworks": {
"net35": {
"compilationOptions": {
"warningsAsErrors": true
"warningsAsErrors": true,
"allowUnsafe": true
}
},
"net40": {
"compilationOptions": {
"warningsAsErrors": true
"warningsAsErrors": true,
"allowUnsafe": true
}
},
"net45": {
"compilationOptions": {
"warningsAsErrors": true
"warningsAsErrors": true,
"allowUnsafe": true
}
},
".NETPortable,Version=v4.5,Profile=Profile259": {
"compilationOptions": {
"warningsAsErrors": true,
"allowUnsafe": true,
"define": [ "PROFILE259", "NO_FILE", "NO_CRYPTO" ]
},
"frameworkAssemblies": {
@@ -50,6 +55,7 @@
"dotnet5.1": {
"compilationOptions": {
"warningsAsErrors": true,
"allowUnsafe": true,
"define": [ "DOTNET51", "NO_FILE" ]
},
"dependencies": {
@@ -65,6 +71,7 @@
"dnxcore50": {
"compilationOptions": {
"warningsAsErrors": true,
"allowUnsafe": true,
"define": [ "DNXCORE50" ]
},
"dependencies": {