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

📄 tagtype.c

📁 一个OPC服务器开发的源代码。结构清晰
💻 C
字号:
/**************************************************************************
 *                                                                        *
 * Light OPC Server development library                                   *
 *                                                                        *
 *   Copyright (c) 2000  Timofei Bondarenko                               *
                                                                          *
 tag types' checking
 **************************************************************************/

/*#include <math.h>  fabs() */
//#include <errno.h>
#include <opcerror.h>
#include "loserv.h"
#include "util.h"

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

#define loDO_CONVERT(attr,type) ((loTF_CONVERT & (attr)->taFlags) && \
                                 ( VT_BSTR == (type) ||              \
                                   VT_DATE == (type) ||              \
                                  (VT_ARRAY & (type)) ) )

HRESULT lo_checktype(loCallerx *cctx, loTagAttrib *attr, VARTYPE type)
{
 HRESULT hr = S_OK;
 int pconv = 0;
 HRESULT meq = S_OK;
 WORD qua = 0;
 loTagPair tp;
 VARIANT tmp; VARIANTINIT(&tmp);

#if 0
 if (loTF_EMPTY & attr->taFlag) return OPC_E_UNKNOWNITEMID;
#endif
 if (VT_EMPTY == taVTYPE(attr)) return OPC_E_INVALIDITEMID;//UNKNOWNITEMID;

 if (VT_EMPTY == type) type = taVTYPE(attr);

 if (loDO_CONVERT(attr, type))
   {
    if ((loTF_NOCONV & attr->taFlags) &&
        (type != VT_EMPTY || type != taVTYPE(attr)))
      return OPC_E_BADTYPE;
    tp.tpAP = 0; /* unknown */
    tp.tpTi = attr->taTi;
    tp.tpRt = attr->taRt;
    pconv = 1;
   }
 else
   {
    if (type == VT_EMPTY) return S_OK;
    if (type == taVTYPE(attr)) return S_OK;
    if (loTF_NOCONV & attr->taFlags) return OPC_E_BADTYPE;
   }

 if (pconv)
   cctx->cactx.ca_se->driver.ldConvertTags(&cctx->cactx, 1, &tp,
                  &tmp, &qua, &hr, &meq, &meq, &attr->taValue, &type, 
                  cctx->cta.vc_lcid);
 else hr = VARIANTCHANGEt(&tmp, &attr->taValue, cctx->cta, type);

 if (S_OK == hr && OPC_ANALOG == attr->taEUtype)
   {
    double *minmax;
         
    if (type & VT_ARRAY)
      {  
       /* Let's check 2 array members at once */
       if (pconv)
         cctx->cactx.ca_se->driver.ldConvertTags(&cctx->cactx, 1, &tp,
                       &tmp, &qua, &hr, &meq, &meq, 
                       &attr->taEUinfo, &type, cctx->cta.vc_lcid);
       else hr = VARIANTCHANGEt(&tmp, &attr->taEUinfo, cctx->cta, type);
      } 
    else /* already checked by AddRealTag/decode_range */
      if (/*V_VT(&attr->eu_info) == (VT_ARRAY|VT_R8) && V_ARRAY(&attr->eu_info) &&*/
        S_OK == (hr = loSA_AccessData(V_ARRAY(&attr->taEUinfo), (void**)&minmax)))
      {
       VARIANT mm;
       V_R8(&mm) = minmax[0];
       V_VT(&mm) = VT_R8;
       if (pconv) cctx->cactx.ca_se->driver.ldConvertTags(&cctx->cactx, 1, &tp,
                       &tmp, &qua, &hr, &meq, &meq, &mm, &type, 
                       cctx->cta.vc_lcid);
       else hr = VARIANTCHANGEt(&tmp, &mm, cctx->cta, type);
       if (S_OK == hr)
         {
          V_R8(&mm) = minmax[1];
          if (pconv) cctx->cactx.ca_se->driver.ldConvertTags(&cctx->cactx, 1, &tp,
                          &tmp, &qua, &hr, &meq, &meq, &mm, &type, 
                          cctx->cta.vc_lcid);
          else hr = VARIANTCHANGEt(&tmp, &mm, cctx->cta, type);
         }
       SafeArrayUnaccessData(V_ARRAY(&attr->taEUinfo));
      }
    else
      {
       UL_ERROR((LOGID, "lo_checktype(%d>%ls) bad EU/%s",
                         type, loWnul(attr->taName), loStrError(hr)));
       hr = S_OK;
      }
   }
 VariantClear(&tmp);
#if 0 /* LO_E_BADTYPE( */
 return S_OK == hr? S_OK: OPC_E_BADTYPE;
#else
 return hr;
#endif
}

