/* * Copyright (C) 2007-2012 Xagasoft, All rights reserved. * * This file is part of the libgats library and is released under the * terms of the license contained in the file LICENSE. */ using System.Text; using System.IO; using System.Linq; using System.Collections; using System.Collections.Generic; namespace Com.Xagasoft.Gats { /// /// Encapsulates a single dictionary of GatsObjects. /// /// /// All keys are strings, and are encoded UTF-8. At the moment it is /// advisable to stick to 7-bit ASCII or LATIN-1 compatible strings for /// interoperability. If you want full unicode for keys, be sure you /// handle it correctly with all libraries. /// /// Values can be any valid GatsObject. /// /// Just like dictionaries in memory, order is not important and is /// considered random in encoded GATS. This means that dictionary items /// may be in a different order after writing them and reading them back /// again. Do not rely on a specific order, if you need ordered data use /// a GatsList. /// /// All standard dictionary interface methods are implemented, so you can /// use a GatsDictionary just like the .NET standard Dictionary. /// public class GatsDictionary : GatsObject, IDictionary // ICollection>, // IEnumerable> { private Dictionary Value = new Dictionary(); public GatsDictionary() { } public override string ToString() { StringBuilder bld = new StringBuilder(); bld.Append("{"); bool begin = true; foreach( KeyValuePair j in Value ) { if( begin ) begin = false; else bld.Append(", "); bld.Append( j.Key ); bld.Append(" = "); bld.Append( j.Value ); } bld.Append("}"); return bld.ToString(); } public override void Read( Stream s, char type ) { for(;;) { GatsObject key = GatsObject.Read( s ); if( key == null ) break; if( key.GetType() != typeof(GatsString) ) throw new GatsException( GatsException.Type.InvalidFormat ); Value.Add( key.ToString(), GatsObject.Read( s ) ); } } public override void Write( Stream s ) { s.WriteByte( (int)'d' ); foreach( KeyValuePair j in Value ) { new GatsString( j.Key ).Write( s ); j.Value.Write( s ); } s.WriteByte( (int)'e' ); } // // Extra helper functions for making life with GATS easier // /// /// Helper function to add a new GatsString to the dictionary from a /// byte array. /// /// The key to insert the new value with /// The byte array to be inserted as a string public void Add( string key, byte[] val ) { Add( key, new GatsString( val ) ); } /// /// Helper function to add a new GatsString to the dictionary from a /// string. /// /// /// The string is encoded UTF-8 by .NETs internal facilities. /// /// The key to insert the new value with /// The string to be inserted as a string public void Add( string key, string val ) { Add( key, new GatsString( val ) ); } /// /// Helper function to add a new GatsInteger to the dictionary. /// /// /// Implicit upcasting should allow all integer types (byte, short, /// int, long), and automatic unboxing should allow all object variants /// to be passed into this method without problem. /// /// The key to insert the new value with /// The long to be inserted public void Add( string key, long val ) { Add( key, new GatsInteger( val ) ); } /// /// Helper function to add a new GatsFloat to the dictionary. /// /// /// Implicit upcasting should allow floats and doubles to both be /// accepted by this method. Please note that decimal types are not /// strictly compatible, please see GatsFloat for more details. /// /// The key to insert the new value with /// The double to be inserted public void Add( string key, double val ) { Add( key, new GatsFloat( val ) ); } /// /// Helper function to add a new GatsBoolean to the dictionary. /// /// The key to insert the new value with /// The boolean value to be inserted public void Add( string key, bool val ) { Add( key, new GatsBoolean( val ) ); } /// /// Helper function to add a new GatsNull to the dictionary. /// /// The key to insert the new null value with public void AddNull( string key ) { Add( key, new GatsNull() ); } /// /// Helper function to add a new GatsDictionary to the dictionary. /// /// /// A new GatsDictionary is created, added to the dictionary, and /// returned. /// /// The key to insert the new value with /// A new, empty dictionary that is already added public GatsDictionary AddDict( string key ) { GatsDictionary dict = new GatsDictionary(); Add( key, dict ); return dict; } /// /// Helper function to add a new GatsList to the dictionary. /// /// /// A new GatsList is created, added to the dictionary, and returned. /// /// The key to insert the new value with /// A new, empty list that is already added public GatsList AddList( string key ) { GatsList list = new GatsList(); Add( key, list ); return list; } // // List interface overrides under here. // public void Add( string key, GatsObject obj ) { Value.Add( key, obj ); } public bool Remove( string key ) { return Value.Remove( key ); } public bool ContainsKey( string key ) { return Value.ContainsKey( key ); } public bool TryGetValue( string key, out GatsObject obj ) { return Value.TryGetValue( key, out obj ); } public GatsObject this[string key] { get { return this.Value[key]; } set { this.Value[key] = value; } } public ICollection Keys { get { return this.Value.Keys; } } public ICollection Values { get { return this.Value.Values; } } public int Count { get { return this.Value.Count; } } public bool IsReadOnly { get { return false; } // return this.Value.IsReadOnly; } } public void Add( KeyValuePair pair ) { ((IDictionary)Value).Add( pair ); } public void Clear() { Value.Clear(); } public bool Contains( KeyValuePair pair ) { return ((IDictionary)Value).Contains( pair ); } public void CopyTo( KeyValuePair[] result, int count ) { ((IDictionary)Value).CopyTo( result, count ); } public bool Remove( KeyValuePair pair ) { return ((IDictionary)Value).Remove( pair ); } IEnumerator > IEnumerable >.GetEnumerator() { return Value.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return Value.GetEnumerator(); } } }