blob: 8899a43496c5906969ca40f551fa2d032b433f9e [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
Zachary Turnerbf9a7732017-02-02 21:39:50 +000010#include "lldb/Utility/Stream.h"
Zachary Turner24ae6292017-02-16 19:38:21 +000011
Zachary Turner01c32432017-02-14 19:06:07 +000012#include "lldb/Utility/Endian.h"
Zachary Turner24ae6292017-02-16 19:38:21 +000013#include "lldb/Utility/VASPrintf.h"
Benjamin Kramer581a6912012-02-27 18:46:54 +000014#include <stddef.h>
Eli Friedman88966972010-06-09 08:50:27 +000015#include <stdio.h>
Eli Friedman88966972010-06-09 08:50:27 +000016#include <stdlib.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
Daniel Malead01b2952012-11-29 21:49:15 +000019#include <inttypes.h>
20
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021using namespace lldb;
22using namespace lldb_private;
23
Kate Stoneb9c1b512016-09-06 20:57:50 +000024Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
25 : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
26 m_indent_level(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027
Kate Stoneb9c1b512016-09-06 20:57:50 +000028Stream::Stream()
29 : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
30 m_indent_level(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
32//------------------------------------------------------------------
33// Destructor
34//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000035Stream::~Stream() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
38 ByteOrder old_byte_order = m_byte_order;
39 m_byte_order = byte_order;
40 return old_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041}
42
43//------------------------------------------------------------------
44// Put an offset "uval" out to the stream using the printf format
45// in "format".
46//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000047void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048
49//------------------------------------------------------------------
50// Put an SLEB128 "uval" out to the stream using the printf format
51// in "format".
52//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000053size_t Stream::PutSLEB128(int64_t sval) {
54 size_t bytes_written = 0;
55 if (m_flags.Test(eBinary)) {
56 bool more = true;
57 while (more) {
58 uint8_t byte = sval & 0x7fu;
59 sval >>= 7;
60 /* sign bit of byte is 2nd high order bit (0x40) */
61 if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40)))
62 more = false;
63 else
64 // more bytes to come
65 byte |= 0x80u;
66 bytes_written += Write(&byte, 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 } else {
69 bytes_written = Printf("0x%" PRIi64, sval);
70 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073}
74
75//------------------------------------------------------------------
76// Put an ULEB128 "uval" out to the stream using the printf format
77// in "format".
78//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000079size_t Stream::PutULEB128(uint64_t uval) {
80 size_t bytes_written = 0;
81 if (m_flags.Test(eBinary)) {
82 do {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 uint8_t byte = uval & 0x7fu;
85 uval >>= 7;
86 if (uval != 0) {
87 // more bytes to come
88 byte |= 0x80u;
89 }
90 bytes_written += Write(&byte, 1);
91 } while (uval != 0);
92 } else {
93 bytes_written = Printf("0x%" PRIx64, uval);
94 }
95 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096}
97
98//------------------------------------------------------------------
Enrico Granata7b59f752012-01-31 17:18:40 +000099// Print a raw NULL terminated C string to the stream.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100//------------------------------------------------------------------
Zachary Turner4fa098a2016-10-06 21:22:44 +0000101size_t Stream::PutCString(llvm::StringRef str) {
102 size_t bytes_written = 0;
103 bytes_written = Write(str.data(), str.size());
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 // when in binary mode, emit the NULL terminator
106 if (m_flags.Test(eBinary))
Zachary Turner4fa098a2016-10-06 21:22:44 +0000107 bytes_written += PutChar('\0');
108 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109}
110
111//------------------------------------------------------------------
112// Print a double quoted NULL terminated C string to the stream
113// using the printf format in "format".
114//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115void Stream::QuotedCString(const char *cstr, const char *format) {
116 Printf(format, cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117}
118
119//------------------------------------------------------------------
120// Put an address "addr" out to the stream with optional prefix
121// and suffix strings.
122//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
124 const char *suffix) {
125 if (prefix == NULL)
126 prefix = "";
127 if (suffix == NULL)
128 suffix = "";
129 // int addr_width = m_addr_size << 1;
130 // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
131 Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132}
133
134//------------------------------------------------------------------
135// Put an address range out to the stream with optional prefix
136// and suffix strings.
137//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
139 uint32_t addr_size, const char *prefix,
140 const char *suffix) {
141 if (prefix && prefix[0])
142 PutCString(prefix);
143 Address(lo_addr, addr_size, "[");
144 Address(hi_addr, addr_size, "-", ")");
145 if (suffix && suffix[0])
146 PutCString(suffix);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147}
148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150
151//------------------------------------------------------------------
152// Print some formatted output to the stream.
153//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154size_t Stream::Printf(const char *format, ...) {
155 va_list args;
156 va_start(args, format);
157 size_t result = PrintfVarArg(format, args);
158 va_end(args);
159 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160}
161
162//------------------------------------------------------------------
163// Print some formatted output to the stream.
164//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165size_t Stream::PrintfVarArg(const char *format, va_list args) {
Zachary Turner24ae6292017-02-16 19:38:21 +0000166 llvm::SmallString<1024> buf;
167 VASprintf(buf, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168
Zachary Turner24ae6292017-02-16 19:38:21 +0000169 // Include the NULL termination byte for binary output
170 size_t length = buf.size();
171 if (m_flags.Test(eBinary))
172 ++length;
173 return Write(buf.c_str(), length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174}
175
176//------------------------------------------------------------------
177// Print and End of Line character to the stream
178//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179size_t Stream::EOL() { return PutChar('\n'); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180
181//------------------------------------------------------------------
182// Indent the current line using the current indentation level and
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000183// print an optional string following the indentation spaces.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185size_t Stream::Indent(const char *s) {
186 return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
Zachary Turnera4496982016-10-05 21:14:38 +0000189size_t Stream::Indent(llvm::StringRef str) {
Zachary Turnerbf9a7732017-02-02 21:39:50 +0000190 return Printf("%*.*s%s", m_indent_level, m_indent_level, "",
191 str.str().c_str());
Zachary Turnera4496982016-10-05 21:14:38 +0000192}
193
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194//------------------------------------------------------------------
195// Stream a character "ch" out to this stream.
196//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197Stream &Stream::operator<<(char ch) {
198 PutChar(ch);
199 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200}
201
202//------------------------------------------------------------------
203// Stream the NULL terminated C string out to this stream.
204//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205Stream &Stream::operator<<(const char *s) {
206 Printf("%s", s);
207 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208}
209
Zachary Turner0ac5f982016-11-08 04:12:42 +0000210Stream &Stream::operator<<(llvm::StringRef str) {
211 Write(str.data(), str.size());
212 return *this;
213}
214
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215//------------------------------------------------------------------
216// Stream the pointer value out to this stream.
217//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218Stream &Stream::operator<<(const void *p) {
219 Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
220 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221}
222
223//------------------------------------------------------------------
224// Stream a uint8_t "uval" out to this stream.
225//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226Stream &Stream::operator<<(uint8_t uval) {
227 PutHex8(uval);
228 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229}
230
231//------------------------------------------------------------------
232// Stream a uint16_t "uval" out to this stream.
233//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234Stream &Stream::operator<<(uint16_t uval) {
235 PutHex16(uval, m_byte_order);
236 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237}
238
239//------------------------------------------------------------------
240// Stream a uint32_t "uval" out to this stream.
241//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242Stream &Stream::operator<<(uint32_t uval) {
243 PutHex32(uval, m_byte_order);
244 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245}
246
247//------------------------------------------------------------------
248// Stream a uint64_t "uval" out to this stream.
249//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250Stream &Stream::operator<<(uint64_t uval) {
251 PutHex64(uval, m_byte_order);
252 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253}
254
255//------------------------------------------------------------------
256// Stream a int8_t "sval" out to this stream.
257//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258Stream &Stream::operator<<(int8_t sval) {
259 Printf("%i", (int)sval);
260 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261}
262
263//------------------------------------------------------------------
264// Stream a int16_t "sval" out to this stream.
265//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266Stream &Stream::operator<<(int16_t sval) {
267 Printf("%i", (int)sval);
268 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269}
270
271//------------------------------------------------------------------
272// Stream a int32_t "sval" out to this stream.
273//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274Stream &Stream::operator<<(int32_t sval) {
275 Printf("%i", (int)sval);
276 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277}
278
279//------------------------------------------------------------------
280// Stream a int64_t "sval" out to this stream.
281//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282Stream &Stream::operator<<(int64_t sval) {
283 Printf("%" PRIi64, sval);
284 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285}
286
287//------------------------------------------------------------------
288// Get the current indentation level
289//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290int Stream::GetIndentLevel() const { return m_indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291
292//------------------------------------------------------------------
293// Set the current indentation level
294//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
297//------------------------------------------------------------------
298// Increment the current indentation level
299//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300void Stream::IndentMore(int amount) { m_indent_level += amount; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301
302//------------------------------------------------------------------
303// Decrement the current indentation level
304//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305void Stream::IndentLess(int amount) {
306 if (m_indent_level >= amount)
307 m_indent_level -= amount;
308 else
309 m_indent_level = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310}
311
312//------------------------------------------------------------------
313// Get the address size in bytes
314//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316
317//------------------------------------------------------------------
318// Set the address size in bytes
319//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321
322//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323// The flags get accessor
324//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000325Flags &Stream::GetFlags() { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326
327//------------------------------------------------------------------
328// The flags const get accessor
329//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330const Flags &Stream::GetFlags() const { return m_flags; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331
Sean Callanan609f8c52010-07-02 02:43:42 +0000332//------------------------------------------------------------------
333// The byte order get accessor
334//------------------------------------------------------------------
335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
Sean Callanan609f8c52010-07-02 02:43:42 +0000337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338size_t Stream::PrintfAsRawHex8(const char *format, ...) {
339 va_list args;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340 va_start(args, format);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341
Zachary Turner24ae6292017-02-16 19:38:21 +0000342 llvm::SmallString<1024> buf;
343 VASprintf(buf, format, args);
344
345 size_t length = 0;
346 for (char C : buf)
347 length += _PutHex8(C, false);
348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350
Zachary Turner24ae6292017-02-16 19:38:21 +0000351 return length;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352}
353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
355 size_t bytes_written = 0;
356 for (size_t i = 0; i < n; ++i)
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000357 bytes_written += _PutHex8(uvalue, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359}
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
362 size_t bytes_written = 0;
363 if (m_flags.Test(eBinary)) {
364 bytes_written = Write(&uvalue, 1);
365 } else {
366 if (add_prefix)
367 PutCString("0x");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
370 '6', '7', '8', '9', 'a', 'b',
371 'c', 'd', 'e', 'f'};
372 char nibble_chars[2];
373 nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
374 nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
375 bytes_written = Write(nibble_chars, sizeof(nibble_chars));
376 }
377 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378}
379
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000380size_t Stream::PutHex8(uint8_t uvalue) { return _PutHex8(uvalue, false); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
383 if (byte_order == eByteOrderInvalid)
384 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 size_t bytes_written = 0;
387 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000388 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
389 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000391 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
392 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 }
394 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395}
396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
398 if (byte_order == eByteOrderInvalid)
399 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401 size_t bytes_written = 0;
402 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000403 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
404 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000406 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
407 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 }
409 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410}
411
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
413 if (byte_order == eByteOrderInvalid)
414 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416 size_t bytes_written = 0;
417 if (byte_order == eByteOrderLittle) {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000418 for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
419 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420 } else {
Pavel Labath0cfd7dc92017-01-13 10:41:59 +0000421 for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
422 bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 }
424 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425}
426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
428 lldb::ByteOrder byte_order) {
429 switch (byte_size) {
430 case 1:
431 return PutHex8((uint8_t)uvalue);
432 case 2:
433 return PutHex16((uint16_t)uvalue);
434 case 4:
435 return PutHex32((uint32_t)uvalue);
436 case 8:
437 return PutHex64(uvalue);
438 }
439 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440}
441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442size_t Stream::PutPointer(void *ptr) {
443 return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
444 endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445}
446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447size_t Stream::PutFloat(float f, ByteOrder byte_order) {
448 if (byte_order == eByteOrderInvalid)
449 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452}
453
Kate Stoneb9c1b512016-09-06 20:57:50 +0000454size_t Stream::PutDouble(double d, ByteOrder byte_order) {
455 if (byte_order == eByteOrderInvalid)
456 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459}
460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
462 if (byte_order == eByteOrderInvalid)
463 byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465 return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466}
467
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468size_t Stream::PutRawBytes(const void *s, size_t src_len,
469 ByteOrder src_byte_order, ByteOrder dst_byte_order) {
470 if (src_byte_order == eByteOrderInvalid)
471 src_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 if (dst_byte_order == eByteOrderInvalid)
474 dst_byte_order = m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476 size_t bytes_written = 0;
477 const uint8_t *src = (const uint8_t *)s;
478 bool binary_was_set = m_flags.Test(eBinary);
479 if (!binary_was_set)
480 m_flags.Set(eBinary);
481 if (src_byte_order == dst_byte_order) {
482 for (size_t i = 0; i < src_len; ++i)
483 bytes_written += _PutHex8(src[i], false);
484 } else {
485 for (size_t i = src_len - 1; i < src_len; --i)
486 bytes_written += _PutHex8(src[i], false);
487 }
488 if (!binary_was_set)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 m_flags.Clear(eBinary);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492}
493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
495 ByteOrder src_byte_order,
496 ByteOrder dst_byte_order) {
497 if (src_byte_order == eByteOrderInvalid)
498 src_byte_order = m_byte_order;
499
500 if (dst_byte_order == eByteOrderInvalid)
501 dst_byte_order = m_byte_order;
502
503 size_t bytes_written = 0;
504 const uint8_t *src = (const uint8_t *)s;
505 bool binary_is_set = m_flags.Test(eBinary);
506 m_flags.Clear(eBinary);
507 if (src_byte_order == dst_byte_order) {
508 for (size_t i = 0; i < src_len; ++i)
509 bytes_written += _PutHex8(src[i], false);
510 } else {
511 for (size_t i = src_len - 1; i < src_len; --i)
512 bytes_written += _PutHex8(src[i], false);
513 }
514 if (binary_is_set)
515 m_flags.Set(eBinary);
516
517 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518}
519
Kate Stoneb9c1b512016-09-06 20:57:50 +0000520size_t Stream::PutCStringAsRawHex8(const char *s) {
521 size_t bytes_written = 0;
522 bool binary_is_set = m_flags.Test(eBinary);
523 m_flags.Clear(eBinary);
524 do {
525 bytes_written += _PutHex8(*s, false);
526 ++s;
527 } while (*s);
528 if (binary_is_set)
529 m_flags.Set(eBinary);
530 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531}
532
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533void Stream::UnitTest(Stream *s) {
534 s->PutHex8(0x12);
535
536 s->PutChar(' ');
537 s->PutHex16(0x3456, endian::InlHostByteOrder());
538 s->PutChar(' ');
539 s->PutHex16(0x3456, eByteOrderBig);
540 s->PutChar(' ');
541 s->PutHex16(0x3456, eByteOrderLittle);
542
543 s->PutChar(' ');
544 s->PutHex32(0x789abcde, endian::InlHostByteOrder());
545 s->PutChar(' ');
546 s->PutHex32(0x789abcde, eByteOrderBig);
547 s->PutChar(' ');
548 s->PutHex32(0x789abcde, eByteOrderLittle);
549
550 s->PutChar(' ');
551 s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
552 s->PutChar(' ');
553 s->PutHex64(0x1122334455667788ull, eByteOrderBig);
554 s->PutChar(' ');
555 s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
556
557 const char *hola = "Hello World!!!";
558 s->PutChar(' ');
559 s->PutCString(hola);
560
561 s->PutChar(' ');
562 s->Write(hola, 5);
563
564 s->PutChar(' ');
565 s->PutCStringAsRawHex8(hola);
566
567 s->PutChar(' ');
568 s->PutCStringAsRawHex8("01234");
569
570 s->PutChar(' ');
571 s->Printf("pid=%i", 12733);
572
573 s->PutChar(' ');
574 s->PrintfAsRawHex8("pid=%i", 12733);
575 s->PutChar('\n');
576}