void lo_check_ev_timestamp(unsigned count, FILETIME *timestamp, const FILETIME *master) { while(count--) { if (!IsFILETIME(*timestamp)) *timestamp = loFT_SUBST(*timestamp, master); timestamp++; } }
static void rio_cache_read(loService *se, loUpdList *upl) { HRESULT mastererr = upl->master_err; HRESULT masterqual = upl->master_qual; HRESULT *errors = upl->errors; WORD *quality = upl->quality; VARIANT *variant = upl->variant; VARTYPE *vartype = upl->vartype; FILETIME *timestamp = upl->timestamp; loTagPair *tpl = upl->tagpair; loTagEntry *tags = se->tags; unsigned ii; unsigned localize_max = 0; unsigned localize_min = 0; lw_rw_rdlock(&se->lkPrim); for(ii = upl->used; ii--; errors++, quality++, variant++, vartype++, timestamp++, tpl++) { if (tpl->tpTi) { HRESULT hr; loTagEntry *te = &tags[tpl->tpTi]; #if 1 == LO_EV_TIMESTAMP if (!IsFILETIME(te->prim.tsTime)) *timestamp = loFT_SUBST(te->prim.tsTime, se->ts_prim); else #endif *timestamp = te->prim.tsTime; *errors = te->prim.tsError; #ifdef VAR_CHANGETYPE *quality = te->prim.tsQuality; hr = VAR_CHANGETYPE(variant, &te->primValue, *vartype); #else loCONV convtype = (loCONV)*quality; *quality = te->prim.tsQuality; switch(convtype/*lo_check_conversion(&te->attr, *vartype)*/) { case loCONV_CHANGE: hr = VARIANTCHANGEt(variant, &te->primValue, upl->rctx.cta, *vartype); break; case loCONV_COPY: hr = VariantCopy(variant, &te->primValue); break; case loCONV_ASSIGN: *variant = te->primValue; #if 1 loTagPair_init(tpl, 1); goto Cont; #else hr = S_OK; break; #endif case loCONV_CONVERT: if (S_OK == (hr = VariantCopy(variant, &te->primValue))) { if (!localize_max) localize_min = quality - upl->quality; localize_max = quality - upl->quality + 1; goto PreserveTP; } break; } loTagPair_init(tpl, 1); PreserveTP: #endif if (S_OK != hr) { LO_E_BADTYPE_QUAL(hr, *errors, *quality); masterqual = S_FALSE; mastererr = S_FALSE; continue; } Cont:; } if (OPC_QUALITY_GOOD != (OPC_QUALITY_MASK & *quality)) masterqual = S_FALSE; if (S_OK != *errors) mastererr = S_FALSE; } #if 2 == LO_EV_TIMESTAMP if (IsFILETIME(*se->ts_prim)) lo_check_ev_timestamp(upl->used, upl->timestamp, se->ts_prim); #endif lw_rw_unlock(&se->lkPrim); if (localize_max) se->driver.ldConvertTags(&upl->rctx.cactx, localize_max - localize_min, upl->tagpair + localize_min, upl->variant + localize_min, upl->quality + localize_min, upl->errors + localize_min, &mastererr, &masterqual, upl->variant + localize_min, upl->vartype + localize_min, upl->rctx.cta.vc_lcid); upl->master_qual = masterqual; /*if (upl->master_err == S_OK)*/ upl->master_err = mastererr; }
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; */ }