buffer オブジェクトと memoryview オブジェクト
*********************************************

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

バッファインタフェースをサポートするオブジェクトの例として、文字列型と
アレイ (array) 型の二つがあります。文字列オブジェクトは、その内容をバ
ッファインタフェースのバイト指向の形式で公開しています。アレイはその内
容を旧スタイルバッファインターフェイス経由でしか公開できません。この制
限は "memoryview" オブジェクトをアレイから構築出来る Python 3 には適用
されません。アレイの要素は複数バイトの値になりえます。

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

バージョン 1.6 から、Python は Python レベルのバッファオブジェクトと、
C 言語レベルのバッファ API を提供しており、任意のビルトイン型やユーザ
ー定義型はその文字列表現を公開することができます。しかし、両方共、幾つ
かの欠点のために廃止予定扱いされていて、 Python 3 では公式に削除され、
新しい C 言語レベルのバッファ API と新しい Python レベルの
"memoryview" という名前のオブジェクトに置き換えられています。

新しいバッファ API は Python 2.6 に逆移植されており、 "memoryviews" オ
ブジェクトは Python 2.7 に逆移植されています。古いバージョンとの互換性
が必要なければ、古いAPIの代わりにこれらを使うことをおすすめします。


新スタイル Py_buffer 構造体
===========================

Py_buffer

   void *buf

      オブジェクトのメモリの開始位置へのポインタ

   Py_ssize_t len

      メモリのトータルサイズ [byte]

   int readonly

      バッファが読み込み専用かどうかを示す

   const char *format

      バッファを通してアクセスできる要素の形式を指定する、 "struct" モ
      ジュールスタイル文法の、 *NULL* 終端文字列。このポインタの値が
      *NULL* なら、 ""B"" (符号無しバイト) として扱われます。

   int ndim

      メモリが多次元配列を表している時の次元数。 "0" の場合、
      "strides" と "suboffsets" は *NULL* でなければなりません。

   Py_ssize_t *shape

      メモリが多次元配列を表しているとき、その形を示す長さ "ndim" の
      "Py_ssize_t" の配列。 "((*shape)[0] * ... *
      (*shape)[ndims-1])*itemsize" は "len" と等しくなければならないこ
      とに気をつけてください。

   Py_ssize_t *strides

      各次元で次の要素を得るためにスキップするバイト数を示す、長さ
      "ndim" の "Py_ssize_t" の配列。

   Py_ssize_t *suboffsets

      長さ "ndim" の "Py_ssize_t" の配列。 suboffset の各数値が 0 以上
      であるとき、その次元に格納されているのはポインタで、 suboffset
      の値はそのポインタの参照を解決するときに何バイトのオフセットを足
      すかを示しています。 suboffset に負の数が格納されているときは、
      参照解決が不要であること (連続したメモリブロック内に直接配置され
      ていること)を意味しています。

      全ての suboffset が負数の場合 (つまり参照解決が不要) な場合、こ
      のフィールドは NULL (デフォルト値) でなければなりません。

      次の例は、 strides も suboffsets も NULL でない場合の、N 次元イ
      ンデックスによって指されている N 次元配列内の要素へのポインタを
      返す関数です。

         void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
             Py_ssize_t *suboffsets, Py_ssize_t *indices) {
             char *pointer = (char*)buf;
             int i;
             for (i = 0; i < ndim; i++) {
                 pointer += strides[i] * indices[i];
                 if (suboffsets[i] >=0 ) {
                     pointer = *((char**)pointer) + suboffsets[i];
                 }
             }
             return (void*)pointer;
          }

   Py_ssize_t itemsize

      これは共有メモリ上の各要素のbyte単位のサイズを格納する変数です。
      これは "PyBuffer_SizeFromFormat()" を使って計算できる値なので技
      術的には不要なのですが、バッファを提供する側はフォーマット文字列
      を解析しなくてもこの情報を知っているでしょうし、バッファを受け取
      る側にとっては正しく解釈するのに必要な情報です。なので、要素サイ
      ズを格納するほうが便利ですし高速です。

   void *internal

      バッファを提供する側のオブジェクトが内部的に利用するための変数で
      す。例えば、提供側はこの変数に整数型をキャストして、 shape,
      strides, suboffsets といった配列をバッファを解放するときに同時に
      解放するべきかどうかを管理するフラグに使うことができるでしょう。
      バッファを受け取る側は、この値を変更してはなりません。


バッファ関連関数
================

int PyObject_CheckBuffer(PyObject *obj)

   *obj* がバッファインタフェースをサポートしている場合に "1" を、それ
   以外の場合に "0" を返します。

