示例#1
0
bool Get_XML_colour (CXMLelement & node,
                        const char * sName,
                        COLORREF & cValue,
                        const bool bUseDefault)

  {
CString strValue;

  if (!Get_XML_string (node, sName, strValue, true, true))
    if (bUseDefault)
      return false;
    else
      {
      cValue = 0;     // default is black
      return false;
      }

  if (strValue.IsEmpty ())
      ThrowErrorException ("No colour supplied for attribute named '%s'" ,
                          sName);

  if (SetColour (strValue, cValue)) 
      ThrowErrorException ("Invalid colour code \"%s\" for attribute named '%s'" ,
                          (LPCTSTR) strValue,
                          sName);
  return true;

  }  // end of Get_XML_colour
示例#2
0
void CXMLparser::ProcessEntity (void)
  {
CString strName;
CString strValue;
CString strTemp;

  strName = GetName ("entity");

  strTemp = strName.Left (3);
  strTemp.MakeUpper ();

  if (strTemp == "XML")
    ThrowErrorException ("Names starting with \"XML\" are reserved");

  strValue = GetValue ("entity", strName);

  // entities might have entities in them, so replace them
  m_CustomEntityMap.SetAt (strName, ReplaceEntities (strValue));

  if (m_xmlBuff [m_xmlPos] != '>')
    ThrowErrorException ("Expected '>', got %c",
        m_xmlBuff [m_xmlPos]);

  m_xmlPos++;   // skip >

  // bypass spaces and comments

  SkipComments (true);

  } // end of CXMLparser::ProcessEntity 
示例#3
0
t_regexp * regcomp(const char *exp, const int options)
  {
const char *error;
int erroroffset;
t_regexp * re;
pcre * program;
pcre_extra * extra;

  program = pcre_compile(exp, options, &error, &erroroffset, NULL);

  if (!program)
    ThrowErrorException("Failed: %s at offset %d", Translate (error), erroroffset);

  // study it for speed purposes
  extra =  pcre_study(program, 0, &error);        

  if (error)
    {
    pcre_free (program);
    ThrowErrorException("Regexp study failed: %s", error);
    }

  // we need to allocate memory for the substring offsets
  re = new t_regexp;

  // remember program and extra stuff
  re->m_program = program;
  re->m_extra = extra;
  re->m_iExecutionError = 0; // no error now


  return re;
  }
示例#4
0
void CXMLparser::SkipComments (const bool bAndSpaces)
  {
  while (true)  // loop in case consecutive comments, or comment - space - comment
    {

    if (bAndSpaces)
      SkipSpaces ();

    // comment?

    if (m_xmlBuff [m_xmlPos] == '<' && 
        m_xmlBuff [m_xmlPos + 1] == '!' && 
        m_xmlBuff [m_xmlPos + 2] == '-' && 
        m_xmlBuff [m_xmlPos + 3] == '-')
      {
      // skip comment

      m_xmlPos += 4; // skip <!--

      while (m_xmlBuff [m_xmlPos] != '-' || 
             m_xmlBuff [m_xmlPos + 1] != '-' || 
             m_xmlBuff [m_xmlPos + 2] != '>')
        {
        if (m_xmlBuff [m_xmlPos] == 0)
          ThrowErrorException ("Unterminated comment at end of file");

        if (m_xmlBuff [m_xmlPos] == '-' && 
            m_xmlBuff [m_xmlPos + 1] == '-')
          ThrowErrorException ("Invalid '--' inside comment");

        if (m_xmlBuff [m_xmlPos] == '\n')
          m_xmlLine++;  // count lines
        m_xmlPos++;
        }
      
      // here for end of comment

      m_xmlPos += 3; // skip -->

      } // end of comment
    else
      return; // no comment, all done

    };

  } // end of SkipComments
示例#5
0
void CXMLparser::ProcessDoctype (void)
  {

  m_strDocumentName = GetName ("Root document");

  // document name may be followed by SYSTEM or PUBLIC

  if (isalpha (m_xmlBuff [m_xmlPos]))
    {
    CString strName = GetName ("External ID");
    
    // we'll get and ignore these for future compatibility
    if (strName == "SYSTEM")
      GetValue ("SYSTEM", "DTD name");     // eg. SYSTEM "c:\blah\my.dtd"
    else
    if (strName == "PUBLIC")
      {
      GetValue ("PUBLIC", "Public ID");    // eg. PUBLIC "blah" "c:\blah\my.dtd"
      GetValue ("PUBLIC", "DTD name");
      }
    else
      ThrowErrorException ("Unsupported declaration \"%s\" inside <!DOCTYPE ...>",
                            (LPCTSTR) strName);


    } // end of SYSTEM/PUBLIC

  if (m_xmlBuff [m_xmlPos] == '[')
    ProcessDTD ();
  
  if (m_xmlBuff [m_xmlPos] != '>')
    {

    // shouldn't have end-of-file before the >
    if (m_xmlBuff [m_xmlPos] == 0)
      ThrowErrorException ("Unexpected end-of-file inside <!DOCTYPE> declaration");

    ThrowErrorException ("Unsupported declaration inside <!DOCTYPE ...>");

    } // end of looking for attributes

  m_xmlPos++; // skip '>' symbol


  }   // end of CXMLparser::ProcessDoctype
示例#6
0
void CXMLparser::ProcessDeclaration (const CString strDeclaration)
  {

  if (strDeclaration == "DOCTYPE")
    ProcessDoctype ();
  else
    ThrowErrorException ("Unrecognised declaration: <!%s ...>",
                         (LPCTSTR) strDeclaration);
  } // end of CXMLparser::ProcessDeclaration
示例#7
0
CString CXMLparser::ReplaceEntities (const CString strSource)
    {

// look for entities imbedded in the string
const char * p = strSource;
const char * pStart = strSource;   // where buffer starts
const char * pEntity;
CString strFixedValue;
CString strEntity;
long length;

  // quick check to eliminate ones that don't have imbedded entities
  if (strSource.Find ('&') == -1)
    return strSource;

  strFixedValue.Empty ();

  for ( ; *p; p++)
    {
    if (*p == '&')
      {

      // copy up to ampersand
      length = p - pStart;
      
      if (length > 0)
        strFixedValue += CString (pStart, length);

      p++;    // skip ampersand
      pEntity = p; // where entity starts
      if (*p == '#')
        p++;
      while (isalnum (*p) ||
             *p == '-' ||
             *p == '.' ||
             *p == '_')
             p++;

      if (*p != ';')
        ThrowErrorException ("No closing \";\" in XML entity argument \"&%s\"", 
                  (LPCTSTR) CString (pEntity, p - pEntity)); 

      strFixedValue += Get_XML_Entity (CString (pEntity, p - pEntity));    // add to list
  
      pStart = p + 1;   // move on past the entity

      } // end of having an ampersand 

    } // end of processing the value

  // copy last bit

  strFixedValue += pStart;

  return strFixedValue;
  }   // end of CXMLparser::ReplaceEntities
示例#8
0
void CXMLparser::ProcessDTD (void)
  {
CString strName;

  m_xmlPos++;    // skip the [ symbol

  SkipComments (true);

  while (m_xmlBuff [m_xmlPos] != ']')
    {

    // shouldn't have end-of-file before the >
    if (m_xmlBuff [m_xmlPos] == 0)
      ThrowErrorException ("Unexpected end-of-file inside DTD declaration");

    // look for declaration start

    if (m_xmlBuff [m_xmlPos] != '<' || m_xmlBuff [m_xmlPos + 1] != '!')
      ThrowErrorException ("Expected '<!', got %c",
            m_xmlBuff [m_xmlPos]);

    m_xmlPos += 2;  // skip <!

    strName = GetName ("DTD Declaration");

    // we only support <!ENTITY ... > right now
    if (strName == "ENTITY")
      ProcessEntity ();
    else
      ThrowErrorException ("Unsupported declaration <!%s ...>",
                          (LPCTSTR) strName);

    } // end of looking for declarations

  m_xmlPos++; // skip ']' symbol

  SkipComments (true);

  } // end of CXMLparser::ProcessDTD
示例#9
0
bool Get_XML_boolean (CXMLelement & node,
                          const char * sName,
                          bool & bValue,
                          const bool bUseDefault)
  {
CString strValue;

  if (!Get_XML_string (node, sName, strValue, bUseDefault))
    if (bUseDefault)
      return false;

  // be nice and let them slip in Y or y
  strValue.MakeLower ();

  if (strValue == "0" ||
      strValue == "" ||   // empty can be considered false
      strValue == "no" ||
      strValue == "n" ||
      strValue == "false" ||
      strValue == "f"
      )
    {
    bValue = false;
    return true;
    }

  if (strValue == "1" ||
      strValue == "-1" ||
      strValue == "yes" ||
      strValue == "y" ||
      strValue == "true" ||
      strValue == "t"
      )
    {
    bValue = true;
    return true;
    }

  ThrowErrorException ("Boolean attribute named \"%s\" has unrecognised value \"%s\"",
                       sName,
                       (LPCTSTR) strValue);

  bValue = false;
  return true;
  }  // end of Get_XML_boolean
  ///////////////////////////////////////////////////////////////////////////////
  // Write to a file.  An assertion will occur if file was opened for reading.
  // Inputs:
  //	unsigned int	size			Number of bytes to write to the file.
  //	const char*		bufferToWrite	Buffer containing data to write to the file.
  // Exceptions:
  //	ErrorException thrown on failure.
  ///////////////////////////////////////////////////////////////////////////////
  void RawFileLinux::Write(
			   unsigned int size,
			   const char* bufferToWrite
			   ) {

    //Write everything in one pass

    assert( IsOpen() );
    filestream.exceptions( std::fstream::badbit | std::fstream::failbit | std::fstream::goodbit );
    
    try {
      filestream.write( bufferToWrite, size );
      lastPosition = position;
      position = filestream.tellp();
      filestream.clear();
    } catch( std::fstream::failure e ) { //throw exception
      ThrowErrorException( e );
    }

  }
示例#11
0
bool Get_XML_number (CXMLelement & node,
                        const char * sName,
                        long & iValue, 
                        const bool bUseDefault,
                        long iMinimum,
                        long iMaximum)
  {

CString strValue;

  if (!Get_XML_string (node, sName, strValue, bUseDefault))
    if (bUseDefault)
      return false;
    else
      strValue = "0";   // default is zero

__int64 iResult = 0;
const char * p =  strValue;
bool bNegative = false;

  // see if sign given
  if (*p == '-')
    {
    bNegative = true;
    p++;
    }
  else
    if (*p == '+')
      p++;

  if (*p == 0)
      ThrowErrorException ("No number suppied for numeric attribute named '%s'" ,
                          sName);

  if (!isdigit (*p))
    ThrowErrorException ("Invalid number \"%s\" for numeric attribute named '%s'" ,
                          (LPCTSTR) strValue,
                          sName);

  for (iResult = 0; *p; p++)
    {
    if (!isdigit (*p))
      ThrowErrorException ("Invalid character '%c' in numeric attribute named '%s'" ,
                          *p,
                          sName);

    iResult *= 10;
    iResult += *p - '0';

    if (iResult > ((__int64) LONG_MAX + 1))   // to allow for LONG_MIN which will be one more
      ThrowErrorException ("Value '%s' too large in numeric attribute named '%s'" ,
                          (LPCTSTR) strValue,
                          sName);

    }

  // make negative if necessary
  if (bNegative)
    iResult = 0 - iResult;

  // fix up default 0, 0 to be 0, 1
  if (iMinimum == 0 && iMaximum == 0)
      iMaximum = 1;

  if (iResult > iMaximum)
    ThrowErrorException ("Value '%s' too large in numeric attribute named '%s'. "
                         "Range is %ld to %ld.",
                        (LPCTSTR) strValue,
                         sName,
                         iMinimum, 
                         iMaximum);

  if (iResult < iMinimum)
    ThrowErrorException ("Value '%s' too small in numeric attribute named '%s'. "
                         "Range is %ld to %ld.",
                        (LPCTSTR) strValue,
                         sName,
                         iMinimum, 
                         iMaximum);

  iValue = (long) iResult;
  return true;

  }  // end of Get_XML_number
示例#12
0
CString CXMLparser::GetValue (const char * sType, const char * sName)
  {
char cQuote;
UINT iStart;
CString strValue;
int iContentLen;

  // in case spaces before the value
  SkipSpaces ();

  // find what sort of quote they are using
  cQuote = m_xmlBuff [m_xmlPos];

  if (cQuote == 0)
    ThrowErrorException ("Unexpected end-of-file looking for value of %s named %s",
                          sType,
                          sName);

  if (cQuote != '\'' && cQuote != '\"')
    // value starting with > is really an omitted value
    if (cQuote == '>')
      ThrowErrorException ("Value for %s not supplied",
                          sType);

    // detect a comment here as a special case
    else
    if (m_xmlBuff [m_xmlPos] == '<' &&
        m_xmlBuff [m_xmlPos + 1] == '!' &&
        m_xmlBuff [m_xmlPos + 2] == '-' &&
        m_xmlBuff [m_xmlPos + 3] == '-')
      ThrowErrorException ("Comment not valid here");
    else
      ThrowErrorException ("Value for %s named '%s' not supplied (in quotes)",
                            sType,
                            sName);

  m_xmlPos++; // get past quote

  iStart = m_xmlPos; // start of value

  while (m_xmlBuff [m_xmlPos] != cQuote)
    {
    if (m_xmlBuff [m_xmlPos] == '\n' || 
        m_xmlBuff [m_xmlPos] == '\r' ||
        m_xmlBuff [m_xmlPos] == 0)
      ThrowErrorException ("Value for %s named '%s' not terminated (no closing quote)",
                            sType,
                            sName);

    // <![CDATA[ terminator invalid here (ie. ]]> )
    if (m_xmlBuff [m_xmlPos] == ']' &&
           m_xmlBuff [m_xmlPos + 1] == ']' &&
           m_xmlBuff [m_xmlPos + 2] == '>')
      ThrowErrorException ("Value for %s named '%s' may not contain CDATA terminator: ']]>'",
                            sType,
                            sName);

    // don't let them slip in non-printables 
    if ((unsigned char) m_xmlBuff [m_xmlPos] < ' ')
      ThrowErrorException ("Non-printable character, code %i, not permitted for "
                           "value for %s named '%s'",
                            (int) m_xmlBuff [m_xmlPos], 
                            sType,
                            sName);

    m_xmlPos++; 
    }

  iContentLen = m_xmlPos - iStart;

  m_xmlPos++;   // get past quote

  SkipSpaces ();

  // construct value from buffer
  return CString (&m_xmlBuff [iStart], iContentLen);

  } // end of CXMLparser::GetValue 
