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

📄 ioread.cpp

📁 一个OPC服务器开发的源代码。结构清晰
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#endif
//       memcpy(err, rq->upl.errors, dwCount * sizeof(*err));
       err = rq->upl.errors;
       rq->com_allocated = 0;
       lo_req_free(rq);
      }
    else hr = LO_E_SHUTDOWN;
   }
 else    /* real cache reading */
   {
    lock_read();
    master_err = extract_itemstate_from_prim(dwCount, err, ist, phServer, 
                                             this, &owner->ctxt);
    unlock();
   }

Return:
  if (S_OK == hr)
   {
    if (ppErrors) *ppErrors = err, err = 0;
    *ppItemValues = ist, ist = 0;
    if (S_OK != master_err) hr = S_FALSE;
    UL_NOTICE((LOG_GRH("SyncIO:Read(%u) = %x Ok"), dwCount, master_err));
   }
 else
   {
    UL_INFO((LOG_GRH("SyncIO:Read(%u) = %x /%s"),
               dwCount, master_err, loStrError(hr)));
   }
    /* it is not neccessary to perform VariantClear() on ist
     because we don't make serious errors after ist.tvDataValue changed */
 if (ist) loComFree(ist);
 if (err) loComFree(err);

 LO_FINISH();
 return hr;
}


/*********************************** LightOPCGroup::IOPCAsyncIO stuff **************************/

#define loUPL_AsyncRead   (loUPL_variant | loUPL_timestamp | loUPL_quality | loUPL_errors |\
                           loUPL_tagpair | loUPL_opchandle | loUPL_vartype )

/********** AsyncIO1:: */

STDMETHODIMP LightOPCGroup::Read(/* [in] */ DWORD dwConnection,
			         /* [in] */ OPCDATASOURCE dwSource,
				 /* [in] */ DWORD dwCount,
				 /* [size_is][in] */ OPCHANDLE *phServer,
				 /* [out] */ DWORD   *pTransactionID,
				 /* [size_is][size_is][out] */ HRESULT **ppErrors)
{
 HRESULT hr = S_FALSE;
 HRESULT *errs = 0;
 loRequest *rq = 0;
 unsigned item_ok = 0;
 int am_mask = OPC_READABLE;

 LO_CHECK_STATEz1("AsyncIO:Read", ppErrors);

 UL_TRACE((LOG_GRH("AsyncIO:Read(%x/%u/%u)..."), dwConnection, dwSource, dwCount));

 if (!phServer || !dwCount || !pTransactionID ||
     dwSource != OPC_DS_DEVICE &&
     dwSource != OPC_DS_CACHE)  { hr = E_INVALIDARG; goto Return; }
 *pTransactionID = 0;
 if (owner->q_req.metric_overload) { hr = CONNECT_E_ADVISELIMIT; goto Return; }

 errs = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_AsyncRead);
 if (!rq || !errs) { hr = E_OUTOFMEMORY; goto Return; }
/* if some enties are not OK we will not use the rest fields at all
   thuse wo don't have to initialize them */
// memset(rq->upl.timestamp, 0, sizeof(FILETIME) * dwCount);
 loTagPair_init(rq->upl.tagpair, dwCount);
// memset(rq->upl.errors, 0, sizeof(HRESULT) * dwCount);

 rq->operation = dwConnection | loRQ_OP_READ |
                (dwSource == OPC_DS_DEVICE ? loRQ_DEVICE: 0);
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->upl.rctx = owner->ctxt;

 lock_read();

 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (dwSource == OPC_DS_DEVICE &&
     owner->access_mode & (loAM_NOREAD_DEV|loAM_ERREAD_DEV))
   {
    if (owner->access_mode & loAM_NOREAD_DEV) rq->operation &= ~loRQ_DEVICE;
    if (owner->access_mode & loAM_ERREAD_DEV)
      am_mask = 0, rq->operation &= ~loRQ_DEVICE;
   }

 if (dwConnection != loRQ_CONN_DATATIME &&
     dwConnection != loRQ_CONN_DATAONLY ||
    (dwConnection & advise_present) == 0) 
   {
    hr = CONNECT_E_NOCONNECTION;
   }
 else
   {
    unsigned ii;
    loTagPair *tpl = rq->upl.tagpair;
    LightOPCItem *it;
    loTagEntry *tags = owner->se->tags;
    int a_active = Active? ~0: 0;

    for(ii = 0; ii < dwCount; ii++, tpl++)
      if (!(it = by_index(phServer[ii]))) errs[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(am_mask/*OPC_READABLE*/ & te->attr.taRights))
           { //errs[ii] = OPC_E_BADRIGHTS; - in callback
            rq->upl.quality[ii] = OPC_QUALITY_BAD;
            rq->upl.errors[ii] = OPC_E_BADRIGHTS;
            rq->upl.master_err = S_FALSE;
           }
         else
#endif
              if (dwSource == OPC_DS_CACHE && !(a_active & it->bActive))
           {
            rq->upl.quality[ii] = OPC_QUALITY_OUT_OF_SERVICE;
            rq->upl.errors[ii] = LO_E_NOTACTIVE;
            rq->upl.master_err = S_FALSE;
           }
         else
           {
            rq->upl.quality[ii] = (WORD)it->convtype;
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
           }
         rq->upl.opchandle[ii] = it->hClient;
         rq->upl.vartype[ii] = it->vtRequestedDataType;
         errs[ii] = S_OK;
         item_ok++;
        }/* end of for */
   }
 unlock();

 if (dwCount == item_ok)
   {
    rq->upl.used = item_ok;
    if (0 == (*pTransactionID = lo_req_put_async(&owner->q_req, rq)))
      hr = CONNECT_E_ADVISELIMIT;
    else hr = S_OK;
    rq = 0;
   }

