.osr 文件格式解析(二) - 数据类型
来源:互联网 发布:晚安网络用语 编辑:程序博客网 时间:2024/06/02 06:02
吐槽一句,PPY很喜欢用文本格式来储存数据,这明明是即不省时间又不省空间的做法….也不知道他怎么想的
先来看一下,osr里出现得数据类型除了Long、ULEB128和String其他的都是普通的类型
- Long 在这里是8字节的,所以直接声明long是不行的(c/c++里long默认是4字节的),要用__int64(long long)
- ULEB128 LEB128是一种变长整数,加个U就是无符号的变长整数,其本质是unsigned char数组。它的字节长度不定(但是一般不超过5字节)。数据格式为每字节的8bit中,编码的每个字节有效部分只有低7bits,每个字节的最高bit用来指示有无下一字节。具体看下面的详细说明。
- String 这里的string不是通常的string,是一个结构体。由3部分组成,具体看下面的详细说明。
ULEB128 与 unsigned int 互转
unsigned int 转 ULEB128:
void EncodeULEB128(unsigned int value, unsigned char *leb128_buffer) { int pos = 0; while (value != 0) { leb128_buffer[pos++] = value & 0x7F | 0x80; //每个字节标识信息都设为1 value >>= 7; } if (pos > 0) leb128_buffer[pos - 1] &= 0x7F; //将最后一个字节的标识信息设为0 }
ULEB128 转 unsigned int:
unsigned int DecodeULEB128(unsigned char *leb128_buffer) { unsigned int value = 0; int pos = 0; int offset = 0; while (leb128_buffer[pos] != 0) { value |= ((leb128_buffer[pos] & 0x7F) << offset); //从低到高将 bits 合并到一起 offset += 7; if (leb128_buffer[pos] & 0x80 == 0) break; pos += 1; } return value; }
osrString
根据官方文档的描述,我们可以得到如下结构体:
struct String { unsigned char Type; //状态标签(如果其值为0x00,则没有下面两部分;若值为0x0B反之) ULEB128 StrLengeh; //str的字节长度 string str; //文本字符串 }
但是这样的结构不适合我们操作(因为ULEB128是变长啊,该死的ppy,就为了省那几字节搞得这么麻烦,用int会死啊,你的字符串长度会int溢出?)
所以我写了个osrString类封装了这个结构,声明如下
class osrString { private: unsigned int StrLengeh; unsigned char Type; std::string str; public: osrString(); ~osrString(); void Load(std::ifstream &fin); //从文件流读入数据 void Save(std::ofstream &fout); //通过文件流输出数据 void SetString(std::string str); //改变string的内容 std::string GetString(); //取得文本 void Clear(); //情况内容,设置Type=0x00 };
方法实现:
osrString::osrString() { Clear(); } osrString::~osrString(){} void osrString::Clear() { this->Type = 0x00; this->StrLengeh = 0; this->str = ""; } void osrString::Load(std::ifstream &fin) { fin.read((char*)&Type, sizeof(Type)); if (Type == 0x00) { Clear(); } else if (Type == 0x0B) { //读取StrLengeh(ULEB128) unsigned int value=0; byte buff; fin.read((char*)&buff, sizeof(buff)); int offset = 0; while (buff != 0) { value |= ((buff & 0x7F) << offset); //从低到高将 bits 合并到一起 offset += 7; if ((buff & 0x80) == 0) break; fin.read((char*)&buff, sizeof(buff)); } StrLengeh = value; //读取str char *strbuff = new char[StrLengeh + 1]; ZeroMemory(strbuff, StrLengeh + 1); fin.read(strbuff, StrLengeh); str = strbuff; delete[] strbuff; str = UTF8_To_string(str); } } void osrString::SetString(std::string str) { if (!str.empty()) { this->Type = 0x0B; this->str = str; } else{ this->Type = 0x00; this->str = ""; } } std::string osrString::GetString() { return this->str; } void osrString::Save(std::ofstream &fout) { fout.write((char*)&Type, sizeof(Type)); if (Type == 0x00) { return; } else if (Type == 0x0B) { std::string utf8_str = string_To_UTF8(str); StrLengeh = utf8_str.size(); //写入StrLengeh(ULEB128) unsigned int value = StrLengeh; byte buff[5] = { 0 }; int pos = 0; while (value != 0) { buff[pos++] = value & 0x7F | 0x80; //每个字节标识信息都设为1 value >>= 7; } if (pos > 0) buff[pos - 1] &= 0x7F; //将最后一个字节的标识信息设为0 fout.write((char*)buff, pos); //写入str fout.write((char*)utf8_str.c_str(), StrLengeh); } }
好了,至此读取osr要用到的类我们都准备好了,下面就可以开始写读取的方法了。
0 0
- .osr 文件格式解析(二) - 数据类型
- .osr 文件格式解析(一) - 官方格式说明
- .osr 文件格式解析(三) - 读取OSB文件
- .osr 文件格式解析(四) - LifeBarGraph和TimeStamp
- .osr 文件格式解析(五) - 回放数据ReplayData
- mp4文件格式解析(二)
- mp4文件格式解析(二)
- mp4文件格式解析(二)
- swf文件格式解析(二)
- mp4文件格式解析(二)
- swf文件格式解析(二)
- mp4文件格式解析(二)
- mp4文件格式详细解析(二)
- MP4文件格式解析 之 二 (Sample table atom )
- MP4文件格式解析 之 二 (Sample table atom )
- MP4文件格式解析 之 二 (Sample table atom )
- OBJ文件格式(二)
- MP3文件格式(二)
- 项亮《推荐系统实践》读书笔记1-推荐系统评价指标
- 三层学习之初相识
- 第7周 数据结构与算法分析 2-11 高效率取幂运算
- Scala学习记录-Scala是什么
- 光棍节的快乐
- .osr 文件格式解析(二) - 数据类型
- django 1.8.2 阅读笔记
- H5特性简介
- 第五届山东省ACM Weighted Median
- laravel5.1框架下的用户权限管理
- C#Winform中运用DevExpress提供的ChartControl控件绘制多条曲线图
- 【AKOJ】1031-素数求和问题
- centos7安装,使用视频压缩,超级好用的工具FFmpeg
- 315MHz无线通讯模块调试心得