/// <summary> /// Load a Cart Node from bindary stream, which is Mulan CRT compatible. /// </summary> /// <param name="br">Binary reader to load CART node.</param> public void Load(BinaryReader br) { if (br == null) { throw new ArgumentNullException("br"); } try { br.ReadInt32(); // Skip the yes child's offset br.ReadInt32(); // Skip the no child's offset NodeType noteType = (NodeType)br.ReadInt32(); if (noteType == NodeType.NotLeaf) { _question = new Question(_metaCart); uint size = br.ReadUInt32(); int startPos = br.ReadInt32(); OperatorSerial[] express = new OperatorSerial[size]; for (uint i = 0; i < size; i++) { express[i] = OperatorSerial.Read(br); } // TODO: parse it into logical presentation string logic = OperatorSerial.ToString(startPos, express); _question.Parse(logic); _leftChild = new CartNode(_metaCart); _leftChild.Load(br); _leftChild.Parent = this; _rightChild = new CartNode(_metaCart); _rightChild.Load(br); _rightChild.Parent = this; QuestionLogic = _question.ToString(); } else if (noteType == NodeType.Leaf) { // AbstractSet int setType = br.ReadInt32(); Debug.Assert(setType == (int)SetType.AbstractSet); int minValue = br.ReadInt32(); int maxValue = br.ReadInt32(); Debug.Assert(maxValue >= minValue); setType = br.ReadInt32(); _setType = (SetType)setType; switch (_setType) { case SetType.BitSet: { // BitSet int size = br.ReadInt32(); Debug.Assert(size == maxValue - minValue + 1); int setCount = br.ReadInt32(); // calculate the number of bytes to allocate to save // the bit set data. the data is INT (4 bytes) aligned int bytesRequired = ((size + 31) >> 5) * 4; byte[] bits = br.ReadBytes(bytesRequired); if (bits.Length != bytesRequired) { string message = string.Format(CultureInfo.InvariantCulture, "Malformed data found, for there is no enough data for Bit set."); throw new InvalidDataException(message); } _unitSet = new BitArray(bits); _unitSet.Length = size; int loadSetCount = 0; for (int k = 0; k < _unitSet.Length; k++) { loadSetCount += _unitSet.Get(k) ? 1 : 0; } Debug.Assert(loadSetCount == setCount); } break; case SetType.IndexSet: { // Count of integer int size = br.ReadInt32(); // Index data _unitSet = new BitArray(maxValue - minValue + 1); _unitSet.SetAll(false); int n = 0; for (int i = 0; i < size; i++) { n = br.ReadInt32(); if (n > _unitSet.Length - 1 || n < 0) { throw new InvalidDataException("Invalid index set data"); } _unitSet.Set(n, true); } } break; default: { throw new InvalidDataException("Invalid set type"); } } } else { Debug.Assert(false); string message = string.Format(CultureInfo.InvariantCulture, "Invalid node type [{0}] of CART tree node found", noteType); throw new InvalidDataException(message); } } catch (EndOfStreamException ese) { string message = string.Format(CultureInfo.InvariantCulture, "Fail to CART tree node from binary stream for invalid data."); throw new InvalidDataException(message, ese); } catch (InvalidDataException ide) { string message = string.Format(CultureInfo.InvariantCulture, "Fail to load CART node from binary stream"); throw new InvalidDataException(message, ide); } }
/// <summary> /// Load CART tree from binary stream. /// </summary> /// <param name="br">Binary reader to load CART tree from.</param> public void Load(BinaryReader br) { Nodes.Clear(); CartNode node = new CartNode(_metaCart); node.Load(br); Root = node; }