- RTC程序设计:实时音视频权威指南
- 戴维
- 1399字
- 2024-05-14 10:03:25
1.2.3 BufferViewer
Demo展示
本节实现了一个最简单的十六进制查看工具——BufferViewer,如图1-8所示。
BufferViewer实现了如下功能。
·打开任意文件,查看其十六进制数据。
·随机生成100字节的十六进制数据,并查看。
·将十六进制转换为Base64编码表示。
·将Base64编码表示转换回十六进制表示。
·判断Base64编码是否合法。
完整的代码可以在ch01/01_BufferViewer中查阅。
图1-8 BufferViewer界面
使用VS2022打开rtcbook.sln,在Solution Explorer中,右键单击01_BufferViewer工程,单击Set as Startup Project,再次右键单击Build,即可运行启动。
工程说明
作为本书的第一个示例工程,我们详细介绍一下各个代码文件的作用。
源码的组织形式如图1-9所示。
主界面使用了WTL(Windows Template Library),这是微软维护的一个轻量级UI库,只有纯头文件,无须库文件。
主窗口的实现位于MainDlg.h中,这是一个派生自WTL的对话框类。
我们可以通过消息函数处理表的宏定义,为其添加各种消息函数,从而实现从UI操作到功能的调用。
为了方便代码复用,本书将所有示例工程的公用代码都放置于Common文件夹下。这些公用代码具有很强的复用性,可以被多个示例同时使用。
依据公用代码的功能不同,Common下又分为多个文件夹。
·Base:缓存、文字编码、线程等。
·Video:视频相关算法。
·Audio:音频相关算法。
·File:文件格式相关。
·Data:数据处理相关。
·Net:网络相关算法。
图1-9 源码的组织结构
我们看一段从文件加载到Buffer并显示其十六进制格式的代码。
第3行,CFileDialog表示WTL提供打开文件对话框用来获取用户所选择的文件。
第7行,DFile类是一个文件封装处理类,用来加载文件到内存。
第8行,DXP类有两个方法:ws2s和s2ws,用作Unicode与MBCS之间字符集的转换,下一节会详细介绍。
第9~10行,我们最多读取100 KB的数据到内存中。
第11行,DBuffer类将数据从文件读取到内存中。
第12行,我们使用DBuffer的ToHexList方法,将其转换为十六进制表示。
第13行,m_hex是一个CEdit的成员对象,这也是WTL提供的一个封装类,用来实现一个多行的文本框。我们将转换好的文本内容贴上去展示。
经过这些基础类的封装,整个代码的易读性都得到了明显的提升。
以二进制/十六进制形式查看任何数据,是我们理解任何计算机技术的基础。
只有细到每一比特,才能真正理解计算机程序的运行规律。
总结
本节我们介绍了比特和字节的基本概念,了解了十六进制与Base64编码。为了能方便地管理字节,我们设计了一个基于引用计数的Buffer类。我们开发了一个十六进制查看器,用来演示Buffer类。后续,我们会经常用它来分析各种媒体文件格式。
参考阅读
1.斯坦福大学的Sean Eron Anderson搜集了大量有关bit的算法。
2.Programming Pearls(1999年),More Programming Pearls(1988年),Jon Louis Bentley著,介绍了一些关于位运算的黑科技。
3.Base64编码的细节,请参考RFC 4648。
4.WTL的atlmisc.h中有一个CString类的实现,包含了更多字符串操作的内容。
5.WinHEX是Windows平台下一款好用的十六进制编辑器。macOS平台下则有hexdump显示工具。
练习题
1.[30分钟](交换字节序)编写一个交换字节序的函数。
2.[2小时](Bitset)设计一个Bitset类,支持按bit来访问4字节长度的二进制数据。
3.[1人天](BitStream)设计一个BitStream类,支持按bit来获取一段长度的比特流。
4.[1人天](Base58编码)Base58是比特币采用的一种二进制编码方式,它使用了哪些字符编码?有什么优势?
5.[30分钟](判断2的幂)写一个函数,判断一个整数是否是2的幂。
6.[30分钟](求二进制数1的个数)写一个函数,求一个整数中有多少个二进制的1。
7.[30分钟](无分支的截取)写一个函数,给定任意无符号整数v,若v大于255,则返回255,否则返回v,不能使用条件判断或问号表达式。
8.[30分钟](无分支的绝对值)写一个函数,给定任意整数v,返回v的绝对值,不能使用条件判断或问号表达式。