blob: a5eca3f38eafd120910d6f2eeb17a2e7893e91fa [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//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100size_t Stream::PutCString(const char *cstr) {
101 size_t cstr_len = strlen(cstr);
102 // when in binary mode, emit the NULL terminator
103 if (m_flags.Test(eBinary))
104 ++cstr_len;
105 return Write(cstr, cstr_len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106}
107
108//------------------------------------------------------------------
109// Print a double quoted NULL terminated C string to the stream
110// using the printf format in "format".
111//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112void Stream::QuotedCString(const char *cstr, const char *format) {
113 Printf(format, cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114}
115
116//------------------------------------------------------------------
117// Put an address "addr" out to the stream with optional prefix
118// and suffix strings.
119//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
121 const char *suffix) {
122 if (prefix == NULL)
123 prefix = "";
124 if (suffix == NULL)
125 suffix = "";
126 // int addr_width = m_addr_size << 1;
127 // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
128 Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129}
130
131//------------------------------------------------------------------
132// Put an address range out to the stream with optional prefix
133// and suffix strings.
134//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
136 uint32_t addr_size, const char *prefix,
137 const char *suffix) {
138 if (prefix && prefix[0])
139 PutCString(prefix);
140 Address(lo_addr, addr_size, "[");
141 Address(hi_addr, addr_size, "-", ")");
142 if (suffix && suffix[0])
143 PutCString(suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144}
145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147
148//------------------------------------------------------------------
149// Print some formatted output to the stream.
150//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151size_t Stream::Printf(const char *format, ...) {
152 va_list args;
153 va_start(args, format);
154 size_t result = PrintfVarArg(format, args);
155 va_end(args);
156 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157}
158
159//------------------------------------------------------------------
160// Print some formatted output to the stream.
161//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162size_t Stream::PrintfVarArg(const char *format, va_list args) {
163 char str[1024];
164 va_list args_copy;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 va_copy(args_copy, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 size_t bytes_written = 0;
169 // Try and format our string into a fixed buffer first and see if it fits
170 size_t length = ::vsnprintf(str, sizeof(str), format, args);
171 if (length < sizeof(str)) {
172 // Include the NULL termination byte for binary output
173 if (m_flags.Test(eBinary))
174 length += 1;
175 // The formatted string fit into our stack based buffer, so we can just
176 // append that to our packet
177 bytes_written = Write(str, length);
178 } else {
179 // Our stack buffer wasn't big enough to contain the entire formatted
180 // string, so lets let vasprintf create the string for us!
181 char *str_ptr = NULL;
182 length = ::vasprintf(&str_ptr, format, args_copy);
183 if (str_ptr) {
184 // Include the NULL termination byte for binary output
185 if (m_flags.Test(eBinary))
186 length += 1;
187 bytes_written = Write(str_ptr, length);
188 ::free(str_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 }
191 va_end(args_copy);
192 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193}
194
195//------------------------------------------------------------------
196// Print and End of Line character to the stream
197//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198size_t Stream::EOL() { return PutChar('\n'); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199
200//------------------------------------------------------------------
201// Indent the current line using the current indentation level and
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000202// print an optional string following the indentation spaces.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204size_t Stream::Indent(const char *s) {
205 return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206}
207
Zachary Turnera4496982016-10-05 21:14:38 +0000208size_t Stream::Indent(llvm::StringRef str) {
209 return Printf("%*.*s%s", m_indent_level, m_indent_level, "", str.str().c_str());
210}
211
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212//------------------------------------------------------------------
213// Stream a character "ch" out to this stream.
214//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215Stream &Stream::operator<<(char ch) {
216 PutChar(ch);
217 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218}
219
220//------------------------------------------------------------------
221// Stream the NULL terminated C string out to this stream.
222//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223Stream &Stream::operator<<(const char *s) {
224 Printf("%s", s);
225 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226}
227
228//------------------------------------------------------------------
229// Stream the pointer value out to this stream.
230//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231Stream &Stream::operator<<(const void *p) {
232 Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
233 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234}
235
236//------------------------------------------------------------------
237// Stream a uint8_t "uval" out to this stream.
238//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239Stream &Stream::operator<<(uint8_t uval) {
240 PutHex8(uval);
241 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242}
243
244//------------------------------------------------------------------
245// Stream a uint16_t "uval" out to this stream.
246//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247Stream &Stream::operator<<(uint16_t uval) {
248 PutHex16(uval, m_byte_order);
249 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250}
251
252//------------------------------------------------------------------
253// Stream a uint32_t "uval" out to this stream.
254//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255Stream &Stream::operator<<(uint32_t uval) {
256 PutHex32(uval, m_byte_order);
257 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258}
259
260//------------------------------------------------------------------
261// Stream a uint64_t "uval" out to this stream.
262//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263Stream &Stream::operator<<(uint64_t uval) {
264 PutHex64(uval, m_byte_order);
265 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266}
267
268//------------------------------------------------------------------
269// Stream a int8_t "sval" out to this stream.
270//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271Stream &Stream::operator<<(int8_t sval) {
272 Printf("%i", (int)sval);
273 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274}
275
276//------------------------------------------------------------------
277// Stream a int16_t "sval" out to this stream.
278//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279Stream &Stream::operator<<(int16_t sval) {
280 Printf("%i", (int)sval);
281 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282}
283
284//------------------------------------------------------------------
285// Stream a int32_t "sval" out to this stream.
286//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287Stream &Stream::operator<<(int32_t sval) {
288 Printf("%i", (int)sval);
289 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290}
291
292//------------------------------------------------------------------
293// Stream a int64_t "sval" out to this stream.
294//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295Stream &Stream::operator<<(int64_t sval) {
296 Printf("%" PRIi64, sval);
297 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298}
299
300//------------------------------------------------------------------
301// Get the current indentation level
302//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303int Stream::GetIndentLevel() const { return m_indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304
305//------------------------------------------------------------------
306// Set the current indentation level
307//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000308void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309
310//------------------------------------------------------------------
311// Increment the current indentation level
312//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313void Stream::IndentMore(int amount) { m_indent_level += amount; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314
315//------------------------------------------------------------------
316// Decrement the current indentation level
317//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318void Stream::IndentLess(int amount) {
319 if (m_indent_level >= amount)
320 m_indent_level -= amount;
321 else
322 m_indent_level = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323}
324
325//------------------------------------------------------------------
326// Get the address size in bytes
327//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329
330//------------------------------------------------------------------
331// Set the address size in bytes
332//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334
335//------------------------------------------------------------------
336// Returns true if the verbose flag bit is set in this stream.
337//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338bool Stream::GetVerbose() const { return m_flags.Test(eVerbose); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339
340//------------------------------------------------------------------
341// Returns true if the debug flag bit is set in this stream.
342//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343bool Stream::GetDebug() const { return m_flags.Test(eDebug); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344
345//------------------------------------------------------------------
346// The flags get accessor
347//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348Flags &Stream::GetFlags() { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349
350//------------------------------------------------------------------
351// The flags const get accessor
352//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353const Flags &Stream::GetFlags() const { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354
Sean Callanan609f8c52010-07-02 02:43:42 +0000355//------------------------------------------------------------------
356// The byte order get accessor
357//------------------------------------------------------------------
358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
Sean Callanan609f8c52010-07-02 02:43:42 +0000360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361size_t Stream::PrintfAsRawHex8(const char *format, ...) {
362 va_list args;
363 va_list args_copy;
364 va_start(args, format);
365 va_copy(args_copy, args); // Copy this so we
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 char str[1024];
368 size_t bytes_written = 0;
369 // Try and format our string into a fixed buffer first and see if it fits
370 size_t length = ::vsnprintf(str, sizeof(str), format, args);
371 if (length < sizeof(str)) {
372 // The formatted string fit into our stack based buffer, so we can just
373 // append that to our packet
374 for (size_t i = 0; i < length; ++i)
375 bytes_written += _PutHex8(str[i], false);
376 } else {
377 // Our stack buffer wasn't big enough to contain the entire formatted
378 // string, so lets let vasprintf create the string for us!
379 char *str_ptr = NULL;
380 length = ::vasprintf(&str_ptr, format, args_copy);
381 if (str_ptr) {
382 for (size_t i = 0; i < length; ++i)
383 bytes_written += _PutHex8(str_ptr[i], false);
384 ::free(str_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 }
387 va_end(args);
388 va_end(args_copy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391}
392
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
394 size_t bytes_written = 0;
395 for (size_t i = 0; i < n; ++i)
396 bytes_written += _PutHex8(uvalue, m_flags.Test(eAddPrefix));
397 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398}
399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
401 size_t bytes_written = 0;
402 if (m_flags.Test(eBinary)) {
403 bytes_written = Write(&uvalue, 1);
404 } else {
405 if (add_prefix)
406 PutCString("0x");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
409 '6', '7', '8', '9', 'a', 'b',
410 'c', 'd', 'e', 'f'};
411 char nibble_chars[2];
412 nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
413 nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
414 bytes_written = Write(nibble_chars, sizeof(nibble_chars));
415 }
416 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419size_t Stream::PutHex8(uint8_t uvalue) {
420 return _PutHex8(uvalue, m_flags.Test(eAddPrefix));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421}
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
424 if (byte_order == eByteOrderInvalid)
425 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 bool add_prefix = m_flags.Test(eAddPrefix);
428 size_t bytes_written = 0;
429 if (byte_order == eByteOrderLittle) {
430 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
431 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
432 } else {
433 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
434 --byte, add_prefix = false)
435 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
436 }
437 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438}
439
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
441 if (byte_order == eByteOrderInvalid)
442 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 bool add_prefix = m_flags.Test(eAddPrefix);
445 size_t bytes_written = 0;
446 if (byte_order == eByteOrderLittle) {
447 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
448 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
449 } else {
450 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
451 --byte, add_prefix = false)
452 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
453 }
454 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455}
456
Kate Stoneb9c1b512016-09-06 20:57:50 +0000457size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
458 if (byte_order == eByteOrderInvalid)
459 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461 bool add_prefix = m_flags.Test(eAddPrefix);
462 size_t bytes_written = 0;
463 if (byte_order == eByteOrderLittle) {
464 for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
465 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
466 } else {
467 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
468 --byte, add_prefix = false)
469 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
470 }
471 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472}
473
Kate Stoneb9c1b512016-09-06 20:57:50 +0000474size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
475 lldb::ByteOrder byte_order) {
476 switch (byte_size) {
477 case 1:
478 return PutHex8((uint8_t)uvalue);
479 case 2:
480 return PutHex16((uint16_t)uvalue);
481 case 4:
482 return PutHex32((uint32_t)uvalue);
483 case 8:
484 return PutHex64(uvalue);
485 }
486 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487}
488
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489size_t Stream::PutPointer(void *ptr) {
490 return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
491 endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492}
493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494size_t Stream::PutFloat(float f, ByteOrder byte_order) {
495 if (byte_order == eByteOrderInvalid)
496 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498 return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499}
500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501size_t Stream::PutDouble(double d, ByteOrder byte_order) {
502 if (byte_order == eByteOrderInvalid)
503 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504
Kate Stoneb9c1b512016-09-06 20:57:50 +0000505 return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506}
507
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
509 if (byte_order == eByteOrderInvalid)
510 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512 return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513}
514
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515size_t Stream::PutRawBytes(const void *s, size_t src_len,
516 ByteOrder src_byte_order, ByteOrder dst_byte_order) {
517 if (src_byte_order == eByteOrderInvalid)
518 src_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519
Kate Stoneb9c1b512016-09-06 20:57:50 +0000520 if (dst_byte_order == eByteOrderInvalid)
521 dst_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523 size_t bytes_written = 0;
524 const uint8_t *src = (const uint8_t *)s;
525 bool binary_was_set = m_flags.Test(eBinary);
526 if (!binary_was_set)
527 m_flags.Set(eBinary);
528 if (src_byte_order == dst_byte_order) {
529 for (size_t i = 0; i < src_len; ++i)
530 bytes_written += _PutHex8(src[i], false);
531 } else {
532 for (size_t i = src_len - 1; i < src_len; --i)
533 bytes_written += _PutHex8(src[i], false);
534 }
535 if (!binary_was_set)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 m_flags.Clear(eBinary);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539}
540
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
542 ByteOrder src_byte_order,
543 ByteOrder dst_byte_order) {
544 if (src_byte_order == eByteOrderInvalid)
545 src_byte_order = m_byte_order;
546
547 if (dst_byte_order == eByteOrderInvalid)
548 dst_byte_order = m_byte_order;
549
550 size_t bytes_written = 0;
551 const uint8_t *src = (const uint8_t *)s;
552 bool binary_is_set = m_flags.Test(eBinary);
553 m_flags.Clear(eBinary);
554 if (src_byte_order == dst_byte_order) {
555 for (size_t i = 0; i < src_len; ++i)
556 bytes_written += _PutHex8(src[i], false);
557 } else {
558 for (size_t i = src_len - 1; i < src_len; --i)
559 bytes_written += _PutHex8(src[i], false);
560 }
561 if (binary_is_set)
562 m_flags.Set(eBinary);
563
564 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565}
566
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567size_t Stream::PutCStringAsRawHex8(const char *s) {
568 size_t bytes_written = 0;
569 bool binary_is_set = m_flags.Test(eBinary);
570 m_flags.Clear(eBinary);
571 do {
572 bytes_written += _PutHex8(*s, false);
573 ++s;
574 } while (*s);
575 if (binary_is_set)
576 m_flags.Set(eBinary);
577 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578}
579
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580void Stream::UnitTest(Stream *s) {
581 s->PutHex8(0x12);
582
583 s->PutChar(' ');
584 s->PutHex16(0x3456, endian::InlHostByteOrder());
585 s->PutChar(' ');
586 s->PutHex16(0x3456, eByteOrderBig);
587 s->PutChar(' ');
588 s->PutHex16(0x3456, eByteOrderLittle);
589
590 s->PutChar(' ');
591 s->PutHex32(0x789abcde, endian::InlHostByteOrder());
592 s->PutChar(' ');
593 s->PutHex32(0x789abcde, eByteOrderBig);
594 s->PutChar(' ');
595 s->PutHex32(0x789abcde, eByteOrderLittle);
596
597 s->PutChar(' ');
598 s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
599 s->PutChar(' ');
600 s->PutHex64(0x1122334455667788ull, eByteOrderBig);
601 s->PutChar(' ');
602 s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
603
604 const char *hola = "Hello World!!!";
605 s->PutChar(' ');
606 s->PutCString(hola);
607
608 s->PutChar(' ');
609 s->Write(hola, 5);
610
611 s->PutChar(' ');
612 s->PutCStringAsRawHex8(hola);
613
614 s->PutChar(' ');
615 s->PutCStringAsRawHex8("01234");
616
617 s->PutChar(' ');
618 s->Printf("pid=%i", 12733);
619
620 s->PutChar(' ');
621 s->PrintfAsRawHex8("pid=%i", 12733);
622 s->PutChar('\n');
623}