Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4921 Serge 1
/*
2
FUNCTION
3
<>, <>---convert between radix-64 ASCII string and long
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
<> routine transforms up to 32 bits of input value starting from
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 <> function performs the reverse translation.  Each
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
<> returns a null-terminated string of 0 to 6 characters.
54
<> returns the 32-bit translated value from the input character string.
55
 
56
PORTABILITY
57
<> and <> are non-ANSI and are defined by the Single Unix Specification.
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