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

📄 proplist.c

📁 OPCSERVER源代码
💻 C
字号:
/**************************************************************************
 *                                                                        *
 * Light OPC Server development library                                   *
 *                                                                        *
 *   Copyright (c) 2001 by Timofei Bondarenko                             *
                                                                          *
 ItemProperties support: Property Lists
 **************************************************************************/

#include <errno.h>
#include <stddef.h> /* offsetof() */
#include "loserv.h"
#include "proplist.h"
#include "util.h"

int loPropListAssign(loService *se, loPLid plid, loTagId ti, int prio)
{
 int rv = 0;
 loTagEntry *te;

 if (prio > loPROPLIST_MAX || prio < 1 && (prio != -1 || plid))
   {
    rv = EINVAL; goto Return;
   }
 if (!loSERVICE_OK(se))
   {
    rv = EBADF; goto Return;
   }

 lw_rw_wrlock(&se->lkMgmt);

 te = &se->tags[ti];
 if (ti <= se->lastused && loTE_USED(te) &&
     plid < se->proplist_count)
   {
    if (prio > 0) te->attr.taPropList[prio - 1] = plid;
    else
      {
       for(prio = 0; prio < loPROPLIST_MAX; prio++)
         te->attr.taPropList[prio] = plid;
      }
   }
 else rv = ENOENT;

 lw_rw_unlock(&se->lkMgmt);

Return:
 if (rv)
   {
    UL_INFO((LOGID, "%!e loPropListAssign(Tag:%u Pr:%d PLid:%u) failed",
             rv, ti, prio, plid));
   }
 else
   {
    UL_NOTICE((LOGID, "loPropListAssign(Tag:%u Pr:%d PLid:%u) Ok", ti, prio, plid));
   }
 return rv;
}

static void loProperty_clear(loProperty *pr);

#define loProperty_clear(pr) (VariantClear(&(pr)->prValue), freeX(pr))

static void loProperty_clear_all(loProperty **prr)
{
 loProperty *pr;
 while(pr = *prr)
   {
    *prr = pr->prNext;
    loProperty_clear(pr);
   }
}

loPLid loPropListCreate(loService *se)
{
 loPLid plid = 0;
 unsigned pl_count, ad_count;

 if (!loSERVICE_OK(se)) return 0;

 lw_rw_wrlock(&se->lkMgmt);

 pl_count = se->proplist_count;
 ad_count =  (pl_count == 0)? 2: 1;

 if (preallocX((void**)&se->proplist, sizeof(loProperty*) * (pl_count + ad_count)))
   {
    memset(se->proplist + pl_count, 0, sizeof(loProperty*) * ad_count);
    plid = pl_count + ad_count - 1;
    se->proplist_count = pl_count + ad_count;
   }

 lw_rw_unlock(&se->lkMgmt);

 if (plid)
   {
    UL_NOTICE((LOGID, "loPropListCreate(%u) Ok", plid));
   }
 else
   {
    UL_INFO((LOGID, "loPropListCreate() failed - Out of memery"));
   }

 return plid;
}


static int intPropertyAdd(loService *se, loPLid plid, unsigned propid, VARIANT *val,
                          const char *path, const char *description,
                          const loWchar *pathW, const loWchar *descriptionW)
{
 int rv = 0;
 loProperty *prop, **prlist;

 if (!loSERVICE_OK(se)) return EBADF;

 if (pathW)
   {
    prop = (loProperty*)lo_string_to_struct(0, offsetof(loProperty, prPath), pathW);
   }
 else if (path)
   {
    if ((pathW = loMWstrdup(path)) &&
        !(prop = (loProperty*)
          lo_string_to_struct((void*)pathW, offsetof(loProperty, prPath), pathW)))
      freeX((void*)pathW);
   }
 else
   {
    prop = (loProperty*)lo_string_to_struct(0, offsetof(loProperty, prPath), L"");
   }
 if (!prop) { rv = ENOMEM; goto Return; }

 prop->prNext = 0;
 prop->prPropID = propid;
 VARIANTINIT(&prop->prValue);
 prop->prDescriptionW = descriptionW;
 prop->prDescription = description? description: lo_prop_descr(propid);

 if (val && S_OK != VariantCopy(&prop->prValue, val))
   {
    rv = ENOMEM; goto Return;
   }

 lw_rw_wrlock(&se->lkMgmt);
 if (prlist = lo_proplist(se, plid))
   {
    prlist = lo_prop_locate(prlist, propid);
    if (*prlist && (*prlist)->prPropID == propid)
      rv = EEXIST;
    else
      {
       prop->prNext = *prlist;
       *prlist = prop;
       prop = 0;
      }
   }
 else rv = EINVAL;

 lw_rw_unlock(&se->lkMgmt);

Return:
 if (prop) loProperty_clear_all(&prop);

 if (rv)
   {
    UL_INFO((LOGID, "%!e loPropertyAdd(%u) failed", rv, plid));
   }
 else
   {
    UL_NOTICE((LOGID, "loPropertyAdd(%u) %u/%x Ok", plid, propid, propid));
   }
 return rv;
}