int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)

   *obj* を "Py_buffer" *view* へエクスポートします。これらの引数は
   *NULL* であってはなりません。 *flag* 引数は呼び出し側がどんなバッフ
   ァを扱おうとしているのか、バッファ提供側がどんなバッファを返すこと
   が許されているのかを示す、ビットフィールドです。バッファインタフェ
   ースは複雑なメモリ共有を可能にしていますが、呼び出し元はすべての複
   雑なバッファを扱えるとは限らず、バッファ提供側がシンプルなビューを
   提供できるならそれを利用したいとかもしれません。

   バッファ提供側はすべての方法でメモリを共有できるとは限らず、呼び出
   し側に何かが不可能であることを伝えるためにエラーを発生させる必要が
   あるかもしれません。その場合のエラーは、もしその問題を実際に引き起
   こしているのが別のエラーだったとしても、 "BufferError" でなければな
   りません。バッファ提供側は flag の情報を使って "Py_buffer" 構造体の
   どのフィールドへの非デフォルト値の設定を省略したり、要求されたシン
   プルな view を提供できない場合はエラーを発生させたりすることができ
   ます。

   成功したら "0" が、エラー時には "-1" が返されます。

   次のテーブルは、 *flags* 引数が取りうる値です。

   +---------------------------------+-----------------------------------------------------+
   | Flag                            | 説明                                                |
   +=================================+=====================================================+
   | "PyBUF_SIMPLE"                  | これはデフォルトの flag の状態です。結果のバッファ  |
   |                                 | は書き込み可能か もしれませんし、不可能かもしれませ |
   |                                 | ん。データのフォーマットは unsigned byte とします。 |
   |                                 | これは "スタンドアロン" のフラグ定数です。 他の定数 |
   |                                 | と '|' を取る必要はありません。提供側はこのような連 |
   |                                 | 続したバ イト列のバッファを提供できない場合に、エラ |
   |                                 | ーを発生させるかもしれま せん。                     |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_WRITABLE"                | 結果のバッファは書込み可能でなければなりません。書  |
   |                                 | き込み不可能な場 合はエラーを発生させます。         |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_STRIDES"                 | この値は "PyBUF_ND" を含みます。バッファは strides  |
   |                                 | 情報を提供しなけ ればなりません。 (言い換えると、   |
   |                                 | strides は NULL であってはいけませ ん。) このフラグ |
   |                                 | は、呼び出し元が、要素間に隙間のある不連続な配列を  |
   |                                 | 扱えるときに使われます。 strides を扱うことは、自動 |
   |                                 | 的に shape も扱 えることを要求されます。提供側は    |
   |                                 | stride 形式のバッファを提供できな いとき(例えば、   |
   |                                 | suboffset が必要な場合)はエラーを発生させます。     |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_ND"                      | バッファは shape 情報を提供しなければなりません。メ |
   |                                 | モリは C スタイ ルの並び (最後の次元が一番高速) だ  |
   |                                 | と仮定されます。提供側はこの種類 の連続バッファを提 |
   |                                 | 供できない場合はエラーを発生させます。このフラグ が |
   |                                 | 指定されていな場合は shape は *NULL* になります。   |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_C_CONTIGUOUS"            | これらのフラグは、返されるバッファの並びを指定しま  |
   | "PyBUF_F_CONTIGUOUS"            | す。それぞれ、C並 び(最後の次元が一番高速)、Fortran |
   | "PyBUF_ANY_CONTIGUOUS"          | 並び(最初の次元が一番高速), そのど ちらでも、を意味 |
   |                                 | します。これらのフラグは "PyBUF_STRIDES" を含んでお |
   |                                 | り、 strides 情報が正しく格納されていることを保証し |
   |                                 | ます。                                              |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_INDIRECT"                | このフラグは、返されるバッファが suboffsets 情報を  |
   |                                 | 含んでいることを 示します。(suboffsets が必要無いと |
   |                                 | きは NULL でもかまいません。) こ のフラグは、バッフ |
   |                                 | ァ利用側が suboffsets を使って参照されている間接 配 |
   |                                 | 列を扱えるときに利用されます。このフラグは          |
   |                                 | "PyBUF_STRIDES" を含み ます。                       |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_FORMAT"                  | 返されるバッファは正しい format 情報を持っていなけ  |
   |                                 | ればなりません。 このフラグは、バッファ利用側が実際 |
   |                                 | に格納されているデータの '種類' をチェックするとき  |
   |                                 | に利用します。バッファ提供側は、要求された場合は 常 |
   |                                 | にこの情報を提供できるべきです。 format が明示的に  |
   |                                 | 要求されていな い場合は format は *NULL* ("'B'",    |
   |                                 | unsigned byte を意味する)であるべ きです。          |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_STRIDED"                 | "(PyBUF_STRIDES | PyBUF_WRITABLE)" と同じ           |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_STRIDED_RO"              | "(PyBUF_STRIDES)" と同じ                            |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_RECORDS"                 | "(PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)"   |
   |                                 | と同じ                                              |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_RECORDS_RO"              | "(PyBUF_STRIDES | PyBUF_FORMAT)" と同じ             |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_FULL"                    | "(PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)"  |
   |                                 | と同じ                                              |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_FULL_RO"                 | "(PyBUF_INDIRECT | PyBUF_FORMAT)" と同じ            |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_CONTIG"                  | "(PyBUF_ND | PyBUF_WRITABLE)" と同じ                |
   +---------------------------------+-----------------------------------------------------+
   | "PyBUF_CONTIG_RO"               | "(PyBUF_ND)" と同じ                                 |
   +---------------------------------+-----------------------------------------------------+

