xref: /haiku/src/kits/shared/StringForSize.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2  * Copyright 2010-2019 Haiku Inc. All rights reserved.
3  * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include "StringForSize.h"
8 
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #include <StringFormat.h>
14 #include <SystemCatalog.h>
15 
16 using BPrivate::gSystemCatalog;
17 
18 
19 #undef B_TRANSLATION_CONTEXT
20 #define B_TRANSLATION_CONTEXT "StringForSize"
21 
22 
23 namespace BPrivate {
24 
25 
26 const char*
27 string_for_size(double size, char* string, size_t stringSize)
28 {
29 	double kib = size / 1024.0;
30 	if (kib < 1.0) {
31 		const char* trKey = B_TRANSLATE_MARK(
32 			"{0, plural, one{# byte} other{# bytes}}");
33 
34 		BString tmp;
35 		BStringFormat format(
36 			gSystemCatalog.GetString(trKey, B_TRANSLATION_CONTEXT));
37 		format.Format(tmp, (int)size);
38 
39 		strlcpy(string, tmp.String(), stringSize);
40 		return string;
41 	}
42 	double mib = kib / 1024.0;
43 	if (mib < 1.0) {
44 		const char* trKey = B_TRANSLATE_MARK("%3.2f KiB");
45 		snprintf(string, stringSize, gSystemCatalog.GetString(trKey,
46 			B_TRANSLATION_CONTEXT), kib);
47 		return string;
48 	}
49 	double gib = mib / 1024.0;
50 	if (gib < 1.0) {
51 		const char* trKey = B_TRANSLATE_MARK("%3.2f MiB");
52 		snprintf(string, stringSize, gSystemCatalog.GetString(trKey,
53 			B_TRANSLATION_CONTEXT), mib);
54 		return string;
55 	}
56 	double tib = gib / 1024.0;
57 	if (tib < 1.0) {
58 		const char* trKey = B_TRANSLATE_MARK("%3.2f GiB");
59 		snprintf(string, stringSize, gSystemCatalog.GetString(trKey,
60 			B_TRANSLATION_CONTEXT), gib);
61 		return string;
62 	}
63 	const char* trKey = B_TRANSLATE_MARK("%.2f TiB");
64 	snprintf(string, stringSize, gSystemCatalog.GetString(trKey,
65 		B_TRANSLATION_CONTEXT), tib);
66 	return string;
67 }
68 
69 
70 int64
71 parse_size(const char* sizeString)
72 {
73 	int64 parsedSize = -1;
74 	char* end;
75 	parsedSize = strtoll(sizeString, &end, 0);
76 	if (end != sizeString && parsedSize > 0) {
77 		int64 rawSize = parsedSize;
78 		switch (tolower(*end)) {
79 			case 't':
80 				parsedSize *= 1024;
81 			case 'g':
82 				parsedSize *= 1024;
83 			case 'm':
84 				parsedSize *= 1024;
85 			case 'k':
86 				parsedSize *= 1024;
87 				end++;
88 				break;
89 			case '\0':
90 				break;
91 			default:
92 				parsedSize = -1;
93 				break;
94 		}
95 
96 		// Check for overflow
97 		if (parsedSize > 0 && rawSize > parsedSize)
98 			parsedSize = -1;
99 	}
100 
101 	return parsedSize;
102 }
103 
104 
105 }	// namespace BPrivate
106 
107