Nimでバイトオーダ(エンディアン)を意識してデータ読み書きする
概要
Nimでstreamsモジュールを使ってのデータ読み書きについてまとめる バイトオーダ(エンディアン)を意識する必要がある
streamsの読み書きのエンディアンを調べる
streamsモジュールには何のエンディアンでデータを読み書きするのか説明がない
調べた
数値の読み書きのエンディアン
code:little.nim
import streams
block:
var strm = newFileStream("9.dat", fmWrite)
strm.write(9'u32)
strm.close()
block:
var strm = newFileStream("9.dat", fmRead)
echo strm.readUint32()
strm.close()
このコードを実行した結果生成される9.datのバイナリを調べると以下のようになる
code:9.sh
$ xxd 9.dat
00000000: 0900 0000 ....
一番下位のバイトが先頭に来ている
そしてreadUint32で取得した値を出力すると9が出力される
文字列の読み書きのエンディアン
code:str.nim
import streams
block:
var strm = newFileStream("hello.dat", fmWrite)
strm.write("hello")
strm.close()
block:
var strm = newFileStream("hello.dat", fmRead)
echo strm.readStr(5)
strm.close()
このコードを実行した結果生成されるhello.datのバイナリを調べると以下のようになる
code:9.sh
$ xxd hello.dat
00000000: 6865 6c6c 6f hello
helloがhelloの順序のまま格納されている
そしてreadStrで取得した値を出力するとhelloが出力される
よってreadStrはビッグエンディアンとして読み込む
数値をビッグエンディアンで読み取る
code:big.nim
import streams, endians
block:
var strm = newFileStream("big.dat", fmWrite)
strm.write(0'u8)
strm.write(0'u8)
strm.write(0'u8)
strm.write(9'u8)
strm.close()
block:
var strm = newFileStream("big.dat", fmRead)
var src = strm.readUint32()
echo "littleEndian32: " & $src
var dst: uint32
bigEndian32(addr(dst), addr(src))
echo "bigEndian32: " & $dst
strm.close()
code:result.txt
littleEndian32: 150994944
bigEndian32: 9