text: #ifndef PARSE_LABEL_H
  #define PARSE_LABEL_H
  
  #include "ratings.h"
  
  //t-markh 8/98
  //extends GetBool() to true/false, yes/no, pass/fail for
  //PICSRules support
  enum PICSRulesBooleanSwitch
  {
      PR_BOOLEAN_TRUEFALSE,
      PR_BOOLEAN_PASSFAIL,
      PR_BOOLEAN_YESNO
  };
  
  //t-markh 8/98
  //Definitions used by GetBool for PICSRules types
  #define PR_YESNO_YES    1
  #define PR_YESNO_NO     0
  
  #define PR_PASSFAIL_PASS    1
  #define PR_PASSFAIL_FAIL    0
  
  void SkipWhitespace(LPSTR *ppsz);
  BOOL IsEqualToken(LPCSTR pszTokenStart, LPCSTR pszTokenEnd, LPCSTR pszTokenToMatch);
  LPSTR FindTokenEnd(LPSTR pszStart);
  HRESULT GetBool(LPSTR *ppszToken, BOOL *pfOut, PICSRulesBooleanSwitch PRBoolSwitch=PR_BOOLEAN_TRUEFALSE);
  HRESULT ParseNumber(LPSTR *ppszNumber, INT *pnOut, BOOL fPICSRules=FALSE);
  HRESULT ParseTime(LPSTR pszTime, DWORD *pOut, BOOL fPICSRules=FALSE);
  
  class COptionsBase
  {
  protected:
      COptionsBase();
      UINT m_cRef;
  
  public:
      void AddRef();
      void Release();
      virtual void Delete();
  
      DWORD m_timeUntil;          /* 'until' time, in UTC net format (secs since 1/1/1970) */
  
      DWORD m_fdwFlags;           /* see LBLOPT_XXX below */
  
      LPSTR m_pszInvalidString;   /* ptr to invalid or unrecognized string */
      LPSTR m_pszURL;             /* value of "for" option, may be NULL */
  
      BOOL CheckUntil(DWORD timeCurrent); /* returns TRUE if 'until' option checks out */
      BOOL CheckURL(LPCSTR pszURL);       /* returns TRUE if 'for' option checks out */
  };
  
  const DWORD LBLOPT_GENERIC = 0x01;
  const DWORD LBLOPT_INVALID = 0x02;
  const DWORD LBLOPT_EXPIRED = 0x04;
  const DWORD LBLOPT_WRONGURL = 0x08;
  const DWORD LBLOPT_URLCHECKED = 0x10;
  
  
  class CStaticOptions : public COptionsBase
  {
  public:
      CStaticOptions() { }
  };
  
  
  class CDynamicOptions : public COptionsBase
  {
  public:
      CDynamicOptions *m_pNext;
  
      CDynamicOptions() { m_pNext = NULL; }
      virtual void Delete();
  };
  
  
  class CParsedRating
  {
  public:
      LPSTR pszTransmitName;
      INT nValue;
      COptionsBase *pOptions;
      BOOL fFound;                /* TRUE if matches a rating in the installed system */
      BOOL fFailed;               /* TRUE if exceeded user's limit */
  };
  
  
  class CParsedServiceInfo
  {
  private:
      CParsedServiceInfo *m_pNext;
      COptionsBase *m_poptCurrent;
      CDynamicOptions *m_poptList;
      LPSTR m_pszCurrent;             /* for parsing routines */
      void SkipWhitespace() { ::SkipWhitespace(&m_pszCurrent); }
  
  public:
      LPCSTR m_pszServiceName;        /* service name URL, may be NULL if not reported */
      LPCSTR m_pszErrorString;        /* points to error string if error reported by site */
      LPCSTR m_pszInvalidString;      /* pointer to invalid or unrecognized string found */
      BOOL m_fInstalled;              /* TRUE if this rating system is installed on this machine */
      CStaticOptions m_opt;
      array<CParsedRating> aRatings;
  
      CParsedServiceInfo();
      ~CParsedServiceInfo();
  
      CParsedServiceInfo *Next() { return m_pNext; }
      void Append(CParsedServiceInfo *pNew);
      HRESULT Parse(LPSTR *ppszServiceInfo);
      HRESULT ParseServiceError();
      HRESULT ParseOptions(LPSTR pszTokenEnd, COptionsBase *pOpt,
                       CDynamicOptions **ppOptOut, LPCSTR pszOptionEndToken);
      HRESULT ParseExtension(COptionsBase *pOpt);
      HRESULT ParseExtensionData(COptionsBase *pOpt);
      HRESULT ParseRating();
      HRESULT ParseSingleLabel();
      HRESULT ParseLabels();
  };
  
  
  class CParsedLabelList
  {
  private:
      LPSTR m_pszList;
      LPSTR m_pszCurrent;
      HRESULT ParseServiceInfo();
      void SkipWhitespace() { ::SkipWhitespace(&m_pszCurrent); }
  
  public:
      CParsedServiceInfo m_ServiceInfo;
      LPCSTR m_pszInvalidString;      /* pointer to invalid or unrecognized string found */
      LPSTR m_pszURL;                 /* copy of URL we were originally given */
      LPSTR m_pszOriginalLabel;      /* copy of original, raw rating label */
  
      BOOL m_fRated;                      /* TRUE if site is considered rated */
  
      BOOL m_fDenied;                 /* TRUE if site is denied by a helper */
      BOOL m_fIsHelper;               /* TRUE if site is judged by a helper */
      BOOL m_fNoRating;               /* TRUE if site contains no ratings */
      
      BOOL m_fIsCustomHelper;
      LPSTR m_pszRatingName;
      LPSTR m_pszRatingReason;
  
      CParsedLabelList();
      ~CParsedLabelList();
  
      HRESULT Parse(LPSTR pszCopy);
  };
  
  
  extern "C" {
  HRESULT ParseLabelList(LPCSTR pszList, CParsedLabelList **ppParsed);
  void FreeParsedLabelList(CParsedLabelList *pList);
  };  /* extern "C" */
  
  #endif
  