Rename and parameterize crc function to crc32
This commit is contained in:
parent
a05903df4d
commit
4d9ce95f6f
@ -35,7 +35,7 @@ namespace XNeedle.Parser
|
|||||||
static Parser<Expression> Function(Context ctx)
|
static Parser<Expression> Function(Context ctx)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
from name in Parse.Letter.AtLeastOnce().Text()
|
from name in Identifier
|
||||||
from lparen in Parse.Char('(')
|
from lparen in Parse.Char('(')
|
||||||
from expr in Parse.Ref(() => Expr(ctx)).DelimitedBy(Parse.Char(',').Token()).Optional()
|
from expr in Parse.Ref(() => Expr(ctx)).DelimitedBy(Parse.Char(',').Token()).Optional()
|
||||||
from rparen in Parse.Char(')')
|
from rparen in Parse.Char(')')
|
||||||
@ -46,23 +46,44 @@ namespace XNeedle.Parser
|
|||||||
{
|
{
|
||||||
var mathMethodInfo = typeof(Math).GetTypeInfo().GetMethod(name, parameters.Select(e => e.Type).ToArray());
|
var mathMethodInfo = typeof(Math).GetTypeInfo().GetMethod(name, parameters.Select(e => e.Type).ToArray());
|
||||||
if (mathMethodInfo != null)
|
if (mathMethodInfo != null)
|
||||||
{
|
|
||||||
return Expression.Call(mathMethodInfo, parameters);
|
return Expression.Call(mathMethodInfo, parameters);
|
||||||
}
|
|
||||||
var ctxMethodInfo = typeof(ContextFunctions).GetTypeInfo().GetMethod(name, parameters.Select(e => e.Type).Prepend(typeof(Context)).ToArray());
|
// Find by name and fill in optional parameters with their default values
|
||||||
|
var ctxMethodInfo = typeof(ContextFunctions).GetTypeInfo()
|
||||||
|
.GetMethods()
|
||||||
|
.FirstOrDefault(m =>
|
||||||
|
{
|
||||||
|
if (m.Name != name) return false;
|
||||||
|
var mp = m.GetParameters();
|
||||||
|
if (mp.Length == 0 || mp[0].ParameterType != typeof(Context)) return false;
|
||||||
|
int required = mp.Skip(1).Count(p => !p.HasDefaultValue);
|
||||||
|
return parameters.Length >= required && parameters.Length <= mp.Length - 1;
|
||||||
|
});
|
||||||
|
|
||||||
if (ctxMethodInfo != null)
|
if (ctxMethodInfo != null)
|
||||||
{
|
{
|
||||||
return Expression.Call(ctxMethodInfo, parameters.Prepend(CtxParam).ToArray());
|
var mp = ctxMethodInfo.GetParameters();
|
||||||
|
var args = mp.Skip(1).Select((p, i) =>
|
||||||
|
i < parameters.Length
|
||||||
|
? parameters[i]
|
||||||
|
: Expression.Constant(p.DefaultValue, p.ParameterType)
|
||||||
|
).ToArray();
|
||||||
|
return Expression.Call(ctxMethodInfo, args.Prepend(CtxParam).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ParseException(string.Format("Function '{0}({1})' does not exist.", name,
|
throw new ParseException(string.Format("Function '{0}({1})' does not exist.", name,
|
||||||
string.Join(",", parameters.Select(e => e.Type.Name))));
|
string.Join(",", parameters.Select(e => e.Type.Name))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly Parser<string> HexNumber =
|
||||||
|
from prefix in Parse.String("0x").Token()
|
||||||
|
from number in Parse.Char(char.IsAsciiHexDigit, "hexadecimal digit").AtLeastOnce().Text()
|
||||||
|
select number;
|
||||||
|
|
||||||
static readonly Parser<Expression> NumberConstant =
|
static readonly Parser<Expression> NumberConstant =
|
||||||
Parse.Decimal
|
HexNumber.Select(x => Expression.Constant(int.Parse(x, System.Globalization.NumberStyles.HexNumber)))
|
||||||
.Select(x => Expression.Constant(double.Parse(x)))
|
.XOr(Parse.Decimal.Select(x => Expression.Constant(double.Parse(x))))
|
||||||
.Named("number");
|
.Named("number");
|
||||||
|
|
||||||
private static readonly Parser<Expression> StringConstant =
|
private static readonly Parser<Expression> StringConstant =
|
||||||
from open in Parse.Char('"')
|
from open in Parse.Char('"')
|
||||||
@ -184,10 +205,6 @@ namespace XNeedle.Parser
|
|||||||
from close in Parse.Char(')')
|
from close in Parse.Char(')')
|
||||||
select new Call{Identifier = new string(identifier.ToArray()), Arguments = arguments};
|
select new Call{Identifier = new string(identifier.ToArray()), Arguments = arguments};
|
||||||
|
|
||||||
/*public static readonly Parser<Expression> ExpressionObject =
|
|
||||||
from expression in CallObject
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static CommentParser Comment = new CommentParser { Single = "#", NewLine = Environment.NewLine };
|
public static CommentParser Comment = new CommentParser { Single = "#", NewLine = Environment.NewLine };
|
||||||
|
|
||||||
public static readonly Parser<Part> BangObject =
|
public static readonly Parser<Part> BangObject =
|
||||||
|
|||||||
@ -26,7 +26,41 @@ namespace XNeedle.Transformation
|
|||||||
level++;
|
level++;
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
public static double crc(Context ctx)
|
|
||||||
|
private static uint ComputeCrc32(byte[] data, uint poly, uint init, uint xorOut, bool reflected)
|
||||||
|
{
|
||||||
|
uint crc = init;
|
||||||
|
uint polyReflected = ReflectBits(poly, 32);
|
||||||
|
foreach (byte b in data)
|
||||||
|
{
|
||||||
|
if (reflected)
|
||||||
|
{
|
||||||
|
crc ^= b;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
crc = (crc & 1) != 0 ? (crc >> 1) ^ polyReflected : crc >> 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crc ^= (uint)b << 24;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
crc = (crc & 0x80000000u) != 0 ? (crc << 1) ^ poly : crc << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc ^ xorOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ReflectBits(uint value, int bits)
|
||||||
|
{
|
||||||
|
uint reflected = 0;
|
||||||
|
for (int i = 0; i < bits; i++)
|
||||||
|
{
|
||||||
|
if ((value & (1u << i)) != 0)
|
||||||
|
reflected |= 1u << (bits - 1 - i);
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double crc32(Context ctx, int poly = 0x04C11DB7, int init = 0, int xorOut = 0, bool reflected = false)
|
||||||
{
|
{
|
||||||
if (ctx.Node is null)
|
if (ctx.Node is null)
|
||||||
return 0;
|
return 0;
|
||||||
@ -40,13 +74,11 @@ namespace XNeedle.Transformation
|
|||||||
// Step 2: Extract all text after the opening tag through and including the closing tag
|
// Step 2: Extract all text after the opening tag through and including the closing tag
|
||||||
string tagName = ctx.Node.Name.LocalName;
|
string tagName = ctx.Node.Name.LocalName;
|
||||||
string data = XmlFragParser.ChecksumData(tagName).Parse(xml);
|
string data = XmlFragParser.ChecksumData(tagName).Parse(xml);
|
||||||
|
//byte[] fragBytes = ctx.SLoc.Encoding.GetBytes(data);
|
||||||
|
byte[] fragBytes = Encoding.UTF8.GetBytes(data);
|
||||||
|
|
||||||
// Step 3: Digest into CRC32 using the source encoding
|
// Step 3: Digest into CRC32 using parameterized CRC32 - by default MPEG-2
|
||||||
var crc32 = new System.IO.Hashing.Crc32();
|
return (double)ComputeCrc32(fragBytes, (uint)poly, (uint)init, (uint)xorOut, reflected);
|
||||||
crc32.Append(ctx.SLoc.Encoding.GetBytes(data));
|
|
||||||
uint result = BitConverter.ToUInt32(crc32.GetCurrentHash());
|
|
||||||
|
|
||||||
return (double)result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string text(Context ctx)
|
public static string text(Context ctx)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user