blob: 8dbb8d21065ff951edfdd54204e8561ccc0247ff [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
Zachary Turner0ac5f982016-11-08 04:12:42 +0000230Stream &Stream::operator<<(llvm::StringRef str) {
231 Write(str.data(), str.size());
232 return *this;
233}
234
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235//------------------------------------------------------------------
236// Stream the pointer value out to this stream.
237//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000238Stream &Stream::operator<<(const void *p) {
239 Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
240 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241}
242
243//------------------------------------------------------------------
244// Stream a uint8_t "uval" out to this stream.
245//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246Stream &Stream::operator<<(uint8_t uval) {
247 PutHex8(uval);
248 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249}
250
251//------------------------------------------------------------------
252// Stream a uint16_t "uval" out to this stream.
253//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254Stream &Stream::operator<<(uint16_t uval) {
255 PutHex16(uval, m_byte_order);
256 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257}
258
259//------------------------------------------------------------------
260// Stream a uint32_t "uval" out to this stream.
261//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262Stream &Stream::operator<<(uint32_t uval) {
263 PutHex32(uval, m_byte_order);
264 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
267//------------------------------------------------------------------
268// Stream a uint64_t "uval" out to this stream.
269//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270Stream &Stream::operator<<(uint64_t uval) {
271 PutHex64(uval, m_byte_order);
272 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273}
274
275//------------------------------------------------------------------
276// Stream a int8_t "sval" out to this stream.
277//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278Stream &Stream::operator<<(int8_t sval) {
279 Printf("%i", (int)sval);
280 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281}
282
283//------------------------------------------------------------------
284// Stream a int16_t "sval" out to this stream.
285//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286Stream &Stream::operator<<(int16_t sval) {
287 Printf("%i", (int)sval);
288 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289}
290
291//------------------------------------------------------------------
292// Stream a int32_t "sval" out to this stream.
293//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294Stream &Stream::operator<<(int32_t sval) {
295 Printf("%i", (int)sval);
296 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297}
298
299//------------------------------------------------------------------
300// Stream a int64_t "sval" out to this stream.
301//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302Stream &Stream::operator<<(int64_t sval) {
303 Printf("%" PRIi64, sval);
304 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305}
306
307//------------------------------------------------------------------
308// Get the current indentation level
309//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310int Stream::GetIndentLevel() const { return m_indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311
312//------------------------------------------------------------------
313// Set the current indentation level
314//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316
317//------------------------------------------------------------------
318// Increment the current indentation level
319//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320void Stream::IndentMore(int amount) { m_indent_level += amount; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321
322//------------------------------------------------------------------
323// Decrement the current indentation level
324//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000325void Stream::IndentLess(int amount) {
326 if (m_indent_level >= amount)
327 m_indent_level -= amount;
328 else
329 m_indent_level = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330}
331
332//------------------------------------------------------------------
333// Get the address size in bytes
334//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336
337//------------------------------------------------------------------
338// Set the address size in bytes
339//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341
342//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343// The flags get accessor
344//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345Flags &Stream::GetFlags() { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346
347//------------------------------------------------------------------
348// The flags const get accessor
349//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350const Flags &Stream::GetFlags() const { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351
Sean Callanan609f8c52010-07-02 02:43:42 +0000352//------------------------------------------------------------------
353// The byte order get accessor
354//------------------------------------------------------------------
355
Kate Stoneb9c1b512016-09-06 20:57:50 +0000356lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
Sean Callanan609f8c52010-07-02 02:43:42 +0000357
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358size_t Stream::PrintfAsRawHex8(const char *format, ...) {
359 va_list args;
360 va_list args_copy;
361 va_start(args, format);
362 va_copy(args_copy, args); // Copy this so we
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 char str[1024];
365 size_t bytes_written = 0;
366 // Try and format our string into a fixed buffer first and see if it fits
367 size_t length = ::vsnprintf(str, sizeof(str), format, args);
368 if (length < sizeof(str)) {
369 // The formatted string fit into our stack based buffer, so we can just
370 // append that to our packet
371 for (size_t i = 0; i < length; ++i)
372 bytes_written += _PutHex8(str[i], false);
373 } else {
374 // Our stack buffer wasn't big enough to contain the entire formatted
375 // string, so lets let vasprintf create the string for us!
376 char *str_ptr = NULL;
377 length = ::vasprintf(&str_ptr, format, args_copy);
378 if (str_ptr) {
379 for (size_t i = 0; i < length; ++i)
380 bytes_written += _PutHex8(str_ptr[i], false);
381 ::free(str_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 }
384 va_end(args);
385 va_end(args_copy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388}
389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
391 size_t bytes_written = 0;
392 for (size_t i = 0; i < n; ++i)
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000393 bytes_written += _PutHex8(uvalue, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395}
396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
398 size_t bytes_written = 0;
399 if (m_flags.Test(eBinary)) {
400 bytes_written = Write(&uvalue, 1);
401 } else {
402 if (add_prefix)
403 PutCString("0x");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405 static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
406 '6', '7', '8', '9', 'a', 'b',
407 'c', 'd', 'e', 'f'};
408 char nibble_chars[2];
409 nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
410 nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
411 bytes_written = Write(nibble_chars, sizeof(nibble_chars));
412 }
413 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414}
415
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000416size_t Stream::PutHex8(uint8_t uvalue) { return _PutHex8(uvalue, false); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
419 if (byte_order == eByteOrderInvalid)
420 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 size_t bytes_written = 0;
423 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000424 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
425 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000427 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
428 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 }
430 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431}
432
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
434 if (byte_order == eByteOrderInvalid)
435 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 size_t bytes_written = 0;
438 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000439 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
440 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000442 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
443 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 }
445 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446}
447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
449 if (byte_order == eByteOrderInvalid)
450 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 size_t bytes_written = 0;
453 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000454 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
455 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000457 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
458 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459 }
460 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461}
462
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
464 lldb::ByteOrder byte_order) {
465 switch (byte_size) {
466 case 1:
467 return PutHex8((uint8_t)uvalue);
468 case 2:
469 return PutHex16((uint16_t)uvalue);
470 case 4:
471 return PutHex32((uint32_t)uvalue);
472 case 8:
473 return PutHex64(uvalue);
474 }
475 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476}
477
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478size_t Stream::PutPointer(void *ptr) {
479 return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
480 endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481}
482
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483size_t Stream::PutFloat(float f, ByteOrder byte_order) {
484 if (byte_order == eByteOrderInvalid)
485 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486
Kate Stoneb9c1b512016-09-06 20:57:50 +0000487 return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488}
489
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490size_t Stream::PutDouble(double d, ByteOrder byte_order) {
491 if (byte_order == eByteOrderInvalid)
492 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494 return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495}
496
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
498 if (byte_order == eByteOrderInvalid)
499 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501 return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502}
503
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504size_t Stream::PutRawBytes(const void *s, size_t src_len,
505 ByteOrder src_byte_order, ByteOrder dst_byte_order) {
506 if (src_byte_order == eByteOrderInvalid)
507 src_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509 if (dst_byte_order == eByteOrderInvalid)
510 dst_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512 size_t bytes_written = 0;
513 const uint8_t *src = (const uint8_t *)s;
514 bool binary_was_set = m_flags.Test(eBinary);
515 if (!binary_was_set)
516 m_flags.Set(eBinary);
517 if (src_byte_order == dst_byte_order) {
518 for (size_t i = 0; i < src_len; ++i)
519 bytes_written += _PutHex8(src[i], false);
520 } else {
521 for (size_t i = src_len - 1; i < src_len; --i)
522 bytes_written += _PutHex8(src[i], false);
523 }
524 if (!binary_was_set)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 m_flags.Clear(eBinary);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528}
529
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
531 ByteOrder src_byte_order,
532 ByteOrder dst_byte_order) {
533 if (src_byte_order == eByteOrderInvalid)
534 src_byte_order = m_byte_order;
535
536 if (dst_byte_order == eByteOrderInvalid)
537 dst_byte_order = m_byte_order;
538
539 size_t bytes_written = 0;
540 const uint8_t *src = (const uint8_t *)s;
541 bool binary_is_set = m_flags.Test(eBinary);
542 m_flags.Clear(eBinary);
543 if (src_byte_order == dst_byte_order) {
544 for (size_t i = 0; i < src_len; ++i)
545 bytes_written += _PutHex8(src[i], false);
546 } else {
547 for (size_t i = src_len - 1; i < src_len; --i)
548 bytes_written += _PutHex8(src[i], false);
549 }
550 if (binary_is_set)
551 m_flags.Set(eBinary);
552
553 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554}
555
Kate Stoneb9c1b512016-09-06 20:57:50 +0000556size_t Stream::PutCStringAsRawHex8(const char *s) {
557 size_t bytes_written = 0;
558 bool binary_is_set = m_flags.Test(eBinary);
559 m_flags.Clear(eBinary);
560 do {
561 bytes_written += _PutHex8(*s, false);
562 ++s;
563 } while (*s);
564 if (binary_is_set)
565 m_flags.Set(eBinary);
566 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567}
568
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569void Stream::UnitTest(Stream *s) {
570 s->PutHex8(0x12);
571
572 s->PutChar(' ');
573 s->PutHex16(0x3456, endian::InlHostByteOrder());
574 s->PutChar(' ');
575 s->PutHex16(0x3456, eByteOrderBig);
576 s->PutChar(' ');
577 s->PutHex16(0x3456, eByteOrderLittle);
578
579 s->PutChar(' ');
580 s->PutHex32(0x789abcde, endian::InlHostByteOrder());
581 s->PutChar(' ');
582 s->PutHex32(0x789abcde, eByteOrderBig);
583 s->PutChar(' ');
584 s->PutHex32(0x789abcde, eByteOrderLittle);
585
586 s->PutChar(' ');
587 s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
588 s->PutChar(' ');
589 s->PutHex64(0x1122334455667788ull, eByteOrderBig);
590 s->PutChar(' ');
591 s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
592
593 const char *hola = "Hello World!!!";
594 s->PutChar(' ');
595 s->PutCString(hola);
596
597 s->PutChar(' ');
598 s->Write(hola, 5);
599
600 s->PutChar(' ');
601 s->PutCStringAsRawHex8(hola);
602
603 s->PutChar(' ');
604 s->PutCStringAsRawHex8("01234");
605
606 s->PutChar(' ');
607 s->Printf("pid=%i", 12733);
608
609 s->PutChar(' ');
610 s->PrintfAsRawHex8("pid=%i", 12733);
611 s->PutChar('\n');
612}