[Add] FishNet
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using MonoFN.Collections.Generic;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace MonoFN.Cecil
|
||||
{
|
||||
public struct CustomAttributeArgument
|
||||
{
|
||||
public TypeReference Type { get; }
|
||||
public object Value { get; }
|
||||
|
||||
public CustomAttributeArgument(TypeReference type, object value)
|
||||
{
|
||||
Mixin.CheckType(type);
|
||||
this.Type = type;
|
||||
this.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public struct CustomAttributeNamedArgument
|
||||
{
|
||||
public string Name { get; }
|
||||
public CustomAttributeArgument Argument { get; }
|
||||
|
||||
public CustomAttributeNamedArgument(string name, CustomAttributeArgument argument)
|
||||
{
|
||||
Mixin.CheckName(name);
|
||||
this.Name = name;
|
||||
this.Argument = argument;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ICustomAttribute
|
||||
{
|
||||
TypeReference AttributeType { get; }
|
||||
bool HasFields { get; }
|
||||
bool HasProperties { get; }
|
||||
bool HasConstructorArguments { get; }
|
||||
Collection<CustomAttributeNamedArgument> Fields { get; }
|
||||
Collection<CustomAttributeNamedArgument> Properties { get; }
|
||||
Collection<CustomAttributeArgument> ConstructorArguments { get; }
|
||||
}
|
||||
|
||||
[DebuggerDisplay("{AttributeType}")]
|
||||
public sealed class CustomAttribute : ICustomAttribute
|
||||
{
|
||||
internal CustomAttributeValueProjection projection;
|
||||
internal readonly uint signature;
|
||||
internal bool resolved;
|
||||
private byte[] blob;
|
||||
internal Collection<CustomAttributeArgument> arguments;
|
||||
internal Collection<CustomAttributeNamedArgument> fields;
|
||||
internal Collection<CustomAttributeNamedArgument> properties;
|
||||
public MethodReference Constructor { get; set; }
|
||||
public TypeReference AttributeType
|
||||
{
|
||||
get { return Constructor.DeclaringType; }
|
||||
}
|
||||
public bool IsResolved
|
||||
{
|
||||
get { return resolved; }
|
||||
}
|
||||
public bool HasConstructorArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
return !arguments.IsNullOrEmpty();
|
||||
}
|
||||
}
|
||||
public Collection<CustomAttributeArgument> ConstructorArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
if (arguments == null)
|
||||
Interlocked.CompareExchange(ref arguments, new(), null);
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
public bool HasFields
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
return !fields.IsNullOrEmpty();
|
||||
}
|
||||
}
|
||||
public Collection<CustomAttributeNamedArgument> Fields
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
if (fields == null)
|
||||
Interlocked.CompareExchange(ref fields, new(), null);
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
public bool HasProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
return !properties.IsNullOrEmpty();
|
||||
}
|
||||
}
|
||||
public Collection<CustomAttributeNamedArgument> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolve();
|
||||
|
||||
if (properties == null)
|
||||
Interlocked.CompareExchange(ref properties, new(), null);
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
internal bool HasImage
|
||||
{
|
||||
get { return Constructor != null && Constructor.HasImage; }
|
||||
}
|
||||
internal ModuleDefinition Module
|
||||
{
|
||||
get { return Constructor.Module; }
|
||||
}
|
||||
|
||||
internal CustomAttribute(uint signature, MethodReference constructor)
|
||||
{
|
||||
this.signature = signature;
|
||||
this.Constructor = constructor;
|
||||
resolved = false;
|
||||
}
|
||||
|
||||
public CustomAttribute(MethodReference constructor)
|
||||
{
|
||||
this.Constructor = constructor;
|
||||
resolved = true;
|
||||
}
|
||||
|
||||
public CustomAttribute(MethodReference constructor, byte[] blob)
|
||||
{
|
||||
this.Constructor = constructor;
|
||||
resolved = false;
|
||||
this.blob = blob;
|
||||
}
|
||||
|
||||
public byte[] GetBlob()
|
||||
{
|
||||
if (blob != null)
|
||||
return blob;
|
||||
|
||||
if (!HasImage)
|
||||
throw new NotSupportedException();
|
||||
|
||||
return Module.Read(ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob(attribute.signature));
|
||||
}
|
||||
|
||||
private void Resolve()
|
||||
{
|
||||
if (resolved || !HasImage)
|
||||
return;
|
||||
|
||||
lock (Module.SyncRoot)
|
||||
{
|
||||
if (resolved)
|
||||
return;
|
||||
|
||||
Module.Read(this, (attribute, reader) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.ReadCustomAttributeSignature(attribute);
|
||||
resolved = true;
|
||||
}
|
||||
catch (ResolutionException)
|
||||
{
|
||||
if (arguments != null)
|
||||
arguments.Clear();
|
||||
if (fields != null)
|
||||
fields.Clear();
|
||||
if (properties != null)
|
||||
properties.Clear();
|
||||
|
||||
resolved = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user