示例#13
0
bool Get_XML_date (CXMLelement & node,
                        const char * sName,
                        CTime & tValue,
                        const bool bUseDefault)

  {
CString strValue;

  if (!Get_XML_string (node, sName, strValue, true, true))
    if (bUseDefault)
      return false;
    else
      {
      tValue = 0;     // default is no time
      return false;
      }

  if (strValue.IsEmpty ())
      ThrowErrorException ("No time supplied for attribute named '%s'" ,
                          sName);

  // break up date into date portion / time portion
  CStringList strDateTime;
  StringToList (strValue, " ", strDateTime);

  if (strDateTime.GetCount () < 1 || strDateTime.GetCount () > 2)
    ThrowErrorException ("Date/time must consist of YYYY-MM-DD [ HH:MM:SS ]");

  CString strDate = strDateTime.RemoveHead ();
  CString strTime;
  if (!strDateTime.IsEmpty ())
     strTime = strDateTime.RemoveHead ();

  CString strYear, strMonth, strDay;

  CStringList strDateList;
  StringToList (strDate, "-", strDateList);

  if (strDateList.GetCount () != 3)
     ThrowErrorException ("Date must consist of YYYY-MM-DD");
   
  strYear = strDateList.RemoveHead ();
  strMonth = strDateList.RemoveHead ();
  strDay = strDateList.RemoveHead ();

  if (!IsNumber (strYear))
     ThrowErrorException ("Year is not numeric");
  if (!IsNumber (strMonth))
     ThrowErrorException ("Month is not numeric");
  if (!IsNumber (strDay))
     ThrowErrorException ("Day is not numeric");

  int iYear, iMonth, iDay;

  iYear = atoi (strYear);
  iMonth = atoi (strMonth);
  iDay = atoi (strDay);

  if (iYear <  1900 || iYear > 2100)
     ThrowErrorException ("Year must be in range 1900 to 2100");
  
  if (iMonth < 1 || iMonth > 12)
     ThrowErrorException ("Month must be in range 1 to 12");
  
  if (iDay < 1 || iDay > 31)
     ThrowErrorException ("Month must be in range 1 to 31");

  int iHour = 0, iMinute = 0, iSecond = 0;

  if (!strTime.IsEmpty ())
    {

    CString strHour, strMinute, strSecond;

    CStringList strTimeList;
    StringToList (strTime, ":", strTimeList);

    if (strTimeList.GetCount () > 3)
       ThrowErrorException ("Time must consist of HH, HH:MM, or HH:MM:SS");
   
    strHour = strTimeList.RemoveHead ();
    strMinute = "0";
    strSecond = "0";

    if (!strTimeList.IsEmpty ())
      {
      strMinute = strTimeList.RemoveHead ();
      if (!strTimeList.IsEmpty ())
        strSecond = strTimeList.RemoveHead ();
      }

    if (!IsNumber (strHour))
       ThrowErrorException ("Hour is not numeric");
    if (!IsNumber (strMinute))
       ThrowErrorException ("Minute is not numeric");
    if (!IsNumber (strSecond))
       ThrowErrorException ("Second is not numeric");

    iHour = atoi (strHour);
    iMinute = atoi (strMinute);
    iSecond = atoi (strSecond);

    if (iHour <  0 || iHour > 23)
       ThrowErrorException ("Hour must be in range 0 to 23");
  
    if (iMinute < 0 || iMinute > 59)
       ThrowErrorException ("Minute must be in range 0 to 59");
  
    if (iSecond < 0 || iSecond > 59)
       ThrowErrorException ("Minute must be in range 0 to 59");

    } // end of having a time

  tValue = CTime (iYear, iMonth, iDay, iHour, iMinute, iSecond, 0);

  return true;

  }  // end of Get_XML_date
示例#14
0
bool Get_XML_double  (CXMLelement & node,
                        const char * sName,
                        double & dValue,
                        const bool bUseDefault,
                        const double dMinimum,
                        const double dMaximum)
  {
CString strValue;

  if (!Get_XML_string (node, sName, strValue, bUseDefault))
    if (bUseDefault)
      return false;
    else
      strValue = "0";   // default is zero

double dResult = 0;
const char * p =  strValue;
int iDots = 0;
int iExponents = 0;
   
  // see if sign given
  if (*p == '-' || *p == '+')
    p++;

  if (*p == 0)
      ThrowErrorException ("No number suppied for numeric attribute named '%s'" ,
                          sName);

  if (!isdigit (*p))
    ThrowErrorException ("Invalid number \"%s\" for numeric attribute named '%s'" ,
                          (LPCTSTR) strValue,
                          sName);

  for ( ; *p; p++)
    {
    if (*p == '.')
      {
      if (++iDots > 1)
        ThrowErrorException ("Too many decimal places for numeric attribute named '%s'" ,
                            sName);
      }  // end of decimal place
    else if (toupper (*p) == 'E')
      {
      if (++iExponents > 1)
        ThrowErrorException ("Too many 'E' characters for numeric attribute named '%s'" ,
                            sName);
      // exponent may have sign
      if (*p == '-' || *p == '+')
        p++;
      } // end of exponent
    else if(!isdigit (*p))
      ThrowErrorException ("Invalid character '%c' in numeric attribute named '%s'" ,
                          *p,
                          sName);

  
    }   // end of checking each character


  myAtoF (strValue, &dResult); 

  /*   // myAtoF does not return myAtoF

  if (dResult == c || dResult == -HUGE_VAL)
    ThrowErrorException ("Value '%s' out of range in numeric attribute named '%s'" ,
                        (LPCTSTR) strValue,
                        sName);

  */

  if (dResult > dMaximum)
    ThrowErrorException ("Value '%s' too large in numeric attribute named '%s'. "
                         "Range is %g to %g.",
                        (LPCTSTR) strValue,
                         sName,
                         dMinimum, 
                         dMaximum);

  if (dResult < dMinimum)
    ThrowErrorException ("Value '%s' too small in numeric attribute named '%s'. "
                         "Range is %g to %g.",
                        (LPCTSTR) strValue,
                         sName,
                         dMinimum, 
                         dMaximum);

  dValue = dResult;
  return true;


  } // end of Get_XML_double
