📄 388-392.html
字号:
<!--Begin Content Column -->
<FONT FACE="Arial,Helvetica" SIZE="-1">
To access the contents, click the chapter and section titles.
</FONT>
<P>
<B>Essential Windows CE Application Programming</B>
<FONT SIZE="-1">
<BR>
<I>(Publisher: John Wiley & Sons, Inc.)</I>
<BR>
Author(s): Robert Burdick
<BR>
ISBN: 0471327476
<BR>
Publication Date: 03/01/99
</FONT>
<P>
<form name="Search" method="GET" action="http://search.earthweb.com/search97/search_redir.cgi">
<INPUT TYPE="hidden" NAME="Action" VALUE="Search">
<INPUT TYPE="hidden" NAME="SearchPage" VALUE="http://search.earthweb.com/search97/samples/forms/srchdemo.htm">
<INPUT TYPE="hidden" NAME="Collection" VALUE="ITK">
<INPUT TYPE="hidden" NAME="ResultTemplate" VALUE="itk-simple-intrabook.hts">
<INPUT TYPE="hidden" NAME="ViewTemplate" VALUE="view.hts">
<font face="arial, helvetica" size=2><b>Search this book:</b></font><br>
<INPUT NAME="queryText" size=50 VALUE=""> <input type="submit" name="submitbutton" value="Go!">
<INPUT type=hidden NAME="section_on" VALUE="on">
<INPUT type=hidden NAME="section" VALUE="http://www.itknowledge.com/reference/standard/0471327476/">
</form>
<!-- Empty Reference Subhead -->
<!--ISBN=0471327476//-->
<!--TITLE=Essential Windows CE Application Programming//-->
<!--AUTHOR=Robert Burdick//-->
<!--PUBLISHER=John Wiley & Sons, Inc.//-->
<!--IMPRINT=Wiley Computer Publishing//-->
<!--CHAPTER=14//-->
<!--PAGES=388-392//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="385-388.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="392-396.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H3><A NAME="Heading11"></A><FONT COLOR="#000077">Transferring the Data</FONT></H3>
<P>The ActiveSync service manager is responsible for transferring data store objects between Windows CE–based devices and desktop computers. For data to be transferred, it must first be converted into binary data <I>packets</I>. A packet in this context is simply an array of the bytes that make up the data store items.</P>
<P>The process of converting data store objects into packets is sometimes called <I>de-serialization</I>. Synchronized data packets are also converted back into data store objects once they reach their destination in a processes called <I>serialization</I>.</P>
<P>Data de-serialization involves three steps. These steps are performed by the service provider using three methods implemented by the IReplObjHandler interface. This is in contrast to all of the synchronization tasks seen so far, which are implemented by the IReplStore interface.</P>
<P>The three IReplObjHandler interface methods that perform de-serialization are:</P>
<DL>
<DD><B>Setup.</B> Tells the service provider what object is to be de-serialized. This gives the provider an opportunity to allocate any resources required for de-serialization.
<DD><B>GetPacket.</B> The service provider creates one or more packets.
<DD><B>Reset.</B> Used by the service provider to free any resources used during de-serialization.
</DL>
<P>Similarly, serialization involves three steps:
</P>
<DL>
<DD><B>Setup.</B> Tells the service provider what object is to be serialized.
<DD><B>SetPacket.</B> The service provider converts packets back into data store objects.
<DD><B>Reset.</B> Used by the service provider to free any resources used during serialization.
</DL>
<P><I>Setup</I> is called by the service manager for each and every object to be serialized or de-serialized by a service provider. Furthermore, it is important to note that a service manager request to serialize an object can occur before a previously de-serialized packet has been transferred. Likewise, a service provider can receive a request to de-serialize a transferred packet before a packet it has just serialized has been transferred by the service manager.</P>
<P>This means that the service provider programmer must make provisions to accommodate these possibilities. We will shortly see how this is typically done.</P>
<P>The <I>Setup</I> method takes a single parameter:</P>
<!-- CODE SNIP //-->
<PRE>
HRESULT Setup(pSetup);
</PRE>
<!-- END CODE SNIP //-->
<P><I>pSetup</I> is a pointer to a REPLSETUP structure that contains information about the item to be synchronized. This structure contains many members. Most relevant to synchronization are a BOOL member called <I>fRead</I> and <I>hItem</I>. <I>hItem</I> is the item handle of the data store object to be synchronized. <I>fRead</I> specifies whether the item is being serialized or de-serialized.</P>
<P>The <I>fRead</I> value is important in light of the fact that a service provider can be asked to serialize a packet before a previous packet is de-serialized and vice versa. A service provider should maintain separate storage for an item to be serialized and for an item to be de-serialized. If packets happen to be serialized and de-serialized at the same time, the service provider can then keep the two items straight.</P>
<P>For example, the phone list application service providers define two REPLSTORE pointer members on their IReplObjHandler interfaces, <I>m_pWriteSetup</I> and <I>m_pReadSetup</I>. The <I>Setup</I> method is then implemented like this:</P>
<!-- CODE //-->
<PRE>
STDMETHODIMP CDataHandler::Setup(PREPLSETUP pSetup)
{
if (pSetup->fRead)
{
m_pReadSetup = pSetup;
}
else
{
m_pWriteSetup = pSetup;
}
return (NOERROR);
}
</PRE>
<!-- END CODE //-->
<P>If the method is called by the service manager to prepare the service provider to serialize a packet, the REPLSETUP information is saved in <I>m_pReadSetup</I>. If called to prepare to de-serialize, the information is stored in <I>m_pWriteSetup</I>.</P>
<P>Then, when the service manager calls <I>SetPacket</I> or <I>GetPacket</I>, the service provider can be sure to serialize or de-serialize the right data store object.</P>
<P>The <I>GetPacket</I> IReplObjHandler method creates a packet from a data store item:</P>
<!-- CODE SNIP //-->
<PRE>
HRESULT GetPacket(lppbData, pcbData, cbRecommend);
</PRE>
<!-- END CODE SNIP //-->
<P><I>lppdData</I> is a pointer to a BYTE array. This is the data buffer where the service provider should put the packet data. <I>pcbData</I> points to a DWORD in which the service provider should return the packet size. <I>cbRecommend</I> is passed by the service manager to tell the service provider the maximum packet size.</P>
<P>A data store object may require more than one packet in order to be completely transferred by the service manager. The service manager will therefore call <I>GetPacket</I> repeatedly until the service provider returns RWRN_LAST_PACKET, indicating that the last packet for the object has been created.</P>
<P>The service provider’s implementation can use the <I>cbRecommend</I> parameter to determine how many packets to create for a particular object. If the number of bytes to be transferred is greater than <I>cbRecommend</I>, the service provider should create packets and return NOERROR until the last packet has been created.</P>
<P>Notice that none of the parameters to <I>GetPacket</I> indicate which item is being packetized. This information is stored in the <I>hItem</I> member of the REPLSETUP structure that was saved in the <I>Setup</I> method.</P>
<P>In the case of the phone list application, the desktop service provider creates packets like this:</P>
<!-- CODE //-->
<PRE>
STDMETHODIMP CDataHandler::GetPacket(
LPBYTE *lppbPacket,
DWORD *pcbPacket,
DWORD cbRecommend)
{
PPHONEENTRY pEntry;
if (m_pReadSetup->hItem == NULL)
{
return E_UNEXPECTED;
}
memset(&m_packet, 0, sizeof(m_packet));
pEntry = m_pStore->FindPhoneEntry(
((PITEM)m_pReadSetup->hItem)->m_uid);
if (pEntry)
{
MultiByteToWideChar(CP_ACP, 0, pEntry->lpszLastName,
-1, m_packet.lpszLastName,
sizeof(m_packet.lpszLastName) - 1);
MultiByteToWideChar(CP_ACP, 0, pEntry->lpszFirstName,
-1, m_packet.lpszFirstName,
sizeof(m_packet.lpszFirstName) - 1);
MultiByteToWideChar(CP_ACP, 0, pEntry->lpszPhoneNumber,
-1, m_packet.lpszPhoneNumber,
sizeof(m_packet.lpszPhoneNumber) - 1);
m_packet.nDept = pEntry->nDept;
m_packet.ftUpdated = pEntry->ftLastModified;
}
*pcbPacket = sizeof(m_packet);
*lppbPacket = (LPBYTE)&m_packet;
return (pEntry ? RWRN_LAST_PACKET : E_UNEXPECTED);
}
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="385-388.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="392-396.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
<!-- reference_subfoot = footer -->
<!-- reference_footer = subfoot -->
<!-- BEGIN SUB FOOTER -->
<br><br>
</TD>
</TR>
</TABLE>
<table width="640" border=0 cellpadding=0 cellspacing=0>
<tr>
<td align="left" width=135><img src="/images/white.gif" width=100 height="1" alt="" border="0"></td>
<!-- END SUB FOOTER -->
<!-- all of the books have the footer and subfoot reveresed -->
<!-- reference_subfoot = footer -->
<!-- reference_footer = subfoot -->
<!-- FOOTER -->
<td width="515" align="left" bgcolor="#FFFFFF">
<font face="arial, helvetica" size="1"><b><a href="/products.html"><font color="#006666">Products</font></a> | <a href="/contactus.html"><font color="#006666">Contact Us</font></a> | <a href="/aboutus.html"><font color="#006666">About Us</font></a> | <a href="http://www.earthweb.com/corporate/privacy.html" target="_blank"><font color="#006666">Privacy</font></a> | <a href="http://www.itmarketer.com/" target="_blank"><font color="#006666">Ad Info</font></a> | <a href="/"><font color="#006666">Home</font></a></b>
<br><br>
Use of this site is subject to certain <a href="/agreement.html">Terms & Conditions</a>, <a href="/copyright.html">Copyright © 1996-1999 EarthWeb Inc.</a><br>
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.</font><p>
</td>
</tr>
</table>
</BODY>
</HTML>
<!-- END FOOTER -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -