1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#ifndef	_UTILS_H
27#define	_UTILS_H
28
29#ifdef	__cplusplus
30extern "C" {
31#endif
32
33#include <sys/types.h>
34
35extern void warn(const char *, ...);
36extern char *setpname(char *);
37
38/*
39 * scale_t
40 *
41 * Used to describe string modifiers and integer scales.
42 *	modifiers:  NULL terminated array of modifier strings, such as
43 *		    { "K", "M", NULL }, for strings like "100KB" or "100MB"
44 *	scales:	    array of scales for each modifer string, such as
45 *		    { 1000, 1000000 }
46 */
47typedef struct scale_struct {
48	char	    **modifers;
49	uint64_t	*scales;
50} scale_t;
51
52/*
53 * pointers to standard scales.
54 */
55extern scale_t *scale_binary;
56extern scale_t *scale_metric;
57
58#define	SCALED_MODIFIER_CASE_INSENSITIVE_FLAG 	0x01
59#define	SCALED_UNIT_CASE_INSENSITIVE_FLAG	0x02
60#define	SCALED_UNIT_OPTIONAL_FLAG		0x04
61#define	SCALED_PAD_WIDTH_FLAG			0x08
62#define	SCALED_ALL_FLAGS			0x0F
63
64/*
65 * 20 characters for UINT64_MAX, 1 character for modifer, 1 character for
66 * unit, 1 character for NULL, 1 extra.
67 */
68#define	SCALED_STRLEN (24)
69
70#define	SCALED_INVALID_MODIFIER		1
71#define	SCALED_INVALID_UNIT		2
72#define	SCALED_INVALID_NUMBER		3
73#define	SCALED_OVERFLOW			4
74
75#define	SCALED_UNIT_BYTES "B"
76#define	SCALED_UNIT_SECONDS "s"
77#define	SCALED_UNIT_NONE ""
78
79/*
80 * scaledtouint64
81 *
82 * converts a string in one of the forms:
83 *	 "[decimal number]][modifier][unit]"
84 *	 "[integer number][unit]"
85 *
86 * to a uint64.  As seen from the two forms, If no modifier is present,
87 * the number must be an integer.
88 *
89 * Inputs:
90 *
91 *	scaledin:   input string containing number string
92 *	scale:	    pointer to scale_t to describe scaling modifiers and scales
93 *	unit:	    expected unit string, such as "B", for the number "100MB"
94 *	flags:	    one of:
95 *			SCALED_MODIFIER_CASE_INSENSITIVE_FLAG
96 *			SCALED_UNIT_CASE_INSENSITIVE_FLAG
97 *			SCALED_UNIT_OPTIONAL_FLAG
98 *		    which are pretty self explainatory.
99 * Outputs:
100 *
101 *	return value:	0 on success, on errors:
102 *		SCALED_INVALID_NUMBER	- string contains no valid number
103 *		SCALED_INVALID_MODIFIER - string has unknown modifier
104 *		SCALED_INVALID_UNIT	- string has unknown or missing unit
105 *		SCALED_OVERFLOW		- number exceeds MAX_UINT64
106 *
107 *	uint64out:	uint64_t value of input string
108 *	widthout:	width of number (not including modifier and unit)
109 *			in the input string.  "10.0MB" has a width of 4.
110 *	modiferout:	pointer to the string in the modifiers array which
111 *			was found in the input string.  If no modifer was
112 *			found, this well be set to NULL;
113 *	unitout:	If unit string was present in the input string, this
114 *			will be set to point to unit, otherwise NULL.
115 */
116int scaledtouint64(char *scaledin, uint64_t *uint64out,
117    int *widthout, char **modifierout, char **unitout,
118    scale_t *scale, char *unit, int flags);
119
120/*
121 * uint64toscaled
122 *
123 * converts a uint64 to a string in one of the forms:
124 *	 "[decimal number]][modifier][unit]"
125 *	 "[integer number][unit]"
126 * (no modifier means number will be an integer)
127 *
128 * Inputs:
129 *
130 *	uint64in:    input number to convert to scaled string
131 *	widthin:     character width of desired string, not including modifier
132 *		     and unit.  Eg:  1.00MB has a width of 4 for the "1.00".
133 *		     unit.
134 *	maxmodifier: The maximium scaling to use.  For instance, to limit the
135 *		     scaling to megabytes (no GB or higher), use "M"
136 *	scale:	     pointer to scale_t to describe modifiers and scales
137 *	unit:	     unit string, such as "B", for the number "100MB"
138 *	flags:	     one of:
139 *			SCALED_PAD_WIDTH_FLAG
140 *			    If the length of the scaled string is less than
141 *			    widthin, pad to the left with spaces.
142 * Outputs:
143 *
144 *	return value:	0 on success, no error conditions.
145 *	scaledout:   Pointer to a string buffer to fill with the scaled string.
146 *	widthout:    Used to return the actual character length of the produced
147 *		     string, not including modifier and unit.
148 *	modifierout: pointer to modifier used in scaled string.
149 */
150int uint64toscaled(uint64_t uint64in, int widthin, char *maxmodifier,
151    char *scaledout, int *widthout, char **modifierout,
152    scale_t *scale, char *unit, int flags);
153
154/*
155 * scaledtoscaled
156 *
157 * Used to rescale a string from/to the following forms:
158 *	 "[decimal number]][modifier][unit]"
159 *	 "[integer number][unit]"
160 *
161 * This is used ensure the desired width and letter casing.
162 *
163 * As seen from the two forms, If no modifier is present,
164 * the number must be an integer.
165 *
166 * Inputs:
167 *	scaledin:   input string containing number string
168 *	widthin:     character width of desired string, not including modifier
169 *		     and unit.  Eg:  1.00MB has a width of 4 for the "1.00".
170 *		     unit.
171 *	maxmodifier: The maximium scaling to use.  For instance, to limit the
172 *		     scaling to megabytes (no GB or higher), use "M"
173 *	scale:	     pointer to scale_t to describe modifiers and scales
174 *	unit:	     unit string, such as "B", for the number "100MB"
175 *	flags:	     one of:
176 *			SCALED_PAD_WIDTH_FLAG
177 *			    If the length of the scaled string is less than
178 *			    widthin, pad to the left with spaces.
179 *			SCALED_MODIFIER_CASE_INSENSITIVE_FLAG
180 *			SCALED_UNIT_CASE_INSENSITIVE_FLAG
181 *			SCALED_UNIT_OPTIONAL_FLAG
182 *			    which are pretty self explainatory.
183 *
184 * Outputs:
185 *
186 *	return value:	0 on success, on errors:
187 *		SCALED_INVALID_NUMBER	- string contains no valid number
188 *		SCALED_INVALID_MODIFIER - string has unknown modifier
189 *		SCALED_INVALID_UNIT	- string has unknown or missing unit
190 *		SCALED_OVERFLOW		- number exceeds MAX_UINT64
191 *
192 *	scaledout:   Pointer to a string buffer to fill with the scaled string.
193 *	widthout:	width of number (not including modifier and unit)
194 *			in the input string.  "10.0MB" has a width of 4.
195 *	modiferout:	pointer to the string in the modifiers array which
196 *			was found in the input string.  If no modifer was
197 *			found, this well be set to NULL;
198 */
199int scaledtoscaled(char *scaledin, int widthin, char *maxmodifier,
200    char *scaledout, int *widthout, char ** modifierout,
201    scale_t *scale, char *unit, int flags);
202
203/*
204 * scaledeqscaled
205 *
206 * Determine if two scaled strings are equivalent.  Flags are same as
207 * scaledtouint64.
208 */
209int scaledeqscaled(char *scale1, char *scale2,
210    scale_t *scale, char *unit, int flags);
211
212/*
213 * scaledequint64
214 *
215 * Determine if a scaled number is equal to an uint64.  The uint64 is scaled
216 * to the same scale and width as the scaled strings.  If the resultant string
217 * is equal, then the numbers are considered equal.
218 *
219 * minwidth:  minimum number width to scale string and number to for
220 *	      comparision.
221 * flags are same as scaledtouint64.
222 */
223int scaledequint64(char *scaled, uint64_t uint64, int minwidth,
224    scale_t *scale, char *unit, int flags);
225
226#ifdef	__cplusplus
227}
228#endif
229
230#endif	/* _UTILS_H */
231