ファイルオフセットの計算
指定されたデータ値のオフセット(ファイル内の位置)を計算するには、指定された変数型nc_typeに適切なデータ値の一つの外部サイズ(バイト単位)をexternal_sizeofとします。
NC_BYTE 1
NC_CHAR 1
NC_SHORT 2
NC_INT 4
NC_FLOAT 4
NC_DOUBLE 8
nc_open (もしくはnc_enddef)呼び出しは前もってvar_arrayと示された変数配列内をスキャンし、recsizeを計算するために"記録”変数のvsizeの和を計算します。
変数の次元サイズの積を右から左にとっていき、記録変数の最も左の(記録)次元は飛ばし、各変数についての結果をproduct配列に格納します。例えば:
Non-record variable:
dimension lengths: [ 5 3 2 7]
product: [210 42 14 7]
Record variable:
dimension lengths: [0 2 9 4]
product: [0 72 36 4]
この時点では、最も左にある積を次の4の倍数に丸めたものが変数サイズ、すなわち、上の文法においてはvsizeになります。例えば、上記の非記録変数では、vsizeフィールド値は212(210を次の4の倍数に丸めた値)です。記録変数に対しては、vsizeの値はちょうど72です。なぜならば、72は既に4の倍数であるからです。
求めるデータ値の座標の配列をcoordとし、求める結果をoffsetとします。この時、offsetは単に、求める変数の最初のデータ値のファイルオフセット(そのbeginフィールド)にcoordとproductベクトルの内積を変数の各データのサイズ(バイト単位)を掛けたものを加えた値となります。最後に、もしその変数が記録変数であれば、記録数‘coord[0]’と記録サイズrecsizeとの積が加算され、最終的なオフセット値が導かれます。
擬似Cコードにおけるoffsetの計算は次のようになります。
for (innerProduct = i = 0; i < var.rank; i++)
innerProduct += product[i] * coord[i]
offset = var.begin;
offset += external_sizeof * innerProduct
if(IS_RECVAR(var))
offset += coord[0] * recsize;
したがって、(外部表現法の)データ値を取得するには、次のようになります。
lseek(fd, offset, SEEK_SET);
read(fd, buf, external_sizeof);
特殊例:記録変数が一つしかない場合には、各記録が4倍との境界に合っていなければならないという制限は外れるので、この場合には記録の詰め込みが行なわれません。
Quadralay Corporation http://www.webworks.com Voice: (512) 719-3399 Fax: (512) 719-3606 sales@webworks.com |