Title: [279051] trunk/Source/WTF
Revision
279051
Author
wei...@apple.com
Date
2021-06-19 19:05:08 -0700 (Sat, 19 Jun 2021)

Log Message

Adopt Span in Base64.h
https://bugs.webkit.org/show_bug.cgi?id=227132

Reviewed by Chris Dumez.

Replaces overloads taking Vectors with ones taking Spans
and add overloads for Span<const std::byte> which all the
others are now implemented in terms of. This is useful since
any Span can be turned into one of type Span<const std::byte>
just by calling asBytes(existingSpan).

This leaves most of the existing overloads in place (though
simplifies them by implementing them as Span contructions)
though we should consider removing some in a separate pass.

* wtf/Vector.h:
Add value_type typedef so that Vector<T> can be automatically
deduced as Span<T>.

* wtf/text/CString.h:
Add bytes() and bytesInludingNullTerminator() (only the former
is used in this patch, but the later will be needed shortly)
which return Span<const uint8_t> of the CString. I chose to use
an explicit function, rather than making it converible to Span
like Vector, because some callers will want the null terminator
and some will not.

* wtf/text/Base64.cpp:
* wtf/text/Base64.h:
Canonicalize all input buffers either as a Span<const std::byte> or
a StringView, making all the other overloads just forward to one of
those two (String -> StringView, everything else -> Span<const std::byte>).

Clean up the header a bit by putting all the declarations at the top of
the file.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (279050 => 279051)


--- trunk/Source/WTF/ChangeLog	2021-06-19 20:31:11 UTC (rev 279050)
+++ trunk/Source/WTF/ChangeLog	2021-06-20 02:05:08 UTC (rev 279051)
@@ -1,3 +1,41 @@
+2021-06-19  Sam Weinig  <wei...@apple.com>
+
+        Adopt Span in Base64.h
+        https://bugs.webkit.org/show_bug.cgi?id=227132
+
+        Reviewed by Chris Dumez.
+
+        Replaces overloads taking Vectors with ones taking Spans
+        and add overloads for Span<const std::byte> which all the
+        others are now implemented in terms of. This is useful since
+        any Span can be turned into one of type Span<const std::byte>
+        just by calling asBytes(existingSpan).
+
+        This leaves most of the existing overloads in place (though
+        simplifies them by implementing them as Span contructions)
+        though we should consider removing some in a separate pass.
+
+        * wtf/Vector.h:
+        Add value_type typedef so that Vector<T> can be automatically
+        deduced as Span<T>.
+
+        * wtf/text/CString.h:
+        Add bytes() and bytesInludingNullTerminator() (only the former
+        is used in this patch, but the later will be needed shortly)
+        which return Span<const uint8_t> of the CString. I chose to use
+        an explicit function, rather than making it converible to Span
+        like Vector, because some callers will want the null terminator
+        and some will not.
+
+        * wtf/text/Base64.cpp:
+        * wtf/text/Base64.h:
+        Canonicalize all input buffers either as a Span<const std::byte> or
+        a StringView, making all the other overloads just forward to one of
+        those two (String -> StringView, everything else -> Span<const std::byte>).
+
+        Clean up the header a bit by putting all the declarations at the top of
+        the file.
+
 2021-06-17  Said Abou-Hallawa  <s...@apple.com>
 
         [Cocoa] Disable hardware decoding in the WebProcess

Modified: trunk/Source/WTF/wtf/Vector.h (279050 => 279051)


--- trunk/Source/WTF/wtf/Vector.h	2021-06-19 20:31:11 UTC (rev 279050)
+++ trunk/Source/WTF/wtf/Vector.h	2021-06-20 02:05:08 UTC (rev 279051)
@@ -612,7 +612,9 @@
     friend class JSC::LLIntOffsetsExtractor;
 
 public:
+    // FIXME: Remove uses of ValueType and standardize on value_type, which is required for std::span.
     typedef T ValueType;
+    typedef T value_type;
 
     typedef T* iterator;
     typedef const T* const_iterator;

