前一篇文字http://blog.csdn.net/linyanwen99/article/details/8627430敘述了PacketReader類的部分方法的最佳化,
這節繼續敘述PacketWriter類的部分方法的最佳化
一.PacketWriter.h的定義如下:
#pragma once
#include "Cumulus.h"
#include "MemoryStream.h"
#include "BinaryWriter.h"
#define PACKETSEND_SIZE 1215
namespace Cumulus {
class PacketWriter: public BinaryWriter {
public:
PacketWriter(const Poco::UInt8* buffer,Poco::UInt32 size);
PacketWriter(PacketWriter&);
Poco::UInt8* begin();
Poco::UInt32 position();
void next(Poco::UInt32 size);
public:
void write8(Poco::UInt8 value);
void write16(Poco::UInt16 value);
void write32(Poco::UInt32 value);
void write7BitValue(Poco::UInt32 value);
void write7BitLongValue(Poco::UInt64 value);
void writeAddress(const Address& address,bool publicFlag);
void writeAddress(const Poco::Net::SocketAddress& address,bool publicFlag);
void writeRaw(const Poco::UInt8* value,Poco::UInt32 size);
void writeRaw(const char* value,Poco::UInt32 size);
void writeRaw(const std::string& value);
void writeString8(const std::string& value);
void writeString8(const char* value,Poco::UInt8 size);
void writeString16(const std::string& value);
void writeString16(const char* value,Poco::UInt16 size);
private:
MemoryOutputStream _memory;
PacketWriter* _pOther;
Poco::UInt32 _size;
};
inline Poco::UInt32 PacketWriter::position() {
return _wppos;//_wppos即寫指標的位置
}
inline Poco::UInt8* PacketWriter::begin() {
return (Poco::UInt8*)_memory._buf._pBuffer;
}
inline void PacketWriter::next(Poco::UInt32 size){
_wgpos += size;//_wgpos即讀指標的位置
_wppos += size;
return _memory.next(size);
}
} // namespace Cumulus
二.PacketWriter.cpp的實現,如下:
#include "PacketWriter.h"
#include "Util.h"
#include "Logs.h"
using namespace std;
using namespace Poco;
using namespace Poco::Net;
namespace Cumulus {
PacketWriter::PacketWriter(const UInt8* buffer,UInt32 size) : _memory((char*)buffer,size),BinaryWriter(_memory),_pOther(NULL),_size(size) {
}
// Consctruction by copy
PacketWriter::PacketWriter(PacketWriter& other) : _pOther(&other),_memory(other._memory),BinaryWriter(_memory),_size(other._size) {
}
void PacketWriter::write8(Poco::UInt8 value){
*(_memory._buf._pBuffer+_wppos) = value;//直接把該位元組寫入buffer
_wppos += 1;
_memory._buf.ppPbump(1);
}
void PacketWriter::write16(Poco::UInt16 value){
value = htons(value);//轉為網路位元組序
memcpy(_memory._buf._pBuffer+_wppos,&value,2);
_wppos += 2;
_memory._buf.ppPbump(2);
}
void PacketWriter::write32(Poco::UInt32 value){
value = htonl(value);//轉為網路位元組序
memcpy(_memory._buf._pBuffer+_wppos,&value,4);
_wppos += 4;
_memory._buf.ppPbump(4);
}
void PacketWriter::write7BitValue(UInt32 value) {
UInt8 shift = (Util::Get7BitValueSize(value)-1)*7;//參考amf3資料格式以便理解
bool max = false;
if(shift>=21) { // 4 bytes maximum
shift = 22;
max = true;
}
while(shift>=7) {
write8(0x80 | ((value>>shift)&0x7F));
shift -= 7;
}
write8(max ? value&0xFF : value&0x7F);
}
void PacketWriter::write7BitLongValue(UInt64 value) {//與rtmfp協議相關的一些東西
UInt8 shift = (Util::Get7BitValueSize(value)-1)*7;
bool max = shift>=63; // Can give 10 bytes!
if(max)
++shift;
while(shift>=7) {
write8(0x80 | ((value>>shift)&0x7F));
shift -= 7;
}
write8(max ? value&0xFF : value&0x7F);
}
void PacketWriter::writeAddress(const Address& address,bool publicFlag) {
UInt8 flag = publicFlag ? 0x02 : 0x01;
if(address.host.size()==16) // IPv6
flag |= 0x80;
write8(flag);
for(int i=0;i<address.host.size();++i)
write8(address.host[i]);
write16(address.port);
}
void PacketWriter::writeAddress(const SocketAddress& address,bool publicFlag) {
UInt8 flag = publicFlag ? 0x02 : 0x01;
UInt8 size = 4;
IPAddress host = address.host();
if(host.family() == IPAddress::IPv6) {
flag |= 0x80;
size = 16;
}
const UInt8* bytes = reinterpret_cast<const UInt8*>(host.addr());
write8(flag);
for(int i=0;i<size;++i)
write8(bytes[i]);
write16(address.port());
}
void PacketWriter::writeRaw(const UInt8* value,UInt32 size){
writeRaw((char*)value,size);
}
void PacketWriter::writeRaw(const char* value,UInt32 size){//函數的功能即把size大小的位元組數直接寫入buffer,以下方法類似
for(int i=0;i<size;++i)
*(_memory._buf._pBuffer+_wppos+i) = *(value+i);
_wppos += size;
_memory._buf.ppPbump(size);
}
void PacketWriter::writeRaw(const std::string& value){
int size = (int)value.length();
char* ptr = (char*)value.data();
for(int i=0;i<size;++i)
*(_memory._buf._pBuffer+_wppos+i) = *(ptr+i);//直接對buffer進行操作
_wppos += size; //_wppos進行對應的位移
_memory._buf.ppPbump(size);
}
void PacketWriter::writeString8(const char* value,UInt8 size){
write8(size);
writeRaw(value,size);
}
void PacketWriter::writeString8(const string& value){
write8(value.size());
writeRaw(value);
}
void PacketWriter::writeString16(const char* value,UInt16 size){
write16(size);
writeRaw(value,size);
}
void PacketWriter::writeString16(const string& value){
write16(value.size());
writeRaw(value);
}
} // namespace Cumulus
轉載請註明出處:山水間部落格,http://blog.csdn.net/linyanwen99/article/details/8643428