• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright Joyent, Inc. and other Node contributors.
2  //
3  // Permission is hereby granted, free of charge, to any person obtaining a
4  // copy of this software and associated documentation files (the
5  // "Software"), to deal in the Software without restriction, including
6  // without limitation the rights to use, copy, modify, merge, publish,
7  // distribute, sublicense, and/or sell copies of the Software, and to permit
8  // persons to whom the Software is furnished to do so, subject to the
9  // following conditions:
10  //
11  // The above copyright notice and this permission notice shall be included
12  // in all copies or substantial portions of the Software.
13  //
14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  // USE OR OTHER DEALINGS IN THE SOFTWARE.
21  
22  #ifndef SRC_STRING_BYTES_H_
23  #define SRC_STRING_BYTES_H_
24  
25  #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26  
27  // Decodes a v8::Local<v8::String> or Buffer to a raw char*
28  
29  #if (__GNUC__ >= 8) && !defined(__clang__)
30  #pragma GCC diagnostic push
31  #pragma GCC diagnostic ignored "-Wcast-function-type"
32  #endif
33  #include "v8.h"
34  #if (__GNUC__ >= 8) && !defined(__clang__)
35  #pragma GCC diagnostic pop
36  #endif
37  #include "env-inl.h"
38  
39  #include <string>
40  
41  namespace node {
42  
43  class StringBytes {
44   public:
45    class InlineDecoder : public MaybeStackBuffer<char> {
46     public:
Decode(Environment * env,v8::Local<v8::String> string,enum encoding enc)47      inline v8::Maybe<bool> Decode(Environment* env,
48                                    v8::Local<v8::String> string,
49                                    enum encoding enc) {
50        size_t storage;
51        if (!StringBytes::StorageSize(env->isolate(), string, enc).To(&storage))
52          return v8::Nothing<bool>();
53        AllocateSufficientStorage(storage);
54        const size_t length =
55            StringBytes::Write(env->isolate(), out(), storage, string, enc);
56  
57        // No zero terminator is included when using this method.
58        SetLength(length);
59        return v8::Just(true);
60      }
61  
size()62      inline size_t size() const { return length(); }
63    };
64  
65    // Fast, but can be 2 bytes oversized for Base64, and
66    // as much as triple UTF-8 strings <= 65536 chars in length
67    static v8::Maybe<size_t> StorageSize(v8::Isolate* isolate,
68                                         v8::Local<v8::Value> val,
69                                         enum encoding enc);
70  
71    // Precise byte count, but slightly slower for Base64 and
72    // very much slower for UTF-8
73    static v8::Maybe<size_t> Size(v8::Isolate* isolate,
74                                  v8::Local<v8::Value> val,
75                                  enum encoding enc);
76  
77    // Write the bytes from the string or buffer into the char*
78    // returns the number of bytes written, which will always be
79    // <= buflen.  Use StorageSize/Size first to know how much
80    // memory to allocate.
81    static size_t Write(v8::Isolate* isolate,
82                        char* buf,
83                        size_t buflen,
84                        v8::Local<v8::Value> val,
85                        enum encoding enc,
86                        int* chars_written = nullptr);
87  
88    // Take the bytes in the src, and turn it into a Buffer or String.
89    static v8::MaybeLocal<v8::Value> Encode(v8::Isolate* isolate,
90                                            const char* buf,
91                                            size_t buflen,
92                                            enum encoding encoding,
93                                            v8::Local<v8::Value>* error);
94  
95    // Warning: This reverses endianness on BE platforms, even though the
96    // signature using uint16_t implies that it should not.
97    // However, the brokenness is already public API and can't therefore
98    // be changed easily.
99    static v8::MaybeLocal<v8::Value> Encode(v8::Isolate* isolate,
100                                            const uint16_t* buf,
101                                            size_t buflen,
102                                            v8::Local<v8::Value>* error);
103  
104    static v8::MaybeLocal<v8::Value> Encode(v8::Isolate* isolate,
105                                            const char* buf,
106                                            enum encoding encoding,
107                                            v8::Local<v8::Value>* error);
108  
109    static size_t hex_encode(const char* src,
110                             size_t slen,
111                             char* dst,
112                             size_t dlen);
113  
114    static std::string hex_encode(const char* src, size_t slen);
115  
116   private:
117    static size_t WriteUCS2(v8::Isolate* isolate,
118                            char* buf,
119                            size_t buflen,
120                            v8::Local<v8::String> str,
121                            int flags,
122                            size_t* chars_written);
123  };
124  
125  }  // namespace node
126  
127  #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
128  
129  #endif  // SRC_STRING_BYTES_H_
130