2

MessagePackのCAPIを見ると、タイプに応じてデータを適切にシリアル化(パック)するための関数がいくつかあります:msgpack_pack_uint8、、msgpack_pack_int32...

APIには、データを解凍するための同等の呼び出しはないようです。 msgpack_unpack_nextを返しますmsgpack_object。これらのオブジェクトは、含まれている列挙型に基づいて、タイプの粗い粒度(タイプの最大のもの:int64、double、...)のみを持ちます。

ここで何かが足りませんか?粗いオブジェクトを使用してキャストすることを期待していますか?

開梱はどのように適切に行う必要がありますか?

さらに、優れたドキュメントや使用例はありますか?ウェブサイトにあるものは些細なものです。

4

1 に答える 1

10

アンパック時には、整数値は常にmsgpack_object固定幅の 64 ビット整数 (int64_t負の場合、負のuint64_t場合) として格納されます。

et al. の詳細については、をcpp/src/msgpack/object.h参照してください。また、 msgpack がアンパック ロジックを処理する方法を確認するには、次の例を参照してください。msgpack_objectcpp/src/msgpack/unpack.c

static inline int template_callback_int8(unpack_user* u,
                                         int8_t d,
                                         msgpack_object* o) {
    if(d >= 0) {
        o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d;
        return 0;
    }
    else {
        o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d;
        return 0;
    }
}

これは、pack 時に、msgpack がその値に従って整数をエンコードする最適な方法を動的に選択するためです。たとえば、msgpack_pack_uint16整数を pack する場合:

  • 値が [0, 127] の場合は 1 バイトで保存され、
  • 0xcc値が [128, 255] の場合は最初のバイトとして2 バイト
  • それ以外の場合は0xcd、最初のバイトとして3 バイト。

詳しくmsgpack_pack_real_uint16はからcpp/src/msgpack/pack_template.hご覧ください。


言い換えると、展開時に、msgpack は整数値を保持するのに十分な大きさの正または負 (obj.typeMSGPACK_OBJECT_POSITIVE_INTEGERまたは かどうかをテスト) を使用します。MSGPACK_OBJECT_NEGATIVE_INTEGERしたがって、それはあなた次第です:

  • 値がキャストタイプをオーバーフローしないと常に想定できる場合は、キャストします。
  • または、値が受信者のタイプに対して十分に大きくないかどうかを (マスクを使用して) 動的にチェックします。
  • または、常に または を使用しint64_tますuint64_t

最後に、C テスト スイート ( msgpack/cpp/test/msgpackc_test.cpp) は、コード サンプルを参照するのに役立つ場合があります。

于 2012-09-25T10:27:12.683 に答える