オフィスアワーがそろそろ始まるよ!()

unicode

std.unicode は UTF-8 と UTF-16LE の間で文字のエンコード変換操作を提供するモジュールです。

構造体

Utf8View

Utf8ViewはUTF-8文字列を保持し、コードポイントのイテレータ Utf8Iterator を生成する構造体です。

Utf8Viewinit関数で初期化します。 init関数は渡されたUTF-8の文字列が正しいかどうかのチェックを行います。

examples/ch09-std/unicode/src/unicode.zen:12:19

const Utf8View = unicode.Utf8View;
test "Utf8View" {
    var view = try Utf8View.init("😁");
    var itr = view.iterator();

    equal(@is(u21, 0x1F601), itr.nextCodepoint());
    ok(itr.nextCodepoint() == null);
}

コンパイル時に文字列を評価できる場合は、initComptimeで初期化も可能です。文字列が不正な場合は、コンパイルに失敗します。

examples/ch09-std/unicode/src/unicode.zen:21:26

test "comptime Utf8View" {
    const view = Utf8View.initComptime("😁");
    var itr = view.iterator();
    equal(@is(u21, 0x1F601), itr.nextCodepoint());
    ok(itr.nextCodepoint() == null);
}

Utf16LeView

Utf16LeViewは UTF-16LEのu16スライスを保持し、コードポイントのイテレータ Utf16LeIterator を生成する構造体です。 また、UTF-16LE を OutStream に print する目的にも使用できます。

examples/ch09-std/unicode/src/unicode.zen:28:39

const Utf16LeView = unicode.Utf16LeView;
test "Utf16LeView" {
    const smile = [_]u16{ 0xD83D, 0xDE01 }; // 😁
    var view = try Utf16LeView.init(smile[0..]);
    var itr = view.iterator();

    equal(@is(u21, 0x1F601), itr.nextCodepoint());
    ok(itr.nextCodepoint() == null);

    var buffer: [4]u8 = undefined;
    equalStrings("😁", try fmt.bufPrint(buffer[0..], "{}", .{view}));
}

コンパイル時に文字列を評価できる場合は、 initComptime で初期化も可能です。文字列が不正な場合は、コンパイルに失敗します。

examples/ch09-std/unicode/src/unicode.zen:41:47

test "comptime Utf16LeView" {
    const smile = [_]u16{ 0xD83D, 0xDE01 }; // 😁
    const view = Utf16LeView.initComptime(smile[0..]);
    var itr = view.iterator();
    equal(@is(u21, 0x1F601), itr.nextCodepoint());
    ok(itr.nextCodepoint() == null);
}

関数

UTF-8 → UTF-16LE 変換関数

UTF-8 文字列を UTF-16LE に変換する関数名は utf8ToUtf16Le から始まります。Zがつく関数は、Null終端スライスを返します。

  • utf8ToUtf16Le(utf8: []u8, buffer: []mut u16): Utf8ToUtf16LeError![]mut u16: bufferにutf8をUTF-16LEに変換した結果を格納し、格納範囲のスライスを返します。
  • utf8ToUtf16LeZ(utf8: []u8, buffer: []mut u16): Utf8ToUtf16LeError![:0]mut u16: bufferにutf8をUTF-16LEに変換した結果を格納し、格納範囲のNull終端スライスを返します。
  • utf8ToUtf16LeAlloc(allocator: heap.Allocator, utf8: []u8): Utf8ToUtf16LeError![]mut u16: utf8を UTF-16LEに変換したスライスを返します。戻り値のスライスは必ず heap.free してください。
  • utf8ToUtf16LeZAlloc(allocator: heap.Allocator, utf8: []u8): Utf8ToUtf16LeError![:0]mut u16: utf8を UTF-16LEに変換したNull終端スライスを返します。戻り値のスライスは必ず heap.free してください。
  • utf8ToUtf16LeLength(utf8: []u8) InvalidUtf8Error!usize: utf8 を UTF-16LE に変換した際に必要な u16 のスライス長さを返します。
  • utf8ToUtf16LeStringLiteral(comptime utf8: []u8): UTF-16LE文字列の 配列ポインタを返します。

UTF-8 から UTF-16LE へ変換するサンプルコードを示します。

examples/ch09-std/unicode/src/unicode.zen:49:70

test "utf8ToUtf16Le" {
    var buf = [3]u16{ 0, 0, 1 };
    const smile = try unicode.utf8ToUtf16Le("😁", buf[0..]);
    equalSlices(u16, &[_]u16{ 0xD83D, 0xDE01 }, smile);
    equal(@to(u16, 1), buf[2]);

    const smileZ = try unicode.utf8ToUtf16LeZ("😄", buf[0..]);
    equalSlices(u16, &[_]u16{ 0xD83D, 0xDE04 }, smileZ);
    equal(@to(u16, 0), buf[2]);
}

test "utf8ToUtf16LeAlloc" {
    const allocator = testing.allocator;
    const smile = try unicode.utf8ToUtf16LeAlloc(allocator, "😁");
    defer heap.free(allocator, smile);
    equalSlices(u16, &[_]u16{ 0xD83D, 0xDE01 }, smile);

    const smileZ = try unicode.utf8ToUtf16LeZAlloc(allocator, "😄");
    defer heap.free(allocator, smileZ);
    equalSlices(u16, &[_]u16{ 0xD83D, 0xDE04 }, smileZ);
    equal([:0]mut u16, @TypeOf(smileZ));
}

定数の UTF-16LE 文字列は utf8ToUtf16LeStringLiteral で保持できます。 この関数は、C言語のワイド文字列リテラル L"" と似た効果を持ちます。 例えば、この関数は"😁" ならば*[2:0]u16 を返します。

