DEC C++
Class Library Reference Manual


Previous Contents Index

To accommodate the need for strings of arbitrary length, this class supports a dynamic mode. When a strstreambuf object is in dynamic mode, space for the character is allocated as needed. When the sequence is extended too far, it is copied to a new array.

If your program expects a buffer to be allocated when none was allocated, then the iostream package allocates a default buffer, with a length specified by BUFSIZ as defined in stdio.h. The package then issues the following warning:


Warning; a null pointer to streambuf was passed to ios::init() 


CONSTRUCTORS AND DESTRUCTORS

strstreambuf()

Constructs an empty strstreambuf object in dynamic mode. This means that space is automatically allocated to accommodate characters put into the strstreambuf object (using the new and delete operators). Because this may require copying the original characters, programs that have many characters to insert should use setbuf() to inform the strstreambuf object about the needed allocation of space, or to use one of the constructors that follow.

strstreambuf(int n)

Constructs an empty strstreambuf object in dynamic mode. The initial allocation of space is at least n bytes.

strstreambuf(char *ptr, int n, char *pstart)

strstreambuf(unsigned char *ptr, int n, unsigned char *pstart)

Constructs a strstreambuf object to use the bytes starting at ptr. The strstreambuf object is in static mode; it does not grow dynamically. If n is positive, then the n bytes starting at ptr are used as the strstreambuf object. If n is 0, ptr is presumed to point to the beginning of a null-terminated string and the bytes of that string (not including the terminating null character) constitute the strstreambuf object. If n is negative, then the strstreambuf object is presumed to continue indefinitely.

The get pointer is initialized to ptr. The put pointer is initialized to pstart. If pstart is not null, then the initial sequence for fetching (the get area) consists of the bytes between ptr and pstart. If pstart is null, then storing operations are treated as errors and the initial get area consists of the entire array.

strstreambuf(void *(*a)(long n), void (*f)(void *ptr))

Constructs an empty strstreambuf object in dynamic mode. a is used as the allocator function in dynamic mode. The argument passed to a is a long denoting the number of bytes to be allocated. If the a argument is null, the new operator is used. f is used to free (or delete) get, put, or reserve areas returned by a. The argument to f becomes a pointer to the array allocated by a. If f is null, the delete operator is used.


MEMBER FUNCTIONS

void freeze(int n)

Inhibits (freezes) automatic deletion of the current array if n is nonzero, or permits (unfreezes) automatic deletion if n is 0. Deletion normally occurs when more space is needed, or when the strstreambuf object is being destroyed. Only space obtained through dynamic allocation is free. Storing characters into a strstreambuf that was dynamically allocated and is now frozen causes an error (the effect is undefined). If you want to resume storing characters in such a strstreambuf object you can thaw (unfreeze) it.

virtual int overflow(int c)

In classes derived from streambuf, it is called to consume characters. If c is not EOF, overflow(c) also must either save c or consume it. Although it can be called at other times, this function is usually called when the put area is full and an attempt is being made to store a new character. The normal action is to consume the characters between pbase() and pptr(), call setp() to establish a new put area, and (if c != EOF) store c using sputc(). overflow(c) should return EOF to indicate an error; otherwise, it should return something else.

virtual streambuf *setbuf(char *ptr, int n)

Causes the strstreambuf object to remember n (if ptr is 0); this ensures that at least n bytes are allocated during the next dynamic mode allocation.

char *str()

Returns a pointer to the first character in the current array and freezes the strstreambuf object. If the strstreambuf object was constructed with an explicit array, the function returns a pointer to that array. If the strstreambuf object is in dynamic allocation mode but nothing has been restored yet, the returned pointer is null.

virtual int underflow()

In classes derived from streambuf, it is called to supply characters for fetching; that is, to create a condition in which the get area is not empty. If this function is called when characters are in the get area, it should return the first character. If the get area is empty, it should create a nonempty get area and return the next character (which it should also leave in the get area). If no more characters are available, underflow() should return EOF and leave an empty get area.


Chapter 5
Messages Package

The Messages package provides a way to retrieve messages stored in a catalog or file that is separate from your program. It consists of a single class, Messages, that retrieves the text of a message.

A message set number is a number specified in the message catalog source file with a $set n line, ranging from 1 to NL_SETMAX, as defined in nl_types.h. To process the message catalog source file, use the gencat command. For more information see the gencat(1int) reference page.


