7
/* #include <off_cvt.h>
9
/* off_t off_cvt_string(string)
10
/* const char *string;
12
/* VSTRING *off_cvt_number(result, offset)
16
/* This module provides conversions between \fIoff_t\fR and string.
18
/* off_cvt_string() converts a string, containing a non-negative
19
/* offset, to numerical form. The result is -1 in case of problems.
21
/* off_cvt_number() converts a non-negative offset to string form.
25
/* String with non-negative number to be converted to off_t.
27
/* Buffer for storage of the result of conversion to string.
29
/* Non-negative off_t value to be converted to string.
31
/* Panic: negative offset
35
/* The Secure Mailer license must be distributed with this software.
38
/* IBM T.J. Watson Research
40
/* Yorktown Heights, NY 10598, USA
48
/* Utility library. */
57
/* Application-specific. */
59
#define STR vstring_str
60
#define END vstring_end
61
#define SWAP(type, a, b) { type temp; temp = a; a = b; b = temp; }
63
/* off_cvt_string - string to number */
65
off_t off_cvt_string(const char *str)
75
* Multiplication by numbers > 2 can overflow without producing a smaller
76
* result mod 2^N (where N is the number of bits in the result type).
77
* (Victor Duchovni, Morgan Stanley).
79
for (result = 0; (ch = *(unsigned char *) str) != 0; str++) {
82
if ((res2 = result + result) < result)
84
if ((res4 = res2 + res2) < res2)
86
if ((res8 = res4 + res4) < res4)
88
if ((res10 = res8 + res2) < res8)
90
if ((result = res10 + ch - '0') < res10)
96
/* off_cvt_number - number to string */
98
VSTRING *off_cvt_number(VSTRING *buf, off_t offset)
100
static char digs[] = "0123456789";
109
msg_panic("off_cvt_number: negative offset -%s",
110
STR(off_cvt_number(buf, -offset)));
113
* First accumulate the result, backwards.
116
while (offset != 0) {
117
VSTRING_ADDCH(buf, digs[offset % 10]);
120
VSTRING_TERMINATE(buf);
123
* Then, reverse the result.
127
for (i = 0; i < VSTRING_LEN(buf) / 2; i++)
128
SWAP(int, start[i], last[-i]);
135
* Proof-of-concept test program. Read a number from stdin, convert to
136
* off_t, back to string, and print the result.
139
#include <vstring_vstream.h>
141
int main(int unused_argc, char **unused_argv)
143
VSTRING *buf = vstring_alloc(100);
146
while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
147
if ((offset = off_cvt_string(STR(buf))) < 0) {
148
msg_warn("bad input %s", STR(buf));
150
vstream_printf("%s\n", STR(off_cvt_number(buf, offset)));
152
vstream_fflush(VSTREAM_OUT);