バイトオブジェクト
******************

下記の関数は、バイトオブジェクトを期待している引数にバイトオブジェクト
でないパラメタを指定して呼び出されると、 "TypeError" を送出します。

"PyBytesObject" の内部バッファには、null 終端の C 文字列との互換性のた
め、末尾に常に追加の null バイトが含まれます。 この追加バイトは
"PyBytes_Size()" や、以下の関数の各種 *length* 引数と *size* 引数には
数えません。

type PyBytesObject

   この "PyObject" のサブタイプは、Python バイトオブジェクトを表します
   。

PyTypeObject PyBytes_Type
    * 次に属します: Stable ABI.*

   この "PyTypeObject" のインスタンスは、Python バイト型を表します;
   Pythonレイヤの "bytes" と同じオブジェクトです。

int PyBytes_Check(PyObject *o)

   オブジェクト *o* が bytes オブジェクトか bytes 型のサブタイプのイン
   スタンスである場合に真を返します。この関数は常に成功します。

int PyBytes_CheckExact(PyObject *o)

   オブジェクト *o* が bytes オブジェクトだが bytes 型のサブタイプのイ
   ンスタンスでない場合に真を返します。この関数は常に成功します。

PyObject *PyBytes_FromString(const char *v)
    *戻り値: 新しい参照。** 次に属します: Stable ABI.** Thread safety:
   Atomic.*

   成功時に、文字列 *v* のコピーを値とする新しいバイトオブジェクトを返
   し、失敗時に "NULL" を返します。 引数 *v* は "NULL" であってはなり
   ません; そのチェックは行われません。

PyObject *PyBytes_FromStringAndSize(const char *v, Py_ssize_t len)
    *戻り値: 新しい参照。** 次に属します: Stable ABI.** Thread safety:
   Atomic.*

   成功時に、文字列 *v* のコピーを値とする長さ *len* の新しいバイトオ
   ブジェクトを返し、失敗時に "NULL" を返します。 引数 *v* が "NULL"
   の場合、バイトオブジェクトの中身は初期化されていません。

   バージョン 3.15 で ソフト非推奨 <Soft deprecated>:
   "PyBytes_FromStringAndSize(NULL, len)" の代わりに "PyBytesWriter"
   API を使ってください。

PyObject *PyBytes_FromFormat(const char *format, ...)
    *戻り値: 新しい参照。** 次に属します: Stable ABI.** Thread safety:
   Atomic.*

   C 関数の "printf()" スタイルの *format* 文字列と可変長の引数を取り
   、結果のPython バイトオブジェクトのサイズを計算し、値を指定した書式
   にしたがって変換したバイトオブジェクトを返します。可変長の引数は C
   のデータ型でなければならず、 *format* 文字列中のフォーマット文字と
   厳密に関連付けられていなければなりません。下記のフォーマット文字が
   使用できます:

   +---------------------+-----------------+----------------------------------+
   | 書式指定文字        | 型              | 備考                             |
   |=====================|=================|==================================|
   | "%%"                | *n/a*           | リテラルの % 文字                |
   +---------------------+-----------------+----------------------------------+
   | "%c"                | int             | C の整数型で表現される単一のバイ |
   |                     |                 | ト。                             |
   +---------------------+-----------------+----------------------------------+
   | "%d"                | int             | "printf("%d")" と同等。 [1]      |
   +---------------------+-----------------+----------------------------------+
   | "%u"                | unsigned int    | "printf("%u")" と同等。 [1]      |
   +---------------------+-----------------+----------------------------------+
   | "%ld"               | long            | "printf("%ld")" と同等。 [1]     |
   +---------------------+-----------------+----------------------------------+
   | "%lu"               | unsigned long   | "printf("%lu")" と同等。 [1]     |
   +---------------------+-----------------+----------------------------------+
   | "%zd"               | "Py_ssize_t"    | "printf("%zd")" と同等。 [1]     |
   +---------------------+-----------------+----------------------------------+
   | "%zu"               | size_t          | "printf("%zu")" と同等。 [1]     |
   +---------------------+-----------------+----------------------------------+
   | "%i"                | int             | "printf("%i")" と同等。 [1]      |
   +---------------------+-----------------+----------------------------------+
   | "%x"                | int             | "printf("%x")" と同等。 [1]      |
   +---------------------+-----------------+----------------------------------+
   | "%s"                | const char*     | null で終端された C の文字列。   |
   +---------------------+-----------------+----------------------------------+
   | "%p"                | const void*     | C ポインタの 16 進表記。         |
   |                     |                 | "printf("%p")" とほとんど同じで  |
   |                     |                 | すが、プラッ トフォームにおける  |
   |                     |                 | "printf" の定義に関わりなく先頭  |
   |                     |                 | にリテラル "0x" が付きます。     |
   +---------------------+-----------------+----------------------------------+

   識別できない書式指定文字があった場合、残りの書式文字列はそのまま結
   果のオブジェクトにコピーされ、残りの引数は無視されます。

   [1] 整数指定子 (d, u, ld, lu, zd, zu, i, x): 精度が与えられていても
       、0指定子は有効です。