Messages class

Retrieves message text for a message number.

HEADER FILE

#include <messages.hxx>

Alternative Header

None.


DECLARATION


class Messages 
{ 
public: 
   Messages(const char *filename_arg, int set_arg = 0, 
        const char *default_file_location_arg = (const char *)(NULL)); 
   ~Messages(); 
   
   const char *text(int msg_arg, const char *fallback_text_arg, int set_arg = 0); 
};               


EXCEPTION HANDLING

If the message file cannot be opened or closed, the system prints one of the following error messages on cerr (as appropriate):

CONSTRUCTORS AND DESTRUCTORS

Messages(const char *filename_arg, int set_arg, const char *default_file_location_arg)

Constructs a Messages object. The filename_arg argument specifies the file name of the message catalog. The set_arg argument specifies the message number to set; a value of 0 specifies that the default setting (NL_SETD as defined in nl_types.h) be used. The default_file_location_arg argument specifies the default location of filename_arg.

~Messages()

Deletes a Messages object.

MEMBER FUNCTION

const char *text(int msg_arg, const char *fallback_text_arg, int set_arg)

Returns the text of the message specified by the msg_arg argument. The fallback_text_arg argument indicates the text to return if the message cannot be found. The set_arg argument specifies the message set number; a value of 0 causes the system to use the set number provided to the constructor.

Example

The following is a sample message source file:

$ messages_example.msf   Messages example -- Digital UNIX message catalog 
 
$ set 1 EXAMPLE_SET 
 
1 This is an example error message 
 
$ End of messages_example.msf 

Entering the following gencat command compiles this file:


$ gencat messages_example.cat message_example.msf 

The following program retrieves the sample error message:


#include <iostream.hxx> 
#include <messages.hxx> 
 
const char *message_file_name = "messages_example"; 
const char *message_file_location = "%N.cat"; 
int message_set_example = 1; 
 
Messages m_example (message_file_name, message_set_example, 
    message_file_location); 
 
int main() 
{ 
    cout << 
        "text of example message 1: " << 
        m_example.text(1, "fallback message 1") << 
        "\n"; 
 
    cout << 
        "text of example message 2: " << 
        m_example.text(2, "fallback message 2") << 
        "\n"; 
 
    return EXIT_SUCCESS; 
} 
 
 
 

Executing the program without compiling the message source file displays the following fallback messages:


text of example message 1: fallback message 1 
text of example message 2: fallback message 2 

After compiling the message source file and setting the NLSPATH environment variable, executing the program retrieves the text of the error message and displays the second fallback message:


text of example message 1: This is an example error message 
text of example message 2: fallback message 2 


Chapter 6
Mutex Package

The Mutex package provides a way to synchronize access to user-defined objects. It consists of a single class, Mutex, that manages the creation, locking and unlocking of Mutex objects.

Construction of a Mutex object creates a recursive mutex that users can lock and unlock using the appropriate member functions or parameterized manipulators. A recursive mutex is a mutex that can be locked many times by the same thread without causing the thread to enter a deadlock state. To completely unlock this kind of mutex, the thread must unlock the mutex the same number of times that the thread locked the mutex. For more information see the Guide to DECthreads manual.

Note

User-defined objects are not automatically thread safe. Users must supply synchronization for such objects if they are shared between threads.

Mutex class

Provides a means whereby users can synchronize access to user-defined objects.

HEADER FILE

#include <mutex.hxx>

Alternative Header

#include <mutex.h>


DECLARATION


class Mutex 
{ 
public: 
             Mutex(); 
             ~Mutex(); 
 
   void      lock(); 
   void      unlock();   
   int       trylock(); 
};               


DESCRIPTION

The synchronization process consists of locking and unlocking Mutex objects associated with user-defined objects. Digital recommends that users create a Mutex object for each user-defined object that needs to be synchronized between threads. Users are then responsible for locking and unlocking the Mutex object to coordinate access to the associated object.

To do the locking and unlocking, you can use the lock and unlock member functions (see Example). Alternatively, if a user-defined object is derived from the istream or ostream classes, you can use the lock and unlock parameterized manipulators, where the parameter is the Mutex object (see the Global Declarations section in Chapter 4).


