blob: 7614d02742b7f3b35e0d41ec40332c4c235e226f [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Stream.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/Stream.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000011#include "lldb/Host/Endian.h"
Zachary Turnerf343968f2016-08-09 23:06:08 +000012#include "lldb/Host/PosixApi.h"
Benjamin Kramer581a6912012-02-27 18:46:54 +000013#include <stddef.h>
Eli Friedman88966972010-06-09 08:50:27 +000014#include <stdio.h>
Eli Friedman88966972010-06-09 08:50:27 +000015#include <stdlib.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000016#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
Daniel Malead01b2952012-11-29 21:49:15 +000018#include <inttypes.h>
19
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020using namespace lldb;
21using namespace lldb_private;
22
Kate Stoneb9c1b512016-09-06 20:57:50 +000023Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
24 : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
25 m_indent_level(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Kate Stoneb9c1b512016-09-06 20:57:50 +000027Stream::Stream()
28 : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
29 m_indent_level(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030
31//------------------------------------------------------------------
32// Destructor
33//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000034Stream::~Stream() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
37 ByteOrder old_byte_order = m_byte_order;
38 m_byte_order = byte_order;
39 return old_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040}
41
42//------------------------------------------------------------------
43// Put an offset "uval" out to the stream using the printf format
44// in "format".
45//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000046void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
48//------------------------------------------------------------------
49// Put an SLEB128 "uval" out to the stream using the printf format
50// in "format".
51//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000052size_t Stream::PutSLEB128(int64_t sval) {
53 size_t bytes_written = 0;
54 if (m_flags.Test(eBinary)) {
55 bool more = true;
56 while (more) {
57 uint8_t byte = sval & 0x7fu;
58 sval >>= 7;
59 /* sign bit of byte is 2nd high order bit (0x40) */
60 if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40)))
61 more = false;
62 else
63 // more bytes to come
64 byte |= 0x80u;
65 bytes_written += Write(&byte, 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 } else {
68 bytes_written = Printf("0x%" PRIi64, sval);
69 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072}
73
74//------------------------------------------------------------------
75// Put an ULEB128 "uval" out to the stream using the printf format
76// in "format".
77//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000078size_t Stream::PutULEB128(uint64_t uval) {
79 size_t bytes_written = 0;
80 if (m_flags.Test(eBinary)) {
81 do {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 uint8_t byte = uval & 0x7fu;
84 uval >>= 7;
85 if (uval != 0) {
86 // more bytes to come
87 byte |= 0x80u;
88 }
89 bytes_written += Write(&byte, 1);
90 } while (uval != 0);
91 } else {
92 bytes_written = Printf("0x%" PRIx64, uval);
93 }
94 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095}
96
97//------------------------------------------------------------------
Enrico Granata7b59f752012-01-31 17:18:40 +000098// Print a raw NULL terminated C string to the stream.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099//------------------------------------------------------------------
Zachary Turner4fa098a2016-10-06 21:22:44 +0000100size_t Stream::PutCString(llvm::StringRef str) {
101 size_t bytes_written = 0;
102 bytes_written = Write(str.data(), str.size());
103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 // when in binary mode, emit the NULL terminator
105 if (m_flags.Test(eBinary))
Zachary Turner4fa098a2016-10-06 21:22:44 +0000106 bytes_written += PutChar('\0');
107 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108}
109
110//------------------------------------------------------------------
111// Print a double quoted NULL terminated C string to the stream
112// using the printf format in "format".
113//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114void Stream::QuotedCString(const char *cstr, const char *format) {
115 Printf(format, cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116}
117
118//------------------------------------------------------------------
119// Put an address "addr" out to the stream with optional prefix
120// and suffix strings.
121//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
123 const char *suffix) {
124 if (prefix == NULL)
125 prefix = "";
126 if (suffix == NULL)
127 suffix = "";
128 // int addr_width = m_addr_size << 1;
129 // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
130 Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131}
132
133//------------------------------------------------------------------
134// Put an address range out to the stream with optional prefix
135// and suffix strings.
136//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
138 uint32_t addr_size, const char *prefix,
139 const char *suffix) {
140 if (prefix && prefix[0])
141 PutCString(prefix);
142 Address(lo_addr, addr_size, "[");
143 Address(hi_addr, addr_size, "-", ")");
144 if (suffix && suffix[0])
145 PutCString(suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146}
147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149
150//------------------------------------------------------------------
151// Print some formatted output to the stream.
152//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153size_t Stream::Printf(const char *format, ...) {
154 va_list args;
155 va_start(args, format);
156 size_t result = PrintfVarArg(format, args);
157 va_end(args);
158 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
161//------------------------------------------------------------------
162// Print some formatted output to the stream.
163//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164size_t Stream::PrintfVarArg(const char *format, va_list args) {
165 char str[1024];
166 va_list args_copy;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 va_copy(args_copy, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 size_t bytes_written = 0;
171 // Try and format our string into a fixed buffer first and see if it fits
172 size_t length = ::vsnprintf(str, sizeof(str), format, args);
173 if (length < sizeof(str)) {
174 // Include the NULL termination byte for binary output
175 if (m_flags.Test(eBinary))
176 length += 1;
177 // The formatted string fit into our stack based buffer, so we can just
178 // append that to our packet
179 bytes_written = Write(str, length);
180 } else {
181 // Our stack buffer wasn't big enough to contain the entire formatted
182 // string, so lets let vasprintf create the string for us!
183 char *str_ptr = NULL;
184 length = ::vasprintf(&str_ptr, format, args_copy);
185 if (str_ptr) {
186 // Include the NULL termination byte for binary output
187 if (m_flags.Test(eBinary))
188 length += 1;
189 bytes_written = Write(str_ptr, length);
190 ::free(str_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 }
193 va_end(args_copy);
194 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195}
196
197//------------------------------------------------------------------
198// Print and End of Line character to the stream
199//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200size_t Stream::EOL() { return PutChar('\n'); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201
202//------------------------------------------------------------------
203// Indent the current line using the current indentation level and
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000204// print an optional string following the indentation spaces.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206size_t Stream::Indent(const char *s) {
207 return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208}
209
Zachary Turnera4496982016-10-05 21:14:38 +0000210size_t Stream::Indent(llvm::StringRef str) {
211 return Printf("%*.*s%s", m_indent_level, m_indent_level, "", str.str().c_str());
212}
213
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214//------------------------------------------------------------------
215// Stream a character "ch" out to this stream.
216//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217Stream &Stream::operator<<(char ch) {
218 PutChar(ch);
219 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220}
221
222//------------------------------------------------------------------
223// Stream the NULL terminated C string out to this stream.
224//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225Stream &Stream::operator<<(const char *s) {
226 Printf("%s", s);
227 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228}
229
230//------------------------------------------------------------------
231// Stream the pointer value out to this stream.
232//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233Stream &Stream::operator<<(const void *p) {
234 Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
235 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236}
237
238//------------------------------------------------------------------
239// Stream a uint8_t "uval" out to this stream.
240//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241Stream &Stream::operator<<(uint8_t uval) {
242 PutHex8(uval);
243 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244}
245
246//------------------------------------------------------------------
247// Stream a uint16_t "uval" out to this stream.
248//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249Stream &Stream::operator<<(uint16_t uval) {
250 PutHex16(uval, m_byte_order);
251 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252}
253
254//------------------------------------------------------------------
255// Stream a uint32_t "uval" out to this stream.
256//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257Stream &Stream::operator<<(uint32_t uval) {
258 PutHex32(uval, m_byte_order);
259 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260}
261
262//------------------------------------------------------------------
263// Stream a uint64_t "uval" out to this stream.
264//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265Stream &Stream::operator<<(uint64_t uval) {
266 PutHex64(uval, m_byte_order);
267 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269
270//------------------------------------------------------------------
271// Stream a int8_t "sval" out to this stream.
272//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273Stream &Stream::operator<<(int8_t sval) {
274 Printf("%i", (int)sval);
275 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276}
277
278//------------------------------------------------------------------
279// Stream a int16_t "sval" out to this stream.
280//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281Stream &Stream::operator<<(int16_t sval) {
282 Printf("%i", (int)sval);
283 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284}
285
286//------------------------------------------------------------------
287// Stream a int32_t "sval" out to this stream.
288//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289Stream &Stream::operator<<(int32_t sval) {
290 Printf("%i", (int)sval);
291 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292}
293
294//------------------------------------------------------------------
295// Stream a int64_t "sval" out to this stream.
296//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297Stream &Stream::operator<<(int64_t sval) {
298 Printf("%" PRIi64, sval);
299 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300}
301
302//------------------------------------------------------------------
303// Get the current indentation level
304//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305int Stream::GetIndentLevel() const { return m_indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306
307//------------------------------------------------------------------
308// Set the current indentation level
309//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311
312//------------------------------------------------------------------
313// Increment the current indentation level
314//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315void Stream::IndentMore(int amount) { m_indent_level += amount; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316
317//------------------------------------------------------------------
318// Decrement the current indentation level
319//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320void Stream::IndentLess(int amount) {
321 if (m_indent_level >= amount)
322 m_indent_level -= amount;
323 else
324 m_indent_level = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325}
326
327//------------------------------------------------------------------
328// Get the address size in bytes
329//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331
332//------------------------------------------------------------------
333// Set the address size in bytes
334//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336
337//------------------------------------------------------------------
338// Returns true if the verbose flag bit is set in this stream.
339//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340bool Stream::GetVerbose() const { return m_flags.Test(eVerbose); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341
342//------------------------------------------------------------------
343// Returns true if the debug flag bit is set in this stream.
344//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345bool Stream::GetDebug() const { return m_flags.Test(eDebug); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346
347//------------------------------------------------------------------
348// The flags get accessor
349//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350Flags &Stream::GetFlags() { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351
352//------------------------------------------------------------------
353// The flags const get accessor
354//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355const Flags &Stream::GetFlags() const { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356
Sean Callanan609f8c52010-07-02 02:43:42 +0000357//------------------------------------------------------------------
358// The byte order get accessor
359//------------------------------------------------------------------
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
Sean Callanan609f8c52010-07-02 02:43:42 +0000362
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363size_t Stream::PrintfAsRawHex8(const char *format, ...) {
364 va_list args;
365 va_list args_copy;
366 va_start(args, format);
367 va_copy(args_copy, args); // Copy this so we
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 char str[1024];
370 size_t bytes_written = 0;
371 // Try and format our string into a fixed buffer first and see if it fits
372 size_t length = ::vsnprintf(str, sizeof(str), format, args);
373 if (length < sizeof(str)) {
374 // The formatted string fit into our stack based buffer, so we can just
375 // append that to our packet
376 for (size_t i = 0; i < length; ++i)
377 bytes_written += _PutHex8(str[i], false);
378 } else {
379 // Our stack buffer wasn't big enough to contain the entire formatted
380 // string, so lets let vasprintf create the string for us!
381 char *str_ptr = NULL;
382 length = ::vasprintf(&str_ptr, format, args_copy);
383 if (str_ptr) {
384 for (size_t i = 0; i < length; ++i)
385 bytes_written += _PutHex8(str_ptr[i], false);
386 ::free(str_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 }
389 va_end(args);
390 va_end(args_copy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393}
394
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
396 size_t bytes_written = 0;
397 for (size_t i = 0; i < n; ++i)
398 bytes_written += _PutHex8(uvalue, m_flags.Test(eAddPrefix));
399 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400}
401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
403 size_t bytes_written = 0;
404 if (m_flags.Test(eBinary)) {
405 bytes_written = Write(&uvalue, 1);
406 } else {
407 if (add_prefix)
408 PutCString("0x");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
411 '6', '7', '8', '9', 'a', 'b',
412 'c', 'd', 'e', 'f'};
413 char nibble_chars[2];
414 nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
415 nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
416 bytes_written = Write(nibble_chars, sizeof(nibble_chars));
417 }
418 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419}
420
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421size_t Stream::PutHex8(uint8_t uvalue) {
422 return _PutHex8(uvalue, m_flags.Test(eAddPrefix));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
Kate Stoneb9c1b512016-09-06 20:57:50 +0000425size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
426 if (byte_order == eByteOrderInvalid)
427 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 bool add_prefix = m_flags.Test(eAddPrefix);
430 size_t bytes_written = 0;
431 if (byte_order == eByteOrderLittle) {
432 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
433 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
434 } else {
435 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
436 --byte, add_prefix = false)
437 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
438 }
439 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440}
441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
443 if (byte_order == eByteOrderInvalid)
444 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 bool add_prefix = m_flags.Test(eAddPrefix);
447 size_t bytes_written = 0;
448 if (byte_order == eByteOrderLittle) {
449 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
450 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
451 } else {
452 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
453 --byte, add_prefix = false)
454 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
455 }
456 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457}
458
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
460 if (byte_order == eByteOrderInvalid)
461 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463 bool add_prefix = m_flags.Test(eAddPrefix);
464 size_t bytes_written = 0;
465 if (byte_order == eByteOrderLittle) {
466 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
467 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
468 } else {
469 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
470 --byte, add_prefix = false)
471 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
472 }
473 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474}
475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
477 lldb::ByteOrder byte_order) {
478 switch (byte_size) {
479 case 1:
480 return PutHex8((uint8_t)uvalue);
481 case 2:
482 return PutHex16((uint16_t)uvalue);
483 case 4:
484 return PutHex32((uint32_t)uvalue);
485 case 8:
486 return PutHex64(uvalue);
487 }
488 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489}
490
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491size_t Stream::PutPointer(void *ptr) {
492 return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
493 endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494}
495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496size_t Stream::PutFloat(float f, ByteOrder byte_order) {
497 if (byte_order == eByteOrderInvalid)
498 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500 return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501}
502
Kate Stoneb9c1b512016-09-06 20:57:50 +0000503size_t Stream::PutDouble(double d, ByteOrder byte_order) {
504 if (byte_order == eByteOrderInvalid)
505 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506
Kate Stoneb9c1b512016-09-06 20:57:50 +0000507 return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508}
509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
511 if (byte_order == eByteOrderInvalid)
512 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514 return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515}
516
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517size_t Stream::PutRawBytes(const void *s, size_t src_len,
518 ByteOrder src_byte_order, ByteOrder dst_byte_order) {
519 if (src_byte_order == eByteOrderInvalid)
520 src_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 if (dst_byte_order == eByteOrderInvalid)
523 dst_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 size_t bytes_written = 0;
526 const uint8_t *src = (const uint8_t *)s;
527 bool binary_was_set = m_flags.Test(eBinary);
528 if (!binary_was_set)
529 m_flags.Set(eBinary);
530 if (src_byte_order == dst_byte_order) {
531 for (size_t i = 0; i < src_len; ++i)
532 bytes_written += _PutHex8(src[i], false);
533 } else {
534 for (size_t i = src_len - 1; i < src_len; --i)
535 bytes_written += _PutHex8(src[i], false);
536 }
537 if (!binary_was_set)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 m_flags.Clear(eBinary);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541}
542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
544 ByteOrder src_byte_order,
545 ByteOrder dst_byte_order) {
546 if (src_byte_order == eByteOrderInvalid)
547 src_byte_order = m_byte_order;
548
549 if (dst_byte_order == eByteOrderInvalid)
550 dst_byte_order = m_byte_order;
551
552 size_t bytes_written = 0;
553 const uint8_t *src = (const uint8_t *)s;
554 bool binary_is_set = m_flags.Test(eBinary);
555 m_flags.Clear(eBinary);
556 if (src_byte_order == dst_byte_order) {
557 for (size_t i = 0; i < src_len; ++i)
558 bytes_written += _PutHex8(src[i], false);
559 } else {
560 for (size_t i = src_len - 1; i < src_len; --i)
561 bytes_written += _PutHex8(src[i], false);
562 }
563 if (binary_is_set)
564 m_flags.Set(eBinary);
565
566 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567}
568
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569size_t Stream::PutCStringAsRawHex8(const char *s) {
570 size_t bytes_written = 0;
571 bool binary_is_set = m_flags.Test(eBinary);
572 m_flags.Clear(eBinary);
573 do {
574 bytes_written += _PutHex8(*s, false);
575 ++s;
576 } while (*s);
577 if (binary_is_set)
578 m_flags.Set(eBinary);
579 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580}
581
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582void Stream::UnitTest(Stream *s) {
583 s->PutHex8(0x12);
584
585 s->PutChar(' ');
586 s->PutHex16(0x3456, endian::InlHostByteOrder());
587 s->PutChar(' ');
588 s->PutHex16(0x3456, eByteOrderBig);
589 s->PutChar(' ');
590 s->PutHex16(0x3456, eByteOrderLittle);
591
592 s->PutChar(' ');
593 s->PutHex32(0x789abcde, endian::InlHostByteOrder());
594 s->PutChar(' ');
595 s->PutHex32(0x789abcde, eByteOrderBig);
596 s->PutChar(' ');
597 s->PutHex32(0x789abcde, eByteOrderLittle);
598
599 s->PutChar(' ');
600 s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
601 s->PutChar(' ');
602 s->PutHex64(0x1122334455667788ull, eByteOrderBig);
603 s->PutChar(' ');
604 s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
605
606 const char *hola = "Hello World!!!";
607 s->PutChar(' ');
608 s->PutCString(hola);
609
610 s->PutChar(' ');
611 s->Write(hola, 5);
612
613 s->PutChar(' ');
614 s->PutCStringAsRawHex8(hola);
615
616 s->PutChar(' ');
617 s->PutCStringAsRawHex8("01234");
618
619 s->PutChar(' ');
620 s->Printf("pid=%i", 12733);
621
622 s->PutChar(' ');
623 s->PrintfAsRawHex8("pid=%i", 12733);
624 s->PutChar('\n');
625}