• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "node.h"
2 #include "string_bytes.h"
3 #include "util-inl.h"
4 #include "v8.h"
5 
6 namespace node {
7 
8 using v8::HandleScope;
9 using v8::Isolate;
10 using v8::Local;
11 using v8::Value;
12 
ParseEncoding(const char * encoding,enum encoding default_encoding)13 enum encoding ParseEncoding(const char* encoding,
14                             enum encoding default_encoding) {
15   switch (encoding[0]) {
16     case 'u':
17     case 'U':
18       // utf8, utf16le
19       if (encoding[1] == 't' && encoding[2] == 'f') {
20         // Skip `-`
21         const size_t skip = encoding[3] == '-' ? 4 : 3;
22         if (encoding[skip] == '8' && encoding[skip + 1] == '\0')
23           return UTF8;
24         if (strncmp(encoding + skip, "16le", 5) == 0)
25           return UCS2;
26       // ucs2
27       } else if (encoding[1] == 'c' && encoding[2] == 's') {
28         const size_t skip = encoding[3] == '-' ? 4 : 3;
29         if (encoding[skip] == '2' && encoding[skip + 1] == '\0')
30           return UCS2;
31       }
32       if (StringEqualNoCase(encoding, "utf8"))
33         return UTF8;
34       if (StringEqualNoCase(encoding, "utf-8"))
35         return UTF8;
36       if (StringEqualNoCase(encoding, "ucs2"))
37         return UCS2;
38       if (StringEqualNoCase(encoding, "ucs-2"))
39         return UCS2;
40       if (StringEqualNoCase(encoding, "utf16le"))
41         return UCS2;
42       if (StringEqualNoCase(encoding, "utf-16le"))
43         return UCS2;
44       break;
45 
46     case 'l':
47     case 'L':
48       // latin1
49       if (encoding[1] == 'a') {
50         if (strncmp(encoding + 2, "tin1", 5) == 0)
51           return LATIN1;
52       }
53       if (StringEqualNoCase(encoding, "latin1"))
54         return LATIN1;
55       break;
56 
57     case 'b':
58     case 'B':
59       // binary is a deprecated alias of latin1
60       if (encoding[1] == 'i') {
61         if (strncmp(encoding + 2, "nary", 5) == 0)
62           return LATIN1;
63       // buffer
64       } else if (encoding[1] == 'u') {
65         if (strncmp(encoding + 2, "ffer", 5) == 0)
66           return BUFFER;
67       // base64
68       } else if (encoding[1] == 'a') {
69         if (strncmp(encoding + 2, "se64", 5) == 0)
70           return BASE64;
71         if (strncmp(encoding + 2, "se64url", 8) == 0)
72           return BASE64URL;
73       }
74       if (StringEqualNoCase(encoding, "binary"))
75         return LATIN1;  // BINARY is a deprecated alias of LATIN1.
76       if (StringEqualNoCase(encoding, "buffer"))
77         return BUFFER;
78       if (StringEqualNoCase(encoding, "base64"))
79         return BASE64;
80       if (StringEqualNoCase(encoding, "base64url"))
81         return BASE64URL;
82       break;
83 
84     case 'a':
85     case 'A':
86       // ascii
87       if (encoding[1] == 's') {
88         if (strncmp(encoding + 2, "cii", 4) == 0)
89           return ASCII;
90       }
91       if (StringEqualNoCase(encoding, "ascii"))
92         return ASCII;
93       break;
94 
95     case 'h':
96     case 'H':
97       // hex
98       if (encoding[1] == 'e')
99         if (encoding[2] == 'x' && encoding[3] == '\0')
100           return HEX;
101       if (StringEqualNoCase(encoding, "hex"))
102         return HEX;
103       break;
104   }
105   return default_encoding;
106 }
107 
108 
ParseEncoding(Isolate * isolate,Local<Value> encoding_v,enum encoding default_encoding)109 enum encoding ParseEncoding(Isolate* isolate,
110                             Local<Value> encoding_v,
111                             enum encoding default_encoding) {
112   CHECK(!encoding_v.IsEmpty());
113 
114   if (!encoding_v->IsString())
115     return default_encoding;
116 
117   Utf8Value encoding(isolate, encoding_v);
118 
119   return ParseEncoding(*encoding, default_encoding);
120 }
121 
Encode(Isolate * isolate,const char * buf,size_t len,enum encoding encoding)122 Local<Value> Encode(Isolate* isolate,
123                     const char* buf,
124                     size_t len,
125                     enum encoding encoding) {
126   CHECK_NE(encoding, UCS2);
127   Local<Value> error;
128   return StringBytes::Encode(isolate, buf, len, encoding, &error)
129       .ToLocalChecked();
130 }
131 
Encode(Isolate * isolate,const uint16_t * buf,size_t len)132 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
133   Local<Value> error;
134   return StringBytes::Encode(isolate, buf, len, &error)
135       .ToLocalChecked();
136 }
137 
138 // Returns -1 if the handle was not valid for decoding
DecodeBytes(Isolate * isolate,Local<Value> val,enum encoding encoding)139 ssize_t DecodeBytes(Isolate* isolate,
140                     Local<Value> val,
141                     enum encoding encoding) {
142   HandleScope scope(isolate);
143 
144   return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
145 }
146 
147 // Returns number of bytes written.
DecodeWrite(Isolate * isolate,char * buf,size_t buflen,Local<Value> val,enum encoding encoding)148 ssize_t DecodeWrite(Isolate* isolate,
149                     char* buf,
150                     size_t buflen,
151                     Local<Value> val,
152                     enum encoding encoding) {
153   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
154 }
155 
156 }  // namespace node
157