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* 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 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