BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_context.h
Go to the documentation of this file.
1/// @file ball_context.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_context.h -*-C++-*-
8#ifndef INCLUDED_BALL_CONTEXT
9#define INCLUDED_BALL_CONTEXT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_context ball_context
15/// @brief Provide a container for the context of a transmitted log record.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_context
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_context-purpose"> Purpose</a>
25/// * <a href="#ball_context-classes"> Classes </a>
26/// * <a href="#ball_context-description"> Description </a>
27/// * <a href="#ball_context-constraints"> Constraints </a>
28/// * <a href="#ball_context-usage"> Usage </a>
29/// * <a href="#ball_context-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#ball_context-purpose}
32/// Provide a container for the context of a transmitted log record.
33///
34/// # Classes {#ball_context-classes}
35///
36/// - ball::Context: context of a transmitted log record
37///
38/// @see ball_transmission, ball_observer, ball_record
39///
40/// # Description {#ball_context-description}
41/// This component defines a container for aggregating a message's
42/// publication cause, as well as the record (or message) index and sequence
43/// length of messages delivered as part of a message sequence. Note that
44/// messages that are not part of a sequence (i.e., PASSTHROUGH) will have the
45/// index and sequence length fields set to 0 and 1, respectively.
46///
47/// The context attributes held by `ball::Context` are detailed in the following
48/// table:
49/// @code
50/// Attribute Type Description Default
51/// ----------------- ------------------------ ----------------- -----------
52/// transmissionCause ball::Transmission::Cause cause of output PASSTHROUGH
53/// recordIndex int index in sequence 0
54/// sequenceLength int # records in seq. 1
55/// @endcode
56///
57/// ## Constraints {#ball_context-constraints}
58///
59///
60/// This attribute class assumes that the following constraints on contained
61/// values hold:
62/// @code
63/// if (ball::Transmission::e_PASSTHROUGH == transmissionCause()) {
64/// assert(0 == recordIndex());
65/// assert(1 == sequenceLength());
66/// }
67/// else {
68/// assert(
69/// ball::Transmission::e_TRIGGER == transmissionCause()
70/// || ball::Transmission::e_TRIGGER_ALL == transmissionCause()
71/// || ball::Transmission::e_MANUAL_PUBLISH == transmissionCause()
72/// || ball::Transmission::e_MANUAL_PUBLISH_ALL == transmissionCause());
73/// assert(0 <= recordIndex());
74/// assert(1 <= sequenceLength());
75/// assert(recordIndex() < sequenceLength());
76/// }
77/// @endcode
78/// A static `isValid` method is provided to verify that particular
79/// `transmissionCause`, `recordIndex`, and `sequenceLength` values are valid
80/// before they are used to create or (unilaterally) modify a context object.
81///
82/// ## Usage {#ball_context-usage}
83///
84///
85/// This section illustrates intended use of this component.
86///
87/// ### Example 1: Basic Usage {#ball_context-example-1-basic-usage}
88///
89///
90/// A `ball::Context` object holds sufficient information to determine the
91/// length of a message sequence and the index of a message within that
92/// sequence. In addition, `ball::Context` indicates the cause for the
93/// transmission of a message. The following example illustrates the essentials
94/// of working with these contextual attributes.
95///
96/// This example illustrates the use of `ball::Context` by a hypothetical
97/// logging system. First we define a simple logger class named `my_Logger`:
98/// @code
99/// // my_logger.h
100///
101/// #include <string>
102/// #include <vector>
103///
104/// class my_Logger {
105///
106/// bsl::vector<bsl::string> archive; // log message archive
107///
108/// // NOT IMPLEMENTED
109/// my_Logger(const my_Logger&);
110/// my_Logger& operator=(const my_Logger&);
111///
112/// // PRIVATE MANIPULATORS
113/// void publish(const bsl::string& message,
114/// const ball::Context& context);
115///
116/// public:
117/// // TYPES
118/// enum Severity { ERROR = 0, WARN = 1, TRACE = 2 };
119///
120/// // CREATORS
121/// my_Logger();
122/// ~my_Logger();
123///
124/// // MANIPULATORS
125/// void logMessage(const bsl::string& message, Severity severity);
126/// };
127/// @endcode
128/// Clients of `my_Logger` log messages at one of three severity levels through
129/// the `logMessage` method. Messages logged with `TRACE` severity are simply
130/// archived by `my_Logger`. Messages logged with `WARN` severity are archived
131/// and also output to `stdout` (say, to a console terminal overseen by an
132/// operator) through the `publish` method. Messages logged with `ERROR`
133/// severity report serious conditions; these trigger a dump of the backlog of
134/// messages that `my_Logger` has archived to that point. The `ball::Context`
135/// argument passed to `publish` provides contextual information regarding the
136/// message it is being asked to publish.
137///
138/// A complete implementation of this trivial logger follows:
139/// @code
140/// // my_Logger.cpp
141///
142/// // PRIVATE MANIPULATORS
143/// void my_Logger::publish(const bsl::string& message,
144/// const ball::Context& context)
145/// {
146/// using namespace std;
147///
148/// switch (context.transmissionCause()) {
149/// case ball::Transmission::e_PASSTHROUGH: {
150/// cout << "Single Pass-through Message: ";
151/// } break;
152/// case ball::Transmission::e_TRIGGER_ALL: {
153/// cout << "Remotely "; // no 'break'; concatenated
154/// // output
155/// } break;
156/// case ball::Transmission::e_TRIGGER: {
157/// cout << "Triggered Publication Sequence: Message "
158/// << context.recordIndex() + 1 // Account for 0-based index.
159/// << " of " << context.sequenceLength() << ": ";
160/// } break;
161/// case ball::Transmission::e_MANUAL_PUBLISH: {
162/// cout << "Manually triggered Message: ";
163/// } break;
164/// default: {
165/// cout << "***ERROR*** Unsupported Message Cause: ";
166/// return;
167/// } break;
168/// }
169/// cout << message << endl;
170/// }
171///
172/// // CREATORS
173/// my_Logger::my_Logger() { }
174/// my_Logger::~my_Logger() { }
175///
176/// // MANIPULATORS
177/// void my_Logger::logMessage(const bsl::string& message, Severity severity)
178/// {
179/// archive.append(message);
180/// switch (severity) {
181/// case TRACE: {
182/// // Do nothing beyond archiving the message.
183/// } break;
184/// case WARN: {
185/// ball::Context context(ball::Transmission::e_PASSTHROUGH, 0, 1);
186/// publish(message, context);
187/// } break;
188/// case ERROR: {
189/// int index = 0;
190/// int length = archive.length();
191/// ball::Context context(ball::Transmission::e_TRIGGER,
192/// index, length);
193/// while (length--) {
194/// publish(archive[length], context);
195/// context.setRecordIndexRaw(++index);
196/// }
197/// archive.removeAll(); // flush archive
198/// } break;
199/// }
200/// }
201/// @endcode
202/// Note that `ball::Transmission::e_TRIGGER_ALL` is not used by `my_Logger`,
203/// but is included in the switch statement for completeness.
204///
205/// Finally, we declare a `my_Logger` named `logger` and simulate the logging of
206/// several messages of varying severity:
207/// @code
208/// my_Logger logger;
209/// bsl::string message;
210///
211/// message = "TRACE 1"; logger.logMessage(message, my_Logger::TRACE);
212/// message = "TRACE 2"; logger.logMessage(message, my_Logger::TRACE);
213/// message = "WARNING"; logger.logMessage(message, my_Logger::WARN);
214/// message = "TRACE 3"; logger.logMessage(message, my_Logger::TRACE);
215/// message = "TROUBLE!"; logger.logMessage(message, my_Logger::ERROR);
216/// @endcode
217/// The following output is produced on `stdout`:
218/// @code
219/// Single Pass-through Message: WARNING
220/// Triggered Publication Sequence: Message 1 of 5: TROUBLE!
221/// Triggered Publication Sequence: Message 2 of 5: TRACE 3
222/// Triggered Publication Sequence: Message 3 of 5: WARNING
223/// Triggered Publication Sequence: Message 4 of 5: TRACE 2
224/// Triggered Publication Sequence: Message 5 of 5: TRACE 1
225/// @endcode
226/// Note that the warning message (severity `WARN`) was emitted first since the
227/// trace messages (severity `TRACE`) were simply archived. When the error
228/// message (severity `ERROR`) was logged, it triggered a dump of the complete
229/// message archive (in reverse order).
230/// @}
231/** @} */
232/** @} */
233
234/** @addtogroup bal
235 * @{
236 */
237/** @addtogroup ball
238 * @{
239 */
240/** @addtogroup ball_context
241 * @{
242 */
243
244#include <balscm_version.h>
245
246#include <ball_transmission.h>
247
248#include <bslma_allocator.h>
250
252
253#include <bsls_platform.h>
254
255#include <bsl_iosfwd.h>
256
257#ifndef BDE_OMIT_INTERNAL_DEPRECATED
258#if defined(BSLS_PLATFORM_CMP_MSVC) && defined(PASSTHROUGH)
259 // Note: on Windows -> WinGDI.h:#define PASSTHROUGH 19
260#undef PASSTHROUGH
261#endif
262#endif // BDE_OMIT_INTERNAL_DEPRECATED
263
264
265namespace ball {
266
267 // =============
268 // class Context
269 // =============
270
271/// This class provides a container for aggregating the auxiliary
272/// information needed to transmit a log record. For each context attribute
273/// in this class (e.g., `recordIndex`), there is an accessor for obtaining
274/// the attribute's value (`recordIndex`) and there are manipulators for
275/// changing the contained attribute values (`setAttributes` checks
276/// attribute constraints; `setAttributesRaw` and `setRecordIndexRaw` do
277/// not). A static `isValid` method is also provided to verify that
278/// particular attribute values are consistent before they are used to
279/// create or modify a context object. Note that it is the client's
280/// responsibility not to construct or unilaterally modify a context object
281/// to hold incompatible attribute values.
282///
283/// Additionally, this class supports a complete set of *value* *semantic*
284/// operations, including copy construction, assignment and equality
285/// comparison, and `ostream` printing. A precise operational definition of
286/// when two instances have the same value can be found in the description
287/// of `operator==` for the class. This class is *exception* *neutral* with
288/// no guarantee of rollback: if an exception is thrown during the
289/// invocation of a method on a pre-existing instance, the object is left in
290/// a valid state, but its value is undefined. In no event is memory
291/// leaked. Finally, *aliasing* (e.g., using all or part of an object as
292/// both source and destination) is supported in all cases.
293///
294/// See @ref ball_context
295class Context {
296
297 // DATA
298 Transmission::Cause d_transmissionCause; // cause of transmitted record
299 int d_recordIndex; // 0-based index within sequence
300 int d_sequenceLength; // number of records in sequence
301
302 // PRIVATE TYPES
303 enum { k_SUCCESS = 0, k_FAILURE = -1 };
304
305 // FRIENDS
306 friend bool operator==(const Context&, const Context&);
307
308 public:
309 // TRAITS
311
312 // CLASS METHODS
313
314 /// Return `true` if the specified `transmissionCause`, `recordIndex`,
315 /// and `sequenceLength` represent a valid context, and `false`
316 /// otherwise. (See the CONSTRAINTS section of the component-level
317 /// documentation above for a complete specification of the constraints
318 /// on attribute values.)
320 int recordIndex,
321 int sequenceLength);
322
323 // CREATORS
324
325 /// Create a context object with all attributes having default values.
326 /// Optionally specify a `basicAllocator` used to supply memory. If
327 /// `basicAllocator` is 0, the currently installed default allocator is
328 /// used. Note that `basicAllocator` is currently ignored.
329 Context(bslma::Allocator *basicAllocator = 0);
330
331 /// Create a context object indicating the specified
332 /// `transmissionCause`, `recordIndex`, and `sequenceLength` values.
333 /// Optionally specify a `basicAllocator` used to supply memory. If
334 /// `basicAllocator` is 0, the currently installed default allocator is
335 /// used. The behavior is undefined unless the resulting attribute
336 /// values are compatible. Note that `basicAllocator` is currently
337 /// ignored.
339 int recordIndex,
340 int sequenceLength,
341 bslma::Allocator *basicAllocator = 0);
342
343 /// Create a context object having the value of the specified `original`
344 /// context object. Optionally specify a `basicAllocator` used to
345 /// supply memory. If `basicAllocator` is 0, the currently installed
346 /// default allocator is used. Note that `basicAllocator` is currently
347 /// ignored.
348 Context(const Context& original, bslma::Allocator *basicAllocator = 0);
349
350 /// Destroy this object.
351 ~Context() = default;
352
353 // MANIPULATORS
354
355 /// Assign to this context object the value of the specified `rhs` context
356 /// object.
357 Context& operator=(const Context& rhs);
358
359 /// Set the value of this context object to the specified
360 /// `transmissionCause`, `recordIndex`, and `sequenceLength` values if
361 /// `transmissionCause`, `recordIndex`, and `sequenceLength` represent a
362 /// valid context. Return 0 on success, and a non-zero value (with no
363 /// effect on this context object) otherwise.
365 int recordIndex,
366 int sequenceLength);
367
368 /// Set the value of this context object to the specified
369 /// `transmissionCause`, `recordIndex`, and `sequenceLength` values.
370 /// The behavior is undefined if the resulting attribute values are
371 /// incompatible.
373 int recordIndex,
374 int sequenceLength);
375
376 /// Set the record index attribute of this context object to the specified
377 /// `index`. The behavior is undefined if the resulting attribute values
378 /// are incompatible.
379 void setRecordIndexRaw(int index);
380
381 // ACCESSORS
382
383 /// Return the transmission cause attribute of this context object.
385
386 /// Return the record index attribute of this context object.
387 int recordIndex() const;
388
389 /// Return the sequence length attribute of this context object.
390 int sequenceLength() const;
391
392 /// Format this object to the specified output `stream` at the
393 /// optionally specified indentation `level` and return a reference to
394 /// the modifiable `stream`. If `level` is specified, optionally
395 /// specify `spacesPerLevel`, the number of spaces per indentation level
396 /// for this and all of its nested objects. Each line is indented by
397 /// the absolute value of `level * spacesPerLevel`. If `level` is
398 /// negative, suppress indentation of the first line. If
399 /// `spacesPerLevel` is negative, suppress line breaks and format the
400 /// entire output on one line. If `stream` is initially invalid, this
401 /// operation has no effect.
402 bsl::ostream& print(bsl::ostream& stream,
403 int level = 0,
404 int spacesPerLevel = 4) const;
405};
406
407// FREE OPERATORS
408
409/// Return `true` if the specified `lhs` and `rhs` context objects have the
410/// same value, and `false` otherwise. Two context objects have the same
411/// value if each respective pair of corresponding attributes have the same
412/// value.
413bool operator==(const Context& lhs, const Context& rhs);
414
415/// Return `true` if the specified `lhs` and `rhs` context objects do not
416/// have the same value, and `false` otherwise. Two context objects do not
417/// have the same value if one or more respective attributes differ in
418/// value.
419bool operator!=(const Context& lhs, const Context& rhs);
420
421/// Write the specified `rhs` context to the specified output `stream` and
422/// return a reference to the modifiable `stream`.
423bsl::ostream& operator<<(bsl::ostream& stream, const Context& rhs);
424
425// ============================================================================
426// INLINE DEFINITIONS
427// ============================================================================
428
429 // -------------
430 // class Context
431 // -------------
432
433// CREATORS
434inline
436: d_transmissionCause(Transmission::e_PASSTHROUGH)
437, d_recordIndex(0)
438, d_sequenceLength(1)
439{
440}
441
442inline
444 int recordIndex,
445 int sequenceLength,
447: d_transmissionCause(transmissionCause)
448, d_recordIndex(recordIndex)
449, d_sequenceLength(sequenceLength)
450{
451}
452
453inline
455: d_transmissionCause(original.d_transmissionCause)
456, d_recordIndex(original.d_recordIndex)
457, d_sequenceLength(original.d_sequenceLength)
458{
459}
460
461// MANIPULATORS
462inline
464{
465 d_transmissionCause = rhs.d_transmissionCause;
466 d_recordIndex = rhs.d_recordIndex;
467 d_sequenceLength = rhs.d_sequenceLength;
468 return *this;
469}
470
471inline
473 int recordIndex,
474 int sequenceLength)
475{
476 d_transmissionCause = transmissionCause;
477 d_recordIndex = recordIndex;
478 d_sequenceLength = sequenceLength;
479}
480
481inline
483 int recordIndex,
484 int sequenceLength)
485{
488 return k_SUCCESS; // RETURN
489 }
490 return k_FAILURE;
491}
492
493inline
495{
496 d_recordIndex = index;
497}
498
499// ACCESSORS
500inline
502{
503 return d_transmissionCause;
504}
505
506inline
508{
509 return d_recordIndex;
510}
511
512inline
514{
515 return d_sequenceLength;
516}
517
518} // close package namespace
519
520// FREE OPERATORS
521inline
522bool ball::operator==(const Context& lhs, const Context& rhs)
523{
524 return lhs.d_transmissionCause == rhs.d_transmissionCause
525 && lhs.d_recordIndex == rhs.d_recordIndex
526 && lhs.d_sequenceLength == rhs.d_sequenceLength;
527}
528
529inline
530bool ball::operator!=(const Context& lhs, const Context& rhs)
531{
532 return !(lhs == rhs);
533}
534
535inline
536bsl::ostream& ball::operator<<(bsl::ostream& stream, const Context& rhs)
537{
538 return rhs.print(stream, 0, -1);
539}
540
541
542
543#endif
544
545// ----------------------------------------------------------------------------
546// Copyright 2015 Bloomberg Finance L.P.
547//
548// Licensed under the Apache License, Version 2.0 (the "License");
549// you may not use this file except in compliance with the License.
550// You may obtain a copy of the License at
551//
552// http://www.apache.org/licenses/LICENSE-2.0
553//
554// Unless required by applicable law or agreed to in writing, software
555// distributed under the License is distributed on an "AS IS" BASIS,
556// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
557// See the License for the specific language governing permissions and
558// limitations under the License.
559// ----------------------------- END-OF-FILE ----------------------------------
560
561/** @} */
562/** @} */
563/** @} */
Definition ball_context.h:295
Context & operator=(const Context &rhs)
Definition ball_context.h:463
BSLMF_NESTED_TRAIT_DECLARATION(Context, bslma::UsesBslmaAllocator)
Transmission::Cause transmissionCause() const
Return the transmission cause attribute of this context object.
Definition ball_context.h:501
int recordIndex() const
Return the record index attribute of this context object.
Definition ball_context.h:507
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
int sequenceLength() const
Return the sequence length attribute of this context object.
Definition ball_context.h:513
void setAttributesRaw(Transmission::Cause transmissionCause, int recordIndex, int sequenceLength)
Definition ball_context.h:472
~Context()=default
Destroy this object.
Context(bslma::Allocator *basicAllocator=0)
Definition ball_context.h:435
friend bool operator==(const Context &, const Context &)
int setAttributes(Transmission::Cause transmissionCause, int recordIndex, int sequenceLength)
Definition ball_context.h:482
void setRecordIndexRaw(int index)
Definition ball_context.h:494
static bool isValid(Transmission::Cause transmissionCause, int recordIndex, int sequenceLength)
Definition bslma_allocator.h:457
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition ball_administration.h:214
bsl::ostream & operator<<(bsl::ostream &output, const Attribute &attribute)
bool operator!=(const Attribute &lhs, const Attribute &rhs)
bool operator==(const Attribute &lhs, const Attribute &rhs)
Definition ball_transmission.h:208
Cause
Definition ball_transmission.h:213
Definition bslma_usesbslmaallocator.h:343