|
@@ -34,8 +34,10 @@
|
|
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
|
+using System;
|
|
using System.Globalization;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Text;
|
|
|
|
+using System.Text.RegularExpressions;
|
|
|
|
|
|
namespace Google.ProtocolBuffers
|
|
namespace Google.ProtocolBuffers
|
|
{
|
|
{
|
|
@@ -64,49 +66,14 @@ namespace Google.ProtocolBuffers
|
|
/// </summary>
|
|
/// </summary>
|
|
private static string UnderscoresToPascalOrCamelCase(string input, bool pascal)
|
|
private static string UnderscoresToPascalOrCamelCase(string input, bool pascal)
|
|
{
|
|
{
|
|
- StringBuilder result = new StringBuilder();
|
|
|
|
- bool capitaliseNext = pascal;
|
|
|
|
- for (int i = 0; i < input.Length; i++)
|
|
|
|
|
|
+ string name = Transform(input, pascal ? UnderlineToPascal : UnderlineToCamel, x => x.Value.TrimStart('_').ToUpper());
|
|
|
|
+ if (!pascal && name.Length > 0 && Char.IsUpper(name[0]))
|
|
{
|
|
{
|
|
- char c = input[i];
|
|
|
|
- if ('a' <= c && c <= 'z')
|
|
|
|
- {
|
|
|
|
- if (capitaliseNext)
|
|
|
|
- {
|
|
|
|
- result.Append(char.ToUpper(c, CultureInfo.InvariantCulture));
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- result.Append(c);
|
|
|
|
- }
|
|
|
|
- capitaliseNext = false;
|
|
|
|
- }
|
|
|
|
- else if ('A' <= c && c <= 'Z')
|
|
|
|
- {
|
|
|
|
- if (i == 0 && !pascal)
|
|
|
|
- {
|
|
|
|
- // Force first letter to lower-case unless explicitly told to
|
|
|
|
- // capitalize it.
|
|
|
|
- result.Append(char.ToLower(c, CultureInfo.InvariantCulture));
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // Capital letters after the first are left as-is.
|
|
|
|
- result.Append(c);
|
|
|
|
- }
|
|
|
|
- capitaliseNext = false;
|
|
|
|
- }
|
|
|
|
- else if ('0' <= c && c <= '9')
|
|
|
|
- {
|
|
|
|
- result.Append(c);
|
|
|
|
- capitaliseNext = true;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- capitaliseNext = true;
|
|
|
|
- }
|
|
|
|
|
|
+ char[] chars = name.ToCharArray();
|
|
|
|
+ chars[0] = char.ToLower(chars[0]);
|
|
|
|
+ return new string(chars);
|
|
}
|
|
}
|
|
- return result.ToString();
|
|
|
|
|
|
+ return name;
|
|
}
|
|
}
|
|
|
|
|
|
internal static string StripProto(string text)
|
|
internal static string StripProto(string text)
|
|
@@ -131,5 +98,44 @@ namespace Google.ProtocolBuffers
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Similar to UnderlineToCamel, but also matches the first character if it is lower-case
|
|
|
|
+ /// </summary>
|
|
|
|
+ private static Regex UnderlineToPascal = new Regex(@"(?:^|[0-9_])[a-z]");
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Matches lower-case character that follow either an underscore, or a number
|
|
|
|
+ /// </summary>
|
|
|
|
+ private static Regex UnderlineToCamel = new Regex(@"[0-9_][a-z]");
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Used for text-template transformation where a regex match is replaced in the input string.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="input">The text to perform the replacement upon</param>
|
|
|
|
+ /// <param name="pattern">The regex used to perform the match</param>
|
|
|
|
+ /// <param name="fnReplace">A delegate that selects the appropriate replacement text</param>
|
|
|
|
+ /// <returns>The newly formed text after all replacements are made</returns>
|
|
|
|
+ /// <remarks>
|
|
|
|
+ /// Originally found at http://csharptest.net/browse/src/Library/Utils/StringUtils.cs#120
|
|
|
|
+ /// Republished here by the original author under this project's licensing.
|
|
|
|
+ /// </remarks>
|
|
|
|
+ private static string Transform(string input, Regex pattern, Converter<Match, string> fnReplace)
|
|
|
|
+ {
|
|
|
|
+ int currIx = 0;
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+
|
|
|
|
+ foreach (Match match in pattern.Matches(input))
|
|
|
|
+ {
|
|
|
|
+ sb.Append(input, currIx, match.Index - currIx);
|
|
|
|
+ string replace = fnReplace(match);
|
|
|
|
+ sb.Append(replace);
|
|
|
|
+
|
|
|
|
+ currIx = match.Index + match.Length;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sb.Append(input, currIx, input.Length - currIx);
|
|
|
|
+ return sb.ToString();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|