Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json\Utilities\StringUtils.cs

Symbol Coverage: 24.49% (36 of 147)

Branch Coverage: 22.78% (18 of 79)

Cyclomatic Complexity Avg: 2.40 Max:6

Code Lines: 148


L V Source
1
#region License
2
// Copyright (c) 2007 James Newton-King
3
//
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
11
// conditions:
12
//
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
15
//
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
24
#endregion
25

  
26
using System;
27
using System.Collections.Generic;
28
using System.IO;
29
using System.Text;
30
using System.Text.RegularExpressions;
31
using System.Linq;
32
using System.Globalization;
33

  
34
namespace Newtonsoft.Json.Utilities
35
{
36
  internal static class StringUtils
37
  {
38
    public const string CarriageReturnLineFeed = "\r\n";
39
    public const string Empty = "";
40
    public const char CarriageReturn = '\r';
41
    public const char LineFeed = '\n';
42
    public const char Tab = '\t';
43

  
44
    //public static string FormatWith(this string format, params object[] args)
45
    //{
46
    //  return FormatWith(format, null, args);
47
    //}
48

  
49
    public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
50
    {
51
 209
      ValidationUtils.ArgumentNotNull(format, "format");
52

  
53
 209
      return string.Format(provider, format, args);
54
 209
    }
55

  
56
    /// <summary>
57
    /// Determines whether the string contains white space.
58
    /// </summary>
59
    /// <param name="s">The string to test for white space.</param>
60
    /// <returns>
61
    /// 	<c>true</c> if the string contains white space; otherwise, <c>false</c>.
62
    /// </returns>
63
    public static bool ContainsWhiteSpace(string s)
64
    {
65
 0
      if (s == null)
66
 0
        throw new ArgumentNullException("s");
67

  
68
 0
      for (int i = 0; i < s.Length; i++)
69
      {
70
 0
        if (char.IsWhiteSpace(s[i]))
71
 0
          return true;
72
      }
73
 0
      return false;
74
 0
    }
75

  
76
    /// <summary>
77
    /// Determines whether the string is all white space. Empty string will return false.
78
    /// </summary>
79
    /// <param name="s">The string to test whether it is all white space.</param>
80
    /// <returns>
81
    /// 	<c>true</c> if the string is all white space; otherwise, <c>false</c>.
82
    /// </returns>
83
    public static bool IsWhiteSpace(string s)
84
    {
85
 1
      if (s == null)
86
 0
        throw new ArgumentNullException("s");
87

  
88
 1
      if (s.Length == 0)
89
 0
        return false;
90

  
91
 1
      for (int i = 0; i < s.Length; i++)
92
      {
93
 2
        if (!char.IsWhiteSpace(s[i]))
94
 0
          return false;
95
      }
96

  
97
 1
      return true;
98
 1
    }
99

  
100
    /// <summary>
101
    /// Ensures the target string ends with the specified string.
102
    /// </summary>
103
    /// <param name="target">The target.</param>
104
    /// <param name="value">The value.</param>
105
    /// <returns>The target string with the value string at the end.</returns>
106
    public static string EnsureEndsWith(string target, string value)
107
    {
108
 0
      if (target == null)
109
 0
        throw new ArgumentNullException("target");
110

  
111
 0
      if (value == null)
112
 0
        throw new ArgumentNullException("value");
113

  
114
 0
      if (target.Length >= value.Length)
115
      {
116
 0
        if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) ==
117
 0
                        0)
118
 0
          return target;
119

  
120
 0
        string trimmedString = target.TrimEnd(null);
121

  
122
 0
        if (string.Compare(trimmedString, trimmedString.Length - value.Length, value, 0, value.Length,
123
 0
                        StringComparison.OrdinalIgnoreCase) == 0)
124
 0
          return target;
125
      }
126

  
127
 0
      return target + value;
128
 0
    }
129

  
130
    public static bool IsNullOrEmptyOrWhiteSpace(string s)
