]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/mime.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / common / mime.c
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14 #include "common/utf8.h"
15
16 #include <errno.h>
17 #include <stdio.h>
18
19 int mime_encode_as_qp(const char *input, char *output, int outlen)
20 {
21 int ret = 1;
22 char *o = output;
23 const unsigned char *i = (const unsigned char*)input;
24 while (1) {
25 int c = *i;
26 if (c == '\0') {
27 break;
28 }
29 else if ((c & 0x80) || (c == '=') || (is_control_character(c))) {
30 if (outlen >= 3) {
31 snprintf(o, outlen, "=%02X", c);
32 outlen -= 3;
33 o += 3;
34 }
35 else
36 outlen = 0;
37 ret += 3;
38 }
39 else {
40 if (outlen >= 1) {
41 snprintf(o, outlen, "%c", c);
42 outlen -= 1;
43 o += 1;
44 }
45 ret += 1;
46 }
47 ++i;
48 }
49 return ret;
50 }
51
52 static inline signed int hexchar_to_int(unsigned int c)
53 {
54 switch(c) {
55 case '0':
56 return 0;
57 case '1':
58 return 1;
59 case '2':
60 return 2;
61 case '3':
62 return 3;
63 case '4':
64 return 4;
65 case '5':
66 return 5;
67 case '6':
68 return 6;
69 case '7':
70 return 7;
71 case '8':
72 return 8;
73 case '9':
74 return 9;
75 case 'A':
76 case 'a':
77 return 10;
78 case 'B':
79 case 'b':
80 return 11;
81 case 'C':
82 case 'c':
83 return 12;
84 case 'D':
85 case 'd':
86 return 13;
87 case 'E':
88 case 'e':
89 return 14;
90 case 'F':
91 case 'f':
92 return 15;
93 case '\0':
94 default:
95 return -EDOM;
96 }
97 }
98
99 int mime_decode_from_qp(const char *input, char *output, int outlen)
100 {
101 int ret = 1;
102 char *o = output;
103 const unsigned char *i = (const unsigned char*)input;
104 while (1) {
105 unsigned int c = *i;
106 if (c == '\0') {
107 break;
108 }
109 else if (c & 0x80) {
110 /* The high bit is never set in quoted-printable encoding! */
111 return -EDOM;
112 }
113 else if (c == '=') {
114 int high = hexchar_to_int(*++i);
115 if (high < 0)
116 return -EINVAL;
117 int low = hexchar_to_int(*++i);
118 if (low < 0)
119 return -EINVAL;
120 c = (high << 4) + low;
121 }
122 ++i;
123
124 if (outlen >= 1) {
125 snprintf(o, outlen, "%c", c);
126 outlen -= 1;
127 o += 1;
128 }
129 ret += 1;
130 }
131 return ret;
132 }