見出し画像

Notes C API探訪: RANGE(データ型)その4

LIST型には、エントリー番号を指定してその位置のデータを取得するListGetText関数というのがありました。今回はそれのRANGE型版を作ってみます。

RangeGetItem

RangeGetItemテンプレート関数は、RANGE型の指定した位置からアイテムを取得します。

/**
* @brief 指定した位置のアイテムエントリーを取得する。
* @tparam Traits 特性構造体
* @param pRange ロック済みメモリポインタへのポインタ
* @param fPrefixDataType データタイププレフィックスの有無
* @param EntrNumber アイテムのエントリー位置
* @param pData 取得したアイテムデータのコピー先
*/
template <typename Traits>
void RangeGetItem(
   void *pRange,
   BOOL fPrefixDataType,
   WORD EntryNumber,
   typename Traits::item *pData
   ) {
 char *pos = static_cast<char*>(pRange)
     + sizeof(WORD) * (fPrefixDataType ? 1 : 0)
     + sizeof(RANGE)
     + sizeof(Traits::item) * EntryNumber;
 *pData = *reinterpret_cast<typename Traits::item*>(pos);
}

・Traitsは、以前の記事で紹介した特性構造体、NumberRangeTraitsかTimeDateRangeTraitsかを指定します。
・pRangeは、RANGE型メモリハンドルのロック済みポインタを指定します。
・fPrefixDataTypeは、データタイププレフィックスを持つかどうか指定します。
・EntryNumberは、取得したいアイテムリスト(ペアでない方のリスト)のインデックス番号を指定します。
・pDataは、取得したいアイテムデータのコピー先を指定します。

RangeGetPair

RangeGetPairテンプレート関数は、RANGE型の指定した位置からペアデータを取得します。

/**
* @brief 指定した位置のペアエントリーを取得する。
* @tparam Traits 特性構造体
* @param pRange ロック済みメモリポインタへのポインタ
* @param fPrefixDataType データタイププレフィックスの有無
* @param EntrNumber ペアのエントリー位置
* @param pData 取得したペアデータのコピー先
*/
template <typename Traits>
void RangeGetPair(
   void *pRange,
   BOOL fPrefixDataType,
   WORD EntryNumber,
   typename Traits::pair *pData
   ) {
 char *pos = static_cast<char*>(pRange)
     + sizeof(WORD) * (fPrefixDataType ? 1 : 0);
 RANGE *_pRange = reinterpret_cast<RANGE*>(pos);
 pos += sizeof(RANGE)
     + sizeof(Traits::item) * _pRange->ListEntries
     + sizeof(Traits::pair) * EntryNumber;
 *pData = *reinterpret_cast<typename Traits::pair*>(pos);
}

・Traitsは、以前の記事で紹介した特性構造体、NumberRangeTraitsかTimeDateRangeTraitsかを指定します。
・pRangeは、RANGE型メモリハンドルのロック済みポインタを指定します。
・fPrefixDataTypeは、データタイププレフィックスを持つかどうか指定します。
・EntryNumberは、取得したいペアリストのインデックス番号を指定します。
・pDataは、取得したいペアデータのコピー先を指定します。

コーディング例

void *pRange = OSLockObject(hRange);

TIMEDATE td;
RangeGetItem<TimeDateRangeTraits>(pRange, TRUE, 0, &td);

TIMEDATE_PAIR tdp;
RangeGetPair<TimeDateRangeTraits>(pRange, TRUE, 0, &tdp);

まとめ

繰り返しになりますが、RANGE型はLIST型に比べヘルパー関数がない割に、個々の要素のデータ長が固定なので、自力で実装してもあまり苦労はしません。しかし、この程度の基礎的な関数くらい揃っていてもよさそうですから、さらっと関数にまとめてしまった方が後々楽でしょう。

注意: コードの利用においてチブル・システムズは一切の責任を負いません。自己責任でご利用をお願いいたします。

この記事が気に入ったらサポートをしてみませんか?