loCONV lo_check_conversion(loTagAttrib *attr, VARTYPE requested)
{
 if (VT_EMPTY == requested) requested = taVTYPE(attr);

 if (loDO_CONVERT(attr, requested)) return loCONV_CONVERT;

 if (taVTYPE(attr) == requested ||
     VT_EMPTY == requested)
   {
    if (!(VT_ARRAY & taVTYPE(attr)) &&
          VT_BSTR != taVTYPE(attr)) return loCONV_ASSIGN;
    return loCONV_COPY;
   }
 return loCONV_CHANGE;
}

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

void loChangeActivity(loCaller *ca, int act, unsigned count, loTagId *til)
{
  int cc;
  loTagId ti;
  loTagPair ch_rt[32];
  loService *se;

 UL_TRACE((LOGID, "loChangeActivity(%u %u)", act, count));
 
 if (!til || !ca) return;
 se = ca->ca_se;
 if (!loSERVICE_OK(se) || !se->driver.ldSubscribe) return;

 if (se->driver.ldFlags & loDF_SUBSCRIBE_RAW)
   {
     while(count)
       {
        for(cc = 0; cc < SIZEOF_ARRAY(ch_rt) && count; til++, count--)
          if (0 < (ti = *til) && ti < se->tag_count/*ti <= se->lastused*/)
            {                     /* se->lastused is not locked now */
             loTagEntry *te = &se->tags[ti];
             ch_rt[cc].tpTi = te->attr.taTi;
             ch_rt[cc].tpRt = te->attr.taRt;
             ch_rt[cc++].tpAP = 0;
             UL_TRACE((LOGID, "lo%sActivate(%u %ls)",
                          act? "": "De", ti, loWnul(te->attr.taName)));
            }
        if (cc) se->driver.ldSubscribe(ca, act? cc: -cc, ch_rt);
       }
   }
 else
   {
    while(count)
     {
    //    lw_rw_rdlock(&se->lkMgmt);
      lw_mutex_lock(&se->lkDr);
      for(cc = 0; cc < SIZEOF_ARRAY(ch_rt) && count; til++, count--)
        if (0 < (ti = *til) && ti < se->tag_count/*ti <= se->lastused*/)
          {                     /* se->lastused is not locked now */
           loTagEntry *te = &se->tags[ti];
           if (loTE_USED(te) && 0 == (act? te->active++: --te->active))
             {
              ch_rt[cc].tpTi = te->attr.taTi;
              ch_rt[cc].tpRt = te->attr.taRt;
              ch_rt[cc++].tpAP = 0;
              UL_TRACE((LOGID, "lo%sActivate(%u %ls)",
                        act? "": "De", ti, loWnul(te->attr.taName)));
             }
          }
      if (cc) se->driver.ldSubscribe(&se->cactx, act? cc: -cc, ch_rt);
      lw_mutex_unlock(&se->lkDr);
    //    lw_rw_unlock(&se->lkMgmt);
        // UL_DEBUG((LOGID, "ldSubscribe... finished"));
     }
   }
// UL_DEBUG((LOGID, "loChangeActivity(%u)... finished", act));
}

/* end of tagtype.c */

⌨️ 快捷键说明

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