* XData [#qd3fc1e2] #contents ** はじめに [#d120ae48] XDataとは,お手製の「XML to バイナリデータ」の仕組みのことです。 このページにはXDataに関する情報を記述します。 ** 特徴 [#c3502091] - データをXMLで記述でき,それをバイナリデータに変換できる - エンディアンはBE,LEどちらにも対応 - 文字列は様々な文字コードの変換可能 - ラベル&リファレンス機能を使えば,データの先頭からのオフセット距離を埋め込むことも可能 ** XML [#fefdc08b] *** タグ仕様 [#k8d1f586] :要素 element| |名前|説明|属性|子となる要素|h |>|>|>|ルートタグ| |xdata_root|ルートとなる要素|major_version &br;minor_version|sint??,uint??,float??,reference,label,align| |>|>|>|データ格納タグ| |sint8 &br;sint16 &br;sint32 &br; sint64|符号有り整数データを格納する要素。 &br;sintの後の数値はbit数を示す。 &br;value属性には指定のbit数で表現できる範囲内の整数を入れる。|value|| |uint8 &br;uint16 &br;uint32 &br; uint64|符号無し整数データを格納する要素。 &br;uintの後の数値はbit数を示す。 &br;value属性には指定のbit数で表現できる範囲内の整数を入れる。|value|| |float32 &br;float64|浮動小数データを格納する要素。 &br;floatの後の数値はbit数を示す。 &br;value属性には指定のbit数で表現できる範囲内の整数を入れる。|value|| |reference|データのオフセット位置データを格納する要素。|label_name|| |>|>|>|その他| |label|データのオフセット位置を表現する要素。&br;referenceタグから参照される。|name|| |align|次に設置するデータのアライメントを表現する要素。 &br;valueにはアライメント値をuint32の範囲内で指定する。|value|| :属性 attribute| |名前|説明|h |major_version|フォーマットのメジャー番号。| |minor_version|フォーマットのマイナー番号。| |major_version|XDataのXMLフォーマットのメジャー番号。| |minor_version|XDataのXMLフォーマットのマイナー番号。| |value|数値。有効な数値は要素によって異なる。| |name|ラベル名。この値が1つのXML内で重複してはならない。| |label_name|参照するラベル名。| *** サンプル [#x9232bfe] #code(xml,){{ <?xml version="1.0" encoding="utf-8"?> <xdata_root major_version="1" minor_version="1" > <reference label_name="pos_array"/> <label name="pos_array"/> <sint8_array count="3">-128 127 1</sint8_array> <uint8 value="0"/> <uint16 value="0"/> <uint32 value="0"/> <uint64 value="0"/> <sint8 value="0"/> <sint16 value="0"/> <sint32 value="0"/> <sint64 value="0"/> <float32_array count="4">1.0 0.5 0.25 <!-- comment --> 0 </float32_array> <float32 value="3.1415926534"/> <float64_array count="0"></float64_array> <float64 value="10000.2"/> <string value="test"/> <align value="32"/> </xdata_root> }} ** コンバータ [#ya7eaf59] *** 概要 [#s3a79acf] xdata_conv.exeは、XMLファイルをバイナリファイルに変換するコマンドラインアプリケーションです。 .Netframework2.0を使用しています。Windows上で実行する場合は、.Netframework2.0以上のランタイムをインストールしてください。 他のOSでは、monoなどのランタイムをインストールして使用してください。 *** コマンドラインサンプル [#ye7c62f4] XMLファイルのパス。input.xml 出力するバイナリファイルのパス。output.bin ./xdata_conv.exe input.xml output.bin *** コマンドラインオプション [#v02c211b] :-endian| - エンディアンを指定します。 - BE : ビッグエンディアン。 - LE : リトルエンディアン。(デフォルト) :-encoding| - stringタグで格納される文字列のエンコードを指定します。 - 例えば'utf_8','shift_jis'が入ります。 - デフォルトは'utf_8'です。 :-ignoreLabelNotFoundError| - referenceで指定されているラベルが見つからないエラーを無視します。 :-silent| - 変換情報の標準出力を切ります。 ** C++ライブラリ [#h2de260a] *** ヘッダ [#n2a53c4d] #code(c,){{ /** * @file * @brief XData型を記述する。 */ #if defined(XDATA_INCLUDED_XDATA_HPP) #else #define XDATA_INCLUDED_XDATA_HPP //------------------------------------------------------------ /** * @brief BigEndian環境かどうか指定するマクロオプション。 * 指定されていなければ、__BIG_ENDIAN__が定義されているかどうかで判定。 */ #if defined(XDATA_OPTION_IS_BIG_ENDIAN) #else #if defined(__BIG_ENDIAN__) #define XDATA_OPTION_IS_BIG_ENDIAN #endif #endif #if defined(XDATA_OPTION_IS_BIG_ENDIAN) #define XDATA_IS_BIG_ENDIAN #else #define XDATA_IS_LITTLE_ENDIAN #endif //------------------------------------------------------------ namespace xdata { /// @name TypeDef //@{ typedef signed char SInt8; typedef signed short SInt16; typedef signed int SInt32; typedef unsigned char UInt8; typedef unsigned short UInt16; typedef unsigned int UInt32; typedef float Float32; typedef double Float64; typedef UInt32 Reference; //@} /// 文字列のヘッダ。 struct String { UInt32 byteLength; ///< 文字列データのバイト数。(終端文字数は含まない) /// 文字列データの先頭ポインタ。 const void* ptr()const { return &(&byteLength)[1]; } /// const char* に変換。 const char* toCStr()const { return reinterpret_cast< const char* >( ptr() ); } }; /// 定数群。 class Constant { public: /// XBIN(Xdata BINary)を示す4文字。 static const UInt32 SIGNATURE = #if defined(XDATA_IS_BIG_ENDIAN) 0x5842494E; #else 0x4E494258; #endif /// エンディアンを示す値。 static const UInt16 ENDIAN = 0x1234; /// メジャーバージョン static const UInt8 VERSION_MAJOR = 1; /// マイナーバージョン static const UInt8 VERSION_MINOR = 1; /// バージョン static const UInt16 VERSION = VERSION_MAJOR * 0x100 + VERSION_MINOR; }; /// XDataのヘッダ。 struct XDataHeader { UInt32 signature; ///< シグネチャ。Constant::SIGNATUREと等しい。 UInt16 endian; ///< エンディアンチェッカー。Constant::ENDIANと等しい。 UInt8 versionMajor; ///< メジャーバージョンを示す値。VERSION_MAJORに等しい。 UInt8 versionMinor; ///< マイナーバージョンを示す値。VERSION_MINOR以下。 UInt32 datasize; ///< ヘッダを含むデータサイズ。バイト数。 UInt32 pageCode; ///< 文字列のページコード。.netframeworkのページコード番号が入る。 }; /// バイナリ形式のXDataへのアクセサ。 class XData { public: /// デフォルトコンストラクタ。 XData() : ptr_(0){} /// バイナリデータの先頭アドレスを指定して作成。 XData( const void* aPtr ) : ptr_( static_cast< const XDataHeader* >( aPtr ) ) { } /// 保持しているポインタを取得する。 const void* ptr()const { return ptr_; } /// 正しいXDataか。 bool isValidData()const { return ptr_ != 0 && ptr_->signature == Constant::SIGNATURE && ptr_->endian == Constant::ENDIAN && ptr_->versionMajor == Constant::VERSION_MAJOR && ptr_->versionMinor <= Constant::VERSION_MINOR && sizeof(XDataHeader) <= ptr_->datasize ; }; /** * @brief データ本体の先頭アドレスを取得する。 * 無効なデータならNULLポインタを返します。 */ const void* dataHeadAddress()const { if ( !isValidData() ) {// 無効なデータならNULLポインタを。 return 0; } return &ptr_[1]; } /** * @brief Referenceタグの値からLabelのアドレスを取得する。 * 無効なデータおよび無効な引数ならNULLを返します。 */ const void* labelAddressWithReference( const Reference aReferenceValue )const { if ( !isValidData() ) {// 無効なデータならNULLポインタを。 return 0; } if ( aReferenceValue < sizeof(XDataHeader) // ヘッダの中を指している || ptr_->datasize < aReferenceValue // データの外を指している ) {// 範囲外 return 0; } return &reinterpret_cast< const UInt8* >( ptr_ )[ aReferenceValue ]; } private: const XDataHeader* ptr_; }; } //------------------------------------------------------------ #endif // EOF }} |