Skip to content

Commit

Permalink
Rewrite of name capitalization routine 'UnderscoresToPascalOrCamelCase'
Browse files Browse the repository at this point in the history
  • Loading branch information
csharptest authored and rogerk committed Aug 12, 2011
1 parent 25981d4 commit c7b23c1
Showing 1 changed file with 47 additions and 41 deletions.
88 changes: 47 additions & 41 deletions src/ProtocolBuffers/NameHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@

#endregion

using System;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace Google.ProtocolBuffers
{
Expand Down Expand Up @@ -64,49 +66,14 @@ public static string UnderscoresToCamelCase(string input)
/// </summary>
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)
Expand All @@ -131,5 +98,44 @@ public static bool StripSuffix(ref string text, string suffix)
}
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();
}
}
}

0 comments on commit c7b23c1

Please sign in to comment.