/* Copyright (c) Citrix Systems Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Drawing; namespace XenAdmin { public static class StringExtensions { /// /// Ellipsise string by appending the ellipsis - no truncation is performed /// /// /// public static string AddEllipsis(this string input) { return String.Concat(input, Messages.ELLIPSIS); } /// /// If input is longer than maxLength, returns a string of length maxLength consisting of a truncated /// version of the input string with an i18n'd ellipsis character appended. Otherwise returns input. /// /// May be null, in which case the empty string is returned. /// Must be >= Messages.ELLIPSIS.Length. /// public static string Ellipsise(this string input, int maxLength) { if (maxLength < Messages.ELLIPSIS.Length) return "."; if (input == null) return ""; if (input.Length < maxLength) return input; else return input.Truncate(maxLength - Messages.ELLIPSIS.Length) + Messages.ELLIPSIS; } /// /// Truncate string to a fixed number of characters, but not cutting it in the middle of a UTF-16 surrogate pair: /// shorten it by one if necessary. The "number of characters" is actually "number of UTF-16 double bytes", not /// the number of true Unicode characters. In other words, this a safe replacement for s.Substring(0, len). /// /// CA-89876 /// The string to be truncated /// The length of the resultant string /// A truncated copy of the string public static string Truncate(this string s, int len) { if (len > 0 && Char.IsSurrogatePair(s, len - 1)) return s.Substring(0, len - 1); else return s.Substring(0, len); } /// /// This has the same bahvoiur as the standard ellipsise extension but this uses graphics /// objects to scale the text. This performs a binary chop on the string to get the correct length /// /// /// /// /// /// public static string Ellipsise(this string text, Graphics g, Rectangle rectangle, Font font) { int width = (int)g.MeasureString(text, font).Width; if (width <= rectangle.Width) return text; int widthel = (int)g.MeasureString(Messages.ELLIPSIS, font).Width; if (widthel > rectangle.Width) return "."; // Binary chop to set the string to the right size int a = 0; int b = text.Length; int c; for (c = (a + b) / 2; c > a; c = (a + b) / 2) { string sr = text.Ellipsise(c); int srWidth = (int)g.MeasureString(sr, font).Width; if (srWidth > rectangle.Width) b = c; else a = c; } return text.Ellipsise(c); } /// /// Escapes ampersands by doubling them up. Will return null if passed null. /// /// /// public static string EscapeAmpersands(this string s) { if (s == null) return null; else return s.Replace("&", "&&"); } } }