wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * TclList.java
3 *
4 * Copyright (c) 1997 Sun Microsystems, Inc.
5 *
6 * See the file "license.terms" for information on usage and
7 * redistribution of this file, and for a DISCLAIMER OF ALL
8 * WARRANTIES.
9 *
10 * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
11 *
12 * RCS @(#) $Id: TclList.java,v 1.5 2003/01/09 02:15:39 mdejong Exp $
13 *
14 */
15 using System;
16 using System.Collections;
17 using System.Text;
18  
19 namespace tcl.lang
20 {
21  
22 /// <summary> This class implements the list object type in Tcl.</summary>
23 public class TclList : InternalRep
24 {
25  
26 /// <summary> Internal representation of a list value.</summary>
27 private ArrayList vector;
28  
29 /// <summary> Create a new empty Tcl List.</summary>
30 private TclList()
31 {
32 vector = new ArrayList( 10 );
33 }
34  
35 /// <summary> Create a new empty Tcl List, with the vector pre-allocated to
36 /// the given size.
37 ///
38 /// </summary>
39 /// <param name="size">the number of slots pre-allocated in the vector.
40 /// </param>
41 private TclList( int size )
42 {
43 vector = new ArrayList( size );
44 }
45  
46 /// <summary> Called to free any storage for the type's internal rep.</summary>
47 /// <param name="obj">the TclObject that contains this internalRep.
48 /// </param>
49 public void dispose()
50 {
51 int size = vector.Count;
52 for ( int i = 0; i < size; i++ )
53 {
54 ( (TclObject)vector[i] ).release();
55 }
56 }
57  
58 /// <summary> DupListInternalRep -> duplicate
59 ///
60 /// Returns a dupilcate of the current object.
61 ///
62 /// </summary>
63 /// <param name="obj">the TclObject that contains this internalRep.
64 /// </param>
65 public InternalRep duplicate()
66 {
67 int size = vector.Count;
68 TclList newList = new TclList( size );
69  
70 for ( int i = 0; i < size; i++ )
71 {
72 TclObject tobj = (TclObject)vector[i];
73 tobj.preserve();
74 newList.vector.Add( tobj );
75 }
76  
77 return newList;
78 }
79  
80 /// <summary> Called to query the string representation of the Tcl object. This
81 /// method is called only by TclObject.toString() when
82 /// TclObject.stringRep is null.
83 ///
84 /// </summary>
85 /// <returns> the string representation of the Tcl object.
86 /// </returns>
87 public override string ToString()
88 {
89 StringBuilder sbuf = new StringBuilder();
90 int size = vector.Count;
91  
92 try
93 {
94 for ( int i = 0; i < size; i++ )
95 {
96 Object elm = vector[i];
97 if ( elm != null )
98 {
99  
100 Util.appendElement( null, sbuf, elm.ToString() );
101 }
102 else
103 {
104 Util.appendElement( null, sbuf, "" );
105 }
106 }
107 }
108 catch ( TclException e )
109 {
110 throw new TclRuntimeError( "unexpected TclException: " + e.Message, e );
111 }
112  
113 return sbuf.ToString();
114 }
115  
116 /// <summary> Creates a new instance of a TclObject with a TclList internal
117 /// rep.
118 ///
119 /// </summary>
120 /// <returns> the TclObject with the given list value.
121 /// </returns>
122  
123 public static TclObject newInstance()
124 {
125 return new TclObject( new TclList() );
126 }
127  
128 /// <summary> Called to convert the other object's internal rep to list.
129 ///
130 /// </summary>
131 /// <param name="interp">current interpreter.
132 /// </param>
133 /// <param name="tobj">the TclObject to convert to use the List internal rep.
134 /// </param>
135 /// <exception cref=""> TclException if the object doesn't contain a valid list.
136 /// </exception>
137 internal static void setListFromAny( Interp interp, TclObject tobj )
138 {
139 InternalRep rep = tobj.InternalRep;
140  
141 if ( !( rep is TclList ) )
142 {
143 TclList tlist = new TclList();
144  
145 splitList( interp, tlist.vector, tobj.ToString() );
146 tobj.InternalRep = tlist;
147 }
148 }
149  
150 /// <summary> Splits a list (in string rep) up into its constituent fields.
151 ///
152 /// </summary>
153 /// <param name="interp">current interpreter.
154 /// </param>
155 /// <param name="v">store the list elements in this vector.
156 /// </param>
157 /// <param name="s">the string to convert into a list.
158 /// </param>
159 /// <exception cref=""> TclException if the object doesn't contain a valid list.
160 /// </exception>
161 private static void splitList( Interp interp, ArrayList v, string s )
162 {
163 int len = s.Length;
164 int i = 0;
165  
166 while ( i < len )
167 {
168 FindElemResult res = Util.findElement( interp, s, i, len );
169 if ( res == null )
170 {
171 break;
172 }
173 else
174 {
175 TclObject tobj = TclString.newInstance( res.elem );
176 tobj.preserve();
177 v.Add( tobj );
178 }
179 i = res.elemEnd;
180 }
181 }
182  
183  
184 /// <summary> Tcl_ListObjAppendElement -> TclList.append()
185 ///
186 /// Appends a TclObject element to a list object.
187 ///
188 /// </summary>
189 /// <param name="interp">current interpreter.
190 /// </param>
191 /// <param name="tobj">the TclObject to append an element to.
192 /// </param>
193 /// <param name="elemObj">the element to append to the object.
194 /// </param>
195 /// <exception cref=""> TclException if tobj cannot be converted into a list.
196 /// </exception>
197 public static void append( Interp interp, TclObject tobj, TclObject elemObj )
198 {
199 if ( tobj.Shared )
200 {
201 throw new TclRuntimeError( "TclList.append() called with shared object" );
202 }
203 setListFromAny( interp, tobj );
204 tobj.invalidateStringRep();
205  
206 TclList tlist = (TclList)tobj.InternalRep;
207 elemObj.preserve();
208 tlist.vector.Add( elemObj );
209 }
210  
211 /// <summary> Queries the length of the list. If tobj is not a list object,
212 /// an attempt will be made to convert it to a list.
213 ///
214 /// </summary>
215 /// <param name="interp">current interpreter.
216 /// </param>
217 /// <param name="tobj">the TclObject to use as a list.
218 /// </param>
219 /// <returns> the length of the list.
220 /// </returns>
221 /// <exception cref=""> TclException if tobj is not a valid list.
222 /// </exception>
223 public static int getLength( Interp interp, TclObject tobj )
224 {
225 setListFromAny( interp, tobj );
226  
227 TclList tlist = (TclList)tobj.InternalRep;
228 return tlist.vector.Count;
229 }
230  
231 /// <summary> Returns a TclObject array of the elements in a list object. If
232 /// tobj is not a list object, an attempt will be made to convert
233 /// it to a list. <p>
234 ///
235 /// The objects referenced by the returned array should be treated
236 /// as readonly and their ref counts are _not_ incremented; the
237 /// caller must do that if it holds on to a reference.
238 ///
239 /// </summary>
240 /// <param name="interp">the current interpreter.
241 /// </param>
242 /// <param name="tobj">the list to sort.
243 /// </param>
244 /// <returns> a TclObject array of the elements in a list object.
245 /// </returns>
246 /// <exception cref=""> TclException if tobj is not a valid list.
247 /// </exception>
248 public static TclObject[] getElements( Interp interp, TclObject tobj )
249 {
250 setListFromAny( interp, tobj );
251 TclList tlist = (TclList)tobj.InternalRep;
252  
253 int size = tlist.vector.Count;
254 TclObject[] objArray = new TclObject[size];
255 for ( int i = 0; i < size; i++ )
256 {
257 objArray[i] = (TclObject)tlist.vector[i];
258 }
259 return objArray;
260 }
261  
262 /// <summary> This procedure returns a pointer to the index'th object from
263 /// the list referenced by tobj. The first element has index
264 /// 0. If index is negative or greater than or equal to the number
265 /// of elements in the list, a null is returned. If tobj is not a
266 /// list object, an attempt will be made to convert it to a list.
267 ///
268 /// </summary>
269 /// <param name="interp">current interpreter.
270 /// </param>
271 /// <param name="tobj">the TclObject to use as a list.
272 /// </param>
273 /// <param name="index">the index of the requested element.
274 /// </param>
275 /// <returns> the the requested element.
276 /// </returns>
277 /// <exception cref=""> TclException if tobj is not a valid list.
278 /// </exception>
279 public static TclObject index( Interp interp, TclObject tobj, int index )
280 {
281 setListFromAny( interp, tobj );
282  
283 TclList tlist = (TclList)tobj.InternalRep;
284 if ( index < 0 || index >= tlist.vector.Count )
285 {
286 return null;
287 }
288 else
289 {
290 return (TclObject)tlist.vector[index];
291 }
292 }
293  
294 /// <summary> This procedure inserts the elements in elements[] into the list at
295 /// the given index. If tobj is not a list object, an attempt will
296 /// be made to convert it to a list.
297 ///
298 /// </summary>
299 /// <param name="interp">current interpreter.
300 /// </param>
301 /// <param name="tobj">the TclObject to use as a list.
302 /// </param>
303 /// <param name="index">the starting index of the insertion operation. <=0 means
304 /// the beginning of the list. >= TclList.getLength(tobj) means
305 /// the end of the list.
306 /// </param>
307 /// <param name="elements">the element(s) to insert.
308 /// </param>
309 /// <param name="from">insert elements starting from elements[from] (inclusive)
310 /// </param>
311 /// <param name="to">insert elements up to elements[to] (inclusive)
312 /// </param>
313 /// <exception cref=""> TclException if tobj is not a valid list.
314 /// </exception>
315 internal static void insert( Interp interp, TclObject tobj, int index, TclObject[] elements, int from, int to )
316 {
317 if ( tobj.Shared )
318 {
319 throw new TclRuntimeError( "TclList.insert() called with shared object" );
320 }
321 replace( interp, tobj, index, 0, elements, from, to );
322 }
323  
324 /// <summary> This procedure replaces zero or more elements of the list
325 /// referenced by tobj with the objects from an TclObject array.
326 /// If tobj is not a list object, an attempt will be made to
327 /// convert it to a list.
328 ///
329 /// </summary>
330 /// <param name="interp">current interpreter.
331 /// </param>
332 /// <param name="tobj">the TclObject to use as a list.
333 /// </param>
334 /// <param name="index">the starting index of the replace operation. <=0 means
335 /// the beginning of the list. >= TclList.getLength(tobj) means
336 /// the end of the list.
337 /// </param>
338 /// <param name="count">the number of elements to delete from the list. <=0 means
339 /// no elements should be deleted and the operation is equivalent to
340 /// an insertion operation.
341 /// </param>
342 /// <param name="elements">the element(s) to insert.
343 /// </param>
344 /// <param name="from">insert elements starting from elements[from] (inclusive)
345 /// </param>
346 /// <param name="to">insert elements up to elements[to] (inclusive)
347 /// </param>
348 /// <exception cref=""> TclException if tobj is not a valid list.
349 /// </exception>
350 public static void replace( Interp interp, TclObject tobj, int index, int count, TclObject[] elements, int from, int to )
351 {
352 if ( tobj.Shared )
353 {
354 throw new TclRuntimeError( "TclList.replace() called with shared object" );
355 }
356 setListFromAny( interp, tobj );
357 tobj.invalidateStringRep();
358 TclList tlist = (TclList)tobj.InternalRep;
359  
360 int size = tlist.vector.Count;
361 int i;
362  
363 if ( index >= size )
364 {
365 // Append to the end of the list. There is no need for deleting
366 // elements.
367 index = size;
368 }
369 else
370 {
371 if ( index < 0 )
372 {
373 index = 0;
374 }
375 if ( count > size - index )
376 {
377 count = size - index;
378 }
379 for ( i = 0; i < count; i++ )
380 {
381 TclObject obj = (TclObject)tlist.vector[index];
382 obj.release();
383 tlist.vector.RemoveAt( index );
384 }
385 }
386 for ( i = from; i <= to; i++ )
387 {
388 elements[i].preserve();
389 tlist.vector.Insert( index++, elements[i] );
390 }
391 }
392  
393 /// <summary> Sorts the list according to the sort mode and (optional) sort command.
394 /// The resulting list will contain no duplicates, if argument unique is
395 /// specifed as true.
396 /// If tobj is not a list object, an attempt will be made to
397 /// convert it to a list.
398 ///
399 /// </summary>
400 /// <param name="interp">the current interpreter.
401 /// </param>
402 /// <param name="tobj">the list to sort.
403 /// </param>
404 /// <param name="sortMode">the sorting mode.
405 /// </param>
406 /// <param name="sortIncreasing">true if to sort the elements in increasing order.
407 /// </param>
408 /// <param name="command">the command to compute the order of two elements.
409 /// </param>
410 /// <param name="unique">true if the result should contain no duplicates.
411 /// </param>
412 /// <exception cref=""> TclException if tobj is not a valid list.
413 /// </exception>
414  
415 internal static void sort( Interp interp, TclObject tobj, int sortMode, int sortIndex, bool sortIncreasing, string command, bool unique )
416 {
417 setListFromAny( interp, tobj );
418 tobj.invalidateStringRep();
419 TclList tlist = (TclList)tobj.InternalRep;
420  
421 int size = tlist.vector.Count;
422  
423 if ( size <= 1 )
424 {
425 return;
426 }
427  
428 TclObject[] objArray = new TclObject[size];
429 for ( int i = 0; i < size; i++ )
430 {
431 objArray[i] = (TclObject)tlist.vector[i];
432 }
433  
434 QSort s = new QSort();
435 int newsize = s.sort( interp, objArray, sortMode, sortIndex, sortIncreasing, command, unique );
436  
437 for ( int i = 0; i < size; i++ )
438 {
439 if ( i < newsize )
440 {
441 tlist.vector[i] = objArray[i];
442 objArray[i] = null;
443 }
444 else
445 tlist.vector.RemoveAt( newsize );
446 }
447 }
448 }
449 }