content/canvas/src/WebGLValidateStrings.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/canvas/src/WebGLValidateStrings.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,251 @@
     1.4 +/*
     1.5 + * Copyright (C) 2011 Apple Inc. All rights reserved.
     1.6 + * Copyright (C) 2011 Mozilla Corporation. All rights reserved.
     1.7 + *
     1.8 + * Redistribution and use in source and binary forms, with or without
     1.9 + * modification, are permitted provided that the following conditions
    1.10 + * are met:
    1.11 + * 1. Redistributions of source code must retain the above copyright
    1.12 + *    notice, this list of conditions and the following disclaimer.
    1.13 + * 2. Redistributions in binary form must reproduce the above copyright
    1.14 + *    notice, this list of conditions and the following disclaimer in the
    1.15 + *    documentation and/or other materials provided with the distribution.
    1.16 + *
    1.17 + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
    1.18 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.20 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
    1.21 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1.22 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    1.23 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    1.24 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    1.25 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.27 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.28 + */
    1.29 +
    1.30 +#ifndef WEBGLVALIDATESTRINGS_H_
    1.31 +#define WEBGLVALIDATESTRINGS_H_
    1.32 +
    1.33 +#include "WebGLContext.h"
    1.34 +
    1.35 +namespace mozilla {
    1.36 +
    1.37 +// The following code was taken from the WebKit WebGL implementation,
    1.38 +// which can be found here:
    1.39 +// http://trac.webkit.org/browser/trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp?rev=93625#L121
    1.40 +// Note that some modifications were done to adapt it to Mozilla.
    1.41 +/****** BEGIN CODE TAKEN FROM WEBKIT ******/
    1.42 +    bool WebGLContext::ValidateGLSLCharacter(char16_t c)
    1.43 +    {
    1.44 +        // Printing characters are valid except " $ ` @ \ ' DEL.
    1.45 +        if (c >= 32 && c <= 126 &&
    1.46 +            c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
    1.47 +        {
    1.48 +             return true;
    1.49 +        }
    1.50 +
    1.51 +        // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
    1.52 +        if (c >= 9 && c <= 13) {
    1.53 +             return true;
    1.54 +        }
    1.55 +
    1.56 +        return false;
    1.57 +    }
    1.58 +
    1.59 +    // Strips comments from shader text. This allows non-ASCII characters
    1.60 +    // to be used in comments without potentially breaking OpenGL
    1.61 +    // implementations not expecting characters outside the GLSL ES set.
    1.62 +    class StripComments {
    1.63 +    public:
    1.64 +        StripComments(const nsAString& str)
    1.65 +            : m_parseState(BeginningOfLine)
    1.66 +            , m_end(str.EndReading())
    1.67 +            , m_current(str.BeginReading())
    1.68 +            , m_position(0)
    1.69 +        {
    1.70 +            m_result.SetLength(str.Length());
    1.71 +            parse();
    1.72 +        }
    1.73 +
    1.74 +        const nsTArray<char16_t>& result()
    1.75 +        {
    1.76 +            return m_result;
    1.77 +        }
    1.78 +
    1.79 +        size_t length()
    1.80 +        {
    1.81 +            return m_position;
    1.82 +        }
    1.83 +
    1.84 +    private:
    1.85 +        bool hasMoreCharacters()
    1.86 +        {
    1.87 +            return (m_current < m_end);
    1.88 +        }
    1.89 +
    1.90 +        void parse()
    1.91 +        {
    1.92 +            while (hasMoreCharacters()) {
    1.93 +                process(current());
    1.94 +                // process() might advance the position.
    1.95 +                if (hasMoreCharacters())
    1.96 +                    advance();
    1.97 +            }
    1.98 +        }
    1.99 +
   1.100 +        void process(char16_t);
   1.101 +
   1.102 +        bool peek(char16_t& character)
   1.103 +        {
   1.104 +            if (m_current + 1 >= m_end)
   1.105 +                return false;
   1.106 +            character = *(m_current + 1);
   1.107 +            return true;
   1.108 +        }
   1.109 +
   1.110 +        char16_t current()
   1.111 +        {
   1.112 +            //ASSERT(m_position < m_length);
   1.113 +            return *m_current;
   1.114 +        }
   1.115 +
   1.116 +        void advance()
   1.117 +        {
   1.118 +            ++m_current;
   1.119 +        }
   1.120 +
   1.121 +        bool isNewline(char16_t character)
   1.122 +        {
   1.123 +            // Don't attempt to canonicalize newline related characters.
   1.124 +            return (character == '\n' || character == '\r');
   1.125 +        }
   1.126 +
   1.127 +        void emit(char16_t character)
   1.128 +        {
   1.129 +            m_result[m_position++] = character;
   1.130 +        }
   1.131 +
   1.132 +        enum ParseState {
   1.133 +            // Have not seen an ASCII non-whitespace character yet on
   1.134 +            // this line. Possible that we might see a preprocessor
   1.135 +            // directive.
   1.136 +            BeginningOfLine,
   1.137 +
   1.138 +            // Have seen at least one ASCII non-whitespace character
   1.139 +            // on this line.
   1.140 +            MiddleOfLine,
   1.141 +
   1.142 +            // Handling a preprocessor directive. Passes through all
   1.143 +            // characters up to the end of the line. Disables comment
   1.144 +            // processing.
   1.145 +            InPreprocessorDirective,
   1.146 +
   1.147 +            // Handling a single-line comment. The comment text is
   1.148 +            // replaced with a single space.
   1.149 +            InSingleLineComment,
   1.150 +
   1.151 +            // Handling a multi-line comment. Newlines are passed
   1.152 +            // through to preserve line numbers.
   1.153 +            InMultiLineComment
   1.154 +        };
   1.155 +
   1.156 +        ParseState m_parseState;
   1.157 +        const char16_t* m_end;
   1.158 +        const char16_t* m_current;
   1.159 +        size_t m_position;
   1.160 +        nsTArray<char16_t> m_result;
   1.161 +    };
   1.162 +
   1.163 +    void StripComments::process(char16_t c)
   1.164 +    {
   1.165 +        if (isNewline(c)) {
   1.166 +            // No matter what state we are in, pass through newlines
   1.167 +            // so we preserve line numbers.
   1.168 +            emit(c);
   1.169 +
   1.170 +            if (m_parseState != InMultiLineComment)
   1.171 +                m_parseState = BeginningOfLine;
   1.172 +
   1.173 +            return;
   1.174 +        }
   1.175 +
   1.176 +        char16_t temp = 0;
   1.177 +        switch (m_parseState) {
   1.178 +        case BeginningOfLine:
   1.179 +            // If it's an ASCII space.
   1.180 +            if (c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9))) {
   1.181 +                emit(c);
   1.182 +                break;
   1.183 +            }
   1.184 +
   1.185 +            if (c == '#') {
   1.186 +                m_parseState = InPreprocessorDirective;
   1.187 +                emit(c);
   1.188 +                break;
   1.189 +            }
   1.190 +
   1.191 +            // Transition to normal state and re-handle character.
   1.192 +            m_parseState = MiddleOfLine;
   1.193 +            process(c);
   1.194 +            break;
   1.195 +
   1.196 +        case MiddleOfLine:
   1.197 +            if (c == '/' && peek(temp)) {
   1.198 +                if (temp == '/') {
   1.199 +                    m_parseState = InSingleLineComment;
   1.200 +                    emit(' ');
   1.201 +                    advance();
   1.202 +                    break;
   1.203 +                }
   1.204 +
   1.205 +                if (temp == '*') {
   1.206 +                    m_parseState = InMultiLineComment;
   1.207 +                    // Emit the comment start in case the user has
   1.208 +                    // an unclosed comment and we want to later
   1.209 +                    // signal an error.
   1.210 +                    emit('/');
   1.211 +                    emit('*');
   1.212 +                    advance();
   1.213 +                    break;
   1.214 +                }
   1.215 +            }
   1.216 +
   1.217 +            emit(c);
   1.218 +            break;
   1.219 +
   1.220 +        case InPreprocessorDirective:
   1.221 +            // No matter what the character is, just pass it
   1.222 +            // through. Do not parse comments in this state. This
   1.223 +            // might not be the right thing to do long term, but it
   1.224 +            // should handle the #error preprocessor directive.
   1.225 +            emit(c);
   1.226 +            break;
   1.227 +
   1.228 +        case InSingleLineComment:
   1.229 +            // The newline code at the top of this function takes care
   1.230 +            // of resetting our state when we get out of the
   1.231 +            // single-line comment. Swallow all other characters.
   1.232 +            break;
   1.233 +
   1.234 +        case InMultiLineComment:
   1.235 +            if (c == '*' && peek(temp) && temp == '/') {
   1.236 +                emit('*');
   1.237 +                emit('/');
   1.238 +                m_parseState = MiddleOfLine;
   1.239 +                advance();
   1.240 +                break;
   1.241 +            }
   1.242 +
   1.243 +            // Swallow all other characters. Unclear whether we may
   1.244 +            // want or need to just emit a space per character to try
   1.245 +            // to preserve column numbers for debugging purposes.
   1.246 +            break;
   1.247 +        }
   1.248 +    }
   1.249 +
   1.250 +/****** END CODE TAKEN FROM WEBKIT ******/
   1.251 +
   1.252 +} // end namespace mozilla
   1.253 +
   1.254 +#endif // WEBGLVALIDATESTRINGS_H_

mercurial