Be sure to install develop package and runtime library if needed since Visual Studio has 4.6.1 included. Signed-off-by: Syrone Wong <wong.syrone@gmail.com>tags/3.3.3
@@ -1,5 +1,5 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Weavers> | |||||
<Caseless StringComparison="Ordinal"/> | |||||
<Costura/> | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Weavers> | |||||
<Caseless StringComparison="Ordinal"/> | |||||
<Costura/> | |||||
</Weavers> | </Weavers> |
@@ -1,24 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// <auto-generated> | // <auto-generated> | ||||
// This code was generated by a tool. | |||||
// Runtime Version:4.0.30319.42000 | |||||
// 此代码由工具生成。 | |||||
// 运行时版本:4.0.30319.42000 | |||||
// | // | ||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// 对此文件的更改可能会导致不正确的行为,并且如果 | |||||
// 重新生成代码,这些更改将会丢失。 | |||||
// </auto-generated> | // </auto-generated> | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
namespace Shadowsocks.Properties { | namespace Shadowsocks.Properties { | ||||
using System; | using System; | ||||
/// <summary> | /// <summary> | ||||
/// A strongly-typed resource class, for looking up localized strings, etc. | |||||
/// 一个强类型的资源类,用于查找本地化的字符串等。 | |||||
/// </summary> | /// </summary> | ||||
// This class was auto-generated by the StronglyTypedResourceBuilder | |||||
// class via a tool like ResGen or Visual Studio. | |||||
// To add or remove a member, edit your .ResX file then rerun ResGen | |||||
// with the /str option, or rebuild your VS project. | |||||
// 此类是由 StronglyTypedResourceBuilder | |||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 | |||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen | |||||
// (以 /str 作为命令选项),或重新生成 VS 项目。 | |||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] | ||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | ||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | ||||
@@ -31,9 +31,9 @@ namespace Shadowsocks.Properties { | |||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] | ||||
internal Resources() { | internal Resources() { | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Returns the cached ResourceManager instance used by this class. | |||||
/// 返回此类使用的缓存的 ResourceManager 实例。 | |||||
/// </summary> | /// </summary> | ||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | ||||
internal static global::System.Resources.ResourceManager ResourceManager { | internal static global::System.Resources.ResourceManager ResourceManager { | ||||
@@ -45,10 +45,10 @@ namespace Shadowsocks.Properties { | |||||
return resourceMan; | return resourceMan; | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Overrides the current thread's CurrentUICulture property for all | |||||
/// resource lookups using this strongly typed resource class. | |||||
/// 使用此强类型资源类,为所有资源查找 | |||||
/// 重写当前线程的 CurrentUICulture 属性。 | |||||
/// </summary> | /// </summary> | ||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | ||||
internal static global::System.Globalization.CultureInfo Culture { | internal static global::System.Globalization.CultureInfo Culture { | ||||
@@ -59,9 +59,9 @@ namespace Shadowsocks.Properties { | |||||
resourceCulture = value; | resourceCulture = value; | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static byte[] abp_js { | internal static byte[] abp_js { | ||||
get { | get { | ||||
@@ -69,9 +69,9 @@ namespace Shadowsocks.Properties { | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized string similar to # translation for Simplified Chinese | |||||
/// 查找类似 # translation for Simplified Chinese | |||||
/// | /// | ||||
///Shadowsocks=Shadowsocks | ///Shadowsocks=Shadowsocks | ||||
/// | /// | ||||
@@ -83,7 +83,9 @@ namespace Shadowsocks.Properties { | |||||
///Global=全局模式 | ///Global=全局模式 | ||||
///Servers=服务器 | ///Servers=服务器 | ||||
///Edit Servers...=编辑服务器... | ///Edit Servers...=编辑服务器... | ||||
///Statistics Config...=统计配置... | |||||
///Start on Boot=开机启动 | ///Start on Boot=开机启动 | ||||
///Forward Proxy...=正向代理设置... | |||||
///Allow Clients from LAN=允许来自局域网的连接 | ///Allow Clients from LAN=允许来自局域网的连接 | ||||
///Local PAC=使用本地 PAC | ///Local PAC=使用本地 PAC | ||||
///Online PAC=使用在线 PAC | ///Online PAC=使用在线 PAC | ||||
@@ -91,30 +93,16 @@ namespace Shadowsocks.Properties { | |||||
///Update Local PAC from GFWList=从 GFWList 更新本地 PAC | ///Update Local PAC from GFWList=从 GFWList 更新本地 PAC | ||||
///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... | ///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... | ||||
///Show QRCode...=显示二维码... | ///Show QRCode...=显示二维码... | ||||
///Scan QRCode from Screen...=扫描屏幕上的二维码... | |||||
///Availability Statistic [rest of string was truncated]";. | |||||
///Scan [字符串的其余部分被截断]"; 的本地化字符串。 | |||||
/// </summary> | /// </summary> | ||||
internal static string cn { | internal static string cn { | ||||
get { | get { | ||||
return ResourceManager.GetString("cn", resourceCulture); | return ResourceManager.GetString("cn", resourceCulture); | ||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// Looks up a localized string similar to # translation for Traditional Chinese | |||||
/// | |||||
///Shadowsocks=Shadowsocks | |||||
/// | |||||
///# Menu items | |||||
/// </summary> | |||||
internal static string zh_tw { | |||||
get { | |||||
return ResourceManager.GetString("zh_tw", resourceCulture); | |||||
} | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static byte[] libsscrypto_dll { | internal static byte[] libsscrypto_dll { | ||||
get { | get { | ||||
@@ -122,9 +110,9 @@ namespace Shadowsocks.Properties { | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static byte[] mgwz_dll { | internal static byte[] mgwz_dll { | ||||
get { | get { | ||||
@@ -132,22 +120,23 @@ namespace Shadowsocks.Properties { | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized string similar to listen-address __POLIPO_BIND_IP__:8123 | |||||
/// 查找类似 listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ | |||||
///show-on-task-bar 0 | ///show-on-task-bar 0 | ||||
///activity-animation 0 | ///activity-animation 0 | ||||
///forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . | |||||
///hide-console. | |||||
///forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . | |||||
///hide-console | |||||
/// 的本地化字符串。 | |||||
/// </summary> | /// </summary> | ||||
internal static string privoxy_conf { | internal static string privoxy_conf { | ||||
get { | get { | ||||
return ResourceManager.GetString("privoxy_conf", resourceCulture); | return ResourceManager.GetString("privoxy_conf", resourceCulture); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static byte[] privoxy_exe { | internal static byte[] privoxy_exe { | ||||
get { | get { | ||||
@@ -155,9 +144,9 @@ namespace Shadowsocks.Properties { | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static byte[] proxy_pac_txt { | internal static byte[] proxy_pac_txt { | ||||
get { | get { | ||||
@@ -165,9 +154,9 @@ namespace Shadowsocks.Properties { | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ss16 { | internal static System.Drawing.Bitmap ss16 { | ||||
get { | get { | ||||
@@ -175,9 +164,9 @@ namespace Shadowsocks.Properties { | |||||
return ((System.Drawing.Bitmap)(obj)); | return ((System.Drawing.Bitmap)(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ss20 { | internal static System.Drawing.Bitmap ss20 { | ||||
get { | get { | ||||
@@ -185,9 +174,9 @@ namespace Shadowsocks.Properties { | |||||
return ((System.Drawing.Bitmap)(obj)); | return ((System.Drawing.Bitmap)(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ss24 { | internal static System.Drawing.Bitmap ss24 { | ||||
get { | get { | ||||
@@ -197,7 +186,7 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ssIn24 { | internal static System.Drawing.Bitmap ssIn24 { | ||||
get { | get { | ||||
@@ -207,7 +196,7 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ssOut24 { | internal static System.Drawing.Bitmap ssOut24 { | ||||
get { | get { | ||||
@@ -217,7 +206,7 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||||
/// </summary> | /// </summary> | ||||
internal static System.Drawing.Bitmap ssw128 { | internal static System.Drawing.Bitmap ssw128 { | ||||
get { | get { | ||||
@@ -225,16 +214,47 @@ namespace Shadowsocks.Properties { | |||||
return ((System.Drawing.Bitmap)(obj)); | return ((System.Drawing.Bitmap)(obj)); | ||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized string similar to ! Put user rules line by line in this file. | |||||
/// 查找类似 ! Put user rules line by line in this file. | |||||
///! See https://adblockplus.org/en/filter-cheatsheet | ///! See https://adblockplus.org/en/filter-cheatsheet | ||||
///. | |||||
/// 的本地化字符串。 | |||||
/// </summary> | /// </summary> | ||||
internal static string user_rule { | internal static string user_rule { | ||||
get { | get { | ||||
return ResourceManager.GetString("user_rule", resourceCulture); | return ResourceManager.GetString("user_rule", resourceCulture); | ||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 查找类似 # translation for Traditional Chinese | |||||
/// | |||||
///Shadowsocks=Shadowsocks | |||||
/// | |||||
///# Menu items | |||||
/// | |||||
///Enable System Proxy=啟用系統代理 | |||||
///Mode=系統代理模式 | |||||
///PAC=PAC 模式 | |||||
///Global=全局模式 | |||||
///Servers=伺服器 | |||||
///Edit Servers...=編輯伺服器... | |||||
///Statistics Config...=統計配置... | |||||
///Start on Boot=開機啟動 | |||||
///Forward Proxy...=正向代理設置... | |||||
///Allow Clients from LAN=允許來自區域網路的連接 | |||||
///Local PAC=使用本地 PAC | |||||
///Online PAC=使用在線 PAC | |||||
///Edit Local PAC File...=編輯本地 PAC 文件... | |||||
///Update Local PAC from GFWList=從 GFWList 更新本地 PAC | |||||
///Edit User Rule for GFWList...=編輯 GFWList 的用戶規則... | |||||
///Show QRCode...=顯示 QR 碼... | |||||
///Scan QRCode from Screen [字符串的其余部分被截断]"; 的本地化字符串。 | |||||
/// </summary> | |||||
internal static string zh_tw { | |||||
get { | |||||
return ResourceManager.GetString("zh_tw", resourceCulture); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,314 +1,314 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Globalization; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
#if EXPOSE_EVERYTHING || EXPOSE_STRINGEX | |||||
public | |||||
#endif | |||||
static partial class StringEx | |||||
{ | |||||
#pragma warning disable 1591 | |||||
public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal; | |||||
[ThreadStatic] | |||||
private static StringComparison? _DefaultComparison; | |||||
public static StringComparison DefaultComparison | |||||
{ | |||||
get { return _DefaultComparison ?? GlobalDefaultComparison; } | |||||
set { _DefaultComparison = value; } | |||||
} | |||||
#region basic String methods | |||||
public static bool IsNullOrEmpty(this string value) | |||||
=> string.IsNullOrEmpty(value); | |||||
public static bool IsNullOrWhiteSpace(this string value) | |||||
=> string.IsNullOrWhiteSpace(value); | |||||
public static bool IsWhiteSpace(this string value) | |||||
{ | |||||
foreach (var c in value) | |||||
{ | |||||
if (char.IsWhiteSpace(c)) continue; | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
#if !PCL | |||||
public static string IsInterned(this string value) | |||||
{ | |||||
if (value == null) | |||||
throw new ArgumentNullException(nameof(value)); | |||||
return string.IsInterned(value); | |||||
} | |||||
public static string Intern(this string value) | |||||
{ | |||||
if (value == null) | |||||
throw new ArgumentNullException(nameof(value)); | |||||
return string.Intern(value); | |||||
} | |||||
#endif | |||||
#if UNSAFE | |||||
public static unsafe string ToLowerForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
value = string.Copy(value); | |||||
fixed (char* low = value) | |||||
{ | |||||
var end = low + value.Length; | |||||
for (var p = low; p < end; p++) | |||||
{ | |||||
var c = *p; | |||||
if (c < 'A' || c > 'Z') | |||||
continue; | |||||
*p = (char)(c + 0x20); | |||||
} | |||||
} | |||||
return value; | |||||
} | |||||
public static unsafe string ToUpperForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
value = string.Copy(value); | |||||
fixed (char* low = value) | |||||
{ | |||||
var end = low + value.Length; | |||||
for (var p = low; p < end; p++) | |||||
{ | |||||
var c = *p; | |||||
if (c < 'a' || c > 'z') | |||||
continue; | |||||
*p = (char)(c - 0x20); | |||||
} | |||||
} | |||||
return value; | |||||
} | |||||
#else | |||||
public static string ToLowerForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
foreach (var c in value) | |||||
{ | |||||
if (c < 'A' || c > 'Z') | |||||
sb.Append(c); | |||||
else | |||||
sb.Append((char)(c + 0x20)); | |||||
} | |||||
return sb.ToString(); | |||||
} | |||||
public static string ToUpperForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
foreach (var c in value) | |||||
{ | |||||
if (c < 'a' || c > 'z') | |||||
sb.Append(c); | |||||
else | |||||
sb.Append((char)(c - 0x20)); | |||||
} | |||||
return sb.ToString(); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#region comparing | |||||
#region Is | |||||
public static bool Is(this string a, string b) | |||||
=> string.Equals(a, b, DefaultComparison); | |||||
public static bool Is(this string a, string b, StringComparison comparisonType) | |||||
=> string.Equals(a, b, comparisonType); | |||||
#endregion | |||||
#region BeginWith | |||||
public static bool BeginWith(this string s, char c) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return s[0] == c; | |||||
} | |||||
public static bool BeginWithAny(this string s, IEnumerable<char> chars) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return chars.Contains(s[0]); | |||||
} | |||||
public static bool BeginWithAny(this string s, params char[] chars) | |||||
=> s.BeginWithAny(chars.AsEnumerable()); | |||||
public static bool BeginWith(this string a, string b) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, DefaultComparison); | |||||
} | |||||
public static bool BeginWith(this string a, string b, StringComparison comparisonType) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, comparisonType); | |||||
} | |||||
#if !PCL | |||||
public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, ignoreCase, culture); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#region FinishWith | |||||
public static bool FinishWith(this string s, char c) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return s.Last() == c; | |||||
} | |||||
public static bool FinishWithAny(this string s, IEnumerable<char> chars) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return chars.Contains(s.Last()); | |||||
} | |||||
public static bool FinishWithAny(this string s, params char[] chars) | |||||
=> s.FinishWithAny(chars.AsEnumerable()); | |||||
public static bool FinishWith(this string a, string b) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, DefaultComparison); | |||||
} | |||||
public static bool FinishWith(this string a, string b, StringComparison comparisonType) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, comparisonType); | |||||
} | |||||
#if !PCL | |||||
public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, ignoreCase, culture); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#endregion | |||||
#region ToLines | |||||
public static IEnumerable<string> ToLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
yield return line; | |||||
} | |||||
public static IEnumerable<string> NonEmptyLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
if (line == "") continue; | |||||
yield return line; | |||||
} | |||||
} | |||||
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
if (line.IsWhiteSpace()) continue; | |||||
yield return line; | |||||
} | |||||
} | |||||
#endregion | |||||
#region others | |||||
private static readonly char[][] Quotes = new[] | |||||
{ | |||||
"\"\"", | |||||
"''", | |||||
"“”", | |||||
"‘’", | |||||
"『』", | |||||
"「」", | |||||
"〖〗", | |||||
"【】", | |||||
}.Select(s => s.ToCharArray()).ToArray(); | |||||
public static string Enquote(this string value) | |||||
{ | |||||
if (value == null) | |||||
return "(null)"; | |||||
foreach (var pair in Quotes) | |||||
{ | |||||
if (value.IndexOfAny(pair) < 0) | |||||
return pair[0] + value + pair[1]; | |||||
} | |||||
return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"'; | |||||
} | |||||
public static string Replace(this string value, string find, string rep, StringComparison comparsionType) | |||||
{ | |||||
if (find.IsNullOrEmpty()) | |||||
throw new ArgumentException(null, nameof(find)); | |||||
if (rep == null) | |||||
rep = ""; | |||||
if (value.IsNullOrEmpty()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
var last = 0; | |||||
var len = find.Length; | |||||
var idx = value.IndexOf(find, DefaultComparison); | |||||
while (idx != -1) | |||||
{ | |||||
sb.Append(value.Substring(last, idx - last)); | |||||
sb.Append(rep); | |||||
idx += len; | |||||
last = idx; | |||||
idx = value.IndexOf(find, idx, comparsionType); | |||||
} | |||||
sb.Append(value.Substring(last)); | |||||
return sb.ToString(); | |||||
} | |||||
public static string ReplaceEx(this string value, string find, string rep) | |||||
=> value.Replace(find, rep, DefaultComparison); | |||||
#endregion | |||||
} | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Globalization; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
#if EXPOSE_EVERYTHING || EXPOSE_STRINGEX | |||||
public | |||||
#endif | |||||
static partial class StringEx | |||||
{ | |||||
#pragma warning disable 1591 | |||||
public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal; | |||||
[ThreadStatic] | |||||
private static StringComparison? _DefaultComparison; | |||||
public static StringComparison DefaultComparison | |||||
{ | |||||
get { return _DefaultComparison ?? GlobalDefaultComparison; } | |||||
set { _DefaultComparison = value; } | |||||
} | |||||
#region basic String methods | |||||
public static bool IsNullOrEmpty(this string value) | |||||
=> string.IsNullOrEmpty(value); | |||||
public static bool IsNullOrWhiteSpace(this string value) | |||||
=> string.IsNullOrWhiteSpace(value); | |||||
public static bool IsWhiteSpace(this string value) | |||||
{ | |||||
foreach (var c in value) | |||||
{ | |||||
if (char.IsWhiteSpace(c)) continue; | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
#if !PCL | |||||
public static string IsInterned(this string value) | |||||
{ | |||||
if (value == null) | |||||
throw new ArgumentNullException(nameof(value)); | |||||
return string.IsInterned(value); | |||||
} | |||||
public static string Intern(this string value) | |||||
{ | |||||
if (value == null) | |||||
throw new ArgumentNullException(nameof(value)); | |||||
return string.Intern(value); | |||||
} | |||||
#endif | |||||
#if UNSAFE | |||||
public static unsafe string ToLowerForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
value = string.Copy(value); | |||||
fixed (char* low = value) | |||||
{ | |||||
var end = low + value.Length; | |||||
for (var p = low; p < end; p++) | |||||
{ | |||||
var c = *p; | |||||
if (c < 'A' || c > 'Z') | |||||
continue; | |||||
*p = (char)(c + 0x20); | |||||
} | |||||
} | |||||
return value; | |||||
} | |||||
public static unsafe string ToUpperForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
value = string.Copy(value); | |||||
fixed (char* low = value) | |||||
{ | |||||
var end = low + value.Length; | |||||
for (var p = low; p < end; p++) | |||||
{ | |||||
var c = *p; | |||||
if (c < 'a' || c > 'z') | |||||
continue; | |||||
*p = (char)(c - 0x20); | |||||
} | |||||
} | |||||
return value; | |||||
} | |||||
#else | |||||
public static string ToLowerForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
foreach (var c in value) | |||||
{ | |||||
if (c < 'A' || c > 'Z') | |||||
sb.Append(c); | |||||
else | |||||
sb.Append((char)(c + 0x20)); | |||||
} | |||||
return sb.ToString(); | |||||
} | |||||
public static string ToUpperForASCII(this string value) | |||||
{ | |||||
if (value.IsNullOrWhiteSpace()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
foreach (var c in value) | |||||
{ | |||||
if (c < 'a' || c > 'z') | |||||
sb.Append(c); | |||||
else | |||||
sb.Append((char)(c - 0x20)); | |||||
} | |||||
return sb.ToString(); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#region comparing | |||||
#region Is | |||||
public static bool Is(this string a, string b) | |||||
=> string.Equals(a, b, DefaultComparison); | |||||
public static bool Is(this string a, string b, StringComparison comparisonType) | |||||
=> string.Equals(a, b, comparisonType); | |||||
#endregion | |||||
#region BeginWith | |||||
public static bool BeginWith(this string s, char c) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return s[0] == c; | |||||
} | |||||
public static bool BeginWithAny(this string s, IEnumerable<char> chars) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return chars.Contains(s[0]); | |||||
} | |||||
public static bool BeginWithAny(this string s, params char[] chars) | |||||
=> s.BeginWithAny(chars.AsEnumerable()); | |||||
public static bool BeginWith(this string a, string b) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, DefaultComparison); | |||||
} | |||||
public static bool BeginWith(this string a, string b, StringComparison comparisonType) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, comparisonType); | |||||
} | |||||
#if !PCL | |||||
public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.StartsWith(b, ignoreCase, culture); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#region FinishWith | |||||
public static bool FinishWith(this string s, char c) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return s.Last() == c; | |||||
} | |||||
public static bool FinishWithAny(this string s, IEnumerable<char> chars) | |||||
{ | |||||
if (s.IsNullOrEmpty()) return false; | |||||
return chars.Contains(s.Last()); | |||||
} | |||||
public static bool FinishWithAny(this string s, params char[] chars) | |||||
=> s.FinishWithAny(chars.AsEnumerable()); | |||||
public static bool FinishWith(this string a, string b) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, DefaultComparison); | |||||
} | |||||
public static bool FinishWith(this string a, string b, StringComparison comparisonType) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, comparisonType); | |||||
} | |||||
#if !PCL | |||||
public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture) | |||||
{ | |||||
if (a == null || b == null) return false; | |||||
return a.EndsWith(b, ignoreCase, culture); | |||||
} | |||||
#endif | |||||
#endregion | |||||
#endregion | |||||
#region ToLines | |||||
public static IEnumerable<string> ToLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
yield return line; | |||||
} | |||||
public static IEnumerable<string> NonEmptyLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
if (line == "") continue; | |||||
yield return line; | |||||
} | |||||
} | |||||
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
if (line.IsWhiteSpace()) continue; | |||||
yield return line; | |||||
} | |||||
} | |||||
#endregion | |||||
#region others | |||||
private static readonly char[][] Quotes = new[] | |||||
{ | |||||
"\"\"", | |||||
"''", | |||||
"“”", | |||||
"‘’", | |||||
"『』", | |||||
"「」", | |||||
"〖〗", | |||||
"【】", | |||||
}.Select(s => s.ToCharArray()).ToArray(); | |||||
public static string Enquote(this string value) | |||||
{ | |||||
if (value == null) | |||||
return "(null)"; | |||||
foreach (var pair in Quotes) | |||||
{ | |||||
if (value.IndexOfAny(pair) < 0) | |||||
return pair[0] + value + pair[1]; | |||||
} | |||||
return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"'; | |||||
} | |||||
public static string Replace(this string value, string find, string rep, StringComparison comparsionType) | |||||
{ | |||||
if (find.IsNullOrEmpty()) | |||||
throw new ArgumentException(null, nameof(find)); | |||||
if (rep == null) | |||||
rep = ""; | |||||
if (value.IsNullOrEmpty()) | |||||
return value; | |||||
var sb = new StringBuilder(value.Length); | |||||
var last = 0; | |||||
var len = find.Length; | |||||
var idx = value.IndexOf(find, DefaultComparison); | |||||
while (idx != -1) | |||||
{ | |||||
sb.Append(value.Substring(last, idx - last)); | |||||
sb.Append(rep); | |||||
idx += len; | |||||
last = idx; | |||||
idx = value.IndexOf(find, idx, comparsionType); | |||||
} | |||||
sb.Append(value.Substring(last)); | |||||
return sb.ToString(); | |||||
} | |||||
public static string ReplaceEx(this string value, string find, string rep) | |||||
=> value.Replace(find, rep, DefaultComparison); | |||||
#endregion | |||||
} |
@@ -1,17 +1,17 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<configuration> | <configuration> | ||||
<startup> | <startup> | ||||
<supportedRuntime version="v4.0" /> | |||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/> | |||||
</startup> | </startup> | ||||
<runtime> | <runtime> | ||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | ||||
<dependentAssembly> | <dependentAssembly> | ||||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" /> | |||||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> | |||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0"/> | |||||
</dependentAssembly> | </dependentAssembly> | ||||
<dependentAssembly> | <dependentAssembly> | ||||
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" /> | |||||
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> | |||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0"/> | |||||
</dependentAssembly> | </dependentAssembly> | ||||
</assemblyBinding> | </assemblyBinding> | ||||
</runtime> | </runtime> | ||||
@@ -1,9 +1,9 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<packages> | <packages> | ||||
<package id="Caseless.Fody" version="1.4.2" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="Fody" version="1.29.4" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net40-client" /> | |||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40-client" /> | |||||
<package id="StringEx.CS" version="0.3.1" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="Caseless.Fody" version="1.4.2" targetFramework="net462" developmentDependency="true" /> | |||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net462" developmentDependency="true" /> | |||||
<package id="Fody" version="1.29.4" targetFramework="net462" developmentDependency="true" /> | |||||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net462" /> | |||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" /> | |||||
<package id="StringEx.CS" version="0.3.1" targetFramework="net462" developmentDependency="true" /> | |||||
</packages> | </packages> |
@@ -10,7 +10,7 @@ | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
<RootNamespace>Shadowsocks</RootNamespace> | <RootNamespace>Shadowsocks</RootNamespace> | ||||
<AssemblyName>Shadowsocks</AssemblyName> | <AssemblyName>Shadowsocks</AssemblyName> | ||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | |||||
<FileAlignment>512</FileAlignment> | <FileAlignment>512</FileAlignment> | ||||
<StartupObject> | <StartupObject> | ||||
</StartupObject> | </StartupObject> | ||||
@@ -21,7 +21,8 @@ | |||||
<UpgradeBackupLocation> | <UpgradeBackupLocation> | ||||
</UpgradeBackupLocation> | </UpgradeBackupLocation> | ||||
<OldToolsVersion>3.5</OldToolsVersion> | <OldToolsVersion>3.5</OldToolsVersion> | ||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile> | |||||
<TargetFrameworkProfile> | |||||
</TargetFrameworkProfile> | |||||
<PublishUrl>publish\</PublishUrl> | <PublishUrl>publish\</PublishUrl> | ||||
<Install>true</Install> | <Install>true</Install> | ||||
<InstallFrom>Disk</InstallFrom> | <InstallFrom>Disk</InstallFrom> | ||||
@@ -72,7 +73,7 @@ | |||||
<Reference Include="Microsoft.CSharp" /> | <Reference Include="Microsoft.CSharp" /> | ||||
<Reference Include="Microsoft.VisualBasic" /> | <Reference Include="Microsoft.VisualBasic" /> | ||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | ||||
<HintPath>3rd\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll</HintPath> | |||||
<HintPath>3rd\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> | |||||
<Private>True</Private> | <Private>True</Private> | ||||
</Reference> | </Reference> | ||||
<Reference Include="PresentationCore" /> | <Reference Include="PresentationCore" /> | ||||
@@ -336,13 +337,6 @@ | |||||
</BootstrapperPackage> | </BootstrapperPackage> | ||||
</ItemGroup> | </ItemGroup> | ||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets'))" /> | |||||
</Target> | |||||
<Import Project="3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" /> | |||||
<UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory"> | <UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory"> | ||||
<ParameterGroup> | <ParameterGroup> | ||||
<Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" /> | <Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" /> | ||||
@@ -379,6 +373,13 @@ foreach (var item in filesToCleanup) | |||||
<Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget"> | <Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget"> | ||||
<CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" /> | <CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" /> | ||||
</Target> | </Target> | ||||
<Import Project="3rd\Fody.1.29.4\build\dotnet\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\dotnet\Fody.targets'))" /> | |||||
</Target> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||||
Other similar extension points exist, see Microsoft.Common.targets. | Other similar extension points exist, see Microsoft.Common.targets. | ||||
<Target Name="BeforeBuild"> | <Target Name="BeforeBuild"> | ||||
@@ -1,5 +1,5 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||
@@ -8,7 +8,7 @@ | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
<RootNamespace>test</RootNamespace> | <RootNamespace>test</RootNamespace> | ||||
<AssemblyName>test</AssemblyName> | <AssemblyName>test</AssemblyName> | ||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | |||||
<FileAlignment>512</FileAlignment> | <FileAlignment>512</FileAlignment> | ||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> | <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> | ||||