xref: /haiku/src/kits/debugger/util/IntegerFormatter.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
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 
16 static integer_format
17 GetFormatForTypeAndFormat(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
94 IntegerFormatter::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