1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2012, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "IntegerFormatter.h"
9
10#include <stdio.h>
11#include <string.h>
12
13#include <TypeConstants.h>
14
15
16static integer_format
17GetFormatForTypeAndFormat(type_code type, integer_format format,
18	char* _formatString, int formatSize)
19{
20	integer_format result = format;
21	_formatString[0] = '%';
22	++_formatString;
23	formatSize -= 1;
24
25	switch (type) {
26		case B_INT8_TYPE:
27			switch (format) {
28				case INTEGER_FORMAT_HEX_DEFAULT:
29					result = INTEGER_FORMAT_HEX_8;
30					break;
31				case INTEGER_FORMAT_SIGNED:
32					strlcpy(_formatString, B_PRId8, formatSize);
33					break;
34				case INTEGER_FORMAT_UNSIGNED:
35					strlcpy(_formatString, B_PRIu8, formatSize);
36					break;
37				default:
38					break;
39			}
40			break;
41		case B_INT16_TYPE:
42			switch (format) {
43				case INTEGER_FORMAT_HEX_DEFAULT:
44					result = INTEGER_FORMAT_HEX_16;
45					break;
46				case INTEGER_FORMAT_SIGNED:
47					strlcpy(_formatString, B_PRId16, formatSize);
48					break;
49				case INTEGER_FORMAT_UNSIGNED:
50					strlcpy(_formatString, B_PRIu16, formatSize);
51					break;
52				default:
53					break;
54			}
55			break;
56		case B_INT32_TYPE:
57			switch (format) {
58				case INTEGER_FORMAT_HEX_DEFAULT:
59					result = INTEGER_FORMAT_HEX_32;
60					break;
61				case INTEGER_FORMAT_SIGNED:
62					strlcpy(_formatString, B_PRId32, formatSize);
63					break;
64				case INTEGER_FORMAT_UNSIGNED:
65					strlcpy(_formatString, B_PRIu32, formatSize);
66					break;
67				default:
68					break;
69			}
70			break;
71		case B_INT64_TYPE:
72		default:
73			switch (format) {
74				case INTEGER_FORMAT_HEX_DEFAULT:
75					result = INTEGER_FORMAT_HEX_64;
76					break;
77				case INTEGER_FORMAT_SIGNED:
78					strlcpy(_formatString, B_PRId64, formatSize);
79					break;
80				case INTEGER_FORMAT_UNSIGNED:
81					strlcpy(_formatString, B_PRIu64, formatSize);
82					break;
83				default:
84					break;
85			}
86			break;
87	}
88
89	return result;
90}
91
92
93/*static*/ bool
94IntegerFormatter::FormatValue(const BVariant& value, integer_format format,
95	char* buffer, size_t bufferSize)
96{
97	bool isSigned;
98	if (!value.IsInteger(&isSigned))
99		return false;
100
101	char formatString[10];
102
103	if (format == INTEGER_FORMAT_DEFAULT) {
104		format = isSigned ? INTEGER_FORMAT_SIGNED : INTEGER_FORMAT_UNSIGNED;
105	}
106
107	format = GetFormatForTypeAndFormat(value.Type(), format, formatString,
108		sizeof(formatString));
109
110	// format the value
111	switch (format) {
112		case INTEGER_FORMAT_SIGNED:
113			snprintf(buffer, bufferSize, formatString,
114				value.Type() == B_INT8_TYPE ? value.ToInt8() :
115					value.Type() == B_INT16_TYPE ? value.ToInt16() :
116						value.Type() == B_INT32_TYPE ? value.ToInt32() :
117							value.ToInt64());
118			break;
119		case INTEGER_FORMAT_UNSIGNED:
120			snprintf(buffer, bufferSize, formatString,
121				value.Type() == B_INT8_TYPE ? value.ToUInt8() :
122					value.Type() == B_INT16_TYPE ? value.ToUInt16() :
123						value.Type() == B_INT32_TYPE ? value.ToUInt32() :
124							value.ToUInt64());
125			break;
126		case INTEGER_FORMAT_HEX_8:
127			snprintf(buffer, bufferSize, "%#x", (uint8)value.ToUInt64());
128			break;
129		case INTEGER_FORMAT_HEX_16:
130			snprintf(buffer, bufferSize, "%#x", (uint16)value.ToUInt64());
131			break;
132		case INTEGER_FORMAT_HEX_32:
133			snprintf(buffer, bufferSize, "%#" B_PRIx32,
134				(uint32)value.ToUInt64());
135			break;
136		case INTEGER_FORMAT_HEX_64:
137		default:
138			snprintf(buffer, bufferSize, "%#" B_PRIx64, value.ToUInt64());
139			break;
140	}
141
142	return true;
143}
144