struct Header {
char tag[3];
char ver;
char rev;
char flags;
uint8_t hSize[4];
};
struct ContentFrame
{
char id[4];
uint32_t contentSize;
char flags[2];
};
int ID3_sync_safe_to_int(uint8_t* sync_safe)
{
uint32_t byte0 = sync_safe[0];
uint32_t byte1 = sync_safe[1];
uint32_t byte2 = sync_safe[2];
uint32_t byte3 = sync_safe[3];
return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;
}
const int FRAMESIZE = 10;
上面的代码用于将二进制数据转换为ASCII数据。 在主函数内部
Header header;
ContentFrame contentFrame;
ifstream file(argv[1], fstream::binary);
//Read header
file.read((char*)&header, FRAMESIZE);
//This will print out 699 which is the correct filesize
cout << "Size: " << ID3_sync_safe_to_int(header.hSize) << endl << endl;
//Read frame header
file.read((char*)&contentFrame, FRAMESIZE);
//This should print out the frame size.
cout << "Frame size: " << int(contentFrame.contentSize) << endl;
我已经用Perl写了一个程序来完成这个任务,它能够很好地工作,其中使用了unpack函数,例如:
my($tag, $ver, $rev, $flags, $size) = unpack("Z3 C C C N"), "header");
my($frameID, $FrameContentSize, $frameFlags) = unpack("Z4 N C2", "content");
sync_safe_to_int函数也用于获取正确的头部大小,但对于内容大小,它只是以未转换的方式进行打印。
N:一个无符号长整型(32位),采用“网络”(大端)字节顺序。
C:一个无符号字符(八位)值。
Z:一个以 null 结尾的(ASCIZ)字符串,将被 null 填充。
我的程序输出:
头部内容
标签:ID3
版本:3
修订版:0
标志:0
大小:699
错误输出!
帧内容
ID:TPE1
大小:167772160
标志:
Perl 的正确输出!
帧内容
ID:TPE1
大小:10
标志:0