• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2 
3 package org.xbill.DNS;
4 
5 /**
6  * Routines for parsing BIND-style TTL values.  These values consist of
7  * numbers followed by 1 letter units of time (W - week, D - day, H - hour,
8  * M - minute, S - second).
9  *
10  * @author Brian Wellington
11  */
12 
13 public final class TTL {
14 
15 public static final long MAX_VALUE = 0x7FFFFFFFL;
16 
17 private
TTL()18 TTL() {}
19 
20 static void
check(long i)21 check(long i) {
22 	if (i < 0 || i > MAX_VALUE)
23 		throw new InvalidTTLException(i);
24 }
25 
26 /**
27  * Parses a TTL-like value, which can either be expressed as a number or a
28  * BIND-style string with numbers and units.
29  * @param s The string representing the numeric value.
30  * @param clamp Whether to clamp values in the range [MAX_VALUE + 1, 2^32 -1]
31  * to MAX_VALUE.  This should be donw for TTLs, but not other values which
32  * can be expressed in this format.
33  * @return The value as a number of seconds
34  * @throws NumberFormatException The string was not in a valid TTL format.
35  */
36 public static long
parse(String s, boolean clamp)37 parse(String s, boolean clamp) {
38 	if (s == null || s.length() == 0 || !Character.isDigit(s.charAt(0)))
39 		throw new NumberFormatException();
40 	long value = 0;
41 	long ttl = 0;
42 	for (int i = 0; i < s.length(); i++) {
43 		char c = s.charAt(i);
44 		long oldvalue = value;
45 		if (Character.isDigit(c)) {
46 			value = (value * 10) + Character.getNumericValue(c);
47 			if (value < oldvalue)
48 				throw new NumberFormatException();
49 		} else {
50 			switch (Character.toUpperCase(c)) {
51 				case 'W': value *= 7;
52 				case 'D': value *= 24;
53 				case 'H': value *= 60;
54 				case 'M': value *= 60;
55 				case 'S': break;
56 				default:  throw new NumberFormatException();
57 			}
58 			ttl += value;
59 			value = 0;
60 			if (ttl > 0xFFFFFFFFL)
61 				throw new NumberFormatException();
62 		}
63 	}
64 	if (ttl == 0)
65 		ttl = value;
66 
67 	if (ttl > 0xFFFFFFFFL)
68 		throw new NumberFormatException();
69 	else if (ttl > MAX_VALUE && clamp)
70 		ttl = MAX_VALUE;
71 	return ttl;
72 }
73 
74 /**
75  * Parses a TTL, which can either be expressed as a number or a BIND-style
76  * string with numbers and units.
77  * @param s The string representing the TTL
78  * @return The TTL as a number of seconds
79  * @throws NumberFormatException The string was not in a valid TTL format.
80  */
81 public static long
parseTTL(String s)82 parseTTL(String s) {
83 	return parse(s, true);
84 }
85 
86 public static String
format(long ttl)87 format(long ttl) {
88 	TTL.check(ttl);
89 	StringBuffer sb = new StringBuffer();
90 	long secs, mins, hours, days, weeks;
91 	secs = ttl % 60;
92 	ttl /= 60;
93 	mins = ttl % 60;
94 	ttl /= 60;
95 	hours = ttl % 24;
96 	ttl /= 24;
97 	days = ttl % 7;
98 	ttl /= 7;
99 	weeks = ttl;
100 	if (weeks > 0)
101 		sb.append(weeks + "W");
102 	if (days > 0)
103 		sb.append(days + "D");
104 	if (hours > 0)
105 		sb.append(hours + "H");
106 	if (mins > 0)
107 		sb.append(mins + "M");
108 	if (secs > 0 || (weeks == 0 && days == 0 && hours == 0 && mins == 0))
109 		sb.append(secs + "S");
110 	return sb.toString();
111 }
112 
113 }
114