diff --git a/binding/csharp/IP2Region.SearchTest/App.config b/binding/csharp/IP2Region.SearchTest/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/binding/csharp/IP2Region.SearchTest/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/binding/csharp/IP2Region.SearchTest/IP2Region.SearchTest.csproj b/binding/csharp/IP2Region.SearchTest/IP2Region.SearchTest.csproj
new file mode 100644
index 0000000..d4eb256
--- /dev/null
+++ b/binding/csharp/IP2Region.SearchTest/IP2Region.SearchTest.csproj
@@ -0,0 +1,59 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {FF136AEA-D41F-4C14-842B-CE597BB97916}
+ Exe
+ IP2Region.SearchTest
+ IP2Region.SearchTest
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {483575a5-ffb3-4131-a2dc-6d3ad3bb268f}
+ IP2Region
+
+
+
+
\ No newline at end of file
diff --git a/binding/csharp/IP2Region.SearchTest/Program.cs b/binding/csharp/IP2Region.SearchTest/Program.cs
new file mode 100644
index 0000000..35267f2
--- /dev/null
+++ b/binding/csharp/IP2Region.SearchTest/Program.cs
@@ -0,0 +1,156 @@
+using IP2Region.xdb;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IP2Region.SearchTest
+{
+ internal class Program
+ {
+
+ public static void PrintHelp(String[] args)
+ {
+ Console.WriteLine("ip2region xdb searcher");
+ Console.WriteLine("SearchTest.exe [command] [command options]");
+ Console.WriteLine("Command: ");
+ Console.WriteLine(" search search input test");
+ Console.WriteLine(" bench search bench test");
+ }
+ public static Searcher CreateSearcher(String dbPath, String cachePolicy)
+ {
+ if ("file" == cachePolicy)
+ {
+ return Searcher.NewWithFileOnly(dbPath);
+ }
+ else if ("vectorIndex" == cachePolicy)
+ {
+ byte[] vIndex = Searcher.LoadVectorIndexFromFile(dbPath);
+ return Searcher.NewWithVectorIndex(dbPath, vIndex);
+ }
+ else if ("content" == cachePolicy)
+ {
+ byte[] cBuff = Searcher.LoadContentFromFile(dbPath);
+ return Searcher.NewWithBuffer(cBuff);
+ }
+ else
+ {
+ throw new Exception("invalid cache policy `" + cachePolicy + "`, options: file/vectorIndex/content");
+ }
+ }
+
+ public static void SearchTest(string[] args)
+ {
+ String dbPath = "", cachePolicy = "vectorIndex";
+ foreach (string r in args)
+ {
+ if (r.Length < 5)
+ {
+ continue;
+ }
+
+ if (r.IndexOf("--") != 0)
+ {
+ continue;
+ }
+
+ int sIdx = r.IndexOf('=');
+ if (sIdx < 0)
+ {
+ Console.WriteLine("missing = for args pair `{0}`", r);
+ return;
+ }
+
+ String key = r.Substring(2, sIdx - 2);
+ String val = r.Substring(sIdx + 1);
+ // System.out.printf("key=%s, val=%s\n", key, val);
+ if ("db" == key)
+ {
+ dbPath = val;
+ }
+ else if ("cache-policy" == key)
+ {
+ cachePolicy = val;
+ }
+ else
+ {
+ Console.WriteLine("undefined option `{0}`", r);
+ return;
+ }
+ }
+
+ if (dbPath.Length < 1)
+ {
+ Console.WriteLine("jSearchTest.exe search [command options]");
+ Console.WriteLine("options:");
+ Console.WriteLine(" --db string ip2region binary xdb file path");
+ Console.WriteLine(" --cache-policy string cache policy: file/vectorIndex/content");
+ return;
+ }
+
+ Searcher searcher = CreateSearcher(dbPath, cachePolicy);
+
+ Console.WriteLine("ip2region xdb searcher test program, cachePolicy: %s\ntype 'quit' to exit", cachePolicy);
+ while (true)
+ {
+ Console.Write("ip2region>> ");
+ var line = Console.ReadLine().Trim();
+ if (line.Length < 2) continue;
+ if (line == "quit") break;
+ try
+ {
+ var st = new Stopwatch();
+ st.Start();
+ var region = searcher.Search(line);
+ st.Stop();
+ var cost = st.ElapsedMilliseconds;
+ Console.WriteLine("{{region: {0}, ioCount: {1}, took: {2} ms}}", region, searcher.IOCount, cost);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("{{err:{0}, ioCount: {1}}}", e, searcher.IOCount);
+ }
+ }
+ Console.WriteLine("searcher test program exited, thanks for trying");
+
+ }
+ public static void BenchTest(String[] args)
+ {
+
+ }
+ static void Main(string[] args)
+ {
+ if (args.Length < 1)
+ {
+ PrintHelp(args);
+ return;
+ }
+ switch (args[0])
+ {
+ case "search":
+ try
+ {
+ SearchTest(args);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("failed running search test: {0}", e);
+ }
+ break;
+ case "bench":
+ try
+ {
+ BenchTest(args);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("failed running bench test: {0}", e);
+ }
+ break;
+ default: PrintHelp(args); break;
+ }
+ }
+ }
+}
diff --git a/binding/csharp/IP2Region.SearchTest/Properties/AssemblyInfo.cs b/binding/csharp/IP2Region.SearchTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..61714dc
--- /dev/null
+++ b/binding/csharp/IP2Region.SearchTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("IP2Region.SearchTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("IP2Region.SearchTest")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("ff136aea-d41f-4c14-842b-ce597bb97916")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/binding/csharp/IP2Region/IP2Region.csproj b/binding/csharp/IP2Region/IP2Region.csproj
index dbc1517..7a87b2b 100644
--- a/binding/csharp/IP2Region/IP2Region.csproj
+++ b/binding/csharp/IP2Region/IP2Region.csproj
@@ -1,7 +1,7 @@
-
- net6.0
-
+
+ netstandard2.0;netcoreapp3.1;net5.0;net6.0
+
diff --git a/binding/csharp/IP2Region/xdb/Searcher.cs b/binding/csharp/IP2Region/xdb/Searcher.cs
index db9ac2e..c04c166 100644
--- a/binding/csharp/IP2Region/xdb/Searcher.cs
+++ b/binding/csharp/IP2Region/xdb/Searcher.cs
@@ -248,7 +248,7 @@ namespace IP2Region.xdb
public static long checkIP(String ip)
{
String[]
- ps = ip.Split(".");
+ ps = ip.Split('.');
if (ps.Length != 4) throw new Exception("invalid ip address `" + ip + "`");
long ipDst = 0;