⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dopack.cpp

📁 一个OPC服务器开发的源代码。结构清晰
💻 CPP
字号:
/**************************************************************************
 *                                                                        *
 * Light OPC Server development library                                   *
 *                                                                        *
 *   Copyright (c) 2000 by Timofei Bondarenko                             *
                                                                          *
 Packing data for IAdviseSink
 **************************************************************************/

#include "privopc.h"

#define DUMMY_UNKNOWN (0)

#ifdef NONAMELESSUNION
#define STGM_hGlobal u.hGlobal
#else
#define STGM_hGlobal   hGlobal
#endif

#define loGMEM_FLAG (GMEM_SHARE|GMEM_MOVEABLE/*GMEM_FIXED*/)

static HGLOBAL gmem_realloc(HGLOBAL *hg, unsigned size)
{
 HGLOBAL hn;
 if (hn = *hg? GlobalReAlloc(*hg, size, loGMEM_FLAG):
               GlobalAlloc(loGMEM_FLAG, size)) *hg = hn;
/* else
   {
    UL_WARNING((LOGID, "%!L gmem_alloc(%u) FAILED", size));
   }*/
 return hn;
}

static void gmem_free(HGLOBAL *hg)
{
 if (*hg && GlobalFree(*hg))
   {
    UL_ERROR((LOGID, "%!L gmem_free(%X) FAILED", *hg));
   }
 *hg = 0;
}

/**************************************************************************/

int lo_OnDataChange1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                     int with_time, IAdviseSink *ias, HGLOBAL *gmem, unsigned *hint_dsize)
{
 HGLOBAL fakegmem = 0;
 unsigned hdrsize, totalsize, ihdr_size, datasize;
 unsigned ii, itcount = upl->used;
 loUpdList lup = *upl;

 ihdr_size = with_time? sizeof(OPCITEMHEADER1): sizeof(OPCITEMHEADER2);
 hdrsize = sizeof(OPCGROUPHEADER) + itcount * ihdr_size;
 datasize = 0;

 if (hint_dsize && *hint_dsize) datasize = *hint_dsize;
 else
   {
    for(ii = itcount; ii--;)
      {
       datasize += loVariantSize(&lup.variant[ii]);
      }
    if (hint_dsize) *hint_dsize = datasize;
   }

 totalsize = hdrsize + datasize;

 if (!gmem) gmem = &fakegmem;
 if (!gmem_realloc(gmem, totalsize))
   {
    itcount = 0;
    hdrsize = sizeof(OPCGROUPHEADER);
    if (!gmem_realloc(gmem, hdrsize))
      {
       UL_ERROR((LOGID, "%!L Trasaction %X ABORTED due gmem_alloc(%u)",
                 lup.trqid, totalsize));
       return -1;
      }
    UL_WARNING((LOGID, "%!L Trasaction %X Failed due gmem_alloc(%u)",
                 lup.trqid, totalsize));
    totalsize = hdrsize;
    lup.master_err = E_OUTOFMEMORY;
   }

{
 char *glob, *glob0, *ihdr;
 OPCGROUPHEADER *gh;
 FILETIME faketime, *timest = &faketime;
 unsigned timest_inc = 0;

 glob = glob0 = (char*)GlobalLock(*gmem);
 gh = (OPCGROUPHEADER*)glob;
 ihdr = (char*)&gh[1];
 glob += hdrsize;

 if (with_time)
   timest_inc = sizeof(OPCITEMHEADER1),
   timest = &((OPCITEMHEADER1*)ihdr)->ftTimeStampItem;

 gh->dwSize = totalsize;
 gh->dwItemCount = itcount;
 gh->hClientGroup = hClient;
 gh->dwTransactionID = lup.trqid;

 for(ii = 0; ii < itcount; ii++)
   {
    ((OPCITEMHEADER1*)ihdr)->wReserved = 0;
    ((OPCITEMHEADER1*)ihdr)->dwValueOffset = glob - glob0;
    ((OPCITEMHEADER1*)ihdr)->hClient  = lup.opchandle[ii];
    ((OPCITEMHEADER1*)ihdr)->wQuality = lup.quality[ii];
    loVariantPack((void**)&glob, &lup.variant[ii]);
    *timest = lup.timestamp[ii];
    timest = (FILETIME*)(((char*)timest) + timest_inc);
    ihdr += ihdr_size;
   }

 gh->hrStatus = lup.master_err != S_OK?
                lup.master_err: lup.master_qual;

 if ((unsigned)(glob - glob0) != totalsize)
   {
    UL_ERROR((LOGID, "Transaction:%X datasize mismatch %u %u",
                      lup.trqid, glob - glob0, totalsize));
   }
 GlobalUnlock(*gmem);
}
{
 STGMEDIUM stgm;
 FORMATETC form;

 form.cfFormat = cform;
 form.dwAspect = DVASPECT_CONTENT;
 form.ptd = NULL;
 form.tymed = TYMED_HGLOBAL;
 form.lindex = -1;
 stgm.tymed = TYMED_HGLOBAL;
 stgm.STGM_hGlobal = *gmem;
 stgm.pUnkForRelease = DUMMY_UNKNOWN;

 UL_DEBUG((LOGID, "OnDataChange1:%s-time(%u)...%p{ %X",
                  with_time? "with": "without", 
                  itcount, ias, *gmem));
 ias->OnDataChange(&form, &stgm);
 UL_DEBUG((LOGID, "OnDataChange()...}"));
}
 gmem_free(&fakegmem);

 return FAILED(lup.master_err)? -1: 0;
}

