list, lines の 処理の再設計 - Implementation of list, lines 20050626 -KM- 20050926 -KM- 20060913 -MT- ■section 1) 検討の前提条件 - 制御構造となるだけ相性を良くする。 -> つまり、すでに UMSDat 構造体が保持している -> buffer, spos, epos を最大限活用し、これのみで処理させる。 -> 制御構造との親和性を高める。 - Lines の処理は List の delimiter と同じ。 ■section 2) decode 属性なし ------------------------------------- 再前処理: 非空白文字まで進める 処理 # 0x010 前処理: 終了位置算出 (space) 処理 # 0x100 後処理: なし separator 属性 ------------------------------------- 再前処理: 1文字進める 処理 # 0x020 前処理: 終了位置算出 (separator) 処理 # 0x200 後処理: なし delimiter 属性 ------------------------------------- 再前処理: なし 前処理: 終了位置算出 (delimiter) 処理 # 0x200 後処理: 1文字進める 処理 # 0x040 終了位置算出 (separator) - searchChar( dat, separator ); 終了位置算出 (space) - serachSpace( dat ); 1文字進める - skipChar( dat ); 非空白文字まで進める - skipSpace( dat ); encode 属性なし ------------------------------------- 再前処理: 1文字出力 処理 # 0x010 後処理: なし separator 属性 ------------------------------------- 再前処理: 1文字出力 処理 # 0x020 後処理: なし delimiter 属性 ------------------------------------- 再前処理: なし 後処理: 1文字出力 処理 # 0x040 [C] type ums__***() [JAVA] static public type jp.jaxa.isas.ums.UMSDat.***() ■section 3) 最前処理 -> list 要素の2個目以上の子 (長子以外の子) のみで実施する処理。 dat:list - dat:* - lang:value-of - ums:data - ums:value 自分が長子の系列かどうかはコンパイル時に xpath で評価する。 その判定方法に関しては別デザインノート for-each を使用する。 前処理・後処理はデータモデル上の子に対して実行する。( 従来の設計は誤り ) mapping definition 上では判定せず、ums__list の メンバ変数に list/lines の子か否かの判定をつける。 この処理は mapping definition 上で list や lines の 子でないことが明らかな場合にも判定と処理を行うコードを 埋め込んで対処するのでパフォーマンスとコードサイズに 影響を与える。 「再前処理」は、データモデル上で最初の子の場合は 実行しない前処理という意味である。 decode 前処理: parentStartDecode( ums__dat ); childStartDecode( ums__dat ); 後処理: childEndDecode( ums__dat ); parentEndDecode( ums__dat ); encode 前処理: parentStartEncode( ums__dat ); 後処理: parentEndEncode( ums__dat ); これらの関数の中の処理として section 2 に記載した処理を呼び出す。 ums__list.containerMode[ums__list.index] list[属性なし] 0x010 | 0x100 = 0x110 list[@separator] 0x020 | 0x200 = 0x220 list[@delimiter] 0x040 | 0x200 = 0x240 ums__list.listSeparator list[属性なし] ... 使用しない list[@separator] その値 list[@delimiter] その値 lines ... 改行コード 以上 ======================================================================== 以下に下位レイヤから順に示す。 ==== src/clng/umsDat.[hc] ==== # searchChar など 5 関数を umsList に移動、削除 ==== 1. src/clng/umsList.[hc] ==== # 以下 umsLibrary から移動し他のモジュールから隠蔽した。関数名から # ums__ を削除。引数を廃止し、 # ums__dat のメンバ変数 spos, epos を用いたインターフェースに変更。 static void searchChar ( ums__dat_t *dat, int separator, ums__exception_t *ex ) static void searchSpace( ums__dat_t *dat, ums__exception_t *ex ) static void skipChar ( ums__dat_t *dat, ums__exception_t *ex ) static void skipSpace ( ums__dat_t *dat, ums__exception_t *ex ) static void characterType_txtEncode ( ums__dat_t *dat, int separator, ums__exception_t *ex ) ==== 1. src/java/../UMSList.java ==== public class UMSList { : private void searchChar( UMSDat dat, int separator ) throws UMSException; private void searchSpace( UMSDat dat ) throws UMSException; private void skipChar( UMSDat dat ) throws UMSException; private void skipSpace( UMSDat dat ) throws UMSException; private void characterType_txtEncode( UMSDat dat, int separator ) throws UMSException; : } ==== 2. src/clng/umsList.[hc] ==== #define UMS__LIST_ARRAY_SIZE_MAX 64 typedef struct ums__list_t { int index; int containerMode[UMS__LIST_ARRAY_SIZE]; int listSeparator[UMS__LIST_ARRAY_SIZE]; int listEpos [UMS__LIST_ARRAY_SIZE]; /* umsCodeGenerator only (start) */ int containerEpos[UMS__LIST_ARRAY_SIZE]; /* umsCodeGenerator only (end) */ } ums__list_t; # スタイルシートに対して見せるのは下記の関数。 # containerMode に応じて seachChar,...,characterType_txtEncode を # 呼び出すか否かの判定を行う。 void ums__list_init ( ums__list_t *list ); void ums__list_parentStartDecode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_parentEndDecode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_parentStartEncode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_parentEndEncode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_childStartDecode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_childEndDecode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); /* umsCodeGenerator only (start) */ void ums__list_pushContainerDecode( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_popContainerDecode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_pushContainerEncode( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); void ums__list_popContainerEncode ( ums__list_t *list, ums__dat_t *dat, ums__exception_t *ex ); /* umsCodeGenerator only (end) */ ==== 2. src/java/../UMSList.java ==== public class UMSList { : public static final int ARRAY_SIZE = 32; : public int index; public int[] containerMode = new int[UMSList.ARRAY_SIZE]; public int[] listSeparator = new int[UMSList.ARRAY_SIZE]; public int[] listEpos = new int[UMSList.ARRAY_SIZE]; /* umsCodeGenerator only (start) */ public int[] containerEpos = new int[UMSList.ARRAY_SIZE]; /* umsCodeGenerator only (end) */ public void init(){ ... } // 処理を追加 : public UMSList ums__clone() { ... } // 処理を追加 newUMSList.index = this.index; System.arraycopy( this.containerMode, 0, newUMSList.containerMode, 0, UMSList.ARRAY_SIZE ); System.arraycopy( this.listSeparator, 0, newUMSList.listSeparator, 0, UMSList.ARRAY_SIZE ); System.arraycopy( this.listEpos, 0, newUMSList.listEpos, 0, UMSList.ARRAY_SIZE ); System.arraycopy( this.containerEpos, 0, newUMSList.containerEpos, 0, UMSList.ARRAY_SIZE ); : } : } ==== 3. src/xslt/mN/tool_clng.xsl ==== : : ums__dat ; ums__dat ; ums__dat ; : : : ums__dat ; ums__dat ; ums__dat ; catchAndThrow( ums__state ); ==== 3. src/xslt/mN/tool_java.xsl ==== 2. と同様。 ==== 4. src/xslt/mN/preTransform.xsl ==== 結局、従来どおりの pushContainer, popContainer の処理に組み込んだ。 : : : epos = ; : === 5. src/xslt/list.xsl === === 5. src/xslt/lines.xsl === ==== 5. src/xslt/list.xsl ==== ==== 6. src/xslt/lines.xsl ==== === 5. src/xslt/defineMapping.xsl === : ums__list_init( ums__list ); : ums__list.init(); : まだ、配列の書きつぶしのチェックは入れていない。 20060912 -MT- 2006091206 - 最新の設計を反映