##
7.3.3 Buffer Objects

C で実装された Python オブジェクトは、``バッファインタフェース (buffer interface)'' と呼ばれる一連の 関数を公開していることがあります。これらの関数は、あるオブジェクトの データを生 (raw) のバイト列形式で公開するために使います。 このオブジェクトの使い手は、バッファインタフェースを使うことで、 オブジェクトをあらかじめコピーしておく必要なしに、オブジェクトの データに直接アクセスできます。

バッファインタフェースをサポートするオブジェクトの例として、 文字列型とアレイ (array) 型の二つがあります。文字列オブジェクトは、 その内容をバッファインタフェースのバイト単位形式で公開して います。アレイもその内容を公開していますが、注意する必要が あるのはアレイの要素は複数バイトの値になりうる、ということです。

バッファインタフェースの使い手の一例として、ファイルオブジェクトの `write()` メソッドがあります。バッファインタフェースを 介してバイト列を公開しているオブジェクトは全て、ファイルへの書き出し ができます。オブジェクトのバッファインタフェースを操作し、 対象となるオブジェクトからデータを返させる `PyArg_ParseTuple()` には数多くのデータ書式化コードが あります。

バッファインタフェースに関するより詳しい情報は、 ``バッファオブジェクト構造体'' 節 ( 10.7 節) の、 `PyBufferProcs` の説明のところに あります。

``バッファオブジェクト'' はヘッダファイル bufferobject.h の中で定義されています (このファイルは Python.h がインクルード しています)。 バッファオブジェクトは、 Python プログラミングの レベルからは文字列オブジェクトと非常によく似ているように見えます: スライス、インデクス指定、結合、その他標準の文字列操作をサポート しています。しかし、バッファオブジェクトのデータは二つのデータソース: 何らかのメモリブロックか、バッファインタフェースを公開している 別のオブジェクト、のいずれかに由来しています。

バッファオブジェクトは、他のオブジェクトのバッファインタフェースから Python プログラマにデータを公開する方法として便利です。 バッファオブジェクトはゼロコピーなスライス機構 (zero-copy slicing mechanism) としても使われます。ブロックメモリを参照するという バッファオブジェクトの機能を使うことで、任意のデータをきわめて簡単に Python プログラマに公開できます。メモリブロックは巨大でも かまいませんし、C 拡張モジュール内の定数配列でもかまいません。 また、オペレーティングシステムライブラリ側に渡す前の、 操作用の生のブロックメモリでもかまいませんし、 構造化されたデータをネイティブのメモリ配置形式でやりとりするため にも使えます。

`PyBufferObject`
  この `PyObject` のサブタイプはバッファオブジェクトを表現します。

PyTypeObject `PyBuffer_Type`
  Python バッファ型 (buffer type) を表現する`PyTypeObject` です; Python レイヤにおける `types.BufferType` と同じオブジェクト です 。

int `Py_END_OF_BUFFER`
  この定数は、`PyBuffer_FromObject()` または の `PyBuffer_FromReadWriteObject()` size パラメタに 渡します。 このパラメタを渡すと、`PyBufferObject` は指定された offset からバッファの終わりまでを base オブジェクトとして参照します。 このパラメタを使うことで、関数の呼び出し側が base オブジェクト のサイズを調べる必要がなくなります。

int `PyBuffer_Check`( | PyObject *p)

  引数が`PyBuffer_Type` 型のときに真を返します。

PyObject* `PyBuffer_FromObject`( | PyObject *base, int offset, int size)

  戻り値: 新たな参照.
  新たな読み出し専用バッファオブジェクトを返します。base が 読み出し専用バッファに必要なバッファプロトコルをサポートしていない 場合や、厳密に一つのバッファセグメントを提供していない場合には `TypeError` を送出し、offset がゼロ以下の場合には `ValueError` を送出します。 バッファオブジェクトはは base オブジェクトに対する参照を保持し、 バッファオブジェクトのの内容は base オブジェクトの offset から size バイトのバッファインタフェースへの参照になります。 size が `Py_END_OF_BUFFER` の場合、新たに作成する バッファオブジェクトの内容は base から公開されているバッファの 末尾までにわたります。

PyObject* `PyBuffer_FromReadWriteObject`( | PyObject *base, int offset, int size)

  戻り値: 新たな参照.
  新たな書き込み可能バッファオブジェクトを返します。パラメタおよび例外 は `PyBuffer_FromObject` と同じです。base オブジェクト が書き込み可能バッファに必要なバッファプロトコルを公開していない 場合、`TypeError` を送出します。

PyObject* `PyBuffer_FromMemory`( | void *ptr, int size)

  戻り値: 新たな参照.
  メモリ上の指定された場所から指定されたサイズのデータを読み出せる、 新たな読み出し専用バッファオブジェクトを返します。 この関数が返すバッファオブジェクトが存続する間、ptr で与え られたメモリバッファがデアロケートされないようにするのは呼び出し側の 責任です。size がゼロ以下の場合には`ValueError` を 送出します。size には `Py_END_OF_BUFFER` を指定しては なりません; 指定すると、`ValueError` を送出します。

PyObject* `PyBuffer_FromReadWriteMemory`( | void *ptr, int size)

  戻り値: 新たな参照.
  `PyBuffer_FromMemory()` に似ていますが、書き込み可能な バッファを返します。

PyObject* `PyBuffer_New`( | int size)

  戻り値: 新たな参照.
  size バイトのメモリバッファを独自に維持する新たな書き込み可能 バッファオブジェクトを返します。 size がゼロまたは正の値でない場合、`ValueError` を 送出します。