2.4 Resizing a Typed Buffer

You can change the size of a buffer allocated with tpalloc() by using the tprealloc(3c) function as follows:

char* tprealloc(char *ptr, long size)

The following table describes the arguments to the tprealloc() function.

Table 2-3 tprealloc() Function Arguments

Argument Description
ptr Pointer to the buffer that is to be resized. This pointer must have been allocated originally by a call to tpalloc(). If it was not, the call fails and tperrno(5) is set to TPEINVAL to signify that invalid arguments have been passed to the function.
size Long integer specifying the new size of the buffer.

The pointer returned by tprealloc() points to a buffer of the same type as the original buffer. You must use the returned pointer to reference the resized buffer because the location of the buffer may have changed.

When you call the tprealloc() function to increase the size of the buffer, the Oracle Tuxedo system makes new space available to the buffer. When you call the tprealloc() function to make a buffer smaller, the system does not actually resize the buffer; instead, it renders the space beyond the specified size unusable. The actual content of the typed buffer remains unchanged. If you want to free up unused space, it is recommended that you copy the data into a buffer of the desired size and then free the larger buffer.

On error, the tprealloc() function returns the NULL pointer and sets tperrno to an appropriate value. Refer to tpalloc(3c) in Oracle Tuxedo ATMI C Function Reference for information on error codes.

WARNING:

If the tprealloc() function returns the NULL pointer, the contents of the buffer passed to it may have been altered and may be no longer valid.

The following listing shows how to reallocate space for a STRING buffer.

Listing Resizing a Buffer

#include <stdio.h>
#include “atmi.h”

char instr[100]; /* string to capture stdin input strings */
long s1len, s2len; /* string 1 and string 2 lengths */
char *s1ptr, *s2ptr; /* string 1 and string 2 pointers */

main()

{

(void)gets(instr);             /* get line from stdin */
s1len = (long)strlen(instr)+1; /* determine its length */

join application

if ((s1ptr = tpalloc(“STRING”, NULL, s1len)) == NULL) {
fprintf(stderr, “tpalloc failed for echo of: %s\n”, instr);
leave application
exit(1);
}
(void)strcpy(s1ptr, instr);

make communication call with buffer pointed to by s1ptr

(void)gets(instr);        /* get another line from stdin */
s2len = (long)strlen(instr)+1; /* determine its length */
if ((s2ptr = tprealloc(s1ptr, s2len)) == NULL) {
  fprintf(stderr, “tprealloc failed for echo of: %s\n”, instr);
  free s1ptr's buffer
  leave application
  exit(1);
}
(void)strcpy(s2ptr, instr);

make communication call with buffer pointed to by s2ptr
 . . .
}

The following listing (an expanded version of the previous example) shows how to check for occurrences of all possible error codes.

Listing Error Checking for tprealloc()

. . .
if ((s2ptr=tprealloc(s1ptr, s2len)) == NULL)
  switch(tperrno) {
  case TPEINVAL:
    fprintf(stderr, "given invalid arguments\n");
    fprintf(stderr, "will do tpalloc instead\n");
      tpfree(s1ptr);
if ((s2ptr=tpalloc("STRING", NULL, s2len)) == NULL) {
  fprintf(stderr, "tpalloc failed for echo of: %s\n", instr);
leave application
exit(1);
}
break;
case TPEPROTO:
   fprintf(stderr, "tried to tprealloc before tpinit;\n");
   fprintf(stderr, "program error; contact product support\n");
     leave application
    exit(1);
case TPESYSTEM:
   fprintf(stderr,
     "ORACLE Tuxedo error occurred; consult today's userlog file\n");
      leave application
  exit(1);
case TPEOS:
   fprintf(stderr, "Operating System error %d occurred\n",Uunixerr);
   leave application
   exit(1);
default:
fprintf(stderr,
"Error from tpalloc: %s\n", tpstrerror(tperrno));
break;
}