25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment

这是Live555源码阅读的第三部分,包括了UsageEnvironment相关的三个类。

本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso
本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

简介

BasicUsageEnvironment0实现了其基类UsageEnvironment的部分纯虚接口(只有部分,其还是一个抽象类),并添加了三个数据成员。其定义在live555sourcecontrol\BasicUsageEnvironment\include\BasicUsageEnvironment0.hh文件中。

代码定义如下

// An abstract base class, useful for subclassing
// (e.g., to redefine the implementation of "operator<<")
class BasicUsageEnvironment0 : public UsageEnvironment {
public:
// redefined virtual functions:重定义虚函数 //返回fResultMsgBuffer
virtual MsgString getResultMsg() const;
// 调用reset将消息结果buffer截空,再将msg(msg1-3)拷贝到buffer
virtual void setResultMsg(MsgString msg);
virtual void setResultMsg(MsgString msg1,
MsgString msg2);
virtual void setResultMsg(MsgString msg1,
MsgString msg2,
MsgString msg3);
//将msg设置到fResultMsgBuffer,支持_WIN32_WCE的平台会将err代表的错误消息也加入
virtual void setResultErrMsg(MsgString msg, int err = 0);
//将msg拷贝到fResultMsgBuffer可用部分,剩余空间不够时,只拷贝部分
virtual void appendToResultMsg(MsgString msg);
////将fResultMsgBuffer中的内容写入到标准错误
virtual void reportBackgroundError(); protected:
BasicUsageEnvironment0(TaskScheduler& taskScheduler);
virtual ~BasicUsageEnvironment0(); private:
void reset(); //截空buffer字符串(首元素置'\0') //消息处理结果缓冲
char fResultMsgBuffer[RESULT_MSG_BUFFER_MAX];
unsigned fCurBufferSize; //当前buffer已用大小
unsigned fBufferMaxSize; //最大buffer大小
};

BasicUsageEnvironment0构造析构与重置

