/// <summary> /// Creates a <see cref="string"/> from a C string. /// </summary> /// <param name="ptr">The pointer to read from.</param> /// <param name="option">The string trim options.</param> /// <returns> /// A managed string that holds a copy of the C string. /// </returns> internal static unsafe string FromCString(byte *ptr, StringTrimOption option) { if (!TryGetCStringLength(ptr, out int length)) { return(null); } return(FromCString(ptr, length, option)); }
/// <summary> /// Creates a <see cref="string"/> from a Pascal string. /// </summary> /// <param name="pascalString">The pascal string to convert.</param> /// <returns> /// A managed string that holds a copy of the Pascal string. /// If <paramref name="pascalString"/> is null, the method returns null. /// </returns> internal static unsafe string FromPascalString(byte *pascalString, StringTrimOption option) { if (pascalString == null) { return(null); } TrimmedStringOffsets trimmed = GetTrimmedStringOffsets(pascalString, 1, pascalString[0], option); if (trimmed.IsEmptyString) { return(string.Empty); } else { return(new string((sbyte *)pascalString, trimmed.startIndex, trimmed.length, Windows1252Encoding)); } }
/// <summary> /// Creates a <see cref="string"/> from a C string that is UTF-16LE encoded. /// </summary> /// <param name="ptr">The pointer to read from.</param> /// <param name="length">The length of the string.</param> /// <param name="option">The string trim options.</param> /// <returns> /// A managed string that holds a copy of the C string. /// </returns> internal static unsafe string FromCStringUni(char *ptr, int length, StringTrimOption option) { if (ptr == null) { return(null); } TrimmedStringOffsets stringOffsets = GetTrimmedStringOffsets(ptr, 0, length, option); if (stringOffsets.IsEmptyString) { return(string.Empty); } else { return(new string(ptr, stringOffsets.startIndex, stringOffsets.length)); } }
/// <summary> /// Creates a <see cref="string"/> from a C string. /// </summary> /// <param name="ptr">The pointer to read from.</param> /// <param name="length">The length of the string.</param> /// <param name="option">The string trim options.</param> /// <returns> /// A managed string that holds a copy of the C string. /// </returns> internal static unsafe string FromCString(byte *ptr, int length, StringTrimOption option) { if (ptr == null) { return(null); } TrimmedStringOffsets stringOffsets = GetTrimmedStringOffsets(ptr, 0, length, option); if (stringOffsets.IsEmptyString) { return(string.Empty); } else { return(new string((sbyte *)ptr, stringOffsets.startIndex, stringOffsets.length, Windows1252Encoding)); } }
private static bool IsTrimmedValue(char value, StringTrimOption option) { switch (option) { case StringTrimOption.None: return(false); case StringTrimOption.NullTerminator: return(value == '\0'); case StringTrimOption.WhiteSpace: return(char.IsWhiteSpace(value)); case StringTrimOption.WhiteSpaceAndNullTerminator: return(value == '\0' || char.IsWhiteSpace(value)); default: throw new InvalidEnumArgumentException(nameof(option), (int)option, typeof(StringTrimOption)); } }
private static bool IsTrimmedValue(byte value, StringTrimOption option) { switch (option) { case StringTrimOption.None: return(false); case StringTrimOption.NullTerminator: return(value == 0); case StringTrimOption.WhiteSpace: return(IsWhiteSpaceWindows1252(value)); case StringTrimOption.WhiteSpaceAndNullTerminator: return(value == 0 || IsWhiteSpaceWindows1252(value)); default: throw new InvalidEnumArgumentException(nameof(option), (int)option, typeof(StringTrimOption)); } }
private static unsafe TrimmedStringOffsets GetTrimmedStringOffsets(char *ptr, int startIndex, int length, StringTrimOption option) { if (length == 0 || option == StringTrimOption.None) { return(new TrimmedStringOffsets(startIndex, length)); } int start = startIndex; int end = length; // The search at the start of the string can be skipped if we not trimming white space. if (option == StringTrimOption.WhiteSpaceAndNullTerminator || option == StringTrimOption.WhiteSpace) { while (start < length) { if (!IsTrimmedValue(ptr[start], option)) { break; } start++; } } while (end >= start) { if (!IsTrimmedValue(ptr[end], option)) { break; } end--; } return(new TrimmedStringOffsets(start, end - start + 1)); }