Modified: trunk/Source/WTF/wtf/text/Base64.cpp (279050 => 279051)


--- trunk/Source/WTF/wtf/text/Base64.cpp	2021-06-19 20:31:11 UTC (rev 279050)
+++ trunk/Source/WTF/wtf/text/Base64.cpp	2021-06-20 02:05:08 UTC (rev 279051)
@@ -93,10 +93,10 @@
     0x31, 0x32, 0x33, nonAlphabet, nonAlphabet, nonAlphabet, nonAlphabet, nonAlphabet
 };
 
-template<typename CharacterType> static void base64EncodeInternal(const uint8_t* inputDataBuffer, unsigned inputLength, CharacterType* destinationDataBuffer, unsigned destinationLength, Base64EncodePolicy policy, Base64EncodeMap map)
+template<typename CharacterType> static void base64EncodeInternal(Span<const uint8_t> inputDataBuffer, Span<CharacterType> destinationDataBuffer, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    ASSERT(destinationLength > 0);
-    ASSERT(calculateBase64EncodedSize(inputLength, policy) == destinationLength);
+    ASSERT(destinationDataBuffer.size() > 0);
+    ASSERT(calculateBase64EncodedSize(inputDataBuffer.size(), policy) == destinationDataBuffer.size());
 
     auto encodeMap = (map == Base64EncodeMap::URL) ? base64URLEncMap : base64EncMap;
 
@@ -104,10 +104,10 @@
     unsigned didx = 0;
     unsigned count = 0;
 
-    bool insertLFs = (policy == Base64EncodePolicy::InsertLFs && destinationLength > maximumBase64LineLengthWhenInsertingLFs);
+    bool insertLFs = (policy == Base64EncodePolicy::InsertLFs && destinationDataBuffer.size() > maximumBase64LineLengthWhenInsertingLFs);
 
-    if (inputLength > 1) {
-        while (sidx < inputLength - 2) {
+    if (inputDataBuffer.size() > 1) {
+        while (sidx < inputDataBuffer.size() - 2) {
             if (insertLFs) {
                 if (count && !(count % maximumBase64LineLengthWhenInsertingLFs))
                     destinationDataBuffer[didx++] = '\n';
@@ -122,12 +122,12 @@
         }
     }
 
-    if (sidx < inputLength) {
+    if (sidx < inputDataBuffer.size()) {
         if (insertLFs && (count > 0) && !(count % maximumBase64LineLengthWhenInsertingLFs))
             destinationDataBuffer[didx++] = '\n';
 
         destinationDataBuffer[didx++] = encodeMap[(inputDataBuffer[sidx] >> 2) & 077];
-        if (sidx < inputLength - 1) {
+        if (sidx < inputDataBuffer.size() - 1) {
             destinationDataBuffer[didx++] = encodeMap[((inputDataBuffer[sidx + 1] >> 4) & 017) | ((inputDataBuffer[sidx] << 4) & 077)];
             destinationDataBuffer[didx++] = encodeMap[ (inputDataBuffer[sidx + 1] << 2) & 077];
         } else
@@ -134,59 +134,64 @@
             destinationDataBuffer[didx++] = encodeMap[ (inputDataBuffer[sidx    ] << 4) & 077];
     }
 
-    ASSERT(policy != Base64EncodePolicy::URL || didx == destinationLength);
+    ASSERT(policy != Base64EncodePolicy::URL || didx == destinationDataBuffer.size());
 
-    while (didx < destinationLength)
+    while (didx < destinationDataBuffer.size())
         destinationDataBuffer[didx++] = '=';
 }
 
-static Vector<uint8_t> base64EncodeInternal(const uint8_t* inputDataBuffer, unsigned inputLength, Base64EncodePolicy policy, Base64EncodeMap map)
+template<typename CharacterType> static void base64EncodeInternal(Span<const std::byte> input, Span<CharacterType> destinationDataBuffer, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    auto destinationLength = calculateBase64EncodedSize(inputLength, policy);
+    base64EncodeInternal(Span { reinterpret_cast<const uint8_t*>(input.data()), input.size() }, destinationDataBuffer, policy, map);
+}
+
+static Vector<uint8_t> base64EncodeInternal(Span<const std::byte> input, Base64EncodePolicy policy, Base64EncodeMap map)
+{
+    auto destinationLength = calculateBase64EncodedSize(input.size(), policy);
     if (!destinationLength)
         return { };
 
     Vector<uint8_t> destinationVector(destinationLength);
-    base64EncodeInternal(inputDataBuffer, inputLength, destinationVector.data(), destinationLength, policy, map);
+    base64EncodeInternal(input, Span { destinationVector }, policy, map);
     return destinationVector;
 }
 
-void base64Encode(const void* inputDataBuffer, unsigned inputLength, UChar* destinationDataBuffer, unsigned destinationLength, Base64EncodePolicy policy, Base64EncodeMap map)
+void base64Encode(Span<const std::byte> input, Span<UChar> destination, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    if (!destinationLength)
+    if (!destination.size())
         return;
-    base64EncodeInternal(static_cast<const uint8_t*>(inputDataBuffer), inputLength, destinationDataBuffer, destinationLength, policy, map);
+    base64EncodeInternal(input, destination, policy, map);
 }
 
-void base64Encode(const void* inputDataBuffer, unsigned inputLength, LChar* destinationDataBuffer, unsigned destinationLength, Base64EncodePolicy policy, Base64EncodeMap map)
+void base64Encode(Span<const std::byte> input, Span<LChar> destination, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    if (!destinationLength)
+    if (!destination.size())
         return;
-    base64EncodeInternal(static_cast<const uint8_t*>(inputDataBuffer), inputLength, destinationDataBuffer, destinationLength, policy, map);
+    base64EncodeInternal(input, destination, policy, map);
 }
 
-Vector<uint8_t> base64EncodeToVector(const void* inputDataBuffer, unsigned inputLength, Base64EncodePolicy policy, Base64EncodeMap map)
+Vector<uint8_t> base64EncodeToVector(Span<const std::byte> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeInternal(static_cast<const uint8_t*>(inputDataBuffer), inputLength, policy, map);
+    return base64EncodeInternal(input, policy, map);
 }
 
-String base64EncodeToString(const void* inputDataBuffer, unsigned inputLength, Base64EncodePolicy policy, Base64EncodeMap map)
+String base64EncodeToString(Span<const std::byte> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return makeString(base64Encoded(inputDataBuffer, inputLength, policy, map));
+    return makeString(base64Encoded(input, policy, map));
 }
 
-template<typename T> static std::optional<Vector<uint8_t>> base64DecodeInternal(const T* inputDataBuffer, unsigned inputLength, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+template<typename T> static std::optional<Vector<uint8_t>> base64DecodeInternal(Span<const T> inputDataBuffer, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
 {
-    if (!inputLength)
+    if (!inputDataBuffer.size())
         return Vector<uint8_t> { };
 
     auto decodeMap = (map == Base64DecodeMap::URL) ? base64URLDecMap : base64DecMap;
 
-    Vector<uint8_t> destination(inputLength);
+    Vector<uint8_t> destination(inputDataBuffer.size());
 
     unsigned equalsSignCount = 0;
     unsigned destinationLength = 0;
-    for (unsigned idx = 0; idx < inputLength; ++idx) {
+    for (unsigned idx = 0; idx < inputDataBuffer.size(); ++idx) {
         unsigned ch = inputDataBuffer[idx];
         if (ch == '=') {
             ++equalsSignCount;
@@ -254,84 +259,19 @@
     return destination;
 }
 
-std::optional<Vector<uint8_t>> base64Decode(const String& input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+std::optional<Vector<uint8_t>> base64Decode(Span<const std::byte> input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
 {
-    unsigned length = input.length();
-    if (!length || input.is8Bit())
-        return base64DecodeInternal(input.characters8(), length, options, map);
-    return base64DecodeInternal(input.characters16(), length, options, map);
-}
-
-std::optional<Vector<uint8_t>> base64Decode(StringView input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
-{
-    unsigned length = input.length();
-    if (!length || input.is8Bit())
-        return base64DecodeInternal(input.characters8(), length, options, map);
-    return base64DecodeInternal(input.characters16(), length, options, map);
-}
-
-std::optional<Vector<uint8_t>> base64Decode(const Vector<uint8_t>& input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
-{
     if (input.size() > std::numeric_limits<unsigned>::max())
         return std::nullopt;
-    return base64DecodeInternal(input.data(), input.size(), options, map);
+    return base64DecodeInternal(Span { reinterpret_cast<const uint8_t*>(input.data()), input.size() }, options, map);
 }
 
-std::optional<Vector<uint8_t>> base64Decode(const Vector<char>& input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+std::optional<Vector<uint8_t>> base64Decode(StringView input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
 {
-    if (input.size() > std::numeric_limits<unsigned>::max())
-        return std::nullopt;
-    return base64DecodeInternal(reinterpret_cast<const uint8_t*>(input.data()), input.size(), options, map);
-}
-
-std::optional<Vector<uint8_t>> base64Decode(const uint8_t* data, unsigned length, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
-{
-    return base64DecodeInternal(data, length, options, map);
-}
-
-std::optional<Vector<uint8_t>> base64Decode(const char* data, unsigned length, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
-{
-    return base64DecodeInternal(reinterpret_cast<const LChar*>(data), length, options, map);
-}
-
-std::optional<Vector<uint8_t>> base64URLDecode(const String& input)
-{
     unsigned length = input.length();
     if (!length || input.is8Bit())
-        return base64DecodeInternal(input.characters8(), length, { }, Base64DecodeMap::URL);
-    return base64DecodeInternal(input.characters16(), length, { }, Base64DecodeMap::URL);
+        return base64DecodeInternal(Span { input.characters8(), length }, options, map);
+    return base64DecodeInternal(Span { input.characters16(), length }, options, map);
 }
 
-std::optional<Vector<uint8_t>> base64URLDecode(StringView input)
-{
-    unsigned length = input.length();
-    if (!length || input.is8Bit())
-        return base64DecodeInternal(input.characters8(), length, { }, Base64DecodeMap::URL);
-    return base64DecodeInternal(input.characters16(), length, { }, Base64DecodeMap::URL);
-}
-
-std::optional<Vector<uint8_t>> base64URLDecode(const Vector<uint8_t>& input)
-{
-    if (input.size() > std::numeric_limits<unsigned>::max())
-        return std::nullopt;
-    return base64DecodeInternal(input.data(), input.size(), { }, Base64DecodeMap::URL);
-}
-
-std::optional<Vector<uint8_t>> base64URLDecode(const Vector<char>& input)
-{
-    if (input.size() > std::numeric_limits<unsigned>::max())
-        return std::nullopt;
-    return base64DecodeInternal(reinterpret_cast<const uint8_t*>(input.data()), input.size(), { }, Base64DecodeMap::URL);
-}
-
-std::optional<Vector<uint8_t>> base64URLDecode(const uint8_t* data, unsigned length)
-{
-    return base64DecodeInternal(data, length, { }, Base64DecodeMap::URL);
-}
-
-std::optional<Vector<uint8_t>> base64URLDecode(const char* data, unsigned length)
-{
-    return base64DecodeInternal(reinterpret_cast<const uint8_t*>(data), length, { }, Base64DecodeMap::URL);
-}
-
 } // namespace WTF

Modified: trunk/Source/WTF/wtf/text/Base64.h (279050 => 279051)


--- trunk/Source/WTF/wtf/text/Base64.h	2021-06-19 20:31:11 UTC (rev 279050)
+++ trunk/Source/WTF/wtf/text/Base64.h	2021-06-20 02:05:08 UTC (rev 279051)
@@ -29,6 +29,7 @@
 
 #include <wtf/Forward.h>
 #include <wtf/OptionSet.h>
+#include <wtf/Span.h>
 #include <wtf/text/StringConcatenate.h>
 #include <wtf/text/WTFString.h>
 
@@ -50,6 +51,12 @@
 
 enum class Base64DecodeMap { Default, URL };
 
+struct Base64Specification {
+    Span<const std::byte> input;
+    Base64EncodePolicy policy;
+    Base64EncodeMap map;
+};
+
 static constexpr unsigned maximumBase64LineLengthWhenInsertingLFs = 76;
 
 // If the input string is pathologically large, just return nothing.
@@ -56,121 +63,209 @@
 // Rather than being perfectly precise, this is a bit conservative.
 static constexpr unsigned maximumBase64EncoderInputBufferSize = std::numeric_limits<unsigned>::max() / 77 * 76 / 4 * 3 - 2;
 
-WTF_EXPORT_PRIVATE void base64Encode(const void*, unsigned, UChar*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
-WTF_EXPORT_PRIVATE void base64Encode(const void*, unsigned, LChar*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+unsigned calculateBase64EncodedSize(unsigned inputLength, Base64EncodePolicy);
 
-WTF_EXPORT_PRIVATE Vector<uint8_t> base64EncodeToVector(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
-Vector<uint8_t> base64EncodeToVector(const Vector<uint8_t>&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
-Vector<uint8_t> base64EncodeToVector(const Vector<char>&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+template<typename CharacterType> bool isBase64OrBase64URLCharacter(CharacterType);
+
+WTF_EXPORT_PRIVATE void base64Encode(Span<const std::byte>, Span<UChar>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+WTF_EXPORT_PRIVATE void base64Encode(Span<const std::byte>, Span<LChar>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+
+WTF_EXPORT_PRIVATE Vector<uint8_t> base64EncodeToVector(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Vector<uint8_t> base64EncodeToVector(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Vector<uint8_t> base64EncodeToVector(Span<const char>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
 Vector<uint8_t> base64EncodeToVector(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Vector<uint8_t> base64EncodeToVector(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
 
-WTF_EXPORT_PRIVATE String base64EncodeToString(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
-String base64EncodeToString(const Vector<uint8_t>&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
-String base64EncodeToString(const Vector<char>&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+WTF_EXPORT_PRIVATE String base64EncodeToString(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+String base64EncodeToString(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+String base64EncodeToString(Span<const char>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
 String base64EncodeToString(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+String base64EncodeToString(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
 
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(const String&, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
+WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(Span<const std::byte>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
 WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(StringView, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(const Vector<uint8_t>&, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(const Vector<char>&, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(const uint8_t*, unsigned, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(const char*, unsigned, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
+std::optional<Vector<uint8_t>> base64Decode(Span<const uint8_t>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
+std::optional<Vector<uint8_t>> base64Decode(Span<const char>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
+std::optional<Vector<uint8_t>> base64Decode(const String&, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
+std::optional<Vector<uint8_t>> base64Decode(const void*, unsigned, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
 
-inline Vector<uint8_t> base64EncodeToVector(const Vector<uint8_t>& input, Base64EncodePolicy policy, Base64EncodeMap map)
+// All the same functions modified for base64url, as defined in RFC 4648.
+// This format uses '-' and '_' instead of '+' and '/' respectively.
+
+Vector<uint8_t> base64URLEncodeToVector(Span<const std::byte>);
+Vector<uint8_t> base64URLEncodeToVector(Span<const uint8_t>);
+Vector<uint8_t> base64URLEncodeToVector(Span<const char>);
+Vector<uint8_t> base64URLEncodeToVector(const CString&);
+Vector<uint8_t> base64URLEncodeToVector(const void*, unsigned);
+
+String base64URLEncodeToString(Span<const std::byte>);
+String base64URLEncodeToString(Span<const uint8_t>);
+String base64URLEncodeToString(Span<const char>);
+String base64URLEncodeToString(const CString&);
+String base64URLEncodeToString(const void*, unsigned);
+
+std::optional<Vector<uint8_t>> base64URLDecode(StringView);
+std::optional<Vector<uint8_t>> base64URLDecode(const String&);
+std::optional<Vector<uint8_t>> base64URLDecode(Span<const std::byte>);
+std::optional<Vector<uint8_t>> base64URLDecode(Span<const uint8_t>);
+std::optional<Vector<uint8_t>> base64URLDecode(Span<const char>);
+std::optional<Vector<uint8_t>> base64URLDecode(const void*, unsigned);
+
+// Versions for use with StringBuilder / makeString.
+
+Base64Specification base64Encoded(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Base64Specification base64Encoded(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Base64Specification base64Encoded(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+Base64Specification base64Encoded(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
+
+Base64Specification base64URLEncoded(Span<const std::byte>);
+Base64Specification base64URLEncoded(Span<const uint8_t>);
+Base64Specification base64URLEncoded(const CString&);
+Base64Specification base64URLEncoded(const void*, unsigned);
+
+
+inline Vector<uint8_t> base64EncodeToVector(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToVector(input.data(), input.size(), policy, map);
+    return base64EncodeToVector(asBytes(input), policy, map);
 }
 
-inline Vector<uint8_t> base64EncodeToVector(const Vector<char>& input, Base64EncodePolicy policy, Base64EncodeMap map)
+inline Vector<uint8_t> base64EncodeToVector(Span<const char> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToVector(input.data(), input.size(), policy, map);
+    return base64EncodeToVector(asBytes(input), policy, map);
 }
 
 inline Vector<uint8_t> base64EncodeToVector(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToVector(input.data(), input.length(), policy, map);
+    return base64EncodeToVector(input.bytes(), policy, map);
 }
 
-inline String base64EncodeToString(const Vector<uint8_t>& input, Base64EncodePolicy policy, Base64EncodeMap map)
+inline Vector<uint8_t> base64EncodeToVector(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToString(input.data(), input.size(), policy, map);
+    return base64EncodeToVector({ static_cast<const std::byte*>(input), length }, policy, map);
 }
 
-inline String base64EncodeToString(const Vector<char>& input, Base64EncodePolicy policy, Base64EncodeMap map)
+inline String base64EncodeToString(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToString(input.data(), input.size(), policy, map);
+    return base64EncodeToString(asBytes(input), policy, map);
 }
 
+inline String base64EncodeToString(Span<const char> input, Base64EncodePolicy policy, Base64EncodeMap map)
+{
+    return base64EncodeToString(asBytes(input), policy, map);
+}
+
 inline String base64EncodeToString(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64EncodeToString(input.data(), input.length(), policy, map);
+    return base64EncodeToString(input.bytes(), policy, map);
 }
 
+inline String base64EncodeToString(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
+{
+    return base64EncodeToString({ static_cast<const std::byte*>(input), length }, policy, map);
+}
 
-// ======================================================================================
-// All the same functions modified for base64url, as defined in RFC 4648.
-// This format uses '-' and '_' instead of '+' and '/' respectively.
-// ======================================================================================
+inline std::optional<Vector<uint8_t>> base64Decode(Span<const uint8_t> input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+{
+    return base64Decode(asBytes(input), options, map);
+}
 
-Vector<uint8_t> base64URLEncodeToVector(const void*, unsigned);
-Vector<uint8_t> base64URLEncodeToVector(const Vector<uint8_t>&);
-Vector<uint8_t> base64URLEncodeToVector(const Vector<char>&);
-Vector<uint8_t> base64URLEncodeToVector(const CString&);
+inline std::optional<Vector<uint8_t>> base64Decode(Span<const char> input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+{
+    return base64Decode(asBytes(input), options, map);
+}
 
-String base64URLEncodeToString(const void*, unsigned);
-String base64URLEncodeToString(const Vector<uint8_t>&);
-String base64URLEncodeToString(const Vector<char>&);
-String base64URLEncodeToString(const CString&);
+inline std::optional<Vector<uint8_t>> base64Decode(const String& input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+{
+    return base64Decode(StringView { input }, options, map);
+}
 
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(const String&);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(StringView);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(const Vector<uint8_t>&);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(const Vector<char>&);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(const uint8_t*, unsigned);
-WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64URLDecode(const char*, unsigned);
+inline std::optional<Vector<uint8_t>> base64Decode(const void* input, unsigned length, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
+{
+    return base64Decode({ static_cast<const std::byte*>(input), length }, options, map);
+}
 
+inline Vector<uint8_t> base64URLEncodeToVector(Span<const std::byte> input)
+{
+    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+}
+
+inline Vector<uint8_t> base64URLEncodeToVector(Span<const uint8_t> input)
+{
+    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+}
+
+inline Vector<uint8_t> base64URLEncodeToVector(Span<const char> input)
+{
+    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+}
+
+inline Vector<uint8_t> base64URLEncodeToVector(const CString& input)
+{
+    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+}
+
 inline Vector<uint8_t> base64URLEncodeToVector(const void* input, unsigned length)
 {
     return base64EncodeToVector(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Vector<uint8_t> base64URLEncodeToVector(const Vector<uint8_t>& input)
+inline String base64URLEncodeToString(Span<const std::byte> input)
 {
-    return base64EncodeToVector(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Vector<uint8_t> base64URLEncodeToVector(const Vector<char>& input)
+inline String base64URLEncodeToString(Span<const uint8_t> input)
 {
-    return base64EncodeToVector(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Vector<uint8_t> base64URLEncodeToVector(const CString& input)
+inline String base64URLEncodeToString(Span<const char> input)
 {
-    return base64EncodeToVector(input.data(), input.length(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
+inline String base64URLEncodeToString(const CString& input)
+{
+    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+}
+
 inline String base64URLEncodeToString(const void* input, unsigned length)
 {
     return base64EncodeToString(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline String base64URLEncodeToString(const Vector<uint8_t>& input)
+inline std::optional<Vector<uint8_t>> base64URLDecode(StringView input)
 {
-    return base64EncodeToString(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Decode(input, { }, Base64DecodeMap::URL);
 }
 
-inline String base64URLEncodeToString(const Vector<char>& input)
+inline std::optional<Vector<uint8_t>> base64URLDecode(const String& input)
 {
-    return base64EncodeToString(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Decode(input, { }, Base64DecodeMap::URL);
 }
 
-inline String base64URLEncodeToString(const CString& input)
+inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const std::byte> input)
 {
-    return base64EncodeToString(input.data(), input.length(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Decode(input, { }, Base64DecodeMap::URL);
 }
 
-template<typename CharacterType> static inline bool isBase64OrBase64URLCharacter(CharacterType c)
+inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const uint8_t> input)
 {
+    return base64Decode(input, { }, Base64DecodeMap::URL);
+}
+
+inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const char> input)
+{
+    return base64Decode(input, { }, Base64DecodeMap::URL);
+}
+
+inline std::optional<Vector<uint8_t>> base64URLDecode(const void* input, unsigned length)
+{
+    return base64Decode(input, length, { }, Base64DecodeMap::URL);
+}
+
+template<typename CharacterType> bool isBase64OrBase64URLCharacter(CharacterType c)
+{
     return isASCIIAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_';
 }
 
@@ -207,51 +302,44 @@
     return 0;
 }
 
-struct Base64Specification {
-    const void* inputData;
-    unsigned inputLength;
-    Base64EncodePolicy policy;
-    Base64EncodeMap map;
-};
-
-inline Base64Specification base64Encoded(const void* inputData, unsigned inputLength, Base64EncodePolicy policy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap map = Base64EncodeMap::Default)
+inline Base64Specification base64Encoded(Span<const std::byte> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return { inputData, inputLength, policy, map };
+    return { input, policy, map };
 }
 
-inline Base64Specification base64Encoded(const Vector<uint8_t>& input, Base64EncodePolicy policy = Base64EncodePolicy::DoNotInsertLFs)
+inline Base64Specification base64Encoded(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64Encoded(input.data(), input.size(), policy);
+    return base64Encoded(asBytes(input), policy, map);
 }
 
-inline Base64Specification base64Encoded(const Vector<char>& input, Base64EncodePolicy policy = Base64EncodePolicy::DoNotInsertLFs)
+inline Base64Specification base64Encoded(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64Encoded(input.data(), input.size(), policy);
+    return base64Encoded(input.bytes(), policy, map);
 }
 
-inline Base64Specification base64Encoded(const CString& input, Base64EncodePolicy policy = Base64EncodePolicy::DoNotInsertLFs)
+inline Base64Specification base64Encoded(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
 {
-    return base64Encoded(input.data(), input.length(), policy);
+    return base64Encoded({ static_cast<const std::byte*>(input), length }, policy, map);
 }
 
-inline Base64Specification base64URLEncoded(const void* inputData, unsigned inputLength)
+inline Base64Specification base64URLEncoded(Span<const std::byte> input)
 {
-    return base64Encoded(inputData, inputLength, Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Base64Specification base64URLEncoded(const Vector<uint8_t>& input)
+inline Base64Specification base64URLEncoded(Span<const uint8_t> input)
 {
-    return base64Encoded(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Base64Specification base64URLEncoded(const Vector<char>& input)
+inline Base64Specification base64URLEncoded(const CString& input)
 {
-    return base64Encoded(input.data(), input.size(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
-inline Base64Specification base64URLEncoded(const CString& input)
+inline Base64Specification base64URLEncoded(const void* input, unsigned length)
 {
-    return base64Encoded(input.data(), input.length(), Base64EncodePolicy::URL, Base64EncodeMap::URL);
+    return base64Encoded(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
 }
 
 template<> class StringTypeAdapter<Base64Specification> {
@@ -258,7 +346,7 @@
 public:
     StringTypeAdapter(const Base64Specification& base64)
         : m_base64 { base64 }
-        , m_encodedLength { calculateBase64EncodedSize(base64.inputLength, base64.policy) }
+        , m_encodedLength { calculateBase64EncodedSize(base64.input.size(), base64.policy) }
     {
     }
 
@@ -267,7 +355,7 @@
 
     template<typename CharacterType> void writeTo(CharacterType* destination) const
     {
-        base64Encode(m_base64.inputData, m_base64.inputLength, destination, m_encodedLength, m_base64.policy, m_base64.map);
+        base64Encode(m_base64.input, Span { destination, m_encodedLength }, m_base64.policy, m_base64.map);
     }
 
 private:

Modified: trunk/Source/WTF/wtf/text/CString.h (279050 => 279051)


--- trunk/Source/WTF/wtf/text/CString.h	2021-06-19 20:31:11 UTC (rev 279050)
+++ trunk/Source/WTF/wtf/text/CString.h	2021-06-20 02:05:08 UTC (rev 279051)
@@ -29,6 +29,7 @@
 #include <wtf/HashTraits.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
+#include <wtf/Span.h>
 
 namespace WTF {
 
@@ -73,6 +74,20 @@
 
     const uint8_t* dataAsUInt8Ptr() const { return reinterpret_cast<const uint8_t*>(data()); }
 
+    Span<const uint8_t> bytes() const
+    {
+        if (m_buffer)
+            return { reinterpret_cast<const uint8_t*>(m_buffer->data()), m_buffer->length() };
+        return { };
+    }
+
+    Span<const uint8_t> bytesInludingNullTerminator() const
+    {
+        if (m_buffer)
+            return { reinterpret_cast<const uint8_t*>(m_buffer->data()), m_buffer->length() + 1 };
+        return { };
+    }
+
     WTF_EXPORT_PRIVATE char* mutableData();
     size_t length() const
     {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to