xref: /freebsd/contrib/llvm-project/lldb/source/Utility/Stream.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- Stream.cpp ----------------------------------------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
10*0b57cec5SDimitry Andric 
11*0b57cec5SDimitry Andric #include "lldb/Utility/Endian.h"
12*0b57cec5SDimitry Andric #include "lldb/Utility/VASPrintf.h"
13*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
14*0b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include <string>
17*0b57cec5SDimitry Andric 
18*0b57cec5SDimitry Andric #include <inttypes.h>
19*0b57cec5SDimitry Andric #include <stddef.h>
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric using namespace lldb;
22*0b57cec5SDimitry Andric using namespace lldb_private;
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
25*0b57cec5SDimitry Andric     : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
26*0b57cec5SDimitry Andric       m_indent_level(0), m_forwarder(*this) {}
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric Stream::Stream()
29*0b57cec5SDimitry Andric     : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
30*0b57cec5SDimitry Andric       m_indent_level(0), m_forwarder(*this) {}
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric // Destructor
33*0b57cec5SDimitry Andric Stream::~Stream() {}
34*0b57cec5SDimitry Andric 
35*0b57cec5SDimitry Andric ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
36*0b57cec5SDimitry Andric   ByteOrder old_byte_order = m_byte_order;
37*0b57cec5SDimitry Andric   m_byte_order = byte_order;
38*0b57cec5SDimitry Andric   return old_byte_order;
39*0b57cec5SDimitry Andric }
40*0b57cec5SDimitry Andric 
41*0b57cec5SDimitry Andric // Put an offset "uval" out to the stream using the printf format in "format".
42*0b57cec5SDimitry Andric void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric // Put an SLEB128 "uval" out to the stream using the printf format in "format".
45*0b57cec5SDimitry Andric size_t Stream::PutSLEB128(int64_t sval) {
46*0b57cec5SDimitry Andric   if (m_flags.Test(eBinary))
47*0b57cec5SDimitry Andric     return llvm::encodeSLEB128(sval, m_forwarder);
48*0b57cec5SDimitry Andric   else
49*0b57cec5SDimitry Andric     return Printf("0x%" PRIi64, sval);
50*0b57cec5SDimitry Andric }
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric // Put an ULEB128 "uval" out to the stream using the printf format in "format".
53*0b57cec5SDimitry Andric size_t Stream::PutULEB128(uint64_t uval) {
54*0b57cec5SDimitry Andric   if (m_flags.Test(eBinary))
55*0b57cec5SDimitry Andric     return llvm::encodeULEB128(uval, m_forwarder);
56*0b57cec5SDimitry Andric   else
57*0b57cec5SDimitry Andric     return Printf("0x%" PRIx64, uval);
58*0b57cec5SDimitry Andric }
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric // Print a raw NULL terminated C string to the stream.
61*0b57cec5SDimitry Andric size_t Stream::PutCString(llvm::StringRef str) {
62*0b57cec5SDimitry Andric   size_t bytes_written = 0;
63*0b57cec5SDimitry Andric   bytes_written = Write(str.data(), str.size());
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric   // when in binary mode, emit the NULL terminator
66*0b57cec5SDimitry Andric   if (m_flags.Test(eBinary))
67*0b57cec5SDimitry Andric     bytes_written += PutChar('\0');
68*0b57cec5SDimitry Andric   return bytes_written;
69*0b57cec5SDimitry Andric }
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric // Print a double quoted NULL terminated C string to the stream using the
72*0b57cec5SDimitry Andric // printf format in "format".
73*0b57cec5SDimitry Andric void Stream::QuotedCString(const char *cstr, const char *format) {
74*0b57cec5SDimitry Andric   Printf(format, cstr);
75*0b57cec5SDimitry Andric }
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric // Put an address "addr" out to the stream with optional prefix and suffix
78*0b57cec5SDimitry Andric // strings.
79*0b57cec5SDimitry Andric void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
80*0b57cec5SDimitry Andric                      const char *suffix) {
81*0b57cec5SDimitry Andric   if (prefix == nullptr)
82*0b57cec5SDimitry Andric     prefix = "";
83*0b57cec5SDimitry Andric   if (suffix == nullptr)
84*0b57cec5SDimitry Andric     suffix = "";
85*0b57cec5SDimitry Andric   //    int addr_width = m_addr_size << 1;
86*0b57cec5SDimitry Andric   //    Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
87*0b57cec5SDimitry Andric   Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, addr, suffix);
88*0b57cec5SDimitry Andric }
89*0b57cec5SDimitry Andric 
90*0b57cec5SDimitry Andric // Put an address range out to the stream with optional prefix and suffix
91*0b57cec5SDimitry Andric // strings.
92*0b57cec5SDimitry Andric void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
93*0b57cec5SDimitry Andric                           uint32_t addr_size, const char *prefix,
94*0b57cec5SDimitry Andric                           const char *suffix) {
95*0b57cec5SDimitry Andric   if (prefix && prefix[0])
96*0b57cec5SDimitry Andric     PutCString(prefix);
97*0b57cec5SDimitry Andric   Address(lo_addr, addr_size, "[");
98*0b57cec5SDimitry Andric   Address(hi_addr, addr_size, "-", ")");
99*0b57cec5SDimitry Andric   if (suffix && suffix[0])
100*0b57cec5SDimitry Andric     PutCString(suffix);
101*0b57cec5SDimitry Andric }
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
104*0b57cec5SDimitry Andric 
105*0b57cec5SDimitry Andric // Print some formatted output to the stream.
106*0b57cec5SDimitry Andric size_t Stream::Printf(const char *format, ...) {
107*0b57cec5SDimitry Andric   va_list args;
108*0b57cec5SDimitry Andric   va_start(args, format);
109*0b57cec5SDimitry Andric   size_t result = PrintfVarArg(format, args);
110*0b57cec5SDimitry Andric   va_end(args);
111*0b57cec5SDimitry Andric   return result;
112*0b57cec5SDimitry Andric }
113*0b57cec5SDimitry Andric 
114*0b57cec5SDimitry Andric // Print some formatted output to the stream.
115*0b57cec5SDimitry Andric size_t Stream::PrintfVarArg(const char *format, va_list args) {
116*0b57cec5SDimitry Andric   llvm::SmallString<1024> buf;
117*0b57cec5SDimitry Andric   VASprintf(buf, format, args);
118*0b57cec5SDimitry Andric 
119*0b57cec5SDimitry Andric   // Include the NULL termination byte for binary output
120*0b57cec5SDimitry Andric   size_t length = buf.size();
121*0b57cec5SDimitry Andric   if (m_flags.Test(eBinary))
122*0b57cec5SDimitry Andric     ++length;
123*0b57cec5SDimitry Andric   return Write(buf.c_str(), length);
124*0b57cec5SDimitry Andric }
125*0b57cec5SDimitry Andric 
126*0b57cec5SDimitry Andric // Print and End of Line character to the stream
127*0b57cec5SDimitry Andric size_t Stream::EOL() { return PutChar('\n'); }
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric // Indent the current line using the current indentation level and print an
130*0b57cec5SDimitry Andric // optional string following the indentation spaces.
131*0b57cec5SDimitry Andric size_t Stream::Indent(const char *s) {
132*0b57cec5SDimitry Andric   return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
133*0b57cec5SDimitry Andric }
134*0b57cec5SDimitry Andric 
135*0b57cec5SDimitry Andric size_t Stream::Indent(llvm::StringRef str) {
136*0b57cec5SDimitry Andric   return Printf("%*.*s%s", m_indent_level, m_indent_level, "",
137*0b57cec5SDimitry Andric                 str.str().c_str());
138*0b57cec5SDimitry Andric }
139*0b57cec5SDimitry Andric 
140*0b57cec5SDimitry Andric // Stream a character "ch" out to this stream.
141*0b57cec5SDimitry Andric Stream &Stream::operator<<(char ch) {
142*0b57cec5SDimitry Andric   PutChar(ch);
143*0b57cec5SDimitry Andric   return *this;
144*0b57cec5SDimitry Andric }
145*0b57cec5SDimitry Andric 
146*0b57cec5SDimitry Andric // Stream the NULL terminated C string out to this stream.
147*0b57cec5SDimitry Andric Stream &Stream::operator<<(const char *s) {
148*0b57cec5SDimitry Andric   Printf("%s", s);
149*0b57cec5SDimitry Andric   return *this;
150*0b57cec5SDimitry Andric }
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric Stream &Stream::operator<<(llvm::StringRef str) {
153*0b57cec5SDimitry Andric   Write(str.data(), str.size());
154*0b57cec5SDimitry Andric   return *this;
155*0b57cec5SDimitry Andric }
156*0b57cec5SDimitry Andric 
157*0b57cec5SDimitry Andric // Stream the pointer value out to this stream.
158*0b57cec5SDimitry Andric Stream &Stream::operator<<(const void *p) {
159*0b57cec5SDimitry Andric   Printf("0x%.*tx", static_cast<int>(sizeof(const void *)) * 2, (ptrdiff_t)p);
160*0b57cec5SDimitry Andric   return *this;
161*0b57cec5SDimitry Andric }
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric // Stream a uint8_t "uval" out to this stream.
164*0b57cec5SDimitry Andric Stream &Stream::operator<<(uint8_t uval) {
165*0b57cec5SDimitry Andric   PutHex8(uval);
166*0b57cec5SDimitry Andric   return *this;
167*0b57cec5SDimitry Andric }
168*0b57cec5SDimitry Andric 
169*0b57cec5SDimitry Andric // Stream a uint16_t "uval" out to this stream.
170*0b57cec5SDimitry Andric Stream &Stream::operator<<(uint16_t uval) {
171*0b57cec5SDimitry Andric   PutHex16(uval, m_byte_order);
172*0b57cec5SDimitry Andric   return *this;
173*0b57cec5SDimitry Andric }
174*0b57cec5SDimitry Andric 
175*0b57cec5SDimitry Andric // Stream a uint32_t "uval" out to this stream.
176*0b57cec5SDimitry Andric Stream &Stream::operator<<(uint32_t uval) {
177*0b57cec5SDimitry Andric   PutHex32(uval, m_byte_order);
178*0b57cec5SDimitry Andric   return *this;
179*0b57cec5SDimitry Andric }
180*0b57cec5SDimitry Andric 
181*0b57cec5SDimitry Andric // Stream a uint64_t "uval" out to this stream.
182*0b57cec5SDimitry Andric Stream &Stream::operator<<(uint64_t uval) {
183*0b57cec5SDimitry Andric   PutHex64(uval, m_byte_order);
184*0b57cec5SDimitry Andric   return *this;
185*0b57cec5SDimitry Andric }
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric // Stream a int8_t "sval" out to this stream.
188*0b57cec5SDimitry Andric Stream &Stream::operator<<(int8_t sval) {
189*0b57cec5SDimitry Andric   Printf("%i", static_cast<int>(sval));
190*0b57cec5SDimitry Andric   return *this;
191*0b57cec5SDimitry Andric }
192*0b57cec5SDimitry Andric 
193*0b57cec5SDimitry Andric // Stream a int16_t "sval" out to this stream.
194*0b57cec5SDimitry Andric Stream &Stream::operator<<(int16_t sval) {
195*0b57cec5SDimitry Andric   Printf("%i", static_cast<int>(sval));
196*0b57cec5SDimitry Andric   return *this;
197*0b57cec5SDimitry Andric }
198*0b57cec5SDimitry Andric 
199*0b57cec5SDimitry Andric // Stream a int32_t "sval" out to this stream.
200*0b57cec5SDimitry Andric Stream &Stream::operator<<(int32_t sval) {
201*0b57cec5SDimitry Andric   Printf("%i", static_cast<int>(sval));
202*0b57cec5SDimitry Andric   return *this;
203*0b57cec5SDimitry Andric }
204*0b57cec5SDimitry Andric 
205*0b57cec5SDimitry Andric // Stream a int64_t "sval" out to this stream.
206*0b57cec5SDimitry Andric Stream &Stream::operator<<(int64_t sval) {
207*0b57cec5SDimitry Andric   Printf("%" PRIi64, sval);
208*0b57cec5SDimitry Andric   return *this;
209*0b57cec5SDimitry Andric }
210*0b57cec5SDimitry Andric 
211*0b57cec5SDimitry Andric // Get the current indentation level
212*0b57cec5SDimitry Andric int Stream::GetIndentLevel() const { return m_indent_level; }
213*0b57cec5SDimitry Andric 
214*0b57cec5SDimitry Andric // Set the current indentation level
215*0b57cec5SDimitry Andric void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
216*0b57cec5SDimitry Andric 
217*0b57cec5SDimitry Andric // Increment the current indentation level
218*0b57cec5SDimitry Andric void Stream::IndentMore(int amount) { m_indent_level += amount; }
219*0b57cec5SDimitry Andric 
220*0b57cec5SDimitry Andric // Decrement the current indentation level
221*0b57cec5SDimitry Andric void Stream::IndentLess(int amount) {
222*0b57cec5SDimitry Andric   if (m_indent_level >= amount)
223*0b57cec5SDimitry Andric     m_indent_level -= amount;
224*0b57cec5SDimitry Andric   else
225*0b57cec5SDimitry Andric     m_indent_level = 0;
226*0b57cec5SDimitry Andric }
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric // Get the address size in bytes
229*0b57cec5SDimitry Andric uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
230*0b57cec5SDimitry Andric 
231*0b57cec5SDimitry Andric // Set the address size in bytes
232*0b57cec5SDimitry Andric void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
233*0b57cec5SDimitry Andric 
234*0b57cec5SDimitry Andric // The flags get accessor
235*0b57cec5SDimitry Andric Flags &Stream::GetFlags() { return m_flags; }
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric // The flags const get accessor
238*0b57cec5SDimitry Andric const Flags &Stream::GetFlags() const { return m_flags; }
239*0b57cec5SDimitry Andric 
240*0b57cec5SDimitry Andric // The byte order get accessor
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
243*0b57cec5SDimitry Andric 
244*0b57cec5SDimitry Andric size_t Stream::PrintfAsRawHex8(const char *format, ...) {
245*0b57cec5SDimitry Andric   va_list args;
246*0b57cec5SDimitry Andric   va_start(args, format);
247*0b57cec5SDimitry Andric 
248*0b57cec5SDimitry Andric   llvm::SmallString<1024> buf;
249*0b57cec5SDimitry Andric   VASprintf(buf, format, args);
250*0b57cec5SDimitry Andric 
251*0b57cec5SDimitry Andric   ByteDelta delta(*this);
252*0b57cec5SDimitry Andric   for (char C : buf)
253*0b57cec5SDimitry Andric     _PutHex8(C, false);
254*0b57cec5SDimitry Andric 
255*0b57cec5SDimitry Andric   va_end(args);
256*0b57cec5SDimitry Andric 
257*0b57cec5SDimitry Andric   return *delta;
258*0b57cec5SDimitry Andric }
259*0b57cec5SDimitry Andric 
260*0b57cec5SDimitry Andric size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
261*0b57cec5SDimitry Andric   ByteDelta delta(*this);
262*0b57cec5SDimitry Andric   for (size_t i = 0; i < n; ++i)
263*0b57cec5SDimitry Andric     _PutHex8(uvalue, false);
264*0b57cec5SDimitry Andric   return *delta;
265*0b57cec5SDimitry Andric }
266*0b57cec5SDimitry Andric 
267*0b57cec5SDimitry Andric void Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
268*0b57cec5SDimitry Andric   if (m_flags.Test(eBinary)) {
269*0b57cec5SDimitry Andric     Write(&uvalue, 1);
270*0b57cec5SDimitry Andric   } else {
271*0b57cec5SDimitry Andric     if (add_prefix)
272*0b57cec5SDimitry Andric       PutCString("0x");
273*0b57cec5SDimitry Andric 
274*0b57cec5SDimitry Andric     static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
275*0b57cec5SDimitry Andric                                                '6', '7', '8', '9', 'a', 'b',
276*0b57cec5SDimitry Andric                                                'c', 'd', 'e', 'f'};
277*0b57cec5SDimitry Andric     char nibble_chars[2];
278*0b57cec5SDimitry Andric     nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
279*0b57cec5SDimitry Andric     nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
280*0b57cec5SDimitry Andric     Write(nibble_chars, sizeof(nibble_chars));
281*0b57cec5SDimitry Andric   }
282*0b57cec5SDimitry Andric }
283*0b57cec5SDimitry Andric 
284*0b57cec5SDimitry Andric size_t Stream::PutHex8(uint8_t uvalue) {
285*0b57cec5SDimitry Andric   ByteDelta delta(*this);
286*0b57cec5SDimitry Andric   _PutHex8(uvalue, false);
287*0b57cec5SDimitry Andric   return *delta;
288*0b57cec5SDimitry Andric }
289*0b57cec5SDimitry Andric 
290*0b57cec5SDimitry Andric size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
291*0b57cec5SDimitry Andric   ByteDelta delta(*this);
292*0b57cec5SDimitry Andric 
293*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
294*0b57cec5SDimitry Andric     byte_order = m_byte_order;
295*0b57cec5SDimitry Andric 
296*0b57cec5SDimitry Andric   if (byte_order == eByteOrderLittle) {
297*0b57cec5SDimitry Andric     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
298*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
299*0b57cec5SDimitry Andric   } else {
300*0b57cec5SDimitry Andric     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
301*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
302*0b57cec5SDimitry Andric   }
303*0b57cec5SDimitry Andric   return *delta;
304*0b57cec5SDimitry Andric }
305*0b57cec5SDimitry Andric 
306*0b57cec5SDimitry Andric size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
307*0b57cec5SDimitry Andric   ByteDelta delta(*this);
308*0b57cec5SDimitry Andric 
309*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
310*0b57cec5SDimitry Andric     byte_order = m_byte_order;
311*0b57cec5SDimitry Andric 
312*0b57cec5SDimitry Andric   if (byte_order == eByteOrderLittle) {
313*0b57cec5SDimitry Andric     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
314*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
315*0b57cec5SDimitry Andric   } else {
316*0b57cec5SDimitry Andric     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
317*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
318*0b57cec5SDimitry Andric   }
319*0b57cec5SDimitry Andric   return *delta;
320*0b57cec5SDimitry Andric }
321*0b57cec5SDimitry Andric 
322*0b57cec5SDimitry Andric size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
323*0b57cec5SDimitry Andric   ByteDelta delta(*this);
324*0b57cec5SDimitry Andric 
325*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
326*0b57cec5SDimitry Andric     byte_order = m_byte_order;
327*0b57cec5SDimitry Andric 
328*0b57cec5SDimitry Andric   if (byte_order == eByteOrderLittle) {
329*0b57cec5SDimitry Andric     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
330*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
331*0b57cec5SDimitry Andric   } else {
332*0b57cec5SDimitry Andric     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
333*0b57cec5SDimitry Andric       _PutHex8(static_cast<uint8_t>(uvalue >> (byte * 8)), false);
334*0b57cec5SDimitry Andric   }
335*0b57cec5SDimitry Andric   return *delta;
336*0b57cec5SDimitry Andric }
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
339*0b57cec5SDimitry Andric                            lldb::ByteOrder byte_order) {
340*0b57cec5SDimitry Andric   switch (byte_size) {
341*0b57cec5SDimitry Andric   case 1:
342*0b57cec5SDimitry Andric     return PutHex8(static_cast<uint8_t>(uvalue));
343*0b57cec5SDimitry Andric   case 2:
344*0b57cec5SDimitry Andric     return PutHex16(static_cast<uint16_t>(uvalue), byte_order);
345*0b57cec5SDimitry Andric   case 4:
346*0b57cec5SDimitry Andric     return PutHex32(static_cast<uint32_t>(uvalue), byte_order);
347*0b57cec5SDimitry Andric   case 8:
348*0b57cec5SDimitry Andric     return PutHex64(uvalue, byte_order);
349*0b57cec5SDimitry Andric   }
350*0b57cec5SDimitry Andric   return 0;
351*0b57cec5SDimitry Andric }
352*0b57cec5SDimitry Andric 
353*0b57cec5SDimitry Andric size_t Stream::PutPointer(void *ptr) {
354*0b57cec5SDimitry Andric   return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
355*0b57cec5SDimitry Andric                      endian::InlHostByteOrder());
356*0b57cec5SDimitry Andric }
357*0b57cec5SDimitry Andric 
358*0b57cec5SDimitry Andric size_t Stream::PutFloat(float f, ByteOrder byte_order) {
359*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
360*0b57cec5SDimitry Andric     byte_order = m_byte_order;
361*0b57cec5SDimitry Andric 
362*0b57cec5SDimitry Andric   return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
363*0b57cec5SDimitry Andric }
364*0b57cec5SDimitry Andric 
365*0b57cec5SDimitry Andric size_t Stream::PutDouble(double d, ByteOrder byte_order) {
366*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
367*0b57cec5SDimitry Andric     byte_order = m_byte_order;
368*0b57cec5SDimitry Andric 
369*0b57cec5SDimitry Andric   return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
370*0b57cec5SDimitry Andric }
371*0b57cec5SDimitry Andric 
372*0b57cec5SDimitry Andric size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
373*0b57cec5SDimitry Andric   if (byte_order == eByteOrderInvalid)
374*0b57cec5SDimitry Andric     byte_order = m_byte_order;
375*0b57cec5SDimitry Andric 
376*0b57cec5SDimitry Andric   return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
377*0b57cec5SDimitry Andric }
378*0b57cec5SDimitry Andric 
379*0b57cec5SDimitry Andric size_t Stream::PutRawBytes(const void *s, size_t src_len,
380*0b57cec5SDimitry Andric                            ByteOrder src_byte_order, ByteOrder dst_byte_order) {
381*0b57cec5SDimitry Andric   ByteDelta delta(*this);
382*0b57cec5SDimitry Andric 
383*0b57cec5SDimitry Andric   if (src_byte_order == eByteOrderInvalid)
384*0b57cec5SDimitry Andric     src_byte_order = m_byte_order;
385*0b57cec5SDimitry Andric 
386*0b57cec5SDimitry Andric   if (dst_byte_order == eByteOrderInvalid)
387*0b57cec5SDimitry Andric     dst_byte_order = m_byte_order;
388*0b57cec5SDimitry Andric 
389*0b57cec5SDimitry Andric   const uint8_t *src = static_cast<const uint8_t *>(s);
390*0b57cec5SDimitry Andric   bool binary_was_set = m_flags.Test(eBinary);
391*0b57cec5SDimitry Andric   if (!binary_was_set)
392*0b57cec5SDimitry Andric     m_flags.Set(eBinary);
393*0b57cec5SDimitry Andric   if (src_byte_order == dst_byte_order) {
394*0b57cec5SDimitry Andric     for (size_t i = 0; i < src_len; ++i)
395*0b57cec5SDimitry Andric       _PutHex8(src[i], false);
396*0b57cec5SDimitry Andric   } else {
397*0b57cec5SDimitry Andric     for (size_t i = src_len - 1; i < src_len; --i)
398*0b57cec5SDimitry Andric       _PutHex8(src[i], false);
399*0b57cec5SDimitry Andric   }
400*0b57cec5SDimitry Andric   if (!binary_was_set)
401*0b57cec5SDimitry Andric     m_flags.Clear(eBinary);
402*0b57cec5SDimitry Andric 
403*0b57cec5SDimitry Andric   return *delta;
404*0b57cec5SDimitry Andric }
405*0b57cec5SDimitry Andric 
406*0b57cec5SDimitry Andric size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
407*0b57cec5SDimitry Andric                                  ByteOrder src_byte_order,
408*0b57cec5SDimitry Andric                                  ByteOrder dst_byte_order) {
409*0b57cec5SDimitry Andric   ByteDelta delta(*this);
410*0b57cec5SDimitry Andric   if (src_byte_order == eByteOrderInvalid)
411*0b57cec5SDimitry Andric     src_byte_order = m_byte_order;
412*0b57cec5SDimitry Andric 
413*0b57cec5SDimitry Andric   if (dst_byte_order == eByteOrderInvalid)
414*0b57cec5SDimitry Andric     dst_byte_order = m_byte_order;
415*0b57cec5SDimitry Andric 
416*0b57cec5SDimitry Andric   const uint8_t *src = static_cast<const uint8_t *>(s);
417*0b57cec5SDimitry Andric   bool binary_is_set = m_flags.Test(eBinary);
418*0b57cec5SDimitry Andric   m_flags.Clear(eBinary);
419*0b57cec5SDimitry Andric   if (src_byte_order == dst_byte_order) {
420*0b57cec5SDimitry Andric     for (size_t i = 0; i < src_len; ++i)
421*0b57cec5SDimitry Andric       _PutHex8(src[i], false);
422*0b57cec5SDimitry Andric   } else {
423*0b57cec5SDimitry Andric     for (size_t i = src_len - 1; i < src_len; --i)
424*0b57cec5SDimitry Andric       _PutHex8(src[i], false);
425*0b57cec5SDimitry Andric   }
426*0b57cec5SDimitry Andric   if (binary_is_set)
427*0b57cec5SDimitry Andric     m_flags.Set(eBinary);
428*0b57cec5SDimitry Andric 
429*0b57cec5SDimitry Andric   return *delta;
430*0b57cec5SDimitry Andric }
431*0b57cec5SDimitry Andric 
432*0b57cec5SDimitry Andric size_t Stream::PutStringAsRawHex8(llvm::StringRef s) {
433*0b57cec5SDimitry Andric   ByteDelta delta(*this);
434*0b57cec5SDimitry Andric   bool binary_is_set = m_flags.Test(eBinary);
435*0b57cec5SDimitry Andric   m_flags.Clear(eBinary);
436*0b57cec5SDimitry Andric   for (char c : s)
437*0b57cec5SDimitry Andric     _PutHex8(c, false);
438*0b57cec5SDimitry Andric   if (binary_is_set)
439*0b57cec5SDimitry Andric     m_flags.Set(eBinary);
440*0b57cec5SDimitry Andric   return *delta;
441*0b57cec5SDimitry Andric }
442