home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_5.ZIP / WINSRC.ZIP / INT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  8.7 KB  |  313 lines

  1. //    Zinc Interface Library - INTEGER.CPP
  2. //    COPYRIGHT (C) 1990, 1991.  All Rights Reserved.
  3. //    Zinc Software Incorporated.  Pleasant Grove, Utah  USA
  4.  
  5. #include "ui_win.hpp"
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, char *a_value,
  12.     char *a_range, USHORT flags, USHORT woFlags,
  13.     int (*validate)(void *object, int ccode)) :
  14.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  15. {
  16.     type = NUM_CHAR;
  17.     Constructor(a_value, width, flags, a_range,
  18.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  19.         UIW_NUMBER::ValidWholeNumber, validate);
  20. }
  21.  
  22. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, unsigned char *a_value,
  23.     char *a_range, USHORT flags, USHORT woFlags,
  24.     int (*validate)(void *object, int ccode)) :
  25.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  26. {
  27.     type = NUM_CHAR;
  28.     Constructor(a_value, width, flags | NMF_UNSIGNED, a_range,
  29.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  30.         UIW_NUMBER::ValidWholeNumber, validate);
  31. }
  32.  
  33. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, int *a_value,
  34.     char *a_range, USHORT flags, USHORT woFlags,
  35.     int (*validate)(void *object, int ccode)) :
  36.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  37. {
  38.     type = NUM_SHORT;
  39.     Constructor(a_value, width, flags, a_range,
  40.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  41.         UIW_NUMBER::ValidWholeNumber, validate);
  42. }
  43.  
  44. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, unsigned int *a_value,
  45.     char *a_range, USHORT flags, USHORT woFlags,
  46.     int (*validate)(void *object, int ccode)) :
  47.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  48. {
  49.     type = NUM_SHORT;
  50.     Constructor(a_value, width, flags | NMF_UNSIGNED, a_range,
  51.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  52.         UIW_NUMBER::ValidWholeNumber, validate);
  53. }
  54.  
  55. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, short *a_value,
  56.     char *a_range, USHORT flags, USHORT woFlags,
  57.     int (*validate)(void *object, int ccode)) :
  58.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  59. {
  60.     type = NUM_SHORT;
  61.     Constructor(a_value, width, flags, a_range,
  62.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  63.         UIW_NUMBER::ValidWholeNumber, validate);
  64. }
  65.  
  66. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, unsigned short *a_value,
  67.     char *a_range, USHORT flags, USHORT woFlags,
  68.     int (*validate)(void *object, int ccode)) :
  69.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  70. {
  71.     type = NUM_SHORT;
  72.     Constructor(a_value, width, flags | NMF_UNSIGNED, a_range,
  73.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  74.         UIW_NUMBER::ValidWholeNumber, validate);
  75. }
  76.  
  77. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, long *a_value,
  78.     char *a_range, USHORT flags, USHORT woFlags,
  79.     int (*validate)(void *object, int ccode)) :
  80.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  81. {
  82.     type = NUM_LONG;
  83.     Constructor(a_value, width, flags, a_range,
  84.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  85.         UIW_NUMBER::ValidWholeNumber, validate);
  86. }
  87.  
  88. UIW_NUMBER::UIW_NUMBER(int left, int top, int width, unsigned long *a_value,
  89.     char *a_range, USHORT flags, USHORT woFlags,
  90.     int (*validate)(void *object, int ccode)) :
  91.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  92. {
  93.     type = NUM_LONG;
  94.     Constructor(a_value, width, flags | NMF_UNSIGNED, a_range,
  95.         UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  96.         UIW_NUMBER::ValidWholeNumber, validate);
  97. }
  98.  
  99. void UIW_NUMBER::WholeToAscii()
  100. {
  101.     switch (type)
  102.     {
  103.     case NUM_CHAR:
  104.         if (FlagSet(woStatus, WOS_UNANSWERED))
  105.             *((char *)value) = 0;
  106.         sprintf(state.text, "%d", nmFlags & NMF_UNSIGNED ?
  107.             *((unsigned char *)value) : *((char *)value));
  108.         break;
  109.  
  110.     case NUM_SHORT:
  111.         if (FlagSet(woStatus, WOS_UNANSWERED))
  112.             *((short *)value) = 0;
  113.         sprintf(state.text, nmFlags & NMF_UNSIGNED ? "%u" : "%d",
  114.             nmFlags & NMF_UNSIGNED ? *((unsigned short *)value) :
  115.             *((short *)value));
  116.         break;
  117.  
  118.     case NUM_LONG:
  119.         if (FlagSet(woStatus, WOS_UNANSWERED))
  120.             *((long *)value) = 0;
  121.         sprintf(state.text, nmFlags & NMF_UNSIGNED ? "%lu" : "%ld",
  122.             nmFlags & NMF_UNSIGNED ? *((unsigned long *)value) :
  123.             *((long *)value));
  124.         break;
  125.     }
  126. }
  127.  
  128. void UIW_NUMBER::AsciiToWhole()
  129. {
  130.     switch (type)
  131.     {
  132.     case NUM_CHAR:
  133.         if (FlagSet(nmFlags, NMF_UNSIGNED))
  134.             *((unsigned char *)value) = atoi(state.text);
  135.         else
  136.         {
  137.             *((char *)value) = atoi(state.text);
  138.             if (state.isNegative)
  139.                 *((char *)value) = - *((char *)value);
  140.         }
  141.         break;
  142.  
  143.     case NUM_SHORT:
  144.         if (FlagSet(nmFlags, NMF_UNSIGNED))
  145.             *((unsigned short *)value) = (unsigned short) atol(state.text);
  146.         else
  147.         {
  148.             *((short *)value) = atoi(state.text);
  149.             if (state.isNegative)
  150.                 *((short *)value) = - *((short *)value);
  151.         }
  152.         break;
  153.  
  154.     case NUM_LONG:
  155.         if (FlagSet(nmFlags, NMF_UNSIGNED))
  156.             *((unsigned long *)value) = strtoul(state.text, 0, 10);
  157.         else
  158.         {
  159.             *((long *)value) = atol(state.text);
  160.             if (state.isNegative)
  161.                 *((long *)value) = - *((long *)value);
  162.         }
  163.         break;
  164.     }
  165. }
  166.  
  167. int UIW_NUMBER::ValidWholeBetween(char *minValue, char *maxValue)
  168. {
  169.     int minNegative;
  170.     int maxNegative;
  171.     int minLength;
  172.     int maxLength;
  173.     int    valLength;
  174.     char *valPtr = state.text;
  175.     int valNegative = state.isNegative;
  176.  
  177.     minNegative = (minValue[0] == '-') ? TRUE : FALSE;
  178.     if (minNegative)
  179.         *minValue++;
  180.     maxNegative = (maxValue[0] == '-') ? TRUE : FALSE;
  181.     if (maxNegative)
  182.         *maxValue++;
  183.     if (!minNegative && valNegative || maxNegative && !valNegative)
  184.         return(FALSE);
  185.  
  186.     // Take out leading zeroes.
  187.     while (*minValue == '0' && *(minValue + 1))
  188.         minValue++;
  189.     while (*maxValue == '0' && *(maxValue + 1))
  190.         maxValue++;
  191.     while (*valPtr == '0' && *(valPtr + 1))
  192.         valPtr++;
  193.  
  194.     valLength = (valPtr) ? strlen(valPtr) : 0;
  195.     minLength = (minValue) ? strlen(minValue) : 0;
  196.     if ((!minNegative &&
  197.          !valNegative &&
  198.          (minLength > valLength ||
  199.           (minLength == valLength && strcmp(minValue, valPtr) > 0))) ||
  200.         (minNegative &&
  201.          valNegative &&
  202.          (minLength < valLength ||
  203.           (minLength == valLength && strcmp(minValue, valPtr) < 0))))
  204.         return(FALSE);
  205.  
  206.     /* Compare the value against the maximum */
  207.     maxLength = (maxValue) ? strlen(maxValue) : 0;
  208.     if ((!maxNegative &&
  209.          !valNegative &&
  210.          (maxLength < valLength ||
  211.           (maxLength == valLength && strcmp(maxValue, valPtr) < 0))) ||
  212.         (maxNegative &&
  213.          valNegative &&
  214.          (maxLength > valLength ||
  215.           (maxLength == valLength && strcmp(maxValue, valPtr) > 0))))
  216.         return(FALSE);
  217.  
  218.     /* The value falls within the minimum and maximum values */
  219.     return(TRUE);
  220. }
  221.  
  222. int UIW_NUMBER::ValidWholeInRange(char *a_range)
  223. {
  224.     /* See if a range exists */
  225.     if (!a_range || a_range[0] == '\0')
  226.         return(TRUE);
  227.  
  228.     /* See if the value is in the specified range */
  229.     char minValue[20];
  230.     char maxValue[20];
  231.     int validNumber = FALSE;
  232.     int offset = 0;
  233.     int rangeLength = (a_range) ? strlen(a_range) : 0;
  234.     while (!validNumber && offset < rangeLength)
  235.     {
  236.         offset = ParseRange(a_range, offset, minValue, maxValue);
  237.         validNumber = ValidWholeBetween(minValue, maxValue);
  238.     }
  239.     return(validNumber);
  240. }
  241.  
  242. int UIW_NUMBER::ValidWholeNumber()
  243. {
  244.     char *absoluteRange;
  245.  
  246.     switch (type)
  247.     {
  248.     case NUM_CHAR:
  249.         absoluteRange = (FlagSet(nmFlags, NMF_UNSIGNED)) ?
  250.             "0..255" : "-128..127";
  251.         break;
  252.  
  253.     case NUM_SHORT:
  254.         absoluteRange = (FlagSet(nmFlags, NMF_UNSIGNED)) ? 
  255.             "0..65535" : "-32768..32767";
  256.         break;
  257.  
  258.     case NUM_LONG:
  259.         absoluteRange = (FlagSet(nmFlags, NMF_UNSIGNED)) ?
  260.             "0..4294967295" : "-2147483648..2147483647";
  261.         break;
  262.     }
  263.  
  264.     if (range && !ValidWholeInRange(range))
  265.     {
  266.         RangeError(range);
  267.         return (FALSE);
  268.     }
  269.     else if (!ValidWholeInRange(absoluteRange))
  270.     {
  271.         RangeError(absoluteRange);
  272.         return (FALSE);
  273.     }
  274.  
  275.     return (TRUE);
  276. }
  277.  
  278. #ifdef ZIL_LOAD
  279. UIW_INTEGER::UIW_INTEGER(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  280.     UIW_NUMBER(name, file, loadFlags | L_SUB_LEVEL)
  281. {
  282.     windowID[0] = ID_NUMBER;
  283.     windowID[1] = ID_STRING;
  284.  
  285.     if (!file)
  286.         file = _storage;
  287.     file->Load(&type);
  288.     file->Load(&nmFlags);
  289.     value = new double;
  290.     file->Load(value, sizeof(double));
  291.     UIW_NUMBER::Constructor(value, relative.right - relative.left + 1,
  292.         nmFlags, 0, UIW_NUMBER::WholeToAscii, UIW_NUMBER::AsciiToWhole,
  293.         UIW_NUMBER::ValidWholeNumber, NULL);
  294.     file->Load(&range);
  295.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  296.         delete file;
  297. }
  298. #endif
  299.  
  300. #ifdef ZIL_STORE
  301. void UIW_INTEGER::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  302. {
  303.     search.type = ID_INTEGER;
  304.     UIW_NUMBER::Store(name, file, storeFlags | S_SUB_LEVEL);
  305.     file->Store(type);
  306.     file->Store(nmFlags);
  307.     file->Store(value, sizeof(double));
  308.     file->Store(range);
  309.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  310.         file->ObjectSize(name, search);
  311. }
  312. #endif
  313.