OpenRTMFP/Cumulus Primer(16)AMF解析之AMFReader
OpenRTMFP/Cumulus Primer(16)AMF解析之AMFReader
- Author: 柳大·Poechant(鍾超)
- Email: zhongchao.ustc#gmail.com (#->@)
- Blog:Blog.CSDN.net/Poechant
- Date: April 24th, 2012
1 ObjectDef
class ObjectDef {
public:
ObjectDef(UInt32 amf3,UInt8 arrayType=0)
: amf3(amf3),
reset(0),
dynamic(false),
externalizable(false),
count(0),
arrayType(arrayType) {
}
list<string> hardProperties;
UInt32 reset;
bool dynamic;
bool externalizable;
UInt32 count;
UInt8 arrayType;
const UInt32 amf3;
};
2 AMFReader 定義
其中 PacketReader 作為其成員。
class AMFReader {
public:
AMFReader(PacketReader& reader);
~AMFReader();
void readSimpleObject(AMFSimpleObject& object);
void read(std::string& value);
double readNumber();
Poco::Int32 readInteger();
bool readBoolean();
BinaryReader& readByteArray(Poco::UInt32& size);
Poco::Timestamp readDate();
bool readObject(std::string& type);
bool readArray();
bool readDictionary(bool& weakKeys);
AMF::Type readKey();
AMF::Type readValue();
AMF::Type readItem(std::string& name);
BinaryReader& readRawObjectContent();
void readNull();
AMF::Type followingType();
bool available();
void startReferencing();
void stopReferencing();
PacketReader& reader;
private:
void readString(std::string& value);
Poco::UInt8 current();
void reset();
std::list<ObjectDef*> _objectDefs;
std::vector<Poco::UInt32> _stringReferences;
std::vector<Poco::UInt32> _classDefReferences;
std::vector<Poco::UInt32> _references;
std::vector<Poco::UInt32> _amf0References;
Poco::UInt32 _amf0Reset;
Poco::UInt32 _reset;
Poco::UInt32 _amf3;
bool _referencing;
};
2.1 建構函式、解構函式
引數為 PacketReader,會初始化一些成員變數。
AMFReader::AMFReader(PacketReader& reader)
: reader(reader),
_reset(0),
_amf3(0),
_amf0Reset(0),
_referencing(true) {
}
析構時,會逐一釋放 _objectDefs 中物件的記憶體:
AMFReader::~AMFReader() {
list<ObjectDef*>::iterator it;
for (it = _objectDefs.begin(); it!=_objectDefs.end(); ++it)
delete *it;
}
2.2 簡單封裝 PacketReader 的一些函式
-
reset:操作指標位置
void AMFReader::reset() { if (_reset > 0) { reader.reset(_reset); _reset = 0; } }
-
available:根據當前緩衝區大小和 written 計算得到
bool AMFReader::available() { reset(); return reader.available() > 0; }
-
current:gptr 記憶體地址
inline Poco::UInt8 AMFReader::current() { return *reader.current(); }
2.3 設定 gptr 位置
其實 pptr 也被影響了,但是在 AMFReader 中只用 gptr。呼叫建構函式的時候,reset 被設為 0,其後在每次讀取資料的時候都會影響reset。
void AMFReader::reset() {
if(_reset>0) {
reader.reset(_reset);
_reset=0;
}
}
2.4 判斷型別
分析請看註釋:
AMF::Type AMFReader::followingType() {
先 reset:
reset();
if (_amf3 != reader.position()) {
if (_objectDefs.size() > 0)
_amf3 = _objectDefs.back()->amf3;
是 AMF0 型別:
else
_amf3 = 0;
}
如果沒有可讀資料了,則返回 AMF::End。
if (!available())
return AMF::End;
開始讀了,先讀到的表示 AMF 資料型別。要注意的是呼叫 current 並不改變指標的位置,所以你會線上面看到呼叫 next。
UInt8 type = current();
if (!_amf3 && type == AMF_AVMPLUS_OBJECT) {
reader.next(1);
_amf3 = reader.position();
if(!available())
return AMF::End;
type = current();
}
AMF3 型別
if (_amf3) {
switch(type) {
Undefined 和 null 都當做 null。
case AMF3_UNDEFINED:
case AMF3_NULL:
return AMF::Null;
false 和 true 都是 boolean。
case AMF3_FALSE:
case AMF3_TRUE:
return AMF::Boolean;
case AMF3_INTEGER:
return AMF::Integer;
case AMF3_NUMBER:
return AMF::Number;
case AMF3_STRING:
return AMF::String;
case AMF3_DATE:
return AMF::Date;
case AMF3_ARRAY:
return AMF::Array;
case AMF3_DICTIONARY:
return AMF::Dictionary;
case AMF3_OBJECT:
return AMF::Object;
case AMF3_BYTEARRAY:
return AMF::ByteArray;
落到 default 手裡的話,就跳過這個位元組,讀取下一個。
default:
ERROR("Unknown AMF3 type %.2x",type)
reader.next(1);
return followingType();
}
}
AMF0 型別
switch (type) {
undefined 和 null 都是 null
case AMF_UNDEFINED:
case AMF_NULL:
return AMF::Null;
case AMF_BOOLEAN:
return AMF::Boolean;
case AMF_NUMBER:
return AMF::Number;
long string 和 string 都是 string
case AMF_LONG_STRING:
case AMF_STRING:
return AMF::String;
mixed array 和 strict array 都是 array
case AMF_MIXED_ARRAY:
case AMF_STRICT_ARRAY:
return AMF::Array;
case AMF_DATE:
return AMF::Date;
begin object 和 begin typed object 都是 object
case AMF_BEGIN_OBJECT:
case AMF_BEGIN_TYPED_OBJECT:
return AMF::Object;
如果是引用,就跳過表示型別值的這個位元組。這個先留下來,帶我們分析完 readArray 和 readObject 再回頭看。
case AMF_REFERENCE: {
reader.next(1);
UInt16 reference = reader.read16();
if (reference > _amf0References.size()) {
ERROR("AMF0 reference not found")
return followingType();
}
_amf0Reset = reader.position();
reader.reset(_amf0References[reference]);
return followingType();
}
如果沒了,或者不支援,或者都不是,就跳過這個位元組,遞迴繼續讀取:
case AMF_END_OBJECT:
ERROR("AMF end object type without begin object type before")
reader.next(1);
return followingType();
case AMF_UNSUPPORTED:
WARN("Unsupported type in AMF format")
reader.next(1);
return followingType();
default:
ERROR("Unknown AMF type %.2x",type)
reader.next(1);
return followingType();
}
}
followingType 是這個類的核心,每個具體的資料型別的分析都依賴於它的判斷。這些型別的解析,會在下一篇文章中介紹。
-
轉載請註明來自柳大的CSDN部落格:Blog.CSDN.net/Poechant
-
相關文章
- OpenRTMFP/Cumulus Primer(18)AMF解析之AMFReader(續2)
- OpenRTMFP/Cumulus Primer(17)AMF解析之AMFReader(續1)
- OpenRTMFP/Cumulus Primer(14)AMF解析之PacketReader/Writer
- OpenRTMFP/Cumulus Primer(9)AMF解析之BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(15)AMF解析之資料型別定義資料型別
- OpenRTMFP/Cumulus Primer(9)AMF 處理方式解析——BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(4)CumulusServer啟動流程分析Server
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續)Server
- OpenRTMFP/Cumulus Primer(13)IO管理之區域性記憶體片記憶體
- OpenRTMFP/Cumulus Primer(8)CumulusServer主程式主迴圈分析Server
- OpenRTMFP/Cumulus Primer(6)CumulusServer啟動流程分析(續2)Server
- OpenRTMFP/Cumulus Primer(7)CumulusServer啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續1)Server
- OpenRTMFP/Cumulus Primer(1)入門介紹與部署CumulusServerServer
- OpenRTMFP/Cumulus Primer(7)CumulusServer 啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(2)用Lua編寫HelloWorld應用擴充套件CumulusServer套件Server
- OpenRTMFP/Cumulus Primer(19)獨立使用CumulusLib時的執行緒安全Bug執行緒
- OpenRTMFP/Cumulus Primer(21)經由伺服器的釋出/訂閱流程的關鍵點伺服器
- OpenRTMFP/Cumulus Primer(23)執行緒邏輯分析之二:RTMFPManager對RTMFPServer的影響執行緒Server
- OpenRTMFP/Cumulus Primer(22)執行緒邏輯分析之一:RTMFPServer執行緒的啟動和等待執行緒Server
- AMF解析遇上XXE,BurpSuite也躺槍UI
- C++ Primer 課後習題解析C++
- c++ primer 之stringC++
- c++_primer之第四章C++
- 《C++ Primer Plus》16.1 string類 學習筆記C++筆記
- 新手入門AMF協議基礎全解協議
- c primer plue 第 16 章 C前處理器和C庫 筆記筆記
- A Hadoop PrimerHadoop
- ORACLE SQL解析之硬解析和軟解析OracleSQL
- Nginx(六):配置解析之location解析Nginx
- CMU15445 之 Project#0 - C++ Primer 詳解ProjectC++
- 【Go學習筆記16】解析xmlGo筆記XML
- xml解析之domXML
- MuJoCo解析之 mjData
- TS流解析之PMT表格解析(轉)
- TS流解析之PAT表格解析(轉)
- TS流解析之TS包頭解析(轉)
- C++ Primer Plus(四)C++