Return:
 if (rq) lo_req_free(rq);

 if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = errs, errs = 0;
    UL_NOTICE((LOG_GRH("AsyncIO:Read(%u) = %u -> %x Ok"),
                       dwCount, item_ok, *pTransactionID));
   }
 else
   {
    UL_INFO((LOG_GRH("AsyncIO:Read[conn=%x advs=%x](%u) = %u /%s"),
               dwConnection, advise_present,
               dwCount, item_ok, loStrError(hr)));
   }
 if (errs) loComFree(errs);

 LO_FINISH();
 return hr;
}

/********** AsyncIO2:: */

STDMETHODIMP LightOPCGroup::Read(DWORD dwCount, OPCHANDLE *phServer, DWORD dwTransactionID,
		                 DWORD *pdwCancelID, HRESULT **ppErrors)
{
 HRESULT hr = S_FALSE;
 HRESULT *errs = 0;
 loRequest *rq = 0;
 unsigned items_ok = 0;

 LO_CHECK_STATEz1("AsyncIO2:Read", ppErrors);

 UL_TRACE((LOG_GRH("AsyncIO2:Read(%x/%u)..."), dwTransactionID, dwCount));

 if (!phServer || !dwCount || !pdwCancelID)  { hr = E_INVALIDARG; goto Return; }
 *pdwCancelID = 0;
 if (owner->q_req.metric_overload) { hr = CONNECT_E_ADVISELIMIT; goto Return; }

 errs = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_AsyncRead);
 if (!rq || !errs) { hr = E_OUTOFMEMORY; goto Return; }
//??  loTagPair_init(rq->upl.tagpair, dwCount);

 rq->operation = loRQ_OP_READ | loRQ_CONN_DATABACK | loRQ_DEVICE;
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->upl.transaction_id = dwTransactionID;
 rq->upl.rctx = owner->ctxt;

 lock_read();
 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (owner->access_mode & (loAM_NOREAD_DEV|loAM_ERREAD_DEV))
   {
    if (owner->access_mode & loAM_NOREAD_DEV) rq->operation &= ~loRQ_DEVICE;
    if (owner->access_mode & loAM_ERREAD_DEV)
      {
       unsigned ii;
       for(ii = 0; ii < dwCount; ii++) errs[ii] = OPC_E_BADRIGHTS;
       goto Unlock;
      }
   }

 if (0 == (advise_present & loRQ_CONN_DATABACK)/*conn_databack*/)
   hr = CONNECT_E_NOCONNECTION;
 else
   {
    unsigned ii;
    loTagPair *tpl = rq->upl.tagpair;
    LightOPCItem *it;
    loTagEntry *tags = owner->se->tags;

    for(ii = 0; ii < dwCount; ii++)
      if (!(it = by_index(phServer[ii]))) errs[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(OPC_READABLE & te->attr.taRights)) errs[ii] = OPC_E_BADRIGHTS;
         else
#endif
           {
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
            tpl++;
            rq->upl.opchandle[items_ok] = it->hClient;
            rq->upl.quality[items_ok] = (WORD)it->convtype;
            rq->upl.vartype[items_ok++] = it->vtRequestedDataType;
            errs[ii] = S_OK;
           }
        }/* end of for */
   }
Unlock:
 unlock();

 if (items_ok)
   {
    rq->upl.master_err = rq->upl.master_qual =
    hr = items_ok == dwCount? S_OK: S_FALSE;
    rq->upl.used = items_ok;
    if (0 == (*pdwCancelID = lo_req_put_async(&owner->q_req, rq)))
      hr = CONNECT_E_ADVISELIMIT;
    rq = 0;
   }

Return:
 if (rq) lo_req_free(rq);

 if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = errs, errs = 0;
    UL_NOTICE((LOG_GRH("AsyncIO2:Read(%u) = %u -> %x Ok"),
                       dwCount, items_ok, *pdwCancelID));
   }
 else
   {
    UL_INFO((LOG_GRH("AsyncIO2:Read(%u) = %u /%s"),
               dwCount, items_ok, loStrError(hr)));
   }
 if (errs) loComFree(errs);

 LO_FINISH();
 return hr;
}


/* end of ioread.cpp */

⌨️ 快捷键说明

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