4bb174bff64b0eb4dd311bb618f6d7fb9d5a0344
[WebKit-https.git] / JavaScriptCore / kjs / JSString.h
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Library General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public License
18  *  along with this library; see the file COPYING.LIB.  If not, write to
19  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #ifndef JSString_h
25 #define JSString_h
26
27 #include "CommonIdentifiers.h"
28 #include "JSCell.h"
29 #include "PropertySlot.h"
30 #include "identifier.h"
31 #include "ustring.h"
32
33 namespace KJS {
34
35   class JSString : public JSCell {
36   public:
37     JSString(const UString& value) : m_value(value) { Heap::heap(this)->reportExtraMemoryCost(value.cost()); }
38     enum HasOtherOwnerType { HasOtherOwner };
39     JSString(const UString& value, HasOtherOwnerType) : m_value(value) { }
40
41     const UString& value() const { return m_value; }
42
43     bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
44     bool getStringPropertySlot(unsigned propertyName, PropertySlot&);
45
46   private:
47     virtual JSType type() const { return StringType; }
48
49     virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
50     virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
51     virtual bool toBoolean(ExecState*) const;
52     virtual double toNumber(ExecState*) const;
53     virtual JSObject* toObject(ExecState*) const;
54     virtual UString toString(ExecState*) const;
55
56     virtual JSObject* toThisObject(ExecState*) const;
57     virtual UString toThisString(ExecState*) const;
58     virtual JSString* toThisJSString(ExecState*);
59
60     // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
61     virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
62     virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
63
64     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
65     static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
66     static JSValue* indexNumericPropertyGetter(ExecState*, unsigned, const PropertySlot&);
67
68     UString m_value;
69   };
70
71   JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string
72   JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0
73
74   // Should be used for strings that are owned by an object that will
75   // likely outlive the JSValue this makes, such as the parse tree or a
76   // DOM object that contains a UString
77   JSString* jsOwnedString(ExecState*, const UString&); 
78
79 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
80 {
81     if (propertyName == exec->propertyNames().length) {
82         slot.setCustom(this, lengthGetter);
83         return true;
84     }
85
86     bool isStrictUInt32;
87     unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
88     if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
89         slot.setCustomIndex(this, i, indexGetter);
90         return true;
91     }
92
93     return false;
94 }
95     
96 ALWAYS_INLINE bool JSString::getStringPropertySlot(unsigned propertyName, PropertySlot& slot)
97 {
98     if (propertyName < static_cast<unsigned>(m_value.size())) {
99         slot.setCustomNumeric(this, indexNumericPropertyGetter);
100         return true;
101     }
102
103     return false;
104 }
105
106 // --- JSValue inlines ----------------------------
107
108 inline JSString* JSValue::toThisJSString(ExecState* exec)
109 {
110     return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec);
111 }
112
113 } // namespace KJS
114
115 #endif // JSString_h