void PyBuffer_Release(Py_buffer *view)

   *view* バッファを解放します。バッファが利用されなくなったときに、そ
   のメモリを解放できるようにこの関数を呼び出すべきです。

Py_ssize_t PyBuffer_SizeFromFormat(const char *)

   "itemsize" の値を "format" から計算して返します。

int PyBuffer_IsContiguous(Py_buffer *view, char fortran)

   *view* で定義されているメモリが、 C スタイル (*fortran* == "'C'")
   のときか、 Fortran スタイル (*fortran* == "'F'") のときか、そのいず
   れか (*fortran* == "'A'") であれば "1" を返します。それ以外の場合は
   "0" を返します。

void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char fortran)

   *strides* 配列を、 *itemsize* の大きさの要素がバイト単位で連続した
   、 *shape* の形をした (*fortran* が "'C'" なら C-style, "'F'" なら
   Fortran-style の) 多次元配列として埋める。

int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)

   バッファ提供側が与えられた長さの "unsigned bytes" の連続した1つのメ
   モリブロックしか提供できないものとして、 *view* バッファ情報構造体
   を正しく埋める。成功したら "0" を、エラー時には (例外を発生させつつ
   ) "-1" を返す。


memoryview オブジェクト
=======================

バージョン 2.7 で追加.

"memoryview" オブジェクトは、新しい、他のオブジェクトと同じように扱え
る Python オブジェクトの形をした C言語レベルのバッファへのインタフェー
スです。

PyObject *PyMemoryView_FromObject(PyObject *obj)

   新しいバッファインタフェースを定義しているオブジェクトから
   memoryview オブジェクトを作ります。

PyObject *PyMemoryView_FromBuffer(Py_buffer *view)

   buffer-info 構造体 *view* をラップする memoryview オブジェクトを作
   ります。作られた memoryview オブジェクトはバッファを所有することに
   なるので、 *view* を解放してはいけません。このバッファは memoryview
   オブジェクトが削除されるときに解放されます。

PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)

   buffer インタフェースを定義しているオブジェクトから ('C' か
   'F'ortran の *order* で) 連続したメモリチャンクへの memoryview オブ
   ジェクトを作ります。メモリが連続している場合、 memoryview オブジェ
   クトは元のメモリを参照します。それ以外の場合、メモリはコピーされて
   、 memoryview オブジェクトは新しい bytes オブジェクトを参照します。

int PyMemoryView_Check(PyObject *obj)

   *obj* が memoryview オブジェクトの場合に真を返します。現在のところ
   、 "memoryview" のサブクラスの作成は許可されていません。

Py_buffer *PyMemoryView_GET_BUFFER(PyObject *obj)

   与えられたオブジェクトにラップされた buffer-info 構造体へのポインタ
   を返します。オブジェクトは memoryview インスタンスで **なければなり
   ません** 。このマクロはオブジェクトの型をチェックしないので、呼び出
   し側で保証しなければクラッシュする可能性があります。


旧スタイルバッファオブジェクト
==============================

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

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

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

PyBufferObject

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

PyTypeObject PyBuffer_Type

   Python バッファ型 (buffer type) を表現する "PyTypeObject" です;
   Python レイヤにおける "buffer" や "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, Py_ssize_t offset, Py_ssize_t size)
    *Return value: New reference.*

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

   バージョン 2.5 で変更: この関数は以前は *offset*, *size* の型に
   "int" を利用していました。この変更により、 64bit システムを正しくサ
   ポートするには修正が必要になります。

PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
    *Return value: New reference.*

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

   バージョン 2.5 で変更: この関数は以前は *offset*, *size* の型に
   "int" を利用していました。この変更により、 64bit システムを正しくサ
   ポートするには修正が必要になります。

PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
    *Return value: New reference.*

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

   バージョン 2.5 で変更: この関数は以前は *size* の型に "int" を利用
   していました。この変更により、 64bit システムを正しくサポートするに
   は修正が必要になります。

PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
    *Return value: New reference.*

   "PyBuffer_FromMemory()" に似ていますが、書き込み可能なバッファを返
   します。

   バージョン 2.5 で変更: この関数は以前は *size* の型に "int" を利用
   していました。この変更により、 64bit システムを正しくサポートするに
   は修正が必要になります。

PyObject* PyBuffer_New(Py_ssize_t size)
    *Return value: New reference.*

   *size* バイトのメモリバッファを独自に維持する新たな書き込み可能バッ
   ファオブジェクトを返します。 *size* がゼロまたは正の値でない場合、
   "ValueError" を送出します。( "PyObject_AsWriteBuffer()" が返すよう
   な) メモリバッファは特に整列されていないので注意して下さい。

   バージョン 2.5 で変更: この関数は以前は *size* の型に "int" を利用
   していました。この変更により、 64bit システムを正しくサポートするに
   は修正が必要になります。
