AS400/IBMi シフト文字を含めてバイト数を計算する

IT関連

AS400いわゆるIBMiには、シフト文字という意味不明な文字がある。

普通「アイウエオ」なら10バイトのはずだが、AS400では、12バイトになる。これは先頭と最後が2バイト文字の場合は、前後にそれぞれ1バイトづつ足されるからだ。他にも発生条件があるのでまとめると、

発生条件は、

・先頭で2バイト文字の場合は+1バイト
・最後で2バイト文字の場合は+1バイト
・文字列で1バイト文字と2バイト文字が隣になれば+1バイト

になる。

「aありがとう」は、13バイト
「あaりがとう」は、15バイト
になる。

当然のことながら、

「arigatou」は、8バイト

だ。

それゆえ、こんなロジックを考えてみた。文字列を1つづつ見て、バイト数を計算するのだ。これしか考えられないのでこうしている。

いいやり方があったら教えてほしい。

<!DOCTYPE>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>

<body>

<form name="myForm">
    <input name="text1" type="text" id="text1" size="40">
    <input type="button" onClick="alert(IBMBytes(document.myForm.text1.value));" value="バイト数は?">
</form>

<script type="text/javascript">

//1文字のバイト数を戻す
function getBytes(strSrc){

    var len = 0;    //カウント
    //urlエンコード
    strSrc = escape(strSrc);
    if(strSrc.substr(0,1) == "%"){
	    if(strSrc.substr(1,1) == "u"){
        len = 2;
      }else{
        len = 1;
      }
    }else{
    len = 1;
    }
    return len;
}

//AS400シフト文字を計算して文字列のバイト数を返す
function IBMBytes(Stringi){

  var strCnt = 0;  //引数の文字数
	var Now = 0;    //現在の文字のバイト数
	var Cnt = 0;    //カウント
  var Prv = 0;    //1つ前の文字のバイト数

  //引数の文字数を取得
  strCnt = Stringi.length;
  //文字列の左から1文字づつチェック
  for (i = 0; i < strCnt; i++){
    //バイト数を取得
    Now = getBytes(Stringi.substr(i,1));
    //最初の文字、かつ、2バイト文字ならば、シフト文字分追加
    if (i == 0 && Now == 2) {
      Cnt = Cnt + 1;
    }
    //最後の文字、かつ、2バイト文字ならば、シフト文字分追加
    if (i == strCnt - 1 && Now == 2) {
      Cnt = Cnt + 1;
    }
    //最初の文字でなく、かつ、1つ前の文字とバイト数が違う場合、シフト文字分追加
    if (i != 0 && Prv != Now) {
      Cnt = Cnt + 1;
    }
    //読んだ文字のバイト数を足しこみ
    Cnt = Cnt + Now;
    //読んだ文字のバイト数を比較のため1つ前に保管
    Prv = Now;
	}
	return Cnt;
}
</script>

</body>

</html>

 

コメント

タイトルとURLをコピーしました