CONSTRUCTORS AND DESTRUCTORS

Mutex()

Constructs a Mutex object, in effect creating but not locking a recursive mutex.

~Mutex()

Deletes a Mutex object.

MEMBER FUNCTIONS

void lock()

Locks a recursive mutex. If the mutex is locked by another thread, the current thread is blocked until the mutex becomes available.

void unlock()

Unlocks a recursive mutex.

int trylock()

Immediately returns to the caller a value of 0 if the mutex is already locked by another thread. Otherwise, this function locks the mutex and returns a value of 1.

Example


#include <string.hxx> 
#include <mutex.hxx> 
   .
   .
   .
String string1; 
Mutex string1_lock; 
 
string1_lock.lock(); 
string1 = "Hello, "; 
string1 += "how are you?"; 
cout << string1; 
string1_lock.unlock(); 

This example synchronizes a sequence of operations on a string object, using the lock() and unlock() member functions.


Chapter 7
Objection Package

The Objection package provides a way to implement simple error handling in DEC C++. You can use this package to catch run-time errors encountered in using classes, and to change or restore actions associated with such errors.


Global Declaration

This typedef is used by, but is not a member of, the Objection class.

HEADER

#include <objection.hxx>

Alternative Header

#include <Objection.h>


DECLARATION


typedef int Objection_action(const char*); 


TYPE

Objection_action

Is the type of an action routine that can be called by the function Objection::raise.

Objection class

Provides the capability to handle and report errors.

HEADER

#include <objection.hxx>

Alternative Header

#include <Objection.h>


DECLARATION


class Objection 
{ 
 
public: 
                      Objection(); 
                      Objection(Objection_action *); 
    int               raise(const char * = ""); 
    Objection_action  *appoint(Objection_action *); 
    Objection_action  *appoint(); 
    Objection_action  *ignore(); 
}; 


DESCRIPTION

This class provides ways to handle objections. An objection is a potential error condition that your program can encounter. The user appoints an error-handling function. An Objection object's raise() function invokes the appointed function by passing it a character string that contains an error message. At any point in your program, you can appoint a new error-handling function, reappoint the original function, or specify that an objection be ignored.

CONSTRUCTORS

Objection()

Constructs an Objection object with no default action (error handler).

Objection(Objection_action *new_action)

Constructs an Objection object with a pointer to the default error handler. The handler is a function that takes one parameter of type const char*msg and returns an int. See the raise() member function for more information.

MEMBER FUNCTIONS

Objection_action *appoint()

Specifies that the handler for the objection is the default error handler (if one exists) and returns the previous action associated with the specified objection. Specifies that the objection not be ignored.

Objection_action *appoint(Objection_action *new_action)

Specifies a new handler for the objection and returns the previous action associated with the specified objection. Specifies that the objection not be ignored.

Objection_action *ignore()

Specifies that the objection be ignored (no error handler is invoked if the objection is raised). This function returns the previous action associated with the specified objection.

int raise(const char *msg = "")

Raises a specified objection, passing a string (error message) to an error handler (if one exists). If no handler exists, or if the handler returns a 0, the default handler is called. The raise function returns the value returned by the last handler it called.

If no default handler exists, then the function returns 0. A 0 is also returned if the objection is ignored. Generally, the return of a nonzero value means that the error handling succeeded, and the return of a 0 value means the error handling failed.

The following example changes the default error handler for the
stack(int)::overflow_error objection:


#include <stdlib.h> 
#include <vector.hxx> 
#include <objection.hxx> 
 
vectordeclare(int) 
stackdeclare(int) 
 
vectorimplement(int) 
stackimplement(int) 
 
stack(int) s(10); 
 
int error(const char *errmsg) 
{ 
    cerr << "ERROR TRAPPED: " << errmsg << " -- ABORTING\n"; 
    cerr.flush(); 
    abort(); 
    return 0; 
} 
 
void main() 
{ 
    Objection_action *save_action; 
    save_action = stack(int)::overflow_error.appoint(error); 
    for(int i=0; i<100; i++)  //push too many things onto stack 
        s.push(i); 
    stack(int)::overflow_error.appoint(save_action); 
} 

When this example executes, the following message prints out:


ERROR TRAPPED: Stack underflow -- ABORTING 
IOT trap (core dumped) 


Previous Next Contents Index