• 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       }
72       if (StringEqualNoCase(encoding, "binary"))
73         return LATIN1;  // BINARY is a deprecated alias of LATIN1.
74       if (StringEqualNoCase(encoding, "buffer"))
75         return BUFFER;
76       if (StringEqualNoCase(encoding, "base64"))
77         return BASE64;
78       break;
79 
80     case 'a':
81     case 'A':
82       // ascii
83       if (encoding[1] == 's') {
84         if (strncmp(encoding + 2, "cii", 4) == 0)
85           return ASCII;
86       }
87       if (StringEqualNoCase(encoding, "ascii"))
88         return ASCII;
89       break;
90 
91     case 'h':
92     case 'H':
93       // hex
94       if (encoding[1] == 'e')
95         if (encoding[2] == 'x' && encoding[3] == '\0')
96           return HEX;
97       if (StringEqualNoCase(encoding, "hex"))
98         return HEX;
99       break;
100   }
101   return default_encoding;
102 }
103 
104 
ParseEncoding(Isolate * isolate,Local<Value> encoding_v,enum encoding default_encoding)105 enum encoding ParseEncoding(Isolate* isolate,
106                             Local<Value> encoding_v,
107                             enum encoding default_encoding) {
108   CHECK(!encoding_v.IsEmpty());
109 
110   if (!encoding_v->IsString())
111     return default_encoding;
112 
113   Utf8Value encoding(isolate, encoding_v);
114 
115   return ParseEncoding(*encoding, default_encoding);
116 }
117 
Encode(Isolate * isolate,const char * buf,size_t len,enum encoding encoding)118 Local<Value> Encode(Isolate* isolate,
119                     const char* buf,
120                     size_t len,
121                     enum encoding encoding) {
122   CHECK_NE(encoding, UCS2);
123   Local<Value> error;
124   return StringBytes::Encode(isolate, buf, len, encoding, &error)
125       .ToLocalChecked();
126 }
127 
Encode(Isolate * isolate,const uint16_t * buf,size_t len)128 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
129   Local<Value> error;
130   return StringBytes::Encode(isolate, buf, len, &error)
131       .ToLocalChecked();
132 }
133 
134 // Returns -1 if the handle was not valid for decoding
DecodeBytes(Isolate * isolate,Local<Value> val,enum encoding encoding)135 ssize_t DecodeBytes(Isolate* isolate,
136                     Local<Value> val,
137                     enum encoding encoding) {
138   HandleScope scope(isolate);
139 
140   return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
141 }
142 
143 // Returns number of bytes written.
DecodeWrite(Isolate * isolate,char * buf,size_t buflen,Local<Value> val,enum encoding encoding)144 ssize_t DecodeWrite(Isolate* isolate,
145                     char* buf,
146                     size_t buflen,
147                     Local<Value> val,
148                     enum encoding encoding) {
149   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
150 }
151 
152 }  // namespace node
153