LCOV - code coverage report
Current view: directory - content/svg/content/src - nsSVGDataParser.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 137 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is the Mozilla SVG project.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * IBM Corporation
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 :  /**
      39                 :   * NOTE:
      40                 :   *
      41                 :   *   How should subclasses use this class?
      42                 :   *   This class was separated from the nsSVGPathDataParser class to share
      43                 :   *   functionality found to be common in other descent parsers in this component.
      44                 :   *
      45                 :   *   A subclass should implement a Match method which gets invoked from the
      46                 :   *   Parse method.  The Parse method can be overridden, as required.
      47                 :   *
      48                 :   */
      49                 : 
      50                 : 
      51                 : #include "nsSVGDataParser.h"
      52                 : #include "prdtoa.h"
      53                 : #include "nsSVGUtils.h"
      54                 : #include "nsMathUtils.h"
      55                 : #include <stdlib.h>
      56                 : #include <math.h>
      57                 : 
      58                 : //----------------------------------------------------------------------
      59                 : // public interface
      60                 : 
      61                 : nsresult
      62               0 : nsSVGDataParser::Parse(const nsAString &aValue)
      63                 : {
      64               0 :   char *str = ToNewUTF8String(aValue);
      65               0 :   if (!str)
      66               0 :     return NS_ERROR_OUT_OF_MEMORY;
      67                 : 
      68               0 :   mInputPos = str;
      69                 : 
      70               0 :   GetNextToken();
      71               0 :   nsresult rv = Match();
      72               0 :   if (mTokenType != END)
      73               0 :     rv = NS_ERROR_FAILURE; // not all tokens were consumed
      74                 : 
      75               0 :   mInputPos = nsnull;
      76               0 :   nsMemory::Free(str);
      77                 : 
      78               0 :   return rv;
      79                 : }
      80                 : 
      81                 : //----------------------------------------------------------------------
      82                 : // helpers
      83                 : 
      84               0 : void nsSVGDataParser::GetNextToken()
      85                 : {
      86               0 :   mTokenPos = mInputPos;
      87               0 :   mTokenVal = *mInputPos;
      88                 :   
      89               0 :   switch (mTokenVal) {
      90                 :     case '0': case '1': case '2': case '3': case '4':
      91                 :     case '5': case '6': case '7': case '8': case '9':
      92               0 :       mTokenType = DIGIT;
      93               0 :       break;
      94                 :     case '\x20': case '\x9': case '\xd': case '\xa':
      95               0 :       mTokenType = WSP;
      96               0 :       break;
      97                 :     case ',':
      98               0 :       mTokenType = COMMA;
      99               0 :       break;
     100                 :     case '+': case '-':
     101               0 :       mTokenType = SIGN;
     102               0 :       break;
     103                 :     case '.':
     104               0 :       mTokenType = POINT;
     105               0 :       break;
     106                 :     case '(':
     107               0 :       mTokenType = LEFT_PAREN;
     108               0 :       break;
     109                 :     case ')':
     110               0 :       mTokenType = RIGHT_PAREN;
     111               0 :       break;
     112                 :     case '\0':
     113               0 :       mTokenType = END;
     114               0 :       break;
     115                 :     default:
     116               0 :       mTokenType = OTHER;
     117                 :   }
     118                 :   
     119               0 :   if (*mInputPos != '\0') {
     120               0 :     ++mInputPos;
     121                 :   }
     122               0 : }
     123                 : 
     124               0 : void nsSVGDataParser::RewindTo(const char* aPos)
     125                 : {
     126               0 :   mInputPos = aPos;
     127               0 :   GetNextToken();
     128               0 : }
     129                 : 
     130                 : //----------------------------------------------------------------------
     131                 : 
     132               0 : nsresult nsSVGDataParser::MatchNonNegativeNumber(float* aX)
     133                 : {
     134                 :   // XXX inefficient implementation. We probably hit the RewindTo case
     135                 :   // often.
     136                 :   
     137               0 :   const char* pos = mTokenPos;
     138                 : 
     139               0 :   nsresult rv = MatchFloatingPointConst();
     140                 : 
     141               0 :   if (NS_FAILED(rv)) {
     142               0 :     RewindTo(pos);
     143               0 :     ENSURE_MATCHED(MatchIntegerConst());
     144                 :   }
     145                 : 
     146                 :   char* end;
     147               0 :   *aX = float(PR_strtod(pos, &end));
     148               0 :   if (pos != end && NS_finite(*aX)) {
     149               0 :     return NS_OK;
     150                 :   }
     151                 :   
     152               0 :   return NS_ERROR_FAILURE;
     153                 : }
     154                 : 
     155               0 : bool nsSVGDataParser::IsTokenNonNegativeNumberStarter()
     156                 : {
     157               0 :   return (mTokenType == DIGIT || mTokenType == POINT);
     158                 : }
     159                 : 
     160                 : //----------------------------------------------------------------------
     161                 : 
     162               0 : nsresult nsSVGDataParser::MatchNumber(float* aX)
     163                 : {
     164               0 :   const char* pos = mTokenPos;
     165                 :   
     166               0 :   if (mTokenType == SIGN)
     167               0 :     GetNextToken();
     168                 : 
     169               0 :   const char* pos2 = mTokenPos;
     170                 : 
     171               0 :   nsresult rv = MatchFloatingPointConst();
     172                 : 
     173               0 :   if (NS_FAILED(rv)) {
     174               0 :     RewindTo(pos2);
     175               0 :     ENSURE_MATCHED(MatchIntegerConst());
     176                 :   }
     177                 : 
     178                 :   char* end;
     179                 :   /* PR_strtod is not particularily fast. We only need a float and not a double so
     180                 :    * we could probably use something faster here if needed. The CSS parser uses
     181                 :    * nsCSSScanner::ParseNumber() instead of PR_strtod. See bug 516396 for some
     182                 :    * additional info. */
     183               0 :   *aX = float(PR_strtod(pos, &end));
     184               0 :   if (pos != end && NS_finite(*aX)) {
     185               0 :     return NS_OK;
     186                 :   }
     187                 :   
     188               0 :   return NS_ERROR_FAILURE;
     189                 : }
     190                 : 
     191               0 : bool nsSVGDataParser::IsTokenNumberStarter()
     192                 : {
     193               0 :   return (mTokenType == DIGIT || mTokenType == POINT || mTokenType == SIGN);
     194                 : }
     195                 : 
     196                 : 
     197                 : //----------------------------------------------------------------------
     198                 : 
     199               0 : nsresult nsSVGDataParser::MatchCommaWsp()
     200                 : {
     201               0 :   switch (mTokenType) {
     202                 :     case WSP:
     203               0 :       ENSURE_MATCHED(MatchWsp());
     204               0 :       if (mTokenType == COMMA)
     205               0 :         GetNextToken();
     206               0 :       break;
     207                 :     case COMMA:
     208               0 :       GetNextToken();
     209               0 :       break;
     210                 :     default:
     211               0 :       return NS_ERROR_FAILURE;
     212                 :   }
     213                 : 
     214               0 :   while (IsTokenWspStarter()) {
     215               0 :     ENSURE_MATCHED(MatchWsp());
     216                 :   }
     217               0 :   return NS_OK;
     218                 : }
     219                 :   
     220               0 : bool nsSVGDataParser::IsTokenCommaWspStarter()
     221                 : {
     222               0 :   return (IsTokenWspStarter() || mTokenType == COMMA);
     223                 : }
     224                 : 
     225                 : //----------------------------------------------------------------------
     226                 : 
     227               0 : nsresult nsSVGDataParser::MatchIntegerConst()
     228                 : {
     229               0 :   ENSURE_MATCHED(MatchDigitSeq());
     230               0 :   return NS_OK;
     231                 : }
     232                 : 
     233                 : //----------------------------------------------------------------------
     234                 : 
     235               0 : nsresult nsSVGDataParser::MatchFloatingPointConst()
     236                 : {
     237                 :   // XXX inefficient implementation. It would be nice if we could make
     238                 :   // this predictive and wouldn't have to backtrack...
     239                 :   
     240               0 :   const char* pos = mTokenPos;
     241                 : 
     242               0 :   nsresult rv = MatchFractConst();
     243               0 :   if (NS_SUCCEEDED(rv)) {
     244               0 :     if (IsTokenExponentStarter())
     245               0 :       ENSURE_MATCHED(MatchExponent());
     246                 :   }
     247                 :   else {
     248               0 :     RewindTo(pos);
     249               0 :     ENSURE_MATCHED(MatchDigitSeq());
     250               0 :     ENSURE_MATCHED(MatchExponent());    
     251                 :   }
     252                 : 
     253               0 :   return NS_OK;  
     254                 : }
     255                 : 
     256                 : //----------------------------------------------------------------------
     257                 : 
     258               0 : nsresult nsSVGDataParser::MatchFractConst()
     259                 : {
     260               0 :   if (mTokenType == POINT) {
     261               0 :     GetNextToken();
     262               0 :     ENSURE_MATCHED(MatchDigitSeq());
     263                 :   }
     264                 :   else {
     265               0 :     ENSURE_MATCHED(MatchDigitSeq());
     266               0 :     if (mTokenType == POINT) {
     267               0 :       GetNextToken();
     268               0 :       if (IsTokenDigitSeqStarter()) {
     269               0 :         ENSURE_MATCHED(MatchDigitSeq());
     270                 :       }
     271                 :     }
     272                 :   }
     273               0 :   return NS_OK;
     274                 : }
     275                 : 
     276                 : //----------------------------------------------------------------------
     277                 : 
     278               0 : nsresult nsSVGDataParser::MatchExponent()
     279                 : {
     280               0 :   if (!(tolower(mTokenVal) == 'e')) return NS_ERROR_FAILURE;
     281                 : 
     282               0 :   GetNextToken();
     283                 : 
     284               0 :   if (mTokenType == SIGN)
     285               0 :     GetNextToken();
     286                 : 
     287               0 :   ENSURE_MATCHED(MatchDigitSeq());
     288                 : 
     289               0 :   return NS_OK;  
     290                 : }
     291                 : 
     292               0 : bool nsSVGDataParser::IsTokenExponentStarter()
     293                 : {
     294               0 :   return (tolower(mTokenVal) == 'e');
     295                 : }
     296                 : 
     297                 : //----------------------------------------------------------------------
     298                 : 
     299               0 : nsresult nsSVGDataParser::MatchDigitSeq()
     300                 : {
     301               0 :   if (!(mTokenType == DIGIT)) return NS_ERROR_FAILURE;
     302                 : 
     303               0 :   do {
     304               0 :     GetNextToken();
     305                 :   } while (mTokenType == DIGIT);
     306                 : 
     307               0 :   return NS_OK;
     308                 : }
     309                 : 
     310               0 : bool nsSVGDataParser::IsTokenDigitSeqStarter()
     311                 : {
     312               0 :   return (mTokenType == DIGIT);
     313                 : }
     314                 : 
     315                 : //----------------------------------------------------------------------
     316                 : 
     317               0 : nsresult nsSVGDataParser::MatchWsp()
     318                 : {
     319               0 :   if (!(mTokenType == WSP)) return NS_ERROR_FAILURE;
     320                 : 
     321               0 :   do {
     322               0 :     GetNextToken();
     323                 :   } while (mTokenType == WSP);
     324                 : 
     325               0 :   return NS_OK;  
     326                 : }
     327                 : 
     328               0 : bool nsSVGDataParser::IsTokenWspStarter()
     329                 : {
     330               0 :   return (mTokenType == WSP);
     331                 : }  
     332                 : 
     333                 : //----------------------------------------------------------------------
     334                 : 
     335               0 : nsresult nsSVGDataParser::MatchLeftParen()
     336                 : {
     337               0 :   switch (mTokenType) {
     338                 :     case LEFT_PAREN:
     339               0 :       GetNextToken();
     340                 :       break;
     341                 :     default:
     342               0 :       return NS_ERROR_FAILURE;
     343                 :   }
     344                 : 
     345                 :  
     346               0 :   return NS_OK;
     347                 : }
     348                 : 
     349               0 : nsresult nsSVGDataParser::MatchRightParen()
     350                 : {
     351               0 :   switch (mTokenType) {
     352                 :     case RIGHT_PAREN:
     353               0 :        GetNextToken();
     354                 :       break;
     355                 :     default:
     356               0 :       return NS_ERROR_FAILURE;
     357                 :   }
     358                 : 
     359               0 :   return NS_OK;
     360                 : }
     361                 : 

Generated by: LCOV version 1.7