/// <summary> /// Restores PivotData from specified state object. /// </summary> /// <remarks>This method assumes that PivotData configuration (dimensions, aggregator factory) matches specified state object.</remarks> /// <param name="state">state object</param> public void SetState(PivotDataState state) { if (state.DimCount != Dimensions.Length) { throw new ArgumentException("Incompatible number of dimensions", "state"); } Clear(); values = new Dictionary <object[], IAggregator>(state.Values.Length, new ValueKeyEqualityComparer()); var revKeyIdx = new object[state.KeyValues.Length]; for (var i = 0; i < revKeyIdx.Length; i++) { revKeyIdx[i] = state.KeyValues[i]; } var dimLen = Dimensions.Length; uint d; IAggregator aggr; for (var i = 0; i < state.ValueKeys.Length; i++) { var vkIdx = state.ValueKeys[i]; var vkDimKeys = new object[dimLen]; for (d = 0; d < dimLen; d++) { vkDimKeys[d] = revKeyIdx[vkIdx[d]]; } if (values.TryGetValue(vkDimKeys, out aggr)) { aggr.Merge(AggregatorFactory.Create(state.Values[i])); } else { values[vkDimKeys] = AggregatorFactory.Create(state.Values[i]); } } if (!lazyTotals) { BatchCalcTotals(); } }
/// <summary> /// Deserializes <see cref="PivotDataState"/> from binary data contained by the specified stream /// </summary> /// <param name="stream">The <see cref="Stream"/> that contains serialized <see cref="PivotDataState"/> data</param> /// <returns>deserialized <see cref="PivotDataState"/> instance</returns> /// <remarks> /// This method is not supported in .NET Standards (.NET Core) PivotData build (use Json.NET or protobuf-net instead). /// </remarks> public static PivotDataState Deserialize(Stream stream) { using (var rdr = new PivotDataStateBinaryReader(stream)) { var typeName = rdr.ReadString(); if (typeName != typeof(PivotDataState).FullName) { throw new InvalidDataException(); } // read version (reserved for future) var majorVer = rdr.ReadInt32(); var minorVer = rdr.ReadInt32(); var propsCount = rdr.ReadUInt16(); var pvtDataState = new PivotDataState(0, null, null, null); for (short propIdx = 0; propIdx < propsCount; propIdx++) { var propName = rdr.ReadString(); switch (propName) { case "KeyValues": var keyValues = ReadObject(rdr); if (keyValues is object[]) { pvtDataState.KeyValues = (object[])keyValues; } else { throw new InvalidDataException("Invalid value type: KeyValues"); } break; case "Values": var values = ReadObject(rdr); if (values is object[]) { pvtDataState.Values = (object[])values; } else { throw new InvalidDataException("Invalid value type: Values"); } break; case "DimCount": pvtDataState.DimCount = rdr.ReadUInt32(); break; case "ValueKeys": if (pvtDataState.DimCount == 0) { throw new InvalidDataException("Missed DimCount property"); } pvtDataState.ValueKeys = ReadValueKeys(rdr, pvtDataState.DimCount); break; default: throw new InvalidDataException(String.Format("Unknown property: {0}", propName)); } } return(pvtDataState); } }