int loPropertyAdd(loService *se, loPLid plid, unsigned propid, VARIANT *val,
                  const char *path, const char *description)
{
 return intPropertyAdd(se, plid, propid, val, path, description, 0, 0);
}

int loPropertyAddW(loService *se, loPLid plid, unsigned propid, VARIANT *val,
                   const loWchar *path, const loWchar *description)
{
 return intPropertyAdd(se, plid, propid, val, 0, 0, path, description);
}

int loPropertyRemove(loService *se, loPLid plid, unsigned propid)
{
 int rv = 0;
 loProperty **prl;

 if (!loSERVICE_OK(se)) return EBADF;
 lw_rw_wrlock(&se->lkMgmt);

 if (prl = lo_proplist(se, plid))
   {
    if ((prl = lo_prop_find(prl, propid)) && *prl)
      {
       loProperty *pr = *prl;
       *prl = pr->prNext;
       pr->prNext = 0;
       loProperty_clear_all(&pr);
      }
    else rv = ENOENT;
   }
 else rv = EINVAL;

 lw_rw_unlock(&se->lkMgmt);

 if (rv)
   {
    UL_INFO((LOGID, "%!e loPropertyRemove(%u :: %u/%x) failed", rv, plid, propid, propid));
   }
 else
   {
    UL_NOTICE((LOGID, "loPropertyRemove(%u :: %u/%x) Ok", plid, propid, propid));
   }

 return rv;
}

int loPropertyChange(loService *se, loPLid plid, unsigned propid, VARIANT *val)
{
 int rv = 0;
 loProperty **prl;

 if (!loSERVICE_OK(se)) return EBADF;
 lw_rw_wrlock(&se->lkMgmt);

 if (prl = lo_proplist(se, plid))
   {
    if ((prl = lo_prop_find(prl, propid)) && *prl)
      if (val)
        {
         HRESULT hr;
         hr = VariantCopy(&(*prl)->prValue, val);
         if (S_OK != hr)
           rv = E_OUTOFMEMORY == hr? ENOMEM: EFAULT;
        }
      else VariantClear(&(*prl)->prValue);
    else rv = ENOENT;
   }
 else rv = EINVAL;

 lw_rw_unlock(&se->lkMgmt);

 if (rv)
   {
    UL_INFO((LOGID, "%!e loPropertyChange(%u :: %u/%x) failed", rv, plid, propid, propid));
   }
 else
   {
    UL_TRACE((LOGID, "loPropertyChange(%u :: %u/%x) Ok", plid, propid, propid));
   }
 return rv;
}


loProperty **lo_prop_locate(loProperty **prl, unsigned propid)
{
 if (prl)
   {
    while(*prl && (*prl)->prPropID > propid) prl = &(*prl)->prNext;
   }
 return prl;
}

loProperty **lo_prop_find(loProperty **prl, unsigned propid)
{
 return ((prl = lo_prop_locate(prl, propid)) &&
        *prl && (*prl)->prPropID == propid)? prl: 0;
}

int lo_proplist_init(loService *se)
{
 se->proplist_count = 0;
 if (se->proplist = (loProperty**)mallocX(sizeof(loProperty*)))
   {
    se->proplist[0] = 0;
    se->proplist_count = 1;
    return 0;
   }
 return ENOMEM;
}

void lo_proplist_clear(loService *se)
{
 if (se->proplist)
   {
    unsigned xx = se->proplist_count;
    loProperty **proplist = se->proplist;
    se->proplist_count = 0;
    se->proplist = 0;

    while(xx--) loProperty_clear_all(proplist + xx);
    freeX(proplist);
   }
 se->proplist_count = 0;
}

/* end of proplist.c */

⌨️ 快捷键说明

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