github.com にある Ruby コードの一部を Javascript に書き直しています。以下の部分を除いて、コードを理解するのに問題はありません。問題は、「ブレーク」がない場合、「ループ」はどのように終了するのかということです。
def utf8_bytes(record_size, record_tag)
Enumerator.new do |yielder|
bits = compressed_bits record_size, record_tag
loop do
# Use the Huffman tree to decode the first character.
node = tree_root
while node < 0x100
# p ['node', node]
bit = bits.next
# p ['bit', bit]
node = (bit == 0) ? tree_left[node] : tree_right[node]
end
first_byte = node - 0x100
# p ['utf8 start', first_byte]
yielder << first_byte
# The other characters are 10xxxxxx, where x'es are raw bits.
2.upto utf8_char_bytes(first_byte) do
byte = 0b10
6.times do
byte = (byte << 1) | bits.next
end
# p ['utf8 byte', byte]
yielder << byte
end
end
end
end
アップデート
すべての回答に感謝しますが、残念ながら、実際に何が起こっているのかまだわかりません。正しく理解すれば、バケツのようなものです。何かを入れるたびに、それは処理されています。そして、'loop do' は、そこに入れられたバイトの数だけ実行されます。
関数は次のように 1 回だけ呼び出されます。
text = utf8_bytes(record_size, record_tag).to_a.pack('C*')
しかし、これも列挙子の内部にあるため、バイトが一方のバケットから他方のバケットに滴り落ちていると思います。
いかなる場合でも。関数をJavascriptに翻訳しました。これが正しいかどうか誰かが教えてくれるでしょうか?(Javascript 関数が配列を返すことはさておき、このように配列を使用することはおそらくあまり効率的ではありません)
function utf8_bytes( record_size, record_tag ) {
var yielder = new Array();
bits = compressed_bits( record_size, record_tag );
// compressed_bits returns an array of 0's and 1's
var v=0;
while( v<bits.length ) {
// # Use the Huffman tree to decode the first character.
var node = tree_root;
while ( node < 0x100 ) {
// # p ['node', node]
bit = bits[v++];
// # p ['bit', bit]
node = (bit == 0) ? tree_left[node] : tree_right[node];
}
var first_byte = node - 0x100;
// # p ['utf8 start', first_byte]
yielder.push( first_byte );
// # The other characters are 10xxxxxx, where x'es are raw bits.
for (var m=2; m<=utf8_char_bytes(first_byte); m++ ){
var mbyte = 2;
for (var n=0; n<6; n++ ) {
mbyte = (mbyte << 1) | bits[v++];
}
// # p ['utf8 byte', mbyte]
yielder.push( mbyte );
}
}
return( yielder );
}