Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4921 | Serge | 1 | /* |
2 | FUNCTION |
||
3 | < |
||
4 | |||
5 | INDEX |
||
6 | a64l |
||
7 | INDEX |
||
8 | l64a |
||
9 | |||
10 | ANSI_SYNOPSIS |
||
11 | #include |
||
12 | long a64l(const char *<[input]>); |
||
13 | char *l64a(long <[input]>); |
||
14 | |||
15 | TRAD_SYNOPSIS |
||
16 | #include |
||
17 | long a64l(<[input]>) |
||
18 | const char *<[input]>; |
||
19 | |||
20 | char *l64a(<[input]>) |
||
21 | long <[input]>; |
||
22 | |||
23 | DESCRIPTION |
||
24 | Conversion is performed between long and radix-64 characters. The |
||
25 | < |
||
26 | least significant bits to the most significant bits. The input value |
||
27 | is split up into a maximum of 5 groups of 6 bits and possibly one |
||
28 | group of 2 bits (bits 31 and 30). |
||
29 | |||
30 | Each group of 6 bits forms a value from 0--63 which is translated into |
||
31 | a character as follows: |
||
32 | |||
33 | O+ |
||
34 | o 0 = '.' |
||
35 | o 1 = '/' |
||
36 | o 2--11 = '0' to '9' |
||
37 | o 12--37 = 'A' to 'Z' |
||
38 | o 38--63 = 'a' to 'z' |
||
39 | O- |
||
40 | |||
41 | When the remaining bits are zero or all bits have been translated, a |
||
42 | null terminator is appended to the string. An input value of 0 |
||
43 | results in the empty string. |
||
44 | |||
45 | The < |
||
46 | character is used to generate a 6-bit value for up to 30 bits and then |
||
47 | a 2-bit value to complete a 32-bit result. The null terminator means |
||
48 | that the remaining digits are 0. An empty input string or NULL string |
||
49 | results in 0L. An invalid string results in undefined behavior. If |
||
50 | the size of a long is greater than 32 bits, the result is sign-extended. |
||
51 | |||
52 | RETURNS |
||
53 | < |
||
54 | < |
||
55 | |||
56 | PORTABILITY |
||
57 | < |
||
58 | |||
59 | Supporting OS subroutines required: None. |
||
60 | */ |
||
61 | |||
62 | #include <_ansi.h> |
||
63 | #include |
||
64 | #include |
||
65 | |||
66 | long |
||
67 | _DEFUN (a64l, (input), |
||
68 | const char *input) |
||
69 | { |
||
70 | const char *ptr; |
||
71 | char ch; |
||
72 | int i, digit; |
||
73 | unsigned long result = 0; |
||
74 | |||
75 | if (input == NULL) |
||
76 | return 0; |
||
77 | |||
78 | ptr = input; |
||
79 | |||
80 | /* it easiest to go from most significant digit to least so find end of input or up |
||
81 | to 6 characters worth */ |
||
82 | for (i = 0; i < 6; ++i) |
||
83 | { |
||
84 | if (*ptr) |
||
85 | ++ptr; |
||
86 | } |
||
87 | |||
88 | while (ptr > input) |
||
89 | { |
||
90 | ch = *(--ptr); |
||
91 | |||
92 | #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) |
||
93 | if (ch >= 'a') |
||
94 | digit = (ch - 'a') + 38; |
||
95 | else if (ch >= 'A') |
||
96 | digit = (ch - 'A') + 12; |
||
97 | else if (ch >= '0') |
||
98 | digit = (ch - '0') + 2; |
||
99 | else if (ch == '/') |
||
100 | digit = 1; |
||
101 | else |
||
102 | digit = 0; |
||
103 | #else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) */ |
||
104 | switch (ch) |
||
105 | { |
||
106 | case '/': |
||
107 | digit = 1; |
||
108 | break; |
||
109 | case '0': |
||
110 | case '1': |
||
111 | case '2': |
||
112 | case '3': |
||
113 | case '4': |
||
114 | case '5': |
||
115 | case '6': |
||
116 | case '7': |
||
117 | case '8': |
||
118 | case '9': |
||
119 | digit = (ch - '0') + 2; |
||
120 | break; |
||
121 | case 'A': |
||
122 | case 'B': |
||
123 | case 'C': |
||
124 | case 'D': |
||
125 | case 'E': |
||
126 | case 'F': |
||
127 | case 'G': |
||
128 | case 'H': |
||
129 | case 'I': |
||
130 | case 'J': |
||
131 | case 'K': |
||
132 | case 'L': |
||
133 | case 'M': |
||
134 | case 'N': |
||
135 | case 'O': |
||
136 | case 'P': |
||
137 | case 'Q': |
||
138 | case 'R': |
||
139 | case 'S': |
||
140 | case 'T': |
||
141 | case 'U': |
||
142 | case 'V': |
||
143 | case 'W': |
||
144 | case 'X': |
||
145 | case 'Y': |
||
146 | case 'Z': |
||
147 | digit = (ch - 'A') + 12; |
||
148 | break; |
||
149 | case 'a': |
||
150 | case 'b': |
||
151 | case 'c': |
||
152 | case 'd': |
||
153 | case 'e': |
||
154 | case 'f': |
||
155 | case 'g': |
||
156 | case 'h': |
||
157 | case 'i': |
||
158 | case 'j': |
||
159 | case 'k': |
||
160 | case 'l': |
||
161 | case 'm': |
||
162 | case 'n': |
||
163 | case 'o': |
||
164 | case 'p': |
||
165 | case 'q': |
||
166 | case 'r': |
||
167 | case 's': |
||
168 | case 't': |
||
169 | case 'u': |
||
170 | case 'v': |
||
171 | case 'w': |
||
172 | case 'x': |
||
173 | case 'y': |
||
174 | case 'z': |
||
175 | digit = (ch - 'a') + 38; |
||
176 | break; |
||
177 | default: |
||
178 | digit = 0; |
||
179 | break; |
||
180 | } |
||
181 | #endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) */ |
||
182 | |||
183 | result = (result << 6) + digit; |
||
184 | } |
||
185 | |||
186 | #if LONG_MAX > 2147483647 |
||
187 | /* for implementations where long is > 32 bits, the result must be sign-extended */ |
||
188 | if (result & 0x80000000) |
||
189 | return (((long)-1 >> 32) << 32) + result; |
||
190 | #endif |
||
191 | |||
192 | return result; |
||
193 | }><>><>> |
||
194 |