Created
September 25, 2019 12:53
-
-
Save wipiano/5ae95de1fa732b4363be2c04da3445a3 to your computer and use it in GitHub Desktop.
Span での文字列操作
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace IMC.Util | |
{ | |
public static class ByteArrayExtensions | |
{ | |
/// <summary> | |
/// 16 進数の文字列に変換します | |
/// </summary> | |
public static string ToHexString(this byte[] source, bool upperCase = false) | |
{ | |
Span<char> buffer = stackalloc char[source.Length * 2]; | |
source.WriteAsHexChars(buffer, out _, upperCase); | |
return buffer.ToString(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
namespace IMC.Util | |
{ | |
/// <summary> | |
/// char の Span 用 util | |
/// </summary> | |
public static class CharSpanUtility | |
{ | |
/// <summary> | |
/// バイトを 16 進数として書き込みます | |
/// </summary> | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static void WriteAsHexChars(this byte b, Span<char> dest, out int charsWritten, bool upperCase = false) | |
{ | |
ReadOnlySpan<char> source = upperCase ? s_byteToHexUpper[b] : s_byteToHexLower[b]; | |
source.CopyTo(dest); | |
charsWritten = source.Length; // 2 固定のはず | |
} | |
/// <summary> | |
/// バイト列を 16 進数の列として書き込みます | |
/// </summary> | |
public static void WriteAsHexChars(this ReadOnlySpan<byte> bytes, Span<char> dest, out int charsWritten, | |
bool upperCase = false) | |
{ | |
charsWritten = 0; | |
foreach (byte b in bytes) | |
{ | |
b.WriteAsHexChars(dest.Slice(charsWritten), out var count, upperCase); | |
charsWritten += count; | |
} | |
} | |
/// <summary> | |
/// バイト列を 16 進数の列として書き込みます | |
/// </summary> | |
public static void WriteAsHexChars(this IEnumerable<byte> bytes, Span<char> dest, out int charsWritten, | |
bool upperCase = false) | |
{ | |
charsWritten = 0; | |
foreach (byte b in bytes) | |
{ | |
b.WriteAsHexChars(dest.Slice(charsWritten), out var count, upperCase); | |
charsWritten += count; | |
} | |
} | |
// byte -> char[] に変換するための 配列 | |
private static readonly char[][] s_byteToHexLower = | |
Enumerable.Range(0, 256).Select(x => ((byte) x).ToString("x2").ToCharArray()).ToArray(); | |
private static readonly char[][] s_byteToHexUpper = | |
Enumerable.Range(0, 256).Select(x => ((byte) x).ToString("X2").ToCharArray()).ToArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace IMC.Util | |
{ | |
public ref struct SpanStringBuilder | |
{ | |
private Span<char> _buffer; | |
private int _index; | |
public SpanStringBuilder(Span<char> buffer) | |
{ | |
_buffer = buffer; | |
_index = 0; | |
} | |
public void Write(ReadOnlySpan<char> str) | |
{ | |
str.CopyTo(_buffer.Slice(_index)); | |
_index += str.Length; | |
} | |
public void WriteLine(ReadOnlySpan<char> str) | |
{ | |
Write(str); | |
Write(Environment.NewLine); | |
} | |
public void Write(char c) | |
{ | |
_buffer[_index++] = c; | |
} | |
public void Write(int value) | |
{ | |
if (!value.TryFormat(_buffer.Slice(_index), out var charsWritten)) | |
{ | |
throw new OutOfMemoryException("buffer のサイズが足りません"); | |
} | |
_index += charsWritten; | |
} | |
public Span<char> AsSpan() => _buffer.Slice(0, _index); | |
public override string ToString() => AsSpan().ToString(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace IMC.Util | |
{ | |
public static class StringMutator | |
{ | |
public static string SnakeCaseToPascalCase(this string snake) | |
{ | |
ReadOnlySpan<char> snakeSpan = snake; | |
Span<char> buffer = stackalloc char[snakeSpan.Length]; | |
int bufferPos = 0; | |
bool toUpper = true; | |
for (var i = 0; i < snake.Length; i++) | |
{ | |
var target = snakeSpan[i]; | |
if (target == '_') | |
{ | |
toUpper = true; | |
} | |
else | |
{ | |
buffer[bufferPos++] = toUpper ? char.ToUpper(target) : target; | |
toUpper = false; | |
} | |
} | |
return buffer.Slice(0, bufferPos).ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment