home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / TValidator.cpp < prev    next >
C/C++ Source or Header  |  1999-05-26  |  17KB  |  872 lines

  1. /*
  2.  * TValidator.cc
  3.  *
  4.  * Turbo Vision - Version 2.0
  5.  *
  6.  * Copyright (c) 1994 by Borland International
  7.  * All Rights Reserved.
  8.  *
  9.  * Modified by Sergio Sigala <ssigala@globalnet.it>
  10.  */
  11.  
  12. #define Uses_MsgBox
  13. #define Uses_TStreamable
  14. #define Uses_TValidator
  15. #define Uses_TPXPictureValidator
  16. #define Uses_TFilterValidator
  17. #define Uses_TRangeValidator
  18. #define Uses_TLookupValidator
  19. #define Uses_TStringLookupValidator
  20. #include <tvision/tv.h>
  21.  
  22. #include <ctype.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25.  
  26. // TValidator
  27.  
  28. TValidator::TValidator()
  29. {
  30.   status = 0;
  31.   options = 0;
  32. }
  33.  
  34. #if !defined(NO_STREAMABLE)
  35.  
  36. TValidator::TValidator( StreamableInit /* s */) /* XXX */
  37. {
  38. }
  39.  
  40. void* TValidator::read(ipstream& is)
  41. {
  42.   is >> options;
  43.   status = 0;
  44.  
  45.   return this;
  46. }
  47.  
  48. #endif
  49.  
  50. void TValidator::error()
  51. {
  52. }
  53.  
  54. Boolean TValidator::isValidInput(char* /* s */, Boolean /* suppressFill */) /* XXX */
  55. {
  56.   return True;
  57. }
  58.  
  59. Boolean TValidator::isValid(const char* /* s */) /* XXX */
  60. {
  61.   return True;
  62. }
  63.  
  64. #if !defined(NO_STREAMABLE)
  65.  
  66. void TValidator::write(opstream& os)
  67. {
  68.     os << options;
  69. }
  70.  
  71. #endif
  72.  
  73. //ushort TValidator::transfer(char* s, void* buffer, TVTransfer flag) /* XXX */
  74. ushort TValidator::transfer(char* /* s */, void* /* buffer */, /* XXX */
  75.     TVTransfer /* flag */) /* XXX */
  76. {
  77.   return 0;
  78. }
  79.  
  80. Boolean TValidator::validate(const char* s)
  81. {
  82.   if (!isValid(s))
  83.   {
  84.     error();
  85.     return False;
  86.   }
  87.   return True;
  88. }
  89.  
  90. // TPXPictureValidator
  91.  
  92. TPXPictureValidator::TPXPictureValidator(const char* aPic, Boolean autoFill)
  93.     : TValidator()
  94. {
  95.  
  96.   char *s;
  97.  
  98.   pic = newStr(aPic);
  99.   if ( autoFill )
  100.        options |= voFill;
  101.   s = "";
  102.   if (picture(s, False) != prEmpty)
  103.     status = vsSyntax;
  104. }
  105.  
  106. #if !defined(NO_STREAMABLE)
  107.  
  108. TPXPictureValidator::TPXPictureValidator( StreamableInit s) : TValidator(s)
  109. {
  110. }
  111.  
  112. void TPXPictureValidator::write(opstream& os)
  113. {
  114.   TValidator::write(os);
  115.   os.writeString(pic);
  116. }
  117.  
  118. void* TPXPictureValidator::read( ipstream& is )
  119. {
  120.   TValidator::read(is);
  121.   pic = is.readString();
  122.   index = jndex = 0;
  123.  
  124.   return this;
  125. }
  126.  
  127. #endif
  128.  
  129. TPXPictureValidator::~TPXPictureValidator()
  130. {
  131.   delete pic;
  132. };
  133.  
  134. void TPXPictureValidator::error()
  135. {
  136.   messageBox(mfError | mfOKButton, errorMsg, pic);
  137. }
  138.  
  139. Boolean TPXPictureValidator::isValidInput(char* s, Boolean suppressFill)
  140. {
  141.   Boolean doFill = Boolean(((options&voFill)!=0) && !suppressFill);
  142.  
  143.   return Boolean((pic==0) || (picture( (char*)s, doFill) != prError));
  144. }
  145.  
  146. Boolean TPXPictureValidator::isValid(const char* s)
  147. {
  148.   char str[256];
  149.  
  150.   strcpy(str, s);
  151.   return Boolean((pic == 0) || (picture(str, False) == prComplete));
  152. }
  153.  
  154. Boolean isNumber(char ch)
  155. {
  156.     return Boolean(('0' <= ch) && (ch <= '9'));
  157. }
  158.  
  159. Boolean isLetter(char ch)
  160. {
  161.     ch &= 0xdf;
  162.     return Boolean(('A' <= ch) && (ch <= 'Z'));
  163. }
  164.  
  165. Boolean isSpecial(char ch, const char* special)
  166. {
  167.     if (strchr(special, ch) != 0)
  168.         return True;
  169.     else
  170.         return False;
  171. }
  172.  
  173. /*
  174.   This helper function will be used for a persistant TInputLine mask.
  175.   It will be moved to TINPUTLI.CPP when needed.
  176. */
  177. uchar numChar(char ch, const char* s)
  178. {
  179.     int count;
  180.     uchar n;
  181.  
  182.     for (count = strlen(s), n = 0; count; count--, s++)
  183.         if (*s == ch)
  184.             n++;
  185.     return n;
  186. }
  187.  
  188. Boolean isComplete(TPicResult result)
  189. {
  190.   return  Boolean((result == prComplete) || (result == prAmbiguous));
  191. }
  192.  
  193. Boolean isIncomplete(TPicResult result)
  194. {
  195.   return Boolean( (result == prIncomplete) || (result == prIncompNoFill) );
  196. }
  197.  
  198.  
  199. // TPXPictureValidator members
  200.  
  201. // Consume input
  202. void TPXPictureValidator::consume(char ch, char* input)
  203. {
  204.       input[jndex] = ch;
  205.       index++;
  206.       jndex++;
  207. }
  208.  
  209. // Skip a character or a picture group
  210.  
  211. void TPXPictureValidator::toGroupEnd(int& i, int termCh)
  212. {
  213.     int  brkLevel, brcLevel;
  214.  
  215.       brkLevel = 0;
  216.       brcLevel = 0;
  217.       do {
  218.         if (i == termCh)
  219.             return;
  220.         else
  221.           switch (pic[i])
  222.           {
  223.           case  '[': brkLevel++; break;
  224.           case  ']': brkLevel--; break;
  225.           case  '{': brcLevel++; break;
  226.           case  '}': brcLevel--; break;
  227.           case  ';': i++; break;
  228.           }
  229.         i++;
  230.       } while (! ((brkLevel == 0) && (brcLevel == 0)));
  231. }
  232.  
  233. // Find the a comma separator
  234. Boolean TPXPictureValidator::skipToComma(int termCh)
  235. {
  236.       do {
  237.           toGroupEnd(index, termCh); 
  238.       } while (! ( (index == termCh) || (pic[index] == ',')));
  239.  
  240.       if (pic[index] == ',')
  241.           index++;
  242.       return Boolean(index < termCh);
  243. }
  244.  
  245. // Calclate the end of a group 
  246. int TPXPictureValidator::calcTerm(int termCh)
  247. {
  248.       int k = index;
  249.       toGroupEnd(k, termCh);
  250.       return k;
  251. }
  252.  
  253. // The next group is repeated X times }
  254. TPicResult TPXPictureValidator::iteration(char* input, int inTerm)
  255. {
  256.       int itr, k, l;
  257.       TPicResult rslt;
  258.       int termCh;
  259.  
  260.       itr = 0;
  261.       rslt = prError;
  262.  
  263.       index++;  // Skip '*'
  264.  
  265.       // Retrieve number
  266.  
  267.       while (isNumber(pic[index]))
  268.       {
  269.         itr = itr * 10 + (pic[index] - '0');
  270.         index++;
  271.       }
  272.  
  273.       k = index;
  274.       termCh = calcTerm(inTerm);
  275.  
  276.       // If Itr is 0 allow any number, otherwise enforce the number
  277.       if (itr != 0)
  278.       {
  279.         for (l = 1; l <= itr; l++)
  280.         {
  281.           index = k;
  282.           rslt = process(input,termCh);
  283.           if ( ! isComplete(rslt))
  284.       {
  285.             // Empty means incomplete since all are required
  286.             if (rslt == prEmpty)
  287.             rslt = prIncomplete;
  288.  
  289.         return rslt;
  290.       }
  291.         }
  292.       }
  293.       else
  294.       {
  295.         do {
  296.           index = k;
  297.           rslt = process(input, termCh);
  298.         } while (rslt == prComplete);
  299.  
  300.         if ((rslt == prEmpty) || (rslt == prError))
  301.         {
  302.           index++;
  303.           rslt = prAmbiguous;
  304.         }
  305.       }
  306.       index = termCh;
  307.  
  308.       return rslt;
  309. }
  310.  
  311. // Process a picture group
  312. TPicResult TPXPictureValidator::group(char* input, int inTerm)
  313. {
  314.  
  315.       TPicResult rslt;
  316.       int termCh;
  317.  
  318.       termCh = calcTerm(inTerm);
  319.       index++;
  320.       rslt = process(input, termCh - 1);
  321.  
  322.       if (! isIncomplete(rslt))  
  323.           index = termCh;
  324.  
  325.       return rslt;
  326. }
  327.  
  328.  
  329. TPicResult TPXPictureValidator::checkComplete(TPicResult rslt, int termCh)
  330. {
  331.     int j = index;
  332.     Boolean status=True;
  333.  
  334.     if (isIncomplete(rslt))
  335.     {
  336.         // Skip optional pieces
  337.         while (status)
  338.           switch (pic[j])
  339.           {
  340.           case '[': 
  341.              toGroupEnd(j, termCh);
  342.              break;
  343.           case  '*':
  344.              if (! isNumber(pic[j + 1]))
  345.                  j++;
  346.              toGroupEnd(j, termCh);
  347.              break;
  348.  
  349.           default:
  350.               status = False;
  351.           }
  352.  
  353.         if (j == termCh)
  354.           rslt = prAmbiguous;
  355.     }
  356.  
  357.     return rslt;
  358. }
  359.  
  360.  
  361. TPicResult TPXPictureValidator::scan(char* input, int termCh)
  362. {
  363.     char ch;
  364.     TPicResult rslt, rScan;
  365.  
  366.     rScan = prError;
  367.     rslt = prEmpty;
  368.  
  369.     while ( (index != termCh) && (pic[index] != ','))
  370.     {
  371. //        if (jndex >= strlen(input)) /* XXX */
  372.         if (jndex >= (int)strlen(input)) /* XXX */
  373.         return checkComplete(rslt, termCh);
  374.  
  375.         ch = input[jndex];
  376.         switch (pic[index])
  377.     {
  378.         case  '#': 
  379.         if (! isNumber(ch)) 
  380.             return prError;
  381.         else 
  382.             consume(ch, input);
  383.         break;
  384.         case  '?': 
  385.         if (! isLetter(ch))
  386.             return prError;
  387.         else 
  388.             consume(ch, input);
  389.         break;
  390.         case  '&': 
  391.         if (! isLetter(ch))
  392.             return prError;
  393.         else 
  394.                 {
  395.                 if( hab == NULLHANDLE )
  396.                 consume(toupper(ch), input);
  397.              else
  398.                 consume( WinUpperChar( hab, Codepage, Country, ch), input);
  399.             }
  400.         break;
  401.         case  '!': 
  402.                 if( hab == NULLHANDLE )
  403.                 consume(toupper(ch), input);
  404.              else
  405.                 consume( WinUpperChar( hab, Codepage, Country, ch), input);
  406.             break;
  407.         case  '@':
  408.         consume(ch, input);
  409.         break;
  410.         case  '*':
  411.     
  412.               rslt = iteration(input,termCh);
  413.               if (! isComplete(rslt))
  414.                   return rslt;
  415.  
  416.               if (rslt == prError) 
  417.               rslt = prAmbiguous;
  418.           break;
  419.  
  420.         case '{':
  421.  
  422.               rslt = group(input, termCh);
  423.               if (! isComplete(rslt))
  424.               return rslt;
  425.  
  426.           break;
  427.         case '[':
  428.             
  429.               rslt = group(input, termCh);
  430.               if (isIncomplete(rslt))
  431.               return rslt;
  432.               if (rslt == prError)
  433.               rslt = prAmbiguous;
  434.  
  435.           break;
  436.  
  437.         default:
  438.  
  439.           if (pic[index] == ';')
  440.           index++;
  441.           char cpchar1, cpchar2;
  442.           if( hab == NULLHANDLE)
  443.           {
  444.               cpchar1 = toupper(pic[index]); cpchar2 = toupper( ch );
  445.           }
  446.           else
  447.           {
  448.               cpchar1 = WinUpperChar( hab, Codepage, Country, pic[ index ] );
  449.               cpchar2 = WinUpperChar( hab, Codepage, Country, ch );
  450.           }
  451.           if ( cpchar1 != cpchar2 )
  452. #ifndef __UNPATCHED
  453.     if (ch != ' ')
  454.         return rScan;
  455. #else
  456.             if (ch == ' ')
  457.              ch = pic[index];
  458.             else 
  459.             return rScan;
  460. #endif
  461.           consume(pic[index], input);
  462.     }
  463.  
  464.         if (rslt == prAmbiguous)
  465.           rslt = prIncompNoFill;
  466.         else
  467.           rslt = prIncomplete;
  468.     }
  469.  
  470.       if (rslt == prIncompNoFill)
  471.         return prAmbiguous;
  472.       else
  473.         return prComplete;
  474. }
  475.  
  476. TPicResult TPXPictureValidator::process(char* input, int termCh)
  477. {
  478.  
  479.    TPicResult rslt, rProcess;
  480.    Boolean incomp;
  481. //   int oldI, oldJ, incompJ=0, incompI; /* XXX */
  482.    int oldI, oldJ, incompJ = 0, incompI = 0; /* XXX */
  483.  
  484.    incomp = False;
  485.    oldI = index;
  486.    oldJ = jndex;
  487.    do {
  488.       rslt = scan(input, termCh);
  489.  
  490.       // Only accept completes if they make it farther in the input
  491.       //   stream from the last incomplete
  492.  
  493.       if ( (rslt == prComplete) && incomp && (jndex < incompJ))
  494.       {
  495.         rslt = prIncomplete;
  496.         jndex = incompJ;
  497.       }
  498.  
  499.       if ((rslt == prError) || (rslt == prIncomplete))
  500.       {
  501.         rProcess = rslt;
  502.  
  503.         if (! incomp &&  (rslt == prIncomplete) )
  504.         {
  505.           incomp  = True;
  506.           incompI = index;
  507.           incompJ = jndex;
  508.         }
  509.         index = oldI;
  510.         jndex = oldJ;
  511.         if (! skipToComma(termCh))
  512.         {
  513.           if ( incomp )
  514.           {
  515.             rProcess = prIncomplete;
  516.             index = incompI;
  517.             jndex = incompJ;
  518.           }
  519.           return rProcess;
  520.         }
  521.         oldI = index;
  522.       }
  523.    } while (!((rslt != prError) && (rslt != prIncomplete)));
  524.  
  525.    if ((rslt == prComplete) && incomp)
  526.       return prAmbiguous;
  527.    else
  528.       return rslt;
  529. }
  530.  
  531. Boolean TPXPictureValidator::syntaxCheck()
  532. {
  533.  
  534.     int i, len;
  535.     int brkLevel, brcLevel;
  536.  
  537.     if (!pic || (strlen(pic) == 0))
  538.         return False;
  539.  
  540.     if (pic[strlen(pic)-1] == ';')
  541.         return False;
  542.  
  543.     i = 0;
  544.     brkLevel = 0;
  545.     brcLevel = 0;
  546.  
  547.     len = strlen(pic);
  548.     while (i < len)
  549.     {
  550.       switch (pic[i])
  551.       {
  552.       case '[': brkLevel++; break;
  553.       case ']': brkLevel--; break;
  554.       case '{': brcLevel++; break;
  555.       case '}': brcLevel--; break;
  556.       case ';': i++;        break;
  557.       }
  558.       i++;
  559.     }
  560.  
  561.     return Boolean( (brkLevel == 0) && (brcLevel == 0) );
  562. }
  563.  
  564. TPicResult TPXPictureValidator::picture(char* input, Boolean autoFill)
  565. {
  566.  
  567.   Boolean reprocess;
  568.   TPicResult rslt;
  569.  
  570.   if (!syntaxCheck())
  571.       return prSyntax;
  572.  
  573.   if (!input || strlen(input)==0)
  574.        return prEmpty;
  575.  
  576.   jndex = 0;
  577.   index = 0;
  578.  
  579.   rslt = process(input, strlen(pic));
  580.  
  581. //  if ((rslt != prError) && (jndex < strlen(input))) /* XXX */
  582.   if ((rslt != prError) && (jndex < (int)strlen(input))) /* XXX */
  583.     rslt = prError;
  584.  
  585.   if ((rslt == prIncomplete) && autoFill)
  586.   {
  587.     reprocess = False;
  588.  
  589. #ifndef __UNPATCHED
  590. //    while ((index < strlen(pic)) && !isSpecial(pic[index], "#?&!@*{}[],")) /* XXX */
  591.     while ((index < (int)strlen(pic)) && !isSpecial(pic[index], /* XXX */
  592.     "#?&!@*{}[],")) /* XXX */
  593. #else
  594.     while ((index < strlen(pic)) && !isSpecial(pic[index], "#?&!@*{}[]"))
  595. #endif
  596.     {
  597.       if (pic[index] == ';')
  598.           index++;
  599.       int end = strlen(input);
  600.       input[end] = pic[index];
  601.       input[end+1] = 0;
  602.       index++;
  603.       reprocess = True;
  604.     }
  605.  
  606.     jndex = 0;
  607.     index = 0;
  608.     if (reprocess)
  609.       rslt = process(input, strlen(pic));
  610.   }
  611.  
  612.   if (rslt == prAmbiguous)
  613.     return prComplete;
  614.   else if (rslt == prIncompNoFill)
  615.     return prIncomplete;
  616.   else
  617.     return rslt;
  618. }
  619.  
  620.  
  621. // TFilterValidator
  622.  
  623. TFilterValidator::TFilterValidator(const char* aValidChars)
  624. {
  625.   validChars = newStr(aValidChars);
  626. }
  627.  
  628. #if !defined(NO_STREAMABLE)
  629.  
  630. TFilterValidator::TFilterValidator( StreamableInit s) : TValidator(s)
  631. {
  632. }
  633.  
  634. #endif
  635.  
  636. TFilterValidator::~TFilterValidator()
  637. {
  638.     delete validChars;
  639. }
  640.  
  641. #if !defined(NO_STREAMABLE)
  642.  
  643. void TFilterValidator::write(opstream& os)
  644. {
  645.   TValidator::write(os);
  646.   os.writeString(validChars);
  647. }
  648.  
  649. void* TFilterValidator::read(ipstream& is)
  650. {
  651.   TValidator::read(is);
  652.   validChars = is.readString();
  653.   return this;
  654. }
  655.  
  656. #endif
  657.  
  658. Boolean TFilterValidator::isValid(const char* s)
  659. {
  660.   return Boolean(strspn(s, validChars) == strlen(s));
  661. }
  662.  
  663. //Boolean TFilterValidator::isValidInput(char* s, Boolean suppressFill) /* XXX */
  664. Boolean TFilterValidator::isValidInput(char* s, Boolean /* suppressFill */) /* XXX */
  665. {
  666.   return Boolean(strspn(s, validChars) == strlen(s));
  667. }
  668.  
  669. void TFilterValidator::error()
  670. {
  671.   messageBox(mfError | mfOKButton, errorMsg );
  672. }
  673.  
  674. // TRangeValidator
  675.  
  676. TRangeValidator::TRangeValidator( long aMin, long aMax ):
  677.     TFilterValidator( 0 ),
  678.     min(aMin),
  679.     max(aMax)
  680. {
  681.     if (aMin >= 0)
  682.         validChars = newStr( TRangeValidator::validUnsignedChars );
  683.     else
  684.         validChars = newStr( TRangeValidator::validSignedChars );
  685. }
  686.  
  687. #if !defined(NO_STREAMABLE)
  688.  
  689. TRangeValidator::TRangeValidator( StreamableInit s) : TFilterValidator(s)
  690. {
  691. }
  692.  
  693. void TRangeValidator::write(opstream& os)
  694. {
  695.   TFilterValidator::write( os );
  696.   os << min << max;
  697. }
  698.  
  699. void* TRangeValidator::read( ipstream& is )
  700. {
  701.   TFilterValidator::read( is );
  702.   is >> min >> max;
  703.   return this;
  704. }
  705.  
  706. #endif
  707.  
  708. void TRangeValidator::error()
  709. {
  710.   messageBox( mfError | mfOKButton, errorMsg, min,max);
  711. }
  712.  
  713.  
  714. Boolean TRangeValidator::isValid(const char* s)
  715. {
  716.   long value;
  717.  
  718.   if (TFilterValidator::isValid(s))
  719. #ifndef __UNPATCHED
  720.     if (sscanf(s,"%ld", &value) != EOF)
  721. #else
  722.     if (sscanf(s,"%ld", &value) != 0)
  723. #endif
  724.         if ((value >= min) && (value <= max))
  725.             return True;
  726.  
  727.   return False;
  728. }
  729.  
  730. ushort TRangeValidator::transfer(char* s, void* buffer, TVTransfer flag)
  731. {
  732.   long value;
  733.  
  734.   if ((options & voTransfer) != 0)
  735.   {
  736.     switch ( flag )
  737.     {
  738.     case vtGetData:
  739.          sscanf(s,"%ld",&value);
  740.          *(long*)buffer = value;
  741.          break;
  742.  
  743.     case vtSetData:
  744.        sprintf(s, "%ld", *(long*)buffer);
  745.        break;
  746.     default:    /* XXX */
  747.     break;    /* XXX */
  748.     }
  749.     return sizeof(long);
  750.   }
  751.   else
  752.     return 0;
  753. }
  754.  
  755. // TLookupValidator
  756.  
  757. #if !defined(NO_STREAMABLE)
  758.  
  759. TLookupValidator::TLookupValidator( StreamableInit s) : TValidator(s)
  760. {
  761. }
  762.  
  763. #endif
  764.  
  765. Boolean TLookupValidator::isValid(const char* s)
  766. {
  767.   return lookup(s);
  768. }
  769.  
  770. Boolean TLookupValidator::lookup(const char* /* s */) /* XXX */
  771. {
  772.   return True;
  773. }
  774.  
  775. // TStringLookupValidator
  776.  
  777. TStringLookupValidator::TStringLookupValidator(TStringCollection* aStrings)
  778. {
  779.   strings = aStrings;
  780. }
  781.  
  782. #if !defined(NO_STREAMABLE)
  783.  
  784. void TStringLookupValidator::write( opstream& os )
  785. {
  786.   TLookupValidator::write( os );
  787.   os << strings;
  788. }
  789.  
  790. void* TStringLookupValidator::read( ipstream& is )
  791. {
  792.   TLookupValidator::read(is);
  793.   is >> strings;
  794.  
  795.   return this;
  796. }
  797.  
  798. TStringLookupValidator::TStringLookupValidator( StreamableInit s) : 
  799.         TLookupValidator(s)
  800. {
  801. }
  802.  
  803. #endif
  804.  
  805. TStringLookupValidator::~TStringLookupValidator()
  806. {
  807.   newStringList(0);
  808. }
  809.  
  810. void TStringLookupValidator::error()
  811. {
  812.   messageBox(mfError | mfOKButton, errorMsg);
  813. }
  814.  
  815. static Boolean stringMatch(void* a1, void* a2)
  816. {
  817.     return Boolean(strcmp((const char*)a1, (const char*)a2) == 0);
  818. }
  819.  
  820.  
  821. Boolean TStringLookupValidator::lookup(const char* s)
  822. {
  823.     return Boolean(strings->firstThat(stringMatch,(void*)s) != 0);
  824. }
  825.  
  826. void TStringLookupValidator::newStringList(TStringCollection* aStrings)
  827. {
  828.   if (strings)
  829. #ifndef __UNPATCHED
  830.       destroy (strings);
  831. #else
  832.       delete strings;
  833. #endif
  834.  
  835.   strings = aStrings;
  836. }
  837.  
  838.  
  839. #if !defined(NO_STREAMABLE)
  840.  
  841. TStreamable *TValidator::build()
  842. {
  843.     return new TValidator( streamableInit );
  844. }
  845.  
  846. TStreamable *TRangeValidator::build()
  847. {
  848.     return new TRangeValidator( streamableInit );
  849. }
  850.  
  851. TStreamable *TFilterValidator::build()
  852. {
  853.     return new TFilterValidator( streamableInit );
  854. }
  855.  
  856. TStreamable *TPXPictureValidator::build()
  857. {
  858.     return new TPXPictureValidator( streamableInit );
  859. }
  860.  
  861. TStreamable *TLookupValidator::build()
  862. {
  863.     return new TLookupValidator( streamableInit );
  864. }
  865.  
  866. TStreamable *TStringLookupValidator::build()
  867. {
  868.     return new TStringLookupValidator( streamableInit );
  869. }
  870.  
  871. #endif
  872.