BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_print.h
Go to the documentation of this file.
1/// @file bdlb_print.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_print.h -*-C++-*-
8#ifndef INCLUDED_BDLB_PRINT
9#define INCLUDED_BDLB_PRINT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_print bdlb_print
15/// @brief Provide platform-independent stream utilities.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_print
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_print-purpose"> Purpose</a>
25/// * <a href="#bdlb_print-classes"> Classes </a>
26/// * <a href="#bdlb_print-description"> Description </a>
27/// * <a href="#bdlb_print-xxd-compatible-hexdump"> xxd-Compatible hexDump </a>
28/// * <a href="#bdlb_print-usage"> Usage </a>
29/// * <a href="#bdlb_print-example-1-using-printptr"> Example 1: Using printPtr </a>
30/// * <a href="#bdlb_print-example-2-using-the-helper-classes"> Example 2: Using the Helper Classes </a>
31///
32/// # Purpose {#bdlb_print-purpose}
33/// Provide platform-independent stream utilities.
34///
35/// # Classes {#bdlb_print-classes}
36///
37/// - bdlb::Print: namespace for procedures on streams
38/// - bdlb::PrintStringHexDumper: create/print hex buffers, multi-line
39/// - bdlb::PrintStringSingleLineHexDumper: create/print hex buffers, single line
40///
41/// # Description {#bdlb_print-description}
42/// This component provides a namespace, `bdlb::Print`, containing
43/// utility functions for formatting data to `bsl::ostream` objects. These
44/// functions provide several variations of hexadecimal format, allow
45/// platform-independent representation of `void *` pointers, and can help with
46/// the indentation of hierarchical data.
47///
48/// This component also provides two helper classes,
49/// `bdlb::PrintStringHexDumper` and `bdlb::PrintStringSingleLineHexDumper`,
50/// that define `operator<<` so they can be used in chains of `<<` operations.
51/// The `bdlb::PrintStringHexDumper` class produces formatted, possibly
52/// multi-line output, whereas the `bdlb::PrintStringSingleLineHexDumper` class
53/// produces a simple sequence of hexadecimal digits (and no newline).
54///
55/// ### xxd-Compatible hexDump {#bdlb_print-xxd-compatible-hexdump}
56///
57///
58/// The output generated by the `hexDump` functions is not `xxd`-compatible (see
59/// `http://gd.tuwien.ac.at/linuxcommand.org/man_pages/xxd1.html`). The
60/// following perl script is provided that will convert `hexDump` output into
61/// `xxd`-compatible form. Run the script with a file containing the `hexDump`
62/// output as the first argument.
63/// @code
64/// #!/usr/bin/perl -w
65///
66/// use strict;
67///
68/// my $num = 0;
69/// while (<>) {
70/// next if (!$_);
71/// my $str = $_;
72/// next if !($str =~ s/^[^:]*?:\s*//);
73/// my $h = sprintf("%08X",$num);
74/// $str =~ s/(\S{4})([\S\W]{4})\s?([\S\W]{4})([\S\W]{4})\s?([\S\W]{4})?
75/// ([\S\W]{4})?\s?([\S\W]{4})?([\S\W]{4})?/$1 $2 $3 $4 $5 $6 $7 $8/;
76/// $str =~ s/\s \|([^|]+)\|.*$/ $1/;
77/// print "$h: ";
78/// print $str;
79/// $num = $num + 16;
80/// }
81/// @endcode
82///
83/// ## Usage {#bdlb_print-usage}
84///
85///
86/// This section illustrates intended use of this component.
87///
88/// ### Example 1: Using printPtr {#bdlb_print-example-1-using-printptr}
89///
90///
91/// The default output produced from pointer values is non-standard across
92/// vendor platforms. The `printPtr` method addresses this inconsistency by
93/// always producing a consistent format for a given pointer size:
94/// @code
95/// const void *a = reinterpret_cast<void *>(0x0);
96/// const void *b = reinterpret_cast<void *>(0xf2ff);
97/// const void *c = reinterpret_cast<void *>(0x0123);
98/// const void *d = reinterpret_cast<void *>(0xf1f2abc9);
99///
100/// bsl::ostringstream out1;
101///
102/// bdlb::Print::printPtr(out1, a); out1 << endl;
103/// bdlb::Print::printPtr(out1, b); out1 << endl;
104/// bdlb::Print::printPtr(out1, c); out1 << endl;
105/// bdlb::Print::printPtr(out1, d); out1 << endl;
106///
107/// assert("0" "\n"
108/// "f2ff" "\n"
109/// "123" "\n"
110/// "f1f2abc9" "\n" == out1.str());
111/// @endcode
112///
113/// ### Example 2: Using the Helper Classes {#bdlb_print-example-2-using-the-helper-classes}
114///
115///
116/// The two helper classes allow users to stream a hexadecimal representation
117/// of a sequence of bytes into an output stream.
118///
119/// The `bdlb::PrintStringHexDumper` provides a formatted, possibly multi-line
120/// representation:
121/// @code
122/// char buf[] = "abcdefghijklmnopqrstuvwxyz";
123///
124/// bsl::ostringstream out2a;
125/// out2a << bdlb::PrintStringHexDumper(buf, sizeof buf);
126///
127/// assert(
128/// " 0: 61626364 65666768 696A6B6C 6D6E6F70 |abcdefghijklmnop|\n"
129/// " 16: 71727374 75767778 797A00 |qrstuvwxyz. |\n"
130/// == out2a.str());
131///
132/// bsl::ostringstream out2b;
133/// out2b << bdlb::PrintStringSingleLineHexDumper(buf, sizeof buf);
134/// @endcode
135/// The `bdlb::PrintStringSingleLineHexDumper` provides a simple, single-line
136/// representation.
137/// @code
138/// assert("6162636465666768696A6B6C6D6E6F707172737475767778797A00"
139/// == out2b.str());
140/// @endcode
141/// @}
142/** @} */
143/** @} */
144
145/** @addtogroup bdl
146 * @{
147 */
148/** @addtogroup bdlb
149 * @{
150 */
151/** @addtogroup bdlb_print
152 * @{
153 */
154
155#include <bdlscm_version.h>
156
157#include <bsls_assert.h>
158#include <bsls_review.h>
159
160#include <bsl_ostream.h>
161#include <bsl_utility.h>
162
163
164namespace bdlb {
165 // ============
166 // struct Print
167 // ============
168
169/// Provide a namespace for the interface to a suite of procedural stream
170/// operations.
171struct Print {
172
173 // CLASS METHODS
174
175 /// Emit to the specified output `stream` the number of spaces (` `)
176 /// equal to the absolute value of the product of the specified `level`
177 /// and `spacesPerLevel` or, if `level` is negative, nothing at all.
178 /// Return a reference providing modifiable access to `stream`. The
179 /// behavior is undefined unless the absolute value of the product of
180 /// the specified `level` and `spacesPerLevel` is representable as
181 /// `int`.
182 static bsl::ostream& indent(bsl::ostream& stream,
183 int level,
184 int spacesPerLevel = 4);
185
186 /// Emit to the specified `stream` a newline ('\n') followed by the
187 /// number of spaces (` `) equal to the absolute value of the product
188 /// of the specified `level` and `spacesPerLevel` or, if
189 /// `spacesPerLevel` is negative, emit a single space (and *no*
190 /// newline). Return a reference providing modifiable access to
191 /// `stream`. The behavior is undefined unless the absolute value of
192 /// the product of the specified `level` and `spacesPerLevel` is
193 /// representable as `int`.
194 static bsl::ostream& newlineAndIndent(bsl::ostream& stream,
195 int level,
196 int spacesPerLevel = 4);
197
198 /// Print to the specified `stream` the specified pointer `value` in a
199 /// standard format. The output is in hexadecimal format with a maximum
200 /// length of `2 * sizeof(void *)`. The output does not have leading
201 /// zeros and is not preceded by `0x`. The hexadecimal digits (`a` to
202 /// `f`, inclusive) are expressed in lower case.
203 static void printPtr(bsl::ostream& stream, const void *value);
204
205 /// Print to the specified `stream` the specified `string` of the
206 /// specified `length` and return a reference providing modifiable
207 /// access to `stream`. If the optionally specified `escapeBackSlash`
208 /// flag is `true`, then all occurrences of the backslash character
209 /// (`\`) in the `string` are escaped (i.e., expanded to "\\") when
210 /// written to the `stream`. Note that non-printable characters in
211 /// `string` will be printed in their hexadecimal representation
212 /// (`\xHH`). If `stream` is not valid on entry, this operation has no
213 /// effect. The behavior is undefined unless `0 <= length`.
214 static bsl::ostream& printString(bsl::ostream& stream,
215 const char *string,
216 int length,
217 bool escapeBackSlash = false);
218
219 /// Print in hexadecimal format the contents of the specified `buffer`
220 /// of the specified `length` to the specified `stream`, and return a
221 /// reference providing modifiable access to `stream`. The behavior is
222 /// undefined unless `0 <= length`.
223 static bsl::ostream& hexDump(bsl::ostream& stream,
224 const char *buffer,
225 int length);
226
227 /// Print to the specified `stream` the specified `numBuffers` buffers
228 /// supplied by specified `buffers` in a hexadecimal representation (16
229 /// chars per line) followed by the ASCII representation. Return a
230 /// reference providing modifiable access to `stream`. The array of
231 /// buffers are supplied as a `bsl::pair<const char*, int> *` where the
232 /// first element is a pointer to the data, and the second element is
233 /// the length of the buffer. The behavior is undefined unless
234 /// `0 <= numBuffers`. Note that the contents of the buffers are
235 /// concatenated and boundaries between buffers are not demarcated.
236 static bsl::ostream& hexDump(bsl::ostream& stream,
238 int numBuffers);
239
240 /// Print to the specified `stream` the uppercase hex encoding of the
241 /// byte sequence defined by the specified `begin` and `end` iterators
242 /// of the parameterized `INPUT_ITERATOR` type, and return a reference
243 /// providing modifiable access to `stream`. Note that `INPUT_ITERATOR`
244 /// need not be random-access, i.e., it need support only increment
245 /// (`++`) and equality comparison (`==`). See the non-template version
246 /// of this function if insulation and/or code bloat are a concern.
247 template <class INPUT_ITERATOR>
248 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
249 INPUT_ITERATOR begin,
250 INPUT_ITERATOR end);
251
252 /// Print to the specified `stream` the uppercase hex encoding of the
253 /// byte sequence defined by the specified `begin` and `end` iterators
254 /// into the specified `stream`, and return a reference providing
255 /// modifiable access to `stream`. This function insulates clients from
256 /// its implementation, but unlike the member template version (above),
257 /// requires random access iterators of type `const char *`. The
258 /// behavior is undefined unless both `begin` and `end` refer to the
259 /// same block of contiguous memory, and `begin <= end`.
260 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
261 const char *begin,
262 const char *end);
263
264 /// Print to the specified `stream` the contents of the specified
265 /// `buffer` having the specified `length` on a single line, and return
266 /// a reference to the modifiable `stream`. The behavior is undefined
267 /// unless `0 <= length`.
268 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
269 const char *buffer,
270 int length);
271};
272
273 // ===========================
274 // struct PrintStringHexDumper
275 // ===========================
276
277/// Utility for hex dumping a blob to standard output streams. This class
278/// has `operator<<` defined for it, so it can be used as follows:
279/// @code
280/// bsl::vector<char> blob;
281/// blob.resize(1024);
282///
283/// // ... fill up the blob with some data ...
284///
285/// bsl::cout << PrintStringHexDumper(blob.data(), blob.size())
286/// << bsl::endl;
287/// @endcode
289
290 // DATA
291 const char *d_data_p;
293
294 // CREATORS
295
296 /// Create a `PrintStringHexDumper` object that can insert to an output
297 /// stream a formated (possibly multi-lined) hexadecimal representation
298 /// the specified `data` of the specified `length`.
299 PrintStringHexDumper(const char *data, int length);
300};
301
302// FREE OPERATORS
303
304/// Hex dump the data referenced by the specified `rhs` to the specified
305/// `stream`.
306inline
307bsl::ostream& operator<<(bsl::ostream& stream,
308 const PrintStringHexDumper& rhs);
309
310 // =====================================
311 // struct PrintStringSingleLineHexDumper
312 // =====================================
313
314/// Utility for hex dumping a string with no extra formatting to standard
315/// output streams. This class has `operator<<` defined for it, so it can
316/// be used as follows:
317/// @code
318/// bsl::string str;
319///
320/// // ... fill up the str with some data ...
321///
322/// bsl::cout
323/// << PrintStringSingleLineHexDumper(str.c_str(), str.size())
324/// << bsl::endl;
325/// @endcode
327
328 // DATA
329 const char *d_data_p;
331
332 // CREATORS
333
334 /// Create a `PrintStringSingleLineHexDumper` object that can insert to
335 /// an output stream a single-line hexadecimal representation the
336 /// specified `data` of the specified `length`.
337 PrintStringSingleLineHexDumper(const char *data, int length);
338};
339
340// FREE OPERATORS
341
342/// Hex dump the data referenced by the specified `rhs` to the specified
343/// `stream`.
344inline
345bsl::ostream& operator<<(bsl::ostream& stream,
347
348// ============================================================================
349// INLINE DEFINITIONS
350// ============================================================================
351
352 // ------------
353 // struct Print
354 // ------------
355
356// CLASS METHODS
357template <class INPUT_ITERATOR>
358bsl::ostream& Print::singleLineHexDump(bsl::ostream& stream,
359 INPUT_ITERATOR begin,
360 INPUT_ITERATOR end)
361{
362 enum { k_LOCAL_BUF_SIZE = 512 };
363 static const char HEX[] = "0123456789ABCDEF";
364
365 char buf[k_LOCAL_BUF_SIZE];
366
367 unsigned int offset = 0;
368
369 for (; begin != end; ++begin) {
370
371 if (offset >= (k_LOCAL_BUF_SIZE - 1)) {
372 stream.write(buf, offset);
373 offset = 0;
374 }
375
376 const unsigned char c = *begin;
377
378 buf[offset++] = HEX[(c >> 4) & 0xF];
379 buf[offset++] = HEX[c & 0xF];
380 }
381
382 if (offset != 0) {
383 stream.write(buf, offset);
384 }
385
386 return stream;
387}
388
389inline
390bsl::ostream& Print::singleLineHexDump(bsl::ostream& stream,
391 const char *buffer,
392 int length)
393{
394 BSLS_REVIEW(buffer);
395 BSLS_REVIEW(0 <= length);
396
397 return singleLineHexDump(stream, buffer, buffer + length);
398}
399
400 // ---------------------------
401 // struct PrintStringHexDumper
402 // ---------------------------
403
404// CREATORS
405inline
407 int length)
408: d_data_p(data)
409, d_length(length)
410{
411 BSLS_REVIEW(data);
412 BSLS_REVIEW(0 <= length);
413
414}
415} // close package namespace
416
417// FREE OPERATORS
418inline
419bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
420 const PrintStringHexDumper& rhs)
421{
422 return Print::hexDump(stream, rhs.d_data_p, rhs.d_length);
423}
424
425namespace bdlb {
426 // -------------------------------------
427 // struct PrintStringSingleLineHexDumper
428 // -------------------------------------
429
430// CREATORS
431inline
433 const char *data,
434 int length)
435: d_data_p(data)
436, d_length(length)
437{
438 BSLS_REVIEW(data);
439 BSLS_REVIEW(0 <= length);
440}
441} // close package namespace
442
443// FREE OPERATORS
444inline
445bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
446 const PrintStringSingleLineHexDumper& rhs)
447{
448 return Print::singleLineHexDump(stream, rhs.d_data_p, rhs.d_length);
449}
450
451
452
453#endif
454
455// ----------------------------------------------------------------------------
456// Copyright 2015 Bloomberg Finance L.P.
457//
458// Licensed under the Apache License, Version 2.0 (the "License");
459// you may not use this file except in compliance with the License.
460// You may obtain a copy of the License at
461//
462// http://www.apache.org/licenses/LICENSE-2.0
463//
464// Unless required by applicable law or agreed to in writing, software
465// distributed under the License is distributed on an "AS IS" BASIS,
466// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
467// See the License for the specific language governing permissions and
468// limitations under the License.
469// ----------------------------- END-OF-FILE ----------------------------------
470
471/** @} */
472/** @} */
473/** @} */
Definition bslstl_pair.h:1210
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_REVIEW(X)
Definition bsls_review.h:949
Definition bdlb_algorithmworkaroundutil.h:74
bsl::ostream & operator<<(bsl::ostream &stream, const BigEndianInt16 &integer)
Definition bdlb_print.h:288
int d_length
Definition bdlb_print.h:292
const char * d_data_p
Definition bdlb_print.h:291
PrintStringHexDumper(const char *data, int length)
Definition bdlb_print.h:406
Definition bdlb_print.h:326
const char * d_data_p
Definition bdlb_print.h:329
PrintStringSingleLineHexDumper(const char *data, int length)
Definition bdlb_print.h:432
int d_length
Definition bdlb_print.h:330
Definition bdlb_print.h:171
static void printPtr(bsl::ostream &stream, const void *value)
static bsl::ostream & singleLineHexDump(bsl::ostream &stream, const char *begin, const char *end)
static bsl::ostream & newlineAndIndent(bsl::ostream &stream, int level, int spacesPerLevel=4)
static bsl::ostream & indent(bsl::ostream &stream, int level, int spacesPerLevel=4)
static bsl::ostream & hexDump(bsl::ostream &stream, const char *buffer, int length)
static bsl::ostream & printString(bsl::ostream &stream, const char *string, int length, bool escapeBackSlash=false)
static bsl::ostream & singleLineHexDump(bsl::ostream &stream, INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition bdlb_print.h:358
static bsl::ostream & hexDump(bsl::ostream &stream, bsl::pair< const char *, int > *buffers, int numBuffers)