示例#15
0
CString CXMLparser::Get_XML_Entity (CString & strName)
  {

CString strEntityContents;

  // look for &#nnn; 

  if (strName [0] == '#')
    {
    int iResult = 0;

    // validate and work out number
    if (strName [1] == 'x')
      {
      for (int i = 2; i < strName.GetLength (); i++)
        {
        if (!isxdigit (strName [i]))
          {
          ThrowErrorException ("Invalid hex number in XML entity: &%s;" ,
                              (LPCTSTR) strName);
          return "";
          }

        int iNewDigit = toupper (strName [i]);
        if (iNewDigit >= 'A')
          iNewDigit -= 7;
        if (iResult & 0xF0)
          ThrowErrorException ("Invalid hex number in XML entity: &%s; "
                               "- maximum of 2 hex digits",
                              (LPCTSTR) strName);
          iResult = (iResult << 4) + iNewDigit - '0';
        }
      } // end of hex entity
    else
      {
      for (int i = 1; i < strName.GetLength (); i++)
        {
        if (!isdigit (strName [i]))
          {
          ThrowErrorException ("Invalid number in XML entity: &%s;" ,
                              (LPCTSTR) strName);
          return "";
          }
        iResult *= 10;
        iResult += strName [i] - '0';
        }
      } // end of decimal entity

    if (iResult != 9)       // we will accept tabs ;)
      if (iResult < 32 ||   // don't allow nonprintable characters
          iResult > 255)   // don't allow characters more than 1 byte
          {
          ThrowErrorException ("Disallowed number in XML entity: &%s;" ,
                              (LPCTSTR) strName);
          return "";
          }
    unsigned char cOneCharacterLine [2] = { (unsigned char) iResult, 0};
    return (char *) cOneCharacterLine;
    } // end of entity starting with #

  
  // look up global entities first
  if (App.m_EntityMap.Lookup (strName, strEntityContents))
    return strEntityContents;
  // then try ones for this document
  else if (m_CustomEntityMap.Lookup (strName, strEntityContents))
    return strEntityContents;

  ThrowErrorException ("Unknown XML entity: &%s;" ,
                        (LPCTSTR) strName);

  return "";    // to avoid warning
  }  // end of CXMLparser::Get_XML_Entity
示例#16
0
void CXMLparser::BuildStructure (CFile * file)
  {

  m_xmlLength = file->GetLength ();

  // can hardly be XML if empty file
  if (m_xmlLength == 0)
    ThrowErrorException ("Zero length XML file \"%s\"",
                          (LPCTSTR) file->GetFilePath ());

  // sanity check - don't read 20 Mb files into memory
  if (m_xmlLength > MAX_XML_DOCUMENT_SIZE)
    ThrowErrorException ("XML file \"%s\"too large - maximum permitted is %i bytes", 
                          (LPCTSTR) file->GetFilePath (),
                          MAX_XML_DOCUMENT_SIZE);

  char * p = m_strxmlBuffer.GetBuffer (m_xmlLength + 1);

  iLineLastItemFound = 0;

  if (file->Read (p, m_xmlLength) != m_xmlLength)
    {
    m_strxmlBuffer.ReleaseBuffer (0);
    ThrowErrorException ("Could not read XML file");
    }

  m_strxmlBuffer.ReleaseBuffer (m_xmlLength);

  // look for Unicode  (FF FE)
  if ((unsigned char) m_strxmlBuffer [0] == 0xFF &&
      (unsigned char) m_strxmlBuffer [1] == 0xFE)
    {
    CString buf2;
    const char * q =  m_strxmlBuffer;
    q += 2; // skip indicator bytes
    // find required buffer length
    int length = WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR) q, (m_xmlLength - 2) / 2, 
                    NULL, 0, NULL, NULL);
    // make a new string with enough length to hold it
    char * p = buf2.GetBuffer (length);
    // convert it
    WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR) q, (m_xmlLength - 2) / 2, 
              p, length, NULL, NULL);
    buf2.ReleaseBuffer (length);
    // copy to our buffer
    m_strxmlBuffer = buf2;
    }
  else 
    // look for UTF-8 indicator bytes  (EF BB BF)
    if ((unsigned char) m_strxmlBuffer [0] == 0xEF &&
        (unsigned char) m_strxmlBuffer [1] == 0xBB &&
        (unsigned char) m_strxmlBuffer [2] == 0xBF)
      m_strxmlBuffer = m_strxmlBuffer.Mid (3);  // skip them


  // convert tabs to spaces, we don't want tabs in our data
  m_strxmlBuffer.Replace ('\t', ' ');

  SeeIfBase64 (m_strxmlBuffer);

  m_xmlBuff = m_strxmlBuffer;    // get const char * pointer to buffer

  ProcessNode (m_xmlRoot);  // process root node

  }   // end of CXMLparser::BuildStructure
示例#17
0
CString CXMLparser::GetName (const char * sType)
  {
int iStart;
int iNameLen;

  iStart = m_xmlPos; // start of name

  if (m_xmlBuff [m_xmlPos] == 0)
    ThrowErrorException ("Unexpected end-of-file looking for %s name",
                          sType);

  // name must start with letter or underscore
  if (!isalpha (m_xmlBuff [m_xmlPos]) && m_xmlBuff [m_xmlPos]  != '_')
      ThrowErrorException ("%s name must start with letter or underscore, "
                           "but starts with \"%c\"",
                          sType,
                          m_xmlBuff [m_xmlPos]);

  // build up name

  while (isalnum (m_xmlBuff [m_xmlPos]) ||
         m_xmlBuff [m_xmlPos] == '-' ||
         m_xmlBuff [m_xmlPos] == '.' ||
         m_xmlBuff [m_xmlPos] == '_')
         m_xmlPos++;

  // OK - we now have a name, unless it is empty 

  iNameLen = m_xmlPos - iStart;
  if (iNameLen == 0)
    // name starting with > is really an omitted name
    if (m_xmlBuff [m_xmlPos] == '>')
      ThrowErrorException ("%s name not supplied",
                          sType);
    // detect a comment inside an element as a special case
    else
    if (m_xmlBuff [m_xmlPos] == '<' &&
        m_xmlBuff [m_xmlPos + 1] == '!' &&
        m_xmlBuff [m_xmlPos + 2] == '-' &&
        m_xmlBuff [m_xmlPos + 3] == '-')
      ThrowErrorException ("Comment not valid here");
    else
      ThrowErrorException ("%s name cannot start with '%c'",
                          sType,
                          m_xmlBuff [m_xmlPos]);

  // sanity check - make sure name not ridiculous
  if (iNameLen > MAX_XML_NAME_LENGTH)
    ThrowErrorException ("%s name is too long (%i characters) "
                         " maximum permitted is %i characters",
        sType,
        iNameLen,
        MAX_XML_NAME_LENGTH);

  // in case spaces before next thing
  SkipSpaces ();

  // construct name from buffer
  return CString (&m_xmlBuff [iStart], iNameLen);

  } // end of CXMLparser::GetName
