zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    hdu1238 Substrings
    CCF试题:高速公路(Targin)
    hdu 1269 迷宫城堡(Targin算法)
    hdu 1253 胜利大逃亡
    NYOJ 55 懒省事的小明
    HDU 1024 Max Sum Plus Plus
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1257 最少拦截系统
    HDU 1069 Monkey and Banana
    HDU 1104 Remainder
  • 原文地址:https://www.cnblogs.com/oloroso/p/4609400.html
Copyright © 2011-2022 走看看