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