BDE 4.39.x 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.
171///
172/// See @ref bdlb_print
173struct Print {
174
175 // CLASS METHODS
176
177 /// Emit to the specified output `stream` the number of spaces (` `)
178 /// equal to the absolute value of the product of the specified `level`
179 /// and `spacesPerLevel` or, if `level` is negative, nothing at all.
180 /// Return a reference providing modifiable access to `stream`.
181 ///
182 /// \pre The behavior is undefined unless the absolute value of the product of
183 /// the specified `level` and `spacesPerLevel` is representable as
184 /// `int`.
185 static bsl::ostream& indent(bsl::ostream& stream,
186 int level,
187 int spacesPerLevel = 4);
188
189 /// Emit to the specified `stream` a newline (`\n`) followed by the
190 /// number of spaces (` `) equal to the absolute value of the product
191 /// of the specified `level` and `spacesPerLevel` or, if
192 /// `spacesPerLevel` is negative, emit a single space (and *no*
193 /// newline). Return a reference providing modifiable access to `stream`.
194 ///
195 /// \pre The behavior is undefined unless the absolute value of
196 /// the product of the specified `level` and `spacesPerLevel` is
197 /// representable as `int`.
198 static bsl::ostream& newlineAndIndent(bsl::ostream& stream,
199 int level,
200 int spacesPerLevel = 4);
201
202 /// Print to the specified `stream` the specified pointer `value` in a
203 /// standard format. The output is in hexadecimal format with a maximum
204 /// length of `2 * sizeof(void *)`. The output does not have leading
205 /// zeros and is not preceded by `0x`. The hexadecimal digits (`a` to
206 /// `f`, inclusive) are expressed in lower case.
207 static void printPtr(bsl::ostream& stream, const void *value);
208
209 /// Print to the specified `stream` the specified `string` of the
210 /// specified `length` and return a reference providing modifiable
211 /// access to `stream`. If the optionally specified `escapeBackSlash`
212 /// flag is `true`, then all occurrences of the backslash character
213 /// ('\') in the `string` are escaped (i.e., expanded to "\\") when written to the `stream`.
214 ///
215 /// \note Note that non-printable characters in
216 /// `string` will be printed in their hexadecimal representation
217 /// ('\xHH'). If `stream` is not valid on entry, this operation has no effect.
218 ///
219 /// \pre The behavior is undefined unless `0 <= length`.
220 static bsl::ostream& printString(bsl::ostream& stream,
221 const char *string,
222 int length,
223 bool escapeBackSlash = false);
224
225 /// Print in hexadecimal format the contents of the specified `buffer`
226 /// of the specified `length` to the specified `stream`, and return a
227 /// reference providing modifiable access to `stream`.
228 ///
229 /// \pre The behavior is undefined unless `0 <= length`.
230 static bsl::ostream& hexDump(bsl::ostream& stream,
231 const char *buffer,
232 int length);
233
234 /// Print to the specified `stream` the specified `numBuffers` buffers
235 /// supplied by specified `buffers` in a hexadecimal representation (16
236 /// chars per line) followed by the ASCII representation. Return a
237 /// reference providing modifiable access to `stream`. The array of
238 /// buffers are supplied as a `bsl::pair<const char*, int> *` where the
239 /// first element is a pointer to the data, and the second element is the length of the buffer.
240 ///
241 /// \pre The behavior is undefined unless `0 <= numBuffers`.
242 ///
243 /// \note Note that the contents of the buffers are
244 /// concatenated and boundaries between buffers are not demarcated.
245 static bsl::ostream& hexDump(bsl::ostream& stream,
247 int numBuffers);
248
249 /// Print to the specified `stream` the uppercase hex encoding of the
250 /// byte sequence defined by the specified `begin` and `end` iterators
251 /// of the parameterized `INPUT_ITERATOR` type, and return a reference providing modifiable access to `stream`.
252 ///
253 /// \note Note that `INPUT_ITERATOR`
254 /// need not be random-access, i.e., it need support only increment
255 /// (`++`) and equality comparison (`==`). See the non-template version
256 /// of this function if insulation and/or code bloat are a concern.
257 template <class INPUT_ITERATOR>
258 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
259 INPUT_ITERATOR begin,
260 INPUT_ITERATOR end);
261
262 /// Print to the specified `stream` the uppercase hex encoding of the
263 /// byte sequence defined by the specified `begin` and `end` iterators
264 /// into the specified `stream`, and return a reference providing
265 /// modifiable access to `stream`. This function insulates clients from
266 /// its implementation, but unlike the member template version (above),
267 /// requires random access iterators of type `const char *`.
268 ///
269 /// \pre The behavior is undefined unless both `begin` and `end` refer to the
270 /// same block of contiguous memory, and `begin <= end`.
271 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
272 const char *begin,
273 const char *end);
274
275 /// Print to the specified `stream` the contents of the specified
276 /// `buffer` having the specified `length` on a single line, and return
277 /// a reference to the modifiable `stream`.
278 ///
279 /// \pre The behavior is undefined unless `0 <= length`.
280 static bsl::ostream& singleLineHexDump(bsl::ostream& stream,
281 const char *buffer,
282 int length);
283};
284
285 // ===========================
286 // struct PrintStringHexDumper
287 // ===========================
288
289/// Utility for hex dumping a blob to standard output streams. This class
290/// has `operator<<` defined for it, so it can be used as follows:
291/// @code
292/// bsl::vector<char> blob;
293/// blob.resize(1024);
294///
295/// // ... fill up the blob with some data ...
296///
297/// bsl::cout << PrintStringHexDumper(blob.data(), blob.size())
298/// << bsl::endl;
299/// @endcode
300///
301/// See @ref bdlb_print
303
304 // DATA
305 const char *d_data_p;
307
308 // CREATORS
309
310 /// Create a `PrintStringHexDumper` object that can insert to an output
311 /// stream a formated (possibly multi-lined) hexadecimal representation
312 /// the specified `data` of the specified `length`.
313 PrintStringHexDumper(const char *data, int length);
314};
315
316// FREE OPERATORS
317
318/// Hex dump the data referenced by the specified `rhs` to the specified
319/// `stream`.
320inline
321bsl::ostream& operator<<(bsl::ostream& stream,
322 const PrintStringHexDumper& rhs);
323
324 // =====================================
325 // struct PrintStringSingleLineHexDumper
326 // =====================================
327
328/// Utility for hex dumping a string with no extra formatting to standard
329/// output streams. This class has `operator<<` defined for it, so it can
330/// be used as follows:
331/// @code
332/// bsl::string str;
333///
334/// // ... fill up the str with some data ...
335///
336/// bsl::cout
337/// << PrintStringSingleLineHexDumper(str.c_str(), str.size())
338/// << bsl::endl;
339/// @endcode
340///
341/// See @ref bdlb_print
343
344 // DATA
345 const char *d_data_p;
347
348 // CREATORS
349
350 /// Create a `PrintStringSingleLineHexDumper` object that can insert to
351 /// an output stream a single-line hexadecimal representation the
352 /// specified `data` of the specified `length`.
353 PrintStringSingleLineHexDumper(const char *data, int length);
354};
355
356// FREE OPERATORS
357
358/// Hex dump the data referenced by the specified `rhs` to the specified
359/// `stream`.
360inline
361bsl::ostream& operator<<(bsl::ostream& stream,
363
364// ============================================================================
365// INLINE DEFINITIONS
366// ============================================================================
367
368 // ------------
369 // struct Print
370 // ------------
371
372// CLASS METHODS
373template <class INPUT_ITERATOR>
374bsl::ostream& Print::singleLineHexDump(bsl::ostream& stream,
375 INPUT_ITERATOR begin,
376 INPUT_ITERATOR end)
377{
378 enum { k_LOCAL_BUF_SIZE = 512 };
379 static const char HEX[] = "0123456789ABCDEF";
380
381 char buf[k_LOCAL_BUF_SIZE];
382
383 unsigned int offset = 0;
384
385 for (; begin != end; ++begin) {
386
387 if (offset >= (k_LOCAL_BUF_SIZE - 1)) {
388 stream.write(buf, offset);
389 offset = 0;
390 }
391
392 const unsigned char c = *begin;
393
394 buf[offset++] = HEX[(c >> 4) & 0xF];
395 buf[offset++] = HEX[c & 0xF];
396 }
397
398 if (offset != 0) {
399 stream.write(buf, offset);
400 }
401
402 return stream;
403}
404
405inline
406bsl::ostream& Print::singleLineHexDump(bsl::ostream& stream,
407 const char *buffer,
408 int length)
409{
410 BSLS_REVIEW(buffer);
411 BSLS_REVIEW(0 <= length);
412
413 return singleLineHexDump(stream, buffer, buffer + length);
414}
415
416 // ---------------------------
417 // struct PrintStringHexDumper
418 // ---------------------------
419
420// CREATORS
421inline
423 int length)
424: d_data_p(data)
425, d_length(length)
426{
427 BSLS_REVIEW(data);
428 BSLS_REVIEW(0 <= length);
429
430}
431} // close package namespace
432
433// FREE OPERATORS
434inline
435bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
436 const PrintStringHexDumper& rhs)
437{
438 return Print::hexDump(stream, rhs.d_data_p, rhs.d_length);
439}
440
441namespace bdlb {
442 // -------------------------------------
443 // struct PrintStringSingleLineHexDumper
444 // -------------------------------------
445
446// CREATORS
447inline
449 const char *data,
450 int length)
451: d_data_p(data)
452, d_length(length)
453{
454 BSLS_REVIEW(data);
455 BSLS_REVIEW(0 <= length);
456}
457} // close package namespace
458
459// FREE OPERATORS
460inline
461bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
462 const PrintStringSingleLineHexDumper& rhs)
463{
464 return Print::singleLineHexDump(stream, rhs.d_data_p, rhs.d_length);
465}
466
467
468
469#endif
470
471// ----------------------------------------------------------------------------
472// Copyright 2015 Bloomberg Finance L.P.
473//
474// Licensed under the Apache License, Version 2.0 (the "License");
475// you may not use this file except in compliance with the License.
476// You may obtain a copy of the License at
477//
478// http://www.apache.org/licenses/LICENSE-2.0
479//
480// Unless required by applicable law or agreed to in writing, software
481// distributed under the License is distributed on an "AS IS" BASIS,
482// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
483// See the License for the specific language governing permissions and
484// limitations under the License.
485// ----------------------------- END-OF-FILE ----------------------------------
486
487/** @} */
488/** @} */
489/** @} */
Definition bslstl_pair.h:1280
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_REVIEW(X)
Definition bsls_review.h:1019
Definition bdlb_algorithmworkaroundutil.h:74
bsl::ostream & operator<<(bsl::ostream &stream, const BigEndianInt16 &integer)
Definition bdlb_print.h:302
int d_length
Definition bdlb_print.h:306
const char * d_data_p
Definition bdlb_print.h:305
PrintStringHexDumper(const char *data, int length)
Definition bdlb_print.h:422
Definition bdlb_print.h:342
const char * d_data_p
Definition bdlb_print.h:345
PrintStringSingleLineHexDumper(const char *data, int length)
Definition bdlb_print.h:448
int d_length
Definition bdlb_print.h:346
Definition bdlb_print.h:173
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:374
static bsl::ostream & hexDump(bsl::ostream &stream, bsl::pair< const char *, int > *buffers, int numBuffers)