/// <summary> /// Returns the type arguments for the provided constructed generic type string. /// </summary> public static Type[] GetArguments(this TypeConverter formatter, IdSpan constructed) { var str = constructed.AsSpan(); var index = str.IndexOf((byte)StartArgument); if (index <= 0) { return(Array.Empty <Type>()); } var safeString = "safer" + str.Slice(str.IndexOf((byte)GenericTypeIndicator)).GetUtf8String(); var parsed = RuntimeTypeNameParser.Parse(safeString); if (!(parsed is ConstructedGenericTypeSpec spec)) { throw new InvalidOperationException($"Unable to correctly parse grain type {constructed}"); } var result = new Type[spec.Arguments.Length]; for (var i = 0; i < result.Length; i++) { var arg = spec.Arguments[i]; var formattedArg = arg.Format(); result[i] = formatter.Parse(formattedArg); if (result[i] is null) { throw new InvalidOperationException($"Unable to parse argument \"{formattedArg}\" as a type for grain type \"{constructed}\""); } } return(result); }
/// <summary> /// Returns the deconstructed form of the provided generic type. /// </summary> public static IdSpan GetDeconstructed(IdSpan type) { var span = type.AsSpan(); var index = span.IndexOf((byte)StartArgument); return(index <= 0 ? type : new IdSpan(span.Slice(0, index).ToArray())); }
/// <summary> /// Returns the constructed form of the provided generic type. /// </summary> public static IdSpan GetConstructed(this TypeConverter formatter, IdSpan unconstructed, params Type[] typeArguments) { var typeString = unconstructed.AsSpan(); var indicatorIndex = typeString.IndexOf((byte)GenericTypeIndicator); var arityString = typeString.Slice(indicatorIndex + 1); if (indicatorIndex < 0 || arityString.IndexOf((byte)StartArgument) >= 0) { throw new InvalidOperationException("Cannot construct an already-constructed type"); } if (!Utf8Parser.TryParse(arityString, out int arity, out var len) || len < arityString.Length || typeArguments.Length != arity) { throw new InvalidOperationException($"Insufficient number of type arguments, {typeArguments.Length}, provided while constructing type \"{unconstructed}\""); } var typeSpecs = new TypeSpec[typeArguments.Length]; for (var i = 0; i < typeArguments.Length; i++) { typeSpecs[i] = RuntimeTypeNameParser.Parse(formatter.Format(typeArguments[i])); } var constructed = new ConstructedGenericTypeSpec(new NamedTypeSpec(null, unconstructed.ToStringUtf8(), typeArguments.Length), typeSpecs).Format(); return(IdSpan.Create(constructed)); }
internal static void Write <TWriter>(this TWriter @this, IdSpan value) where TWriter : IBinaryTokenStreamWriter { @this.Write(value.GetHashCode()); var array = IdSpan.UnsafeGetArray(value); @this.Write((ushort)array.Length); @this.Write(array); }
internal static IdSpan ReadIdSpan <TReader>(this TReader @this) where TReader : IBinaryTokenStreamReader { var hashCode = @this.ReadInt(); var len = @this.ReadUShort(); var bytes = @this.ReadBytes(len); return(IdSpan.UnsafeCreate(bytes, hashCode)); }
/// <summary>Constructs a reference to the grain with the specified Id.</summary> protected GrainReference(GrainReferenceShared shared, IdSpan key) { _shared = shared; _key = key; }
/// <summary> /// Returns true if the provided type string is a constructed generic type. /// </summary> public static bool IsConstructed(IdSpan type) => type.AsSpan().IndexOf((byte)StartArgument) > 0;
/// <summary> /// Returns true if the provided type string is a generic type. /// </summary> public static bool IsGenericType(IdSpan type) => type.AsSpan().IndexOf((byte)GenericTypeIndicator) >= 0;
/// <summary> /// Creates a new <see cref="GrainType"/> instance. /// </summary> public GrainType(IdSpan id) => Value = id;
/// <summary> /// Creates a new <see cref="GrainType"/> instance. /// </summary> private GrainId(SerializationInfo info, StreamingContext context) { Type = new GrainType(IdSpan.UnsafeCreate((byte[])info.GetValue("tv", typeof(byte[])), info.GetInt32("th"))); Key = IdSpan.UnsafeCreate((byte[])info.GetValue("kv", typeof(byte[])), info.GetInt32("kh")); }
/// <summary> /// Creates a new <see cref="GrainType"/> instance. /// </summary> public GrainId(GrainType type, IdSpan key) { Type = type; Key = key; }
protected NewGrainReference(GrainReferenceShared shared, IdSpan key) : base(shared, key) { }