ULONG loEnum<BASE,ITEM,IFACE>::grow_list(ULONG newcount) { if (base || total > count) return 0; /* don't grow cloned lists */ if (newcount <= count) return count; newcount = (newcount + 3) & ~3; if (!preallocX((void**)&list, sizeof(ITEM) * newcount)) return 0; memset(list + count, 0, sizeof(ITEM) * (newcount - count)); count = newcount; return count; }
STDMETHODIMP LightOPCServer::BrowseOPCItemIDs( /* [in] */ OPCBROWSETYPE dwBrowseFilterType, /* [string][in] */ LPCWSTR szFilterCriteria, /* [in] */ VARTYPE vtDataTypeFilter, /* [in] */ DWORD dwAccessRightsFilter, /* [out] */ LPENUMSTRING *ppIEnumString) { HRESULT hr = S_OK; loEnumString *ulist = 0; LO_CHECK_STATEz1("BrowseOPCItemIDs", ppIEnumString); if (szFilterCriteria && !*szFilterCriteria) szFilterCriteria = 0; if (!ppIEnumString || dwBrowseFilterType != OPC_FLAT && dwBrowseFilterType != OPC_BRANCH && dwBrowseFilterType != OPC_LEAF) { hr = E_INVALIDARG; goto Return; } if (!(ulist = new loEnumString(0))) { hr = E_OUTOFMEMORY; goto Return; } { loTagId ti; lo_hash *hash_list = 0; loWchar brsep = se->branch_sep; BOOL casesens = 0 == (/*se->driver.*/ldFlags & loDF_IGNCASE); loWchar *brpos = 0; unsigned brlen = 0; int am_mask; loCallerx cctx = ctxt; loStringBuf aname; loStringBuf_init(&aname); lock_browse(); if (browsepos.sb_str) { brlen = wcslen(browsepos.sb_str); brpos = loWstrdup(browsepos.sb_str); } cctx.cta.vc_lcid = ctxt.cta.vc_lcid; unlock_browse(); if (brlen && !brpos) { hr = E_OUTOFMEMORY; goto Return; } if (!brsep) dwBrowseFilterType = OPC_FLAT; // level = lo_name_level(brsep, browsepos.sb_str); UL_TRACE((LOG_SR("Browse for: %u/%ls/ access %d"), brlen, loWnul(brpos), dwAccessRightsFilter)); dwAccessRightsFilter &= loOPC_RIGHTS; if (dwAccessRightsFilter == (OPC_READABLE | OPC_WRITEABLE)) dwAccessRightsFilter = 0; am_mask = dwAccessRightsFilter; if (access_mode & loAM_RDONLY_BROWSE) am_mask &= ~OPC_WRITEABLE; //loMilliSec stst = lo_millisec(); loLOCK_MGMT_O(&se->lkMgmt); for(ti = 0; ti = lo_browse_tag(se, ti, brpos, brlen, dwBrowseFilterType); ti++) { unsigned alen; loTagEntry *te = &se->tags[ti]; const loWchar *item = te->attr.taName + brlen; if (!*item) continue; /* don't return itself */ if (brsep == *item) item++; switch(dwBrowseFilterType) { case OPC_LEAF: if (wcschr(item, brsep)) continue; //if (1 < lo_name_level(brsep, item)) continue; case OPC_FLAT: alen = wcslen(item); if (dwAccessRightsFilter && !(am_mask/*dwAccessRightsFilter*/ & te->attr.taRights)) continue; if (vtDataTypeFilter != VT_EMPTY && S_OK != lo_checktype(&cctx, &te->attr, vtDataTypeFilter)) continue; break; case OPC_BRANCH: if (!wcschr(item, brsep)) continue; //if (1 >= lo_name_level(brsep, item)) continue; alen = lo_name_levlen(brsep, item, 1); { loWchar *uit; if (ulist->total && !se->wstrncmp(item, uit = ulist->list[ulist->total - 1], alen) && 0 == uit[alen]) continue; /* duplicate */ } break; } if (!loStringBuf_REALLOC(&aname, alen + 1)) { hr = E_OUTOFMEMORY; break; } wcsncpy(aname.sb_str, item, alen); aname.sb_str[alen] = 0; if (szFilterCriteria && !MatchPattern(aname.sb_str, szFilterCriteria, casesens)) continue; if (OPC_BRANCH == dwBrowseFilterType) { unsigned uu; lo_hash a_hash = loSTRHASH(se, aname.sb_str); for(uu = ulist->total; uu; uu--) if (a_hash == hash_list[uu-1] && !se->wstrcmp(aname.sb_str, ulist->list[uu-1]) ) break; if (uu) continue; if (!preallocX((void**)&hash_list, sizeof(*hash_list)*(ulist->total+1))) { hr = E_OUTOFMEMORY; break; } hash_list[ulist->total] = a_hash; } //UL_DEBUG((LOG_SR("Browse %ls"), aname.sb_str)); hr = ulist->add_item(&aname.sb_str); if (S_OK != hr) break; } /* end of for() */ loUnLOCK_MGMT_O(&se->lkMgmt); /* UL_WARNING((LOG_SR("BrowseOPC <%ls> %d TIME %d"), loWnul(brpos), ulist->total, lo_millisec() - stst)); //*/ if (brpos) freeX(brpos); if (hash_list) freeX(hash_list); loStringBuf_clear(&aname); } Return: if (S_OK == hr && S_OK == (hr = ulist->initiate(&otrk))) { *ppIEnumString = (LPENUMSTRING)ulist; UL_NOTICE((LOG_SR("BrowseOPCItemIDs() = %u"), ulist->total)); if (!ulist->total) { ENUM_EMPTY(hr, ldFlags, ppIEnumString); } } else { if (ulist) { delete ulist; ulist = 0; } UL_INFO((LOG_SR("BrowseOPCItemIDs() = %s"), loStrError(hr))); } LO_FINISH(); return hr; }