Skip to content

Commit a58e81e

Browse files
authored
C sharp example (#240)
* add C# example
1 parent 40d5ec5 commit a58e81e

File tree

3 files changed

+182
-0
lines changed

3 files changed

+182
-0
lines changed

examples/c-sharp/count/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
.PHONY: publish-osx publish-win help clean
3+
4+
help:
5+
@echo "make publish-win|publish-osx|clean"
6+
7+
publish-win:
8+
dotnet publish -c Release -r win-x64 --self-contained true -o ./publish/win-x64
9+
@echo "Remember to copy libzsv.dll into ./publish/win-x64"
10+
11+
publish-osx:
12+
dotnet publish -c Release -r osx-arm64 --self-contained true -o ./publish/osx-arm64
13+
@echo "Remember to copy libzsv.dylib into ./publish/win-x64"
14+
15+
clean:
16+
rm -rf obj bin publish

examples/c-sharp/count/Program.cs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System;
2+
using System.IO;
3+
using System.Runtime.InteropServices;
4+
5+
class ZsvInterop {
6+
private const string ZsvDll =
7+
#if WINDOWS || WIN32 || WIN64 || _WIN32 || __WIN32
8+
"libzsv.dll";
9+
#elif __MACOS__ || MACOS || OSX
10+
"libzsv.dylib";
11+
#else
12+
"libzsv.so"; // Default or throw an error
13+
#endif
14+
15+
private const string CRT_LIB =
16+
#if WINDOWS
17+
"msvcrt.dll";
18+
#else
19+
"libc";
20+
#endif
21+
22+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
23+
public delegate void ZsvRowHandler(IntPtr parser);
24+
25+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
26+
public static extern IntPtr zsv_new(IntPtr opts);
27+
28+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
29+
public static extern void zsv_delete(IntPtr parser);
30+
31+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
32+
public static extern void zsv_set_row_handler(IntPtr parser, ZsvRowHandler handler);
33+
34+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
35+
public static extern void zsv_set_context(IntPtr parser, IntPtr context);
36+
37+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
38+
public static extern void zsv_set_input(IntPtr parser, IntPtr file);
39+
40+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
41+
public static extern int zsv_parse_more(IntPtr parser);
42+
43+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
44+
public static extern void zsv_finish(IntPtr parser);
45+
46+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
47+
public static extern UIntPtr zsv_cell_count(IntPtr parser);
48+
49+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
50+
public static extern IntPtr zsv_get_cell_str(IntPtr parser, UIntPtr cellIndex);
51+
52+
[DllImport(ZsvDll, CallingConvention = CallingConvention.Cdecl)]
53+
public static extern UIntPtr zsv_get_cell_len(IntPtr parser, UIntPtr cellIndex);
54+
55+
[DllImport(CRT_LIB, CallingConvention = CallingConvention.Cdecl)]
56+
public static extern IntPtr fopen(string filename, string mode);
57+
58+
[DllImport(CRT_LIB, CallingConvention = CallingConvention.Cdecl)]
59+
public static extern int fclose(IntPtr file);
60+
}
61+
62+
class Program {
63+
static int lineCount = 0;
64+
65+
static void OnRowParsed(IntPtr parser) {
66+
lineCount++;
67+
68+
/** example code for printing the first cell of each row:
69+
70+
UIntPtr cellCount = ZsvInterop.zsv_cell_count(parser);
71+
if (cellCount.ToUInt64() > 0) {
72+
73+
// Index of the first cell
74+
UIntPtr cellIndex = new UIntPtr(0);
75+
76+
// Get the pointer to the cell string
77+
IntPtr cellStrPtr = ZsvInterop.zsv_get_cell_str(parser, cellIndex);
78+
79+
// Get the length of the cell string
80+
UIntPtr cellLen = ZsvInterop.zsv_get_cell_len(parser, cellIndex);
81+
82+
// Convert the cell data to a string
83+
int length = (int)cellLen.ToUInt64();
84+
string cellValue = string.Empty;
85+
86+
if (length > 0) {
87+
byte[] buffer = new byte[length];
88+
Marshal.Copy(cellStrPtr, buffer, 0, length);
89+
cellValue = System.Text.Encoding.UTF8.GetString(buffer);
90+
}
91+
92+
Console.WriteLine($"Row {lineCount}: {cellValue}");
93+
}
94+
**/
95+
}
96+
97+
static void Main(string[] args) {
98+
if (args.Length != 1) {
99+
Console.WriteLine("Usage: count-cs <csv_file_path>");
100+
return;
101+
}
102+
103+
string csvFilePath = args[0];
104+
105+
if (!File.Exists(csvFilePath)) {
106+
Console.WriteLine($"Error: File '{csvFilePath}' does not exist.");
107+
return;
108+
}
109+
110+
IntPtr parser = ZsvInterop.zsv_new(IntPtr.Zero);
111+
if (parser == IntPtr.Zero) {
112+
Console.WriteLine("Failed to create zsv parser.");
113+
return;
114+
}
115+
116+
ZsvInterop.ZsvRowHandler handler = new ZsvInterop.ZsvRowHandler(OnRowParsed);
117+
ZsvInterop.zsv_set_row_handler(parser, handler);
118+
ZsvInterop.zsv_set_context(parser, parser);
119+
120+
// Open the file using fopen
121+
IntPtr file = ZsvInterop.fopen(csvFilePath, "r");
122+
if (file == IntPtr.Zero) {
123+
Console.WriteLine($"Error: Failed to open file '{csvFilePath}'.");
124+
ZsvInterop.zsv_delete(parser);
125+
return;
126+
}
127+
128+
ZsvInterop.zsv_set_input(parser, file);
129+
130+
int result = 0;
131+
while (result == 0) {
132+
result = ZsvInterop.zsv_parse_more(parser);
133+
}
134+
135+
ZsvInterop.zsv_finish(parser);
136+
ZsvInterop.zsv_delete(parser);
137+
ZsvInterop.fclose(file);
138+
139+
if (result != 2) // zsv_status_no_more_input
140+
{
141+
Console.WriteLine("Parsing failed: " + $"{result}");
142+
} else {
143+
Console.WriteLine($"{lineCount-1}");
144+
}
145+
}
146+
}

examples/c-sharp/count/count.csproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'win-x64' Or '$(RuntimeIdentifier)' == 'win-x86'">
11+
<DefineConstants>WINDOWS</DefineConstants>
12+
</PropertyGroup>
13+
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'osx-x64' Or '$(RuntimeIdentifier)' == 'osx-arm64'">
14+
<DefineConstants>OSX</DefineConstants>
15+
</PropertyGroup>
16+
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' Or '$(RuntimeIdentifier)' == 'linux-arm64'">
17+
<DefineConstants>LINUX</DefineConstants>
18+
</PropertyGroup>
19+
</Project>
20+

0 commit comments

Comments
 (0)