/ src / libnml / cms / cms_dup.cc
cms_dup.cc
  1  /********************************************************************
  2  * Description: cms_dup.cc
  3  *   Provides the interface to CMS used by NML update functions
  4  *   including a CMS update function for all the basic C data types
  5  *   to convert NMLmsgs to XDR.
  6  *
  7  *   Derived from a work by Fred Proctor & Will Shackleford
  8  *
  9  * Author:
 10  * License: LGPL Version 2
 11  * System: Linux
 12  *    
 13  * Copyright (c) 2004 All rights reserved.
 14  *
 15  * Last change: 
 16  ********************************************************************/
 17  
 18  #ifdef __cplusplus
 19  extern "C" {
 20  #endif
 21  
 22  #include <errno.h>		/* errno global variable */
 23  #include <limits.h>		/* SHORT_MIN, SHOR_MAX, . . . */
 24  #include <float.h>		/* FLT_MIN, FLT_MAX */
 25  #include <string.h>		/* memcpy(), strerror() */
 26  #include <stdlib.h>		/* strtol(), strtoul(), strtod() */
 27  #include <stdio.h>		/* sprintf() */
 28  #include <ctype.h>		/* isspace() */
 29  
 30  #ifdef __cplusplus
 31  }
 32  #endif
 33  #include "cms.hh"		/* class CMS */
 34  #include "cms_dup.hh"		/* class CMS_DISPLAY_ASCII_UPDATER */
 35  #include "rcs_print.hh"		/* rcs_print_error() */
 36  #define DEFAULT_WARNING_COUNT_MAX 100
 37  /* Member functions for CMS_DISPLAY_ASCII_UPDATER Class */
 38      CMS_DISPLAY_ASCII_UPDATER::CMS_DISPLAY_ASCII_UPDATER(CMS * _cms_parent):
 39  CMS_UPDATER(_cms_parent)
 40  {
 41      /* Set pointers to NULL. */
 42      begin_current_string = (char *) NULL;
 43      end_current_string = (char *) NULL;
 44      max_length_current_string = 0;
 45      updating_string = 0;
 46  
 47      /* Store and validate constructors arguments. */
 48      cms_parent = _cms_parent;
 49      if (NULL == cms_parent) {
 50  	rcs_print_error("CMS parent for updater is NULL.\n");
 51  	return;
 52      }
 53  
 54      /* Allocate the encoded header too large, and find out what size it
 55         really is. */
 56      encoded_header = malloc(neutral_size_factor * sizeof(CMS_HEADER));
 57      if (encoded_header == NULL) {
 58  	rcs_print_error("CMS:can't malloc encoded_header");
 59  	status = CMS_CREATE_ERROR;
 60  	return;
 61      }
 62  
 63      /* If queuing is enabled, then initialize streams for encoding and
 64         decoding the header with the queue information. */
 65      if (cms_parent->queuing_enabled) {
 66  	/* Allocate the encoded header too large, and find out what size it
 67  	   really is. */
 68  	encoded_queuing_header =
 69  	    malloc(neutral_size_factor * sizeof(CMS_QUEUING_HEADER));
 70      }
 71      using_external_encoded_data = 0;
 72      warning_count = 0;
 73      warning_count_max = DEFAULT_WARNING_COUNT_MAX;
 74  }
 75  
 76  CMS_DISPLAY_ASCII_UPDATER::~CMS_DISPLAY_ASCII_UPDATER()
 77  {
 78      if (NULL != encoded_data && !using_external_encoded_data) {
 79  	free(encoded_data);
 80  	encoded_data = NULL;
 81      }
 82      if (NULL != encoded_header) {
 83  	free(encoded_header);
 84  	encoded_header = NULL;
 85      }
 86      if (NULL != encoded_queuing_header) {
 87  	free(encoded_queuing_header);
 88  	encoded_queuing_header = NULL;
 89      }
 90  }
 91  
 92  void CMS_DISPLAY_ASCII_UPDATER::find_next_comma()
 93  {
 94      while (*end_current_string != ',' && *end_current_string) {
 95  	if (length_current_string >= max_length_current_string) {
 96  	    rcs_print_error("Maximum string length exceeded.\n");
 97  	    status = CMS_UPDATE_ERROR;
 98  	    return;
 99  	}
100  	length_current_string++;
101  	end_current_string++;
102      }
103      end_current_string++;
104      length_current_string++;
105  }
106  
107  int CMS_DISPLAY_ASCII_UPDATER::set_mode(CMS_UPDATER_MODE _mode)
108  {
109      mode = _mode;
110      CMS_UPDATER::set_mode(_mode);
111      switch (mode) {
112      case CMS_NO_UPDATE:
113  	begin_current_string = end_current_string = (char *) NULL;
114  	max_length_current_string = 0;
115  	length_current_string = 0;
116  	break;
117  
118      case CMS_ENCODE_DATA:
119  	begin_current_string = end_current_string = (char *) encoded_data;
120  	max_length_current_string = neutral_size_factor * size;
121  	if (max_length_current_string > cms_parent->max_encoded_message_size) {
122  	    max_length_current_string = cms_parent->max_encoded_message_size;
123  	}
124  	length_current_string = 0;
125  	encoding = 1;
126  	break;
127  
128      case CMS_DECODE_DATA:
129  	begin_current_string = end_current_string = (char *) encoded_data;
130  	max_length_current_string = neutral_size_factor * size;
131  	if (max_length_current_string > cms_parent->max_encoded_message_size) {
132  	    max_length_current_string = cms_parent->max_encoded_message_size;
133  	}
134  	length_current_string = 0;
135  	encoding = 0;
136  	break;
137  
138      case CMS_ENCODE_HEADER:
139  	begin_current_string = end_current_string = (char *) encoded_header;
140  	max_length_current_string = neutral_size_factor * sizeof(CMS_HEADER);
141  	length_current_string = 0;
142  	encoding = 1;
143  	break;
144  
145      case CMS_DECODE_HEADER:
146  	begin_current_string = end_current_string = (char *) encoded_header;
147  	max_length_current_string = neutral_size_factor * sizeof(CMS_HEADER);
148  	length_current_string = 0;
149  	encoding = 0;
150  	break;
151  
152      case CMS_ENCODE_QUEUING_HEADER:
153  	begin_current_string = end_current_string =
154  	    (char *) encoded_queuing_header;
155  	max_length_current_string =
156  	    neutral_size_factor * sizeof(CMS_QUEUING_HEADER);
157  	length_current_string = 0;
158  	encoding = 1;
159  	break;
160  
161      case CMS_DECODE_QUEUING_HEADER:
162  	begin_current_string = end_current_string =
163  	    (char *) encoded_queuing_header;
164  	max_length_current_string =
165  	    neutral_size_factor * sizeof(CMS_QUEUING_HEADER);
166  	length_current_string = 0;
167  	encoding = 0;
168  	break;
169  
170      default:
171  	rcs_print_error("CMS updater in invalid mode.\n");
172  	return (-1);
173      }
174      return (0);
175  }
176  
177  int CMS_DISPLAY_ASCII_UPDATER::check_pointer(char *_pointer, long _bytes)
178  {
179      if (NULL == cms_parent || NULL == begin_current_string
180  	|| NULL == end_current_string) {
181  	rcs_print_error
182  	    ("CMS_DISPLAY_ASCII_UPDATER: Required pointer is NULL.\n");
183  	return (-1);
184      }
185      if (length_current_string + _bytes * 4 > max_length_current_string) {
186  	rcs_print_error
187  	    ("CMS_DISPLAY_ASCII_UPDATER: length of current string(%ld) + bytes to add of(%ld) exceeds maximum of %ld.\n",
188  	    length_current_string, _bytes * 4, max_length_current_string);
189  	return (-1);
190      }
191      return (cms_parent->check_pointer(_pointer, _bytes));
192  }
193  
194  /* Repositions the data buffer to the very beginning */
195  void CMS_DISPLAY_ASCII_UPDATER::rewind()
196  {
197      CMS_UPDATER::rewind();
198      end_current_string = begin_current_string;
199      if (encoding) {
200  	memset(begin_current_string, 0, max_length_current_string);
201      }
202      length_current_string = 0;
203      if (NULL != cms_parent) {
204  	cms_parent->format_size = 0;
205      }
206  }
207  
208  int CMS_DISPLAY_ASCII_UPDATER::get_encoded_msg_size()
209  {
210      return (length_current_string);
211  }
212  
213  /* Char functions */
214  
215  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update_char(char &x)
216  {
217  
218      if (encoding) {
219  	if (x == ',') {
220  	    strcat(end_current_string, "\\c");
221  	    end_current_string += 2;
222  	    length_current_string += 2;
223  	} else if (x == '\\') {
224  	    strcat(end_current_string, "\\\\");
225  	    end_current_string += 2;
226  	    length_current_string += 2;
227  	} else if (x == '\n') {
228  	    strcat(end_current_string, "\\n");
229  	    end_current_string += 2;
230  	    length_current_string += 2;
231  	} else if (x == 0 && updating_string) {
232  	} else if (!isgraph(x)) {
233  	    sprintf(end_current_string, "\\%3.3d", x);
234  	    end_current_string += 4;
235  	    length_current_string += 4;
236  	} else {
237  	    end_current_string[0] = x;
238  	    end_current_string++;
239  	    length_current_string++;
240  	}
241      } else {
242  	if (end_current_string[0] == ',' || end_current_string[0] == 0) {
243  	    x = 0;
244  	} else if (end_current_string[0] == '\\') {
245  	    if (end_current_string[1] == 'c') {
246  		x = ',';
247  		end_current_string += 2;
248  		length_current_string += 2;
249  	    } else if (end_current_string[1] == '\\') {
250  		x = end_current_string[1];
251  		length_current_string += 2;
252  		end_current_string += 2;
253  	    } else if (end_current_string[1] == 'n') {
254  		x = '\n';
255  		length_current_string += 2;
256  		end_current_string += 2;
257  	    } else {
258  		char temp[4];
259  		memcpy(temp, end_current_string + 1, 3);
260  		temp[3] = 0;
261  		x = (char) strtol(temp, (char **) NULL, 10);
262  		length_current_string += 4;
263  		end_current_string += 4;
264  	    }
265  	} else {
266  	    x = end_current_string[0];
267  	    end_current_string += 1;
268  	    length_current_string++;
269  	}
270      }
271      return status;
272  }
273  
274  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(bool &x)
275  {
276      /* Check to see if the pointers are in the proper range. */
277      if (-1 == check_pointer((char *) &x, sizeof(char))) {
278  	return (CMS_UPDATE_ERROR);
279      }
280  
281      update_char((char &)x);
282      end_current_string[0] = ',';
283      find_next_comma();
284      return (status);
285  }
286  
287  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(char &x)
288  {
289      /* Check to see if the pointers are in the proper range. */
290      if (-1 == check_pointer((char *) &x, sizeof(char))) {
291  	return (CMS_UPDATE_ERROR);
292      }
293  
294      update_char(x);
295      end_current_string[0] = ',';
296      find_next_comma();
297      return (status);
298  }
299  
300  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(char *x, unsigned int len)
301  {
302      /* Check to see if the pointers are in the proper range. */
303      if (-1 == check_pointer((char *) x, sizeof(char) * len)) {
304  	return (CMS_UPDATE_ERROR);
305      }
306      unsigned int i;
307      updating_string = 1;
308  
309      for (i = 0; i < len; i++) {
310  	update_char(x[i]);
311  	if (x[i] == 0) {
312  	    break;
313  	}
314      }
315      end_current_string[0] = ',';
316      find_next_comma();
317      updating_string = 0;
318      return (status);
319  }
320  
321  /* Char functions */
322  
323  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned char &x)
324  {
325      /* Check to see if the pointers are in the proper range. */
326      if (-1 == check_pointer((char *) &x, sizeof(unsigned char))) {
327  	return (CMS_UPDATE_ERROR);
328      }
329      char cx;
330      cx = (char) x;
331      update_char(cx);
332      x = (unsigned char) x;
333      end_current_string[0] = ',';
334      find_next_comma();
335  
336      return (status);
337  }
338  
339  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned char *x,
340      unsigned int len)
341  {
342      /* Check to see if the pointers are in the proper range. */
343      if (-1 == check_pointer((char *) x, sizeof(unsigned char) * len)) {
344  	return (CMS_UPDATE_ERROR);
345      }
346      char cx;
347      unsigned int i;
348  
349      for (i = 0; i < len; i++) {
350  	cx = (char) x[i];
351  	update_char(cx);
352  	x[i] = (unsigned char) cx;
353      }
354      end_current_string[0] = ',';
355      find_next_comma();
356      return (status);
357  }
358  
359  /* Short functions */
360  
361  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(short int &x)
362  {
363      /* Check to see if the pointers are in the proper range. */
364      if (-1 == check_pointer((char *) &x, sizeof(short))) {
365  	return (CMS_UPDATE_ERROR);
366      }
367  
368      if (encoding) {
369  	sprintf(end_current_string, "%+d,", x);
370      } else {
371  	errno = 0;
372  	long number = strtol(end_current_string, (char **) NULL, 10);
373  	if (errno != 0) {
374  	    rcs_print_error
375  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtol of(%s).\n",
376  		errno, strerror(errno), end_current_string);
377  	    return (status = CMS_UPDATE_ERROR);
378  	}
379  	if ((number < SHRT_MIN || SHRT_MAX < number)
380  	    && warning_count < warning_count_max) {
381  	    warning_count++;
382  	    rcs_print_error
383  		("CMS_DISPLAY_ASCII_UPDATER:  (warning) Number %ld out of range for short(%d,%d)\n",
384  		number, SHRT_MIN, SHRT_MAX);
385  	}
386  	x = (short) number;
387      }
388      find_next_comma();
389  
390      return (status);
391  }
392  
393  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(short *x, unsigned int len)
394  {
395      /* Check to see if the pointers are in the proper range. */
396      if (-1 == check_pointer((char *) x, sizeof(short) * len)) {
397  	return (CMS_UPDATE_ERROR);
398      }
399  
400      for (unsigned int i = 0; i < len; i++) {
401  	if (CMS_UPDATE_ERROR == update(x[i])) {
402  	    return (CMS_UPDATE_ERROR);
403  	}
404      }
405      return (status);
406  }
407  
408  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned short int &x)
409  {
410      /* Check to see if the pointers are in the proper range. */
411      if (-1 == check_pointer((char *) &x, sizeof(short))) {
412  	return (CMS_UPDATE_ERROR);
413      }
414  
415      if (encoding) {
416  	sprintf(end_current_string, "%d,", x);
417      } else {
418  	if (0 == end_current_string[0]) {
419  	    x = 0;
420  	    return status;
421  	}
422  	errno = 0;
423  	unsigned long number =
424  	    strtoul(end_current_string, (char **) NULL, 10);
425  	if (errno != 0) {
426  	    rcs_print_error
427  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtoul of (%s).\n",
428  		errno, strerror(errno), end_current_string);
429  	    return (status = CMS_UPDATE_ERROR);
430  	}
431  	if (number > USHRT_MAX && warning_count < warning_count_max) {
432  	    warning_count++;
433  	    rcs_print_error
434  		("CMS_DISPLAY_ASCII_UPDATER: Number %ld out of range for unsigned short(0,%d)\n",
435  		number, USHRT_MAX);
436  	}
437  	x = (unsigned short) number;
438      }
439      find_next_comma();
440  
441      return (status);
442  }
443  
444  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned short *x,
445      unsigned int len)
446  {
447      /* Check to see if the pointers are in the proper range. */
448      if (-1 == check_pointer((char *) x, sizeof(unsigned short) * len)) {
449  	return (CMS_UPDATE_ERROR);
450      }
451  
452      for (unsigned int i = 0; i < len; i++) {
453  	if (CMS_UPDATE_ERROR == update(x[i])) {
454  	    return (CMS_UPDATE_ERROR);
455  	}
456      }
457      return (status);
458  }
459  
460  /* Int  functions */
461  
462  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(int &x)
463  {
464      /* Check to see if the pointers are in the proper range. */
465      if (-1 == check_pointer((char *) &x, sizeof(int))) {
466  	return (CMS_UPDATE_ERROR);
467      }
468  
469      if (encoding) {
470  	if (x > 9999999 && warning_count < warning_count_max) {
471  	    warning_count++;
472  	    rcs_print_error
473  		("CMS_DISPLAY_ASCII_UPDATER: int %d is too large. (Use type long.)\n",
474  		x);
475  	}
476  	sprintf(end_current_string, "%+6d,", x);
477      } else {
478  	if (0 == end_current_string[0]) {
479  	    x = 0;
480  	    return status;
481  	}
482  	errno = 0;
483  	long number = strtol(end_current_string, (char **) NULL, 10);
484  	if (errno != 0) {
485  	    rcs_print_error
486  		("CMS_DISPLAY_ASCII_UPDATER: Error %d:%s occurred during strtol of (%s).\n",
487  		errno, strerror(errno), end_current_string);
488  	    return (status = CMS_UPDATE_ERROR);
489  	}
490  	if ((number < ((long) INT_MIN)) || ((((long) INT_MAX) < number) && (warning_count < warning_count_max))) {
491  	    warning_count++;
492  	    rcs_print_error
493  		("CMS_DISPLAY_ASCII_UPDATER: (warning) Number %ld out of range for int(%d,%d)\n",
494  		number, INT_MIN, INT_MAX);
495  	}
496  	x = (int) number;
497      }
498      find_next_comma();
499  
500      return (status);
501  }
502  
503  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(int *x, unsigned int len)
504  {
505      /* Check to see if the pointers are in the proper range. */
506      if (-1 == check_pointer((char *) x, sizeof(int) * len)) {
507  	return (CMS_UPDATE_ERROR);
508      }
509  
510      for (unsigned int i = 0; i < len; i++) {
511  	if (CMS_UPDATE_ERROR == update(x[i])) {
512  	    return (CMS_UPDATE_ERROR);
513  	}
514      }
515      return (status);
516  }
517  
518  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned int &x)
519  {
520      /* Check to see if the pointers are in the proper range. */
521      if (-1 == check_pointer((char *) &x, sizeof(unsigned int))) {
522  	return (CMS_UPDATE_ERROR);
523      }
524  
525      if (encoding) {
526  	if (x > 9999999 && warning_count < warning_count_max) {
527  	    warning_count++;
528  	    rcs_print_error
529  		("CMS_DISPLAY_ASCII_UPDATER: unsigned int %d is too large. (Use type long.)\n",
530  		x);
531  	}
532  	sprintf(end_current_string, "%6d,", x);
533      } else {
534  	if (0 == end_current_string[0]) {
535  	    x = 0;
536  	    return status;
537  	}
538  	errno = 0;
539  	unsigned long number =
540  	    strtoul(end_current_string, (char **) NULL, 10);
541  	if (errno != 0) {
542  	    rcs_print_error
543  		("CMS_DISPLAY_ASCII_UPDATER: Error %d:%s occurred during strtoul of (%s).\n",
544  		errno, strerror(errno), end_current_string);
545  	    return (status = CMS_UPDATE_ERROR);
546  	}
547  	if (UINT_MAX < number && warning_count < warning_count_max) {
548  	    rcs_print_error
549  		("CMS_DISPLAY_ASCII_UPDATER: Number %ld out of range for unsigned int (0,%u)\n",
550  		number, UINT_MAX);
551  	}
552  	x = (unsigned int) number;
553      }
554      find_next_comma();
555  
556      return (status);
557  }
558  
559  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned int *x,
560      unsigned int len)
561  {
562      /* Check to see if the pointers are in the proper range. */
563      if (-1 == check_pointer((char *) x, sizeof(unsigned int) * len)) {
564  	return (CMS_UPDATE_ERROR);
565      }
566  
567      for (unsigned int i = 0; i < len; i++) {
568  	if (CMS_UPDATE_ERROR == update(x[i])) {
569  	    return (CMS_UPDATE_ERROR);
570  	}
571      }
572      return (status);
573  }
574  
575  /* Long functions */
576  
577  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(long int &x)
578  {
579      /* Check to see if the pointers are in the proper range. */
580      if (-1 == check_pointer((char *) &x, sizeof(long))) {
581  	return (CMS_UPDATE_ERROR);
582      }
583  
584      if (encoding) {
585  	end_current_string[15] = 0;
586  	sprintf(end_current_string, "%+ld,", x);
587  	if (end_current_string[15] != 0 && warning_count < warning_count_max) {
588  	    warning_count++;
589  	    rcs_print_error
590  		("CMS_DISPLAY_ASCII_UPDATER: (warning) long with value %-14ld caused an overflow\n",
591  		x);
592  	}
593  	end_current_string[15] = 0;
594      } else {
595  	if (0 == end_current_string[0]) {
596  	    x = 0;
597  	    return status;
598  	}
599  	errno = 0;
600  	long number = strtol(end_current_string, (char **) NULL, 10);
601  	if (errno != 0) {
602  	    rcs_print_error
603  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtol of(%s).\n",
604  		errno, strerror(errno), end_current_string);
605  	    return (status = CMS_UPDATE_ERROR);
606  	}
607  	x = number;
608      }
609      find_next_comma();
610  
611      return (status);
612  }
613  
614  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(long *x, unsigned int len)
615  {
616      /* Check to see if the pointers are in the proper range. */
617      if (-1 == check_pointer((char *) x, sizeof(long) * len)) {
618  	return (CMS_UPDATE_ERROR);
619      }
620  
621      for (unsigned int i = 0; i < len; i++) {
622  	if (CMS_UPDATE_ERROR == update(x[i])) {
623  	    return (CMS_UPDATE_ERROR);
624  	}
625      }
626      return (status);
627  }
628  
629  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned long int &x)
630  {
631      /* Check to see if the pointers are in the proper range. */
632      if (-1 == check_pointer((char *) &x, sizeof(unsigned long))) {
633  	return (CMS_UPDATE_ERROR);
634      }
635  
636      if (encoding) {
637  	sprintf(end_current_string, "%ld,", x);
638  
639      } else {
640  	if (0 == end_current_string[0]) {
641  	    x = 0;
642  	    return status;
643  	}
644  	errno = 0;
645  	unsigned long number =
646  	    strtoul(end_current_string, (char **) NULL, 10);
647  	if (errno != 0) {
648  	    rcs_print_error
649  		("CMS_DISPLAY_ASCII_UPDATER: Error %d:%s occurred during strtoul of(%s).\n",
650  		errno, strerror(errno), end_current_string);
651  	    return (status = CMS_UPDATE_ERROR);
652  	}
653  	x = number;
654      }
655      find_next_comma();
656  
657      return (status);
658  }
659  
660  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(unsigned long *x,
661      unsigned int len)
662  {
663      /* Check to see if the pointers are in the proper range. */
664      if (-1 == check_pointer((char *) x, sizeof(unsigned long) * len)) {
665  	return (CMS_UPDATE_ERROR);
666      }
667  
668      for (unsigned int i = 0; i < len; i++) {
669  	if (CMS_UPDATE_ERROR == update(x[i])) {
670  	    return (CMS_UPDATE_ERROR);
671  	}
672      }
673      return (status);
674  }
675  
676  /* Float functions */
677  
678  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(float &x)
679  {
680      /* Check to see if the pointers are in the proper range. */
681      if (-1 == check_pointer((char *) &x, sizeof(float))) {
682  	return (CMS_UPDATE_ERROR);
683      }
684  
685      if (encoding) {
686  	sprintf(end_current_string, "%f,", x);
687      } else {
688  	if (0 == end_current_string[0]) {
689  	    x = 0;
690  	    return status;
691  	}
692  	errno = 0;
693  	double number = strtod(end_current_string, (char **) NULL);
694  	if (errno != 0) {
695  	    rcs_print_error
696  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtol of (%s).\n",
697  		errno, strerror(errno), end_current_string);
698  	    return (status = CMS_UPDATE_ERROR);
699  	}
700  	if ((number < -FLT_MAX || FLT_MAX < number) &&
701  	    warning_count < warning_count_max) {
702  	    warning_count++;
703  	    rcs_print_error
704  		("CMS_DISPLAY_ASCII_UPDATER: (warning) Number %lf out of range for float(%f,%f)\n",
705  		number, -FLT_MAX, FLT_MAX);
706  	}
707  	x = (float) number;
708      }
709      find_next_comma();
710  
711      return (status);
712  }
713  
714  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(float *x, unsigned int len)
715  {
716      /* Check to see if the pointers are in the proper range. */
717      if (-1 == check_pointer((char *) x, sizeof(float) * len)) {
718  	return (CMS_UPDATE_ERROR);
719      }
720  
721      for (unsigned int i = 0; i < len; i++) {
722  	if (CMS_UPDATE_ERROR == update(x[i])) {
723  	    return (CMS_UPDATE_ERROR);
724  	}
725      }
726      return (status);
727  }
728  
729  /* Double functions */
730  
731  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(double &x)
732  {
733      /* Check to see if the pointers are in the proper range. */
734      if (-1 == check_pointer((char *) &x, sizeof(double))) {
735  	return (CMS_UPDATE_ERROR);
736      }
737  
738      if (encoding) {
739  	sprintf(end_current_string, "%f,", x);
740      } else {
741  	if (0 == end_current_string[0]) {
742  	    x = 0;
743  	    return status;
744  	}
745  	errno = 0;
746  	double number = strtod(end_current_string, (char **) NULL);
747  	if (errno != 0) {
748  	    rcs_print_error
749  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtol of (%s).\n",
750  		errno, strerror(errno), end_current_string);
751  	    return (status = CMS_UPDATE_ERROR);
752  	}
753  	x = number;
754      }
755      find_next_comma();
756  
757      return (status);
758  }
759  
760  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(double *x, unsigned int len)
761  {
762      /* Check to see if the pointers are in the proper range. */
763      if (-1 == check_pointer((char *) x, sizeof(double) * len)) {
764  	return (CMS_UPDATE_ERROR);
765      }
766  
767      for (unsigned int i = 0; i < len; i++) {
768  	if (CMS_UPDATE_ERROR == update(x[i])) {
769  	    return (CMS_UPDATE_ERROR);
770  	}
771      }
772      return (status);
773  }
774  
775  /* long double functions */
776  
777  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(long double &x)
778  {
779      /* Check to see if the pointers are in the proper range. */
780      if (-1 == check_pointer((char *) &x, sizeof(long double))) {
781  	return (CMS_UPDATE_ERROR);
782      }
783  
784      if (encoding) {
785  	end_current_string[15] = 0;
786  	sprintf(end_current_string, "%-14.8e,", (double) x);
787      } else {
788  	if (0 == end_current_string[0]) {
789  	    x = 0;
790  	    return status;
791  	}
792  	errno = 0;
793  	double number = strtod(end_current_string, (char **) NULL);
794  	if (errno != 0) {
795  	    rcs_print_error
796  		("CMS_DISPLAY_ASCII_UPDATER: Error %d: %s occurred during strtod of (%s).\n",
797  		errno, strerror(errno), end_current_string);
798  	    return (status = CMS_UPDATE_ERROR);
799  	}
800  	x = (long double) number;
801      }
802      find_next_comma();
803  
804      return (status);
805  }
806  
807  CMS_STATUS CMS_DISPLAY_ASCII_UPDATER::update(long double *x, unsigned int len)
808  {
809      /* Check to see if the pointers are in the proper range. */
810      if (-1 == check_pointer((char *) x, sizeof(long double) * len)) {
811  	return (CMS_UPDATE_ERROR);
812      }
813  
814      for (unsigned int i = 0; i < len; i++) {
815  	if (CMS_UPDATE_ERROR == update(x[i])) {
816  	    return (CMS_UPDATE_ERROR);
817  	}
818      }
819      return (status);
820  }