examples/ch09-std/unicode/src/unicode.zen:72:78

test "utf8ToUtf16LeStringLiteral" {
    const L = unicode.utf8ToUtf16LeStringLiteral;
    const smile = L("😁");

    equal(*[2:0]u16, @TypeOf(smile));
    equalSlices(u16, &[_]u16{ 0xD83D, 0xDE01 }, smile);
}

UTF-16LE → UTF-8 変換関数

UTF-16LE を UTF-8 文字列に変換する関数名は utf16leToUtf8 から始まります。Zがつく関数は、Null終端スライスを返します。

  • utf16leToUtf8(utf16: []u16, buffer: []mut u8): Utf16LeToUtf8Error![]mut u16: bufferにutf16をUTF-8に変換した結果を格納し、格納範囲のスライスを返します。
  • utf16leToUtf8Z(utf16: []u16, buffer: []mut u8): Utf16LeToUtf8LeError![:0]mut u16: bufferにutf16をUTF-8に変換した結果を格納し、格納範囲のNull終端スライスを返します。
  • utf16leToUtf8Alloc(allocator: heap.Allocator, utf16: []u16): Utf16LeToUtf8Error![]mut u16: utf16を UTF-8に変換したスライスを返します。戻り値のスライスは必ず heap.free してください。
  • utf16leToUtf8ZAlloc(allocator: heap.Allocator, utf16: []u16): Utf16LeToUtf8Error![:0]mut u16: utf16を UTF-8に変換したNull終端スライスを返します。戻り値のスライスは必ず heap.free してください。
  • utf16leToUtf8Length(utf16: []u16) InvalidUtf16LeError!usize: utf16 を UTF-8 に変換した際に必要な u16 のスライス長さを返します。

UTF-16LE から UTF-8 の文字列に変換するサンプルコードを以下に示します。

examples/ch09-std/unicode/src/unicode.zen:80:93

test "utf16leToUtf8" {
    const L = unicode.utf8ToUtf16LeStringLiteral;
    const smile1_16le = L("😁");
    const smile2_16le = L("😄");

    var buf = [_]u8{ 0, 0, 0, 0, 1 };
    const smile = try unicode.utf16leToUtf8(smile1_16le, buf[0..]);
    equalStrings("😁", smile);
    equal(@to(u8, 1), buf[smile.len]);

    const smileZ = try unicode.utf16leToUtf8Z(smile2_16le, buf[0..]);
    equalStrings("😄", smileZ);
    equal(@to(u8, 0), buf[smileZ.len]);
}

エンコード デコード関数

コードポイントを扱う場合や、変換処理のエラーを細かく制御したい場合は、以下に示すエンコード デコード関数を使用できます。

  • utf8Encode(c: u21, out: []mut u8) EncodeError!u3: コードポイントを UTF-8 に変換し、 out に結果を格納します。格納した長さを返します。
  • utf8Decode(bytes: []u8) Utf8DecodeError!u21 : UTF-8 エンコードされた 1 文字をコードポイントに変換します。 1 文字のバイト数が分かっている場合は、 utf8Decode2utf8Decode3utf8Decode4を直接使用しても良いです。
  • utf8CodepointSequenceLength(c: u21) CodepointTooLargeError!u3 : コードポイントを UTF-8 文字に変換した場合のバイト数を返します。 utf8Encode が返す長さと同じです。
  • utf8ByteSequenceLength(first_byte: u8) Utf8InvalidStartError!u3: UTF-8 の 1 文字を表すのに何バイト必要か、最初のバイトデータから計算します。 utf8Decode がデコードに利用するバイト数と同じです。
  • utf16leEncode(c: u21, out: []mut u16) EncodeError!u2: コードポイントを UTF-16LE に変換し、 out に結果を格納します。格納した長さを返します。
  • utf16leByteEncode(c: u21, out: []mut u8) EncodeError!u3: コードポイントを UTF-16LE に変換し、 out に結果を格納します。格納した長さを返します。
  • utf16leDecode(bytes: []u16) Utf16LeDecodeError!u21 : UTF-16LE エンコードされた 1 文字をコードポイントに変換します。
  • utf16leByteDecode(bytes: []u8) Utf16LeDecodeError!u21 : UTF-16LE エンコードされた 1 文字をコードポイントに変換します。
  • utf16leCodepointSequenceLength(c: u21) CodepointTooLargeError!u2 : コードポイントを UTF-16LE 文字に変換した場合の u16 スライスの長さを返します。 utf16leEncode が返す長さと同じです。
  • utf16leByteCodepointByteSequenceLength(c: u21) CodepointTooLargeError!u3 : コードポイントを UTF-16LE 文字に変換した場合のバイト数を返します。 utf16leByteEncode が返す長さと同じです。
  • utf16leSequenceLength(first_byte: u16) Utf16LeInvalidStartError!u2: UTF-16LE の 1 文字を表すのに必要な u16スライスの長さを、最初のデータから計算します。
  • utf16leByteSequenceLength(first_byte: *[2]u8) Utf16LeInvalidStartError!u3: UTF-16LE の 1 文字を表すのに何バイト必要か、最初のデータから計算します。

Chapter 1

Chapter 2

Chapter 3

Chapter 4

Chapter 5

Chapter 6

Chapter 7

Chapter 8

Chapter 9

Chapter 10

Chapter 11

Chapter 12

Chapter 13

Chapter 14

Chapter 15

Appendix

Error Explanation

☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2020 connectFree Corporation. All rights reserved. | 特定商取引法に基づく表示
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.