tvm
Loading...
Searching...
No Matches
base64.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
26#ifndef TVM_SUPPORT_BASE64_H_
27#define TVM_SUPPORT_BASE64_H_
28
29#include <tvm/ffi/error.h>
30#include <tvm/support/io.h>
31
32#include <cctype>
33#include <cstdio>
34#include <string>
35
36namespace tvm {
37namespace support {
39namespace base64 {
40// decoding table
41const char DecodeTable[] = {
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 62, // '+'
45 0, 0, 0,
46 63, // '/'
47 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
48 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
49 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
50 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
51 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
52};
53// encoding table
54static const char EncodeTable[] =
55 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56} // namespace base64
57
63 public:
64 explicit StreamBufferReader(size_t buffer_size) { buffer_.resize(buffer_size); }
70 stream_ = stream;
71 read_len_ = read_ptr_ = 1;
72 }
76 int GetChar() {
77 while (true) {
78 if (read_ptr_ < read_len_) {
79 return static_cast<int>(buffer_[read_ptr_++]);
80 } else {
81 read_len_ = stream_->Read(&buffer_[0], buffer_.length());
82 if (read_len_ == 0) return EOF;
83 read_ptr_ = 0;
84 }
85 }
86 }
88 bool AtEnd() const { return read_len_ == 0; }
89
90 private:
92 tvm::support::Stream* stream_{nullptr};
94 std::string buffer_;
96 size_t read_len_{1};
98 size_t read_ptr_{1};
99};
100
105 public:
106 explicit Base64InStream(tvm::support::Stream* fs) : reader_(256) { reader_.set_stream(fs); }
111 void InitPosition(void) {
112 // get a character
113 do {
114 temp_ch_ = reader_.GetChar();
115 } while (isspace(temp_ch_));
116 }
118 bool IsEOF(void) const { return num_prev_ == 0 && (temp_ch_ == EOF || isspace(temp_ch_)); }
119
121 // override read function.
122 size_t Read(void* ptr, size_t size) final {
124 if (size == 0) return 0;
125 // use tlen to record left size
126 size_t tlen = size;
127 unsigned char* cptr = static_cast<unsigned char*>(ptr);
128 // if anything left, load from previous buffered result
129 if (num_prev_ != 0) {
130 if (num_prev_ == 2) {
131 if (tlen >= 2) {
132 *cptr++ = buf_prev[0];
133 *cptr++ = buf_prev[1];
134 tlen -= 2;
135 num_prev_ = 0;
136 } else {
137 // assert tlen == 1
138 *cptr++ = buf_prev[0];
139 --tlen;
140 buf_prev[0] = buf_prev[1];
141 num_prev_ = 1;
142 }
143 } else {
144 // assert num_prev_ == 1
145 *cptr++ = buf_prev[0];
146 --tlen;
147 num_prev_ = 0;
148 }
149 }
150 if (tlen == 0) return size;
151 int nvalue;
152 // note: everything goes with 4 bytes in Base64
153 // so we process 4 bytes a unit
154 while (tlen && temp_ch_ != EOF && !isspace(temp_ch_)) {
155 // first byte
156 nvalue = DecodeTable[temp_ch_] << 18;
157 {
158 // second byte
159 temp_ch_ = reader_.GetChar();
160 TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
161 nvalue |= DecodeTable[temp_ch_] << 12;
162 *cptr++ = (nvalue >> 16) & 0xFF;
163 --tlen;
164 }
165 {
166 // third byte
167 temp_ch_ = reader_.GetChar();
168 TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
169 // handle termination
170 if (temp_ch_ == '=') {
171 temp_ch_ = reader_.GetChar();
172 TVM_FFI_ICHECK(temp_ch_ == '=') << "invalid base64 format";
173 temp_ch_ = reader_.GetChar();
174 TVM_FFI_ICHECK(temp_ch_ == EOF || isspace(temp_ch_)) << "invalid base64 format";
175 break;
176 }
177 nvalue |= DecodeTable[temp_ch_] << 6;
178 if (tlen) {
179 *cptr++ = (nvalue >> 8) & 0xFF;
180 --tlen;
181 } else {
182 buf_prev[num_prev_++] = (nvalue >> 8) & 0xFF;
183 }
184 }
185 {
186 // fourth byte
187 temp_ch_ = reader_.GetChar();
188 TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
189 if (temp_ch_ == '=') {
190 temp_ch_ = reader_.GetChar();
191 TVM_FFI_ICHECK(temp_ch_ == EOF || isspace(temp_ch_)) << "invalid base64 format";
192 break;
193 }
194 nvalue |= DecodeTable[temp_ch_];
195 if (tlen) {
196 *cptr++ = nvalue & 0xFF;
197 --tlen;
198 } else {
199 buf_prev[num_prev_++] = nvalue & 0xFF;
200 }
201 }
202 // get next char
203 temp_ch_ = reader_.GetChar();
204 }
205 if (kStrictCheck) {
206 TVM_FFI_ICHECK_EQ(tlen, 0) << "Base64InStream: read incomplete";
207 }
208 return size - tlen;
209 }
210 size_t Write(const void* ptr, size_t size) final {
211 TVM_FFI_THROW(InternalError) << "Base64InStream do not support write";
212 return 0;
213 }
214
215 private:
216 // internal reader
217 StreamBufferReader reader_;
218 int temp_ch_{0};
219 int num_prev_{0};
220 unsigned char buf_prev[2];
221 // whether we need to do strict check
222 static const bool kStrictCheck = false;
223};
224
229 public:
230 explicit Base64OutStream(tvm::support::Stream* fp) : fp_(fp) {}
231
233
234 size_t Write(const void* ptr, size_t size) final {
235 using base64::EncodeTable;
236 size_t tlen = size;
237 const unsigned char* cptr = static_cast<const unsigned char*>(ptr);
238 while (tlen) {
239 while (buf__top_ < 3 && tlen != 0) {
240 buf_[++buf__top_] = *cptr++;
241 --tlen;
242 }
243 if (buf__top_ == 3) {
244 // flush 4 bytes out
245 PutChar(EncodeTable[buf_[1] >> 2]);
246 PutChar(EncodeTable[((buf_[1] << 4) | (buf_[2] >> 4)) & 0x3F]);
247 PutChar(EncodeTable[((buf_[2] << 2) | (buf_[3] >> 6)) & 0x3F]);
248 PutChar(EncodeTable[buf_[3] & 0x3F]);
249 buf__top_ = 0;
250 }
251 }
252 return size;
253 }
254 virtual size_t Read(void* ptr, size_t size) {
255 TVM_FFI_THROW(InternalError) << "Base64OutStream do not support read";
256 return 0;
257 }
262 void Finish(int endch = EOF) {
263 using base64::EncodeTable;
264 if (buf__top_ == 1) {
265 PutChar(EncodeTable[buf_[1] >> 2]);
266 PutChar(EncodeTable[(buf_[1] << 4) & 0x3F]);
267 PutChar('=');
268 PutChar('=');
269 }
270 if (buf__top_ == 2) {
271 PutChar(EncodeTable[buf_[1] >> 2]);
272 PutChar(EncodeTable[((buf_[1] << 4) | (buf_[2] >> 4)) & 0x3F]);
273 PutChar(EncodeTable[(buf_[2] << 2) & 0x3F]);
274 PutChar('=');
275 }
276 buf__top_ = 0;
277 if (endch != EOF) PutChar(endch);
278 this->Flush();
279 }
280
281 private:
282 static constexpr size_t kBufferSize = 256;
283
284 tvm::support::Stream* fp_{nullptr};
285 int buf__top_{0};
286 unsigned char buf_[4];
287 std::string out_buf_;
288
289 void PutChar(char ch) {
290 out_buf_ += ch;
291 if (out_buf_.length() >= kBufferSize) Flush();
292 }
293 void Flush(void) {
294 if (out_buf_.length() != 0) {
295 fp_->Write(&out_buf_[0], out_buf_.length());
296 out_buf_.clear();
297 }
298 }
299};
300} // namespace support
301} // namespace tvm
302#endif // TVM_SUPPORT_BASE64_H_
Input stream from base64 encoding.
Definition base64.h:104
bool IsEOF(void) const
whether current position is end of a base64 stream
Definition base64.h:118
Base64InStream(tvm::support::Stream *fs)
Definition base64.h:106
void InitPosition(void)
initialize the stream position to beginning of next base64 stream
Definition base64.h:111
size_t Read(void *ptr, size_t size) final
Read raw bytes from the stream.
Definition base64.h:122
size_t Write(const void *ptr, size_t size) final
Write raw bytes to the stream.
Definition base64.h:210
Stream to write to base64 format.
Definition base64.h:228
size_t Write(const void *ptr, size_t size) final
Write raw bytes to the stream.
Definition base64.h:234
void Finish(int endch=EOF)
finish writing of all current base64 stream, do some post processing
Definition base64.h:262
virtual size_t Read(void *ptr, size_t size)
Read raw bytes from the stream.
Definition base64.h:254
Base64OutStream(tvm::support::Stream *fp)
Definition base64.h:230
Buffer reader from stream to avoid virtual call overhead on each read.
Definition base64.h:62
bool AtEnd() const
Definition base64.h:88
StreamBufferReader(size_t buffer_size)
Definition base64.h:64
int GetChar()
Definition base64.h:76
void set_stream(tvm::support::Stream *stream)
set input stream
Definition base64.h:69
Abstract binary stream for serialization.
Definition io.h:57
virtual size_t Read(void *ptr, size_t size)=0
Read raw bytes from the stream.
virtual size_t Write(const void *ptr, size_t size)=0
Write raw bytes to the stream.
Binary stream I/O interface.
const char DecodeTable[]
Definition base64.h:41
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23