Stream.cpp revision 341825
1317027Sdim//===-- Stream.cpp ----------------------------------------------*- C++ -*-===//
2317027Sdim//
3317027Sdim//                     The LLVM Compiler Infrastructure
4317027Sdim//
5317027Sdim// This file is distributed under the University of Illinois Open Source
6317027Sdim// License. See LICENSE.TXT for details.
7317027Sdim//
8317027Sdim//===----------------------------------------------------------------------===//
9317027Sdim
10317027Sdim#include "lldb/Utility/Stream.h"
11317027Sdim
12317027Sdim#include "lldb/Utility/Endian.h"
13317027Sdim#include "lldb/Utility/VASPrintf.h"
14317027Sdim#include "llvm/ADT/SmallString.h" // for SmallString
15317027Sdim
16317027Sdim#include <string>
17317027Sdim
18317027Sdim#include <inttypes.h>
19317027Sdim#include <stddef.h>
20317027Sdim
21317027Sdimusing namespace lldb;
22317027Sdimusing namespace lldb_private;
23317027Sdim
24317027SdimStream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
25317027Sdim    : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
26317027Sdim      m_indent_level(0) {}
27317027Sdim
28317027SdimStream::Stream()
29317027Sdim    : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
30317027Sdim      m_indent_level(0) {}
31317027Sdim
32317027Sdim//------------------------------------------------------------------
33317027Sdim// Destructor
34317027Sdim//------------------------------------------------------------------
35317027SdimStream::~Stream() {}
36317027Sdim
37317027SdimByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
38317027Sdim  ByteOrder old_byte_order = m_byte_order;
39317027Sdim  m_byte_order = byte_order;
40317027Sdim  return old_byte_order;
41317027Sdim}
42317027Sdim
43317027Sdim//------------------------------------------------------------------
44341825Sdim// Put an offset "uval" out to the stream using the printf format in "format".
45317027Sdim//------------------------------------------------------------------
46317027Sdimvoid Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
47317027Sdim
48317027Sdim//------------------------------------------------------------------
49341825Sdim// Put an SLEB128 "uval" out to the stream using the printf format in "format".
50317027Sdim//------------------------------------------------------------------
51317027Sdimsize_t Stream::PutSLEB128(int64_t sval) {
52317027Sdim  size_t bytes_written = 0;
53317027Sdim  if (m_flags.Test(eBinary)) {
54317027Sdim    bool more = true;
55317027Sdim    while (more) {
56317027Sdim      uint8_t byte = sval & 0x7fu;
57317027Sdim      sval >>= 7;
58317027Sdim      /* sign bit of byte is 2nd high order bit (0x40) */
59317027Sdim      if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40)))
60317027Sdim        more = false;
61317027Sdim      else
62317027Sdim        // more bytes to come
63317027Sdim        byte |= 0x80u;
64317027Sdim      bytes_written += Write(&byte, 1);
65317027Sdim    }
66317027Sdim  } else {
67317027Sdim    bytes_written = Printf("0x%" PRIi64, sval);
68317027Sdim  }
69317027Sdim
70317027Sdim  return bytes_written;
71317027Sdim}
72317027Sdim
73317027Sdim//------------------------------------------------------------------
74341825Sdim// Put an ULEB128 "uval" out to the stream using the printf format in "format".
75317027Sdim//------------------------------------------------------------------
76317027Sdimsize_t Stream::PutULEB128(uint64_t uval) {
77317027Sdim  size_t bytes_written = 0;
78317027Sdim  if (m_flags.Test(eBinary)) {
79317027Sdim    do {
80317027Sdim
81317027Sdim      uint8_t byte = uval & 0x7fu;
82317027Sdim      uval >>= 7;
83317027Sdim      if (uval != 0) {
84317027Sdim        // more bytes to come
85317027Sdim        byte |= 0x80u;
86317027Sdim      }
87317027Sdim      bytes_written += Write(&byte, 1);
88317027Sdim    } while (uval != 0);
89317027Sdim  } else {
90317027Sdim    bytes_written = Printf("0x%" PRIx64, uval);
91317027Sdim  }
92317027Sdim  return bytes_written;
93317027Sdim}
94317027Sdim
95317027Sdim//------------------------------------------------------------------
96317027Sdim// Print a raw NULL terminated C string to the stream.
97317027Sdim//------------------------------------------------------------------
98317027Sdimsize_t Stream::PutCString(llvm::StringRef str) {
99317027Sdim  size_t bytes_written = 0;
100317027Sdim  bytes_written = Write(str.data(), str.size());
101317027Sdim
102317027Sdim  // when in binary mode, emit the NULL terminator
103317027Sdim  if (m_flags.Test(eBinary))
104317027Sdim    bytes_written += PutChar('\0');
105317027Sdim  return bytes_written;
106317027Sdim}
107317027Sdim
108317027Sdim//------------------------------------------------------------------
109341825Sdim// Print a double quoted NULL terminated C string to the stream using the
110341825Sdim// printf format in "format".
111317027Sdim//------------------------------------------------------------------
112317027Sdimvoid Stream::QuotedCString(const char *cstr, const char *format) {
113317027Sdim  Printf(format, cstr);
114317027Sdim}
115317027Sdim
116317027Sdim//------------------------------------------------------------------
117341825Sdim// Put an address "addr" out to the stream with optional prefix and suffix
118341825Sdim// strings.
119317027Sdim//------------------------------------------------------------------
120317027Sdimvoid Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
121317027Sdim                     const char *suffix) {
122317027Sdim  if (prefix == NULL)
123317027Sdim    prefix = "";
124317027Sdim  if (suffix == NULL)
125317027Sdim    suffix = "";
126317027Sdim  //    int addr_width = m_addr_size << 1;
127317027Sdim  //    Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
128317027Sdim  Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
129317027Sdim}
130317027Sdim
131317027Sdim//------------------------------------------------------------------
132341825Sdim// Put an address range out to the stream with optional prefix and suffix
133341825Sdim// strings.
134317027Sdim//------------------------------------------------------------------
135317027Sdimvoid Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
136317027Sdim                          uint32_t addr_size, const char *prefix,
137317027Sdim                          const char *suffix) {
138317027Sdim  if (prefix && prefix[0])
139317027Sdim    PutCString(prefix);
140317027Sdim  Address(lo_addr, addr_size, "[");
141317027Sdim  Address(hi_addr, addr_size, "-", ")");
142317027Sdim  if (suffix && suffix[0])
143317027Sdim    PutCString(suffix);
144317027Sdim}
145317027Sdim
146317027Sdimsize_t Stream::PutChar(char ch) { return Write(&ch, 1); }
147317027Sdim
148317027Sdim//------------------------------------------------------------------
149317027Sdim// Print some formatted output to the stream.
150317027Sdim//------------------------------------------------------------------
151317027Sdimsize_t Stream::Printf(const char *format, ...) {
152317027Sdim  va_list args;
153317027Sdim  va_start(args, format);
154317027Sdim  size_t result = PrintfVarArg(format, args);
155317027Sdim  va_end(args);
156317027Sdim  return result;
157317027Sdim}
158317027Sdim
159317027Sdim//------------------------------------------------------------------
160317027Sdim// Print some formatted output to the stream.
161317027Sdim//------------------------------------------------------------------
162317027Sdimsize_t Stream::PrintfVarArg(const char *format, va_list args) {
163317027Sdim  llvm::SmallString<1024> buf;
164317027Sdim  VASprintf(buf, format, args);
165317027Sdim
166317027Sdim  // Include the NULL termination byte for binary output
167317027Sdim  size_t length = buf.size();
168317027Sdim  if (m_flags.Test(eBinary))
169317027Sdim    ++length;
170317027Sdim  return Write(buf.c_str(), length);
171317027Sdim}
172317027Sdim
173317027Sdim//------------------------------------------------------------------
174317027Sdim// Print and End of Line character to the stream
175317027Sdim//------------------------------------------------------------------
176317027Sdimsize_t Stream::EOL() { return PutChar('\n'); }
177317027Sdim
178317027Sdim//------------------------------------------------------------------
179341825Sdim// Indent the current line using the current indentation level and print an
180341825Sdim// optional string following the indentation spaces.
181317027Sdim//------------------------------------------------------------------
182317027Sdimsize_t Stream::Indent(const char *s) {
183317027Sdim  return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
184317027Sdim}
185317027Sdim
186317027Sdimsize_t Stream::Indent(llvm::StringRef str) {
187317027Sdim  return Printf("%*.*s%s", m_indent_level, m_indent_level, "",
188317027Sdim                str.str().c_str());
189317027Sdim}
190317027Sdim
191317027Sdim//------------------------------------------------------------------
192317027Sdim// Stream a character "ch" out to this stream.
193317027Sdim//------------------------------------------------------------------
194317027SdimStream &Stream::operator<<(char ch) {
195317027Sdim  PutChar(ch);
196317027Sdim  return *this;
197317027Sdim}
198317027Sdim
199317027Sdim//------------------------------------------------------------------
200317027Sdim// Stream the NULL terminated C string out to this stream.
201317027Sdim//------------------------------------------------------------------
202317027SdimStream &Stream::operator<<(const char *s) {
203317027Sdim  Printf("%s", s);
204317027Sdim  return *this;
205317027Sdim}
206317027Sdim
207317027SdimStream &Stream::operator<<(llvm::StringRef str) {
208317027Sdim  Write(str.data(), str.size());
209317027Sdim  return *this;
210317027Sdim}
211317027Sdim
212317027Sdim//------------------------------------------------------------------
213317027Sdim// Stream the pointer value out to this stream.
214317027Sdim//------------------------------------------------------------------
215317027SdimStream &Stream::operator<<(const void *p) {
216317027Sdim  Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
217317027Sdim  return *this;
218317027Sdim}
219317027Sdim
220317027Sdim//------------------------------------------------------------------
221317027Sdim// Stream a uint8_t "uval" out to this stream.
222317027Sdim//------------------------------------------------------------------
223317027SdimStream &Stream::operator<<(uint8_t uval) {
224317027Sdim  PutHex8(uval);
225317027Sdim  return *this;
226317027Sdim}
227317027Sdim
228317027Sdim//------------------------------------------------------------------
229317027Sdim// Stream a uint16_t "uval" out to this stream.
230317027Sdim//------------------------------------------------------------------
231317027SdimStream &Stream::operator<<(uint16_t uval) {
232317027Sdim  PutHex16(uval, m_byte_order);
233317027Sdim  return *this;
234317027Sdim}
235317027Sdim
236317027Sdim//------------------------------------------------------------------
237317027Sdim// Stream a uint32_t "uval" out to this stream.
238317027Sdim//------------------------------------------------------------------
239317027SdimStream &Stream::operator<<(uint32_t uval) {
240317027Sdim  PutHex32(uval, m_byte_order);
241317027Sdim  return *this;
242317027Sdim}
243317027Sdim
244317027Sdim//------------------------------------------------------------------
245317027Sdim// Stream a uint64_t "uval" out to this stream.
246317027Sdim//------------------------------------------------------------------
247317027SdimStream &Stream::operator<<(uint64_t uval) {
248317027Sdim  PutHex64(uval, m_byte_order);
249317027Sdim  return *this;
250317027Sdim}
251317027Sdim
252317027Sdim//------------------------------------------------------------------
253317027Sdim// Stream a int8_t "sval" out to this stream.
254317027Sdim//------------------------------------------------------------------
255317027SdimStream &Stream::operator<<(int8_t sval) {
256317027Sdim  Printf("%i", (int)sval);
257317027Sdim  return *this;
258317027Sdim}
259317027Sdim
260317027Sdim//------------------------------------------------------------------
261317027Sdim// Stream a int16_t "sval" out to this stream.
262317027Sdim//------------------------------------------------------------------
263317027SdimStream &Stream::operator<<(int16_t sval) {
264317027Sdim  Printf("%i", (int)sval);
265317027Sdim  return *this;
266317027Sdim}
267317027Sdim
268317027Sdim//------------------------------------------------------------------
269317027Sdim// Stream a int32_t "sval" out to this stream.
270317027Sdim//------------------------------------------------------------------
271317027SdimStream &Stream::operator<<(int32_t sval) {
272317027Sdim  Printf("%i", (int)sval);
273317027Sdim  return *this;
274317027Sdim}
275317027Sdim
276317027Sdim//------------------------------------------------------------------
277317027Sdim// Stream a int64_t "sval" out to this stream.
278317027Sdim//------------------------------------------------------------------
279317027SdimStream &Stream::operator<<(int64_t sval) {
280317027Sdim  Printf("%" PRIi64, sval);
281317027Sdim  return *this;
282317027Sdim}
283317027Sdim
284317027Sdim//------------------------------------------------------------------
285317027Sdim// Get the current indentation level
286317027Sdim//------------------------------------------------------------------
287317027Sdimint Stream::GetIndentLevel() const { return m_indent_level; }
288317027Sdim
289317027Sdim//------------------------------------------------------------------
290317027Sdim// Set the current indentation level
291317027Sdim//------------------------------------------------------------------
292317027Sdimvoid Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
293317027Sdim
294317027Sdim//------------------------------------------------------------------
295317027Sdim// Increment the current indentation level
296317027Sdim//------------------------------------------------------------------
297317027Sdimvoid Stream::IndentMore(int amount) { m_indent_level += amount; }
298317027Sdim
299317027Sdim//------------------------------------------------------------------
300317027Sdim// Decrement the current indentation level
301317027Sdim//------------------------------------------------------------------
302317027Sdimvoid Stream::IndentLess(int amount) {
303317027Sdim  if (m_indent_level >= amount)
304317027Sdim    m_indent_level -= amount;
305317027Sdim  else
306317027Sdim    m_indent_level = 0;
307317027Sdim}
308317027Sdim
309317027Sdim//------------------------------------------------------------------
310317027Sdim// Get the address size in bytes
311317027Sdim//------------------------------------------------------------------
312317027Sdimuint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
313317027Sdim
314317027Sdim//------------------------------------------------------------------
315317027Sdim// Set the address size in bytes
316317027Sdim//------------------------------------------------------------------
317317027Sdimvoid Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
318317027Sdim
319317027Sdim//------------------------------------------------------------------
320317027Sdim// The flags get accessor
321317027Sdim//------------------------------------------------------------------
322317027SdimFlags &Stream::GetFlags() { return m_flags; }
323317027Sdim
324317027Sdim//------------------------------------------------------------------
325317027Sdim// The flags const get accessor
326317027Sdim//------------------------------------------------------------------
327317027Sdimconst Flags &Stream::GetFlags() const { return m_flags; }
328317027Sdim
329317027Sdim//------------------------------------------------------------------
330317027Sdim// The byte order get accessor
331317027Sdim//------------------------------------------------------------------
332317027Sdim
333317027Sdimlldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
334317027Sdim
335317027Sdimsize_t Stream::PrintfAsRawHex8(const char *format, ...) {
336317027Sdim  va_list args;
337317027Sdim  va_start(args, format);
338317027Sdim
339317027Sdim  llvm::SmallString<1024> buf;
340317027Sdim  VASprintf(buf, format, args);
341317027Sdim
342317027Sdim  size_t length = 0;
343317027Sdim  for (char C : buf)
344317027Sdim    length += _PutHex8(C, false);
345317027Sdim
346317027Sdim  va_end(args);
347317027Sdim
348317027Sdim  return length;
349317027Sdim}
350317027Sdim
351317027Sdimsize_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
352317027Sdim  size_t bytes_written = 0;
353317027Sdim  for (size_t i = 0; i < n; ++i)
354317027Sdim    bytes_written += _PutHex8(uvalue, false);
355317027Sdim  return bytes_written;
356317027Sdim}
357317027Sdim
358317027Sdimsize_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
359317027Sdim  size_t bytes_written = 0;
360317027Sdim  if (m_flags.Test(eBinary)) {
361317027Sdim    bytes_written = Write(&uvalue, 1);
362317027Sdim  } else {
363317027Sdim    if (add_prefix)
364317027Sdim      PutCString("0x");
365317027Sdim
366317027Sdim    static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
367317027Sdim                                               '6', '7', '8', '9', 'a', 'b',
368317027Sdim                                               'c', 'd', 'e', 'f'};
369317027Sdim    char nibble_chars[2];
370317027Sdim    nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
371317027Sdim    nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
372317027Sdim    bytes_written = Write(nibble_chars, sizeof(nibble_chars));
373317027Sdim  }
374317027Sdim  return bytes_written;
375317027Sdim}
376317027Sdim
377317027Sdimsize_t Stream::PutHex8(uint8_t uvalue) { return _PutHex8(uvalue, false); }
378317027Sdim
379317027Sdimsize_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
380317027Sdim  if (byte_order == eByteOrderInvalid)
381317027Sdim    byte_order = m_byte_order;
382317027Sdim
383317027Sdim  size_t bytes_written = 0;
384317027Sdim  if (byte_order == eByteOrderLittle) {
385317027Sdim    for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
386317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
387317027Sdim  } else {
388317027Sdim    for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
389317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
390317027Sdim  }
391317027Sdim  return bytes_written;
392317027Sdim}
393317027Sdim
394317027Sdimsize_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
395317027Sdim  if (byte_order == eByteOrderInvalid)
396317027Sdim    byte_order = m_byte_order;
397317027Sdim
398317027Sdim  size_t bytes_written = 0;
399317027Sdim  if (byte_order == eByteOrderLittle) {
400317027Sdim    for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
401317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
402317027Sdim  } else {
403317027Sdim    for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
404317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
405317027Sdim  }
406317027Sdim  return bytes_written;
407317027Sdim}
408317027Sdim
409317027Sdimsize_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
410317027Sdim  if (byte_order == eByteOrderInvalid)
411317027Sdim    byte_order = m_byte_order;
412317027Sdim
413317027Sdim  size_t bytes_written = 0;
414317027Sdim  if (byte_order == eByteOrderLittle) {
415317027Sdim    for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
416317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
417317027Sdim  } else {
418317027Sdim    for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
419317027Sdim      bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
420317027Sdim  }
421317027Sdim  return bytes_written;
422317027Sdim}
423317027Sdim
424317027Sdimsize_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
425317027Sdim                           lldb::ByteOrder byte_order) {
426317027Sdim  switch (byte_size) {
427317027Sdim  case 1:
428317027Sdim    return PutHex8((uint8_t)uvalue);
429317027Sdim  case 2:
430317027Sdim    return PutHex16((uint16_t)uvalue);
431317027Sdim  case 4:
432317027Sdim    return PutHex32((uint32_t)uvalue);
433317027Sdim  case 8:
434317027Sdim    return PutHex64(uvalue);
435317027Sdim  }
436317027Sdim  return 0;
437317027Sdim}
438317027Sdim
439317027Sdimsize_t Stream::PutPointer(void *ptr) {
440317027Sdim  return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
441317027Sdim                     endian::InlHostByteOrder());
442317027Sdim}
443317027Sdim
444317027Sdimsize_t Stream::PutFloat(float f, ByteOrder byte_order) {
445317027Sdim  if (byte_order == eByteOrderInvalid)
446317027Sdim    byte_order = m_byte_order;
447317027Sdim
448317027Sdim  return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
449317027Sdim}
450317027Sdim
451317027Sdimsize_t Stream::PutDouble(double d, ByteOrder byte_order) {
452317027Sdim  if (byte_order == eByteOrderInvalid)
453317027Sdim    byte_order = m_byte_order;
454317027Sdim
455317027Sdim  return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
456317027Sdim}
457317027Sdim
458317027Sdimsize_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
459317027Sdim  if (byte_order == eByteOrderInvalid)
460317027Sdim    byte_order = m_byte_order;
461317027Sdim
462317027Sdim  return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
463317027Sdim}
464317027Sdim
465317027Sdimsize_t Stream::PutRawBytes(const void *s, size_t src_len,
466317027Sdim                           ByteOrder src_byte_order, ByteOrder dst_byte_order) {
467317027Sdim  if (src_byte_order == eByteOrderInvalid)
468317027Sdim    src_byte_order = m_byte_order;
469317027Sdim
470317027Sdim  if (dst_byte_order == eByteOrderInvalid)
471317027Sdim    dst_byte_order = m_byte_order;
472317027Sdim
473317027Sdim  size_t bytes_written = 0;
474317027Sdim  const uint8_t *src = (const uint8_t *)s;
475317027Sdim  bool binary_was_set = m_flags.Test(eBinary);
476317027Sdim  if (!binary_was_set)
477317027Sdim    m_flags.Set(eBinary);
478317027Sdim  if (src_byte_order == dst_byte_order) {
479317027Sdim    for (size_t i = 0; i < src_len; ++i)
480317027Sdim      bytes_written += _PutHex8(src[i], false);
481317027Sdim  } else {
482317027Sdim    for (size_t i = src_len - 1; i < src_len; --i)
483317027Sdim      bytes_written += _PutHex8(src[i], false);
484317027Sdim  }
485317027Sdim  if (!binary_was_set)
486317027Sdim    m_flags.Clear(eBinary);
487317027Sdim
488317027Sdim  return bytes_written;
489317027Sdim}
490317027Sdim
491317027Sdimsize_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
492317027Sdim                                 ByteOrder src_byte_order,
493317027Sdim                                 ByteOrder dst_byte_order) {
494317027Sdim  if (src_byte_order == eByteOrderInvalid)
495317027Sdim    src_byte_order = m_byte_order;
496317027Sdim
497317027Sdim  if (dst_byte_order == eByteOrderInvalid)
498317027Sdim    dst_byte_order = m_byte_order;
499317027Sdim
500317027Sdim  size_t bytes_written = 0;
501317027Sdim  const uint8_t *src = (const uint8_t *)s;
502317027Sdim  bool binary_is_set = m_flags.Test(eBinary);
503317027Sdim  m_flags.Clear(eBinary);
504317027Sdim  if (src_byte_order == dst_byte_order) {
505317027Sdim    for (size_t i = 0; i < src_len; ++i)
506317027Sdim      bytes_written += _PutHex8(src[i], false);
507317027Sdim  } else {
508317027Sdim    for (size_t i = src_len - 1; i < src_len; --i)
509317027Sdim      bytes_written += _PutHex8(src[i], false);
510317027Sdim  }
511317027Sdim  if (binary_is_set)
512317027Sdim    m_flags.Set(eBinary);
513317027Sdim
514317027Sdim  return bytes_written;
515317027Sdim}
516317027Sdim
517317027Sdimsize_t Stream::PutCStringAsRawHex8(const char *s) {
518317027Sdim  size_t bytes_written = 0;
519317027Sdim  bool binary_is_set = m_flags.Test(eBinary);
520317027Sdim  m_flags.Clear(eBinary);
521317027Sdim  do {
522317027Sdim    bytes_written += _PutHex8(*s, false);
523317027Sdim    ++s;
524317027Sdim  } while (*s);
525317027Sdim  if (binary_is_set)
526317027Sdim    m_flags.Set(eBinary);
527317027Sdim  return bytes_written;
528317027Sdim}
529