把这三个放在一起,因为其内容很少。
构造的时候调用了基类UsageEnvironment的构造,并把fBufferMaxSize(buffer最大尺寸)的值设置为fResultMsgBuffer数组的大小(见宏定义#define RESULT_MSG_BUFFER_MAX 1000)并调用reset重置buffer

reset方法用于重置buffer(这里说的buffer都代指fResultMsgBuffer字符串),其将fResultMsgBuffer的首元素置为’\0’,也就是将其截空。

BasicUsageEnvironment0::BasicUsageEnvironment0(TaskScheduler& taskScheduler)
: UsageEnvironment(taskScheduler),
fBufferMaxSize(RESULT_MSG_BUFFER_MAX) {
reset();
} BasicUsageEnvironment0::~BasicUsageEnvironment0() {
} void BasicUsageEnvironment0::reset() {
fCurBufferSize = 0;
fResultMsgBuffer[fCurBufferSize] = '\0';
}

ResultMsg系列方法

ResultMsg系列方法是指一系列fResultMsgBuffer进行操作的方法,包括get/set/append/report等多个。这些方法都在基类UsageEnvironment中声明,这里对其进行了实现。注意,这些接口都是public权限的,理应对参数进行判断。后面介绍的时候会提到一些方法中没有对参数的合法性进行判断。

getResultMsg() const方法(获取buffer)

getResultMsg方法是一个const方法,不会对对象有写操作。其返回fResultMsgBuffer数组的首地址。fResultMsgBuffer数组这里再提一下,其是一个char类型的数组,从变量名上理解,是用于保存处理消息结果。

char const* BasicUsageEnvironment0::getResultMsg() const {
return fResultMsgBuffer;
}

appendToResultMsg方法(添加msg到buffer)

appendToResultMsg方法用与向buffer中添加内容。参数msg是标识一个char*字符串。注意,这里没有判断msg是否为NULL是一个bug。因为strlen(NULL)以及memmove(dest,NULL,len)的后果是未定义的。

如果buffer中剩余的可用空间容不下msg的全部内容,那么会拷贝msg中的部分内容,将buffer填满。

void BasicUsageEnvironment0::appendToResultMsg(MsgString msg) {
char* curPtr = &fResultMsgBuffer[fCurBufferSize];
unsigned spaceAvailable = fBufferMaxSize - fCurBufferSize;
unsigned msgLength = strlen(msg); // Copy only enough of "msg" as will fit:
// fResultMsgBuffer剩余空间不够放,拷贝一部分
if (msgLength > spaceAvailable-1) {
msgLength = spaceAvailable-1;
}
/* memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够
保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标
区域与源区域没有重叠则和memcpy函数功能相同。*/
memmove(curPtr, (char*)msg, msgLength);
fCurBufferSize += msgLength;
fResultMsgBuffer[fCurBufferSize] = '\0'; //这个必须有
}

setResultMsg方法(重置buffer内容为msg)

setResultMsg用于重置buffer内容。它将其内容重新设置为参数msg(msg1-3)的内容。

setResultMsg有多个重载形式,区别在于参数个数不一致。这里提一下,C++的重载就是以参数不同为依据的。在这多个重载中都使用到了appendToResultMsg方法,也就继承了没有判断参数合法性的bug。

// 调用reset将消息结果buffer截空,再将msg拷贝到buffer
void BasicUsageEnvironment0::setResultMsg(MsgString msg) {
reset();
appendToResultMsg(msg);
}
void BasicUsageEnvironment0::setResultMsg(MsgString msg1, MsgString msg2) {
setResultMsg(msg1);
appendToResultMsg(msg2);
}
void BasicUsageEnvironment0::setResultMsg(MsgString msg1, MsgString msg2,
MsgString msg3) {
setResultMsg(msg1, msg2);
appendToResultMsg(msg3);
}

setResultErrMsg方法(重置buffer内容为msg/err)

setResultErrMsg方法有两个参数,msg参数用于重置buffer内容。

err参数在windows(WIN32/WINCE)平台会使用到,如果err为0,那么会调用getError(),这个方法在派生类BasicUsageEnvironment中实现。在windows相关平台其return WSAGetLastError()也就是该线程进行的上一次Windows Sockets API函数调用时的错误代码。如果是其他平台,直接返回errno。这里说了,在非windows平台是不会调用的。如果err不为0 ,会之间调用strerror(err)获取错误描述字符串添加到buffer

void BasicUsageEnvironment0::setResultErrMsg(MsgString msg, int err) {
setResultMsg(msg); #ifndef _WIN32_WCE
appendToResultMsg(strerror(err == 0 ? getErrno() : err));
#endif
}

reportBackgroundError方法(报告错误消息)

reportBackgroundErrorbuffer中的内容输出到标准错误。这里很简单,要提的一点是,stderr无缓冲的的输出流,写入的数据直接送入到内核缓冲区。这是C语言的一点基础知识。

//将fResultMsgBuffer中的内容写入到标准错误
void BasicUsageEnvironment0::reportBackgroundError() {
fputs(getResultMsg(), stderr);
}

25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment的更多相关文章

  1. 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment

    24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...

  2. 26 BasicUsageEnvironment基本使用环境——Live555源码阅读(三)UsageEnvironment

    26 BasicUsageEnvironment基本使用环境--Live555源码阅读(三)UsageEnvironment 26 BasicUsageEnvironment基本使用环境--Live5 ...

  3. 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  4. 12 哈希表相关类——Live555源码阅读(一)基本组件类

    12 哈希表相关类--Live555源码阅读(一)基本组件类 这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 ...

  5. 10 DelayQueue 延时队列类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 www.cnblogs.com/oloroso/ 本文由乌合 ...

  6. 13 HashTable抽象哈希表类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  7. 11 AlarmHandler定时处理类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  8. 9 DelayQueueEntry 延时队列节点类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  9. 8 延时队列相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

随机推荐

  1. JavaWeb学习笔记——开发动态WEB资源(六)ServletConfig和ServletContext

    1.只有在第一次请求服务器产生实例的时候才会调用init()方法,有一种办法能在服务器一启动的时候就加载init()方法. 即服务器启动即加载Servlet,且按数字大小顺序实例化Servlet. 方 ...

  2. C# unmanaged function pointers for iOS

    C# unmanaged function pointers for iOS Just a reminder to myself when I need this thing next time fo ...

  3. XtraFinder在OSX10.11的使用

    重启系统,按住command键加上R键 进入恢复模式还是什么模式里,然后启动terminal 然后键入 csrutil enable --without debug 重启电脑,可正常使用 居然上传不了 ...

  4. Redis-cluster集群【第二篇】:redis持久化

    Redis持久化原理: Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot).AOF ...

  5. border opacity

    div { border: 1px solid rgb(127, 0, 0); border: 1px solid rgba(255, 0, 0, .5); -webkit-background-cl ...

  6. smarty string_format用法 取小数点后2位

    <{if $d.ul_pv}> <{$d.sum/$d.ul_pv|string_format:'%.2f'}> <{else}> 0.00 <{/if}&g ...

  7. embed 层级太高

    它怎么就好了,凭什么就好了.为什么就好了.我到底当时是哪里写错了.怎么个情况 兼容Firefox ,IE的flash透明和flash置底代码 <object classid="clsi ...

  8. 你真的懂了R中的stem函数是如何绘制茎叶图的么?

    本文原创,转载请注明出处,本人Q1273314690(交流学习)   哭晕 你真的学会了stem()函数了吗? stem()函数的使用方法是: stem(x, scale=1,width=80, at ...

  9. VPN和SSH的原理区别

    原文:http://www.hostloc.com/thread-153223-1-1.html 看了http://www.hostloc.com/thread-153166-1-1.html 主要说 ...

  10. 微信 6.5.1 for iOS发布 可以在朋友圈分享相册中的视频

    今天微信 6.5.1 for iOS发布了,最主要的一个功能是可以在朋友圈分享相册中的视频,卖转发朋友圈视频软件的家伙估计要哭了.微信这次更新,更有利于个人号的运营,个人号的价值将更高.先定一个小目标 ...