blob: 428f71bdbae966c095349cbdf73968dd3b00d621 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/*
* mstolfp - convert an ascii string in milliseconds to an l_fp number
*/
#include <config.h>
#include <stdio.h>
#include <ctype.h>
#include "ntp_fp.h"
#include "ntp_stdlib.h"
int
mstolfp(
const char *str,
l_fp *lfp
)
{
int ch, neg = 0;
u_int32 q, r;
/*
* We understand numbers of the form:
*
* [spaces][-|+][digits][.][digits][spaces|\n|\0]
*
* This is kinda hack. We use 'atolfp' to do the basic parsing
* (after some initial checks) and then divide the result by
* 1000. The original implementation avoided that by
* hacking up the input string to move the decimal point, but
* that needed string manipulations prone to buffer overruns.
* To avoid that trouble we do the conversion first and adjust
* the result.
*/
while (isspace(ch = *(const unsigned char*)str))
++str;
switch (ch) {
case '-': neg = TRUE;
case '+': ++str;
default : break;
}
if (!isdigit(ch = *(const unsigned char*)str) && (ch != '.'))
return 0;
if (!atolfp(str, lfp))
return 0;
/* now do a chained/overlapping division by 1000 to get from
* seconds to msec. 1000 is small enough to go with temporary
* 32bit accus for Q and R.
*/
q = lfp->l_ui / 1000u;
r = lfp->l_ui - (q * 1000u);
lfp->l_ui = q;
r = (r << 16) | (lfp->l_uf >> 16);
q = r / 1000u;
r = ((r - q * 1000) << 16) | (lfp->l_uf & 0x0FFFFu);
lfp->l_uf = q << 16;
q = r / 1000;
lfp->l_uf |= q;
r -= q * 1000u;
/* fix sign */
if (neg)
L_NEG(lfp);
/* round */
if (r >= 500)
L_ADDF(lfp, (neg ? -1 : 1));
return 1;
}
|