diff --git a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs index bba8a132..6f70d5c6 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs @@ -55,6 +55,7 @@ namespace Newtonsoft.Json.Tests.Utilities Assert.AreEqual("iPhone", StringUtils.ToCamelCase("IPhone")); Assert.AreEqual("i Phone", StringUtils.ToCamelCase("I Phone")); Assert.AreEqual(" IPhone", StringUtils.ToCamelCase(" IPhone")); + Assert.AreEqual("isCIA", StringUtils.ToCamelCase("IsCIA")); } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/StringUtils.cs b/Src/Newtonsoft.Json/Utilities/StringUtils.cs index 3fad3249..122fc837 100644 --- a/Src/Newtonsoft.Json/Utilities/StringUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/StringUtils.cs @@ -170,26 +170,26 @@ namespace Newtonsoft.Json.Utilities public static string ToCamelCase(string s) { - if (string.IsNullOrEmpty(s)) - { - return s; - } - - if (!char.IsUpper(s[0])) + if (string.IsNullOrEmpty(s) || !char.IsUpper(s[0])) { return s; } char[] chars = s.ToCharArray(); - for (int i = 0; i < chars.Length; i++) + int toLowerUntilIndex = 1; + while (toLowerUntilIndex < chars.Length && char.IsUpper(chars[toLowerUntilIndex])) { - bool hasNext = (i + 1 < chars.Length); - if (i > 0 && hasNext && !char.IsUpper(chars[i + 1])) - { - break; - } + ++toLowerUntilIndex; + } + // decrement if starts with consecutive upper case letters but is not all upper + if (toLowerUntilIndex > 1 && toLowerUntilIndex < chars.Length) + { + --toLowerUntilIndex; + } + for (int i = 0; i < toLowerUntilIndex; ++i) + { #if !(DOTNET || PORTABLE) chars[i] = char.ToLower(chars[i], CultureInfo.InvariantCulture); #else