GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: api/encoding.cc Lines: 79 87 90.8 %
Date: 2022-11-04 03:21:42 Branches: 75 90 83.3 %

Line Branch Exec Source
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
13
89387
enum encoding ParseEncoding(const char* encoding,
14
                            enum encoding default_encoding) {
15

89387
  switch (encoding[0]) {
16
17651
    case 'u':
17
    case 'U':
18
      // Note: the two first conditions are needed for performance reasons
19
      // as "utf8"/"utf-8" is a common case.
20
      // (same for other cases below)
21
22
      // utf8, utf16le
23

17651
      if (encoding[1] == 't' && encoding[2] == 'f') {
24
        // Skip `-`
25
17619
        const size_t skip = encoding[3] == '-' ? 4 : 3;
26

17619
        if (encoding[skip] == '8' && encoding[skip + 1] == '\0')
27
17596
          return UTF8;
28
23
        if (strncmp(encoding + skip, "16le", 5) == 0)
29
23
          return UCS2;
30
      // ucs2
31

32
      } else if (encoding[1] == 'c' && encoding[2] == 's') {
32
23
        const size_t skip = encoding[3] == '-' ? 4 : 3;
33

23
        if (encoding[skip] == '2' && encoding[skip + 1] == '\0')
34
23
          return UCS2;
35
      }
36
11
      if (StringEqualNoCase(encoding, "utf8"))
37
1
        return UTF8;
38
10
      if (StringEqualNoCase(encoding, "utf-8"))
39
3
        return UTF8;
40
7
      if (StringEqualNoCase(encoding, "ucs2"))
41
1
        return UCS2;
42
6
      if (StringEqualNoCase(encoding, "ucs-2"))
43
1
        return UCS2;
44
5
      if (StringEqualNoCase(encoding, "utf16le"))
45
1
        return UCS2;
46
4
      if (StringEqualNoCase(encoding, "utf-16le"))
47
1
        return UCS2;
48
3
      break;
49
50
65865
    case 'l':
51
    case 'L':
52
      // latin1
53
65865
      if (encoding[1] == 'a') {
54
65862
        if (strncmp(encoding + 2, "tin1", 5) == 0)
55
65862
          return LATIN1;
56
      }
57
3
      if (StringEqualNoCase(encoding, "latin1"))
58
1
        return LATIN1;
59
2
      break;
60
61
2446
    case 'b':
62
    case 'B':
63
      // binary is a deprecated alias of latin1
64
2446
      if (encoding[1] == 'i') {
65
19
        if (strncmp(encoding + 2, "nary", 5) == 0)
66
19
          return LATIN1;
67
      // buffer
68
2427
      } else if (encoding[1] == 'u') {
69
2238
        if (strncmp(encoding + 2, "ffer", 5) == 0)
70
2238
          return BUFFER;
71
      // base64
72
189
      } else if (encoding[1] == 'a') {
73
183
        if (strncmp(encoding + 2, "se64", 5) == 0)
74
166
          return BASE64;
75
17
        if (strncmp(encoding + 2, "se64url", 8) == 0)
76
17
          return BASE64URL;
77
      }
78
6
      if (StringEqualNoCase(encoding, "binary"))
79
1
        return LATIN1;  // BINARY is a deprecated alias of LATIN1.
80
5
      if (StringEqualNoCase(encoding, "buffer"))
81
1
        return BUFFER;
82
4
      if (StringEqualNoCase(encoding, "base64"))
83
1
        return BASE64;
84
3
      if (StringEqualNoCase(encoding, "base64url"))
85
1
        return BASE64URL;
86
2
      break;
87
88
95
    case 'a':
89
    case 'A':
90
      // ascii
91
95
      if (encoding[1] == 's') {
92
94
        if (strncmp(encoding + 2, "cii", 4) == 0)
93
93
          return ASCII;
94
      }
95
2
      if (StringEqualNoCase(encoding, "ascii"))
96
1
        return ASCII;
97
1
      break;
98
99
3329
    case 'h':
100
    case 'H':
101
      // hex
102
3329
      if (encoding[1] == 'e')
103

3327
        if (encoding[2] == 'x' && encoding[3] == '\0')
104
3327
          return HEX;
105
2
      if (StringEqualNoCase(encoding, "hex"))
106
1
        return HEX;
107
1
      break;
108
  }
109
10
  return default_encoding;
110
}
111
112
113
237302
enum encoding ParseEncoding(Isolate* isolate,
114
                            Local<Value> encoding_v,
115
                            enum encoding default_encoding) {
116
237302
  CHECK(!encoding_v.IsEmpty());
117
118
474604
  if (!encoding_v->IsString())
119
147915
    return default_encoding;
120
121
178774
  Utf8Value encoding(isolate, encoding_v);
122
123
89387
  return ParseEncoding(*encoding, default_encoding);
124
}
125
126
2
Local<Value> Encode(Isolate* isolate,
127
                    const char* buf,
128
                    size_t len,
129
                    enum encoding encoding) {
130
2
  CHECK_NE(encoding, UCS2);
131
  Local<Value> error;
132
4
  return StringBytes::Encode(isolate, buf, len, encoding, &error)
133
2
      .ToLocalChecked();
134
}
135
136
Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
137
  Local<Value> error;
138
  return StringBytes::Encode(isolate, buf, len, &error)
139
      .ToLocalChecked();
140
}
141
142
// Returns -1 if the handle was not valid for decoding
143
ssize_t DecodeBytes(Isolate* isolate,
144
                    Local<Value> val,
145
                    enum encoding encoding) {
146
  HandleScope scope(isolate);
147
148
  return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
149
}
150
151
// Returns number of bytes written.
152
ssize_t DecodeWrite(Isolate* isolate,
153
                    char* buf,
154
                    size_t buflen,
155
                    Local<Value> val,
156
                    enum encoding encoding) {
157
  return StringBytes::Write(isolate, buf, buflen, val, encoding);
158
}
159
160
}  // namespace node