OpenRTMFP/Cumulus开发笔记(2) Cumulus相关AMF数据的解析

来源:互联网 发布:企业网络管理 编辑:程序博客网 时间:2024/04/29 22:22

一.DataContainer.h:

#ifndef DATA_CONTAINER_H

#define DATA_CONTAINER_H

#include <vector>

#include <Poco/Any.h>

class DataContainer{

public:

   static const DataContainer EmptyContainer;

       voidpush(Poco::Any any);

       Poco::Anyget(int index);

       size_tsize();

private:

       std::vector<Poco::Any>_vector;

};

inline void DataContainer::push(Poco::Anyany){

       _vector.push_back(any);

}

inline Poco::Any DataContainer::get(intindex){

       if(index< size()){

              return_vector[index];

       }else{

              return0;

       }

}

inline size_t DataContainer::size(){

       return_vector.size();

}

#endif        


二.DataAuxiliary.h:

#ifndefDATA_AUXILIARY_H

#defineDATA_AUXILIARY_H

#include"DataContainer.h"

#include<Poco/Types.h>

using namespacePoco;

classDataAuxiliary{

public:

                  static boolgetBool(DataContainer& container,int index);

                  static intgetInt(DataContainer& container,int index);

                  static UInt64getUInt64(DataContainer& container,int index);

                  static UInt32getUInt32(DataContainer& container,int index);

                  static UInt16getUInt16(DataContainer& container,int index);

                  static DataContainergetContainer(DataContainer& container,int index);

                  static std::stringgetString(DataContainer& container,int index);

private:

                  DataAuxiliary(){}

};

#endif


三.DataAuxiliary.cpp:

#include"DataAuxiliary.h"

#include<Poco/Exception.h>

boolDataAuxiliary::getBool(DataContainer& container,int index){

    try{

        returnAnyCast<bool>(container.get(index));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    return false;

}

intDataAuxiliary::getInt(DataContainer& container,int index){

   try{

        returnstatic_cast<int>(AnyCast<double>(container.get(index)));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    return 0;

}

Poco::UInt32DataAuxiliary::getUInt32(DataContainer& container,int index){

   try{

        returnstatic_cast<Poco::UInt32>(AnyCast<double>(container.get(index)));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    return 0;

}

Poco::UInt16DataAuxiliary::getUInt16(DataContainer& container,int index){

   try{

        return static_cast<Poco::UInt16>(AnyCast<double>(container.get(index)));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    return 0;

}

std::stringDataAuxiliary::getString(DataContainer& container,int index){

    try{

        return AnyCast<std::string>(container.get(index));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    std::string empty =std::string("");

    return empty;

}

DataContainerDataAuxiliary::getContainer(DataContainer& container,int index){

    try{

        return AnyCast<DataContainer>(container.get(index));

    }catch(Poco::BadCastException& e){

        throw e;

    }

    return DataContainer::EmptyContainer;

}


四.AMFReaderParser.h:

#ifndefCLIENT_REQUESTER_H

#defineCLIENT_REQUESTER_H

#include"DataContainer.h"

#include"AMFReader.h"

usingCumulus::AMFReader;

usingCumulus::AMF;

usingPoco::UInt32;

namespace Proxy{

    class AMFReaderParser{

        public:

            static void parseAMF(DataContainer&container, AMFReader& reader, UInt32 count);

            static void parseAMF(DataContainer&container, AMF::Type type, AMFReader& reader);

        private:

            AMFReaderParser(){}

    };

}//namespace

#endif


五.AMFReaderParser.cpp:

#include"AMFReaderParser.h"

#include<string>

#include<iostream>

#include<Poco/Any.h>

using std::string;

using namespacePoco;

namespace Proxy{

    voidAMFReaderParser::parseAMF(DataContainer& container, AMFReader& reader,UInt32 count){

       std::cout<<"parseAMF"<<std::endl;

        AMF::Type type;

        bool all = (count == 0);

        if(all){

            count = 1;

        }

        while(count > 0 && (type =reader.followingType()) != AMF::End){

            parseAMF(container, type, reader);

            if(!all){

                --count;

            }

        }

    }

    void AMFReaderParser::parseAMF(DataContainer&container, AMF::Type type, AMFReader& reader){

        std::cout << "switchtype"<<std::endl;

        switch(type){

            case AMF::Null:{

                 std::cout <<"AMF::Null"<<std::endl;

                 reader.readNull();

                container.push(Poco::Any(std::string("")));

                 break;

            }

            case AMF::String:{

                 std::cout <<"AMF::String"<<std::endl;

                 string value;

                 reader.read(value);

                container.push(Poco::Any(value));

                 break;

            }

            case AMF::ByteArray:{

                 std::cout <<"AMF::ByteArray"<<std::endl;

                 UInt32 size;

                 reader.readByteArray(size);

                 string tmp;

                tmp.assign((char*)reader.reader.current(), size);

                container.push(Poco::Any(tmp));

                 reader.reader.next(size);

                 break;

            }

            case AMF::Integer:{

                 std::cout <<"AMF::Integer"<<std::endl;

                 container.push(Poco::Any(reader.readInteger()));

                 break;

            }

            case AMF::Number:{

                 std::cout <<"AMF::Number"<<std::endl;

                 container.push(reader.readNumber());

                 break;

            }

            case AMF::Boolean:{

                 std::cout <<"AMF::Boolean"<<std::endl;

                container.push(Poco::Any(reader.readBoolean()));

                 break;

            }

            case AMF::Object:{

                 std::cout <<"AMF::Object"<<std::endl;

                 string objectType;

                 string name;

                if(reader.readObject(objectType)){

                     DataContainer subContainer;

                     while((type =reader.readItem(name)) != AMF::End && type != AMF::RawObjectContent){

                         parseAMF(subContainer,type, reader);

                     }

                     container.push(Poco::Any(subContainer));

                 }

                 break;

            }

            default:

                 reader.reader.next(1);

                 std::cout << "Unknown AMFType" << std::endl;

                 break;

        }

    }

}//namespace

六.在Server.cpp中解析客户端传递过来的参数,如下:

bool Server::onMessage(Client& client,const string& name,AMFReader& reader) {
    std::cout<<"onMessage"<<std::endl;
    DataContainer params;
    AMFReaderParser::parseAMF(params,reader,0);
    int uriType = Poco::NumberParser::parse(name);
    std::cout<<"uriType:"<<uriType<<std::endl;
    Poco::UInt32 uid = DataAuxiliary::getUInt32(params, 0);//uid
    Poco::UInt32 sid = DataAuxiliary::getUInt32(params, 1);//sid
    std::string cookie = DataAuxiliary::getString(params, 2);//cookie
    std::cout << "uid->"<<uid<<std::endl;
    std::cout << "sid->"<<sid<<std::endl;
    std::cout << "cookie->"<<cookie<<std::endl;
    return true;
}

顺利的话,会正确解析并输出客户端传递过来的相关参数!


参考文档:http://blog.csdn.net/poechant/article/details/7700589

PS:初写文章,文笔生涩之处,各位请见谅,若有疑问或者交流的,可加本人YY号:301558660

转载请注明出处:山水间博客http://blog.csdn.net/linyanwen99/article/details/8127672

 

 

 


原创粉丝点击