Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[.NET] Stub out foundation classes for .Net interface
- Loading branch information
Showing
7 changed files
with
259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
*.swp | ||
*.*~ | ||
project.lock.json | ||
.DS_Store | ||
*.pyc | ||
nupkg/ | ||
|
||
# Visual Studio Code | ||
.vscode | ||
|
||
# Rider | ||
.idea | ||
|
||
# User-specific files | ||
*.suo | ||
*.user | ||
*.userosscache | ||
*.sln.docstates | ||
|
||
# Build results | ||
[Dd]ebug/ | ||
[Dd]ebugPublic/ | ||
[Rr]elease/ | ||
[Rr]eleases/ | ||
x64/ | ||
x86/ | ||
build/ | ||
bld/ | ||
[Bb]in/ | ||
[Oo]bj/ | ||
[Oo]ut/ | ||
msbuild.log | ||
msbuild.err | ||
msbuild.wrn | ||
|
||
# Visual Studio 2015 | ||
.vs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.30114.105 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cantera", "Cantera\Cantera.csproj", "{9FAB2B8A-5BAA-4D44-B0E4-1B00A45A7DAC}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{9FAB2B8A-5BAA-4D44-B0E4-1B00A45A7DAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{9FAB2B8A-5BAA-4D44-B0E4-1B00A45A7DAC}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{9FAB2B8A-5BAA-4D44-B0E4-1B00A45A7DAC}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{9FAB2B8A-5BAA-4D44-B0E4-1B00A45A7DAC}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<LangVersion>10</LangVersion> | ||
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||
<AssemblyName>CanteraDotNet</AssemblyName> | ||
</PropertyGroup> | ||
|
||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> | ||
<PackageReference Include="Nullable" Version="1.3.0"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="System.Memory" Version="4.5.4" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Cantera; | ||
|
||
/// <summary> | ||
/// Represents a error that occurred in the native Cantera library. | ||
/// </summary> | ||
public class CanteraException : ExternalException | ||
{ | ||
static class LibCantera | ||
{ | ||
[DllImport(Interop.LIBCANTERA)] | ||
unsafe public static extern int ct_getCanteraError(int buflen, byte* buf); | ||
} | ||
|
||
private CanteraException(string message) : base(message) { } | ||
|
||
unsafe internal static void ThrowLatest() | ||
{ | ||
var errorMessage = Interop.GetString(500, LibCantera.ct_getCanteraError); | ||
throw new CanteraException(errorMessage); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Cantera; | ||
|
||
/// <summary> | ||
/// The base class for a handle to a cantera object. | ||
/// </summary> | ||
/// </remarks> | ||
/// Cantera uses signed 32-bit ints for handles, yet SafeHandle uses "native int" IntPtr. | ||
/// The constuctor and the IsInvalid property are designed to account for this. | ||
/// <remarks> | ||
internal abstract class CanteraHandle : SafeHandle | ||
{ | ||
static IntPtr INVALID = IntPtr.Size == 4 | ||
? new IntPtr(-1) // 32-bit IntPtr: 0xFFFFFFFF | ||
: new IntPtr((long) unchecked((uint) -1)); // 64-bit IntPtr: 0x00000000FFFFFFFF | ||
|
||
public CanteraHandle() : base(INVALID, true) { } | ||
|
||
public override bool IsInvalid => | ||
(int)(long)handle < 0; // removes any leading bits | ||
|
||
public void EnsureValidHandleReceived() | ||
{ | ||
if (IsInvalid) | ||
CanteraException.ThrowLatest(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Cantera; | ||
|
||
public static class CanteraInfo | ||
{ | ||
static class LibCantera | ||
{ | ||
[DllImport(Interop.LIBCANTERA)] | ||
unsafe public static extern int ct_getCanteraVersion(int buflen, byte* buf); | ||
|
||
[DllImport(Interop.LIBCANTERA)] | ||
unsafe public static extern int ct_getGitCommit(int buflen, byte* buf); | ||
|
||
} | ||
|
||
unsafe static readonly Lazy<string> _version = | ||
new Lazy<string>(() => Interop.GetString(10, LibCantera.ct_getCanteraVersion)); | ||
|
||
unsafe static readonly Lazy<string> _gitCommit = | ||
new Lazy<string>(() => Interop.GetString(10, LibCantera.ct_getGitCommit)); | ||
|
||
public static string Version => | ||
_version.Value; | ||
|
||
public static string GitCommit => | ||
_gitCommit.Value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System.Buffers; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Cantera; | ||
|
||
internal static class Interop | ||
{ | ||
public unsafe delegate int GetStringFunc(int initialSize, byte* buffer); | ||
|
||
static ArrayPool<byte> Pool = ArrayPool<byte>.Shared; | ||
|
||
public const string LIBCANTERA = "cantera.2.6.0"; | ||
|
||
public static double CheckReturn(double code) | ||
{ | ||
// Cantera returns this value when the function resulted in error | ||
const double Error = -999.999; | ||
|
||
if (code == Error) | ||
CanteraException.ThrowLatest(); | ||
|
||
return code; | ||
} | ||
|
||
public static int CheckReturn(int code) | ||
{ | ||
// Cantera returns this value when the function resulted in an error internal to Cantera | ||
const int Error1 = -1; | ||
// Cantera returns this value when the function resulted in an external error | ||
// Some functions also return a negative value as the amount of space they need to | ||
// fill a buffer with a string. There is no way to account for the ambiguity that arises | ||
// when such a function returns -999! | ||
const int Error999 = -999; | ||
if (code == Error1 || code == Error999) | ||
CanteraException.ThrowLatest(); | ||
|
||
// some functions return negative when they want more chars, others positive! | ||
return Math.Abs(code); | ||
} | ||
|
||
[SuppressMessage("Reliability", "CA2014:NoStackallocInLoops", Justification = "Loop is executed at most twice.")] | ||
public static string GetString(int initialSize, GetStringFunc func) | ||
{ | ||
// take up to two tries | ||
// 1) use the initial size | ||
// if the initial size was large enough, return the string | ||
// if the initial size was not large enough ... | ||
// 2) try again with the needed size | ||
// if the needed size was large enough, return the string | ||
// otherwise, catastrophe, throw! | ||
for(var i = 0; i < 2; i++) | ||
{ | ||
int neededSize; | ||
|
||
if (initialSize <= 120) | ||
{ | ||
Span<byte> span = stackalloc byte[initialSize]; | ||
if (TryGetString(span, func, out var value, out neededSize)) | ||
return value; | ||
} | ||
else | ||
{ | ||
var array = Pool.Rent(initialSize); | ||
try | ||
{ | ||
if (TryGetString(array, func, out var value, out neededSize)) | ||
return value; | ||
} | ||
finally | ||
{ | ||
Pool.Return(array); | ||
} | ||
} | ||
|
||
initialSize = neededSize; | ||
} | ||
|
||
throw new InvalidOperationException("Could not retrieve a string value from Cantera!"); | ||
|
||
unsafe static bool TryGetString(Span<byte> span, GetStringFunc func, [NotNullWhen(true)] out string? value, out int neededSize) | ||
{ | ||
var initialSize = span.Length; | ||
|
||
fixed(byte* buffer = span) | ||
{ | ||
neededSize = CheckReturn(func(initialSize, buffer)); | ||
|
||
if(initialSize >= neededSize) | ||
{ | ||
value = new String((sbyte*) buffer); | ||
return true; | ||
} | ||
} | ||
|
||
value = null; | ||
return false; | ||
} | ||
} | ||
} |