/// <summary> /// Send CPMGetRowsIn. /// </summary> /// <param name="_hCursor">_hCursor field to be used.</param> /// <param name="_cRowsToTransfer">_cRowsToTransfer field to be used.</param> /// <param name="_cbRowWidth">_cbRowWidth field to be used.</param> /// <param name="_cbSeek">_cbSeek field to be used.</param> /// <param name="_cbReserved">_cbReserved field to be used.</param> /// <param name="_cbReadBuffer">_cbReadBuffer field to be used.</param> /// <param name="_ulClientBase">_ulClientBase field to be used.</param> /// <param name="_fBwdFetch">_fBwdFetch field to be used.</param> /// <param name="eType">eType field to be used.</param> /// <param name="_chapt">_chapt field to be used.</param> /// <param name="seekDescription">SeekDescription field to be used.</param> public void SendCPMGetRowsIn( uint _hCursor, uint _cRowsToTransfer, uint _cbRowWidth, uint _cbSeek, uint _cbReserved, uint _cbReadBuffer, uint _ulClientBase, uint _fBwdFetch, CPMGetRowsIn_eType_Values eType, uint _chapt, IWspSeekDescription seekDescription ) { var request = new CPMGetRowsIn { Header = new WspMessageHeader { _msg = WspMessageHeader_msg_Values.CPMGetRowsIn, }, _hCursor = _hCursor, _cRowsToTransfer = _cRowsToTransfer, _cbRowWidth = _cbRowWidth, _cbSeek = _cbSeek, _cbReserved = _cbReserved, _cbReadBuffer = _cbReadBuffer, _ulClientBase = _ulClientBase, _fBwdFetch = _fBwdFetch, eType = eType, _chapt = _chapt, SeekDescription = seekDescription, }; latestCPMGetRowsIn = request; Send(request); }
public void FromBytes(WspBuffer buffer) { var header = new WspMessageHeader(); var initialReadOffset = buffer.ReadOffset; header.FromBytes(buffer); Header = header; // Do not parse message body if the status in header is not success. if (header._status != (uint)WspErrorCode.SUCCESS && header._status != (uint)WspErrorCode.DB_S_ENDOFROWSET && header._status != (uint)WspErrorCode.DB_S_DIALECTIGNORED) { return; } _cRowsReturned = buffer.ToStruct <uint>(); eType = buffer.ToStruct <RowSeekType>(); _chapt = buffer.ToStruct <uint>(); switch (eType) { case RowSeekType.eRowSeekNone: SeekDescription = null; break; case RowSeekType.eRowSeekNext: SeekDescription = buffer.ToStruct <CRowSeekNext>(); break; case RowSeekType.eRowSeekAt: SeekDescription = buffer.ToStruct <CRowSeekAt>(); break; case RowSeekType.eRowSeekAtRatio: SeekDescription = buffer.ToStruct <CRowSeekAtRatio>(); break; case RowSeekType.eRowSeekByBookmark: var tempSeekDescription = new CRowSeekByBookmark(); tempSeekDescription.FromBytes(buffer); SeekDescription = tempSeekDescription; break; } int rowStartIndex = initialReadOffset + (int)((CPMGetRowsIn)Request)._cbReserved; int paddingSize = rowStartIndex - buffer.ReadOffset; paddingRows = buffer.ReadBytes(paddingSize); rowStartIndex = buffer.ReadOffset; Rows = new Row[_cRowsReturned]; uint cColumns = BindingRequest.cColumns; for (int i = 0; i < _cRowsReturned; i++) { Rows[i].Columns = new Column[cColumns]; for (int j = 0; j < cColumns; j++) { if (BindingRequest.aColumns[j].StatusOffset != null) { Rows[i].Columns[j].Status = (StoreStatus)buffer.Peek <byte>(rowStartIndex + BindingRequest.aColumns[j].StatusOffset.Value); } if (BindingRequest.aColumns[j].LengthOffset != null) { Rows[i].Columns[j].Length = buffer.Peek <byte>(rowStartIndex + BindingRequest.aColumns[j].LengthOffset.Value); } if (BindingRequest.aColumns[j].ValueOffset != null) { int valueOffset = rowStartIndex + BindingRequest.aColumns[j].ValueOffset.Value; if (BindingRequest.aColumns[j].vType == CBaseStorageVariant_vType_Values.VT_VARIANT) { Rows[i].Columns[j].RowVariant = new CTableVariant(); Rows[i].Columns[j].RowVariant.Is64bit = this.Is64Bit; WspBuffer rowVariantBuffer = new WspBuffer(buffer.ReadBytesFromOffset(valueOffset, BindingRequest.aColumns[j].ValueSize.Value)); Rows[i].Columns[j].RowVariant.FromBytes(rowVariantBuffer); if (Rows[i].Columns[j].RowVariant.vType == CBaseStorageVariant_vType_Values.VT_LPWSTR) { int dataOffset = GetRealOffset(Rows[i].Columns[j].RowVariant.Offset); Rows[i].Columns[j].Data = ReadValueByType(Rows[i].Columns[j].RowVariant.vType, dataOffset, buffer); } else if (Rows[i].Columns[j].RowVariant.vType.HasFlag(CBaseStorageVariant_vType_Values.VT_VECTOR)) { var baseVType = Rows[i].Columns[j].RowVariant.vType ^ CBaseStorageVariant_vType_Values.VT_VECTOR; var vectorCount = Rows[i].Columns[j].RowVariant.Count; if (baseVType == CBaseStorageVariant_vType_Values.VT_LPWSTR) { var startOffset = GetRealOffset(Rows[i].Columns[j].RowVariant.Offset); var items = new List <string>(); for (var idx = 0; idx < vectorCount; idx++) { WspBuffer offsetBuffer; int itemOffset; if (Is64Bit) { offsetBuffer = new WspBuffer(buffer.ReadBytesFromOffset(startOffset + idx * 8, 8)); itemOffset = GetRealOffset(offsetBuffer.ToStruct <long>()); } else { offsetBuffer = new WspBuffer(buffer.ReadBytesFromOffset(startOffset + idx * 4, 4)); itemOffset = GetRealOffset(offsetBuffer.ToStruct <int>()); } var item = ReadValueByType(CBaseStorageVariant_vType_Values.VT_LPWSTR, itemOffset, buffer) as string; items.Add(item); } Rows[i].Columns[j].Data = items.ToArray(); } else if (baseVType == CBaseStorageVariant_vType_Values.VT_FILETIME) { var startOffset = GetRealOffset(Rows[i].Columns[j].RowVariant.Offset); var items = new List <object>(); for (var idx = 0; idx < vectorCount; idx++) { var item = ReadValueByType(CBaseStorageVariant_vType_Values.VT_FILETIME, startOffset, buffer); startOffset += 8; // VT_FILETIME is a 64-bit value items.Add(item); } Rows[i].Columns[j].Data = items.ToArray(); } else { throw new NotImplementedException(); } } else { // If the type is not a string, the offset field saves the actual data. Rows[i].Columns[j].Data = ReadValueByType(Rows[i].Columns[j].RowVariant.vType, 8, rowVariantBuffer); } } else { Rows[i].Columns[j].Data = ReadValueByType(BindingRequest.aColumns[j].vType, valueOffset, buffer); } } } rowStartIndex += (int)((CPMGetRowsIn)Request)._cbRowWidth; } }