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 18using BPrivate::gSystemCatalog; 19 20 21#undef B_TRANSLATION_CONTEXT 22#define B_TRANSLATION_CONTEXT "StringForSize" 23 24 25namespace BPrivate { 26 27 28const char* 29string_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 61int64 62parse_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