示例#18
0
void CXMLparser::ProcessAttributes (CXMLelement & node)
  {
CAttribute * pAttribute;
CString strName;
CString strValue;

  while (m_xmlBuff [m_xmlPos] != '>')
    {
    // look for "empty element" terminator: />
    if (m_xmlBuff [m_xmlPos] == '/' && m_xmlBuff [m_xmlPos + 1] == '>')
      {
      node.bEmpty = true;
      m_xmlPos++; // skip '/' symbol
      break;
      }

    // look for terminator ?> at end of <?xml tag
    if (m_xmlBuff [m_xmlPos] == '?' && 
        m_xmlBuff [m_xmlPos + 1] == '>' &&
        node.strName [0] == '?'
        )
      {
      node.bEmpty = true;
      m_xmlPos++; // skip '?' symbol
      break;
      }

    // shouldn't have end-of-file before the >
    if (m_xmlBuff [m_xmlPos] == 0)
      ThrowErrorException ("Unexpected end-of-file inside element definition for %s",
                            (LPCTSTR) node.strName);

    // we really should have a name now ...

    strName = GetName ("Attribute");

    // already there? error
    if (node.AttributeMap.Lookup (strName, pAttribute))
      ThrowErrorException ("Duplicate attribute name '%s'",
                            (LPCTSTR) strName);

    // in case spaces before next thing
    SkipSpaces ();

    if (m_xmlBuff [m_xmlPos] != '=')
      ThrowErrorException ("Attribute name '%s' not followed by '='",
                            (LPCTSTR) strName);

    m_xmlPos++;    // skip the = sign

    int iLine =  m_xmlLine; // line that = sign is on

    strValue = GetValue ("attribute", strName);

    pAttribute = new CAttribute;

    if (!pAttribute)
      ThrowErrorException ("Could not allocate memory for XML parsing of attribute %s",
                            (LPCTSTR) strName);

    pAttribute->strName = strName;
    pAttribute->strValue = ReplaceEntities (strValue);
    pAttribute->iLine = iLine;

    // add to map
    node.AttributeMap.SetAt (strName, pAttribute);

    } // end of looking for attributes

  m_xmlPos++; // skip '>' symbol


  }   // end of CXMLparser::ProcessAttributes
示例#19
0
void CXMLparser::AssembleContent (CXMLelement & node, 
                                    const UINT iFirstLine, 
                                    const UINT iNodeStart)
  {

/*
   work out content - it will be non-nested text belonging to this element
   eg. <a>xxx<b>yyy</b>zzz</a>
      "a" will have content xxxzzz
      "b" will have content yyy
   whitespace is preserved

   You can reassemble an entire element (including nested ones) by
   concatenating the contents of its children.
  
   For cross-platform consistency, carriage returns are dropped,
    and linefeeds become carriage-return/linefeed

  */

int iContentLen = m_xmlPos - iNodeStart;

int iLines = m_xmlLine - iFirstLine;    // lines of content
const char * pi = &m_xmlBuff [iNodeStart];    // copy from
const char * pl = &m_xmlBuff [m_xmlPos];      // limit of copy
char * po = node.strContent.GetBuffer (iContentLen + 1 + iLines); // copy to
int iDepth = 0;
bool bInside = false;
char cQuote = ' ';

  while (pi < pl)   // copy, dropping nested elements
    {

    // they might have <blah value=">">
    // so we have to skip special characters inside quotes

    if (bInside && (*pi == '\'' || *pi == '\"'))
      {
      cQuote = *pi;   // for terminator
      pi++;
      while (pi < pl && *pi != cQuote)
        pi++;
      pi++;  // skip terminating quote
      continue;   // back to start of loop
      } // end of quotes inside a definition

    // <![CDATA[  is special - just copy contents

    if (pi [0] == '<' &&
        pi [1] == '!' &&
        pi [2] == '[' &&
        pi [3] == 'C' &&
        pi [4] == 'D' &&
        pi [5] == 'A' &&
        pi [6] == 'T' &&
        pi [7] == 'A' &&
        pi [8] == '[')
      {

      pi += 9;  // skip <![CDATA[

      // this shouldn't happen
      if (bInside)
        ThrowErrorException ("Unexpected '<![CDATA[' inside element definition");

      // should be terminated as we checked earlier, but may as well check again
      while (pi < pl &&
             (pi [0] != ']' ||
              pi [1] != ']' ||
              pi [2] != '>'))
        {
       // copy if not nested, and not inside an element definition
       //  -- omit carriage returns
       if (iDepth == 0 && 
           *pi != '\r')
         {
         // make linefeeds into carriage return/linefeed
         if (*pi == '\n')
           *po++ = '\r';
         // special treatment for ampersands, so they don't get converted
         // into entities ...
         if (*pi == '&')
           *po++ = '\x01';
         else
          *po++ = *pi;    // copy it
         }
        pi++;
        }  // end of inside <![CDATA[

      pi += 3;  // skip ]]>
      continue; // back to start of loop

      } // end of <![CDATA[ section

    if (*pi == '<')   // going into an element
      {
      bInside = true;
      if (pi [1] == '/')   // </tag> drops a level
        {
        iDepth--;
       if (iDepth < 0)
         iDepth = 0;    // cannot have negative depth
        }
      else
        if (pi [1] != '!' && pi [1] != '?')  // excepting special ones
          iDepth++;           // <tag> goes up a level
      }

   // copy if not nested, and not inside an element definition
   //  -- omit carriage returns
   if (iDepth == 0 && 
      !bInside && 
      *pi != '\r')
     {
     // make linefeeds into carriage return/linefeed
     if (*pi == '\n')
       *po++ = '\r';
     *po++ = *pi;    // copy if not inside an element
     }
    
    // leaving an element (only occurs 'inside' a <... sequence )
   if (bInside && pi [0] == '/' && pi [1] == '>') 
     {
     iDepth--;  // cancel level gain - this tag is empty
     if (iDepth < 0)
       iDepth = 0;    // cannot have negative depth
     }
    else
      if (*pi == '>')   // leaving an element
        bInside = false;

    pi++; // onto next

    }
  
  *po = 0;  // terminating null
  node.strContent.ReleaseBuffer (-1);

  // get rid of entities (such as &lt;) in the content

  node.strContent = ReplaceEntities (node.strContent);

  // now, in case we had <![CDATA[ sections, replace 0x01 by &

  node.strContent.Replace ('\x01', '&');

  } // end of CXMLparser::AssembleContent 
