DSP序列化反序列化对象SDK开发包
DSP(Dynamic Serialize Packet)是一个动态序列化和反序列化对象的SDK开发包,使用DSP可以将对象序列化成数据流保存到文件中,或者将序列化后的数据流通过Socket传递给远端;也可以使用DSP从文件或Socket中读取数据,然后反序列化成对象。
DSP和VC++的序列化、Java的序列化有着本质的区别,比VC++和Java的序列化对象具有更好的控制性,DSP提供了对象标准的序列化方式,可以将对象的数据以数据流的方式传递,不管发送方是Java还是C++,也不论接收方是C++还是Java,或是其它的语言,数据流都可以被正确地还原成相应的对象。(当前的DSP采用纯C++语言开发,以后将陆续地提供其它语言的SDK开发包,在适当地时候,我会提供所有的源代码)
DSP在反序列化对象时,可以反序列化数据流成为序列化时的对象,如果序列化时的对象注册过,则可以将数据流反序列化成序列化对象的最接近的一个基类。
DSP采用阻塞方式序列化和反序列化对象,实时地传送或接收序列化后的数据到Socket或文件中,不需要经过缓冲区拷贝,大大地提高了序列化和反序列化的速度。
DSP采用二进制数据流方式序列化数据,允许序列化后的数据中包含字符串终结符'\0',因此允许序列化任意的二进制数据、文件、图像缓冲区、音频缓冲区等。
DSP可以传送任意大小的数据,你甚至可以在一个对象中包含一个或多个任意大小的二进制文件,DSP会自动地对数据进行分段传送,并确保数据能正确地被序列化。利用DSP可以序列化任意大小文件的特性,你可以在序列化对象时读取一个文件,通过Socket传送到远端;远端读取Socket数据,在反序列化数据流时,直接将传送的文件保存起来,从而实现P2P或Email中传送多媒体信息的应用。
DSP可以在序列化对象时选择是否进行CRC校验、是否对数据值进行压缩处理,可以自定义压缩处理函数,并且可以指定反序列化对象后自动执行的函数集。
DSP通过多重CRC校验,保证数据不会在传送过程中被修改,为保证数据的安全性,每一类序列化对象都可以自定义压缩处理函数,在压缩处理函数内对数据进行压缩或加密,如果设定了压缩处理函数,DSP会在序列化过程中调用压缩处理函数对数据进行处理,传递压缩函数处理过后的数据;在反序列化过程中,DSP就会调用解压缩处理函数,先将接收到的数据还原,然后将数据保存到对象的相应属性中。
DSP还允许从Socket或文件中读取数据到一个已存在的指定对象中,从而确保只能从数据源得到指定的对象。
DSP可以处理任意多层嵌套对象的序列化和反序列化,即一个可序列化对象可以是另一个可序列化对象的一个属性,并且一个可序列化对象中可以包含任意多个可序列化对象。
DSP反序列化时,对象中的任何一个属性的值被反序列化完成后,都会发出明确的通知,可以在接到该通知后执行任意的代码。
SDK开发包的使用说明
SDK包的内容?
SDK包仅仅包含2个类,一个是DSP类,该类中定义了序列化和反序列化对象时的方法,以及所需要的结构,DSP类不能够被实例化,所有的方法都是静态的,DSP类的实际作用仅仅是定义一个命名空间。
DSP类中包含有两个结构,_DSPPACKET和_DSPERROR。_DSPPACKET结构是序列化和反序列化时必不可少的结构,在序列化和反序列化时需要创建一个该结构的实例,然后调用结构中的方法进行序列化和反序列化操作。序列化操作的WriteObject()方法和反序列化的ReadObject()方法都是该结构中的方法。
_DSPERROR结构中记录了最近一次错误的代码,错误的详述,以及在序列化和反序列化第几个基类的第几个属性时产生了错误。如果调用ReadObject()和WriteObject()返回了一个错误,可以调用_DSPPACKET::GetLastError()返回描述该错误的_DSPERROR结构的指针。
SDK包中的另一个类是DSPACT类,这个类是所有可以被序列化和反序列化的类的基类。
这两个类全部都是采用纯C++语言书写的。
SDK包的附带内容?
SDK包中还带有一个DNS类,该类的主要功能是查询DNS服务器,得到相关的信息,这个类还在完善中。
该类提供了一些较低级的方法来查询DNS服务器,也封装了一个较高级的方法DNS::_DNSPACKET::GetMXHostSet(),该方法会直接查询DNS服务器,并返回包含MX记录的集合,然后可以直接调用另一个较高级的方法DNS::_DNSPACKET::GetMX()得到一个MX记录,重复调用该函数,就可以得到下一个MX记录,一直到读完为止。
这个DNS类比MicroSoft SDK开发包中提供的DnsQuery()方法要简单的多,你只需要创建一个DNS::_DNSPACKET结构的实例,然后调用该实例的GetMXHostSet()方法,传递要查询的域名即可,得到MX记录也只需要调用该实例的GetMXHost()方法,该方法会返回要查询的域名的邮件服务器的hostent结构的指针。
什么对象可以被序列化?
由DSPACT类派生出来的任何一个类,或者说只要一个类的基类是DSPACT类,这个类就可以被序列化。就象VC++的所有可以被序列化的类必需是由CObject类派生出来的,DSP可以被序列化的类也必需是由类DSPACT派生出来的。
什么对象可以被反序列化?
任何由DSPACT类派生出来的类都可以被DSP反序列化,被反序列化的类可以预先调用DSP::RegisterAct()函数注册该类,这样,DSP在反序列化过程时可以动态创建出被注册过的类的对象;如果类没有被注册过,也可以通过在反序列化时传递需要被反序列化的对象的指针,将数据反序列化到指定的对象中。
如何对反序列化对象上溯造型?
反序列化对象是通过调用ReadObject()函数来实现的,函数返回的是指向反序列化后的对象的指针,该指针固定是一个DSPACT对象的指针,如何知道该指针应该上溯造型成哪一个对象的指针呢?可以通过调用DSPACT对象的IsKindOf()方法,传递类名字的字符串指针,该函数会判断该对象是否是指定的类的一个对象,并返回true或false。如果方法返回true,则对象可以被安全地上溯造型为指定的对象。
在调用DSP::RegisterAct()方法注册类时,可以传递一个附加的32位数据值,该值可以是一个结构的指针,也可以是一个DWORD数据(在Window系统中,可以设定成消息的ID)。当对象被反序列化成功后,会返回一个DSPACT对象的指针,这时在_DSPPACKET结构中的属性dwData中保存了该值。
DSP::_DSPPACKET结构说明
类型:属性
定义:timeval Timeout
描述:如果序列化的数据流需要通过Socket来传送,或者反序列化的数据流来自Socket,则该属性有效。
该属性设定了接收或传送时的Socket超时时间,如果Socket超时,则序列化或反序列化失败。
类型:属性
定义:DWORD dwData
描述:在反序列化成功后,该变量内保存了RegisterAct()方法注册类时传递的dwData参数的值。
类型:方法
定义:void Empty()
参数:无
描述:清空_DSPPACKET结构,为下一次反序列化作准备。序列化对象时不需要调用该方法。连续进行反序列化时不需要在每次反序列化前都调用该方法。
类型:方法
定义:inline void SetParameter(BOOL bCompress=FALSE,BOOL bVerifyCRC=TRUE,BYTE byInitType=0)
参数:bCompress -- 是否压缩数据,如果值为TRUE,只有重载DSPACT::Compress()方法才有效。
bVerifyCRC-- 是否进行CRC校验。不进行CRC校验时,执行速度会稍快一些。
byInitType -- 对象反序列化完成后,调用对象的Init()方法时传递的参数。
取值为[0..15],0表示在反序列化完成后,不调用对象的Init()方法。
描述:设置序列化时的参数,一次设置会一直有效,直到重新设置。
类型:方法
定义:inline _DSPERROR* GetLastError()
参数:无
描述:得到最近的一次错误描述
类型:方法
定义:DSPACT* ReadObject(SOCKET sock,DSPACT* pAct=NULL)
参数:sock -- 接收序列化数据的SOCKET
pAct -- 读取一个指定的对象,并将数据读到该对象中。如果值为NULL,表示反序列化为序列化时的对象。
返回:当pAct==NULL时,如果反序列化成功,则返回一个DSPACT的派生类对象的指针。失败时,返回NULL。
当pAct!=NULL时,如果读取的数据反序列化时不是指定的类的对象或反序列化过程失败,则返回NULL。
描述:调用该方法,从SOCKET中读取已序列化的数据,然后反序列化数据流成对象。
注意:反序列化成功时,返回一个对象的指针,该对象在堆中被创建,返回后DSP并没有再保存该对象的指针,因此,必需注意在反序列化成功时,应该接收该指针,在对象使用完后,必需使用delete释放对象的资源。
类型:方法
定义:DSPACT* ReadObject(ifstream& ifs,DSPACT* pAct=NULL)
参数:ifs -- 保存有序列化数据的ifstream对象
pAct -- 读取一个指定的对象,并将数据读到该对象中。如果值为NULL,表示反序列化为序列化时的对象。
返回:当pAct==NULL时,如果反序列化成功,则返回一个DSPACT的派生类对象的指针。失败时,返回NULL。
当pAct!=NULL时,如果读取的数据反序列化时不是指定的类的对象,则返回NULL。
描述:调用该方法,将从文件输入流中读取已序列化的数据,然后反序列化数据流成对象。
注意:反序列化成功时,返回一个对象的指针,该对象在堆中被创建,返回后DSP并没有再保存该对象的指针,因此,必需注意在反序列化成功时,应该接收该指针,在对象使用完后,必需使用delete释放对象的资源。
类型:方法
定义:bool WriteObject(SOCKET sock,DSPACT* const pAct)
参数:sock -- 传送序列化数据的SOCKET
pAct -- 需要序列化的对象的指针,值不可以为NULL。
返回:true -- 序列化并且传送序列化数据成功;
false -- 序列化过程或传送序列化数据时发生了错误,调用GetLastError()可以得到错误描述。
描述:调用该方法,将序列化指定的对象,然后通过SOCKET传送序列化后的数据,序列化和传送是一个阻塞的过程。
类型:方法
定义:bool WriteObject(ofstream& ofs,DSPACT* const pAct)
参数:ofs -- 记录序列化数据的ofstream对象
pAct -- 需要序列化的对象的指针,值不可以为NULL。
返回:true -- 序列化并且传送序列化数据成功;
false -- 序列化过程或传送序列化数据时发生了错误,调用GetLastError()可以得到错误描述。
描述:调用该方法,将序列化指定对象后的数据记录在ofstream对象所打开的文件中。
类型:方法
定义:bool Read(char& attr)
参数:attr -- 一个字符型变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的char型变量中
类型:方法
定义:bool Read(BYTE& attr)
参数:attr -- 一个无符号字符型变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的BYTE型变量中
类型:方法
定义:bool Read(short& attr)
参数:attr -- 一个双字节有符号变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的short型变量中
类型:方法
定义:bool Read(WORD& attr)
参数:attr -- 一个双字节无符号型变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的WORD型变量中
类型:方法
定义:bool Read(int& attr)
参数:attr -- 一个4字节有符号变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的int型变量中
类型:方法
定义:bool Read(DWORD& attr)
参数:attr -- 一个4字节无符号变量。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的DWORD型变量中
类型:方法
定义:bool Read(bool& attr)
参数:attr -- 一个bool型变量
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的布尔型变量中
类型:方法
定义:bool Read(std::string& attr,DWORD nLen)
参数:attr -- 一个string型字符串变量。
nLen -- 反序列化的属性的长度,这个长度值是UnSerialize()方法的参数。
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的字符串变量中
类型:方法
定义:bool Read(char* const pAttr,DWORD nLen)
参数:attr -- 一个指向字符型缓冲区指针
nLen -- 缓冲区的长度,这个长度是缓冲的实际长度,不是UnSerialize()方法的参数
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的二进制流缓冲区变量中
类型:方法
定义:bool Read(DSPACT& attr)
参数:attr -- 一个基类为DSPACT的类的对象
返回:true -- 反序列化属性值已经完成,属性的值已经被记录到变量中。
false -- 反序列化属性值还没有完成,属性的值不可用。
描述:反序列化数据到对象中的一个DSPACT派生类的变量中
类型:方法
定义:void Write(int attr)
参数:attr -- 一个整型的数值型的值
描述:序列化属性中的整型变量,包括int、DWORD、short、WORD、BYTE、char、BOOL类型的变量
类型:方法
定义:void Write(bool attr)
参数:attr -- 一个布尔型的数值
描述:序列化属性中的布尔型的变量
类型:方法
定义:void Write(const std::string& attr)
参数:attr -- 一个string类型的字符串型变量
描述:序列化属性中的字符串类型的变量
类型:方法
定义:void Write(char* const pAttr,DWORD nLen,bool bLast=true)
参数:pAttr -- 一个指向字符型缓冲区的指针
nLen -- 缓冲区的长度
bLast -- 是否为普通缓冲区。
值为true时,表示为普通缓冲区。
值为false时,表示是多段缓冲区;
如果缓冲区为多段缓冲区,则缓冲区中的数据在调用对象的AttrSectRecv()方法时填充;
如果缓冲区不为普通缓冲区,则当前保存在缓冲区中的数据就是要被序列化的数据。
描述:序列化属性中的二进制流缓冲区
类型:方法
定义:void Write(DSPACT* const pAttr,BOOL bCompress=FALSE,BOOL bVerifyCRC=TRUE,BYTE byInitType=0)
参数:pAttr -- 一个指向DSPACT派生类对象的指针
bCompress -- pAttr所指的对象在序列化时是否压缩
bVerifyCRC-- pAttr所指的对象在序列化时是否进行CRC校验
byInitType-- pAttr所指的对象在在反序列化成功后调用对象的Init()方法传递的参数
描述:序列化属性中的一个DSPACT派生类的对象
DSP类的静态方法
类型:静态方法
定义:static bool RegisterAct(const char* classID,DSPCALLFUNC(dspActFun),DWORD dwData=0)
参数:classID -- 指向类的ClassID的字符串指针
dspActFun -- DSP回调函数的指针,回调函数定义如下:
DSPACT* FunctionName(const std::string& strID)
该函数在堆中创建一个classID为strID的DSPACT类的派生类的对象,并返回该对象的指针
例如:static DSPACT* PPQ::GetDSPObject(const std::string& strID)
{ return (new PPQ()); };
该函数的指针为:&PPQ::GetDSPObject;
dwData -- 一个32位的指针或数值。对象被反序列化成功后可以得到该值。
返回:true --注册成功;
false --注册失败。
描述:注册一个类,使在调用反序列化方法时,可以成功地反序列化对象
应用:设置合适的dwData值,可以创建多种应用模型。
在windows系统中,可以充分利用window的消息机制,使反序列化对象自动归类执行。方法是设定dwData的值为一个消息ID,每一个类的消息ID都不同,在反序列化成功后,只需要向指定的一个窗口发送一个表示该类消息,并且将对象的指针作为参数传递。在响应消息的窗口中,只需要相应地对各消息进行处理即可。
另外,充分地利用好反序列化对象的Init()函数,也可以使反序列化后的对象自动执行规定的操作。
类型:静态方法
定义:static inline BOOL OpenIfstreamForRead(ifstream& ifs,const char* const lpFileName,int nMode=0)
参数:ifs -- 文件输入流对象
lpFileName-- 打开的文件的文件名
nMode -- 打开的方式
返回:true --文件打开成功;
false --文件打开失败。
描述:在一个对象中,如果包含一个文件,在序列化对象时,需要采用该方法打开一个文件准备读,也就是说在序列化对象时,如果一个文件内容需要被序列化,该文件必需以二进制形式打开。
类型:静态方法
定义:static inline BOOL OpenOfstreamForWrite(ofstream& ofs,const char* const lpFileName,int nMode=0)
参数:ofs -- 文件输出流对象
lpFileName-- 打开的文件的文件名
nMode -- 打开的方式
返回:true --文件打开成功;
false --文件打开失败。
描述:在一个对象中,如果包含一个文件,在反序列化对象时,需要采用该方法打开一个文件准备写,也就是说在反序列化对象时,如果一个文件内容需要被反序列化,该文件必需以二进制形式打开。
DSPACT类的方法说明
DSPACT类是所有可以被序列化和反序列化的对象的基类,如果希望一个类可以被序列化和反序列化,则该类必需是从DSPACT类派生出的一个新类,为了实现类的序列化和反序列化,DSPACT类中包含了几个虚函数,这些虚函数可以全部都被重载或只重载一部分。DSPACT中的所有方法都是虚函数。
类型:序列化对象所必需包含的宏
定义:SELF_SERIALIZE(classid,className,base_className)
参数:classid -- 类的ID,字符串型式
className -- 类的名字,字符串型式
base_className-- 该类的基类的名字,非字符串型式,不需要被引号括起来
描述:重载了几个序列化中必需包含的方法,这个宏必需在DSPACT的派生类的头文件中出现
举例:类PPQ是直接从类DSPACT派生出的新类,类P2P是直接从类PPQ派生出的新类
SELF_SERIALIZE("PPQ","PPQ",DSPACT);
SELF_SERIALIZE("P2P.Sub@PPQ","P2P",PPQ);
类型:protected虚函数,该函数在SELF_SERIALIZE宏中被重载
定义:virtual BYTE GetClassLevel()
参数:无
描述:得到类的深度,即当前类相对于DSPACT进行了多少次派生。类的最大派生深度为15。
如果一个类直接从DSPACT类派生,则它的类深度为1。
类型:public虚函数,该函数在SELF_SERIALIZE宏中被重载
定义:virtual char* GetClassID()
参数:无
描述:得到类的ClassID。
****ClassID严格区分大小写****
声明:每一个类都包含有唯一的ClassID,类的ClassID不能相同。类的ClassID采用类似于Internet域名的方法命名---派生类继承基类的ClassID,并向左增加标识自己类的ClassID,在基类的ClassID和新增加的标识自己类的ClassID之间加入一个'@'字符。派生类和基类的ClassID合在一起,构成派生类的唯一的ClassID。
ClassID采用字符串形式表式,可以使用除'@'之外的任何字符串中允许出现的字符,'@'字符只允许出现在基类和派生类的ClassID之间,不允许出现在其它地方。ClassID的总长度不能超过256个字符。
DSPACT作为最底层的基类,它没有ClassID。
举例:类PPQ是直接从类DSPACT派生出的新类,类PPQ的ClassID为"PPQ";
类P2P是直接从类PPQ派生出的新类,类P2P的ClassID为"PP.SUB@PPQ"
类型:public虚函数,该函数在SELF_SERIALIZE宏中被重载
定义:virtual bool IsKindOf(char* lpClassName)
参数:lpClassName -- 类的名字的字符串形式
返回:true --当前对象是指定类的一个实例;
false --当前对象不是指定类的一个实例。
描述:判断当前对象是否是指定的类的一个实例。
类型:protected虚函数
定义:virtual void Init(BYTE byType){}
参数:byType -- 初始化的类型,可根据类型值,设置不同的初始化过程。取值为[1..15]
应用:充分地利用好反序列化对象的Init()函数,可以使反序列化后的对象自动执行规定的操作。
类型:protected虚函数
定义:virtual bool AttrSectRecv(BYTE byClassLevels,BYTE byAttrNo,const char* const lpBuff,DWORD dwLen,BOOL bLast)
参数:byClassLevels -- 类的深度
byAttrNo -- 当前操作的属性的序号
lpBuff -- 需要被接收的数据所在缓冲区的首地址
dwLen -- 当前缓冲区中的有效数据的字节数
bLast -- 是否是最后一段被接收的数据
当bLast==true时,表示当前接收的数据是最后一段数据,具有相同的byClassLevels和byAttrNo值的调用,不会再次出现,可以在接收到bLast==true后,并闭文件输出流或释放不再需要的资源。也可以不在这个地方处理,当bLast==true后,紧接着会调用UnSerialize()方法,通知该属性已完成赋值,也可以在UnSerialize()方法中去释放不需要的资源。
返回:true --接收成功;
false --接收失败,如果返回false,反序列化过程会终止。
描述:接收大数据量的分段传送的二进制流数据。
应用:DSP允许在序列化对象时传送任意大小的文件或动态改变的二进制流缓冲区,传送这些数据时,数据的大小是不确定的,数据通过AttrSectSend()方法分段赋值,并立即被序列化输出或传送,在反序列化过程中,如果接收到这样的属性值,则会调用AttrSectRecv()方法接收。
举例:
bool DSPACT::AttrSectRecv(BYTE byClassLevels,BYTE byAttrNo,const char* const lpBuff,DWORD dwLen,BOOL bLast)
{
if(byClassLevels>1)
return BaseObject::AttrSectRecv(byClassLevels,byAttrNo,dwLen,bLast);
else
{
//属性的序号必需与Serialize()中的属性序号相同
switch(byAttrNo)
{
case 1:
break;
}
}
return true;
}
类型:protected虚函数
定义:virtual bool AttrSectSend(BYTE byClassLevels,BYTE byAttrNo,char** const lpBuff,DWORD& dwLen,bool& bContinue)
参数:byClassLevels -- 类的深度
byAttrNo -- 当前操作的属性的序号
lpBuff -- 需要被传送的数据所在缓冲区的首地址,每次都可以修改
dwLen -- 当前缓冲区中的有效数据的字节数,每次都可以修改
bContinue -- 是否是最后一段被传送的数据
当bContinue==true时,表示当前传送的数据是最后一段数据,具有相同的byClassLevels和byAttrNo值的调用,不会再次出现,应该在设置最后一段数据后,并闭文件输入流或释放不再需要的资源。
描述:传送大数据量的二进制流数据。
应用:DSP允许在序列化对象时传送任意大小的文件或动态改变的二进制流缓冲区,传送这些数据时,数据的大小是不确定的,数据通过AttrSectSend()方法分段赋值,并立即被序列化输出或传送,在反序列化过程中,如果接收到这样的属性值,则会调用AttrSectRecv()方法接收。
举例:
bool DSPACT::AttrSectSend(BYTE byClassLevels,BYTE byAttrNo,char** const lpBuff,DWORD& dwLen,bool& bContinue)
{
if(byClassLevels>1)
return BaseObject::AttrSectSend(byClassLevels,byAttrNo,lpBuff,dwLen,bContinue);
else
{
//属性的序号必需与Serialize()中的属性序号相同
switch(byAttrNo)
{
case 1:
break;
}
}
return true;
}
类型:protected虚函数,派生类对象必需重载该函数
定义:virtual bool Serialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp)
参数:byClassLevels -- 类的深度
byAttrNo -- 当前操作的属性的序号
dsp -- 进行序列化操作的_DSPPACKET结构
返回:true --表示当前对象的属性已经全部还原完,该属性是对象的最后一个属性
false --表示当前对象的属性还没有全部还原完
描述:设置对象中的哪些属性进行序列化操作,这个方法在对象序列化时会自动调用
举例:
bool DSPACT::Serialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp)
{
if(byClassLevels>1)
return BaseObject::Serialize(byClassLevels-1,byAttrNo,dsp);
else
{
//属性的序号从1开始编号,每一个属性递增一个序号
switch(byAttrNo)
{
case 1: //序列化第1个属性
dsp.Write();
return false;
case 2: //序列化第2个属性
dsp.Write();
return false;
case 3: //序列化最后一个属性
dsp.Write();
}
}
return true;
}
类型:protected虚函数,派生类对象必需重载该函数
定义:virtual bool UnSerialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp,DWORD dwLen)
参数:byClassLevels -- 类的深度
byAttrNo -- 当前操作的属性的序号
dsp -- 进行序列化操作的_DSPPACKET结构
返回:true --表示当前对象的属性已经全部还原完,该属性是对象的最后一个属性
false --表示当前对象的属性还没有全部还原完
描述:与Serialize()方法中的属性相对应,定义了对象中的哪些属性进行反序列化操作,这个方法在对象反序列化时会自动调用
举例:
bool DSPACT::UnSerialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp,DWORD dwLen)
{
//反序列化对象
if(byClassLevels>1)
return BaseObject::UnSerialize(byClassLevels-1,byAttrNo,dsp,dwLen);
else
{
switch(byAttrNo)
{
//属性的序号必需与Serialize()中的序号相对应
case 1: //得到第1个属性
if(dsp.Read(,dwLen))
{
//如果反序列化属性的函数返回真,则表示该属性的值已填充完成
}
return false;
case 2: //得到第2个属性
dsp.Read();
return false;
case 3: //得到最后一个属性
dsp.Read(,dwLen);
}
}
return true;
}
类型:protected虚函数,派生类对象必需重载该函数
定义:virtual bool Compress(char** const lpBuff,DWORD* pdwLen)
参数:lpBuff -- 在调用时,指向要压缩的数据缓冲区的指针,压缩后指向压缩数据的缓冲区的首址
pdwLen -- 在调用时,为要压缩的数据的字节个数,压缩后为压缩后的数据的字节数
返回:true --压缩程序有效;
false --压缩程序无效;
当压缩有效时,必需修改lpBuff为保存压缩后数据的缓冲区的指针,pdwLen地址内保存为压缩后的数据的长度
类型:protected虚函数,派生类对象必需重载该函数
定义:virtual bool UnCompress(char** const lpBuff,DWORD* pdwLen,bool bStart)
参数:lpBuff -- bStart==true时,调用时指向被压缩的数据缓冲区的首址;解压缩后,指向解压缩的数据缓冲区的首址
bStart==false时,将接收被压缩数据的缓冲区的首址保存在该地址中
pdwLen -- bStart==true时,调用时保存被压缩的数据的字节数;解压缩后,保存解压缩的数据的字节数
bStart==false时,调用时为被压缩数据的字节数,缓冲区不能小于该字节数,这时不能修改该值
bStart -- true,表示数据已经被填充到lpBuff指定的缓冲区中,填充数据的长度为*pdwLen;
false,表示该次调用只是指定填充数据的缓冲区,缓冲区的长度不能小于*pdwLen;
返回:true --解压缩程序有效;
false --解压缩程序无效
当解压缩程序有效时,必需修改lpBuff为保存解压缩后数据的缓冲区的指针,*pdwLen地址内保存为解压缩后的数据的长度
DSP源程序下载:http://www.copathway.com/vchelp/file2003_3/ppqtest.zip
DSP更名为SSP。
请关注SSP应用实例二----利用UDP轻松实现BT多点传送