aboutsummaryrefslogtreecommitdiff
path: root/cs-dotnet/src/gatslist.cs
blob: dd0c84cf326ab4b2efc7417796dda90722c59dab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/*
 * Copyright (C) 2007-2013 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;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

namespace Com.Xagasoft.Gats
{
    /// <summary>
    /// Encapsulates a single list of GatsObjects.
    /// </summary>
    /// <remarks>
    /// A list of arbitrary size containing ordered GatsObjects.  All standard
    /// .NET IList, ICollection, and IEnumerable interfaces are implemented,
    /// so a GatsList should work just like a standard List, but with a few
    /// extras.
    /// </remarks>
    public class GatsList : GatsObject, IList<GatsObject>,
        ICollection<GatsObject>, IEnumerable<GatsObject>
//        IReadOnlyList<GatsObject>, IReadOnlyCollection<GatsObject>,
//        These two are in .net 4.5, not 4.0, mono can't use them.
    {
        private List<GatsObject> Value = new List<GatsObject>();

        public GatsList()
        {
        }

        public override string ToString()
        {
            StringBuilder bld = new StringBuilder();
            bld.Append("[");
            for( int j = 0; j < Value.Count-1; j++ )
            {
                bld.Append( Value[j] );
                bld.Append(", ");
            }
            bld.Append( Value[Value.Count-1] );
            bld.Append("]");
            return bld.ToString();
        }

        public override void Read( Stream s, char type )
        {
            for(;;)
            {
                GatsObject obj = GatsObject.Read( s );
                if( obj == null )
                    break;
                Value.Add( obj );
            }
        }

        public override void Write( Stream s )
        {
            s.WriteByte( (int)'l' );
            foreach( GatsObject obj in Value )
            {
                obj.Write( s );
            }
            s.WriteByte( (int)'e' );
        }

        //
        // Helper functions
        //

        /// <summary>
        /// Helper function to add a new GatsString to the list.
        /// </summary>
        /// <param name="val">The byte array to be added as a GatsString</param>
        public void Add( byte[] val )
        {
            Add( new GatsString( val ) );
        }

        /// <summary>
        /// Helper function to add a new GatsString to the list.
        /// </summary>
        /// <remarks>
        /// The string is encoded UTF-8 by .NETs internal facilities.
        /// </remarks>
        /// <param name="val">The string to be added as a GatsString</param>
        public void Add( string val )
        {
            Add( new GatsString( val ) );
        }

        /// <summary>
        /// Helper function to add a new GatsInteger to the list.
        /// </summary>
        /// <remarks>
        /// 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.
        /// </remarks>
        /// <param name="val">The long to be added as a GatsInteger</param>
        public void Add( long val )
        {
            Add( new GatsInteger( val ) );
        }

        /// <summary>
        /// Helper function to add a new GatsFloat to the list.
        /// </summary>
        /// <remarks>
        /// 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.
        /// </remarks>
        /// <param name="val">The double to be added as a GatsFloat</param>
        public void Add( double val )
        {
            Add( new GatsFloat( val ) );
        }

        /// <summary>
        /// Helper function to add a new GatsBoolean to the list.
        /// </summary>
        /// <param name="val">
        /// The boolean value to be added as a GatsBoolean
        /// </param>
        public void Add( bool val )
        {
            Add( new GatsBoolean( val ) );
        }

        /// <summary>
        /// Helper to append a GatsNull to the list.
        /// </summary>
        public void AddNull()
        {
            Add( new GatsNull() );
        }

        /// <summary>
        /// Helper to append a GatsDictionary to the list.
        /// </summary>
        /// <remarks>
        /// A new GatsDictionary is constructed, appended to the list, and
        /// returned.
        /// </remarks>
        public GatsDictionary AddDict()
        {
            GatsDictionary dict = new GatsDictionary();
            Add( dict );
            return dict;
        }

        /// <summary>
        /// Helper to append a GatsList to the list.
        /// </summary>
        /// <remarks>
        /// A new GatsList is constructed, appended to the list, and returned.
        /// </remarks>
        public GatsList AddList()
        {
            GatsList list = new GatsList();
            Add( list );
            return list;
        }

        //
        // List interface overrides under here.
        //
        public int IndexOf( GatsObject obj )
        {
            return Value.IndexOf( obj );
        }

        public void Insert( int idx, GatsObject obj )
        {
            Value.Insert( idx, obj );
        }

        public void RemoveAt( int idx )
        {
            Value.RemoveAt( idx );
        }

        public GatsObject this[int idx] {
            get { return this.Value[idx]; }
            set { this.Value[idx] = value; }
        }
        
        public int Count {
            get { return this.Value.Count; }
        }

        public bool IsReadOnly {
            get { return false; } // this.Value.IsReadOnly; }
        }

        public void Add( GatsObject obj )
        {
            Value.Add( obj );
        }

        public void Clear()
        {
            Value.Clear();
        }

        public bool Contains( GatsObject obj )
        {
            return Value.Contains( obj );
        }

        public void CopyTo( GatsObject[] result, int count )
        {
            Value.CopyTo( result, count );
        }

        public bool Remove( GatsObject obj )
        {
            return Value.Remove( obj );
        }

        IEnumerator<GatsObject> IEnumerable<GatsObject>.GetEnumerator()
        {
            return Value.GetEnumerator();
        }
        
        IEnumerator IEnumerable.GetEnumerator()
        {
            return Value.GetEnumerator();
        }

        public bool IsFixedSize {
            get { return false; } // this.Value.IsFixedSize; }
        }

        public bool IsSynchronized {
            get { return false; } // this.Value.IsSynchronized; }
        }

        public object SyncRoot {
            get { return null; } // this.Value.SyncRoot; }
        }

    }
}