/// <summary> /// Initializes a new instance of the <see cref="DataStoreNodeWriter"/> class. /// </summary> /// <param name="maxLength">The maximum number of characters or bytes to read; or <c>-1</c> to read them all.</param> public DataStoreNodeWriter( int maxLength = -1 ) { this.root = null; this.parents = new List<IDataStoreObject>(); this.valueSerializer = new DataStoreValueSerializer(maxLength); this.objectSerializer = new DataStoreObjectSerializer(this.valueSerializer); }
private string WriteNode( IDataStoreNode node, bool indent ) { var sb = new StringBuilder(); using( var writer = new XmlDataStoreWriter(sb, indent) ) { if( node.NotNullReference() ) writer.Write(node); } return sb.ToString(); }
/// <summary> /// Initializes a new instance of the <see cref="DataStoreNodeWriter"/> class. /// </summary> /// <param name="valueSerializer">The <see cref="DataStoreValueSerializer"/> to use.</param> /// <param name="objectSerializer">The <see cref="DataStoreObjectSerializer"/> to use.</param> public DataStoreNodeWriter( DataStoreValueSerializer valueSerializer, DataStoreObjectSerializer objectSerializer ) { Ensure.That(valueSerializer).NotNull(); Ensure.That(objectSerializer).NotNull(); this.root = null; this.parents = new List<IDataStoreObject>(); this.valueSerializer = valueSerializer; this.objectSerializer = objectSerializer; }
/// <summary> /// Called when the object is being disposed of. Inheritors must call base.OnDispose to be properly disposed. /// </summary> /// <param name="disposing">If set to <c>true</c>, release both managed and unmanaged resources; otherwise release only the unmanaged resources.</param> protected override void OnDispose( bool disposing ) { if( disposing ) { //// dispose-only (i.e. non-finalizable) logic //// (managed, disposable resources you own) if( this.memoryStream.NotNullReference() ) { this.memoryStream.Dispose(); this.memoryStream = null; } } //// shared cleanup logic //// (unmanaged resources) this.root = null; this.binaryWriter = null; this.textWriter = null; base.OnDispose(disposing); }
/// <summary> /// Clears the writer (just as if it were newly created). /// </summary> public void Clear() { this.ThrowIfDisposed(); this.root = null; this.parents.Clear(); }
private void AddChild( IDataStoreNode node ) { if( this.parents.Count == 0 ) { if( this.root.NotNullReference() ) throw new InvalidOperationException("There can be at most one root node!").StoreFileLine(); else this.root = node; } else { var parent = this.parents[this.parents.Count - 1]; parent.Nodes.Add(node); } }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <param name="other">An object to compare this object to.</param> /// <returns><c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.</returns> public /*virtual*/ bool Equals( IDataStoreNode other ) { /* // in case we're overriding if( !base.Equals( other ) ) return false; */ // might not need this, if the base has checked it (or if 'other' is a value type) if( other.NullReference() ) return false; if( !DataStore.Comparer.Equals(this.Name, other.Name) ) return false; var value = this as IDataStoreValue; var otherValue = other as IDataStoreValue; if( value.NullReference() && otherValue.NullReference() ) { // both must be objects var obj = (IDataStoreObject)this; var otherObj = (IDataStoreObject)other; if( obj.Nodes.Count != otherObj.Nodes.Count ) return false; for( int i = 0; i < obj.Nodes.Count; ++i ) { if( !obj.Nodes[i].Equals(otherObj.Nodes[i]) ) return false; } return true; } else { // both are values var binary = value as IDataStoreBinaryValue; var otherBinary = otherValue as IDataStoreBinaryValue; if( binary.NotNullReference() && otherBinary.NotNullReference() ) { // both are binary values if( binary.Content.Count != otherBinary.Content.Count ) return false; for( int i = 0; i < binary.Content.Count; ++i ) { if( binary.Content.Array[binary.Content.Offset + i] != otherBinary.Content.Array[otherBinary.Content.Offset + i] ) return false; } return true; } else { var text = value as IDataStoreTextValue; var otherText = otherValue as IDataStoreTextValue; if( text.NotNullReference() && otherText.NotNullReference() ) { // both are text values return text.Content.Equals(otherText.Content, System.Globalization.CompareOptions.Ordinal, System.Globalization.CultureInfo.InvariantCulture); } else { throw new ArgumentException("Invalid type!").Store("type", this.GetType()).Store("otherType", other.GetType()); } } } }
/// <summary> /// Moves the reader to the next <see cref="DataStoreToken"/>. /// </summary> /// <param name="name">The name of the data store node found; or <c>null</c>.</param> /// <returns>The <see cref="DataStoreToken"/> found.</returns> protected override DataStoreToken ReadToken( out string name ) { if( this.Token == DataStoreToken.DataStoreStart ) { if( this.rootNode.NullReference() ) { this.currentNode = null; name = null; return DataStoreToken.DataStoreEnd; } else this.currentNode = this.rootNode; } else { if( this.parents.Count == 0 ) { if( this.rootNode is IDataStoreObject ) { this.currentNode = this.rootNode; name = this.currentNode.Name; this.PopObject(); return DataStoreToken.ObjectEnd; } else { this.currentNode = null; name = null; return DataStoreToken.DataStoreEnd; } } else { //// not at root level int infoAt = this.parents.Count - 1; var info = this.parents[infoAt]; if( info.Index == info.Object.Nodes.Count ) { this.currentNode = info.Object; name = this.currentNode.Name; this.PopObject(); return DataStoreToken.ObjectEnd; } else { this.currentNode = info.Object.Nodes[info.Index]; ++info.Index; this.parents[infoAt] = info; } } } // proces current node name = this.currentNode.Name; if( this.currentNode is IDataStoreObject ) { this.PushObject(); return DataStoreToken.ObjectStart; } else if( this.currentNode is IDataStoreTextValue ) return DataStoreToken.TextValue; else if( this.currentNode is IDataStoreBinaryValue ) return DataStoreToken.BinaryValue; else throw new Exception("Invalid data store node type!").Store("nodeType", this.currentNode.GetType()); }
/// <summary> /// Initializes a new instance of the <see cref="DataStoreNodeReader"/> class. /// </summary> /// <param name="rootNode">The node representing the data store root; or <c>null</c> for empty data stores.</param> public DataStoreNodeReader( IDataStoreNode rootNode ) : base() { this.rootNode = rootNode; }