Skip to content

Commit 8d20cdd

Browse files
Initial featurizers project (#4413)
* DateTimeTransformer is done. ToStringTransformer is done. CatagoryImputer is done. TimeSeriesImputer is done. RobustScaler is done. Adding in samples and documentation. General code cleanup. Made the RowToRowMapperTransform create a new mapper if possible for each cursor. * only files needed for initial project checkin * removed samples, fixed nuget * changed dependencies to nightly ML.NET * removed old TODO: * changes from PR comments * Fixes based on PR comments * fixed rebase error * Added line removed by rebase Added line in Directory.Build.Props that was removed during the rebase process. The line already exists in master and shouldn't be removed.
1 parent b4c845b commit 8d20cdd

File tree

11 files changed

+351
-4
lines changed

11 files changed

+351
-4
lines changed

Microsoft.ML.sln

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.AutoML.Samples
271271
EndProject
272272
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Samples.GPU", "docs\samples\Microsoft.ML.Samples.GPU\Microsoft.ML.Samples.GPU.csproj", "{3C8F910B-7F23-4D25-B521-6D5AC9570ADD}"
273273
EndProject
274+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Featurizers", "src\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.csproj", "{E2DD0721-5B0F-4606-8182-4C7EFB834518}"
275+
EndProject
276+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.ML.Featurizers", "Microsoft.ML.Featurizers", "{1BA5C784-52E8-4A87-8525-26B2452F2882}"
277+
ProjectSection(SolutionItems) = preProject
278+
pkg\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.nupkgproj = pkg\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.nupkgproj
279+
pkg\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.symbols.nupkgproj = pkg\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.symbols.nupkgproj
280+
EndProjectSection
281+
EndProject
274282
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CodeGenerator", "src\Microsoft.ML.CodeGenerator\Microsoft.ML.CodeGenerator.csproj", "{56CB0850-7341-4D71-9AE4-9EFC472D93DD}"
275283
EndProject
276284
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CodeGenerator.Tests", "test\Microsoft.ML.CodeGenerator.Tests\Microsoft.ML.CodeGenerator.Tests.csproj", "{46CC5637-3DDF-4100-93FC-44BB87B2DB81}"
@@ -1763,6 +1771,30 @@ Global
17631771
{C8DB58DC-6434-4431-A81F-263D86E2A5F3}.Release-netfx|Any CPU.Build.0 = Release-netfx|Any CPU
17641772
{C8DB58DC-6434-4431-A81F-263D86E2A5F3}.Release-netfx|x64.ActiveCfg = Release-netfx|Any CPU
17651773
{C8DB58DC-6434-4431-A81F-263D86E2A5F3}.Release-netfx|x64.Build.0 = Release-netfx|Any CPU
1774+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1775+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug|Any CPU.Build.0 = Debug|Any CPU
1776+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug|x64.ActiveCfg = Debug|Any CPU
1777+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug|x64.Build.0 = Debug|Any CPU
1778+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netcoreapp3_0|Any CPU.ActiveCfg = Debug-netcoreapp3_0|Any CPU
1779+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netcoreapp3_0|Any CPU.Build.0 = Debug-netcoreapp3_0|Any CPU
1780+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netcoreapp3_0|x64.ActiveCfg = Debug-netcoreapp3_0|Any CPU
1781+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netcoreapp3_0|x64.Build.0 = Debug-netcoreapp3_0|Any CPU
1782+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netfx|Any CPU.ActiveCfg = Debug-netfx|Any CPU
1783+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netfx|Any CPU.Build.0 = Debug-netfx|Any CPU
1784+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netfx|x64.ActiveCfg = Debug-netfx|Any CPU
1785+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Debug-netfx|x64.Build.0 = Debug-netfx|Any CPU
1786+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release|Any CPU.ActiveCfg = Release|Any CPU
1787+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release|Any CPU.Build.0 = Release|Any CPU
1788+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release|x64.ActiveCfg = Release|Any CPU
1789+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release|x64.Build.0 = Release|Any CPU
1790+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netcoreapp3_0|Any CPU.ActiveCfg = Release-netcoreapp3_0|Any CPU
1791+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netcoreapp3_0|Any CPU.Build.0 = Release-netcoreapp3_0|Any CPU
1792+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netcoreapp3_0|x64.ActiveCfg = Release-netcoreapp3_0|Any CPU
1793+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netcoreapp3_0|x64.Build.0 = Release-netcoreapp3_0|Any CPU
1794+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|Any CPU.ActiveCfg = Release-netfx|Any CPU
1795+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|Any CPU.Build.0 = Release-netfx|Any CPU
1796+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|x64.ActiveCfg = Release-netfx|Any CPU
1797+
{E2DD0721-5B0F-4606-8182-4C7EFB834518}.Release-netfx|x64.Build.0 = Release-netfx|Any CPU
17661798
EndGlobalSection
17671799
GlobalSection(SolutionProperties) = preSolution
17681800
HideSolutionNode = FALSE
@@ -1857,6 +1889,8 @@ Global
18571889
{C8DB58DC-6434-4431-A81F-263D86E2A5F3} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
18581890
{C91F81E3-B900-4968-A6DF-F53B515E97E1} = {BF66A305-DF10-47E4-8D81-42049B149D2B}
18591891
{027DBA48-85B6-46F1-9487-0B49B5057FC0} = {C91F81E3-B900-4968-A6DF-F53B515E97E1}
1892+
{E2DD0721-5B0F-4606-8182-4C7EFB834518} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
1893+
{1BA5C784-52E8-4A87-8525-26B2452F2882} = {D3D38B03-B557-484D-8348-8BADEE4DF592}
18601894
EndGlobalSection
18611895
GlobalSection(ExtensibilityGlobals) = postSolution
18621896
SolutionGuid = {41165AF1-35BB-4832-A189-73060F82B01D}

docs/samples/Microsoft.ML.Samples/Microsoft.ML.Samples.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
<ItemGroup>
1313
<ProjectReference Include="..\..\..\src\Microsoft.ML.Vision\Microsoft.ML.Vision.csproj" />
14+
<ProjectReference Include="..\..\..\src\Microsoft.ML.Featurizers\Microsoft.ML.Featurizers.csproj" />
1415
<ProjectReference Include="..\..\..\src\Microsoft.ML.LightGbm\Microsoft.ML.LightGbm.csproj" />
1516
<ProjectReference Include="..\..\..\src\Microsoft.ML.Mkl.Components\Microsoft.ML.Mkl.Components.csproj" />
1617
<ProjectReference Include="..\..\..\src\Microsoft.ML.KMeansClustering\Microsoft.ML.KMeansClustering.csproj" />
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="Pack">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<PackageDescription>ML.NET featurizers with native code implementation</PackageDescription>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="../Microsoft.ML/Microsoft.ML.nupkgproj" />
10+
11+
<PackageReference Include="Microsoft.MLFeaturizers" Version="0.3.5" />
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project DefaultTargets="Pack">
2+
3+
<Import Project="Microsoft.ML.Featurizers.nupkgproj" />
4+
5+
</Project>

src/Microsoft.ML.Core/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@
4040
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Vision" + PublicKey.Value)]
4141
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.TimeSeries" + PublicKey.Value)]
4242
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Transforms" + PublicKey.Value)]
43-
4443
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.AutoML" + PublicKey.Value)]
45-
44+
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Featurizers" + PublicKey.Value)]
4645
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Internal.MetaLinearLearner" + InternalPublicKey.Value)]
4746
[assembly: InternalsVisibleTo(assemblyName: "TreeVisualizer" + InternalPublicKey.Value)]
4847
[assembly: InternalsVisibleTo(assemblyName: "TMSNlearnPrediction" + InternalPublicKey.Value)]

src/Microsoft.ML.Core/Utilities/Utils.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,14 @@ private static MethodInfo MarshalInvokeCheckAndCreate<TRet>(Type genArg, Delegat
966966
return meth;
967967
}
968968

969+
private static MethodInfo MarshalInvokeCheckAndCreate<TRet>(Type[] genArgs, Delegate func)
970+
{
971+
var meth = MarshalActionInvokeCheckAndCreate(genArgs, func);
972+
if (meth.ReturnType != typeof(TRet))
973+
throw Contracts.ExceptParam(nameof(func), "Cannot be generic on return type");
974+
return meth;
975+
}
976+
969977
// REVIEW: n-argument versions? The multi-column re-application problem?
970978
// Think about how to address these.
971979

@@ -1092,6 +1100,28 @@ public static TRet MarshalInvoke<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7
10921100
return (TRet)meth.Invoke(func.Target, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
10931101
}
10941102

1103+
/// <summary>
1104+
/// A 1 argument and n type version of <see cref="MarshalInvoke{TRet}"/>.
1105+
/// </summary>
1106+
public static TRet MarshalInvoke<TArg1, TRet>(
1107+
Func<TArg1, TRet> func,
1108+
Type[] genArgs, TArg1 arg1)
1109+
{
1110+
var meth = MarshalInvokeCheckAndCreate<TRet>(genArgs, func);
1111+
return (TRet)meth.Invoke(func.Target, new object[] { arg1});
1112+
}
1113+
1114+
/// <summary>
1115+
/// A 2 argument and n type version of <see cref="MarshalInvoke{TRet}"/>.
1116+
/// </summary>
1117+
public static TRet MarshalInvoke<TArg1, TArg2, TRet>(
1118+
Func<TArg1, TArg2, TRet> func,
1119+
Type[] genArgs, TArg1 arg1, TArg2 arg2)
1120+
{
1121+
var meth = MarshalInvokeCheckAndCreate<TRet>(genArgs, func);
1122+
return (TRet)meth.Invoke(func.Target, new object[] { arg1, arg2});
1123+
}
1124+
10951125
private static MethodInfo MarshalActionInvokeCheckAndCreate(Type genArg, Delegate func)
10961126
{
10971127
Contracts.CheckValue(genArg, nameof(genArg));
@@ -1104,6 +1134,18 @@ private static MethodInfo MarshalActionInvokeCheckAndCreate(Type genArg, Delegat
11041134
return meth;
11051135
}
11061136

1137+
private static MethodInfo MarshalActionInvokeCheckAndCreate(Type[] typeArguments, Delegate func)
1138+
{
1139+
Contracts.CheckValue(typeArguments, nameof(typeArguments));
1140+
Contracts.CheckValue(func, nameof(func));
1141+
var meth = func.GetMethodInfo();
1142+
Contracts.CheckParam(meth.IsGenericMethod, nameof(func), "Should be generic but is not");
1143+
Contracts.CheckParam(meth.GetGenericArguments().Length == typeArguments.Length, nameof(func),
1144+
"Method should have exactly the same number of generic type parameters as list passed in but it does not.");
1145+
meth = meth.GetGenericMethodDefinition().MakeGenericMethod(typeArguments);
1146+
return meth;
1147+
}
1148+
11071149
/// <summary>
11081150
/// This is akin to <see cref="MarshalInvoke{TRet}(Func{TRet}, Type)"/>, except applied to
11091151
/// <see cref="Action"/> instead of <see cref="Func{TRet}"/>.

src/Microsoft.ML.Data/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@
4444
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.DnnImageFeaturizer.ResNet101" + PublicKey.Value)]
4545
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.DnnImageFeaturizer.ResNet18" + PublicKey.Value)]
4646
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.DnnImageFeaturizer.ResNet50" + PublicKey.Value)]
47-
4847
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Experimental" + PublicKey.Value)]
49-
48+
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Featurizers" + PublicKey.Value)]
5049
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Internal.MetaLinearLearner" + InternalPublicKey.Value)]
5150
[assembly: InternalsVisibleTo(assemblyName: "TMSNlearnPrediction" + InternalPublicKey.Value)]
5251
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.CntkWrapper" + InternalPublicKey.Value)]
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Runtime.InteropServices;
4+
using System.Security;
5+
using System.Text;
6+
using Microsoft.Win32.SafeHandles;
7+
8+
namespace Microsoft.ML.Featurizers
9+
{
10+
internal enum FitResult : byte
11+
{
12+
Complete = 1,
13+
Continue = 2,
14+
ResetAndContinue = 3
15+
}
16+
17+
// Not all these types are currently supported. These are taken directly from the Native code implementation.
18+
internal enum TypeId : uint
19+
{
20+
// Enumeration values are in the following format:
21+
//
22+
// 0xVTTTXXXX
23+
// ^^^^^^^^
24+
// || |- Id
25+
// ||- Number of trailing types
26+
// |- Has trailing types
27+
//
28+
String = 1,
29+
SByte = 2,
30+
Short = 3,
31+
Int = 4,
32+
Long = 5,
33+
Byte = 6,
34+
UShort = 7,
35+
UInt = 8,
36+
ULong = 9,
37+
Float16 = 10,
38+
Float32 = 11,
39+
Double = 12,
40+
Complex64 = 13,
41+
Complex128 = 14,
42+
BFloat16 = 15,
43+
Bool = 16,
44+
Timepoint = 17,
45+
Duration = 18,
46+
47+
LastStaticValue = 19,
48+
49+
// The following values have N number of trailing types
50+
Tensor = 0x1001 | LastStaticValue + 1,
51+
SparseTensor = 0x1001 | LastStaticValue + 2,
52+
Tabular = 0x1001 | LastStaticValue + 3,
53+
54+
Nullable = 0x1001 | LastStaticValue + 4,
55+
Vector = 0x1001 | LastStaticValue + 5,
56+
MapId = 0x1002 | LastStaticValue + 6
57+
};
58+
59+
// Is a struct mirroring the native struct.
60+
// I used to pass binary data between ML.NET and the native code.
61+
[StructLayout(LayoutKind.Sequential, Pack = 1)]
62+
internal unsafe struct NativeBinaryArchiveData
63+
{
64+
public byte* Data;
65+
public IntPtr DataSize;
66+
}
67+
68+
#region SafeHandles
69+
70+
// Safe handle that frees the memory for a native error returned to ML.NET.
71+
internal class ErrorInfoSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
72+
{
73+
[DllImport("Featurizers", EntryPoint = "DestroyErrorInfo", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
74+
private static extern bool DestroyErrorInfo(IntPtr error);
75+
76+
public ErrorInfoSafeHandle(IntPtr handle) : base(true)
77+
{
78+
SetHandle(handle);
79+
}
80+
81+
protected override bool ReleaseHandle()
82+
{
83+
return DestroyErrorInfo(handle);
84+
}
85+
}
86+
87+
// Safe handle that frees the memory for errors strings return from the native code to ML.NET.
88+
internal class ErrorInfoStringSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
89+
{
90+
[DllImport("Featurizers", EntryPoint = "DestroyErrorInfoString", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
91+
private static extern bool DestroyErrorInfoString(IntPtr errorString, IntPtr errorStringSize);
92+
93+
private IntPtr _length;
94+
public ErrorInfoStringSafeHandle(IntPtr handle, IntPtr length) : base(true)
95+
{
96+
SetHandle(handle);
97+
_length = length;
98+
}
99+
100+
protected override bool ReleaseHandle()
101+
{
102+
return DestroyErrorInfoString(handle, _length);
103+
}
104+
}
105+
106+
// Safe handle that frees the memory for the transformed data.
107+
// Is called automatically after each call to transform.
108+
internal delegate bool DestroyTransformedDataNative(IntPtr output, IntPtr outputSize, out IntPtr errorHandle);
109+
internal class TransformedDataSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
110+
{
111+
private DestroyTransformedDataNative _destroySaveDataHandler;
112+
private IntPtr _dataSize;
113+
114+
public TransformedDataSafeHandle(IntPtr handle, IntPtr dataSize, DestroyTransformedDataNative destroyCppTransformerEstimator) : base(true)
115+
{
116+
SetHandle(handle);
117+
_dataSize = dataSize;
118+
_destroySaveDataHandler = destroyCppTransformerEstimator;
119+
}
120+
121+
protected override bool ReleaseHandle()
122+
{
123+
// Not sure what to do with error stuff here. There shoudln't ever be one though.
124+
return _destroySaveDataHandler(handle, _dataSize, out IntPtr errorHandle);
125+
}
126+
}
127+
128+
// Safe handle that frees the memory for a native estimator or transformer.
129+
// Is called automatically at the end of life for a transformer or estimator.
130+
internal delegate bool DestroyNativeTransformerEstimator(IntPtr estimator, out IntPtr errorHandle);
131+
internal class TransformerEstimatorSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
132+
{
133+
private DestroyNativeTransformerEstimator _destroyNativeTransformerEstimator;
134+
public TransformerEstimatorSafeHandle(IntPtr handle, DestroyNativeTransformerEstimator destroyNativeTransformerEstimator) : base(true)
135+
{
136+
SetHandle(handle);
137+
_destroyNativeTransformerEstimator = destroyNativeTransformerEstimator;
138+
}
139+
140+
protected override bool ReleaseHandle()
141+
{
142+
// Not sure what to do with error stuff here. There shouldn't ever be one though.
143+
return _destroyNativeTransformerEstimator(handle, out IntPtr errorHandle);
144+
}
145+
}
146+
147+
// Safe handle that frees the memory for the internal state of a native transformer.
148+
// Is called automatically after we save the model.
149+
internal delegate bool DestroyTransformerSaveData(IntPtr buffer, IntPtr bufferSize, out IntPtr errorHandle);
150+
internal class SaveDataSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
151+
{
152+
private readonly IntPtr _dataSize;
153+
154+
[DllImport("Featurizers", EntryPoint = "DestroyTransformerSaveData", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
155+
private static extern bool DestroyTransformerSaveDataNative(IntPtr buffer, IntPtr bufferSize, out IntPtr error);
156+
157+
public SaveDataSafeHandle(IntPtr handle, IntPtr dataSize) : base(true)
158+
{
159+
SetHandle(handle);
160+
_dataSize = dataSize;
161+
}
162+
163+
protected override bool ReleaseHandle()
164+
{
165+
// Not sure what to do with error stuff here. There shoudln't ever be one though.
166+
return DestroyTransformerSaveDataNative(handle, _dataSize, out _);
167+
}
168+
}
169+
170+
#endregion
171+
172+
// Static extension classes with Common methods used in multiple featurizers
173+
internal static class CommonExtensions
174+
{
175+
[DllImport("Featurizers", EntryPoint = "GetErrorInfoString", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
176+
private static extern bool GetErrorInfoString(IntPtr error, out IntPtr errorHandleString, out IntPtr errorHandleStringSize);
177+
178+
internal static string GetErrorDetailsAndFreeNativeMemory(IntPtr errorHandle)
179+
{
180+
using (var error = new ErrorInfoSafeHandle(errorHandle))
181+
{
182+
GetErrorInfoString(errorHandle, out IntPtr errorHandleString, out IntPtr errorHandleStringSize);
183+
using (var errorString = new ErrorInfoStringSafeHandle(errorHandleString, errorHandleStringSize))
184+
{
185+
byte[] buffer = new byte[errorHandleStringSize.ToInt32()];
186+
Marshal.Copy(errorHandleString, buffer, 0, buffer.Length);
187+
188+
return Encoding.UTF8.GetString(buffer);
189+
}
190+
}
191+
}
192+
193+
internal static TypeId GetNativeTypeIdFromType(this Type type)
194+
{
195+
if (type == typeof(sbyte))
196+
return TypeId.SByte;
197+
else if (type == typeof(short))
198+
return TypeId.Short;
199+
else if (type == typeof(int))
200+
return TypeId.Int;
201+
else if (type == typeof(long))
202+
return TypeId.Long;
203+
else if (type == typeof(byte))
204+
return TypeId.Byte;
205+
else if (type == typeof(ushort))
206+
return TypeId.UShort;
207+
else if (type == typeof(uint))
208+
return TypeId.UInt;
209+
else if (type == typeof(ulong))
210+
return TypeId.ULong;
211+
else if (type == typeof(float))
212+
return TypeId.Float32;
213+
else if (type == typeof(double))
214+
return TypeId.Double;
215+
else if (type == typeof(bool))
216+
return TypeId.Bool;
217+
else if (type == typeof(ReadOnlyMemory<char>))
218+
return TypeId.String;
219+
220+
throw new InvalidOperationException($"Unsupported type {type}");
221+
}
222+
}
223+
}

0 commit comments

Comments
 (0)