value.h
00001 // -*- c-basic-offset: 2 -*- 00002 /* 00003 * This file is part of the KDE libraries 00004 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 00005 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 00006 * Copyright (C) 2003 Apple Computer, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Library General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Library General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Library General Public License 00019 * along with this library; see the file COPYING.LIB. If not, write to 00020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 * Boston, MA 02110-1301, USA. 00022 * 00023 */ 00024 00025 #ifndef _KJS_VALUE_H_ 00026 #define _KJS_VALUE_H_ 00027 00028 #include <stdlib.h> // Needed for size_t 00029 00030 #include "ustring.h" 00031 #include "simple_number.h" 00032 00033 // Primitive data types 00034 00035 namespace KJS { 00036 00037 class Value; 00038 class ValueImp; 00039 class ValueImpPrivate; 00040 class Undefined; 00041 class UndefinedImp; 00042 class Null; 00043 class NullImp; 00044 class Boolean; 00045 class BooleanImp; 00046 class String; 00047 class StringImp; 00048 class Number; 00049 class NumberImp; 00050 class Object; 00051 class ObjectImp; 00052 class Reference; 00053 class List; 00054 class ListImp; 00055 class Completion; 00056 class ExecState; 00057 00061 enum Type { 00062 UnspecifiedType = 0, 00063 UndefinedType = 1, 00064 NullType = 2, 00065 BooleanType = 3, 00066 StringType = 4, 00067 NumberType = 5, 00068 ObjectType = 6 00069 }; 00070 00079 class KJS_EXPORT ValueImp { 00080 friend class Collector; 00081 friend class Value; 00082 friend class ContextImp; 00083 public: 00084 ValueImp(); 00085 virtual ~ValueImp(); 00086 00087 ValueImp* ref() { if (!SimpleNumber::is(this)) refcount++; return this; } 00088 bool deref() { if (SimpleNumber::is(this)) return false; else return (!--refcount); } 00089 00090 virtual void mark(); 00091 bool marked() const; 00092 void* operator new(size_t); 00093 void operator delete(void*); 00094 00100 void setGcAllowed(); 00101 00102 // Will crash if called on a simple number. 00103 void setGcAllowedFast() { _flags |= VI_GCALLOWED; } 00104 00105 int toInteger(ExecState *exec) const; 00106 int toInt32(ExecState *exec) const; 00107 unsigned int toUInt32(ExecState *exec) const; 00108 unsigned short toUInt16(ExecState *exec) const; 00109 00110 // Dispatch wrappers that handle the special small number case 00111 00112 Type dispatchType() const; 00113 Value dispatchToPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const; 00114 bool dispatchToBoolean(ExecState *exec) const; 00115 double dispatchToNumber(ExecState *exec) const; 00116 UString dispatchToString(ExecState *exec) const; 00117 bool dispatchToUInt32(unsigned&) const; 00118 Object dispatchToObject(ExecState *exec) const; 00119 00120 unsigned short int refcount; 00121 00122 bool isDestroyed() const { return _flags & VI_DESTRUCTED; } 00123 00124 private: 00125 unsigned short int _flags; 00126 00127 virtual Type type() const = 0; 00128 00129 // The conversion operations 00130 00131 virtual Value toPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const = 0; 00132 virtual bool toBoolean(ExecState *exec) const = 0; 00133 virtual double toNumber(ExecState *exec) const = 0; 00134 // TODO: no need for the following 4 int conversions to be virtual 00135 virtual UString toString(ExecState *exec) const = 0; 00136 virtual Object toObject(ExecState *exec) const = 0; 00137 virtual bool toUInt32(unsigned&) const; 00138 00139 enum { 00140 VI_MARKED = 1, 00141 VI_GCALLOWED = 2, 00142 VI_CREATED = 4, 00143 VI_DESTRUCTED = 8 // nice word we have here :) 00144 }; // VI means VALUEIMPL 00145 00146 ValueImpPrivate *_vd; 00147 00148 // Give a compile time error if we try to copy one of these. 00149 ValueImp(const ValueImp&); 00150 ValueImp& operator=(const ValueImp&); 00151 }; 00152 00168 class KJS_EXPORT Value { 00169 public: 00170 Value() : rep(0) { } 00171 explicit Value(ValueImp *v); 00172 Value(const Value &v); 00173 ~Value(); 00174 00175 Value& operator=(const Value &v); 00182 bool isValid() const { return rep != 0; } 00187 bool isNull() const { return rep == 0; } 00188 ValueImp *imp() const { return rep; } 00189 00196 Type type() const { return rep->dispatchType(); } 00197 00204 bool isA(Type t) const { return rep->dispatchType() == t; } 00205 00210 Value toPrimitive(ExecState *exec, 00211 Type preferredType = UnspecifiedType) const 00212 { return rep->dispatchToPrimitive(exec, preferredType); } 00213 00217 bool toBoolean(ExecState *exec) const { return rep->dispatchToBoolean(exec); } 00218 00222 double toNumber(ExecState *exec) const { return rep->dispatchToNumber(exec); } 00223 00227 int toInteger(ExecState *exec) const { return rep->toInteger(exec); } 00228 00232 int toInt32(ExecState *exec) const { return rep->toInt32(exec); } 00233 00237 unsigned int toUInt32(ExecState *exec) const { return rep->toUInt32(exec); } 00238 00242 unsigned short toUInt16(ExecState *exec) const { return rep->toUInt16(exec); } 00243 00247 UString toString(ExecState *exec) const { return rep->dispatchToString(exec); } 00248 00252 Object toObject(ExecState *exec) const; 00253 00257 bool toUInt32(unsigned& i) const { return rep->dispatchToUInt32(i); } 00258 00259 protected: 00260 ValueImp *rep; 00261 }; 00262 00263 // Primitive types 00264 00270 class KJS_EXPORT Undefined : public Value { 00271 public: 00272 Undefined(); 00273 00283 static Undefined dynamicCast(const Value &v); 00284 private: 00285 friend class UndefinedImp; 00286 explicit Undefined(UndefinedImp *v); 00287 00288 }; 00289 00295 class KJS_EXPORT Null : public Value { 00296 public: 00297 Null(); 00298 00308 static Null dynamicCast(const Value &v); 00309 private: 00310 friend class NullImp; 00311 explicit Null(NullImp *v); 00312 }; 00313 00317 class KJS_EXPORT Boolean : public Value { 00318 public: 00319 Boolean(bool b = false); 00320 00330 static Boolean dynamicCast(const Value &v); 00331 00332 bool value() const; 00333 private: 00334 friend class BooleanImp; 00335 explicit Boolean(BooleanImp *v); 00336 }; 00337 00341 class KJS_EXPORT String : public Value { 00342 public: 00343 String(const UString &s = ""); 00344 00354 static String dynamicCast(const Value &v); 00355 00356 UString value() const; 00357 private: 00358 friend class StringImp; 00359 explicit String(StringImp *v); 00360 }; 00361 00362 extern const double NaN; 00363 extern const double Inf; 00364 00368 class KJS_EXPORT Number : public Value { 00369 friend class ValueImp; 00370 public: 00371 Number(int i); 00372 Number(unsigned int u); 00373 Number(double d = 0.0); 00374 Number(long int l); 00375 Number(long unsigned int l); 00376 00377 double value() const; 00378 int intValue() const; 00379 00380 bool isNaN() const; 00381 bool isInf() const; 00382 00392 static Number dynamicCast(const Value &v); 00393 private: 00394 friend class NumberImp; 00395 explicit Number(NumberImp *v); 00396 }; 00397 00398 } // namespace 00399 00400 #endif // _KJS_VALUE_H_