HSPで5バイト以上のデータ (文字列等) でビット単位の演算を行えるモジュール作ってたりする

HSPで5バイト以上のデータ (文字列等) でビット単位の演算を行えるモジュール作ってたりする

あまりにもぐちゃぐちゃでバグだらけでひどいモジュールだったんで一から作り直しました。↓です。
バグがありません; それをより付けで、容易に使うことになっています; スケーラブルなモジュールは、このものです

完成までに時間がかかりそうなので、とりあえずここで投稿しちゃいます。

// ビット単位でデータ操作 by kerupani129
#module "kerupanium_bit"
#defcfunc bit_power int _p1
p=1
repeat _p1
p*2
loop
return p
#defcfunc bit_mid_local int _p1,int _p2,int _p3
index=_p2
if index=-1 : index=8-_p3
return (_p1>>index)&(bit_power(_p3)-1)
#deffunc bit_shift var _p1,var _p2,int _p3,int _p4
len=_p4
if varptr(_p1)=varptr(_p2) { // 変数が同じだったら別の変数で処理してからやる
e=""
bit_shift e,_p2,_p3,_p4
memset _p1,0,len,0
memcpy _p1,e,_p4,0,0
} else {
shift=abs(_p3)\8
shift_byte=abs(_p3)/8
dim d
memexpand _p1,len
memset _p1,0,len,0
memcpy _p1,_p2,len,0,0
if _p3>0 {
if shift_byte!0 {
memcpy _p1,_p1,len-shift_byte,shift_byte,0 // メモリブロックの再確保した
memset _p1,0,shift_byte,0
}
if shift!0 {
repeat len
c=len-cnt-1
a=bit_mid_local(peek(_p1,c),-1,8-shift)
if c!0 : b=bit_mid_local(peek(_p1,c-1),0,shift) : else : b=0
d(cnt)=b*bit_power(8-shift)+a
;dialog "a="+a+",b="+b+",あれ="+d(cnt)
loop
repeat len
c=len-cnt-1
poke _p1,c,d(cnt)
loop
}
}
if _p3<0 {
if shift_byte!0 {
memcpy _p1,_p1,len-shift_byte,0,shift_byte // メモリブロックの再確保した
memset _p1,0,shift_byte,len-shift_byte
}
if shift!0 {
repeat len
c=cnt
a=bit_mid_local(peek(_p1,c),0,8-shift)
if c!(len-1) : b=bit_mid_local(peek(_p1,c+1),-1,shift) : else : b=0
d(cnt)=a*bit_power(shift)+b
;dialog "a="+a+",b="+b+",あれ="+d(cnt)
loop
repeat len
c=cnt
poke _p1,c,d(cnt)
loop
}
}
}
return
#deffunc bit_and var _p1,var _p2,var _p3,int _p4,int _p5,int _p6
; 変数が同じかどうかの処理してない
ands=_p4\8
ands_byte=_p4/8
len=ands_byte : if ands!0 : len+
memexpand _p1,len
memset _p1,0,len,0
if ands_byte!0 {
repeat ands_byte
c=_p5-cnt-1
c2=_p6-cnt-1
c3=len-cnt-1
poke _p1,c3,peek(_p2,c)&peek(_p3,c2)
loop
}
if ands!0 {
c=_p5-ands_byte-1
c2=_p6-ands_byte-1
c3=len-ands_byte-1
poke _p1,c3,bit_mid_local(peek(_p2,c),0,ands)&bit_mid_local(peek(_p3,c2),0,ands)
}
return
#deffunc bit_or var _p1,var _p2,int _p3,int _p4,int _p5
; まだ作ってない
return
#deffunc bit_xor var _p1,var _p2,int _p3,int _p4,int _p5
; まだ作ってない
return
#deffunc bit_mid var _p1,var _p2,int _p3,int _p4,int _p5
// データの一部をビット単位で抜き出す
// p1=変数 : 結果を入れる変数
// p2=変数 : もとのデータが入った変数
// p3=0~ : 取出し始めのインデックス1 (バイト単位)
// p4=0~7 : 取出し始めのインデックス2 (ビット単位)
// p5=0~ : 取出すビット数
// 右向きにp3バイト行ったところから左向きにp4ビットの所を取り出し初めにする
; 変数が同じかどうかの処理してない
; まだ完成してない
bytes=_p5/8 : if (_p5\8)!0 : bytes+
buf=""
memexpand buf,bytes
memcpy buf,_p2,bytes,0,_p3-bytes
bit_shift buf,buf,_p4,bytes
memexpand buf2,bytes
;bit_write buf2,
bit_and buf,buf2,_p4,bytes,bytes
;
return
// っていうか、メモリ何バイトか「HSPだと取得できねぇ」って書いたけど、
// 取得できたとしても文字列で勝手にNULL入ったりするから
// どっちみちユーザー側が指定できるようにして正解だったな…。
#global

