parsparm.c
上传用户:yuandong
上传日期:2022-08-08
资源大小:954k
文件大小:8k
源码类别:

Delphi控件源码

开发平台:

C++ Builder

  1. /*++
  2. Copyright (c) 1990-1998  Microsoft Corporation
  3. All Rights Reserved
  4. Abstract:
  5.     Table and routine to send formfeed to a printer.
  6. --*/
  7. #include <windows.h>
  8. #include <winspool.h>
  9. #include <winsplp.h>
  10. #include <wchar.h>
  11. #include "winprint.h"
  12. /** Constants for our various states **/
  13. #define ST_KEY      0x01        /** Looking for a key **/
  14. #define ST_VALUE    0x02        /** Looking for a value **/
  15. #define ST_EQUAL    0x04        /** Looking for an = sign **/
  16. #define ST_EQNODATA 0x08        /** Looking for equal w/ no data **/
  17. #define ST_DELIM    0x10        /** Looking for a ; **/
  18. #define ST_DMNODATA 0x20        /** Looking for a ; w/ no data **/
  19. /*++
  20. *******************************************************************
  21.     G e t K e y V a l u e
  22.     Routine Description:
  23.         Returns the value for a given key in the given
  24.         parameter string.  The key/values are in the order of
  25.         KEY = VALUE;.  The spaces are optional, the ';' is
  26.         required and MUST be present, directly after the value.
  27.         If the call fails, the return length will be 0 and the
  28.         return code will give the error.  This routine is written
  29.         as a state machine, driven by the current character. 
  30.     Arguments:
  31.         pParmString => Parameter string to parse
  32.         pKeyName    => Key to search for
  33.         ValueType   =  type of value to return, string or ULONG
  34.         pDestLength => length of dest buffer on enter,
  35.                        new length on exit.
  36.         pDestBuffer => area to store the key value
  37.     Return Value:
  38.         0 if okay
  39.         error if failed (from winerror.h)
  40. *******************************************************************
  41. --*/
  42. USHORT
  43. GetKeyValue(
  44.     IN      PWCHAR  pParmString,
  45.     IN      PWCHAR  pKeyName,
  46.     IN      USHORT  ValueType,
  47.     IN OUT  PUSHORT pDestLength,
  48.     OUT     PVOID   pDestBuffer)
  49. {
  50.     PWCHAR  pKey, pVal, pValEnd = NULL;
  51.     WCHAR   HoldChar;
  52.     USHORT  State = ST_KEY;    /** Start looking for a key **/
  53.     ULONG   length;
  54.     /** If any of the pointers are bad, return error **/
  55.     if ((pParmString == NULL) ||
  56.         (pKeyName == NULL)    ||
  57.         (pDestLength == NULL) ||
  58.         (pDestBuffer == NULL)) {
  59.         if (pDestLength) {
  60.             *pDestLength = 0;
  61.         }
  62.         return ERROR_INVALID_PARAMETER;
  63.     }
  64.     /**
  65.         If we are looking for a ULONG, make sure they passed
  66.         in a big enough buffer.
  67.     **/
  68.     if (ValueType == VALUE_ULONG) {
  69.         if (*pDestLength < sizeof(ULONG)) {
  70.             *(PULONG)pDestBuffer = 0;
  71.             return ERROR_INSUFFICIENT_BUFFER;
  72.         }
  73.     }
  74.         
  75.     while (pParmString && *pParmString) {
  76.         /**
  77.             Update our state, if necessary, depending on
  78.             the current character.
  79.         **/
  80.         switch (*pParmString) {
  81.         /**
  82.             We got a white space.  If we were looking for an equal
  83.             sign or delimiter, then note that we got a space.  If
  84.             we run across more data, then we have an error.
  85.         **/
  86.         case (WCHAR)' ':
  87.         case (WCHAR)'t':
  88.             /**
  89.                 If we were looking for an equal sign,
  90.                 check to see if this is the key they
  91.                 wanted.  If not, jump to the next key.
  92.             **/
  93.             if (State == ST_EQUAL) {
  94.                 if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
  95.                     if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  96.                         pParmString++;
  97.                     }
  98.                     State = ST_KEY;
  99.                     pValEnd = NULL;
  100.                     break;
  101.                 }
  102.                 /** Looking for an equal sign with no more data **/
  103.                 State = ST_EQNODATA;
  104.             }
  105.             else if (State == ST_DELIM) {
  106.                 /** If this is the end of the value, remember it **/
  107.                 if (!pValEnd) {
  108.                     pValEnd = pParmString;
  109.                 }
  110.                 /** Now looking for a delimiter with no more data **/
  111.                 State = ST_DMNODATA;
  112.             }
  113.             pParmString++;
  114.             break;
  115.         /**
  116.             Found an equal sign.  If we were looking for one,
  117.             then great - we will then be looking for a value.
  118.             We will check to see if this is the key they wanted.
  119.             Otherwise, this is an error and we will start over
  120.             with the next key.
  121.         **/
  122.         case (WCHAR)'=':
  123.             if (State == ST_EQUAL) {
  124.                 if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
  125.                     /** Error - go to next key **/
  126.                     if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  127.                         pParmString++;
  128.                     }
  129.                     State = ST_KEY;
  130.                     pValEnd = NULL;
  131.                     break;
  132.                 }
  133.                 pParmString++;
  134.                 State = ST_VALUE;
  135.             }
  136.             else {
  137.                 /** Error - go to next key **/
  138.                 if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  139.                     pParmString++;
  140.                 }
  141.                 State = ST_KEY;
  142.                 pValEnd = NULL;
  143.             }
  144.             break;
  145.         case (WCHAR)';':    
  146.             if (State == ST_DELIM) {
  147.                 if (!pValEnd) {
  148.                     pValEnd = pParmString;
  149.                 }
  150.                 if (ValueType == VALUE_ULONG) {
  151.                     if (!iswdigit(*pVal)) {
  152.                         if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  153.                             pParmString++;
  154.                         }
  155.                         State = ST_KEY;
  156.                         pValEnd = NULL;
  157.                         break;
  158.                     }
  159.                     *(PULONG)pDestBuffer = wcstoul(pVal, NULL, 10);
  160.                     return 0;
  161.                 }
  162.                 else if (ValueType == VALUE_STRING) {
  163.                     /**
  164.                         ASCIIZ the value to copy it out without
  165.                         any trailing spaces.
  166.                     **/
  167.                     HoldChar = *pValEnd;
  168.                     *pValEnd = (WCHAR)0;
  169.                     /** Make sure the buffer is big enough **/
  170.                     length = lstrlen(pVal);
  171.                     if (*pDestLength < length) {
  172.                         *pDestLength = 0;
  173.                         return ERROR_INSUFFICIENT_BUFFER;
  174.                     }
  175.                     /**
  176.                         Copy the data, restore the character where
  177.                         we ASCIIZ'd the string, set up the length
  178.                         and return.
  179.                     **/
  180.                     lstrcpy(pDestBuffer, pVal);
  181.                     *pValEnd = HoldChar;
  182.                     *(PULONG)pDestLength = length;
  183.                     return 0;
  184.                 }
  185.             }
  186.             else {
  187.                 /** We weren't looking for a delimiter - next key **/
  188.                 State = ST_KEY;
  189.                 pValEnd = NULL;
  190.                 pParmString++;
  191.             }
  192.             break;
  193.         /**
  194.             Found some data.  If we had hit a space,
  195.             and were expecting a equal sign or delimiter,
  196.             this is an error.
  197.         **/
  198.         default:
  199.             if ((State == ST_EQNODATA) ||
  200.                 (State == ST_DMNODATA)) {
  201.                 if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  202.                     pParmString++;
  203.                 }
  204.                 State = ST_KEY;
  205.                 pValEnd = NULL;
  206.                 break;
  207.             }
  208.             else if (State == ST_KEY) {
  209.                 pKey = pParmString;
  210.                 State = ST_EQUAL;
  211.             }
  212.             else if (State == ST_VALUE) {
  213.                 pVal = pParmString;
  214.                 State = ST_DELIM;
  215.             }
  216.             pParmString++;
  217.             break;
  218.         } /* End switch */
  219.     } /* While parms data */
  220.     *pDestLength = 0;
  221.     return ERROR_NO_DATA;
  222. }