/*
* 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();
}
}
}