131
    {
132
 0
      if (string.IsNullOrEmpty(s))
133
 0
        return true;
134
 0
      else if (IsWhiteSpace(s))
135
 0
        return true;
136
      else
137
 0
        return false;
138
 0
    }
139

  
140
    /// <summary>
141
    /// Perform an action if the string is not null or empty.
142
    /// </summary>
143
    /// <param name="value">The value.</param>
144
    /// <param name="action">The action to perform.</param>
145
    public static void IfNotNullOrEmpty(string value, Action<string> action)
146
    {
147
 0
      IfNotNullOrEmpty(value, action, null);
148
 0
    }
149

  
150
    private static void IfNotNullOrEmpty(string value, Action<string> trueAction, Action<string> falseAction)
151
    {
152
 0
      if (!string.IsNullOrEmpty(value))
153
      {
154
 0
        if (trueAction != null)
155
 0
          trueAction(value);
156
      }
157
      else
158
      {
159
 0
        if (falseAction != null)
160
 0
          falseAction(value);
161
      }
162
 0
    }
163

  
164
    /// <summary>
165
    /// Indents the specified string.
166
    /// </summary>
167
    /// <param name="s">The string to indent.</param>
168
    /// <param name="indentation">The number of characters to indent by.</param>
169
    /// <returns></returns>
170
    public static string Indent(string s, int indentation)
171
    {
172
 0
      return Indent(s, indentation, ' ');
173
 0
    }
174

  
175
    /// <summary>
176
    /// Indents the specified string.
177
    /// </summary>
178
    /// <param name="s">The string to indent.</param>
179
    /// <param name="indentation">The number of characters to indent by.</param>
180
    /// <param name="indentChar">The indent character.</param>
181
    /// <returns></returns>
182
    public static string Indent(string s, int indentation, char indentChar)
183
    {
184
 0
      if (s == null)
185
 0
        throw new ArgumentNullException("s");
186

  
187
 0
      if (indentation <= 0)
188
 0
        throw new ArgumentException("Must be greater than zero.", "indentation");
189

  
190
 0
      StringReader sr = new StringReader(s);
191
 0
      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
192

  
193
 0
      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
194
 0
      {
195
 0
        tw.Write(new string(indentChar, indentation));
196
 0
        tw.Write(line);
197
 0
      });
198

  
199
 0
      return sw.ToString();
200
 0
    }
201

  
202
    private delegate void ActionLine(TextWriter textWriter, string line);
203

  
204
    private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction)
205
    {
206
      string line;
207
 0
      bool firstLine = true;
208
 0
      while ((line = textReader.ReadLine()) != null)
209
      {
210
 0
        if (!firstLine)
211
 0
          textWriter.WriteLine();
212
        else
213
 0
          firstLine = false;
214

  
215
 0
        lineAction(textWriter, line);
216
      }
217
 0
    }
218

  
219
    /// <summary>
220
    /// Numbers the lines.
221
    /// </summary>
222
    /// <param name="s">The string to number.</param>
223
    /// <returns></returns>
224
    public static string NumberLines(string s)
225
    {
226
 0
      if (s == null)
227
 0
        throw new ArgumentNullException("s");
228

  
229
 0
      StringReader sr = new StringReader(s);
230
 0
      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
231

  
232
 0
      int lineNumber = 1;
233

  
234
 0
      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
235
 0
      {
236
 0
        tw.Write(lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(4));
237
 0
        tw.Write(". ");
238
 0
        tw.Write(line);
239
 0

  
240
 0
        lineNumber++;
241
 0
      });
242

  
243
 0
      return sw.ToString();
244
 0
    }
245

  
246
    /// <summary>
247
    /// Nulls an empty string.
248
    /// </summary>
249
    /// <param name="s">The string.</param>
250
    /// <returns>Null if the string was null, otherwise the string unchanged.</returns>
251
    public static string NullEmptyString(string s)
