KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > mapping > Values


1 package gnu.mapping;
2 import java.io.*;
3 import gnu.lists.*;
4 import gnu.text.Printable;
5
6 /** Encapsulate multiple values in a single object.
7  * In Scheme and Lisp mainly used to return multiple values from a function.
8  */

9
10 public class Values extends TreeList implements Printable, Externalizable
11 {
12   public static final Object JavaDoc[] noArgs = new Object JavaDoc[0];
13
14   public static final Values empty = new Values(noArgs);
15
16   public Values ()
17   {
18   }
19
20   /** Constructor.
21    * @param values the values to encapulate
22    */

23   public Values (Object JavaDoc[] values)
24   {
25     for (int i = 0; i < values.length; i++)
26       writeObject(values[i]);
27   }
28
29   /** Get the values encapsulated. */
30   // Used by CallContext.writeValue, call_with_values.apply(CallContext) FIXME
31
public Object JavaDoc[] getValues ()
32   {
33     return isEmpty() ? noArgs : toArray();
34   }
35
36   public static Object JavaDoc values$V(Object JavaDoc[] vals)
37   {
38     return make(vals);
39   }
40
41   public static Values make ()
42   {
43     return new Values();
44   }
45
46   public static Object JavaDoc make (Object JavaDoc[] vals)
47   {
48     if (vals.length == 1)
49       return vals[0];
50     else if (vals.length == 0)
51       return empty;
52     else
53       return new Values(vals);
54   }
55
56   public static Object JavaDoc make (Sequence seq)
57   {
58     int count = seq.size();
59     if (count == 0)
60       return empty;
61     if (count == 1)
62       return seq.get(0);
63     Values vals = new Values();
64     java.util.Enumeration JavaDoc it = seq.elements();
65     while (it.hasMoreElements())
66       vals.writeObject(it.nextElement());
67     return vals;
68   }
69
70   public static Object JavaDoc make (TreeList list)
71   {
72     return make(list, 0, list.data.length);
73   }
74
75   public static Object JavaDoc make (TreeList list, int startPosition, int endPosition)
76   {
77     int next;
78     if (startPosition == endPosition
79     || (next = list.nextDataIndex(startPosition)) <= 0)
80       return empty;
81     if (next == endPosition || list.nextDataIndex(next) < 0)
82       return list.getPosNext(startPosition << 1); // Singleton value
83
Values vals = new Values();
84     list.consumeIRange(startPosition, endPosition, vals);
85     return vals;
86   }
87
88   /** If a simple value, return that value.
89    * Also, if no values, return empty.
90    */

91   public final Object JavaDoc canonicalize ()
92   {
93     if (gapEnd == data.length)
94       {
95     if (gapStart == 0)
96       return empty;
97     if (nextDataIndex(0) == gapStart) // Singleton value.
98
return getPosNext(0);
99       }
100     return this;
101   }
102
103   /** Apply a Procedure with these values as the arguments. */
104   public Object JavaDoc call_with (Procedure proc) throws Throwable JavaDoc
105   {
106     return proc.applyN (toArray());
107   }
108
109   public void print (Consumer out)
110   {
111     if (this == empty)
112       {
113     out.write("#!void");
114     return;
115       }
116     Object JavaDoc[] vals = toArray(); // FIXME!
117
int size = vals.length;
118     boolean readable = true; // FIXME
119
if (readable)
120       out.write("#<values");
121     for (int i = 0;;)
122       {
123         int next = nextDataIndex(i);
124         if (next < 0)
125           break;
126     out.write(' ');
127         if (i >= gapEnd)
128           i -= gapEnd - gapStart;
129         Object JavaDoc val = getPosNext(i << 1);
130         if (val instanceof Printable)
131           ((Printable) val).print(out);
132         else
133           out.writeObject(val);
134         i = next;
135       }
136     if (readable)
137       out.write('>');
138   }
139
140   /**
141    * @serialData Write the length (using writeInt), followed by
142    * the values in order (written using writeObject).
143    */

144   public void writeExternal(ObjectOutput out) throws IOException
145   {
146     Object JavaDoc[] vals = toArray(); // FIXME
147
int len = vals.length;
148     out.writeInt(len);
149     for (int i = 0; i < len; i++)
150       out.writeObject(vals[i]);
151   }
152
153   public void readExternal(ObjectInput in)
154     throws IOException, ClassNotFoundException JavaDoc
155   {
156     int len = in.readInt();
157     for (int i = 0; i < len; i++)
158       writeObject(in.readObject());
159   }
160
161   public Object JavaDoc readResolve() throws ObjectStreamException
162   {
163     return isEmpty() ? empty : this;
164   }
165
166   /** Helper method called by code using a SeriesTarget.
167    * The compiled code iterates through zero or more values.
168    * Return the index of the next value, or -1 if currently at eof.
169    * A non-Values object is treated as a singleton value,
170    * so in that case there is no next value.
171    */

172   public static int nextIndex(Object JavaDoc values, int curIndex)
173   {
174     if (values instanceof Values)
175       return ((Values) values).nextDataIndex(curIndex);
176     else
177       return curIndex == 0 ? 1 : -1;
178   }
179
180   /** Helper method called by code using a SeriesTarget.
181    * The compiled code iterates through zero or more values.
182    * Extract the object referenced by the curIndex.
183    * A non-Values object is treated as a singleton value.
184    */

185   public static Object JavaDoc nextValue(Object JavaDoc values, int curIndex)
186   {
187     if (values instanceof Values)
188       {
189     Values v = (Values) values;
190     if (curIndex >= v.gapEnd)
191       curIndex -= v.gapEnd - v.gapStart;
192     return ((Values) values).getPosNext(curIndex << 1);
193       }
194     else
195       return values;
196   }
197
198   public static void writeValues(Object JavaDoc value, Consumer out)
199   {
200     if (value instanceof Values)
201       {
202     ((Values) value).consume(out);
203     /*
204     Object[] values = ((Values) value).getValues();
205     for (int i = 0; i < values.length; i++)
206       writeValues(values[i], out);
207     */

208       }
209     /*
210     else if (value instanceof Consumable)
211       {
212     ((Consumable) value).consume(out);
213       }
214     */

215     else
216       out.writeObject(value);
217   }
218
219   public static int countValues (Object JavaDoc value)
220   {
221     return value instanceof Values ? ((Values) value).size() : 1;
222   }
223 }
224
Popular Tags