Add support for HEVC codec types in Media Capabilities
[WebKit-https.git] / Source / WTF / wtf / text / StringToIntegerConversion.h
1 /*
2  * Copyright (C) 2018 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 #pragma once
27
28 namespace WTF {
29
30 inline bool isCharacterAllowedInBase(UChar c, int base)
31 {
32     if (c > 0x7F)
33         return false;
34     if (isASCIIDigit(c))
35         return c - '0' < base;
36     if (isASCIIAlpha(c)) {
37         if (base > 36)
38             base = 36;
39         return (c >= 'a' && c < 'a' + base - 10)
40             || (c >= 'A' && c < 'A' + base - 10);
41     }
42     return false;
43 }
44
45 template<typename IntegralType, typename CharacterType>
46 inline IntegralType toIntegralType(const CharacterType* data, size_t length, bool* ok = nullptr, int base = 10)
47 {
48     static const IntegralType integralMax = std::numeric_limits<IntegralType>::max();
49     static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
50     const IntegralType maxMultiplier = integralMax / base;
51
52     IntegralType value = 0;
53     bool isOk = false;
54     bool isNegative = false;
55
56     if (!data)
57         goto bye;
58
59     // skip leading whitespace
60     while (length && isSpaceOrNewline(*data)) {
61         --length;
62         ++data;
63     }
64
65     if (isSigned && length && *data == '-') {
66         --length;
67         ++data;
68         isNegative = true;
69     } else if (length && *data == '+') {
70         --length;
71         ++data;
72     }
73
74     if (!length || !isCharacterAllowedInBase(*data, base))
75         goto bye;
76
77     while (length && isCharacterAllowedInBase(*data, base)) {
78         --length;
79         IntegralType digitValue;
80         auto c = *data;
81         if (isASCIIDigit(c))
82             digitValue = c - '0';
83         else if (c >= 'a')
84             digitValue = c - 'a' + 10;
85         else
86             digitValue = c - 'A' + 10;
87
88         if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative))
89             goto bye;
90
91         value = base * value + digitValue;
92         ++data;
93     }
94
95 #if COMPILER(MSVC)
96 #pragma warning(push, 0)
97 #pragma warning(disable:4146)
98 #endif
99
100     if (isNegative)
101         value = -value;
102
103 #if COMPILER(MSVC)
104 #pragma warning(pop)
105 #endif
106
107     // skip trailing space
108     while (length && isSpaceOrNewline(*data)) {
109         --length;
110         ++data;
111     }
112
113     if (!length)
114         isOk = true;
115 bye:
116     if (ok)
117         *ok = isOk;
118     return isOk ? value : 0;
119 }
120
121 template<typename IntegralType, typename StringOrStringView>
122 inline IntegralType toIntegralType(const StringOrStringView& stringView, bool* ok = nullptr, int base = 10)
123 {
124     if (stringView.is8Bit())
125         return toIntegralType<IntegralType, LChar>(stringView.characters8(), stringView.length(), ok, base);
126     return toIntegralType<IntegralType, UChar>(stringView.characters16(), stringView.length(), ok, base);
127 }
128
129 }
130
131 using WTF::toIntegralType;