From c7b23c17979e93fb91be6e9a35ec0aef4a73704d Mon Sep 17 00:00:00 2001 From: csharptest Date: Fri, 12 Aug 2011 16:34:50 -0500 Subject: Rewrite of name capitalization routine 'UnderscoresToPascalOrCamelCase' --- src/ProtocolBuffers/NameHelpers.cs | 88 ++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 41 deletions(-) (limited to 'src/ProtocolBuffers/NameHelpers.cs') diff --git a/src/ProtocolBuffers/NameHelpers.cs b/src/ProtocolBuffers/NameHelpers.cs index cd8f2a79..40231147 100644 --- a/src/ProtocolBuffers/NameHelpers.cs +++ b/src/ProtocolBuffers/NameHelpers.cs @@ -34,8 +34,10 @@ #endregion +using System; using System.Globalization; using System.Text; +using System.Text.RegularExpressions; namespace Google.ProtocolBuffers { @@ -64,49 +66,14 @@ namespace Google.ProtocolBuffers /// 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) @@ -131,5 +98,44 @@ namespace Google.ProtocolBuffers } return false; } + + /// + /// Similar to UnderlineToCamel, but also matches the first character if it is lower-case + /// + private static Regex UnderlineToPascal = new Regex(@"(?:^|[0-9_])[a-z]"); + + /// + /// Matches lower-case character that follow either an underscore, or a number + /// + private static Regex UnderlineToCamel = new Regex(@"[0-9_][a-z]"); + + /// + /// Used for text-template transformation where a regex match is replaced in the input string. + /// + /// The text to perform the replacement upon + /// The regex used to perform the match + /// A delegate that selects the appropriate replacement text + /// The newly formed text after all replacements are made + /// + /// Originally found at http://csharptest.net/browse/src/Library/Utils/StringUtils.cs#120 + /// Republished here by the original author under this project's licensing. + /// + private static string Transform(string input, Regex pattern, Converter 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(); + } } } \ No newline at end of file -- cgit v1.2.3