1254721Semaste//===-- Stream.cpp ----------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/Stream.h" 11254721Semaste#include "lldb/Host/Endian.h" 12254721Semaste#include <stddef.h> 13254721Semaste#include <stdio.h> 14254721Semaste#include <string.h> 15254721Semaste#include <stdlib.h> 16254721Semaste 17254721Semaste#include <inttypes.h> 18254721Semaste 19254721Semasteusing namespace lldb; 20254721Semasteusing namespace lldb_private; 21254721Semaste 22254721SemasteStream::Stream (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : 23254721Semaste m_flags (flags), 24254721Semaste m_addr_size (addr_size), 25254721Semaste m_byte_order (byte_order), 26254721Semaste m_indent_level(0) 27254721Semaste{ 28254721Semaste} 29254721Semaste 30254721SemasteStream::Stream () : 31254721Semaste m_flags (0), 32254721Semaste m_addr_size (4), 33254721Semaste m_byte_order (lldb::endian::InlHostByteOrder()), 34254721Semaste m_indent_level(0) 35254721Semaste{ 36254721Semaste} 37254721Semaste 38254721Semaste//------------------------------------------------------------------ 39254721Semaste// Destructor 40254721Semaste//------------------------------------------------------------------ 41254721SemasteStream::~Stream () 42254721Semaste{ 43254721Semaste} 44254721Semaste 45254721SemasteByteOrder 46254721SemasteStream::SetByteOrder (ByteOrder byte_order) 47254721Semaste{ 48254721Semaste ByteOrder old_byte_order = m_byte_order; 49254721Semaste m_byte_order = byte_order; 50254721Semaste return old_byte_order; 51254721Semaste} 52254721Semaste 53254721Semaste//------------------------------------------------------------------ 54254721Semaste// Put an offset "uval" out to the stream using the printf format 55254721Semaste// in "format". 56254721Semaste//------------------------------------------------------------------ 57254721Semastevoid 58254721SemasteStream::Offset (uint32_t uval, const char *format) 59254721Semaste{ 60254721Semaste Printf (format, uval); 61254721Semaste} 62254721Semaste 63254721Semaste//------------------------------------------------------------------ 64254721Semaste// Put an SLEB128 "uval" out to the stream using the printf format 65254721Semaste// in "format". 66254721Semaste//------------------------------------------------------------------ 67254721Semastesize_t 68254721SemasteStream::PutSLEB128 (int64_t sval) 69254721Semaste{ 70254721Semaste size_t bytes_written = 0; 71254721Semaste if (m_flags.Test(eBinary)) 72254721Semaste { 73254721Semaste bool more = true; 74254721Semaste while (more) 75254721Semaste { 76254721Semaste uint8_t byte = sval & 0x7fu; 77254721Semaste sval >>= 7; 78254721Semaste /* sign bit of byte is 2nd high order bit (0x40) */ 79254721Semaste if ((sval == 0 && !(byte & 0x40)) || 80254721Semaste (sval == -1 && (byte & 0x40)) ) 81254721Semaste more = false; 82254721Semaste else 83254721Semaste // more bytes to come 84254721Semaste byte |= 0x80u; 85254721Semaste bytes_written += Write(&byte, 1); 86254721Semaste } 87254721Semaste } 88254721Semaste else 89254721Semaste { 90254721Semaste bytes_written = Printf ("0x%" PRIi64, sval); 91254721Semaste } 92254721Semaste 93254721Semaste return bytes_written; 94254721Semaste 95254721Semaste} 96254721Semaste 97254721Semaste//------------------------------------------------------------------ 98254721Semaste// Put an ULEB128 "uval" out to the stream using the printf format 99254721Semaste// in "format". 100254721Semaste//------------------------------------------------------------------ 101254721Semastesize_t 102254721SemasteStream::PutULEB128 (uint64_t uval) 103254721Semaste{ 104254721Semaste size_t bytes_written = 0; 105254721Semaste if (m_flags.Test(eBinary)) 106254721Semaste { 107254721Semaste do 108254721Semaste { 109254721Semaste 110254721Semaste uint8_t byte = uval & 0x7fu; 111254721Semaste uval >>= 7; 112254721Semaste if (uval != 0) 113254721Semaste { 114254721Semaste // more bytes to come 115254721Semaste byte |= 0x80u; 116254721Semaste } 117254721Semaste bytes_written += Write(&byte, 1); 118254721Semaste } while (uval != 0); 119254721Semaste } 120254721Semaste else 121254721Semaste { 122254721Semaste bytes_written = Printf ("0x%" PRIx64, uval); 123254721Semaste } 124254721Semaste return bytes_written; 125254721Semaste} 126254721Semaste 127254721Semaste//------------------------------------------------------------------ 128254721Semaste// Print a raw NULL terminated C string to the stream. 129254721Semaste//------------------------------------------------------------------ 130254721Semastesize_t 131254721SemasteStream::PutCString (const char *cstr) 132254721Semaste{ 133254721Semaste size_t cstr_len = strlen(cstr); 134254721Semaste // when in binary mode, emit the NULL terminator 135254721Semaste if (m_flags.Test(eBinary)) 136254721Semaste ++cstr_len; 137254721Semaste return Write (cstr, cstr_len); 138254721Semaste} 139254721Semaste 140254721Semaste//------------------------------------------------------------------ 141254721Semaste// Print a double quoted NULL terminated C string to the stream 142254721Semaste// using the printf format in "format". 143254721Semaste//------------------------------------------------------------------ 144254721Semastevoid 145254721SemasteStream::QuotedCString (const char *cstr, const char *format) 146254721Semaste{ 147254721Semaste Printf (format, cstr); 148254721Semaste} 149254721Semaste 150254721Semaste//------------------------------------------------------------------ 151254721Semaste// Put an address "addr" out to the stream with optional prefix 152254721Semaste// and suffix strings. 153254721Semaste//------------------------------------------------------------------ 154254721Semastevoid 155254721SemasteStream::Address (uint64_t addr, uint32_t addr_size, const char *prefix, const char *suffix) 156254721Semaste{ 157254721Semaste if (prefix == NULL) 158254721Semaste prefix = ""; 159254721Semaste if (suffix == NULL) 160254721Semaste suffix = ""; 161254721Semaste// int addr_width = m_addr_size << 1; 162254721Semaste// Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix); 163254721Semaste Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix); 164254721Semaste} 165254721Semaste 166254721Semaste//------------------------------------------------------------------ 167254721Semaste// Put an address range out to the stream with optional prefix 168254721Semaste// and suffix strings. 169254721Semaste//------------------------------------------------------------------ 170254721Semastevoid 171254721SemasteStream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix, const char *suffix) 172254721Semaste{ 173254721Semaste if (prefix && prefix[0]) 174254721Semaste PutCString (prefix); 175254721Semaste Address (lo_addr, addr_size, "["); 176254721Semaste Address (hi_addr, addr_size, "-", ")"); 177254721Semaste if (suffix && suffix[0]) 178254721Semaste PutCString (suffix); 179254721Semaste} 180254721Semaste 181254721Semaste 182254721Semastesize_t 183254721SemasteStream::PutChar (char ch) 184254721Semaste{ 185254721Semaste return Write (&ch, 1); 186254721Semaste} 187254721Semaste 188254721Semaste 189254721Semaste//------------------------------------------------------------------ 190254721Semaste// Print some formatted output to the stream. 191254721Semaste//------------------------------------------------------------------ 192254721Semastesize_t 193254721SemasteStream::Printf (const char *format, ...) 194254721Semaste{ 195254721Semaste va_list args; 196254721Semaste va_start (args, format); 197254721Semaste size_t result = PrintfVarArg(format, args); 198254721Semaste va_end (args); 199254721Semaste return result; 200254721Semaste} 201254721Semaste 202254721Semaste//------------------------------------------------------------------ 203254721Semaste// Print some formatted output to the stream. 204254721Semaste//------------------------------------------------------------------ 205254721Semastesize_t 206254721SemasteStream::PrintfVarArg (const char *format, va_list args) 207254721Semaste{ 208254721Semaste char str[1024]; 209254721Semaste va_list args_copy; 210254721Semaste 211254721Semaste va_copy (args_copy, args); 212254721Semaste 213254721Semaste size_t bytes_written = 0; 214254721Semaste // Try and format our string into a fixed buffer first and see if it fits 215254721Semaste size_t length = ::vsnprintf (str, sizeof(str), format, args); 216254721Semaste if (length < sizeof(str)) 217254721Semaste { 218254721Semaste // Include the NULL termination byte for binary output 219254721Semaste if (m_flags.Test(eBinary)) 220254721Semaste length += 1; 221254721Semaste // The formatted string fit into our stack based buffer, so we can just 222254721Semaste // append that to our packet 223254721Semaste bytes_written = Write (str, length); 224254721Semaste } 225254721Semaste else 226254721Semaste { 227254721Semaste // Our stack buffer wasn't big enough to contain the entire formatted 228254721Semaste // string, so lets let vasprintf create the string for us! 229254721Semaste char *str_ptr = NULL; 230254721Semaste length = ::vasprintf (&str_ptr, format, args_copy); 231254721Semaste if (str_ptr) 232254721Semaste { 233254721Semaste // Include the NULL termination byte for binary output 234254721Semaste if (m_flags.Test(eBinary)) 235254721Semaste length += 1; 236254721Semaste bytes_written = Write (str_ptr, length); 237254721Semaste ::free (str_ptr); 238254721Semaste } 239254721Semaste } 240254721Semaste va_end (args_copy); 241254721Semaste return bytes_written; 242254721Semaste} 243254721Semaste 244254721Semaste//------------------------------------------------------------------ 245254721Semaste// Print and End of Line character to the stream 246254721Semaste//------------------------------------------------------------------ 247254721Semastesize_t 248254721SemasteStream::EOL() 249254721Semaste{ 250254721Semaste return PutChar ('\n'); 251254721Semaste} 252254721Semaste 253254721Semaste//------------------------------------------------------------------ 254254721Semaste// Indent the current line using the current indentation level and 255254721Semaste// print an optional string following the idenatation spaces. 256254721Semaste//------------------------------------------------------------------ 257254721Semastesize_t 258254721SemasteStream::Indent(const char *s) 259254721Semaste{ 260254721Semaste return Printf ("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : ""); 261254721Semaste} 262254721Semaste 263254721Semaste//------------------------------------------------------------------ 264254721Semaste// Stream a character "ch" out to this stream. 265254721Semaste//------------------------------------------------------------------ 266254721SemasteStream& 267254721SemasteStream::operator<< (char ch) 268254721Semaste{ 269254721Semaste PutChar (ch); 270254721Semaste return *this; 271254721Semaste} 272254721Semaste 273254721Semaste//------------------------------------------------------------------ 274254721Semaste// Stream the NULL terminated C string out to this stream. 275254721Semaste//------------------------------------------------------------------ 276254721SemasteStream& 277254721SemasteStream::operator<< (const char *s) 278254721Semaste{ 279254721Semaste Printf ("%s", s); 280254721Semaste return *this; 281254721Semaste} 282254721Semaste 283254721Semaste//------------------------------------------------------------------ 284254721Semaste// Stream the pointer value out to this stream. 285254721Semaste//------------------------------------------------------------------ 286254721SemasteStream& 287254721SemasteStream::operator<< (void *p) 288254721Semaste{ 289254721Semaste Printf ("0x%.*tx", (int)sizeof(void*) * 2, (ptrdiff_t)p); 290254721Semaste return *this; 291254721Semaste} 292254721Semaste 293254721Semaste//------------------------------------------------------------------ 294254721Semaste// Stream a uint8_t "uval" out to this stream. 295254721Semaste//------------------------------------------------------------------ 296254721SemasteStream& 297254721SemasteStream::operator<< (uint8_t uval) 298254721Semaste{ 299254721Semaste PutHex8(uval); 300254721Semaste return *this; 301254721Semaste} 302254721Semaste 303254721Semaste//------------------------------------------------------------------ 304254721Semaste// Stream a uint16_t "uval" out to this stream. 305254721Semaste//------------------------------------------------------------------ 306254721SemasteStream& 307254721SemasteStream::operator<< (uint16_t uval) 308254721Semaste{ 309254721Semaste PutHex16(uval, m_byte_order); 310254721Semaste return *this; 311254721Semaste} 312254721Semaste 313254721Semaste//------------------------------------------------------------------ 314254721Semaste// Stream a uint32_t "uval" out to this stream. 315254721Semaste//------------------------------------------------------------------ 316254721SemasteStream& 317254721SemasteStream::operator<< (uint32_t uval) 318254721Semaste{ 319254721Semaste PutHex32(uval, m_byte_order); 320254721Semaste return *this; 321254721Semaste} 322254721Semaste 323254721Semaste//------------------------------------------------------------------ 324254721Semaste// Stream a uint64_t "uval" out to this stream. 325254721Semaste//------------------------------------------------------------------ 326254721SemasteStream& 327254721SemasteStream::operator<< (uint64_t uval) 328254721Semaste{ 329254721Semaste PutHex64(uval, m_byte_order); 330254721Semaste return *this; 331254721Semaste} 332254721Semaste 333254721Semaste//------------------------------------------------------------------ 334254721Semaste// Stream a int8_t "sval" out to this stream. 335254721Semaste//------------------------------------------------------------------ 336254721SemasteStream& 337254721SemasteStream::operator<< (int8_t sval) 338254721Semaste{ 339254721Semaste Printf ("%i", (int)sval); 340254721Semaste return *this; 341254721Semaste} 342254721Semaste 343254721Semaste//------------------------------------------------------------------ 344254721Semaste// Stream a int16_t "sval" out to this stream. 345254721Semaste//------------------------------------------------------------------ 346254721SemasteStream& 347254721SemasteStream::operator<< (int16_t sval) 348254721Semaste{ 349254721Semaste Printf ("%i", (int)sval); 350254721Semaste return *this; 351254721Semaste} 352254721Semaste 353254721Semaste//------------------------------------------------------------------ 354254721Semaste// Stream a int32_t "sval" out to this stream. 355254721Semaste//------------------------------------------------------------------ 356254721SemasteStream& 357254721SemasteStream::operator<< (int32_t sval) 358254721Semaste{ 359254721Semaste Printf ("%i", (int)sval); 360254721Semaste return *this; 361254721Semaste} 362254721Semaste 363254721Semaste//------------------------------------------------------------------ 364254721Semaste// Stream a int64_t "sval" out to this stream. 365254721Semaste//------------------------------------------------------------------ 366254721SemasteStream& 367254721SemasteStream::operator<< (int64_t sval) 368254721Semaste{ 369254721Semaste Printf ("%" PRIi64, sval); 370254721Semaste return *this; 371254721Semaste} 372254721Semaste 373254721Semaste//------------------------------------------------------------------ 374254721Semaste// Get the current indentation level 375254721Semaste//------------------------------------------------------------------ 376254721Semasteint 377254721SemasteStream::GetIndentLevel() const 378254721Semaste{ 379254721Semaste return m_indent_level; 380254721Semaste} 381254721Semaste 382254721Semaste//------------------------------------------------------------------ 383254721Semaste// Set the current indentation level 384254721Semaste//------------------------------------------------------------------ 385254721Semastevoid 386254721SemasteStream::SetIndentLevel(int indent_level) 387254721Semaste{ 388254721Semaste m_indent_level = indent_level; 389254721Semaste} 390254721Semaste 391254721Semaste//------------------------------------------------------------------ 392254721Semaste// Increment the current indentation level 393254721Semaste//------------------------------------------------------------------ 394254721Semastevoid 395254721SemasteStream::IndentMore(int amount) 396254721Semaste{ 397254721Semaste m_indent_level += amount; 398254721Semaste} 399254721Semaste 400254721Semaste//------------------------------------------------------------------ 401254721Semaste// Decrement the current indentation level 402254721Semaste//------------------------------------------------------------------ 403254721Semastevoid 404254721SemasteStream::IndentLess (int amount) 405254721Semaste{ 406254721Semaste if (m_indent_level >= amount) 407254721Semaste m_indent_level -= amount; 408254721Semaste else 409254721Semaste m_indent_level = 0; 410254721Semaste} 411254721Semaste 412254721Semaste//------------------------------------------------------------------ 413254721Semaste// Get the address size in bytes 414254721Semaste//------------------------------------------------------------------ 415254721Semasteuint32_t 416254721SemasteStream::GetAddressByteSize() const 417254721Semaste{ 418254721Semaste return m_addr_size; 419254721Semaste} 420254721Semaste 421254721Semaste//------------------------------------------------------------------ 422254721Semaste// Set the address size in bytes 423254721Semaste//------------------------------------------------------------------ 424254721Semastevoid 425254721SemasteStream::SetAddressByteSize(uint32_t addr_size) 426254721Semaste{ 427254721Semaste m_addr_size = addr_size; 428254721Semaste} 429254721Semaste 430254721Semaste//------------------------------------------------------------------ 431254721Semaste// Returns true if the verbose flag bit is set in this stream. 432254721Semaste//------------------------------------------------------------------ 433254721Semastebool 434254721SemasteStream::GetVerbose() const 435254721Semaste{ 436254721Semaste return m_flags.Test(eVerbose); 437254721Semaste} 438254721Semaste 439254721Semaste//------------------------------------------------------------------ 440254721Semaste// Returns true if the debug flag bit is set in this stream. 441254721Semaste//------------------------------------------------------------------ 442254721Semastebool 443254721SemasteStream::GetDebug() const 444254721Semaste{ 445254721Semaste return m_flags.Test(eDebug); 446254721Semaste} 447254721Semaste 448254721Semaste//------------------------------------------------------------------ 449254721Semaste// The flags get accessor 450254721Semaste//------------------------------------------------------------------ 451254721SemasteFlags& 452254721SemasteStream::GetFlags() 453254721Semaste{ 454254721Semaste return m_flags; 455254721Semaste} 456254721Semaste 457254721Semaste//------------------------------------------------------------------ 458254721Semaste// The flags const get accessor 459254721Semaste//------------------------------------------------------------------ 460254721Semasteconst Flags& 461254721SemasteStream::GetFlags() const 462254721Semaste{ 463254721Semaste return m_flags; 464254721Semaste} 465254721Semaste 466254721Semaste//------------------------------------------------------------------ 467254721Semaste// The byte order get accessor 468254721Semaste//------------------------------------------------------------------ 469254721Semaste 470254721Semastelldb::ByteOrder 471254721SemasteStream::GetByteOrder() const 472254721Semaste{ 473254721Semaste return m_byte_order; 474254721Semaste} 475254721Semaste 476254721Semastesize_t 477254721SemasteStream::PrintfAsRawHex8 (const char *format, ...) 478254721Semaste{ 479254721Semaste va_list args; 480254721Semaste va_list args_copy; 481254721Semaste va_start (args, format); 482254721Semaste va_copy (args, args_copy); // Copy this so we 483254721Semaste 484254721Semaste char str[1024]; 485254721Semaste size_t bytes_written = 0; 486254721Semaste // Try and format our string into a fixed buffer first and see if it fits 487254721Semaste size_t length = ::vsnprintf (str, sizeof(str), format, args); 488254721Semaste if (length < sizeof(str)) 489254721Semaste { 490254721Semaste // The formatted string fit into our stack based buffer, so we can just 491254721Semaste // append that to our packet 492254721Semaste for (size_t i=0; i<length; ++i) 493254721Semaste bytes_written += _PutHex8 (str[i], false); 494254721Semaste } 495254721Semaste else 496254721Semaste { 497254721Semaste // Our stack buffer wasn't big enough to contain the entire formatted 498254721Semaste // string, so lets let vasprintf create the string for us! 499254721Semaste char *str_ptr = NULL; 500254721Semaste length = ::vasprintf (&str_ptr, format, args_copy); 501254721Semaste if (str_ptr) 502254721Semaste { 503254721Semaste for (size_t i=0; i<length; ++i) 504254721Semaste bytes_written += _PutHex8 (str_ptr[i], false); 505254721Semaste ::free (str_ptr); 506254721Semaste } 507254721Semaste } 508254721Semaste va_end (args); 509254721Semaste va_end (args_copy); 510254721Semaste 511254721Semaste return bytes_written; 512254721Semaste} 513254721Semaste 514254721Semastesize_t 515254721SemasteStream::PutNHex8 (size_t n, uint8_t uvalue) 516254721Semaste{ 517254721Semaste size_t bytes_written = 0; 518254721Semaste for (size_t i=0; i<n; ++i) 519254721Semaste bytes_written += _PutHex8 (uvalue, m_flags.Test(eAddPrefix)); 520254721Semaste return bytes_written; 521254721Semaste} 522254721Semaste 523254721Semastesize_t 524254721SemasteStream::_PutHex8 (uint8_t uvalue, bool add_prefix) 525254721Semaste{ 526254721Semaste size_t bytes_written = 0; 527254721Semaste if (m_flags.Test(eBinary)) 528254721Semaste { 529254721Semaste bytes_written = Write (&uvalue, 1); 530254721Semaste } 531254721Semaste else 532254721Semaste { 533254721Semaste if (add_prefix) 534254721Semaste PutCString("0x"); 535254721Semaste 536254721Semaste static char g_hex_to_ascii_hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 537254721Semaste char nibble_chars[2]; 538254721Semaste nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf]; 539254721Semaste nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf]; 540254721Semaste bytes_written = Write (nibble_chars, sizeof(nibble_chars)); 541254721Semaste } 542254721Semaste return bytes_written; 543254721Semaste} 544254721Semaste 545254721Semastesize_t 546254721SemasteStream::PutHex8 (uint8_t uvalue) 547254721Semaste{ 548254721Semaste return _PutHex8 (uvalue, m_flags.Test(eAddPrefix)); 549254721Semaste} 550254721Semaste 551254721Semastesize_t 552254721SemasteStream::PutHex16 (uint16_t uvalue, ByteOrder byte_order) 553254721Semaste{ 554254721Semaste if (byte_order == eByteOrderInvalid) 555254721Semaste byte_order = m_byte_order; 556254721Semaste 557254721Semaste bool add_prefix = m_flags.Test(eAddPrefix); 558254721Semaste size_t bytes_written = 0; 559254721Semaste if (byte_order == eByteOrderLittle) 560254721Semaste { 561254721Semaste for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) 562254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 563254721Semaste } 564254721Semaste else 565254721Semaste { 566254721Semaste for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false) 567254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 568254721Semaste } 569254721Semaste return bytes_written; 570254721Semaste} 571254721Semaste 572254721Semastesize_t 573254721SemasteStream::PutHex32(uint32_t uvalue, ByteOrder byte_order) 574254721Semaste{ 575254721Semaste if (byte_order == eByteOrderInvalid) 576254721Semaste byte_order = m_byte_order; 577254721Semaste 578254721Semaste bool add_prefix = m_flags.Test(eAddPrefix); 579254721Semaste size_t bytes_written = 0; 580254721Semaste if (byte_order == eByteOrderLittle) 581254721Semaste { 582254721Semaste for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) 583254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 584254721Semaste } 585254721Semaste else 586254721Semaste { 587254721Semaste for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false) 588254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 589254721Semaste } 590254721Semaste return bytes_written; 591254721Semaste} 592254721Semaste 593254721Semastesize_t 594254721SemasteStream::PutHex64(uint64_t uvalue, ByteOrder byte_order) 595254721Semaste{ 596254721Semaste if (byte_order == eByteOrderInvalid) 597254721Semaste byte_order = m_byte_order; 598254721Semaste 599254721Semaste bool add_prefix = m_flags.Test(eAddPrefix); 600254721Semaste size_t bytes_written = 0; 601254721Semaste if (byte_order == eByteOrderLittle) 602254721Semaste { 603254721Semaste for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) 604254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 605254721Semaste } 606254721Semaste else 607254721Semaste { 608254721Semaste for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false) 609254721Semaste bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix); 610254721Semaste } 611254721Semaste return bytes_written; 612254721Semaste} 613254721Semaste 614254721Semastesize_t 615254721SemasteStream::PutMaxHex64 616254721Semaste( 617254721Semaste uint64_t uvalue, 618254721Semaste size_t byte_size, 619254721Semaste lldb::ByteOrder byte_order 620254721Semaste) 621254721Semaste{ 622254721Semaste switch (byte_size) 623254721Semaste { 624254721Semaste case 1: return PutHex8 ((uint8_t)uvalue); 625254721Semaste case 2: return PutHex16 ((uint16_t)uvalue); 626254721Semaste case 4: return PutHex32 ((uint32_t)uvalue); 627254721Semaste case 8: return PutHex64 (uvalue); 628254721Semaste } 629254721Semaste return 0; 630254721Semaste} 631254721Semaste 632254721Semastesize_t 633254721SemasteStream::PutPointer (void *ptr) 634254721Semaste{ 635254721Semaste return PutRawBytes (&ptr, sizeof(ptr), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); 636254721Semaste} 637254721Semaste 638254721Semastesize_t 639254721SemasteStream::PutFloat(float f, ByteOrder byte_order) 640254721Semaste{ 641254721Semaste if (byte_order == eByteOrderInvalid) 642254721Semaste byte_order = m_byte_order; 643254721Semaste 644254721Semaste return PutRawBytes (&f, sizeof(f), lldb::endian::InlHostByteOrder(), byte_order); 645254721Semaste} 646254721Semaste 647254721Semastesize_t 648254721SemasteStream::PutDouble(double d, ByteOrder byte_order) 649254721Semaste{ 650254721Semaste if (byte_order == eByteOrderInvalid) 651254721Semaste byte_order = m_byte_order; 652254721Semaste 653254721Semaste return PutRawBytes (&d, sizeof(d), lldb::endian::InlHostByteOrder(), byte_order); 654254721Semaste} 655254721Semaste 656254721Semastesize_t 657254721SemasteStream::PutLongDouble(long double ld, ByteOrder byte_order) 658254721Semaste{ 659254721Semaste if (byte_order == eByteOrderInvalid) 660254721Semaste byte_order = m_byte_order; 661254721Semaste 662254721Semaste return PutRawBytes (&ld, sizeof(ld), lldb::endian::InlHostByteOrder(), byte_order); 663254721Semaste} 664254721Semaste 665254721Semastesize_t 666254721SemasteStream::PutRawBytes (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order) 667254721Semaste{ 668254721Semaste if (src_byte_order == eByteOrderInvalid) 669254721Semaste src_byte_order = m_byte_order; 670254721Semaste 671254721Semaste if (dst_byte_order == eByteOrderInvalid) 672254721Semaste dst_byte_order = m_byte_order; 673254721Semaste 674254721Semaste size_t bytes_written = 0; 675254721Semaste const uint8_t *src = (const uint8_t *)s; 676254721Semaste bool binary_was_set = m_flags.Test (eBinary); 677254721Semaste if (!binary_was_set) 678254721Semaste m_flags.Set (eBinary); 679254721Semaste if (src_byte_order == dst_byte_order) 680254721Semaste { 681254721Semaste for (size_t i = 0; i < src_len; ++i) 682254721Semaste bytes_written += _PutHex8 (src[i], false); 683254721Semaste } 684254721Semaste else 685254721Semaste { 686254721Semaste for (size_t i = src_len-1; i < src_len; --i) 687254721Semaste bytes_written += _PutHex8 (src[i], false); 688254721Semaste } 689254721Semaste if (!binary_was_set) 690254721Semaste m_flags.Clear (eBinary); 691254721Semaste 692254721Semaste return bytes_written; 693254721Semaste} 694254721Semaste 695254721Semastesize_t 696254721SemasteStream::PutBytesAsRawHex8 (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order) 697254721Semaste{ 698254721Semaste if (src_byte_order == eByteOrderInvalid) 699254721Semaste src_byte_order = m_byte_order; 700254721Semaste 701254721Semaste if (dst_byte_order == eByteOrderInvalid) 702254721Semaste dst_byte_order = m_byte_order; 703254721Semaste 704254721Semaste size_t bytes_written = 0; 705254721Semaste const uint8_t *src = (const uint8_t *)s; 706254721Semaste bool binary_is_set = m_flags.Test(eBinary); 707254721Semaste m_flags.Clear(eBinary); 708254721Semaste if (src_byte_order == dst_byte_order) 709254721Semaste { 710254721Semaste for (size_t i = 0; i < src_len; ++i) 711254721Semaste bytes_written += _PutHex8 (src[i], false); 712254721Semaste } 713254721Semaste else 714254721Semaste { 715254721Semaste for (size_t i = src_len-1; i < src_len; --i) 716254721Semaste bytes_written += _PutHex8 (src[i], false); 717254721Semaste } 718254721Semaste if (binary_is_set) 719254721Semaste m_flags.Set(eBinary); 720254721Semaste 721254721Semaste return bytes_written; 722254721Semaste} 723254721Semaste 724254721Semastesize_t 725254721SemasteStream::PutCStringAsRawHex8 (const char *s) 726254721Semaste{ 727254721Semaste size_t bytes_written = 0; 728254721Semaste bool binary_is_set = m_flags.Test(eBinary); 729254721Semaste m_flags.Clear(eBinary); 730254721Semaste do 731254721Semaste { 732254721Semaste bytes_written += _PutHex8 (*s, false); 733254721Semaste ++s; 734254721Semaste } while (*s); 735254721Semaste if (binary_is_set) 736254721Semaste m_flags.Set(eBinary); 737254721Semaste return bytes_written; 738254721Semaste} 739254721Semaste 740254721Semastevoid 741254721SemasteStream::UnitTest(Stream *s) 742254721Semaste{ 743254721Semaste s->PutHex8(0x12); 744254721Semaste 745254721Semaste s->PutChar(' '); 746254721Semaste s->PutHex16(0x3456, lldb::endian::InlHostByteOrder()); 747254721Semaste s->PutChar(' '); 748254721Semaste s->PutHex16(0x3456, eByteOrderBig); 749254721Semaste s->PutChar(' '); 750254721Semaste s->PutHex16(0x3456, eByteOrderLittle); 751254721Semaste 752254721Semaste s->PutChar(' '); 753254721Semaste s->PutHex32(0x789abcde, lldb::endian::InlHostByteOrder()); 754254721Semaste s->PutChar(' '); 755254721Semaste s->PutHex32(0x789abcde, eByteOrderBig); 756254721Semaste s->PutChar(' '); 757254721Semaste s->PutHex32(0x789abcde, eByteOrderLittle); 758254721Semaste 759254721Semaste s->PutChar(' '); 760254721Semaste s->PutHex64(0x1122334455667788ull, lldb::endian::InlHostByteOrder()); 761254721Semaste s->PutChar(' '); 762254721Semaste s->PutHex64(0x1122334455667788ull, eByteOrderBig); 763254721Semaste s->PutChar(' '); 764254721Semaste s->PutHex64(0x1122334455667788ull, eByteOrderLittle); 765254721Semaste 766254721Semaste const char *hola = "Hello World!!!"; 767254721Semaste s->PutChar(' '); 768254721Semaste s->PutCString (hola); 769254721Semaste 770254721Semaste s->PutChar(' '); 771254721Semaste s->Write (hola, 5); 772254721Semaste 773254721Semaste s->PutChar(' '); 774254721Semaste s->PutCStringAsRawHex8 (hola); 775254721Semaste 776254721Semaste s->PutChar(' '); 777254721Semaste s->PutCStringAsRawHex8 ("01234"); 778254721Semaste 779254721Semaste s->PutChar(' '); 780254721Semaste s->Printf ("pid=%i", 12733); 781254721Semaste 782254721Semaste s->PutChar(' '); 783254721Semaste s->PrintfAsRawHex8 ("pid=%i", 12733); 784254721Semaste s->PutChar('\n'); 785254721Semaste} 786254721Semaste 787