1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <https/Support.h>
18
19 #include <cassert>
20 #include <cstdint>
21 #include <cstdio>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <sys/errno.h>
25
makeFdNonblocking(int fd)26 void makeFdNonblocking(int fd) {
27 int flags = fcntl(fd, F_GETFL, 0);
28 if (flags < 0) { flags = 0; }
29 DEBUG_ONLY(int res = )fcntl(fd, F_SETFL, flags | O_NONBLOCK);
30 assert(res >= 0);
31 }
32
hexdump(const void * _data,size_t size)33 void hexdump(const void *_data, size_t size) {
34 const uint8_t *data = static_cast<const uint8_t *>(_data);
35
36 size_t offset = 0;
37 while (offset < size) {
38 printf("%08zx: ", offset);
39
40 for (size_t col = 0; col < 16; ++col) {
41 if (offset + col < size) {
42 printf("%02x ", data[offset + col]);
43 } else {
44 printf(" ");
45 }
46
47 if (col == 7) {
48 printf(" ");
49 }
50 }
51
52 printf(" ");
53
54 for (size_t col = 0; col < 16; ++col) {
55 if (offset + col < size && isprint(data[offset + col])) {
56 printf("%c", data[offset + col]);
57 } else if (offset + col < size) {
58 printf(".");
59 }
60 }
61
62 printf("\n");
63
64 offset += 16;
65 }
66 }
67
encode6Bit(unsigned x)68 static char encode6Bit(unsigned x) {
69 static char base64[] =
70 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
71 return base64[x & 63];
72 }
73
encodeBase64(const void * _data,size_t size,std::string * out)74 void encodeBase64(const void *_data, size_t size, std::string *out) {
75 out->clear();
76 out->reserve(((size+2)/3)*4);
77
78 const uint8_t *data = (const uint8_t *)_data;
79
80 size_t i;
81 for (i = 0; i < (size / 3) * 3; i += 3) {
82 uint8_t x1 = data[i];
83 uint8_t x2 = data[i + 1];
84 uint8_t x3 = data[i + 2];
85
86 out->append(1, encode6Bit(x1 >> 2));
87 out->append(1, encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
88 out->append(1, encode6Bit((x2 << 2 | x3 >> 6) & 0x3f));
89 out->append(1, encode6Bit(x3 & 0x3f));
90 }
91 switch (size % 3) {
92 case 0:
93 break;
94 case 2:
95 {
96 uint8_t x1 = data[i];
97 uint8_t x2 = data[i + 1];
98 out->append(1, encode6Bit(x1 >> 2));
99 out->append(1, encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
100 out->append(1, encode6Bit((x2 << 2) & 0x3f));
101 out->append(1, '=');
102 break;
103 }
104 default:
105 {
106 uint8_t x1 = data[i];
107 out->append(1, encode6Bit(x1 >> 2));
108 out->append(1, encode6Bit((x1 << 4) & 0x3f));
109 out->append("==");
110 break;
111 }
112 }
113 }
114
U16_AT(const uint8_t * ptr)115 uint16_t U16_AT(const uint8_t *ptr) {
116 return ptr[0] << 8 | ptr[1];
117 }
118
U32_AT(const uint8_t * ptr)119 uint32_t U32_AT(const uint8_t *ptr) {
120 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
121 }
122
U64_AT(const uint8_t * ptr)123 uint64_t U64_AT(const uint8_t *ptr) {
124 return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
125 }
126
U16LE_AT(const uint8_t * ptr)127 uint16_t U16LE_AT(const uint8_t *ptr) {
128 return ptr[0] | (ptr[1] << 8);
129 }
130
U32LE_AT(const uint8_t * ptr)131 uint32_t U32LE_AT(const uint8_t *ptr) {
132 return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
133 }
134
U64LE_AT(const uint8_t * ptr)135 uint64_t U64LE_AT(const uint8_t *ptr) {
136 return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
137 }
138