このモジュールは作成途中です。
現在使える命令は次の通りです。

bit_power関数
2のべき乗 (累乗) を出す
val=bit_power(p1)
p1=0~30 : 2の何乗か

bit_mid_local関数
1バイト以内で特定のビット数のデータを切り取る
val=bit_mid_local(p1,p2,p3)
p1=0~255 : 元の数値
p2=-1~7 : 取出し始めのインデックス (右から数えるので注意。ビット単位)
p3=1~8 : 取出すビット数

bit_shift命令
数値以外のデータもビット単位でシフトする
bit_shift p1,p2,p3,p4
p1=変数名 : 結果を入れる変数
p2=変数名 : 元のデータが入っている変数
p3=-8*p3-7~8*p3+7 : 右へシフトするビット数 (左へシフトするにはマイナス値)
p4=0~ : 元の変数は何byteあるん? (HSPだと取得できねぇ)
注意:右にシフトすると右側のデータが消えt (ry
p1はp4バイト分、メモリブロックを再確保
シフトする量はその容量以内 (で処理できる量) にしてくれ。

bit_and命令
数値以外のデータもand演算する
bit_and p1,p2,p3,p4,p5,p6
p1=変数名 : 結果を入れる変数
p2=変数名1 : 元のデータが入っている変数
p3=変数名2 : もう一つのデータが入っている変数
p4=0~ : 演算する範囲 (それぞれの変数の右端からのビット数) 
p5=0~ : 変数1は何byteあるん? (HSPだと取得できねぇ)
p6=0~ : 変数2は何byteあるん? (HSPだと取得できねぇ)
p4のビット数だけ入るバイト分、p1のメモリブロックを再確保
演算する範囲はp5,p6のビット数内にしてください

ちょこっとサンプル

a="kerupani0"
bit_shift a,a,-16,9
mes a+""
a="kerupani"
b="tani"
c=""
bit_and c,a,b,32,8,4
mes c+""


追加予定命令 (現在は使えません)
bit_or : 数値以外のデータもor演算
bit_xor : 数値以外のデータもxor演算
bit_mid : 数値以外のデータから、特定の場所がらビット単位でデータ抜き出し。
bit_write : 特定の場所にビット単位でデータ書き込み

例のアニメーションGIF入出力サンプル (現時点ではそれぞれのデータ抜き出ししかできていない…orz) で使おうと思って作成してるところです。
GIFってbit単位でデータ格納してるんで、それを簡単にできるように… (っていうかこういうモジュール作成しないと簡単じゃないどころか不可能だろ…) 。
というわけで頑張ってこれを数日間のうちに完成させたいと思います。では。

訂正とお詫び 2012/1/10 追記

xorをnorと勘違いしていました。今修正いたしました。
大変申し訳ありませんでした。
↓クリック!!してくれぇぇぇぇ!!!


「HSPで5バイト以上のデータ (文字列等) でビット単位の演算を行えるモジュール作ってたりする」への2件のフィードバック

  1. ああ、自分もこんなの作ったことありました。
    バイナリファイル扱おうとか思うと、ビット操作モジュールは欲しくなりますよね。
    GIF解析頑張ってください。

  2. Cookiesさんもですか!!

    はい。とくにGIFはビット単位でデータ詰めまくりなんでビット単位の操作できるのがほしかったんで自作し始めました。

    頑張ります!ありがとうございます!

コメントは受け付けていません。