PyObject *PyBytes_FromFormatV(const char *format, va_list vargs)
    *戻り値: 新しい参照。** 次に属します: Stable ABI.** Thread safety:
   Atomic.*

   ちょうど２つの引数を取ることを除いて、 "PyBytes_FromFormat()" と同
   じです。

PyObject *PyBytes_FromObject(PyObject *o)
    *戻り値: 新しい参照。** 次に属します: Stable ABI.** Thread safety:
   Safe for concurrent use on the same object.*

   バッファプロトコルを実装するオブジェクト *o* のバイト表現を返します
   。

   注釈:

     オブジェクトがバッファプロトコルを実装している場合、bytes オブジ
     ェクトの作成中にそのバッファを変更してはいけません。

Py_ssize_t PyBytes_Size(PyObject *o)
    * 次に属します: Stable ABI.** Thread safety: Atomic.*

   バイトオブジェクト *o* のバイト単位の長さを返します。

Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
    * Thread safety: Atomic.*

   "PyBytes_Size()" に似ていますが、エラーチェックを行いません。

char *PyBytes_AsString(PyObject *o)
    * 次に属します: Stable ABI.** Thread safety: Safe to call from
   multiple threads with external synchronization only.*

   *o* の内容へのポインタを返します。 このポインタは "len(o) + 1" バイ
   トからなる *o* の内部バッファを参照します。 内部に他の null バイト
   があるかどうかにかかわらず、バッファの最後のバイトは常に null です
   。 "PyBytes_FromStringAndSize(NULL, size)" で作成したばかりのオブジ
   ェクトでない限り、データを変更してはいけません。 このバッファを解放
   してはいけません。 *o* が bytes オブジェクトでなければ、
   "PyBytes_AsString()" は "NULL" を返し、"TypeError" を送出します。

char *PyBytes_AS_STRING(PyObject *string)
    * Thread safety: Safe to call from multiple threads with external
   synchronization only.*

   "PyBytes_AsString()" に似ていますが、エラーチェックを行いません。

int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
    * 次に属します: Stable ABI.** Thread safety: Safe to call from
   multiple threads with external synchronization only.*

   出力変数 *buffer* と *length* を通じて、オブジェクト *obj* の null
   終端された内容を返します。 成功すると "0" を返します。

   *length* が "NULL" の場合、bytes オブジェクトの内部に null バイトが
   含まれていてはいけません。 含まれている場合は "-1" を返し、
   "ValueError" を送出します。

   "buffer" は *obj* の内部バッファを参照します。 このバッファには末尾
   に追加の null バイトが含まれます (*length* には数えません)。
   "PyBytes_FromStringAndSize(NULL, size)" で作成したばかりのオブジェ
   クトでない限り、データを変更してはいけません。 このバッファを解放し
   てはいけません。 *obj* が bytes オブジェクトでなければ、
   "PyBytes_AsStringAndSize()" は "-1" を返し、"TypeError" を送出しま
   す。

   バージョン 3.5 で変更: 以前は bytes オブジェクトにヌルバイトが埋め
   込まれていたときに "TypeError" を送出していました。

void PyBytes_Concat(PyObject **bytes, PyObject *newpart)
    * 次に属します: Stable ABI.** Thread safety: Safe for concurrent
   use on the same object.*

   *bytes* の内容に *newpart* の内容を追加した新しい bytes オブジェク
   トを **bytes* に作成します。 呼び出し側はこの新しい参照を所有します
   。 *bytes* の元の値への参照は「*盗まれます*」。 新しいオブジェクト
   を作成できない場合も、*bytes* の元の参照は「盗まれ」、**bytes* の値
   は "NULL" に設定され、適切な例外が設定されます。

   注釈:

     *newpart* がバッファプロトコルを実装している場合、新しい bytes オ
     ブジェクトの作成中にそのバッファを変更してはいけません。

