1 /*
2 * Copyright 2010-2024 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 <NumberFormat.h>
14 #include <StringFormat.h>
15 #include <SystemCatalog.h>
16
17
18 using BPrivate::gSystemCatalog;
19
20
21 #undef B_TRANSLATION_CONTEXT
22 #define B_TRANSLATION_CONTEXT "StringForSize"
23
24
25 namespace BPrivate {
26
27
28 const char*
string_for_size(double size,char * string,size_t stringSize)29 string_for_size(double size, char* string, size_t stringSize)
30 {
31 const char* kFormats[] = {
32 B_TRANSLATE_MARK_COMMENT("{0, plural, one{%s byte} other{%s bytes}}", "size unit"),
33 B_TRANSLATE_MARK_COMMENT("%s KiB", "size unit"),
34 B_TRANSLATE_MARK_COMMENT("%s MiB", "size unit"),
35 B_TRANSLATE_MARK_COMMENT("%s GiB", "size unit"),
36 B_TRANSLATE_MARK_COMMENT("%s TiB", "size unit")
37 };
38
39 size_t index = 0;
40 while (index < B_COUNT_OF(kFormats) - 1 && size >= 1024.0) {
41 size /= 1024.0;
42 index++;
43 }
44
45 BString format;
46 BStringFormat formatter(
47 gSystemCatalog.GetString(kFormats[index], B_TRANSLATION_CONTEXT, "size unit"));
48 formatter.Format(format, size);
49
50 BString printedSize;
51 BNumberFormat numberFormat;
52 numberFormat.SetPrecision(index == 0 ? 0 : 2);
53 numberFormat.Format(printedSize, size);
54
55 snprintf(string, stringSize, format.String(), printedSize.String());
56
57 return string;
58 }
59
60
61 int64
parse_size(const char * sizeString)62 parse_size(const char* sizeString)
63 {
64 int64 parsedSize = -1;
65 char* end;
66 parsedSize = strtoll(sizeString, &end, 0);
67 if (end != sizeString && parsedSize > 0) {
68 int64 rawSize = parsedSize;
69 switch (tolower(*end)) {
70 case 't':
71 parsedSize *= 1024;
72 case 'g':
73 parsedSize *= 1024;
74 case 'm':
75 parsedSize *= 1024;
76 case 'k':
77 parsedSize *= 1024;
78 end++;
79 break;
80 case '\0':
81 break;
82 default:
83 parsedSize = -1;
84 break;
85 }
86
87 // Check for overflow
88 if (parsedSize > 0 && rawSize > parsedSize)
89 parsedSize = -1;
90 }
91
92 return parsedSize;
93 }
94
95
96 } // namespace BPrivate
97
98