"struct" --- バイト列をパックされたバイナリデータとして解釈する
***************************************************************

**ソースコード:** Lib/struct.py

======================================================================

このモジュールは、 Python の値と Python "bytes" オブジェクトとして表さ
れる C の構造体データとの間の変換を実現します。このモジュールは特に、
ファイルに保存されたり、ネットワーク接続を経由したバイナリデータを扱う
ときに使われます。このモジュールでは、C 構造体のレイアウトおよび
Python の値との間で行いたい変換をコンパクトに表現するために、 書式文字
列 を使います。

注釈:

  デフォルトでは、与えられた C の構造体をパックする際に、関連する C デ
  ータ型を適切にアラインメント(alignment)するために数バイトのパディン
  グを行うことがあります。この挙動が選択されたのは、パックされた構造体
  のバイト表現を対応する C 構造体のメモリレイアウトに正確に対応させる
  ためです。プラットフォーム独立のデータフォーマットを扱ったり、隠れた
  パディングを排除したりするには、サイズ及びアラインメントとして
  "native" の代わりに "standard" を使うようにします: 詳しくは バイトオ
  ーダ、サイズ、アラインメント を参照して下さい。

いくつかの "struct" の関数 (および "Struct" のメソッド) は *buffer* 引
数を取ります。 これは バッファプロトコル (buffer Protocol) を実装して
いて読み取り可能または読み書き可能なバッファを提供するオブジェクトのこ
とです。この目的のために使われる最も一般的な型は "bytes" と
"bytearray" ですが、バイトの配列とみなすことができるような他の多くの型
がバッファプロトコルを実装しています。そのため、それらは "bytes" オブ
ジェクトから追加のコピーなしで読み出しや書き込みができます。


関数と例外
==========

このモジュールは以下の例外と関数を定義しています:

exception struct.error

   様々な状況で送出される例外です。引数は何が問題なのかを記述する文字
   列です。

struct.pack(format, v1, v2, ...)

   フォーマット文字列 *format* に従い値 *v1*, *v2*, ...  をパックして
   、バイト列オブジェクトを返します。引数は指定したフォーマットが要求
   する型と正確に一致していなければなりません。

struct.pack_into(format, buffer, offset, v1, v2, ...)

   フォーマット文字列 *format* に従い値 *v1*, *v2*, ...  をパックして
   バイト列にし、書き込み可能な *buffer* のオフセット *offset* 位置よ
   り書き込みます。オフセットは省略出来ません。

struct.unpack(format, buffer)

   ("pack(format, ...)" でパックされたであろう) バッファ *buffer* を、
   書式文字列 *format* に従ってアンパックします。 値が一つしかない場合
   を含め、結果はタプルで返されます。 バッファのバイトサイズは、
   "calcsize()" の返り値である書式文字列が要求するサイズと一致しなけれ
   ばなりません。

struct.unpack_from(format, /, buffer, offset=0)

   バッファ *buffer* を、 *offset* の位置から書式文字列 *format* に従
   ってアンパックします。 値が一つしかない場合を含め、結果はタプルで返
   されます。 *offset* を始点とするバッファのバイトサイズは、少なくと
   も "calcsize()" の返り値である書式文字列が要求するサイズでなければ
   なりません。

struct.iter_unpack(format, buffer)

   Iteratively unpack from the buffer *buffer* according to the format
   string *format*.  This function returns an iterator which will read
   equally-sized chunks from the buffer until all its contents have
   been consumed.  The buffer's size in bytes must be a multiple of
   the size required by the format, as reflected by "calcsize()".

   イテレーション毎に書式文字列で指定されたタプルを yield します。

   バージョン 3.4 で追加.

struct.calcsize(format)

   書式文字列 *format* に従って、構造体 (それと "pack(format, ...)" に
   よって作成されるバイト列オブジェクト) のサイズを返します。


書式文字列
==========

書式文字列はデータをパックしたりアンパックしたりするときの期待されるレ
イアウトを指定するためのメカニズムです。文字列はパック/アンパックされ
るデータの型を指定する 書式指定文字 から組み立てられます。さらに、 バ
イトオーダ、サイズ、アラインメント を制御するための特殊文字もあります
。


バイトオーダ、サイズ、アラインメント
------------------------------------

デフォルトでは、C での型はマシンのネイティブ (native) の形式およびバイ
トオーダ (byte order) で表され、適切にアラインメント (alignment) する
ために、必要に応じて数バイトのパディングを行ってスキップします (これは
C コンパイラが用いるルールに従います)。

これに代わって、フォーマット文字列の最初の文字を使って、バイトオーダや
サイズ、アラインメントを指定することができます。指定できる文字を以下の
テーブルに示します:

