static void rio_cache_write(loService *se, loUpdList *upl) { HRESULT *errors = upl->errors; VARIANT *variant = upl->variant; loTagPair *tpl = upl->tagpair; loTagEntry *tags = se->tags; unsigned ii, items_fail = 0, items_clamp = 0; FILETIME ft; VARIANT var; VARIANTINIT(&var); loTagValue *ts; se->driver.ldCurrentTime(&se->cactx, &ft); // UL_INFO((LOGID, "rio_cache_write() in %d", upl->master_err)); if (!(ts = loCacheLock(se))) return; for(ii = upl->used; ii--; tpl++, errors++, variant++) if (tpl->tpTi) { loTagValue *tv = &ts[tpl->tpTi]; VARTYPE cvt = taVTYPE(&tags[tpl->tpTi].attr); HRESULT hr; if (V_VT(variant) != VT_EMPTY && V_VT(variant) != cvt && S_OK != (hr = #if 0 VARIANTCHANGEt(variant, variant, upl->rctx.cta, cvt) #else VariantChangeType(variant, variant, 0, cvt) #endif )) { *errors = LO_E_BADTYPE(hr); items_fail = 1; } else if (tv->tvTi) { *errors = OPC_S_CLAMP; items_fail = 1; } else { VARIANT tvmp; tv->tvTi = tpl->tpTi; tvmp = tv->tvValue; tv->tvValue = *variant; *variant = tvmp; tv->tvState.tsTime = ft; tv->tvState.tsError = *errors = loOPC_S_CLAMP; tv->tvState.tsQuality = OPC_QUALITY_LOCAL_OVERRIDE; items_clamp = 1; } } loCacheUnlock(se, 0); if (items_fail || items_clamp && loOPC_S_CLAMP != S_OK) upl->master_err = S_FALSE; }
loTrid loCacheUpdate(loService *se, unsigned count, loTagValue taglist[], FILETIME *timestamp) { unsigned ii; loTagValue *ts; #if 0 != LO_FILL_TIMESTAMP FILETIME ft; #endif // UL_DEBUG((LOGID, "loCacheUpdate(%p %u %p)", se, count, taglist)); if (!loSERVICE_OK(se)) return 0;//EBADF; /*ERROR:EARG*/ if (!timestamp && (0 >= count || !taglist)) return 0; #if 0 != LO_FILL_TIMESTAMP #if 1 == LO_FILL_TIMESTAMP se->driver.ldCurrentTime(&se->cactx, &ft); #else if (timestamp) ft = *timestamp; else memset(&ft, 0, sizeof(ft)); #endif #endif if (!(ts = loCacheLock(se))) { UL_INFO((LOGID, "loCacheUpdate() lock failed")); return 0;//-1; /*ERROR:out-of-service*/ } for(ii = 0; ii < count; ii++, taglist++) { loTagId ti; if (0 == (ti = taglist->tvTi)) continue; else if (ti < 1 || ti > se->lastused/*tag_count*/) { /*rv = -1;*//*ERROR:BAD ti*/ UL_INFO((LOGID, "loCacheUpdate(BAD ti:%u)", ii)); continue; } else { HRESULT hr; loTagValue *tv = &ts[ti]; tv->tvState = taglist->tvState; #if 0 != LO_FILL_TIMESTAMP if (!IsFILETIME(tv->tvState.tsTime)) tv->tvState.tsTime = ft; #endif /* hr = (V_ISBYREF(&taglist->tvValue)? VariantCopyInd(&tv->tvValue, &taglist->tvValue): VariantCopy(&tv->tvValue, &taglist->tvValue)); */ hr = VariantCopy(&tv->tvValue, &taglist->tvValue); if (S_OK != hr) { LO_E_BADTYPE_QUAL(hr, tv->tvState.tsError, tv->tvState.tsQuality); /*rv = -1;*//*ERROR:BAD VALUE*/ UL_WARNING((LOGID, "%!l loCacheUpdate(VariantCopy())", hr)); } tv->tvTi = ti; } } return loCacheUnlock(se, timestamp); /* return rv; */ }