NdrStreams.cpp
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* NdrStreams.cpp - VxDCOM NDR marshaling streams */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01s,17dec01,nel  Add include symbol for diab build.
  7. 01r,01oct01,nel  SPR#69557. Add extra padding bytes to make VT_BOOL type work.
  8. 01q,13jul01,dbs  fix up includes
  9. 01p,09feb01,nel  SPR#63068. Correct NdrStreams::reserve algorithm to allocate
  10.                  at least required amount of memory, not just double the
  11.                  existing amount.
  12. 01o,18oct00,nel  SPR#34927. Init some member variables.
  13. 01n,18sep00,nel  SPR#33730. Merge T2 OPC fixes into T3 branch.
  14. 01m,19jan00,nel  Modifications for Linux debug build
  15. 01l,05aug99,dbs  fix align() when buffer empty
  16. 01k,20jul99,dbs  optimise NDR reformatting
  17. 01j,20jul99,aim  removed call to print_this()
  18. 01i,09jul99,dbs  make sure reserve() is called before attempting to align the
  19.                  stream
  20. 01h,17jun99,aim  includes vxdcom.h
  21. 01g,17jun99,dbs  change to COM_MEM_ALLOC
  22. 01f,02jun99,aim  changes for solaris build
  23. 01e,25may99,dbs  make sure stream dtors free buffer memory
  24. 01d,20may99,dbs  move NDR phase into streams
  25. 01c,18may99,dbs  no need to memcpy() when addresses are same
  26. 01b,17may99,dbs  replace realloc() with vxdcom calls
  27. 01a,12may99,dbs  created
  28. */
  29. /*
  30.   DESCRIPTION:
  31. */
  32. #include <stdlib.h>
  33. #include "NdrStreams.h"
  34. #include "dcomProxy.h"
  35. #include "orpcLib.h"
  36. #include "private/comMisc.h"
  37. #if defined (VXDCOM_PLATFORM_VXWORKS)
  38. #include <memLib.h>
  39. #else
  40. #include <memory.h>
  41. #endif
  42. #include <stdio.h>
  43. /* Include symbol for diab */
  44. extern "C" int include_vxdcom_NdrStreams (void)
  45.     {
  46.     return 0;
  47.     }
  48. #if 0
  49. static void
  50. print_this (NdrMarshalStream* p)
  51.     {
  52.     byte* a = p->begin ();
  53.     int len = p->size ();
  54.     for (int i = 0; i < len; i++)
  55.         {
  56.         int b = 0;
  57.         b = (int) *a;
  58.         ++a;
  59.         }
  60.     }
  61. #endif
  62. //////////////////////////////////////////////////////////////////////////
  63. //
  64. // ndrMakeRight -- only ever called for 2, 4 or 8-byte quantities
  65. //
  66. inline void ndrMakeRight (size_t nb, void* pv)
  67.     {
  68.     char *a = (char*) pv;
  69.     char *b = ((char*) pv) + nb - 1;
  70.     char tmp;
  71.     for (size_t n=0; n < (nb / 2); ++n)
  72.         {
  73.         tmp = *a;
  74.         *a++ = *b;
  75.         *b-- = tmp;
  76.         }
  77.     }
  78. //////////////////////////////////////////////////////////////////////////
  79. //
  80. NdrMarshalStream::NdrMarshalStream
  81.     (
  82.     NdrPhase::Phase_t   ph,
  83.     DREP                drep,
  84.     byte*               pb,
  85.     size_t              nb
  86.     ) 
  87.       : m_drep (drep),
  88.         m_buffer (pb),
  89.         m_iptr (pb),
  90.         m_end (pb + nb),
  91.         m_bOwnMemory (false),
  92.         m_phase (ph),
  93. m_endPadding (0)
  94.     {
  95.     }
  96. //////////////////////////////////////////////////////////////////////////
  97. //
  98. NdrMarshalStream::~NdrMarshalStream ()
  99.     {
  100.     if (m_bOwnMemory && m_buffer)
  101.         delete [] m_buffer;
  102.     }
  103. //////////////////////////////////////////////////////////////////////////
  104. //
  105. NdrMarshalStream::NdrMarshalStream (NdrPhase::Phase_t ph, DREP drep)
  106.   : m_drep (drep),
  107.     m_buffer (0),
  108.     m_iptr (0),
  109.     m_end (0),
  110.     m_bOwnMemory (true),
  111.     m_phase (ph),
  112.     m_endPadding (0)
  113.     {
  114.     }
  115. //////////////////////////////////////////////////////////////////////////
  116. //
  117. size_t NdrMarshalStream::size () const
  118.     {
  119.     return (m_iptr - m_buffer);
  120.     }
  121. //////////////////////////////////////////////////////////////////////////
  122. //
  123. HRESULT NdrMarshalStream::align (size_t n)
  124.     {
  125.     // Reserve as many bytes as we are trying to align to
  126.     reserve (n);
  127.     // Now align the buffer-pointer
  128.     unsigned long p1 = (unsigned long) m_buffer;
  129.     unsigned long p2 = (unsigned long) m_iptr;
  130.     unsigned long p3 = (unsigned long) m_iptr;
  131.     const unsigned long mask = n - 1;
  132.     
  133.     // Align p2 w.r.t. p1
  134.     p2 = p1 + (((p2 - p1) + mask) & ~mask);
  135.     if (p3 != p2)
  136.         memset (m_iptr, 0, p2 - p3);
  137.     m_iptr = (byte*) p2;
  138.     if (m_iptr > m_end)
  139.         return E_FAIL;
  140.     return S_OK;
  141.     }
  142. //////////////////////////////////////////////////////////////////////////
  143. //
  144. // NdrMarsalStream::reserve -- reserve space for 'nb' more bytes in 
  145. // the stream. If necessary, the stream expands to allow space...
  146. //
  147. HRESULT NdrMarshalStream::reserve (size_t nb)
  148.     {
  149.     // There should never be 'negative space' in the buffer...
  150.     int space = m_end - m_iptr;
  151.     COM_ASSERT(space >= 0);
  152.     // Make sure the space is enough to hold the requested amount, if
  153.     // not, then we need to expand the buffer...
  154.     if (space < (int) nb)
  155.         {
  156.         // Cannot expand if we don't own the memory...
  157.         if (! m_bOwnMemory)
  158.             return E_UNEXPECTED;
  159.         
  160.         // Need to expand - make it worthwhile for small values of
  161.         // 'nb' by having a minimum expansion size of MINEXPAND...
  162.         const size_t MINEXPAND = 512;
  163.         size_t expansion = (nb < MINEXPAND) ? MINEXPAND : nb;
  164.         // New total length 'len' is old total plus expansion...
  165.         size_t len = (m_end - m_buffer) + expansion;
  166.         // Allocate new memory...
  167.         byte* ptmp = new byte [len];
  168.         if (! ptmp)
  169.             return E_OUTOFMEMORY;
  170.         // Copy in previous contents, if there were any...
  171.         if (m_buffer)
  172.             memcpy (ptmp, m_buffer, m_iptr - m_buffer);
  173.         // update members and free previous buffer
  174.         m_end = ptmp + len;
  175.         m_iptr = ptmp + (m_iptr - m_buffer);
  176.         if (m_buffer)
  177.             delete [] m_buffer;
  178.         m_buffer = ptmp;
  179.         }
  180.     return S_OK;
  181.     }
  182. //////////////////////////////////////////////////////////////////////////
  183. //
  184. HRESULT NdrMarshalStream::insert
  185.     (
  186.     size_t              nb,
  187.     const void*         pvData,
  188.     bool                reformat
  189.     )
  190.     {
  191.     HRESULT hr = reserve (nb);
  192.     if (FAILED (hr))
  193.         return hr;
  194.     memcpy (m_iptr, pvData, nb);
  195.     if ((m_drep != VXDCOM_DREP_LOCAL) && reformat)
  196.         ndrMakeRight (nb, m_iptr);
  197.     m_iptr += nb;
  198.     // enable this for UMR checks.
  199.     // print_this (this);
  200.     return S_OK;
  201.     }
  202. //////////////////////////////////////////////////////////////////////////
  203. //
  204. // NdrUnmarshalStream ctor -- allocate stub-buffer (if in stub
  205. // unmarshal phase) of same size as supplied buffer...
  206. //
  207. NdrUnmarshalStream::NdrUnmarshalStream
  208.     (
  209.     NdrPhase::Phase_t   ph,
  210.     DREP                drep,
  211.     byte*               pb,
  212.     size_t              nb
  213.     )
  214.       : m_drep (drep),
  215.         m_buffer (pb),
  216.         m_optr (pb),
  217.         m_end (pb + nb),
  218.         m_phase (ph),
  219.         m_stubBuffer (0),
  220.         m_stubNext (0)
  221.     {
  222.     // If we are in the stub-unmarshaling pahse, its safe to allocate
  223.     // memory for stub variables (arrays, etc) from a private heap,
  224.     // which will automatically be reclaimed in the stream's dtor. We
  225.     // allocate twice the stream's stub-data size, just to be safe...
  226.     if (m_phase == NdrPhase::STUB_UNMSHL)
  227.         {
  228.         m_stubBuffer = new byte [2 * nb];
  229.         m_stubNext = m_stubBuffer;
  230.         }
  231.     }
  232. //////////////////////////////////////////////////////////////////////////
  233. //
  234. NdrUnmarshalStream::~NdrUnmarshalStream ()
  235.     {
  236.     if (m_stubBuffer)
  237.         delete [] m_stubBuffer;
  238.     }
  239. //////////////////////////////////////////////////////////////////////////
  240. //
  241. // NdrUnmarshalStream::stubAlloc -- allocate 'nb' bytes from the safe
  242. // stub memory. Since the stub-buffer is always as big as the original
  243. // packet stub-data, then it should never run out...
  244. //
  245. byte* NdrUnmarshalStream::stubAlloc (size_t nb)
  246.     {
  247.     if (m_phase != NdrPhase::STUB_UNMSHL)
  248.         return 0;
  249.     
  250.     if (m_stubBuffer == 0)
  251.         return 0;
  252.     // Round up m_stubNext to multiple of 4...
  253.     m_stubNext = (byte*) (((ULONG)(m_stubNext + 3)) & ~3);
  254.     byte* p = m_stubNext;
  255.     m_stubNext += nb;
  256.     return p;
  257.     }
  258. //////////////////////////////////////////////////////////////////////////
  259. //
  260. //
  261. NdrUnmarshalStream::NdrUnmarshalStream ()
  262.   : m_drep (0),
  263.     m_buffer (0),
  264.     m_optr (0),
  265.     m_end (0),
  266.     m_phase (NdrPhase::NOPHASE),
  267.     m_stubBuffer (0),
  268.         m_stubNext (0)
  269.     {
  270.     }
  271. //////////////////////////////////////////////////////////////////////////
  272. //
  273. // assignment -- as we don't own the buffer, we just copy the pointers
  274. //
  275. NdrUnmarshalStream& NdrUnmarshalStream::operator=
  276.     (
  277.     const NdrUnmarshalStream&        rhs
  278.     )
  279.     {
  280.     m_drep = rhs.m_drep;
  281.     m_buffer = rhs.m_buffer;
  282.     m_optr = rhs.m_optr;
  283.     m_end = rhs.m_end;
  284.     m_phase = rhs.m_phase;
  285.     // set stub-buffer ptrs to NULL...
  286.     m_stubBuffer = 0;
  287.     m_stubNext = 0;
  288.     return *this;
  289.     }
  290. //////////////////////////////////////////////////////////////////////////
  291. //
  292. size_t NdrUnmarshalStream::size () const
  293.     {
  294.     return (m_optr - m_buffer);
  295.     }
  296. //////////////////////////////////////////////////////////////////////////
  297. //
  298. HRESULT NdrUnmarshalStream::align (size_t n)
  299.     {
  300.     unsigned long p1 = (unsigned long) m_buffer;
  301.     unsigned long p2 = (unsigned long) m_optr;
  302.     unsigned long p3 = (unsigned long) m_optr;
  303.     const unsigned long mask = n - 1;
  304.     
  305.     // Align p2 w.r.t. p1
  306.     p2 = p1 + (((p2 - p1) + mask) & ~mask);
  307.     byte* oldptr = m_optr;
  308.     m_optr = (byte*) p2;
  309.     // If we have gone beyond the end, fail...
  310.     if (m_optr > m_end)
  311.         return E_FAIL;
  312.     // Clear the gap we have just opened to zeroes...
  313.     if (p3 != p2)
  314.         memset (oldptr, 0, p2 - p3);
  315.     return S_OK;
  316.     }
  317. //////////////////////////////////////////////////////////////////////////
  318. //
  319. // NdrUnmarshalStream::extract -- extract data from the stream to the
  320. // supplied location at 'pvData' - if pvData is NULL then don't
  321. // actually copy any data, just adjust the stream pointers
  322. //
  323. HRESULT NdrUnmarshalStream::extract
  324.     (
  325.     size_t      nb,
  326.     void*       pvData,
  327.     bool        reformat
  328.     )
  329.     {
  330.     if ((m_end - m_optr) < (int) nb)
  331.         return E_FAIL;
  332.     // only copy data out if pvData is non-NULL, and does not point
  333.     // back into this stream's buffer, as it will when unmarshaling by
  334.     // copying occurs in optimised cases...
  335.     
  336.     if (pvData && (pvData != ((void*) m_optr)))
  337.         memcpy (pvData, m_optr, nb);
  338.     m_optr += nb;
  339.     if ((m_drep != VXDCOM_DREP_LOCAL) && reformat && pvData)
  340.         ndrMakeRight (nb, pvData);
  341.     return S_OK;
  342.     }