+-------------+--------------------------+------------+-------------+
| 文字        | バイトオーダ             | サイズ     | アラインメ  |
|             |                          |            | ント        |
|=============|==========================|============|=============|
| "@"         | native                   | native     | native      |
+-------------+--------------------------+------------+-------------+
| "="         | native                   | standard   | none        |
+-------------+--------------------------+------------+-------------+
| "<"         | リトルエンディアン       | standard   | none        |
+-------------+--------------------------+------------+-------------+
| ">"         | ビッグエンディアン       | standard   | none        |
+-------------+--------------------------+------------+-------------+
| "!"         | ネットワーク (= ビッグエ | standard   | none        |
|             | ンディアン)              |            |             |
+-------------+--------------------------+------------+-------------+

フォーマット文字列の最初の文字が上のいずれかでない場合、"'@'" であると
みなされます。

ネイティブのバイトオーダはビッグエンディアンかリトルエンディアンで、ホ
スト計算機に依存します。例えば、Intel x86 および AMD64 (x86-64) はリト
ルエンディアンです。Motorola 68000 および PowerPC G5 はビッグエンディ
アンです。ARM および Intel Itanium はエンディアンを切り替えられる機能
を備えています (バイエンディアン)。使っているシステムでのエンディアン
は "sys.byteorder" を使って調べて下さい。

ネイティブのサイズおよびアラインメントは C コンパイラの "sizeof" 式で
決定されます。ネイティブのサイズおよびアラインメントはネイティブのバイ
トオーダと同時に使われます。

標準のサイズはフォーマット文字だけで決まります。 書式指定文字 の表を参
照して下さい。

"'@'" と "'='" の違いに注意してください: 両方ともネイティブのバイトオ
ーダですが、後者のバイトサイズとアラインメントは標準のものに合わせてあ
ります。

The form "'!'" represents the network byte order which is always big-
endian as defined in IETF RFC 1700.

バイトオーダに関して、「(強制的にバイトスワップを行う)ネイティブの逆」
を指定する方法はありません。"'<'" または "'>'" のうちふさわしい方を選
んでください。

注釈:

1. パディングは構造体のメンバの並びの中にだけ自動で追加されます。最初
   や最後にパディングが追加されることはありません。

2. ネイティブでないサイズおよびアラインメントが使われる場合にはパディ
   ングは行われません (たとえば '<', '>', '=', '!' を使った場合です)。

3. 特定の型によるアラインメント要求に従うように構造体の末端をそろえる
   には、繰り返し回数をゼロにした特定の型でフォーマットを終端します。
   使用例 を参照して下さい。


書式指定文字
------------

フォーマット文字 (format character) は以下の意味を持っています; C と
Python の間の変換では、値は正確に以下に指定された型でなくてはなりませ
ん: 「標準のサイズ」列は standard サイズ使用時にパックされた値が何バイ
トかを示します。つまり、フォーマット文字列が "'<'", "'>'", "'!'",
"'='" のいずれかで始まっている場合のものです。native サイズ使用時には
パックされた値の大きさはプラットフォーム依存です。

+----------+----------------------------+----------------------+------------------+--------------+
| フォーマ | C の型                     | Python の型          | 標準のサイズ     | 注釈         |
| ット     |                            |                      |                  |              |
|==========|============================|======================|==================|==============|
| "x"      | パディングバイト           | 値なし               |                  |              |
+----------+----------------------------+----------------------+------------------+--------------+
| "c"      | "char"                     | 長さ 1 のバイト列    | 1                |              |
+----------+----------------------------+----------------------+------------------+--------------+
| "b"      | "signed char"              | 整数                 | 1                | (1), (2)     |
+----------+----------------------------+----------------------+------------------+--------------+
| "B"      | "unsigned char"            | 整数                 | 1                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "?"      | "_Bool"                    | 真偽値型(bool)       | 1                | (1)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "h"      | "short"                    | 整数                 | 2                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "H"      | "unsigned short"           | 整数                 | 2                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "i"      | "int"                      | 整数                 | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "I"      | "unsigned int"             | 整数                 | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "l"      | "long"                     | 整数                 | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "L"      | "unsigned long"            | 整数                 | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "q"      | "long long"                | 整数                 | 8                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "Q"      | "unsigned long long"       | 整数                 | 8                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "n"      | "ssize_t"                  | 整数                 |                  | (3)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "N"      | "size_t"                   | 整数                 |                  | (3)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "e"      | (6)                        | 浮動小数点数         | 2                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "f"      | "float"                    | 浮動小数点数         | 4                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "d"      | "double"                   | 浮動小数点数         | 8                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "s"      | "char[]"                   | bytes                |                  |              |
+----------+----------------------------+----------------------+------------------+--------------+
| "p"      | "char[]"                   | bytes                |                  |              |
+----------+----------------------------+----------------------+------------------+--------------+
| "P"      | "void *"                   | 整数                 |                  | (5)          |
+----------+----------------------------+----------------------+------------------+--------------+

バージョン 3.3 で変更: "'n'" および "'N'" フォーマットのサポートが追加
されました。

バージョン 3.6 で変更: "'e'" フォーマットのサポートが追加されました。

注釈:

1. "'?'" 変換コードは C99 で定義された "_Bool" 型に対応します。その型
   が利用できない場合は、 "char" で代用されます。標準モードでは常に1バ
   イトで表現されます。

2. 非整数を整数の変換コードを使ってパックしようとすると、非整数が
   "__index__()" メソッドを持っていた場合は、整数に変換するためにパッ
   クする前にそのメソッドが呼ばれます。

   バージョン 3.2 で変更: Added use of the "__index__()" method for
   non-integers.

3. "'n'" および "'N'" 変換コードは (デフォルトもしくはバイトオーダ文字
   "'@'" 付きで選択される) native サイズ使用時のみ利用できます。
   standard サイズ使用時には、自身のアプリケーションに適する他の整数フ
   ォーマットを使うことができます。

4. "'f'" 、 "'d'" および "'e'" 変換コードについて、パックされた表現は
   IEEE 754 binary32 ("'f'" の場合) 、 binary64 ("'d'" の場合) 、また
   はbinary16("'e'" の場合) フォーマットが、プラットフォームにおける浮
   動小数点数のフォーマットに関係なく使われます。

5. "'P'" フォーマット文字はネイティブバイトオーダでのみ利用可能です (
   デフォルトのネットワークバイトオーダに設定するか、"'@'" バイトオー
   ダ指定文字を指定しなければなりません)。"'='" を指定した場合、ホスト
   計算機のバイトオーダに基づいてリトルエンディアンとビッグエンディア
   ンのどちらを使うかを決めます。struct モジュールはこの設定をネイティ
   ブのオーダ設定として解釈しないので、"'P'" を使うことはできません。

6. IEEE 754 の binary16 "半精度" 型は、 IEEE 754 standard の2008 年の
   改訂で導入されました。 半精度型は、符号 bit 、5 bit の指数部、 11
   bit の精度 (明示的には 10 bit が保存される) を持ち、おおよそ
   "6.1e-05" から "6.5e+04" までの数を完全な精度で表現できます。 この
   型は C コンパイラでは広くはサポートされていません: たいていのマシン
   では、保存するのに unsigned short が使えますが、数学の演算には使え
   ません。 詳しいことは Wikipedia の half-precision floating-point
   format のページを参照してください。

フォーマット文字の前に整数をつけ、繰り返し回数 (count) を指定すること
ができます。例えば、フォーマット文字列 "'4h'" は "'hhhh'" と全く同じ意
味です。

フォーマット文字間の空白文字は無視されます; count とフォーマット文字の
間にはスペースを入れてはいけません。

"'s'" フォーマット文字での繰り返し回数 (count) は、他のフォーマット文
字のような繰り返し回数ではなく、バイト長として解釈されます。例えば、
"'10s'" は単一の 10 バイトの文字列を意味し、"'10c'" は 10 個の文字を意
味します。繰り返し回数が指定されなかった場合は、デフォルト値の 1 とみ
なされます。パックでは、文字列はサイズに合うように切り詰められたり
null バイトで埋められたりします。アンパックでは、返されるバイトオブジ
ェクトのバイト数は、正確に指定した通りになります。特殊な場合として、
"'0s'" は単一の空文字列を意味し、"'0c'" は 0 個の文字を意味します。

整数フォーマット ("'b'", "'B'", "'h'", "'H'", "'i'", "'I'", "'l'",
"'L'", "'q'", "'Q'") のいずれかを使って値 "x" をパックするとき "x" が
フォーマットの適切な値の範囲に無い場合、 "struct.error" が送出されます
。

バージョン 3.1 で変更: 以前は、いくつかの整数フォーマットが適切な範囲
にない値を覆い隠して、 "struct.error" の代わりに "DeprecationWarning"
を送出していました。