示例#20
0
CString CMUSHclientDoc::FixSendText (const CString strSource, 
                                     const int iSendTo,
                                     const t_regexp * regexp,    // regular expression (for triggers, aliases)
                                     const char * sLanguage,     // language for send-to-script
                                     const bool bMakeWildcardsLower,
                                     const bool bExpandVariables,   // convert @foo
                                     const bool bExpandWildcards,   // convert %x
                                     const bool bFixRegexps, // convert \ to \\ for instance
                                     const bool bIsRegexp,   // true = regexp trigger
                                     const bool bThrowExceptions)
  {
CString strOutput;   // result of expansion

const char * pText,
           * pStartOfGroup;

  pText = pStartOfGroup = strSource;

  while (*pText)
    {
    switch (*pText)
      {

/* -------------------------------------------------------------------- *
 *  Variable expansion - @foo becomes <contents of foo>                 *
 * -------------------------------------------------------------------- */

      case '@':
        {
        if (!bExpandVariables)
          {
          pText++;      // just copy the @
          break;
          }


       // copy up to the @ sign

        strOutput += CString (pStartOfGroup, pText - pStartOfGroup);
      
        pText++;    // skip the @

        // @@ becomes @
        if (*pText == '@')
          {
          pStartOfGroup = ++pText;
          strOutput += "@";
          continue;
          }

        const char * pName;
        bool bEscape = bFixRegexps;

        // syntax @!variable defeats the escaping

        if (*pText == '!')
          {
          pText++;
          bEscape = false;
          }

        pName = pText;

        // find end of variable name
        while (*pText)
          if (*pText == '_' || isalnum ((unsigned char) *pText))
            pText++;
          else
            break;

/* -------------------------------------------------------------------- *
 *  We have a variable - look it up and do internal replacements        *
 * -------------------------------------------------------------------- */
          
        CString strVariableName (pName, pText - pName);

        if (strVariableName.IsEmpty ())
          {
          if (bThrowExceptions)
            ThrowErrorException ("@ must be followed by a variable name");
          } // end of no variable name
        else
          {
          CVariable * variable_item;

          strVariableName.MakeLower ();

          if (GetVariableMap ().Lookup (strVariableName, variable_item))
            {
            // fix up so regexps don't get confused with [ etc. inside variable
            CString strVariableContents;
            if (bEscape)
              {
              const char * pi;
              // allow for doubling in size, plus terminating null
              char * po = strVariableContents.GetBuffer ((variable_item->strContents.GetLength () * 2) + 1);
              for (pi = variable_item->strContents;
                  *pi;
                  pi++)
                {
                if (((unsigned char) *pi) < ' ')
                  continue;   // drop non-printables
                if (bIsRegexp)
                  if (!isalnum ((unsigned char) *pi) && *pi != ' ')
                    {
                    *po++ = '\\'; // escape it
                    *po++ = *pi;
                    }
                  else
                    *po++ = *pi;    // just copy it
                else          // not regexp
                  if (*pi != '*')
                    *po++ = *pi;    // copy all except asterisks
                }

              *po = 0;  // terminating null
              strVariableContents.ReleaseBuffer (-1); 
              }  // end of escaping wanted
            else
              strVariableContents = variable_item->strContents;

            // in the "send" box may need to convert script expansions etc.
            if (!bFixRegexps)
               strVariableContents = FixWildcard ((const char *) strVariableContents,
                                                 false, // not force variables to lowercase
                                                 iSendTo,
                                                 sLanguage).c_str ();

            // fix up HTML sequences if we are sending it to a log file
            if (m_bLogHTML && iSendTo == eSendToLogFile)
              strVariableContents = FixHTMLString (strVariableContents);

            strOutput += strVariableContents;
            }   // end of name existing in variable map
          else
            {
            if (bThrowExceptions)
              ThrowErrorException ("Variable '%s' is not defined.", 
                                  (LPCTSTR) strVariableName);
            }  // end of variable does not exist

          } // end of not empty name

          // get ready for next batch from beyond the variable
          pStartOfGroup = pText;
         }
        break;    // end of '@'

/* -------------------------------------------------------------------- *
 *  Wildcard substitution - %1 becomes <contents of wildcard 1>         *
 *                        - %<foo> becomes <contents of wildcard "foo"  *
 *                        - %% becomes %                                *
 * -------------------------------------------------------------------- */

      case '%':

           if (!bExpandWildcards)
            {
            pText++;      // just copy the %
            break;
            }

        // see what comes after the % symbol
        switch (pText [1])
           {

/* -------------------------------------------------------------------- *
 *  %%                                                                  *
 * -------------------------------------------------------------------- */

           case '%':

          // copy up to - and including - the percent sign

            strOutput += CString (pStartOfGroup, pText - pStartOfGroup + 1);

            // get ready for next batch from beyond the %%

            pText += 2;    // don't reprocess the %%
            pStartOfGroup = pText;  
            break;   // end of %%

/* -------------------------------------------------------------------- *
 *  %0 to %9                                                            *
 * -------------------------------------------------------------------- */
          
           case '0':       // a digit?
           case '1':
           case '2':
           case '3':
           case '4':
           case '5':
           case '6':
           case '7':
           case '8':
           case '9':
             {

            // copy up to the percent sign

              strOutput += CString (pStartOfGroup, pText - pStartOfGroup);
                    
            // output the appropriate replacement text

            if (regexp)
              {
              CString strWildcard = FixWildcard (regexp->GetWildcard (string (1, *++pText)),
                                                 bMakeWildcardsLower,
                                                 iSendTo,
                                                 sLanguage).c_str ();

              // fix up HTML sequences if we are sending it to a log file
              if (m_bLogHTML && iSendTo == eSendToLogFile)
                strWildcard = FixHTMLString (strWildcard);

              strOutput += strWildcard;
              }

            // get ready for next batch from beyond the digit

             pStartOfGroup = ++pText;


             } 
             break;   // end of %(digit) (eg. %2)

/* -------------------------------------------------------------------- *
 *  %<name>                                                             *
 * -------------------------------------------------------------------- */

           case '<':
             {
            // copy up to the % sign

              strOutput += CString (pStartOfGroup, pText - pStartOfGroup);
    
              pText +=2;    // skip the %<

              const char * pName = pText;

              // find end of wildcard name
              while (*pText)
                if (*pText != '>')
                  pText++;
                else
                  break;
  
              string sWildcardName (pName, pText - pName);

              if (!sWildcardName.empty () && regexp)
                {
                CString strWildcard = FixWildcard (regexp->GetWildcard (sWildcardName),
                                                   bMakeWildcardsLower,
                                                   iSendTo,
                                                   sLanguage).c_str ();

                // fix up HTML sequences if we are sending it to a log file
                if (m_bLogHTML && iSendTo == eSendToLogFile)
                  strWildcard = FixHTMLString (strWildcard);

                strOutput += strWildcard;

                }
              // get ready for next batch from beyond the name

              if (*pText == '>')
                pText++;
              pStartOfGroup = pText;
             }
             break;   // end of %<foo>

/* -------------------------------------------------------------------- *
 *  %C - clipboard contents                                             *
 * -------------------------------------------------------------------- */

           case 'C':
           case 'c':
             {
            // copy up to the percent sign
              strOutput += CString (pStartOfGroup, pText - pStartOfGroup);

              CString strClipboard;

              if (GetClipboardContents (strClipboard, m_bUTF_8))
                strOutput += strClipboard;
              else
                if (bThrowExceptions)
                  ThrowErrorException ("No text on the Clipboard");

        // get ready for next batch from beyond the 'c'

              pText += 2;
              pStartOfGroup = pText;
             }
             break; // end of %c

/* -------------------------------------------------------------------- *
 *  %(something else)                                                   *
 * -------------------------------------------------------------------- */

           default:
              pText++;
              break;

           }  // end of switch on character after '%'

         break;    // end of '%(something)'

/* -------------------------------------------------------------------- *
 *  All other characters - just increment pointer so we can copy later  *
 * -------------------------------------------------------------------- */

      default:
        pText++;
        break;

      } // end of switch on *pText

    }   // end of not end of string yet

// copy last group

  strOutput += pStartOfGroup;

  return strOutput;
  } // end of  CMUSHclientDoc::FixSendText
