/// <param name="cellBytes">If property is external, byte[0] means empty data item</param> public void SetPropertyValue(int rowIndex, int columnIndex, byte[] propertyBytes) { TableColumnDescriptor columnDescriptor = m_tcInfo.rgTCOLDESC[columnIndex]; if (columnDescriptor.IsStoredExternally) { byte[] cellBytes = GetInternalCellBytes(rowIndex, columnIndex); HeapOrNodeID heapOrNodeID; if (cellBytes != null) { heapOrNodeID = new HeapOrNodeID(cellBytes); } else { heapOrNodeID = new HeapOrNodeID(HeapID.EmptyHeapID); } HeapOrNodeID newHeapOrNodeID = NodeStorageHelper.StoreExternalProperty(this.File, m_heap, ref m_subnodeBTree, heapOrNodeID, propertyBytes); // we call SetInternalCellBytes even when oldHeapID.Value == newHeapID.Value, // this will make sure the CEB will be updated SetInternalCellBytes(rowIndex, columnIndex, LittleEndianConverter.GetBytes(newHeapOrNodeID.Value)); } else { SetInternalCellBytes(rowIndex, columnIndex, propertyBytes); } }
public void SetExternalProperty(PropertyID propertyID, PropertyTypeName propertyType, byte[] propertyBytes) { PropertyContextRecord record = GetRecordByPropertyID(propertyID); if (record != null) { if (record.wPropType != propertyType) { throw new InvalidPropertyException("Property type mismatch"); } if (record.IsExternal) { HeapOrNodeID newHeapOrNodeID = NodeStorageHelper.StoreExternalProperty(this.File, this.Heap, ref m_subnodeBTree, record.HeapOrNodeID, propertyBytes); if (record.HeapOrNodeID.Value != newHeapOrNodeID.Value) { record.HeapOrNodeID = newHeapOrNodeID; UpdateRecord(record); } } else { // old record is not external but new record is, this should never happen. throw new InvalidPropertyException("Old record should be external but is not"); } } else // old record does not exist { record = new PropertyContextRecord(); record.HeapOrNodeID = NodeStorageHelper.StoreExternalProperty(this.File, this.Heap, ref m_subnodeBTree, propertyBytes); record.wPropId = propertyID; record.wPropType = propertyType; AddRecord(record); } }