2014-11-04

libecbufr を読んでみる(反復・次元に関するデータ構造はどうやって作られているか)

TEMP BUFR を bufr_decoder -dump していると

007007 {R=1}{5002=52.419998,6002=-4,4025=30} 1685

みたいな出力にでくわすことがある。
この中括弧はなんだろう。

0.8.5 のソースコード、 API/Sources/bufr_meta.c の
bufr_print_rtmd_data(char *outstr, BufrRTMD *rtmd) あたりでやっているよ
うだ。

まず、 rtmd == NULL ならば、この中括弧群は一切生成しないで関数を抜ける。

{R=1} というのが反復記述子による反復数であることはだいたい察しがつくけれ
ど、それは bufr_print_rtmd_repl() でやっている。
rtmd->nesting が真の場合に "R=" が表示され、 rtmd->nb_nesting が2以上の
場合は R=1.1.1 のようにピリオド区切りで数が表示される。
被表示数は rtmd->nesting[i] である。

(つまり rtmd->nesting が偽の場合は "{}" が表示されるロジックなんだが、
それでいいの? おそらくそれは起こらない想定だろうけど)

第2の括弧ブロックは、 rtmd->nb_tlc が真である場合に表示され、
rtmd->nb_tlc 個だけコンマ区切りの記述子・値ペアが表示される。
記述子は rtmd->tlc[i].descriptor, 値は rtmd->tlc[i].value である。

まあ、どうせ、次元記述子の修飾関係を明示するというつもりなのはわかるのだ
が、出現条件が知りたい。

ここらでコールツリーの上方へ探索。

bufr_print_rtmd_data() を読んでいるのは API/Sources/bufr_dataset.c の
bufr_fdump_dataset(BUFR_Dataset *dts, FILE *fp) である。

それを呼んでいるのは同じソースの bufr_dump_dataset(BUFR_Dataset *dts,
const char *filename) である。

それを呼んでいるのは Utilities/bufr_decoder.c の run_decoder(void) <=
main() である。
まあ、なんというか、 main を見つけると安心するよね。

さて、 run_decoder から下方探索はしんどいので後回しにして、

BufrRTMD::nb_nesting を設定しているのは bufr_meta.c:
bufr_create_rtmd(int count) である。
これは単純に反復記述子を数えているようである。

BufrRTMD::nb_tlc を設定しているのは bufr_ddo.c:
bufr_assoc_location(BufrDescriptor *bc, BufrDDOp *ddo) である。
これは ddo->current_location の各要素から記述子と値をとっている。

これを呼んでいるのは bufr_sequence.c: bufr_apply_Tables(BufrDDOp *ddoi,
BUFR_Sequence *bsq, BUFR_Template *tmplt, ListNode *current, int
*errcode) である。
これは多数回呼ばれるので上方探索が難しい。

あきらめて dts に戻る。
bufr_print_rtmd_data に食わされる BufrRTMD は bufr_fdump_dataset() 内で
は bcv->meta と呼ばれている。
これは bcv = bufr_datasubset_get_descriptor(subset, j) といって抽出される。
subset は bufr_get_datasubset(dts, i) といって dts->datasubsets から抽出
される。

BUFR_Dataset::datasubsets は DataSubsetArray 型でありそれは ArrayPtr 型
のエイリアスである。
ArrayPtr 型は名目上は char * と定義されているけれど、それは実際には
Array 構造体をさしている。
管理ルーチン arr_create(), arr_add() など以外が内部を操作しないようにオ
ペーク化しているのである。

Array の構造は Array::grow の値によって大きく異なる。
Array::grow が零または負であれば固定長配列で、 Array::eles が指す配列は
Array そのものと一体的に malloc される。
Array::size が1要素の大きさ、Array::total = [arr_create() の引数 len] が
要素数である。
Array::grow が正であれば可変長配列で、 初期には Array そのものとは別に
Array::total 個の要素が確保され、
不足時には Array::grow 個増やして realloc(3) される。

さて run_decoder() 内で dts の構築は bufr_decode_message(BUFR_Message
*msg, BUFR_Tables *tables) がしている。

その中で dts->datasubsets は ...

今日はちょっとここらでおしまい。たぶん続きは書かれない。

0 件のコメント:

コメントを投稿