• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _TCUFORMATUTIL_HPP
2 #define _TCUFORMATUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief String format utilities.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "deString.h"
28 
29 #include <ostream>
30 #include <string>
31 #include <sstream>
32 #include <iomanip>
33 
34 namespace tcu
35 {
36 namespace Format
37 {
38 
39 // Hexadecimal value formatter.
40 template <size_t NumDigits>
41 class Hex
42 {
43 public:
Hex(deUint64 value_)44 	Hex (deUint64 value_) : value(value_) {}
45 
toStream(std::ostream & stream) const46 	std::ostream& toStream (std::ostream& stream) const
47 	{
48 		DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);
49 
50 		return stream	<< "0x"
51 						<< std::right
52 						<< std::setfill('0')
53 						<< std::setw(NumDigits)
54 						<< std::hex
55 						<< value;
56 	}
57 
toString(void) const58 	std::string toString (void) const
59 	{
60 		std::stringstream stream;
61 
62 		toStream(stream);
63 		return stream.str();
64 	}
65 
66 private:
67 	deUint64 value;
68 };
69 
70 template <size_t NumDigits>
operator <<(std::ostream & stream,tcu::Format::Hex<NumDigits> hex)71 std::ostream& operator<< (std::ostream& stream, tcu::Format::Hex<NumDigits> hex)
72 {
73 	return hex.toStream(stream);
74 }
75 
76 // Bitfield formatter.
77 
78 class BitDesc
79 {
80 public:
81 	deUint64	bit;
82 	const char*	name;
83 
BitDesc(deUint64 bit_,const char * name_)84 	BitDesc (deUint64 bit_, const char* name_) : bit(bit_), name(name_) {}
85 };
86 
87 #define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT)
88 
89 template <size_t BitfieldSize>
90 class Bitfield
91 {
92 public:
Bitfield(deUint64 value,const BitDesc * begin,const BitDesc * end)93 	Bitfield (deUint64 value, const BitDesc* begin, const BitDesc* end)
94 		: m_value	(value)
95 		, m_begin	(begin)
96 		, m_end		(end)
97 	{
98 	}
99 
toStream(std::ostream & stream)100 	std::ostream& toStream (std::ostream& stream)
101 	{
102 		deUint64 bitsLeft = m_value;
103 		for (const BitDesc* curDesc = m_begin; curDesc != m_end; curDesc++)
104 		{
105 			if (curDesc->bit & bitsLeft)
106 			{
107 				if (bitsLeft != m_value)
108 					stream << "|";
109 				stream << curDesc->name;
110 				bitsLeft ^= curDesc->bit;
111 			}
112 		}
113 
114 		if (bitsLeft != 0)
115 		{
116 			if (bitsLeft != m_value)
117 				stream << "|";
118 			stream << Hex<BitfieldSize/4>(bitsLeft);
119 		}
120 
121 		return stream;
122 	}
123 
124 private:
125 	deUint64			m_value;
126 	const BitDesc*		m_begin;
127 	const BitDesc*		m_end;
128 };
129 
130 template <size_t BitfieldSize>
operator <<(std::ostream & stream,Bitfield<BitfieldSize> decoder)131 inline std::ostream& operator<< (std::ostream& stream, Bitfield<BitfieldSize> decoder)
132 {
133 	return decoder.toStream(stream);
134 }
135 
136 // Enum formatter.
137 // \todo [2012-10-30 pyry] Use template for GetName.
138 template <typename T, size_t NumBytes = sizeof(T)>
139 class Enum
140 {
141 public:
142 	typedef const char* (*GetNameFunc) (T value);
143 
Enum(GetNameFunc getName,T value)144 	Enum (GetNameFunc getName, T value)
145 		: m_getName	(getName)
146 		, m_value (value)
147 	{
148 	}
149 
toStream(std::ostream & stream) const150 	std::ostream& toStream (std::ostream& stream) const
151 	{
152 		const char* name = m_getName(m_value);
153 		if (name)
154 			return stream << name;
155 		else
156 			return stream << Hex<NumBytes*2>((deUint64)m_value);
157 	}
158 
toString(void) const159 	std::string toString (void) const
160 	{
161 		const char* name = m_getName(m_value);
162 		if (name)
163 			return std::string(name);
164 		else
165 			return Hex<NumBytes*2>((deUint64)m_value).toString();
166 	}
167 
168 private:
169 	const GetNameFunc	m_getName;
170 	const T				m_value;
171 };
172 
173 template <typename T, size_t NumBytes>
operator <<(std::ostream & stream,const Enum<T,NumBytes> & fmt)174 inline std::ostream& operator<< (std::ostream& stream, const Enum<T, NumBytes>& fmt) { return fmt.toStream(stream); }
175 
176 // Array formatters.
177 
178 template <typename Iterator>
179 class Array
180 {
181 public:
182 	Iterator	begin;
183 	Iterator	end;
184 
Array(const Iterator & begin_,const Iterator & end_)185 	Array (const Iterator& begin_, const Iterator& end_) : begin(begin_), end(end_) {}
186 };
187 
188 template <typename T>
189 class ArrayPointer
190 {
191 public:
192 	const T*	arr;
193 	int			size;
194 
ArrayPointer(const T * arr_,int size_)195 	ArrayPointer (const T* arr_, int size_) : arr(arr_), size(size_) {}
196 };
197 
198 template <typename Iterator>
operator <<(std::ostream & str,const Array<Iterator> & fmt)199 std::ostream& operator<< (std::ostream& str, const Array<Iterator>& fmt)
200 {
201 	str << "{ ";
202 	for (Iterator cur = fmt.begin; cur != fmt.end; ++cur)
203 	{
204 		if (cur != fmt.begin)
205 			str << ", ";
206 		str << *cur;
207 	}
208 	str << " }";
209 	return str;
210 }
211 
212 template <typename T>
operator <<(std::ostream & str,const ArrayPointer<T> & fmt)213 std::ostream& operator<< (std::ostream& str, const ArrayPointer<T>& fmt)
214 {
215 	if (fmt.arr != DE_NULL)
216 		return str << Array<const T*>(fmt.arr, fmt.arr+fmt.size);
217 	else
218 		return str << "(null)";
219 }
220 
221 // Hex format iterator (useful for combining with ArrayFormatter).
222 // \todo [2012-10-30 pyry] Implement more generic format iterator.
223 
224 template <typename T, typename Iterator = const T*>
225 class HexIterator
226 {
227 public:
HexIterator(Iterator iter)228 										HexIterator			(Iterator iter) : m_iter(iter) {}
229 
operator ++(void)230 	HexIterator<T, Iterator>&			operator++			(void)	{ ++m_iter; return *this;		}
operator ++(int)231 	HexIterator<T, Iterator>			operator++			(int)	{ return HexIterator(m_iter++);	}
232 
operator ==(const HexIterator<T,Iterator> & other) const233 	bool								operator==			(const HexIterator<T, Iterator>& other) const { return m_iter == other.m_iter; }
operator !=(const HexIterator<T,Iterator> & other) const234 	bool								operator!=			(const HexIterator<T, Iterator>& other) const { return m_iter != other.m_iter; }
235 
236 #if !defined(__INTELLISENSE__)
237 	// Intellisense in VS2013 crashes when parsing this.
operator *(void) const238 	Hex<sizeof(T)*2>					operator*			(void) const { return Hex<sizeof(T)*2>(*m_iter);	}
239 #endif
240 
241 private:
242 	Iterator							m_iter;
243 };
244 
245 } // Format
246 
makeMask64(void)247 template <int Bits>		inline deUint64 makeMask64			(void)				{ return (1ull<<Bits)-1;								}
makeMask64(void)248 template <>				inline deUint64 makeMask64<64>		(void)				{ return ~0ull;											}
toUint64(T value)249 template <typename T>	inline deUint64	toUint64			(T value)			{ return (deUint64)value & makeMask64<sizeof(T)*8>();	}
250 
251 /** Format value as hexadecimal number. */
252 template <size_t NumDigits, typename T>
toHex(T value)253 inline Format::Hex<NumDigits> toHex (T value)
254 {
255 	return Format::Hex<NumDigits>(toUint64(value));
256 }
257 
258 /** Format value as hexadecimal number. */
259 template <typename T>
toHex(T value)260 inline Format::Hex<sizeof(T)*2> toHex (T value)
261 {
262 	return Format::Hex<sizeof(T)*2>(toUint64(value));
263 }
264 
265 /** Decode and format bitfield. */
266 template <typename T, size_t Size>
formatBitfield(T value,const Format::BitDesc (& desc)[Size])267 inline Format::Bitfield<sizeof(T)*8> formatBitfield (T value, const Format::BitDesc (&desc)[Size])
268 {
269 	return Format::Bitfield<sizeof(T)*8>((deUint64)value, &desc[0], &desc[Size]);
270 }
271 
272 /** Format array contents. */
273 template <typename Iterator>
formatArray(const Iterator & begin,const Iterator & end)274 inline Format::Array<Iterator> formatArray (const Iterator& begin, const Iterator& end)
275 {
276 	return Format::Array<Iterator>(begin, end);
277 }
278 
279 /** Format array contents. */
280 template <typename T>
formatArray(const T * arr,int size)281 inline Format::ArrayPointer<T> formatArray (const T* arr, int size)
282 {
283 	return Format::ArrayPointer<T>(arr, size);
284 }
285 
286 /** Format array contents. */
287 template <typename T, int Size>
formatArray(const T (& arr)[Size])288 inline Format::ArrayPointer<T> formatArray (const T (&arr)[Size])
289 {
290 	return Format::ArrayPointer<T>(arr, Size);
291 }
292 
293 } // tcu
294 
295 #endif // _TCUFORMATUTIL_HPP
296