Profile

書いてる人:

たけ-ちーず
紹介文:
SkypeID:take-cheeze

Link

RSS Feed

Search

Calender

Latest Article

Category

Access Counter

Online Counter

Show All Article

どうでもいい独り言。 と、少しの開発日記。
  • 11 «
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • » 01
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
【--/--/-- --:--】 | スポンサー広告 |
BERの展開と格納するコードを特集してみる。
http://nanashia.blog8.fc2.com/blog-entry-66.htmlに触発されて、やってみます。
(実際は、ソースコード貼り付ければ水増しできる、……なんて思っていません。)

因みに、大層なアルゴリズムを組んでいるわけでもないので、有名な言い方の『解凍』を『展開』・『圧縮』を『格納』と表記するのでお気をつけください。
それと、インデント無しです。ごめんなさい。


まず、展開ルーチンです。
触発元の do {} while(); を参考に書き加えたりしてます。

裏話として、while() の中にある不等号が逆だったおかげで、昨日の酷い結果は招かれたようです。
直したら、平然と動きました。

uint32_t Stream::getBER()
{
uint32_t ret = 0;
uint8_t data;
// extract
do {
data = this->read();
ret = (ret << BER_BIT) | (data & BER_MASK);
} while(data > BER_SIGN);
// result
return ret;
}



続いて、格納ルーチンです。
テストしてない危ないコードだったりします。

将来的に、変更の余地はあります。

uint Stream::setBER(uint32_t num)
{
uint8_t buff[ ( sizeof(num) * CHAR_BIT ) / BER_BIT + 1];
uint size = getBERSize(num), index = size;
// set data
buff[--index] = num & BER_MASK;
num >>= BER_BIT;
while(!num) {
buff[--index] = (num & BER_MASK) | BER_SIGN;
num >>= BER_BIT;
}
// write data
write(buff, size);
return size;
}




以下は、番外編な部分です。
無くてもいいけど、有ると深まるねって程度なので、追記します。
まずは、定数宣言と格納の際に要となる関数の宣言です。
定数は、随所で使われているので、まあ理解しといてください。

わたしの無知で発生した注意点は、CHAR_BIT は <limits.h> に宣言されています。

static const uint
BER_BIT = (CHAR_BIT-1),
BER_SIGN = 0x01 << BER_BIT,
BER_MASK = BER_SIGN - 1;
extern uint getBERSize(uint num);



続いて、整数 -> BER圧縮整数した時に必要な大きさを求める関数の実装です。
得で特に深い説明は出来ません。

uint rpg2kLib::structure::getBERSize(uint32_t num)
{
if(!num) return 1;
else {
uint ret = 0;
for(; num != 0; num >>= BER_BIT) ret++;
return ret;
}
}



最後に、ところどころにある read() やら write() の宣言です。
実際に呼んでいる関数は違いますが、内容はほとんど同じなので、気に留めておいてください。

class StreamInterface
{
protected:
StreamInterface() {}
StreamInterface(const StreamInterface& i);
public:
virtual ~StreamInterface();

virtual string name() const = 0;

virtual uint seekFromSet(uint val = 0) = 0;
virtual uint seekFromCur(uint val = 0) = 0;
virtual uint seekFromEnd(uint val = 0) = 0;

virtual uint8_t read() = 0;
virtual uint read(uint8_t* data, uint size) = 0;

virtual uint length() = 0;
virtual void resize(uint size) = 0;

virtual void write(uint8_t data) = 0;
virtual uint write(uint8_t* data, uint size) = 0;
};




とまあ、きっと参考にならない説明でした。
【2010/02/10 20:28】 | RPG2k_Emu | トラックバック(0) | コメント(0) |
<<virtual関数を減らしました。 | HOME | メモリリーク酷い。>>
コメント
コメントの投稿












管理者にだけ表示を許可する

トラックバック
トラックバックURL
http://takecheeze.blog47.fc2.com/tb.php/275-d83438f9
この記事にトラックバックする(FC2ブログユーザー)
ホーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。