From a6c4d2a2bcc6d4039d859e97bacb615aa6c20a31 Mon Sep 17 00:00:00 2001 From: Daiyuu Nobori Date: Sat, 22 Sep 2018 11:50:58 +0900 Subject: [PATCH] Add 'stbcheck': the STB File Multilanguage Full-Mesh Consistency Checker --- .gitignore | 180 ++++++ developer_tools/stbchecker/Program.cs | 59 ++ developer_tools/stbchecker/README.md | 60 ++ developer_tools/stbchecker/Stb.cs | 375 ++++++++++++ developer_tools/stbchecker/Str.cs | 555 +++++++++++++++++ developer_tools/stbchecker/Util.cs | 603 +++++++++++++++++++ developer_tools/stbchecker/stbchecker.csproj | 16 + developer_tools/stbchecker/stbchecker.sln | 24 + 8 files changed, 1872 insertions(+) create mode 100644 developer_tools/stbchecker/Program.cs create mode 100644 developer_tools/stbchecker/README.md create mode 100644 developer_tools/stbchecker/Stb.cs create mode 100644 developer_tools/stbchecker/Str.cs create mode 100644 developer_tools/stbchecker/Util.cs create mode 100644 developer_tools/stbchecker/stbchecker.csproj create mode 100644 developer_tools/stbchecker/stbchecker.sln diff --git a/.gitignore b/.gitignore index e415bfdb..e319c0ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +# Global .cproject .project .settings/ @@ -10,3 +11,182 @@ tmp/ .gitconfig CMakeCache.txt CMakeFiles/ + + +# Applied for 'developer_tools/stbchecker/' +# Copied from by https://www.gitignore.io/api/visualstudio +developer_tools/stbchecker/**/*.suo +developer_tools/stbchecker/**/*.user +developer_tools/stbchecker/**/*.userosscache +developer_tools/stbchecker/**/*.sln.docstates +developer_tools/stbchecker/**/*.userprefs +developer_tools/stbchecker/**/[Dd]ebug/ +developer_tools/stbchecker/**/[Dd]ebugPublic/ +developer_tools/stbchecker/**/[Rr]elease/ +developer_tools/stbchecker/**/[Rr]eleases/ +developer_tools/stbchecker/**/x64/ +developer_tools/stbchecker/**/x86/ +developer_tools/stbchecker/**/bld/ +developer_tools/stbchecker/**/[Bb]in/ +developer_tools/stbchecker/**/[Oo]bj/ +developer_tools/stbchecker/**/[Ll]og/ +developer_tools/stbchecker/**/.vs/ +developer_tools/stbchecker/**/Generated\ Files/ +developer_tools/stbchecker/**/s +developer_tools/stbchecker/**/[Tt]est[Rr]esult*/ +developer_tools/stbchecker/**/[Bb]uild[Ll]og.* +developer_tools/stbchecker/**/*.VisualState.xml +developer_tools/stbchecker/**/TestResult.xml +developer_tools/stbchecker/**/[Dd]ebugPS/ +developer_tools/stbchecker/**/[Rr]eleasePS/ +developer_tools/stbchecker/**/dlldata.c +developer_tools/stbchecker/**/BenchmarkDotNet.Artifacts/ +developer_tools/stbchecker/**/project.lock.json +developer_tools/stbchecker/**/project.fragment.lock.json +developer_tools/stbchecker/**/artifacts/ +developer_tools/stbchecker/**/StyleCopReport.xml +developer_tools/stbchecker/**/*_i.c +developer_tools/stbchecker/**/*_p.c +developer_tools/stbchecker/**/*_i.h +developer_tools/stbchecker/**/*.ilk +developer_tools/stbchecker/**/*.meta +developer_tools/stbchecker/**/*.obj +developer_tools/stbchecker/**/*.iobj +developer_tools/stbchecker/**/*.pch +developer_tools/stbchecker/**/*.pdb +developer_tools/stbchecker/**/*.ipdb +developer_tools/stbchecker/**/*.pgc +developer_tools/stbchecker/**/*.pgd +developer_tools/stbchecker/**/*.rsp +developer_tools/stbchecker/**/*.sbr +developer_tools/stbchecker/**/*.tlb +developer_tools/stbchecker/**/*.tli +developer_tools/stbchecker/**/*.tlh +developer_tools/stbchecker/**/*.tmp +developer_tools/stbchecker/**/*.tmp_proj +developer_tools/stbchecker/**/*.log +developer_tools/stbchecker/**/*.vspscc +developer_tools/stbchecker/**/*.vssscc +developer_tools/stbchecker/**/.builds +developer_tools/stbchecker/**/*.pidb +developer_tools/stbchecker/**/*.svclog +developer_tools/stbchecker/**/*.scc +developer_tools/stbchecker/**/_Chutzpah* +developer_tools/stbchecker/**/ipch/ +developer_tools/stbchecker/**/*.aps +developer_tools/stbchecker/**/*.ncb +developer_tools/stbchecker/**/*.opendb +developer_tools/stbchecker/**/*.opensdf +developer_tools/stbchecker/**/*.sdf +developer_tools/stbchecker/**/*.cachefile +developer_tools/stbchecker/**/*.VC.db +developer_tools/stbchecker/**/*.VC.VC.opendb +developer_tools/stbchecker/**/*.psess +developer_tools/stbchecker/**/*.vsp +developer_tools/stbchecker/**/*.vspx +developer_tools/stbchecker/**/*.sap +developer_tools/stbchecker/**/*.e2e +developer_tools/stbchecker/**/$tf/ +developer_tools/stbchecker/**/*.gpState +developer_tools/stbchecker/**/_ReSharper*/ +developer_tools/stbchecker/**/*.[Rr]e[Ss]harper +developer_tools/stbchecker/**/*.DotSettings.user +developer_tools/stbchecker/**/.JustCode +developer_tools/stbchecker/**/_TeamCity* +developer_tools/stbchecker/**/*.dotCover +developer_tools/stbchecker/**/.axoCover/* +developer_tools/stbchecker/**/!.axoCover/settings.json +developer_tools/stbchecker/**/*.coverage +developer_tools/stbchecker/**/*.coveragexml +developer_tools/stbchecker/**/_NCrunch_* +developer_tools/stbchecker/**/.*crunch*.local.xml +developer_tools/stbchecker/**/nCrunchTemp_* +developer_tools/stbchecker/**/*.mm.* +developer_tools/stbchecker/**/AutoTest.Net/ +developer_tools/stbchecker/**/.sass-cache/ +developer_tools/stbchecker/**/[Ee]xpress/ +developer_tools/stbchecker/**/DocProject/buildhelp/ +developer_tools/stbchecker/**/DocProject/Help/*.HxT +developer_tools/stbchecker/**/DocProject/Help/*.HxC +developer_tools/stbchecker/**/DocProject/Help/*.hhc +developer_tools/stbchecker/**/DocProject/Help/*.hhk +developer_tools/stbchecker/**/DocProject/Help/*.hhp +developer_tools/stbchecker/**/DocProject/Help/Html2 +developer_tools/stbchecker/**/DocProject/Help/html +developer_tools/stbchecker/**/publish/ +developer_tools/stbchecker/**/*.[Pp]ublish.xml +developer_tools/stbchecker/**/*.azurePubxml +developer_tools/stbchecker/**/*.pubxml +developer_tools/stbchecker/**/*.publishproj +developer_tools/stbchecker/**/PublishScripts/ +developer_tools/stbchecker/**/*.nupkg +developer_tools/stbchecker/**/**/[Pp]ackages/* +developer_tools/stbchecker/**/!**/[Pp]ackages/build/ +developer_tools/stbchecker/**/*.nuget.props +developer_tools/stbchecker/**/*.nuget.targets +developer_tools/stbchecker/**/csx/ +developer_tools/stbchecker/**/*.build.csdef +developer_tools/stbchecker/**/ecf/ +developer_tools/stbchecker/**/rcf/ +developer_tools/stbchecker/**/AppPackages/ +developer_tools/stbchecker/**/BundleArtifacts/ +developer_tools/stbchecker/**/Package.StoreAssociation.xml +developer_tools/stbchecker/**/_pkginfo.txt +developer_tools/stbchecker/**/*.appx +developer_tools/stbchecker/**/*.[Cc]ache +developer_tools/stbchecker/**/!*.[Cc]ache/ +developer_tools/stbchecker/**/ClientBin/ +developer_tools/stbchecker/**/~$* +developer_tools/stbchecker/**/*~ +developer_tools/stbchecker/**/*.dbmdl +developer_tools/stbchecker/**/*.dbproj.schemaview +developer_tools/stbchecker/**/*.jfm +developer_tools/stbchecker/**/*.pfx +developer_tools/stbchecker/**/*.publishsettings +developer_tools/stbchecker/**/orleans.codegen.cs +developer_tools/stbchecker/**/Generated_Code/ +developer_tools/stbchecker/**/_UpgradeReport_Files/ +developer_tools/stbchecker/**/Backup*/ +developer_tools/stbchecker/**/UpgradeLog*.XML +developer_tools/stbchecker/**/UpgradeLog*.htm +developer_tools/stbchecker/**/ServiceFabricBackup/ +developer_tools/stbchecker/**/*.rptproj.bak +developer_tools/stbchecker/**/*.mdf +developer_tools/stbchecker/**/*.ldf +developer_tools/stbchecker/**/*.ndf +developer_tools/stbchecker/**/*.rdl.data +developer_tools/stbchecker/**/*.bim.layout +developer_tools/stbchecker/**/*.bim_*.settings +developer_tools/stbchecker/**/*.rptproj.rsuser +developer_tools/stbchecker/**/FakesAssemblies/ +developer_tools/stbchecker/**/*.GhostDoc.xml +developer_tools/stbchecker/**/.ntvs_analysis.dat +developer_tools/stbchecker/**/node_modules/ +developer_tools/stbchecker/**/*.plg +developer_tools/stbchecker/**/*.opt +developer_tools/stbchecker/**/*.vbw +developer_tools/stbchecker/**/*.HTMLClient/GeneratedArtifacts +developer_tools/stbchecker/**/*.DesktopClient/GeneratedArtifacts +developer_tools/stbchecker/**/*.DesktopClient/ModelManifest.xml +developer_tools/stbchecker/**/*.Server/GeneratedArtifacts +developer_tools/stbchecker/**/*.Server/ModelManifest.xml +developer_tools/stbchecker/**/_Pvt_Extensions +developer_tools/stbchecker/**/.paket/paket.exe +developer_tools/stbchecker/**/paket-files/ +developer_tools/stbchecker/**/.fake/ +developer_tools/stbchecker/**/.idea/ +developer_tools/stbchecker/**/*.sln.iml +developer_tools/stbchecker/**/.cr/ +developer_tools/stbchecker/**/__pycache__/ +developer_tools/stbchecker/**/*.pyc +developer_tools/stbchecker/**/*.tss +developer_tools/stbchecker/**/*.jmconfig +developer_tools/stbchecker/**/*.btp.cs +developer_tools/stbchecker/**/*.btm.cs +developer_tools/stbchecker/**/*.odx.cs +developer_tools/stbchecker/**/*.xsd.cs +developer_tools/stbchecker/**/OpenCover/ +developer_tools/stbchecker/**/ASALocalRun/ +developer_tools/stbchecker/**/*.binlog +developer_tools/stbchecker/**/*.nvuser +developer_tools/stbchecker/**/.mfractor/ diff --git a/developer_tools/stbchecker/Program.cs b/developer_tools/stbchecker/Program.cs new file mode 100644 index 00000000..e2dde10e --- /dev/null +++ b/developer_tools/stbchecker/Program.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; + +public class Program +{ + static int Main(string[] args) + { + Console.WriteLine("SoftEther VPN Project"); + Console.WriteLine("STB File Multilanguage Full-Mesh Consistency Checker"); + Console.WriteLine(""); + + if (args.Length != 1) + { + Console.WriteLine("Usage: dotnet run [hamcore_dir]"); + return -1; + } + else + { + string hamcore_dir = args[0]; + + string[] stb_files = Directory.GetFiles(hamcore_dir, "*.stb", SearchOption.TopDirectoryOnly); + + if (stb_files.Length == 0) + { + Console.WriteLine("Error: There are no .stb files in the directory '" + hamcore_dir + "'."); + return -1; + } + + int total_num = 0; + + for (int i = 0; i < stb_files.Length; i++) + { + for (int j = 0; j < stb_files.Length; j++) + { + if (i != j) + { + Console.WriteLine("---\nComparing '{1}' to '{0}'...", Path.GetFileName(stb_files[i]), Path.GetFileName(stb_files[j])); + + total_num += Stb.Compare(stb_files[i], stb_files[j]); + } + } + } + + Console.WriteLine("--- Results ---"); + if (total_num == 0) + { + Console.WriteLine("OK: Excellent! There are no errors between multilanguage stb files."); + Console.WriteLine(); + Console.WriteLine(" - In Jurassic Park: \"It's a UNIX system! I know this!\""); + return 0; + } + else + { + Console.WriteLine($"ERROR: There are {total_num} errors on multilanguage stb files. Please kindly correct them before submitting us Pull Requests."); + return -3; + } + } + } +} diff --git a/developer_tools/stbchecker/README.md b/developer_tools/stbchecker/README.md new file mode 100644 index 00000000..f937b186 --- /dev/null +++ b/developer_tools/stbchecker/README.md @@ -0,0 +1,60 @@ +# STB File Multilanguage Full-Mesh Consistency Checker + +September 20, 2018 By Daiyuu Nobori + +## Overview +stbchecker is a utility to check the consistency between existing `*.stb` files (string resources) in the specified directory. + +- Works on Windows, Linux, macOS with .NET Core 2.1. +- Written in C#. +- Easy to use. + + +When modifying or adding any stb files, you have to check the consistency between all existing `*.stb` files. If there are any error, the SoftEther VPN programs may fail or crash on runtime. + + +You must not publish any build which has failed to pass stbchecker. + + +## Usage +### 1. Install .NET Core 2.1 +https://www.microsoft.com/net/download/dotnet-core/2.1 + + +#### Option: Use Visual Studio 2017 on Windows +If you are using Visual Studio 2017 on Windows, you can open the `stbchecker.sln` file instead. With Visual Studio 2017 you do not need using .NET Core 2.1 command-line utility. + +### 2. Go to the `developer_tools/stbchcker` directory +``` +$ cd developer_tools/stbchcker/ +``` + +### 3. Run stbchecker +``` +$ dotnet run [hamcore_dir] +``` +You need to specify the `src/bin/hamcore` directory of the SoftEther VPN repository. The `hamcore` directory has multiple `*.stb` files. + + +### 4. Show the result +#### In error cases +Errors as following will be displayed, and the program returns `non-zero` values as the exit code. + +``` +Comparing 'strtable_ko.stb' to 'strtable_cn.stb'... +File2: Error: Missing 'HUB_AO_DenyAllRadiusLoginWithNoVlanAssign' +File2: Error: Missing 'HUB_AO_UseHubNameAsDhcpUserClassOption' +File2: Error: Missing 'HUB_AO_UseHubNameAsRadiusNasId' +File2: Error: Missing 'CM_VLAN_REINSTALL_MSG' +--- Results --- +ERROR: There are 123 errors on multilanguage stb files. Please kindly correct them before submitting us Pull Requests. +``` + + +#### In successful cases +The following message will be displayed, and the program returns `0` as the exit code. + + +``` +OK: Excellent! There are no errors between multilanguage stb files. +``` diff --git a/developer_tools/stbchecker/Stb.cs b/developer_tools/stbchecker/Stb.cs new file mode 100644 index 00000000..b11c7a4e --- /dev/null +++ b/developer_tools/stbchecker/Stb.cs @@ -0,0 +1,375 @@ +using System; +using System.Collections.Generic; +using System.IO; + +public class StbTable +{ + List tagList; + public string[] TagList + { + get + { + return tagList.ToArray(); + } + } + + string name; + public string Name + { + get { return name; } + } + + string str; + public string String + { + get { return str; } + } + + public StbTable(string name, string str) + { + this.name = name; + this.str = str; + + tagList = ParseTagList(str); + } + + public static string UnescapeStr(string str) + { + int i, len; + string tmp; + + len = str.Length; + tmp = ""; + + for (i = 0; i < len; i++) + { + if (str[i] == '\\') + { + i++; + switch (str[i]) + { + case '\\': + tmp += '\\'; + break; + + case ' ': + tmp += ' '; + break; + + case 'n': + case 'N': + tmp += '\n'; + break; + + case 'r': + case 'R': + tmp += '\r'; + break; + + case 't': + case 'T': + tmp += '\t'; + break; + } + } + else + { + tmp += str[i]; + } + } + + return tmp; + } + + public static StbTable ParseTableLine(string line, ref string prefix) + { + int i, len; + int string_start; + int len_name; + string name, name2; + + line = line.TrimStart(' ', '\t'); + len = line.Length; + if (len == 0) + { + return null; + } + + if (line[0] == '#' || (line[0] == '/' && line[1] == '/')) + { + return null; + } + + bool b = false; + len_name = 0; + for (i = 0; i < line.Length; i++) + { + if (line[i] == ' ' || line[i] == '\t') + { + b = true; + break; + } + len_name++; + } + + if (b == false) + { + return null; + } + + name = line.Substring(0, len_name); + + string_start = len_name; + for (i = len_name; i < len; i++) + { + if (line[i] != ' ' && line[i] != '\t') + { + break; + } + string_start++; + } + if (i == len) + { + return null; + } + + string str = line.Substring(string_start); + + str = UnescapeStr(str); + + if (Str.StrCmpi(name, "PREFIX")) + { + prefix = str; + prefix = prefix.TrimStart(); + + if (Str.StrCmpi(prefix, "$") || Str.StrCmpi(prefix, "NULL")) + { + prefix = ""; + } + + return null; + } + + name2 = ""; + + if (prefix != "") + { + name2 += prefix + "@"; + } + + name2 += name; + + return new StbTable(name2, str); + } + + public static bool CompareTagList(string[] list1, string[] list2) + { + if (list1.Length != list2.Length) + { + return false; + } + + int i; + for (i = 0; i < list1.Length; i++) + { + if (list1[i] != list2[i]) + { + return false; + } + } + + return true; + } + + public static List ParseTagList(string str) + { + List list = new List(); + int i, len; + int mode = 0; + string tmp = ""; + + str += "_"; + + len = str.Length; + + for (i = 0; i < len; i++) + { + char c = str[i]; + + if (mode == 0) + { + switch (c) + { + case '%': + if (str[i + 1] == '%') + { + i++; + tmp += c; + } + else + { + mode = 1; + tmp = "" + c; + } + break; + + default: + tmp = "" + c; + break; + } + } + else + { + string tag; + + switch (c) + { + case 'c': + case 'C': + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + case 'n': + case 'N': + case 's': + case 'S': + case 'r': + case ' ': + tmp += c; + tag = tmp; + list.Add(tag); + mode = 0; + break; + default: + tmp += c; + break; + } + } + } + + return list; + } +} + +public class Stb +{ + Dictionary tableList; + string name; + public string Name + { + get { return name; } + } + + public Stb(string fileName) + { + init(File.ReadAllBytes(fileName), fileName); + } + + public Stb(string fileName, string name) + { + init(File.ReadAllBytes(fileName), name); + } + + public Stb(byte[] data, string name) + { + init(data, name); + } + + void init(byte[] data, string name) + { + if (data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf) + { + byte[] tmp = new byte[data.Length - 3]; + Array.Copy(data, 3, tmp, 0, data.Length - 3); + data = tmp; + } + + StringReader sr = new StringReader(Str.Utf8Encoding.GetString(data)); + tableList = new Dictionary(); + + this.name = name; + string prefix = ""; + + while (true) + { + string tmp = sr.ReadLine(); + if (tmp == null) + { + break; + } + + StbTable t = StbTable.ParseTableLine(tmp, ref prefix); + if (t != null) + { + if (tableList.ContainsKey(t.Name.ToUpper()) == false) + { + tableList.Add(t.Name.ToUpper(), t); + } + else + { + ShowWarning(name, string.Format("Duplicated '{0}'", t.Name)); + } + } + } + } + + protected static void ShowWarning(string name, string str) + { + Console.WriteLine("{0}: Warning: {1}", name, str); + } + + protected static void ShowError(string name, string str) + { + Console.WriteLine("{0}: Error: {1}", name, str); + } + + public static int Compare(string file1, string file2) + { + Stb stb1 = new Stb(file1, "File1"); + Stb stb2 = new Stb(file2, "File2"); + int num = 0; + + string file1_fn = Path.GetFileName(file1); + string file2_fn = Path.GetFileName(file2); + + foreach (string name1 in stb1.tableList.Keys) + { + if (name1.Equals("DEFAULT_FONT_WIN7", StringComparison.InvariantCultureIgnoreCase) || + name1.Equals("DEFAULT_FONT_HIGHDPI", StringComparison.InvariantCultureIgnoreCase)) + { + continue; + } + + StbTable t1 = stb1.tableList[name1]; + + if (stb2.tableList.ContainsKey(name1) == false) + { + ShowError(stb2.name, string.Format("Missing '{0}'", t1.Name)); + num++; + } + else + { + StbTable t2 = stb2.tableList[name1]; + + if (StbTable.CompareTagList(t1.TagList, t2.TagList) == false) + { + ShowError(stb2.name, string.Format("Difference printf-style parameters '{0}'", t1.Name)); + num++; + } + } + } + + Console.WriteLine("\nThere are {0} errors.\n\n{1}\n", num, + (num == 0 ? "Good work! No problem!" : "You must correct them before sending us Pull Requests!")); + + return num; + } +} diff --git a/developer_tools/stbchecker/Str.cs b/developer_tools/stbchecker/Str.cs new file mode 100644 index 00000000..570d4e3f --- /dev/null +++ b/developer_tools/stbchecker/Str.cs @@ -0,0 +1,555 @@ +using System; +using System.Text; +using System.Collections.Generic; +using System.IO; + +public class Str +{ + static Encoding asciiEncoding = Encoding.ASCII; + public static Encoding AsciiEncoding + { + get { return Str.asciiEncoding; } + } + + static Encoding utf8Encoding = Encoding.UTF8; + public static Encoding Utf8Encoding + { + get { return Str.utf8Encoding; } + } + + static Encoding uniEncoding = Encoding.Unicode; + public static Encoding UniEncoding + { + get { return Str.uniEncoding; } + } + + public static string ByteToHex3(byte[] data) + { + if (data.Length == 0) + { + return ""; + } + + return BitConverter.ToString(data) + "-"; + } + + public static string ByteToHex(byte[] data) + { + StringBuilder ret = new StringBuilder(); + foreach (byte b in data) + { + string s = b.ToString("X"); + if (s.Length == 1) + { + s = "0" + s; + } + + ret.Append(s); + } + + return ret.ToString(); + } + + public static byte[] HexToByte(string str) + { + try + { + List o = new List(); + string tmp = ""; + int i, len; + + str = str.ToUpper().Trim(); + len = str.Length; + + for (i = 0; i < len; i++) + { + char c = str[i]; + if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F')) + { + tmp += c; + if (tmp.Length == 2) + { + byte b = Convert.ToByte(tmp, 16); + o.Add(b); + tmp = ""; + } + } + else if (c == ' ' || c == ',' || c == '-' || c == ';') + { + } + else + { + break; + } + } + + return o.ToArray(); + } + catch + { + return new byte[0]; + } + } + + public static string ByteToStr(byte[] data, Encoding enc) + { + try + { + return enc.GetString(data); + } + catch + { + return ""; + } + } + + public static byte[] StrToByte(string str, Encoding enc) + { + try + { + return enc.GetBytes(str); + } + catch + { + return new byte[0]; + } + } + + public static string[] GetLines(string str) + { + List a = new List(); + StringReader sr = new StringReader(str); + while (true) + { + string s = sr.ReadLine(); + if (s == null) + { + break; + } + a.Add(s); + } + return a.ToArray(); + } + + public static string LinesToStr(string[] lines) + { + StringWriter sw = new StringWriter(); + foreach (string s in lines) + { + sw.WriteLine(s); + } + return sw.ToString(); + } + + public static bool IsEmptyStr(string str) + { + if (str == null || str.Trim().Length == 0) + { + return true; + } + else + { + return false; + } + } + + public static bool IsSplitChar(char c, string splitStr) + { + if (splitStr == null) + { + splitStr = StrToken.DefaultSplitStr; + } + + foreach (char t in splitStr) + { + string a = "" + t; + string b = "" + c; + if (Util.StrCmpi(a, b)) + { + return true; + } + } + + return false; + } + + public static bool GetKeyAndValue(string str, out string key, out string value) + { + return GetKeyAndValue(str, out key, out value, null); + } + public static bool GetKeyAndValue(string str, out string key, out string value, string splitStr) + { + uint mode = 0; + string keystr = "", valuestr = ""; + if (splitStr == null) + { + splitStr = StrToken.DefaultSplitStr; + } + + foreach (char c in str) + { + switch (mode) + { + case 0: + if (IsSplitChar(c, splitStr) == false) + { + mode = 1; + keystr += c; + } + break; + + case 1: + if (IsSplitChar(c, splitStr) == false) + { + keystr += c; + } + else + { + mode = 2; + } + break; + + case 2: + if (IsSplitChar(c, splitStr) == false) + { + mode = 3; + valuestr += c; + } + break; + + case 3: + valuestr += c; + break; + } + } + + if (mode == 0) + { + value = ""; + key = ""; + return false; + } + else + { + value = valuestr; + key = keystr; + return true; + } + } + + public static int StrCmpRetInt(string s1, string s2) + { + return s1.CompareTo(s2); + } + public static bool StrCmp(string s1, string s2) + { + return StrCmpRetInt(s1, s2) == 0 ? true : false; + } + public static int StrCmpiRetInt(string s1, string s2) + { + s1 = s1.ToUpper(); + s2 = s2.ToUpper(); + return StrCmpRetInt(s1, s2); + } + public static bool StrCmpi(string s1, string s2) + { + return StrCmpiRetInt(s1, s2) == 0 ? true : false; + } + + public static bool IsStrInList(string str, params string[] args) + { + return IsStrInList(str, true, args); + } + public static bool IsStrInList(string str, bool ignoreCase, params string[] args) + { + foreach (string s in args) + { + if (ignoreCase) + { + if (StrCmpi(str, s)) + { + return true; + } + } + else + { + if (StrCmp(str, s)) + { + return true; + } + } + } + + return false; + } + + public static bool IsNumber(string str) + { + str = str.Trim(); + + foreach (char c in str) + { + if (c >= '0' && c <= '9') + { + } + else + { + return false; + } + } + + return true; + } + + public static string DateToString(DateTime dt) + { + if (dt.Ticks != 0) + { + return dt.ToString("yyyyMMdd HHmmss").Substring(2); + } + else + { + return "000000_000000"; + } + } + + public static DateTime StringToDate(string str) + { + str = str.Replace("(JST)", "").Trim(); + + try + { + return DateTime.Parse(str); + } + catch + { + return new DateTime(0); + } + } + + public static string ToSafeString(string str) + { + char[] chars = + { + ';', '?', '=', '<', '>', ':', '@', '%', '$', '\\', '/', '|', '\"', '\r', '\n', + }; + + string ret = str; + foreach (char c in chars) + { + ret = ret.Replace(c, '_'); + } + + string ret2 = ""; + + foreach (char c in ret) + { + bool b = false; + + if (c >= 0x00 && c <= 0x1f) + { + b = true; + } + + if (c >= 0x7f && c <= 0xff) + { + b = true; + } + + if (b == false) + { + ret2 += c; + } + else + { + ret2 += "_"; + } + } + + return ret2; + } + + public static byte[] Base64Decode(string src) + { + try + { + return System.Convert.FromBase64String(src); + } + catch + { + return null; + } + } + + public static string DecodeMime(string src) + { + string[] s = src.Split('?'); + byte[] b; + if (s[2] == "B") + { + b = System.Convert.FromBase64String(s[3]); + } + else + { + throw new Exception("Bad Encode."); + } + string ret = System.Text.Encoding.GetEncoding(s[1]).GetString(b); + + if (s.Length >= 4) + { + string tmp = s[s.Length - 1]; + + if (tmp.StartsWith("=")) + { + ret += tmp.Substring(1); + } + } + + return ret; + } + + public static bool HasNullChar(string str) + { + if (str.IndexOf('\0') != -1) + { + return true; + } + + return false; + } + + public static bool IsMailHeaderStr(string str) + { + if (str == null) + { + return false; + } + if (HasNullChar(str)) + { + return false; + } + + string[] sep = { ": " }; + string[] tokens = str.Split(sep, StringSplitOptions.RemoveEmptyEntries); + + if (tokens.Length >= 2) + { + return true; + } + + return false; + } + + public static bool IsStrForBase64(string str) + { + string b64str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/+="; + + foreach (char c in str) + { + bool b = false; + + foreach (char c2 in b64str) + { + if (c == c2) + { + b = true; + break; + } + } + + if (b == false) + { + return false; + } + } + + return true; + } + +} + +public class StrToken +{ + string[] tokens; + + public string[] Tokens + { + get { return tokens; } + } + + public string this[uint index] + { + get { return tokens[index]; } + } + + public uint NumTokens + { + get + { + return (uint)Tokens.Length; + } + } + + const string defaultSplitStr = " ,\t\r\n"; + + public static string DefaultSplitStr + { + get { return defaultSplitStr; } + } + + + public StrToken(string str) + : this(str, null) + { + } + public StrToken(string str, string splitStr) + { + if (splitStr == null) + { + splitStr = defaultSplitStr; + } + int i, len; + len = splitStr.Length; + char[] chars = new char[len]; + for (i = 0; i < len; i++) + { + chars[i] = splitStr[i]; + } + tokens = str.Split(chars, StringSplitOptions.RemoveEmptyEntries); + } +} + +public class StrData +{ + string strValue; + + public string StrValue + { + get { return strValue; } + } + + public uint IntValue + { + get + { + return Util.StrToUInt(strValue); + } + } + + public ulong Int64Value + { + get + { + return Util.StrToULong(strValue); + } + } + + public StrData(string str) + { + if (str == null) + { + str = ""; + } + strValue = str; + } +} diff --git a/developer_tools/stbchecker/Util.cs b/developer_tools/stbchecker/Util.cs new file mode 100644 index 00000000..243eb7ec --- /dev/null +++ b/developer_tools/stbchecker/Util.cs @@ -0,0 +1,603 @@ +using System; +using System.Text; +using System.Collections; +using System.Security.Cryptography; +using System.Web; +using System.IO; +using System.Drawing; + +public class Util +{ + public static string TruncStr(string str, int len) + { + if (str.Length <= len) + { + return str; + } + else + { + return str.Substring(len); + } + } + + public static string GenRand() + { + return ByteToStr(Hash(Guid.NewGuid().ToByteArray())); + } + + public static bool StrCmpi(string s1, string s2) + { + try + { + if (s1.ToUpper() == s2.ToUpper()) + { + return true; + } + + return false; + } + catch + { + return false; + } + } + + public static bool StrCmp(string s1, string s2) + { + try + { + if (s1 == s2) + { + return true; + } + + return false; + } + catch + { + return false; + } + } + + public static Encoding UTF8() + { + return Encoding.UTF8; + } + + public static Encoding EucJP() + { + return Encoding.GetEncoding("euc-jp"); + } + + public static Encoding ShiftJIS() + { + return Encoding.GetEncoding("shift_jis"); + } + + public static byte[] Hash(string str) + { + return Hash(Encoding.UTF8.GetBytes(str)); + } + + public static byte[] Hash(byte[] data) + { + SHA1 sha1 = SHA1.Create(); + return sha1.ComputeHash(data); + } + + public static string ByteToStr(byte[] data) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in data) + { + sb.Append(b.ToString("X2")); + } + + return sb.ToString(); + } + + public static string RandToStr6(string rand) + { + byte[] hash = Hash(rand + "packetix.net"); + return ByteToStr(hash).Substring(0, 6); + } + + public static bool CheckImageRand(string rand, string str) + { + string s = RandToStr6(rand); + string tmp = str.ToUpper(); + tmp = tmp.Replace("O", "0").Replace("I", "1"); + return StrCmpi(s, tmp); + } + + public static bool IsAscii(char c) + { + if (c >= '0' && c <= '9') + { + return true; + } + if (c >= 'A' && c <= 'Z') + { + return true; + } + if (c >= 'a' && c <= 'z') + { + return true; + } + if (c == '!' || c == '\"' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' || + c == '(' || c == ')' || c == '-' || c == ' ' || c == '=' || c == '~' || c == '^' || c == '_' || + c == '\\' || c == '|' || c == '{' || c == '}' || c == '[' || c == ']' || c == '@' || + c == '*' || c == '+' || c == '.' || c == '<' || c == '>' || + c == ',' || c == '?' || c == '/') + { + return true; + } + return false; + } + public static bool IsAscii(string str) + { + foreach (char c in str) + { + if (IsAscii(c) == false) + { + return false; + } + } + return true; + } + + public static bool CheckMailAddress(string str) + { + str = str.Trim(); + if (str.Length == 0) + { + return false; + } + + string[] tokens = str.Split('@'); + + if (tokens.Length != 2) + { + return false; + } + + string a = tokens[0]; + string b = tokens[1]; + + if (a.Length == 0 || b.Length == 0) + { + return false; + } + + if (b.IndexOf(".") == -1) + { + return false; + } + + return IsAscii(str); + } + + public static string GetFileSizeStr(int size) + { + if (size >= 1024 * 1024) + { + return ((double)(size) / 1024.0f / 1024.0f).ToString(".##") + " MB"; + } + if (size >= 1024) + { + return ((double)(size) / 1024.0f).ToString(".##") + " KB"; + } + return ((double)(size)).ToString() + " Bytes"; + } + + + public static string IntToStr(int i) + { + return i.ToString(); + } + public static string IntToStr(uint i) + { + return i.ToString(); + } + + public static string LongToStr(long i) + { + return i.ToString(); + } + public static string LongToStr(ulong i) + { + return i.ToString(); + } + + public static int StrToInt(string str) + { + try + { + return int.Parse(str); + } + catch + { + try + { + return (int)double.Parse(str); + } + catch + { + return 0; + } + } + } + public static uint StrToUInt(string str) + { + try + { + return uint.Parse(str); + } + catch + { + return 0; + } + } + + public static long StrToLong(string str) + { + try + { + return long.Parse(str); + } + catch + { + return 0; + } + } + public static ulong StrToULong(string str) + { + try + { + return ulong.Parse(str); + } + catch + { + return 0; + } + } + + public static DateTime StrToDate(string str) + { + DateTime ret = new DateTime(0); + str = str.Trim(); + if (str.Length == 8) + { + int year = StrToInt(str.Substring(0, 4)); + int month = StrToInt(str.Substring(4, 2)); + int day = StrToInt(str.Substring(6, 2)); + + ret = new DateTime(year, month, day); + } + return ret; + } + + public static string SafeSql(string str) + { + return str.Replace("'", ""); + } + + public static bool IsFileExists(string name) + { + try + { + return File.Exists(name); + } + catch + { + return false; + } + } + + public static string GetDefaultDocumentIfExists(string dir) + { + string[] targets = + { + "default.aspx", + "default.asp", + "default.html", + "default.htm", + "index.html", + "index.htm", + }; + + foreach (string s in targets) + { + string name = dir + s; + + if (IsFileExists(name)) + { + return name; + } + } + + return null; + } + + public static string ReadHtmlFile(string filename) + { + return File.ReadAllText(filename, Encoding.GetEncoding("shift_jis")); + } + + public static string GetAlternativeTitleFromHtml(string src) + { + string tmp; + string upper; + int i; + + upper = src.ToLower(); + i = upper.IndexOf(""); + if (i == -1) + { + return null; + } + + tmp = src.Substring(0, i); + + i = tmp.IndexOf(""); + if (i == -1) + { + return null; + } + + string ret = tmp.Substring(i + 4); + + if (ret.Length == 0) + { + return null; + } + else + { + return ret; + } + } + + public static string GetTitleFromHtml(string src) + { + string tmp; + string upper; + int i; + + upper = src.ToLower(); + i = upper.IndexOf(""); + if (i == -1) + { + return null; + } + + tmp = src.Substring(0, i); + + i = tmp.IndexOf(""); + if (i == -1) + { + return null; + } + + return tmp.Substring(i + 7); + } + + public static string GetTitleFromHtmlFile(string filename) + { + return GetTitleFromHtml(ReadHtmlFile(filename)); + } + public static string GetAlternativeTitleFromHtmlFile(string filename) + { + return GetAlternativeTitleFromHtml(ReadHtmlFile(filename)); + } + + public static string GetUrlFileNameFromPath(string url) + { + string folder = GetUrlDirNameFromPath(url); + + return url.Substring(folder.Length); + } + + public static string GetUrlDirNameFromPath(string url) + { + string ret = ""; + string[] strs = url.Split('/'); + int i; + if (strs.Length >= 1) + { + for (i = 0; i < strs.Length - 1; i++) + { + ret += strs[i] + "/"; + } + } + return ret; + } + + public static string Encode64(string str) + { + return Convert.ToBase64String(Encoding.UTF8.GetBytes(str)).Replace("/", "(").Replace("+", ")"); + } + + public static string Decode64(string str) + { + return Encoding.UTF8.GetString(Convert.FromBase64String(str.Replace(")", "+").Replace("(", "/"))); + } + + public static string RemoveDefaultHtml(string url) + { + string tmp = url.ToLower(); + if (tmp.EndsWith("/default.asp") || tmp.EndsWith("/default.aspx") || tmp.EndsWith("/default.htm") || tmp.EndsWith("/default.html")) + { + return GetUrlDirNameFromPath(url); + } + else + { + return url; + } + } + + public static string RemovePortFromHostHeader(string str) + { + try + { + string[] ret = str.Split(':'); + + return ret[0]; + } + catch + { + return str; + } + } + + public static string ToStr3(ulong v) + { + string tmp = LongToStr(v); + int len, i; + string tmp2 = ""; + + len = tmp.Length; + + for (i = len - 1; i >= 0; i--) + { + tmp2 += tmp[i]; + } + + tmp = ""; + + for (i = 0; i < len; i++) + { + if (i != 0 && (i % 3) == 0) + { + tmp += ","; + } + tmp += tmp2[i]; + } + + tmp2 = ""; + len = tmp.Length; + + for (i = len - 1; i >= 0; i--) + { + tmp2 += tmp[i]; + } + + return tmp2; + } + + public static string DateTimeToStr(DateTime dt) + { + return DateTimeToStr(dt, false); + } + public static string DateTimeToStr(DateTime dt, bool toLocalTime) + { + if (toLocalTime) + { + dt = dt.ToLocalTime(); + } + + return dt.ToString("yyyy年M月d日(ddd) H時m分s秒"); + } + + public static byte[] IntToByte(uint value) + { + MemoryStream st = new MemoryStream(); + BinaryWriter w = new BinaryWriter(st); + w.Write(value); + st.Seek(0, SeekOrigin.Begin); + return st.ToArray(); + } + + public static uint ByteToInt(byte[] b) + { + MemoryStream st = new MemoryStream(); + st.Write(b, 0, b.Length); + st.Seek(0, SeekOrigin.Begin); + BinaryReader r = new BinaryReader(st); + return r.ReadUInt32(); + } + + public static byte[] ReverseByteArray(byte[] b) + { + int i, num, j; + num = b.Length; + byte[] ret = new byte[num]; + j = 0; + + for (i = num - 1; i >= 0; i--) + { + ret[j++] = b[i]; + } + + return ret; + } + + public static uint ReverseEndian(uint value) + { + return ByteToInt(ReverseByteArray(IntToByte(value))); + } + + public static string SafeDomainStr(string str) + { + string ret = str.Replace("(", "").Replace(")", "").Replace(" ", "").Replace("-", "").Replace("#", "") + .Replace("%", "").Replace("%", "").Replace("&", "").Replace(".", ""); + if (ret == "") + { + ret = "host"; + } + + return ret; + } + + public static bool CompareByte(byte[] b1, byte[] b2) + { + if (b1.Length != b2.Length) + { + return false; + } + int i, len; + len = b1.Length; + for (i = 0; i < len; i++) + { + if (b1[i] != b2[i]) + { + return false; + } + } + return true; + } + + public static int CompareByteRetInt(byte[] b1, byte[] b2) + { + int i; + for (i = 0; ; i++) + { + int a1 = -1, a2 = -1; + if (b1.Length < i) + { + a1 = (int)b1[i]; + } + if (b2.Length < i) + { + a2 = (int)b2[i]; + } + + if (a1 > a2) + { + return 1; + } + else if (a1 < a2) + { + return -1; + } + if (a1 == -1 && a2 == -1) + { + return 0; + } + } + } + + public static byte[] CloneByteArray(byte[] src) + { + return (byte[])src.Clone(); + } +} diff --git a/developer_tools/stbchecker/stbchecker.csproj b/developer_tools/stbchecker/stbchecker.csproj new file mode 100644 index 00000000..3483b250 --- /dev/null +++ b/developer_tools/stbchecker/stbchecker.csproj @@ -0,0 +1,16 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>netcoreapp2.1</TargetFramework> + </PropertyGroup> + + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + +</Project> diff --git a/developer_tools/stbchecker/stbchecker.sln b/developer_tools/stbchecker/stbchecker.sln new file mode 100644 index 00000000..fca35aa8 --- /dev/null +++ b/developer_tools/stbchecker/stbchecker.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2026 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "stbchecker", "stbchecker.csproj", "{BA902FC8-E936-44AA-9C88-57D358BBB700}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BA902FC8-E936-44AA-9C88-57D358BBB700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA902FC8-E936-44AA-9C88-57D358BBB700}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA902FC8-E936-44AA-9C88-57D358BBB700}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA902FC8-E936-44AA-9C88-57D358BBB700}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AD05DECC-E457-42C1-B8AC-46F021023817} + EndGlobalSection +EndGlobal