フォーマット文字 "'p'" は "Pascal 文字列 (pascal string)"  をコードし
ます。Pascal 文字列は count で与えられる *固定長のバイト列* に収められ
た短い可変長の文字列です。このデータの先頭の 1 バイトには文字列の長さ
か255 のうち、小さい方の数が収められます。その後に文字列のバイトデータ
が続きます。 "pack()" に渡された Pascal 文字列の長さが長すぎた
(count-1 よりも長い) 場合、先頭の "count-1" バイトが書き込まれます。文
字列が "count-1" よりも短い場合、指定した count バイトに達するまでの残
りの部分はヌルで埋められます。 "unpack()" では、フォーマット文字 "'p'"
は指定された "count" バイトだけデータを読み込みますが、返される文字列
は決して 255 文字を超えることはないので注意してください。

"'?'" フォーマット文字では、返り値は "True" または "False" です。パッ
クするときには、引数オブジェクトの論理値としての値が使われます。 0 ま
たは 1 のネイティブや標準の真偽値表現でパックされ、アンパックされると
きはゼロでない値は "True" になります。


使用例
------

注釈:

  全ての例は、ビッグエンディアンのマシンで、ネイティブのバイトオーダ、
  サイズおよびアラインメントを仮定します。

基本的な例として、三つの整数をパック/アンパックします:

   >>> from struct import *
   >>> pack('hhl', 1, 2, 3)
   b'\x00\x01\x00\x02\x00\x00\x00\x03'
   >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
   (1, 2, 3)
   >>> calcsize('hhl')
   8

アンパックした結果のフィールドは、変数に割り当てるか named tuple でラ
ップすることによって名前を付けることができます:

   >>> record = b'raymond   \x32\x12\x08\x01\x08'
   >>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

   >>> from collections import namedtuple
   >>> Student = namedtuple('Student', 'name serialnum school gradelevel')
   >>> Student._make(unpack('<10sHHb', record))
   Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)

アラインメントの要求を満たすために必要なパディングが異なるという理由に
より、フォーマット文字の順番がサイズの違いを生み出すことがあります:

   >>> pack('ci', b'*', 0x12131415)
   b'*\x00\x00\x00\x12\x13\x14\x15'
   >>> pack('ic', 0x12131415, b'*')
   b'\x12\x13\x14\x15*'
   >>> calcsize('ci')
   8
   >>> calcsize('ic')
   5

以下のフォーマット "'llh0l'" は、long 型が 4 バイトを境界としてそろえ
られていると仮定して、末端に 2 バイトをパディングします:

   >>> pack('llh0l', 1, 2, 3)
   b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

この例はネイティブのサイズとアラインメントが使われているときだけ思った
通りに動きます。標準のサイズとアラインメントはアラインメントの設定では
いかなるアラインメントも行いません。

参考:

  "array" モジュール
     一様なデータ型からなるバイナリ記録データのパック。

  "xdrlib" モジュール
     XDR データのパックおよびアンパック。


クラス
======

"struct" モジュールは次の型を定義します:

class struct.Struct(format)

   フォーマット文字列 *format* に従ってバイナリデータを読み書きする、
   新しい Struct オブジェクトを返します。 Struct オブジェクトを一度作
   ってからそのメソッドを使うと、フォーマット文字列のコンパイルが一度
   で済むので、 "struct" モジュールの関数を同じフォーマットで何度も呼
   び出すよりも効率的です。

   注釈:

     The compiled versions of the most recent format strings passed to
     "Struct" and the module-level functions are cached, so programs
     that use only a few format strings needn't worry about reusing a
     single "Struct" instance.

   コンパイルされた Struct オブジェクトは以下のメソッドと属性をサポー
   トします:

   pack(v1, v2, ...)

      "pack()" 関数と同じ、コンパイルされたフォーマットを利用するメソ
      ッドです。 ("len(result)" は "size" と等しいでしょう)

   pack_into(buffer, offset, v1, v2, ...)

      "pack_into()" 関数と同じ、コンパイルされたフォーマットを利用する
      メソッドです。

   unpack(buffer)

      "unpack()" 関数と同じ、コンパイルされたフォーマットを利用するメ
      ソッドです。 (buffer のバイト数は "size" と等しくなければなりま
      せん)。

   unpack_from(buffer, offset=0)

      "unpack_from()" 関数と同じ、コンパイルされたフォーマットを利用す
      るメソッドです。 (*offset* を始点とする buffer のバイト数は少な
      くとも "size" 以上でなければなりません)。

   iter_unpack(buffer)

      "iter_unpack()" 関数と同じ、コンパイルされたフォーマットを利用す
      るメソッドです。 (buffer のバイト数は "size" の倍数でなければな
      りません)。

      バージョン 3.4 で追加.

   format

      この Struct オブジェクトを作成する時に利用されたフォーマット文字
      列です。

      バージョン 3.7 で変更: The format string type is now "str"
      instead of "bytes".

   size

      "format" 属性に対応する構造体の (従って "pack()" メソッドによっ
      て作成されるバイト列オブジェクトの) サイズです。
