/source/Core/Stream.cpp

https://gitlab.com/jorjpimm/lldb · C++ · 786 lines · 561 code · 90 blank · 135 comment · 79 complexity · f0d8c221cb31032e51aa9dcac227a5de MD5 · raw file

  1. //===-- 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. #include "lldb/Core/Stream.h"
  10. #include "lldb/Host/Endian.h"
  11. #include <stddef.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <inttypes.h>
  16. using namespace lldb;
  17. using namespace lldb_private;
  18. Stream::Stream (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
  19. m_flags (flags),
  20. m_addr_size (addr_size),
  21. m_byte_order (byte_order),
  22. m_indent_level(0)
  23. {
  24. }
  25. Stream::Stream () :
  26. m_flags (0),
  27. m_addr_size (4),
  28. m_byte_order (lldb::endian::InlHostByteOrder()),
  29. m_indent_level(0)
  30. {
  31. }
  32. //------------------------------------------------------------------
  33. // Destructor
  34. //------------------------------------------------------------------
  35. Stream::~Stream ()
  36. {
  37. }
  38. ByteOrder
  39. Stream::SetByteOrder (ByteOrder byte_order)
  40. {
  41. ByteOrder old_byte_order = m_byte_order;
  42. m_byte_order = byte_order;
  43. return old_byte_order;
  44. }
  45. //------------------------------------------------------------------
  46. // Put an offset "uval" out to the stream using the printf format
  47. // in "format".
  48. //------------------------------------------------------------------
  49. void
  50. Stream::Offset (uint32_t uval, const char *format)
  51. {
  52. Printf (format, uval);
  53. }
  54. //------------------------------------------------------------------
  55. // Put an SLEB128 "uval" out to the stream using the printf format
  56. // in "format".
  57. //------------------------------------------------------------------
  58. size_t
  59. Stream::PutSLEB128 (int64_t sval)
  60. {
  61. size_t bytes_written = 0;
  62. if (m_flags.Test(eBinary))
  63. {
  64. bool more = true;
  65. while (more)
  66. {
  67. uint8_t byte = sval & 0x7fu;
  68. sval >>= 7;
  69. /* sign bit of byte is 2nd high order bit (0x40) */
  70. if ((sval == 0 && !(byte & 0x40)) ||
  71. (sval == -1 && (byte & 0x40)) )
  72. more = false;
  73. else
  74. // more bytes to come
  75. byte |= 0x80u;
  76. bytes_written += Write(&byte, 1);
  77. }
  78. }
  79. else
  80. {
  81. bytes_written = Printf ("0x%" PRIi64, sval);
  82. }
  83. return bytes_written;
  84. }
  85. //------------------------------------------------------------------
  86. // Put an ULEB128 "uval" out to the stream using the printf format
  87. // in "format".
  88. //------------------------------------------------------------------
  89. size_t
  90. Stream::PutULEB128 (uint64_t uval)
  91. {
  92. size_t bytes_written = 0;
  93. if (m_flags.Test(eBinary))
  94. {
  95. do
  96. {
  97. uint8_t byte = uval & 0x7fu;
  98. uval >>= 7;
  99. if (uval != 0)
  100. {
  101. // more bytes to come
  102. byte |= 0x80u;
  103. }
  104. bytes_written += Write(&byte, 1);
  105. } while (uval != 0);
  106. }
  107. else
  108. {
  109. bytes_written = Printf ("0x%" PRIx64, uval);
  110. }
  111. return bytes_written;
  112. }
  113. //------------------------------------------------------------------
  114. // Print a raw NULL terminated C string to the stream.
  115. //------------------------------------------------------------------
  116. size_t
  117. Stream::PutCString (const char *cstr)
  118. {
  119. size_t cstr_len = strlen(cstr);
  120. // when in binary mode, emit the NULL terminator
  121. if (m_flags.Test(eBinary))
  122. ++cstr_len;
  123. return Write (cstr, cstr_len);
  124. }
  125. //------------------------------------------------------------------
  126. // Print a double quoted NULL terminated C string to the stream
  127. // using the printf format in "format".
  128. //------------------------------------------------------------------
  129. void
  130. Stream::QuotedCString (const char *cstr, const char *format)
  131. {
  132. Printf (format, cstr);
  133. }
  134. //------------------------------------------------------------------
  135. // Put an address "addr" out to the stream with optional prefix
  136. // and suffix strings.
  137. //------------------------------------------------------------------
  138. void
  139. Stream::Address (uint64_t addr, uint32_t addr_size, const char *prefix, const char *suffix)
  140. {
  141. if (prefix == NULL)
  142. prefix = "";
  143. if (suffix == NULL)
  144. suffix = "";
  145. // int addr_width = m_addr_size << 1;
  146. // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
  147. Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
  148. }
  149. //------------------------------------------------------------------
  150. // Put an address range out to the stream with optional prefix
  151. // and suffix strings.
  152. //------------------------------------------------------------------
  153. void
  154. Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix, const char *suffix)
  155. {
  156. if (prefix && prefix[0])
  157. PutCString (prefix);
  158. Address (lo_addr, addr_size, "[");
  159. Address (hi_addr, addr_size, "-", ")");
  160. if (suffix && suffix[0])
  161. PutCString (suffix);
  162. }
  163. size_t
  164. Stream::PutChar (char ch)
  165. {
  166. return Write (&ch, 1);
  167. }
  168. //------------------------------------------------------------------
  169. // Print some formatted output to the stream.
  170. //------------------------------------------------------------------
  171. size_t
  172. Stream::Printf (const char *format, ...)
  173. {
  174. va_list args;
  175. va_start (args, format);
  176. size_t result = PrintfVarArg(format, args);
  177. va_end (args);
  178. return result;
  179. }
  180. //------------------------------------------------------------------
  181. // Print some formatted output to the stream.
  182. //------------------------------------------------------------------
  183. size_t
  184. Stream::PrintfVarArg (const char *format, va_list args)
  185. {
  186. char str[1024];
  187. va_list args_copy;
  188. va_copy (args_copy, args);
  189. size_t bytes_written = 0;
  190. // Try and format our string into a fixed buffer first and see if it fits
  191. size_t length = ::vsnprintf (str, sizeof(str), format, args);
  192. if (length < sizeof(str))
  193. {
  194. // Include the NULL termination byte for binary output
  195. if (m_flags.Test(eBinary))
  196. length += 1;
  197. // The formatted string fit into our stack based buffer, so we can just
  198. // append that to our packet
  199. bytes_written = Write (str, length);
  200. }
  201. else
  202. {
  203. // Our stack buffer wasn't big enough to contain the entire formatted
  204. // string, so lets let vasprintf create the string for us!
  205. char *str_ptr = NULL;
  206. length = ::vasprintf (&str_ptr, format, args_copy);
  207. if (str_ptr)
  208. {
  209. // Include the NULL termination byte for binary output
  210. if (m_flags.Test(eBinary))
  211. length += 1;
  212. bytes_written = Write (str_ptr, length);
  213. ::free (str_ptr);
  214. }
  215. }
  216. va_end (args_copy);
  217. return bytes_written;
  218. }
  219. //------------------------------------------------------------------
  220. // Print and End of Line character to the stream
  221. //------------------------------------------------------------------
  222. size_t
  223. Stream::EOL()
  224. {
  225. return PutChar ('\n');
  226. }
  227. //------------------------------------------------------------------
  228. // Indent the current line using the current indentation level and
  229. // print an optional string following the indentation spaces.
  230. //------------------------------------------------------------------
  231. size_t
  232. Stream::Indent(const char *s)
  233. {
  234. return Printf ("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
  235. }
  236. //------------------------------------------------------------------
  237. // Stream a character "ch" out to this stream.
  238. //------------------------------------------------------------------
  239. Stream&
  240. Stream::operator<< (char ch)
  241. {
  242. PutChar (ch);
  243. return *this;
  244. }
  245. //------------------------------------------------------------------
  246. // Stream the NULL terminated C string out to this stream.
  247. //------------------------------------------------------------------
  248. Stream&
  249. Stream::operator<< (const char *s)
  250. {
  251. Printf ("%s", s);
  252. return *this;
  253. }
  254. //------------------------------------------------------------------
  255. // Stream the pointer value out to this stream.
  256. //------------------------------------------------------------------
  257. Stream&
  258. Stream::operator<< (void *p)
  259. {
  260. Printf ("0x%.*tx", (int)sizeof(void*) * 2, (ptrdiff_t)p);
  261. return *this;
  262. }
  263. //------------------------------------------------------------------
  264. // Stream a uint8_t "uval" out to this stream.
  265. //------------------------------------------------------------------
  266. Stream&
  267. Stream::operator<< (uint8_t uval)
  268. {
  269. PutHex8(uval);
  270. return *this;
  271. }
  272. //------------------------------------------------------------------
  273. // Stream a uint16_t "uval" out to this stream.
  274. //------------------------------------------------------------------
  275. Stream&
  276. Stream::operator<< (uint16_t uval)
  277. {
  278. PutHex16(uval, m_byte_order);
  279. return *this;
  280. }
  281. //------------------------------------------------------------------
  282. // Stream a uint32_t "uval" out to this stream.
  283. //------------------------------------------------------------------
  284. Stream&
  285. Stream::operator<< (uint32_t uval)
  286. {
  287. PutHex32(uval, m_byte_order);
  288. return *this;
  289. }
  290. //------------------------------------------------------------------
  291. // Stream a uint64_t "uval" out to this stream.
  292. //------------------------------------------------------------------
  293. Stream&
  294. Stream::operator<< (uint64_t uval)
  295. {
  296. PutHex64(uval, m_byte_order);
  297. return *this;
  298. }
  299. //------------------------------------------------------------------
  300. // Stream a int8_t "sval" out to this stream.
  301. //------------------------------------------------------------------
  302. Stream&
  303. Stream::operator<< (int8_t sval)
  304. {
  305. Printf ("%i", (int)sval);
  306. return *this;
  307. }
  308. //------------------------------------------------------------------
  309. // Stream a int16_t "sval" out to this stream.
  310. //------------------------------------------------------------------
  311. Stream&
  312. Stream::operator<< (int16_t sval)
  313. {
  314. Printf ("%i", (int)sval);
  315. return *this;
  316. }
  317. //------------------------------------------------------------------
  318. // Stream a int32_t "sval" out to this stream.
  319. //------------------------------------------------------------------
  320. Stream&
  321. Stream::operator<< (int32_t sval)
  322. {
  323. Printf ("%i", (int)sval);
  324. return *this;
  325. }
  326. //------------------------------------------------------------------
  327. // Stream a int64_t "sval" out to this stream.
  328. //------------------------------------------------------------------
  329. Stream&
  330. Stream::operator<< (int64_t sval)
  331. {
  332. Printf ("%" PRIi64, sval);
  333. return *this;
  334. }
  335. //------------------------------------------------------------------
  336. // Get the current indentation level
  337. //------------------------------------------------------------------
  338. int
  339. Stream::GetIndentLevel() const
  340. {
  341. return m_indent_level;
  342. }
  343. //------------------------------------------------------------------
  344. // Set the current indentation level
  345. //------------------------------------------------------------------
  346. void
  347. Stream::SetIndentLevel(int indent_level)
  348. {
  349. m_indent_level = indent_level;
  350. }
  351. //------------------------------------------------------------------
  352. // Increment the current indentation level
  353. //------------------------------------------------------------------
  354. void
  355. Stream::IndentMore(int amount)
  356. {
  357. m_indent_level += amount;
  358. }
  359. //------------------------------------------------------------------
  360. // Decrement the current indentation level
  361. //------------------------------------------------------------------
  362. void
  363. Stream::IndentLess (int amount)
  364. {
  365. if (m_indent_level >= amount)
  366. m_indent_level -= amount;
  367. else
  368. m_indent_level = 0;
  369. }
  370. //------------------------------------------------------------------
  371. // Get the address size in bytes
  372. //------------------------------------------------------------------
  373. uint32_t
  374. Stream::GetAddressByteSize() const
  375. {
  376. return m_addr_size;
  377. }
  378. //------------------------------------------------------------------
  379. // Set the address size in bytes
  380. //------------------------------------------------------------------
  381. void
  382. Stream::SetAddressByteSize(uint32_t addr_size)
  383. {
  384. m_addr_size = addr_size;
  385. }
  386. //------------------------------------------------------------------
  387. // Returns true if the verbose flag bit is set in this stream.
  388. //------------------------------------------------------------------
  389. bool
  390. Stream::GetVerbose() const
  391. {
  392. return m_flags.Test(eVerbose);
  393. }
  394. //------------------------------------------------------------------
  395. // Returns true if the debug flag bit is set in this stream.
  396. //------------------------------------------------------------------
  397. bool
  398. Stream::GetDebug() const
  399. {
  400. return m_flags.Test(eDebug);
  401. }
  402. //------------------------------------------------------------------
  403. // The flags get accessor
  404. //------------------------------------------------------------------
  405. Flags&
  406. Stream::GetFlags()
  407. {
  408. return m_flags;
  409. }
  410. //------------------------------------------------------------------
  411. // The flags const get accessor
  412. //------------------------------------------------------------------
  413. const Flags&
  414. Stream::GetFlags() const
  415. {
  416. return m_flags;
  417. }
  418. //------------------------------------------------------------------
  419. // The byte order get accessor
  420. //------------------------------------------------------------------
  421. lldb::ByteOrder
  422. Stream::GetByteOrder() const
  423. {
  424. return m_byte_order;
  425. }
  426. size_t
  427. Stream::PrintfAsRawHex8 (const char *format, ...)
  428. {
  429. va_list args;
  430. va_list args_copy;
  431. va_start (args, format);
  432. va_copy (args_copy,args); // Copy this so we
  433. char str[1024];
  434. size_t bytes_written = 0;
  435. // Try and format our string into a fixed buffer first and see if it fits
  436. size_t length = ::vsnprintf (str, sizeof(str), format, args);
  437. if (length < sizeof(str))
  438. {
  439. // The formatted string fit into our stack based buffer, so we can just
  440. // append that to our packet
  441. for (size_t i=0; i<length; ++i)
  442. bytes_written += _PutHex8 (str[i], false);
  443. }
  444. else
  445. {
  446. // Our stack buffer wasn't big enough to contain the entire formatted
  447. // string, so lets let vasprintf create the string for us!
  448. char *str_ptr = NULL;
  449. length = ::vasprintf (&str_ptr, format, args_copy);
  450. if (str_ptr)
  451. {
  452. for (size_t i=0; i<length; ++i)
  453. bytes_written += _PutHex8 (str_ptr[i], false);
  454. ::free (str_ptr);
  455. }
  456. }
  457. va_end (args);
  458. va_end (args_copy);
  459. return bytes_written;
  460. }
  461. size_t
  462. Stream::PutNHex8 (size_t n, uint8_t uvalue)
  463. {
  464. size_t bytes_written = 0;
  465. for (size_t i=0; i<n; ++i)
  466. bytes_written += _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
  467. return bytes_written;
  468. }
  469. size_t
  470. Stream::_PutHex8 (uint8_t uvalue, bool add_prefix)
  471. {
  472. size_t bytes_written = 0;
  473. if (m_flags.Test(eBinary))
  474. {
  475. bytes_written = Write (&uvalue, 1);
  476. }
  477. else
  478. {
  479. if (add_prefix)
  480. PutCString("0x");
  481. 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' };
  482. char nibble_chars[2];
  483. nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
  484. nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
  485. bytes_written = Write (nibble_chars, sizeof(nibble_chars));
  486. }
  487. return bytes_written;
  488. }
  489. size_t
  490. Stream::PutHex8 (uint8_t uvalue)
  491. {
  492. return _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
  493. }
  494. size_t
  495. Stream::PutHex16 (uint16_t uvalue, ByteOrder byte_order)
  496. {
  497. if (byte_order == eByteOrderInvalid)
  498. byte_order = m_byte_order;
  499. bool add_prefix = m_flags.Test(eAddPrefix);
  500. size_t bytes_written = 0;
  501. if (byte_order == eByteOrderLittle)
  502. {
  503. for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
  504. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  505. }
  506. else
  507. {
  508. for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
  509. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  510. }
  511. return bytes_written;
  512. }
  513. size_t
  514. Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order)
  515. {
  516. if (byte_order == eByteOrderInvalid)
  517. byte_order = m_byte_order;
  518. bool add_prefix = m_flags.Test(eAddPrefix);
  519. size_t bytes_written = 0;
  520. if (byte_order == eByteOrderLittle)
  521. {
  522. for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
  523. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  524. }
  525. else
  526. {
  527. for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
  528. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  529. }
  530. return bytes_written;
  531. }
  532. size_t
  533. Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order)
  534. {
  535. if (byte_order == eByteOrderInvalid)
  536. byte_order = m_byte_order;
  537. bool add_prefix = m_flags.Test(eAddPrefix);
  538. size_t bytes_written = 0;
  539. if (byte_order == eByteOrderLittle)
  540. {
  541. for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
  542. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  543. }
  544. else
  545. {
  546. for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
  547. bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
  548. }
  549. return bytes_written;
  550. }
  551. size_t
  552. Stream::PutMaxHex64
  553. (
  554. uint64_t uvalue,
  555. size_t byte_size,
  556. lldb::ByteOrder byte_order
  557. )
  558. {
  559. switch (byte_size)
  560. {
  561. case 1: return PutHex8 ((uint8_t)uvalue);
  562. case 2: return PutHex16 ((uint16_t)uvalue);
  563. case 4: return PutHex32 ((uint32_t)uvalue);
  564. case 8: return PutHex64 (uvalue);
  565. }
  566. return 0;
  567. }
  568. size_t
  569. Stream::PutPointer (void *ptr)
  570. {
  571. return PutRawBytes (&ptr, sizeof(ptr), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
  572. }
  573. size_t
  574. Stream::PutFloat(float f, ByteOrder byte_order)
  575. {
  576. if (byte_order == eByteOrderInvalid)
  577. byte_order = m_byte_order;
  578. return PutRawBytes (&f, sizeof(f), lldb::endian::InlHostByteOrder(), byte_order);
  579. }
  580. size_t
  581. Stream::PutDouble(double d, ByteOrder byte_order)
  582. {
  583. if (byte_order == eByteOrderInvalid)
  584. byte_order = m_byte_order;
  585. return PutRawBytes (&d, sizeof(d), lldb::endian::InlHostByteOrder(), byte_order);
  586. }
  587. size_t
  588. Stream::PutLongDouble(long double ld, ByteOrder byte_order)
  589. {
  590. if (byte_order == eByteOrderInvalid)
  591. byte_order = m_byte_order;
  592. return PutRawBytes (&ld, sizeof(ld), lldb::endian::InlHostByteOrder(), byte_order);
  593. }
  594. size_t
  595. Stream::PutRawBytes (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
  596. {
  597. if (src_byte_order == eByteOrderInvalid)
  598. src_byte_order = m_byte_order;
  599. if (dst_byte_order == eByteOrderInvalid)
  600. dst_byte_order = m_byte_order;
  601. size_t bytes_written = 0;
  602. const uint8_t *src = (const uint8_t *)s;
  603. bool binary_was_set = m_flags.Test (eBinary);
  604. if (!binary_was_set)
  605. m_flags.Set (eBinary);
  606. if (src_byte_order == dst_byte_order)
  607. {
  608. for (size_t i = 0; i < src_len; ++i)
  609. bytes_written += _PutHex8 (src[i], false);
  610. }
  611. else
  612. {
  613. for (size_t i = src_len-1; i < src_len; --i)
  614. bytes_written += _PutHex8 (src[i], false);
  615. }
  616. if (!binary_was_set)
  617. m_flags.Clear (eBinary);
  618. return bytes_written;
  619. }
  620. size_t
  621. Stream::PutBytesAsRawHex8 (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
  622. {
  623. if (src_byte_order == eByteOrderInvalid)
  624. src_byte_order = m_byte_order;
  625. if (dst_byte_order == eByteOrderInvalid)
  626. dst_byte_order = m_byte_order;
  627. size_t bytes_written = 0;
  628. const uint8_t *src = (const uint8_t *)s;
  629. bool binary_is_set = m_flags.Test(eBinary);
  630. m_flags.Clear(eBinary);
  631. if (src_byte_order == dst_byte_order)
  632. {
  633. for (size_t i = 0; i < src_len; ++i)
  634. bytes_written += _PutHex8 (src[i], false);
  635. }
  636. else
  637. {
  638. for (size_t i = src_len-1; i < src_len; --i)
  639. bytes_written += _PutHex8 (src[i], false);
  640. }
  641. if (binary_is_set)
  642. m_flags.Set(eBinary);
  643. return bytes_written;
  644. }
  645. size_t
  646. Stream::PutCStringAsRawHex8 (const char *s)
  647. {
  648. size_t bytes_written = 0;
  649. bool binary_is_set = m_flags.Test(eBinary);
  650. m_flags.Clear(eBinary);
  651. do
  652. {
  653. bytes_written += _PutHex8 (*s, false);
  654. ++s;
  655. } while (*s);
  656. if (binary_is_set)
  657. m_flags.Set(eBinary);
  658. return bytes_written;
  659. }
  660. void
  661. Stream::UnitTest(Stream *s)
  662. {
  663. s->PutHex8(0x12);
  664. s->PutChar(' ');
  665. s->PutHex16(0x3456, lldb::endian::InlHostByteOrder());
  666. s->PutChar(' ');
  667. s->PutHex16(0x3456, eByteOrderBig);
  668. s->PutChar(' ');
  669. s->PutHex16(0x3456, eByteOrderLittle);
  670. s->PutChar(' ');
  671. s->PutHex32(0x789abcde, lldb::endian::InlHostByteOrder());
  672. s->PutChar(' ');
  673. s->PutHex32(0x789abcde, eByteOrderBig);
  674. s->PutChar(' ');
  675. s->PutHex32(0x789abcde, eByteOrderLittle);
  676. s->PutChar(' ');
  677. s->PutHex64(0x1122334455667788ull, lldb::endian::InlHostByteOrder());
  678. s->PutChar(' ');
  679. s->PutHex64(0x1122334455667788ull, eByteOrderBig);
  680. s->PutChar(' ');
  681. s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
  682. const char *hola = "Hello World!!!";
  683. s->PutChar(' ');
  684. s->PutCString (hola);
  685. s->PutChar(' ');
  686. s->Write (hola, 5);
  687. s->PutChar(' ');
  688. s->PutCStringAsRawHex8 (hola);
  689. s->PutChar(' ');
  690. s->PutCStringAsRawHex8 ("01234");
  691. s->PutChar(' ');
  692. s->Printf ("pid=%i", 12733);
  693. s->PutChar(' ');
  694. s->PrintfAsRawHex8 ("pid=%i", 12733);
  695. s->PutChar('\n');
  696. }