示例#21
0
int regexec(register t_regexp *prog, 
            register const char *string,
            const int start_offset)
  {
int options = App.m_bRegexpMatchEmpty ? 0 : PCRE_NOTEMPTY;    // don't match on an empty string
int count;

  // exit if no regexp program to process (possibly because of previous error)
  if (prog->m_program == NULL)
    return false;

  // inspired by a suggestion by Twisol (to remove a hard-coded limit on the number of wildcards)
  int capturecount = 0;
  // how many captures did we get?
  pcre_fullinfo(prog->m_program, NULL, PCRE_INFO_CAPTURECOUNT, &capturecount);
  // allocate enough memory
  vector<int> offsets ((capturecount + 1) * 3);  // we always get offset 0 - the whole match

  LARGE_INTEGER start, 
                finish;


  if (App.m_iCounterFrequency)
    QueryPerformanceCounter (&start);
  else
    {
    start.QuadPart = 0;
    finish.QuadPart = 0;
    }

  pcre_callout = NULL;
  count = pcre_exec(prog->m_program, prog->m_extra, string, strlen (string),
                    start_offset, options, &offsets [0], offsets.size ());

  if (App.m_iCounterFrequency)
    {
    QueryPerformanceCounter (&finish);
    prog->iTimeTaken += finish.QuadPart - start.QuadPart;
    }

  prog->m_iMatchAttempts++;  // how many times did we try to match?

  if (count == PCRE_ERROR_NOMATCH)
    return false;  // no match  - don't save matching string etc.

  //  otherwise free program as an indicator that we can't keep trying to do this one
  if (count <= 0)
    {
    pcre_free (prog->m_program);
    prog->m_program = NULL;
    pcre_free (prog->m_extra);
    prog->m_extra = NULL;
    prog->m_iExecutionError = count; // remember reason
    ThrowErrorException (TFormat ("Error executing regular expression: %s",
                         (LPCTSTR) Convert_PCRE_Runtime_Error (count)));
    }


  // if, and only if, we match, we will save the matching string, the count
  // and offsets, so we can extract the wildcards later on

  prog->m_sTarget = string;  // for extracting wildcards
  prog->m_iCount = count;    // ditto
  prog->m_vOffsets.clear (); 
  copy (offsets.begin (), offsets.end (), back_inserter (prog->m_vOffsets));
  return true; // match
  }
示例#22
0
void CXMLparser::ProcessNode (CXMLelement & parent)
  {

CString strName;
CString strValue;
CString strPrefix;
UINT iNodeStart = m_xmlPos;
UINT iFirstLine = m_xmlLine;

  while (m_xmlBuff [m_xmlPos])
    {

    // bypass spaces and comments

    SkipComments (true);

    // nothing left? all done

    if (m_xmlBuff [m_xmlPos] == 0)
      break;

    // look for element start

    if (m_xmlBuff [m_xmlPos] != '<')
      {
      // not element - must be content

      // can't have content at root level
      if (parent.strName.IsEmpty ())
        ThrowErrorException ("Expected '<', got \"%c\" (content not permitted here)",
            m_xmlBuff [m_xmlPos]);

      if (m_xmlBuff [m_xmlPos] == '\n')
        m_xmlLine++;   // count lines

      // <![CDATA[ terminator invalid here (ie. ]]> )
      if (m_xmlBuff [m_xmlPos] == ']' &&
             m_xmlBuff [m_xmlPos + 1] == ']' &&
             m_xmlBuff [m_xmlPos + 2] == '>')
        ThrowErrorException ("CDATA terminator ']]>' invalid");

      // don't let them slip in non-printables 
      if ((unsigned char) m_xmlBuff [m_xmlPos] < ' ' &&
          (unsigned char) m_xmlBuff [m_xmlPos] != '\n' && 
          (unsigned char) m_xmlBuff [m_xmlPos] != '\r')
        ThrowErrorException ("Non-printable character, code %i, not permitted",
                              (int) m_xmlBuff [m_xmlPos]);

      m_xmlPos++;  // skip character
      continue;     // keep processing content

      }

    m_xmlPos++;  // skip <

    // special cases: <?xml blah?> <!doctype blah> </end-of-something>

    if (m_xmlBuff [m_xmlPos] == '!' || 
        m_xmlBuff [m_xmlPos] == '?' ||
        m_xmlBuff [m_xmlPos] == '/')
      {
      strPrefix = m_xmlBuff [m_xmlPos]; 
      m_xmlPos++;    // bypass special types
      }
    else
      strPrefix.Empty ();

    // special and bizarre case of <![CDATA[ ... ]]>
    if (strPrefix == '!' &&
        m_xmlBuff [m_xmlPos] == '[' &&
        m_xmlBuff [m_xmlPos + 1] == 'C' &&
        m_xmlBuff [m_xmlPos + 2] == 'D' &&
        m_xmlBuff [m_xmlPos + 3] == 'A' &&
        m_xmlBuff [m_xmlPos + 4] == 'T' &&
        m_xmlBuff [m_xmlPos + 5] == 'A' &&
        m_xmlBuff [m_xmlPos + 6] == '[')
      {

      // can't have content at root level
      if (parent.strName.IsEmpty ())
        ThrowErrorException ("<![CDATA[ invalid at root level");

      m_xmlPos += 7;  // skip [CDATA[

      while (m_xmlBuff [m_xmlPos] != ']' ||
             m_xmlBuff [m_xmlPos + 1] != ']' ||
             m_xmlBuff [m_xmlPos + 2] != '>')
        {

        // shouldn't have end-of-file before the ]]>
        if (m_xmlBuff [m_xmlPos] == 0)
          ThrowErrorException ("Unexpected end-of-file inside [CDATA[ definition");

        // don't let them slip in non-printables 
        if ((unsigned char) m_xmlBuff [m_xmlPos] < ' ' &&
            (unsigned char) m_xmlBuff [m_xmlPos] != '\n' && 
            (unsigned char) m_xmlBuff [m_xmlPos] != '\r')
          ThrowErrorException ("Non-printable character, code %i, not permitted",
                                (int) m_xmlBuff [m_xmlPos]);

        if (m_xmlBuff [m_xmlPos] == '\n')
          m_xmlLine++;   // count lines
        m_xmlPos++;   // try next character
        }

      m_xmlPos += 3;  // skip ]]>
      continue; // back to start of loop

      } // end of <![CDATA[ section

    int iLine = m_xmlLine;    // line where we expect to see name
    strName = GetName ("Element");

    // check for sequence </blah xxx>
    if (strPrefix == '/' && m_xmlBuff [m_xmlPos] != '>')
      if (m_xmlBuff [m_xmlPos] == 0)
        ThrowErrorException ("Unexpected end-of-file after '</%s'",
            (LPCTSTR) strName);
      else
        ThrowErrorException ("Surplus characters after '</%s'",
            (LPCTSTR) strName);

    // check for sequence </blah>

    if (strPrefix == '/')
      {
      if (strName != parent.strName)
        if (parent.strName.IsEmpty ())  // can't go up a level here :)
          ThrowErrorException ("Unexpected closing tag </%s> - "
                               "no corresponding opening tag",
                                (LPCTSTR) strName);

        else
          ThrowErrorException ("Elements terminated out of sequence, "
                               "expected </%s>, got </%s>",
                                (LPCTSTR) parent.strName,
                                (LPCTSTR) strName);

      AssembleContent (parent, iFirstLine, iNodeStart);

      m_xmlPos++; // skip terminating >

      return;    // terminated this node
      }

    if (strPrefix == '!')
      ProcessDeclaration (strName);   // process declaration, eg. <!DOCTYPE
    else
      {     // not a declaration, must be an ordinary element

      // time to create a new element
      CXMLelement * pElement = new CXMLelement;

      if (!pElement)
        ThrowErrorException ("Could not allocate memory for XML parsing of element %s",
                              (LPCTSTR) strName);

      // remember its name
      pElement->strName = strPrefix + strName;
      pElement->iLine = iLine;

      parent.ChildrenList.AddTail (pElement);    // add to parent's list of children

      // OK, we have a new sibling for our parent, let's see if it has any attributes ...

      ProcessAttributes (*pElement);  // process its attributes

      // hmm - we have now got something like <blah> ...
      // drop down to find children for it - unless 'empty' element

      if (!pElement->bEmpty)
        ProcessNode (*pElement);

      }   // end of non-declaration
    } // end of processing buffer

  if (!parent.strName.IsEmpty ())
    ThrowErrorException ("Unexpected end-of-file while looking for </%s>",
                          (LPCTSTR) parent.strName);

  }   // end of CXMLparser::ProcessNode 
示例#23
0
static void readfont(CString strName)
{
#define MAXFIRSTLINELEN 1000
  int i,row,numsread;
  inchr theord;
  int maxlen,cmtlines,ffright2left;
  int smush,smush2;
  char *fileline,magicnum[5];


  CStdioFile fontfile (strName, 
                        CFile::modeRead|CFile::shareDenyNone|CFile::typeText);

  readmagic(fontfile,magicnum);
  fileline = (char*)myalloc(sizeof(char)*(MAXFIRSTLINELEN+1));
  if (fontfile.ReadString(fileline,MAXFIRSTLINELEN+1)==NULL) {
    fileline[0] = '\0';
    }
  if (MYSTRLEN(fileline)>0 ? fileline[MYSTRLEN(fileline)-1]!='\n' : 0) {
    skiptoeol(fontfile);
    }
  numsread = sscanf(fileline,"%*c%c %d %*d %d %d %d %d %d",
    &hardblank,&charheight,&maxlen,&smush,&cmtlines,
    &ffright2left,&smush2);
  myfree(fileline);
  if (strcmp(magicnum,FONTFILEMAGICNUMBER) || numsread<5)
    ThrowErrorException ("Not a FIGlet 2 font file");
  for (i=1;i<=cmtlines;i++) {
    skiptoeol(fontfile);
    }

  if (numsread<6) {
    ffright2left = 0;
    }

  if (numsread<7) { /* if no smush2, decode smush into smush2 */
    if (smush == 0) smush2 = SM_KERN;
    else if (smush < 0) smush2 = 0;
    else smush2 = (smush & 31) | SM_SMUSH;
    }

  if (charheight<1) {
    charheight = 1;
    }

  if (maxlen<1) {
    maxlen = 1;
    }

  maxlen += 100; /* Give ourselves some extra room */

  if (smushoverride == SMO_NO)
     smushmode = smush2;
  else if (smushoverride == SMO_FORCE)
     smushmode |= smush2;

  if (right2left<0) {
    right2left = ffright2left;
    }

  if (justification<0) {
    justification = 2*right2left;
    }

  fileline = (char*)myalloc(sizeof(char)*(maxlen+1));
  /* Allocate "missing" character */
  fcharlist = (fcharnode*)myalloc(sizeof(fcharnode));
  fcharlist->ord = 0;
  fcharlist->thechar = (char**)myalloc(sizeof(char*)*charheight);
  fcharlist->next = NULL;
  for (row=0;row<charheight;row++) {
    fcharlist->thechar[row] = (char*)myalloc(sizeof(char));
    fcharlist->thechar[row][0] = '\0';
    }
  for (theord=' ';theord<='~';theord++) {
    readfontchar(fontfile,theord,fileline,maxlen);
    }
  for (theord=0;theord<=6;theord++) {
    readfontchar(fontfile,deutsch[theord],fileline,maxlen);
    }
  while (fontfile.ReadString(fileline,maxlen+1)==NULL?0:
    sscanf(fileline,"%li",&theord)==1) {
    readfontchar(fontfile,theord,fileline,maxlen);
    }
  myfree(fileline);
}