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


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

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

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

    简介

    BasicUsageEnvironment0实现了其基类UsageEnvironment的部分纯虚接口(只有部分,其还是一个抽象类),并添加了三个数据成员。其定义在live555sourcecontrolBasicUsageEnvironmentincludeBasicUsageEnvironment0.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字符串(首元素置'')
    
        //消息处理结果缓冲
        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的首元素置为’’,也就是将其截空。

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

    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] = '';  //这个必须有
    }
    

    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);
    }
    
  • 相关阅读:
    JSOUP 简单爬取网页
    RSS 实体清单
    [转载]从零开始学习OpenGL ES之四 – 光效
    [转载]从零开始学习OpenGL ES之四补遗 – setupView重写
    [转载]Xcode创建的默认iOS OpenGL ES 2.0 project代码分析
    [转载]从零开始学习OpenGL ES之八 – 交叉存取顶点数据
    [转载]从零开始学习OpenGL ES之十 – 完结
    [转载]从零开始学习OpenGL ES之五 – 材质
    [转载]从零开始学习OpenGL ES之六 – 纹理及纹理映射
    [转载]从零开始学习OpenGL ES之九(上) – 动画基础和关键帧动画
  • 原文地址:https://www.cnblogs.com/oloroso/p/4609400.html
Copyright © 2020-2023  润新知