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 BString printedSize; 32 33 double value = size / 1024.0; 34 if (value < 1024.0) { 35 BStringFormat format( 36 B_TRANSLATE_MARK_ALL("{0, plural, one{# byte} other{# bytes}}", 37 B_TRANSLATION_CONTEXT, "size unit")); 38 39 format.Format(printedSize, (int)size); 40 strlcpy(string, gSystemCatalog.GetString(printedSize.String(), B_TRANSLATION_CONTEXT, 41 "size unit"), stringSize); 42 43 return string; 44 } 45 46 const char* kFormats[] = { 47 B_TRANSLATE_MARK_ALL("%s KiB", B_TRANSLATION_CONTEXT, "size unit"), 48 B_TRANSLATE_MARK_ALL("%s MiB", B_TRANSLATION_CONTEXT, "size unit"), 49 B_TRANSLATE_MARK_ALL("%s GiB", B_TRANSLATION_CONTEXT, "size unit"), 50 B_TRANSLATE_MARK_ALL("%s TiB", B_TRANSLATION_CONTEXT, "size unit") 51 }; 52 53 size_t index = 0; 54 while (index < B_COUNT_OF(kFormats) && value >= 1024.0) { 55 value /= 1024.0; 56 index++; 57 } 58 59 BNumberFormat numberFormat; 60 numberFormat.SetPrecision(2); 61 numberFormat.Format(printedSize, value); 62 snprintf(string, stringSize, gSystemCatalog.GetString(kFormats[index], B_TRANSLATION_CONTEXT, 63 "size unit"), printedSize.String()); 64 65 return string; 66 } 67 68 69 int64 70 parse_size(const char* sizeString) 71 { 72 int64 parsedSize = -1; 73 char* end; 74 parsedSize = strtoll(sizeString, &end, 0); 75 if (end != sizeString && parsedSize > 0) { 76 int64 rawSize = parsedSize; 77 switch (tolower(*end)) { 78 case 't': 79 parsedSize *= 1024; 80 case 'g': 81 parsedSize *= 1024; 82 case 'm': 83 parsedSize *= 1024; 84 case 'k': 85 parsedSize *= 1024; 86 end++; 87 break; 88 case '\0': 89 break; 90 default: 91 parsedSize = -1; 92 break; 93 } 94 95 // Check for overflow 96 if (parsedSize > 0 && rawSize > parsedSize) 97 parsedSize = -1; 98 } 99 100 return parsedSize; 101 } 102 103 104 } // namespace BPrivate 105 106