近頃版/another blog@hatena/Wiki/BBS
< Reiser4のファイルセマンティクス:オープンソースには好機[japan.linux.com] | (no title) >
なぜかEUC-JP文字列の表示長による折り返し処理とかを実装。まあEUC-JPの仕様通りに適当に書けばおしまい。参考になるかはわからんけど該当部分のコードをベタっと載せておこう。とりあえずで書いたのでいろいろ格好悪いが所詮は参考ってことで。
struct displine{
unsigned char mes[LINE_BUF_SIZE];
int restwide;
};
struct splitbuffer{
int num_lines;
struct displine line[5];
};
void parse_message(struct splitbuffer *sb,unsigned char mes[])
{
int i,j,c,p;
int leng_in_byte;
int skip_bytes,copy_bytes,disp_wide;
struct displine *line;
for(i=0;i<sb->num_lines;i++)
memset(sb->line[i].mes,0,LINE_BUF_SIZE);
p = 0;
skip_bytes = 0;
copy_bytes = 0;
disp_wide = 0;
for(i=0;i < sb->num_lines;i++){
line = &(sb->line[i]);
leng_in_byte = 0;
while(leng_in_byte < LINE_BUF_SIZE){
c = mes[p];
// check type of character
if(c == 0x0a || c == 0x00){
break;
}else if( (0x00 <= c && c <= 0x1f) || c == 0x7f ){//制御文字
skip_bytes = 1;
copy_bytes = 0;
disp_wide = 0;
}else if(0x20 <= c && c <= 0x7e){// ASCII文字
copy_bytes = 1;
disp_wide = 1;
}else if(0xa1 <= c && c <= 0xfe){// 2バイト全角文字
copy_bytes = 2;
disp_wide = 2;
}else if(c == 0x8e){//半角カナ
copy_bytes = 2;
disp_wide = 1;
}else if(c == 0x8f){// 3バイト全角文字
copy_bytes = 3;
disp_wide = 2;
}else{// ぶっちゃけエラーケース。とりあえず無視。
skip_bytes = 1;
copy_bytes = 0;
disp_wide = 0;
}
//check display wide
if(line->restwide < disp_wide)
break;
//copying
while(copy_bytes > 0){
line->mes[leng_in_byte++] = mes[p++];
copy_bytes--;
}
line->restwide -= disp_wide;
p += skip_bytes;
skip_bytes = 0;
}
if( c == 0x00 ){
break;
}else if( c == 0x0a ){
line->mes[leng_in_byte] = '\0';
p++;
}
}
}