/// <summary> /// This property returns the AdditionalDetail as a 16-bit vendor-specific value /// if the AdditionalDetailType is set to AdditionalDetailType.VendorSpecific. /// If the AdditionalDetailType is set to a different value, 0 is returned. /// </summary> /// <param name="statusCode"> /// The 32-bit status code from which AdditionalDetail is to be extracted. /// </param> /// <returns> /// The vendor-specific AdditionalDetail value. 0 if the AdditionalDetailType /// indicates that the AdditionalDetail does not contain a vendor-specific value. /// </returns> public static ushort VendorSpecific(uint statusCode) { if (XiStatusCode.AdditionalDetailType(statusCode) == (byte)XiStatusCodeAdditionalDetailType.VendorSpecificDetail) { return((ushort)((statusCode) & AdditionalDetailMask)); } return(0); }
/// <summary> /// <para> /// Writing data object values to the server is a two step process composed of preparing a list of data objects /// to be written, followed by writing that list to the server. /// </para> /// <para> /// This method is used in the first step to individually mark each data object in the Data List as ready for /// writing. It examines all data objects in the Data List that are ready for writing and writes them to the server /// . /// </para> /// </summary> /// <returns> /// The list of data objects whose write failed. Results are not returned data object whose writes succeeded. If /// all writes succeeded, null is returned. /// </returns> public IEnumerable <IXiDataListItem>?CommitWriteDataListItems() { if (Disposed) { throw new ObjectDisposedException("Cannot access a disposed XiDataList."); } DataValueArraysWithAlias?writeValueArrays = null; var writeValueDictionary = new Dictionary <uint, XiDataListItem>(); int uintCount = 0; int dblCount = 0; int objCount = 0; foreach (XiDataListItem item in ListItemsManager) { if (item.PendingWriteValueStatusTimestamp is not null && item.PendingWriteValueStatusTimestamp.Value.ValueStatusCode != ValueStatusCode.Unknown) { switch (item.PendingWriteValueStatusTimestamp.Value.Value.ValueStorageType) { case Any.StorageType.Double: dblCount += 1; break; case Any.StorageType.UInt32: uintCount += 1; break; case Any.StorageType.Object: objCount += 1; break; } writeValueDictionary.Add(item.ClientAlias, item); } } if (0 < dblCount || 0 < uintCount || 0 < objCount) { writeValueArrays = new DataValueArraysWithAlias(dblCount, uintCount, objCount); int intIdx = 0; int dblIdx = 0; int objIdx = 0; foreach (var kvp in writeValueDictionary) { XiDataListItem item = kvp.Value; if (item.PendingWriteValueStatusTimestamp is not null && item.PendingWriteValueStatusTimestamp.Value.ValueStatusCode != ValueStatusCode.Unknown) { var statusCode = XiStatusCode.MakeStatusCode( XiStatusCode.MakeStatusByte((byte)XiStatusCodeStatusBits.GoodNonSpecific, 0), XiStatusCode.MakeFlagsByte((byte)XiStatusCodeHistoricalValueType.NotUsed, false, false, XiStatusCodeAdditionalDetailType.NotUsed), 0); switch (item.PendingWriteValueStatusTimestamp.Value.Value.ValueStorageType) { case Any.StorageType.Double: writeValueArrays.SetDouble(dblIdx++, item.ServerAlias, statusCode, item.PendingWriteValueStatusTimestamp.Value.TimestampUtc, item.PendingWriteValueStatusTimestamp.Value.Value.StorageDouble); break; case Any.StorageType.UInt32: writeValueArrays.SetUint(intIdx++, item.ServerAlias, statusCode, item.PendingWriteValueStatusTimestamp.Value.TimestampUtc, item.PendingWriteValueStatusTimestamp.Value.Value.StorageUInt32); break; case Any.StorageType.Object: writeValueArrays.SetObject(objIdx++, item.ServerAlias, statusCode, item.PendingWriteValueStatusTimestamp.Value.TimestampUtc, item.PendingWriteValueStatusTimestamp.Value.Value.StorageObject); break; } } item.HasWritten(XiFaultCodes.S_OK); } } var listXiValues = new List <XiDataListItem>(); if (writeValueArrays is not null) { List <AliasResult>?listAliasResult = Context.WriteData(ServerListId, writeValueArrays); if (listAliasResult is not null) { foreach (AliasResult aliasResult in listAliasResult) { XiDataListItem?item = null; if (writeValueDictionary.TryGetValue(aliasResult.ClientAlias, out item)) { item.HasWritten(aliasResult.Result); listXiValues.Add(item); } } } } writeValueDictionary.Clear(); return((0 != listXiValues.Count) ? listXiValues : null); }