OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libc/] [stdlib/] [a64l.c] - Blame information for rev 862

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/*
2
FUNCTION
3
<<a64l>>, <<l64a>>---convert between radix-64 ASCII string and long
4
 
5
INDEX
6
        a64l
7
INDEX
8
        l64a
9
 
10
ANSI_SYNOPSIS
11
        #include <stdlib.h>
12
        long a64l(const char *<[input]>);
13
        char *l64a(long <[input]>);
14
 
15
TRAD_SYNOPSIS
16
        #include <stdlib.h>
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
<<l64a>> 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 <<a64l>> 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
<<l64a>> returns a null-terminated string of 0 to 6 characters.
54
<<a64l>> returns the 32-bit translated value from the input character string.
55
 
56
PORTABILITY
57
<<l64a>> and <<a64l>> 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 <stdlib.h>
64
#include <limits.h>
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
 
195
 
196
 
197
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.