int lo_OnWriteComplete1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                        IAdviseSink *ias, HGLOBAL *gmem)
{
 HGLOBAL fakegmem = 0;
 unsigned datasize;
 unsigned ii, itcount = upl->used;
 loUpdList lup = *upl;

 datasize = sizeof(OPCGROUPHEADERWRITE) + itcount * sizeof(OPCITEMHEADERWRITE);

 if (!gmem) gmem = &fakegmem;
 if (!gmem_realloc(gmem, datasize))
   {
    itcount = 0;
    datasize = sizeof(OPCGROUPHEADERWRITE);
    if (!gmem_realloc(gmem, datasize))
      {
       UL_ERROR((LOGID, "%!L Trasaction %X ABORTED due gmem_alloc(%u)",
                 lup.trqid, datasize));
       return -1;
      }
    UL_WARNING((LOGID, "%!L Trasaction %X Failed due gmem_alloc(%u)",
                 lup.trqid, datasize));
    lup.master_err = E_OUTOFMEMORY;
   }

{
 OPCGROUPHEADERWRITE *gh;
 OPCITEMHEADERWRITE *ihdr;

 gh = (OPCGROUPHEADERWRITE*)GlobalLock(*gmem);
 ihdr = (OPCITEMHEADERWRITE*)&gh[1];

 gh->dwItemCount = itcount;
 gh->hClientGroup = hClient;
 gh->dwTransactionID = lup.trqid;
 gh->hrStatus = lup.master_err;

 for(ii = 0; ii < itcount; ii++, ihdr++)
   {
    ihdr->hClient = lup.opchandle[ii];
    ihdr->dwError = lup.errors[ii];
// UL_DEBUG((LOGID, "OnWriteComplete(%u : %X/%X)", itcount, ihdr->dwError, gh->hrStatus));
   }

 if ((unsigned)((char*)ihdr - (char*)gh) != datasize)
   {
    UL_ERROR((LOGID, "Transaction:%X datasize mismatch %u %u",
                      lup.trqid, (char*)ihdr - (char*)gh, datasize));
   }
 UL_DEBUG((LOGID, "OnWriteComplete(%u : %X/%X)", itcount, gh->hrStatus, lup.master_err));
 GlobalUnlock(*gmem);
}
{
 STGMEDIUM stgm;
 FORMATETC form;

 form.cfFormat = cform;
 form.dwAspect = DVASPECT_CONTENT;
 form.ptd = NULL;
 form.tymed = TYMED_HGLOBAL;
 form.lindex = -1;
 stgm.tymed = TYMED_HGLOBAL;
 stgm.STGM_hGlobal = *gmem;
 stgm.pUnkForRelease = DUMMY_UNKNOWN;

 ias->OnDataChange(&form, &stgm);
 UL_DEBUG((LOGID, "OnWriteComplete()...}"));
}
 gmem_free(&fakegmem);

 return FAILED(lup.master_err)? -1: 0;
}

/* end of dopack.cpp */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -