mdebug

cortex m series debugger
git clone http://frotz.net/git/mdebug.git
Log | Files | Refs | README | LICENSE

base64.c (3415B)


      1 /* base64.h
      2  *
      3  * Copyright 2011 Brian Swetland <swetland@frotz.net>
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <stdint.h>
     21 #include <unistd.h>
     22 #include <string.h>
     23 
     24 typedef uint8_t u8;
     25 typedef uint32_t u32;
     26 
     27 #define OP_MASK  0xC0
     28 #define OP_BITS  0x00
     29 #define OP_END   0x40
     30 #define OP_SKIP  0x80
     31 #define OP_BAD   0xC0
     32 
     33 static u8 DTABLE[256] =
     34 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x80\x80\xc0\xc0\x80\xc0\xc0"
     35 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     36 	"\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x3e\xc0\xc0\xc0\x3f"
     37 	"\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\xc0\xc0\xc0\x40\xc0\xc0"
     38 	"\xc0\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
     39 	"\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xc0\xc0\xc0\xc0\xc0"
     40 	"\xc0\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28"
     41 	"\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\xc0\xc0\xc0\xc0\xc0"
     42 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     43 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     44 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     45 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     46 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     47 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     48 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0"
     49 	"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0";
     50 
     51 static u8 ETABLE[64] =
     52 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     53 	"abcdefghijklmnopqrstuvwxyz"
     54 	"0123456789+/";
     55 
     56 int base64_decode(u8 *data, u32 len, u8 *out)
     57 {
     58 	u8 *start = out;
     59 	u32 tmp = 0, pos = 0;
     60 
     61 	while (len-- > 0) {
     62 		u8 x = DTABLE[*data++];
     63 		switch (x & OP_MASK) {
     64 		case OP_BITS:
     65 			tmp = (tmp << 6) | x;
     66 			if (++pos == 4) {
     67 				*out++ = tmp >> 16;
     68 				*out++ = tmp >> 8;
     69 				*out++ = tmp;
     70 				tmp = 0;
     71 				pos = 0;
     72 			}
     73 			break;
     74 		case OP_SKIP:
     75 			break;
     76 		case OP_END:
     77 			if (pos == 2) {
     78 				if (*data != '=')
     79 					return -1;
     80 				*out++ = (tmp >> 4);
     81 			} else if (pos == 3) {
     82 				*out++ = (tmp >> 10);
     83 				*out++ = (tmp >> 2);
     84 			} else {
     85 				return -1;
     86 			}
     87 			return out - start;
     88 		case OP_BAD:
     89 			return -1;
     90 		}
     91 	}
     92 
     93 	if (pos != 0)
     94 		return -1;
     95 
     96 	return out - start;
     97 }
     98 
     99 int base64_encode(u8 *data, u32 len, u8 *out)
    100 {
    101 	u8 *start = out;
    102 	u32 n;
    103 
    104 	while (len >= 3) {
    105 		n = (data[0] << 16) | (data[1] << 8) | data[2];
    106 		data += 3;
    107 		len -= 3;
    108 		*out++ = ETABLE[(n >> 18) & 63];
    109 		*out++ = ETABLE[(n >> 12) & 63];
    110 		*out++ = ETABLE[(n >> 6) & 63];
    111 		*out++ = ETABLE[n & 63];
    112 	}
    113 	if (len == 2) {
    114 		*out++ = ETABLE[(data[0] >> 2) & 63];
    115 		*out++ = ETABLE[((data[0] << 4) | (data[1] >> 4)) & 63];
    116 		*out++ = ETABLE[(data[1] << 2) & 63];
    117 		*out++ = '=';
    118 	} else if (len == 1) {
    119 		*out++ = ETABLE[(data[0] >> 2) & 63];
    120 		*out++ = ETABLE[(data[0] << 4) & 63];
    121 		*out++ = '=';
    122 		*out++ = '=';
    123 	}
    124 
    125 	return out - start;
    126 }