d2258b471b4c79856992841600612951e95220a4
[WebKit-https.git] / Source / JavaScriptCore / runtime / PropertyName.h
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef PropertyName_h
27 #define PropertyName_h
28
29 #include "Identifier.h"
30
31 namespace JSC {
32
33 template <typename CharType>
34 ALWAYS_INLINE uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length)
35 {
36     // An empty string is not a number.
37     if (!length)
38         return UINT_MAX;
39
40     // Get the first character, turning it into a digit.
41     uint32_t value = characters[0] - '0';
42     if (value > 9)
43         return UINT_MAX;
44     
45     // Check for leading zeros. If the first characher is 0, then the
46     // length of the string must be one - e.g. "042" is not equal to "42".
47     if (!value && length > 1)
48         return UINT_MAX;
49     
50     while (--length) {
51         // Multiply value by 10, checking for overflow out of 32 bits.
52         if (value > 0xFFFFFFFFU / 10)
53             return UINT_MAX;
54         value *= 10;
55         
56         // Get the next character, turning it into a digit.
57         uint32_t newValue = *(++characters) - '0';
58         if (newValue > 9)
59             return UINT_MAX;
60         
61         // Add in the old value, checking for overflow out of 32 bits.
62         newValue += value;
63         if (newValue < value)
64             return UINT_MAX;
65         value = newValue;
66     }
67     
68     return value;
69 }
70
71 ALWAYS_INLINE uint32_t toUInt32FromStringImpl(StringImpl* impl)
72 {
73     if (impl->is8Bit())
74         return toUInt32FromCharacters(impl->characters8(), impl->length());
75     return toUInt32FromCharacters(impl->characters16(), impl->length());
76 }
77
78 class PropertyName {
79 public:
80     PropertyName(const Identifier& propertyName)
81         : m_impl(propertyName.impl())
82     {
83     }
84
85     StringImpl* impl() const { return m_impl; }
86     UString ustring() const { return m_impl; }
87
88     static const uint32_t NotAnIndex = UINT_MAX;
89     uint32_t asIndex()
90     {
91         return toUInt32FromStringImpl(m_impl);
92     }
93
94 private:
95     StringImpl* m_impl;
96 };
97
98 inline bool operator==(PropertyName a, const Identifier& b)
99 {
100     return a.impl() == b.impl();
101 }
102
103 inline bool operator==(const Identifier& a, PropertyName b)
104 {
105     return a.impl() == b.impl();
106 }
107
108 inline bool operator==(PropertyName a, PropertyName b)
109 {
110     return a.impl() == b.impl();
111 }
112
113 inline bool operator!=(PropertyName a, const Identifier& b)
114 {
115     return a.impl() != b.impl();
116 }
117
118 inline bool operator!=(const Identifier& a, PropertyName b)
119 {
120     return a.impl() != b.impl();
121 }
122
123 inline bool operator!=(PropertyName a, PropertyName b)
124 {
125     return a.impl() != b.impl();
126 }
127
128 }
129
130 #endif