void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
    * 次に属します: Stable ABI.** Thread safety: Safe for concurrent
   use on the same object.*

   *bytes* の内容に *newpart* の内容を追加した新しい bytes オブジェク
   トを **bytes* に作成します。 この関数は *newpart* への *強参照* を
   解放します (つまり参照カウントを減らします)。

   注釈:

     *newpart* がバッファプロトコルを実装している場合、新しい bytes オ
     ブジェクトの作成中にそのバッファを変更してはいけません。

PyObject *PyBytes_Join(PyObject *sep, PyObject *iterable)
    * Thread safety: Safe for concurrent use on the same object.*

   Python の "sep.join(iterable)" と同様です。

   *sep* は Python の "bytes" オブジェクトでなければなりません。
   ("PyUnicode_Join()" は区切り文字として "NULL" を受け取り、空白とし
   て扱いますが、"PyBytes_Join()" は区切り文字に "NULL" を受け付けませ
   ん。)

   *iterable* は バッファプロトコル を実装するオブジェクトを生成するイ
   テラブルオブジェクトでなければなりません。

   成功すると新しい "bytes" オブジェクトを返します。 エラー時には例外
   を設定して "NULL" を返します。

   Added in version 3.14.

   注釈:

     *iterable* のオブジェクトがバッファプロトコルを実装している場合、
     新しい bytes オブジェクトの作成中にそれらのバッファを変更してはい
     けません。

int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
    * Thread safety: Safe to call without external synchronization on
   distinct objects.*

   bytes オブジェクトのサイズを変更します。 *newsize* が bytes オブジ
   ェクトの新しい長さになります。 新しい bytes オブジェクトを作成して
   古いものを破棄する操作を、より効率よく行うものと考えることができま
   す。 既存の bytes オブジェクトのアドレスを左辺値 (書き込みが行われ
   る可能性があります) として渡し、希望する新しいサイズを指定します。
   成功すると **bytes* はサイズ変更後の bytes オブジェクトを保持し、
   "0" を返します。 **bytes* のアドレスは入力時の値と異なる場合があり
   ます。 再割り当てに失敗すると、**bytes* の元の bytes オブジェクトを
   解放し、**bytes* に "NULL" を設定し、"MemoryError" を設定して "-1"
   を返します。

   バージョン 3.15 で ソフト非推奨 <Soft deprecated>: 代わりに
   "PyBytesWriter" API を使ってください。

PyObject *PyBytes_Repr(PyObject *bytes, int smartquotes)
    * 次に属します: Stable ABI.** Thread safety: Atomic.*

   *bytes* の文字列表現を取得します。 現在、この関数は Python の
   "bytes.__repr__()" の実装に使われています。

   この関数は型チェックを行いません。 *bytes* に bytes オブジェクト以
   外のオブジェクトや "NULL" を渡すと、動作は未定義です。

   *smartquotes* が真の場合、*bytes* にシングルクォートが含まれていれ
   ば、その表現にはシングルクォートの代わりにダブルクォートで囲んだ文
   字列を使います。 例えば、バイト文字列 "'Python'" の表現は、
   *smartquotes* が真なら "b"'Python'""、偽なら "b'\'Python\''" となり
   ます。

   成功すると、この関数は表現を格納した "str" オブジェクトへの *強参照
   * を返します。 失敗すると例外を設定して "NULL" を返します。

PyObject *PyBytes_DecodeEscape(const char *s, Py_ssize_t len, const char *errors, Py_ssize_t unicode, const char *recode_encoding)
    * 次に属します: Stable ABI.** Thread safety: Atomic.*

   バックスラッシュでエスケープされた文字列 *s* のエスケープを解除しま
   す。 *s* は "NULL" であってはなりません。 *len* は *s* のサイズでな
   ければなりません。

   *errors* は ""strict""、""replace""、""ignore"" のいずれかでなけれ
   ばなりません。 *errors* が "NULL" の場合、デフォルトで ""strict""
   を使います。

   成功すると、この関数はエスケープを解除した文字列を格納する Python
   の "bytes" オブジェクトへの *強参照* を返します。 失敗すると例外を
   設定して "NULL" を返します。

   バージョン 3.9 で変更: *unicode* と *recode_encoding* は使われなく
   なりました。


