001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.quercus.env;
031:
032: import com.caucho.vfs.WriteStream;
033:
034: import java.io.IOException;
035: import java.io.PrintWriter;
036: import java.util.IdentityHashMap;
037:
038: /**
039: * Represents a PHP long value.
040: */
041: public class LongValue extends NumberValue {
042: public static final LongValue MINUS_ONE = new LongValue(-1);
043: public static final LongValue ZERO = new LongValue(0);
044: public static final LongValue ONE = new LongValue(1);
045:
046: public static final int STATIC_MIN = -256;
047: public static final int STATIC_MAX = 256;
048:
049: public static final LongValue[] STATIC_VALUES;
050:
051: private final long _value;
052:
053: public LongValue(long value) {
054: _value = value;
055: }
056:
057: public static LongValue create(long value) {
058: if (STATIC_MIN <= value && value <= STATIC_MAX)
059: return STATIC_VALUES[(int) (value - STATIC_MIN)];
060: else
061: return new LongValue(value);
062: }
063:
064: public static LongValue create(Number value) {
065: if (value == null)
066: return LongValue.ZERO;
067: else
068: return new LongValue(value.longValue());
069: }
070:
071: /**
072: * Returns the type.
073: */
074: public String getType() {
075: return "integer";
076: }
077:
078: /**
079: * Returns the ValueType.
080: */
081: @Override
082: public ValueType getValueType() {
083: return ValueType.LONG;
084: }
085:
086: /**
087: * Returns true for a long.
088: */
089: public boolean isLongConvertible() {
090: return true;
091: }
092:
093: /**
094: * Returns true for is_numeric
095: */
096: @Override
097: public boolean isNumeric() {
098: return true;
099: }
100:
101: /**
102: * Returns true for a scalar
103: */
104: public boolean isScalar() {
105: return true;
106: }
107:
108: /**
109: * Returns true if the value is empty
110: */
111: @Override
112: public boolean isEmpty() {
113: return _value == 0;
114: }
115:
116: /**
117: * Converts to a boolean.
118: */
119: public boolean toBoolean() {
120: return _value != 0;
121: }
122:
123: /**
124: * Converts to a long.
125: */
126: public long toLong() {
127: return _value;
128: }
129:
130: /**
131: * Converts to a double.
132: */
133: public double toDouble() {
134: return _value;
135: }
136:
137: /**
138: * Converts to a string.
139: */
140: public String toString() {
141: return String.valueOf(_value);
142: }
143:
144: /**
145: * Converts to a string builder
146: */
147: @Override
148: public StringValue toStringBuilder(Env env) {
149: return env.createUnicodeBuilder().append(_value);
150: }
151:
152: /**
153: * Converts to a long value
154: */
155: public LongValue toLongValue() {
156: return this ;
157: }
158:
159: /**
160: * Converts to a key.
161: */
162: public Value toKey() {
163: return this ;
164: }
165:
166: /**
167: * Converts to an object.
168: */
169: public Object toObject() {
170: return String.valueOf(_value);
171: }
172:
173: /**
174: * Converts to a java object.
175: */
176: public Object toJavaObject() {
177: return new Long(_value);
178: }
179:
180: /**
181: * Negates the value.
182: */
183: public Value neg() {
184: return new LongValue(-_value);
185: }
186:
187: /**
188: * Negates the value.
189: */
190: public Value pos() {
191: return this ;
192: }
193:
194: /**
195: * Pre-increment the following value.
196: */
197: public Value preincr(int incr) {
198: return LongValue.create(_value + incr);
199: }
200:
201: /**
202: * Post-increment the following value.
203: */
204: public Value postincr(int incr) {
205: return LongValue.create(_value + incr);
206: }
207:
208: /**
209: * Adds to the following value.
210: */
211: @Override
212: public Value add(Value value) {
213: return value.add(_value);
214: }
215:
216: /**
217: * Adds to the following value.
218: */
219: @Override
220: public Value add(long lLong) {
221: return LongValue.create(lLong + _value);
222: }
223:
224: /**
225: * Subtracts to the following value.
226: */
227: @Override
228: public Value sub(Value rValue) {
229: if (rValue.isLongConvertible())
230: return LongValue.create(_value - rValue.toLong());
231:
232: return DoubleValue.create(_value - rValue.toDouble());
233: }
234:
235: /**
236: * Subtracts the following value.
237: */
238: @Override
239: public Value sub(long rLong) {
240: return LongValue.create(_value - rLong);
241: }
242:
243: /**
244: * Returns true for equality
245: */
246: public boolean eql(Value rValue) {
247: rValue = rValue.toValue();
248:
249: if (!(rValue instanceof LongValue))
250: return false;
251:
252: long rLong = ((LongValue) rValue)._value;
253:
254: return _value == rLong;
255: }
256:
257: /**
258: * Returns true for equality
259: */
260: public int cmp(Value rValue) {
261: long l = _value;
262: double r = rValue.toDouble();
263:
264: if (l == r)
265: return 0;
266: else if (l < r)
267: return -1;
268: else
269: return 1;
270: }
271:
272: /**
273: * Returns the next array index based on this value.
274: */
275: @Override
276: public long nextIndex(long oldIndex) {
277: if (oldIndex <= _value)
278: return _value + 1;
279: else
280: return oldIndex;
281: }
282:
283: /**
284: * Prints the value.
285: * @param env
286: */
287: public void print(Env env) {
288: env.print(_value);
289: }
290:
291: /**
292: * Append to a unicode builder.
293: */
294: @Override
295: public StringValue appendTo(UnicodeBuilderValue sb) {
296: return sb.append(_value);
297: }
298:
299: /**
300: * Append to a binary builder.
301: */
302: @Override
303: public StringValue appendTo(BinaryBuilderValue sb) {
304: return sb.append(_value);
305: }
306:
307: /**
308: * Append to a string builder.
309: */
310: @Override
311: public StringValue appendTo(StringBuilderValue sb) {
312: return sb.append(_value);
313: }
314:
315: /**
316: * Append to a string builder.
317: */
318: @Override
319: public StringValue appendTo(LargeStringBuilderValue sb) {
320: return sb.append(_value);
321: }
322:
323: /**
324: * Serializes the value.
325: */
326: public void serialize(StringBuilder sb) {
327: sb.append("i:");
328: sb.append(_value);
329: sb.append(";");
330: }
331:
332: /**
333: * Exports the value.
334: */
335: public void varExport(StringBuilder sb) {
336: sb.append(_value);
337: }
338:
339: //
340: // Java generator code
341: //
342:
343: /**
344: * Generates code to recreate the expression.
345: *
346: * @param out the writer to the Java source code.
347: */
348: public void generate(PrintWriter out) throws IOException {
349: if (_value == 0)
350: out.print("LongValue.ZERO");
351: else if (_value == 1)
352: out.print("LongValue.ONE");
353: else if (_value == -1)
354: out.print("LongValue.MINUS_ONE");
355: else if (STATIC_MIN <= _value && _value <= STATIC_MAX)
356: out.print("LongValue.STATIC_VALUES["
357: + (_value - STATIC_MIN) + "]");
358: else
359: out.print("new LongValue(" + _value + "L)");
360: }
361:
362: /**
363: * Returns the hash code
364: */
365: public final int hashCode() {
366: long v = _value;
367:
368: return (int) (17 * v + 65537 * (v >> 32));
369: }
370:
371: /**
372: * Compare for equality.
373: */
374: public boolean equals(Object o) {
375: if (this == o)
376: return true;
377: else if (!(o instanceof LongValue))
378: return false;
379:
380: LongValue value = (LongValue) o;
381:
382: return _value == value._value;
383: }
384:
385: public void varDumpImpl(Env env, WriteStream out, int depth,
386: IdentityHashMap<Value, String> valueSet) throws IOException {
387: out.print("int(" + toLong() + ")");
388: }
389:
390: //
391: // Java Serialization
392: //
393:
394: private Object readResolve() {
395: if (STATIC_MIN <= _value && _value <= STATIC_MAX)
396: return STATIC_VALUES[(int) (_value - STATIC_MIN)];
397: else
398: return this ;
399: }
400:
401: static {
402: STATIC_VALUES = new LongValue[STATIC_MAX - STATIC_MIN + 1];
403:
404: for (int i = STATIC_MIN; i <= STATIC_MAX; i++) {
405: STATIC_VALUES[i - STATIC_MIN] = new LongValue(i);
406: }
407: }
408: }
|