252
    {
253
 4
      return (string.IsNullOrEmpty(s)) ? null : s;
254
 4
    }
255

  
256
    public static string ReplaceNewLines(string s, string replacement)
257
    {
258
 0
      StringReader sr = new StringReader(s);
259
 0
      StringBuilder sb = new StringBuilder();
260

  
261
 0
      bool first = true;
262

  
263
      string line;
264
 0
      while ((line = sr.ReadLine()) != null)
265
      {
266
 0
        if (first)
267
 0
          first = false;
268
        else
269
 0
          sb.Append(replacement);
270

  
271
 0
        sb.Append(line);
272
      }
273

  
274
 0
      return sb.ToString();
275
 0
    }
276

  
277
    public static string Truncate(string s, int maximumLength)
278
    {
279
 0
      return Truncate(s, maximumLength, "...");
280
 0
    }
281

  
282
    public static string Truncate(string s, int maximumLength, string suffix)
283
    {
284
 0
      if (suffix == null)
285
 0
        throw new ArgumentNullException("suffix");
286

  
287
 0
      if (maximumLength <= 0)
288
 0
        throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength");
289

  
290
 0
      int subStringLength = maximumLength - suffix.Length;
291

  
292
 0
      if (subStringLength <= 0)
293
 0
        throw new ArgumentException("Length of suffix string is greater or equal to maximumLength");
294

  
295
 0
      if (s != null && s.Length > maximumLength)
296
      {
297
 0
        string truncatedString = s.Substring(0, subStringLength);
298
        // incase the last character is a space
299
 0
        truncatedString = truncatedString.Trim();
300
 0
        truncatedString += suffix;
301

  
302
 0
        return truncatedString;
303
      }
304
      else
305
      {
306
 0
        return s;
307
      }
308
 0
    }
309

  
310
    public static StringWriter CreateStringWriter(int capacity)
311
    {
312
 38
      StringBuilder sb = new StringBuilder(capacity);
313
 38
      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
314

  
315
 38
      return sw;
316
 38
    }
317

  
318
    public static int? GetLength(string value)
319
    {
320
 30
      if (value == null)
321
 0
        return null;
322
      else
323
 30
        return value.Length;
324
 30
    }
325

  
326
    public static string ToCharAsUnicode(char c)
327
    {
328
 5258
      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
329
 5258
      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
330
 5258
      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
331
 5258
      char h4 = MathUtils.IntToHex(c & '\x000f');
332

  
333
 5258
      return new string(new[] { '\\', 'u', h1, h2, h3, h4 });
334
 5258
    }
335

  
336
    public static void WriteCharAsUnicode(TextWriter writer, char c)
337
    {
338
 0
      ValidationUtils.ArgumentNotNull(writer, "writer");
339

  
340
 0
      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
341
 0
      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
342
 0
      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
343
 0
      char h4 = MathUtils.IntToHex(c & '\x000f');
344

  
345
 0
      writer.Write('\\');
346
 0
      writer.Write('u');
347
 0
      writer.Write(h1);
348
 0
      writer.Write(h2);
349
 0
      writer.Write(h3);
350
 0
      writer.Write(h4);
351
 0
    }
352

  
353
    public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
354
    {
355
 28
      if (source == null)
356
 0
        throw new ArgumentNullException("source");
357
 28
      if (valueSelector == null)
358
 0
        throw new ArgumentNullException("valueSelector");
359

  
360
 28
      var caseInsensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase) == 0);
361
 28
      if (caseInsensitiveResults.Count() <= 1)
362
      {
363
 26
        return caseInsensitiveResults.SingleOrDefault();
364
      }
365
      else
366
      {
367
        // multiple results returned. now filter using case sensitivity
368
 2
        var caseSensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.Ordinal) == 0);
369
 2
        return caseSensitiveResults.SingleOrDefault();
370
      }
371
 28
    }
372
  }
373
}