PyBytesWriter
*************

"PyBytesWriter" API を使って Python の "bytes" オブジェクトを作成でき
ます。

Added in version 3.15.

type PyBytesWriter

   bytes ライターのインスタンスです。

   この API は **スレッドセーフではありません**。 複数のスレッドでライ
   ターを共有するには、クリティカルセクションまたはロックが必要です。

   成功時には "PyBytesWriter_Finish()"、エラー時には
   "PyBytesWriter_Discard()" でインスタンスを破棄しなければなりません
   。


作成、完了、破棄
================

PyBytesWriter *PyBytesWriter_Create(Py_ssize_t size)

   *size* バイトを書き込むための "PyBytesWriter" を作成します。

   *size* がゼロより大きければ *size* バイトを割り当て、ライターのサイ
   ズを *size* に設定します。 呼び出し側は "PyBytesWriter_GetData()"
   を使って *size* バイトを書き込む責任があります。 この関数は余分な領
   域を割り当てません。

   エラー時には例外を設定して "NULL" を返します。

   *size* は正の値またはゼロでなければなりません。

PyObject *PyBytesWriter_Finish(PyBytesWriter *writer)

   "PyBytesWriter_Create()" で作成した "PyBytesWriter" の処理を完了し
   ます。

   成功すると Python の "bytes" オブジェクトを返します。 エラー時には
   例外を設定して "NULL" を返します。

   呼び出し後は、成功したかどうかにかかわらずライターのインスタンスは
   無効になります。 "PyBytesWriter_Finish()" の後に、そのライターに対
   して API を呼び出すことはできません。

PyObject *PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)

   "PyBytesWriter_Finish()" と同様ですが、"bytes" オブジェクトを作成す
   る前にライターのサイズを *size* バイトに変更します。

PyObject *PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)

   "PyBytesWriter_Finish()" と同様ですが、"bytes" オブジェクトを作成す
   る前に *buf* ポインタを使ってライターのサイズを変更します。

   *buf* ポインタが内部バッファの範囲外であれば、例外を設定して "NULL"
   を返します。

   関数の疑似コードを示します。

      Py_ssize_t size = (char*)buf - (char*)PyBytesWriter_GetData(writer);
      return PyBytesWriter_FinishWithSize(writer, size);

void PyBytesWriter_Discard(PyBytesWriter *writer)

   "PyBytesWriter_Create()" で作成した "PyBytesWriter" を破棄します。

   *writer* が "NULL" の場合は何もしません。

   呼び出し後はライターのインスタンスは無効になります。
   "PyBytesWriter_Discard()" の後に、そのライターに対して API を呼び出
   すことはできません。


高レベルAPI
===========

int PyBytesWriter_WriteBytes(PyBytesWriter *writer, const void *bytes, Py_ssize_t size)

   *writer* の内部バッファを *size* バイト拡張し、*bytes* の *size* バ
   イトを *writer* の末尾に書き込み、*writer* のサイズに *size* を加え
   ます。

   *size* が "-1" の場合は "strlen(bytes)" を呼び出して文字列の長さを
   取得します。

   成功すると "0" を返します。 エラー時には例外を設定して "-1" を返し
   ます。

int PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)

   "PyBytes_FromFormat()" と同様ですが、出力をライターの末尾に直接書き
   込みます。 必要に応じてライターの内部バッファを拡張します。 その後
   、書き込んだサイズをライターのサイズに加えます。

   成功すると "0" を返します。 エラー時には例外を設定して "-1" を返し
   ます。


値の取得
========

Py_ssize_t PyBytesWriter_GetSize(PyBytesWriter *writer)

   ライターのサイズを取得します。

   この関数は "PyBytesWriter_GetData()" が返したポインタを無効にしませ
   ん。

   この関数は失敗しません。

void *PyBytesWriter_GetData(PyBytesWriter *writer)

   ライターのデータ、つまり内部バッファの先頭を取得します。

   このポインタは、*writer* に対して "PyBytesWriter_GetData()" と
   "PyBytesWriter_GetSize()" 以外の "PyBytesWriter" 関数を呼び出すまで
   有効です。

   この関数は失敗しません。


低レベルAPI
===========

int PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)

   ライターのサイズを *size* バイトに変更します。 ライターの拡張にも縮
   小にも使えます。 この関数は通常、サイズ変更を繰り返したときの償却性
   能をよくするため、余分な領域を割り当てます。

   新しく割り当てられたバイトは初期化されません。

   成功すると "0" を返します。 エラー時には例外を設定して "-1" を返し
   ます。

   *size* は正の値またはゼロでなければなりません。

int PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t grow)

   現在のライターのサイズに *grow* バイトを加えてサイズを変更します。
   この関数は通常、サイズ変更を繰り返したときの償却性能をよくするため
   、余分な領域を割り当てます。

   新しく割り当てられたバイトは初期化されません。

   成功すると "0" を返します。 エラー時には例外を設定して "-1" を返し
   ます。

   *grow* に負の値を指定するとライターを縮小できます。

void *PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size, void *buf)

   "PyBytesWriter_Grow()" と同様ですが、*buf* ポインタも更新します。

   内部バッファがメモリ上で移動した場合は、*buf* ポインタも移動します
   。 内部バッファ内での *buf* の相対位置は変わりません。

   エラー時には例外を設定して "NULL" を返します。

   *buf* は "NULL" であってはなりません。

   関数の疑似コードを示します。

      Py_ssize_t pos = (char*)buf - (char*)PyBytesWriter_GetData(writer);
      if (PyBytesWriter_Grow(writer, size) < 0) {
          return NULL;
      }
      return (char*)PyBytesWriter_GetData(writer) + pos;


文字列 "b'abc'" を作成する例
============================

3 バイトの固定サイズでバイト文字列 "b"abc"" を作成する例です。

   PyObject* create_abc(void)
   {
       PyBytesWriter *writer = PyBytesWriter_Create(3);
       if (writer == NULL) {
           return NULL;
       }

       char *str = PyBytesWriter_GetData(writer);
       memcpy(str, "abc", 3);
       return PyBytesWriter_Finish(writer);
   }

ポインタを使って最終的なサイズを計算する別の例です。

   PyObject* create_abc_ptr(void)
   {
       PyBytesWriter *writer = PyBytesWriter_Create(3);
       if (writer == NULL) {
           return NULL;
       }

       char *str = PyBytesWriter_GetData(writer);
       memcpy(str, "abc", 3);
       str += 3;
       return PyBytesWriter_FinishWithPointer(writer, str);
   }


"PyBytes_FromStringAndSize()" を使うコードの更新
================================================

ソフト非推奨の API "PyBytes_FromStringAndSize(NULL, size)" を使うコー
ドの例です。

   int copy_bytes(char *dest, const char *src, Py_ssize_t num_bytes)
   {
       ...
   }

   PyObject* create_string(const char *start, Py_ssize_t num_bytes)
   {
       PyObject *result = PyBytes_FromStringAndSize(NULL, num_bytes);
       if (result == NULL) {
           return NULL;
       }
       if (copy_bytes(PyBytes_AS_STRING(result), start, num_bytes) < 0) {
           Py_CLEAR(result);
       }
       return result;
   }

これを次のように更新できます。

   PyObject* create_string(const char *start, Py_ssize_t num_bytes)
   {
       PyBytesWriter *writer = PyBytesWriter_Create(num_bytes);
       if (writer == NULL) {
           return NULL;
       }
       if (copy_bytes(PyBytesWriter_GetData(writer), start, num_bytes) < 0) {
           PyBytesWriter_Discard(writer);
           return NULL;
       }
       return PyBytesWriter_Finish(writer);
   }


"_PyBytes_Resize()" を使うコードの更新
======================================

ソフト非推奨の API "_PyBytes_Resize()" を使うコードの例です。

   PyObject* create_string(Py_ssize_t size)
   {
       PyObject *bytes = PyBytes_FromStringAndSize(NULL, size);
       if (bytes == NULL) {
           return NULL;
       }
       char *str = PyBytes_AS_STRING(bytes);

       // ... write data into str ...

       if (_PyBytes_Resize(&bytes, (str - PyBytes_AS_STRING(bytes)))) {
           return NULL;
       }
       return bytes;
   }

これを次のように更新できます。

   PyObject* create_string(Py_ssize_t size)
   {
       PyBytesWriter *writer = PyBytesWriter_Create(size);
       if (writer == NULL) {
           return NULL;
       }
       char *str = PyBytesWriter_GetData(writer);

       // ... write data into str ...

       return PyBytesWriter_FinishWithPointer(writer, str);
   }
