Backed out changeset 58dbd2146e24 (bug 944961) for bustage.
[gecko.git] / content / canvas / src / WebGLValidateStrings.h
blobc7ccec3f464ad87418f981b727ca34f60a81429e
1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Mozilla Corporation. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef WEBGLVALIDATESTRINGS_H_
28 #define WEBGLVALIDATESTRINGS_H_
30 #include "WebGLContext.h"
32 namespace mozilla {
34 // The following code was taken from the WebKit WebGL implementation,
35 // which can be found here:
36 // http://trac.webkit.org/browser/trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp?rev=93625#L121
37 // Note that some modifications were done to adapt it to Mozilla.
38 /****** BEGIN CODE TAKEN FROM WEBKIT ******/
39 bool WebGLContext::ValidateGLSLCharacter(PRUnichar c)
41 // Printing characters are valid except " $ ` @ \ ' DEL.
42 if (c >= 32 && c <= 126 &&
43 c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
45 return true;
48 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
49 if (c >= 9 && c <= 13) {
50 return true;
53 return false;
56 // Strips comments from shader text. This allows non-ASCII characters
57 // to be used in comments without potentially breaking OpenGL
58 // implementations not expecting characters outside the GLSL ES set.
59 class StripComments {
60 public:
61 StripComments(const nsAString& str)
62 : m_parseState(BeginningOfLine)
63 , m_end(str.EndReading())
64 , m_current(str.BeginReading())
65 , m_position(0)
67 m_result.SetLength(str.Length());
68 parse();
71 const nsTArray<PRUnichar>& result()
73 return m_result;
76 size_t length()
78 return m_position;
81 private:
82 bool hasMoreCharacters()
84 return (m_current < m_end);
87 void parse()
89 while (hasMoreCharacters()) {
90 process(current());
91 // process() might advance the position.
92 if (hasMoreCharacters())
93 advance();
97 void process(PRUnichar);
99 bool peek(PRUnichar& character)
101 if (m_current + 1 >= m_end)
102 return false;
103 character = *(m_current + 1);
104 return true;
107 PRUnichar current()
109 //ASSERT(m_position < m_length);
110 return *m_current;
113 void advance()
115 ++m_current;
118 bool isNewline(PRUnichar character)
120 // Don't attempt to canonicalize newline related characters.
121 return (character == '\n' || character == '\r');
124 void emit(PRUnichar character)
126 m_result[m_position++] = character;
129 enum ParseState {
130 // Have not seen an ASCII non-whitespace character yet on
131 // this line. Possible that we might see a preprocessor
132 // directive.
133 BeginningOfLine,
135 // Have seen at least one ASCII non-whitespace character
136 // on this line.
137 MiddleOfLine,
139 // Handling a preprocessor directive. Passes through all
140 // characters up to the end of the line. Disables comment
141 // processing.
142 InPreprocessorDirective,
144 // Handling a single-line comment. The comment text is
145 // replaced with a single space.
146 InSingleLineComment,
148 // Handling a multi-line comment. Newlines are passed
149 // through to preserve line numbers.
150 InMultiLineComment
153 ParseState m_parseState;
154 const PRUnichar* m_end;
155 const PRUnichar* m_current;
156 size_t m_position;
157 nsTArray<PRUnichar> m_result;
160 void StripComments::process(PRUnichar c)
162 if (isNewline(c)) {
163 // No matter what state we are in, pass through newlines
164 // so we preserve line numbers.
165 emit(c);
167 if (m_parseState != InMultiLineComment)
168 m_parseState = BeginningOfLine;
170 return;
173 PRUnichar temp = 0;
174 switch (m_parseState) {
175 case BeginningOfLine:
176 // If it's an ASCII space.
177 if (c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9))) {
178 emit(c);
179 break;
182 if (c == '#') {
183 m_parseState = InPreprocessorDirective;
184 emit(c);
185 break;
188 // Transition to normal state and re-handle character.
189 m_parseState = MiddleOfLine;
190 process(c);
191 break;
193 case MiddleOfLine:
194 if (c == '/' && peek(temp)) {
195 if (temp == '/') {
196 m_parseState = InSingleLineComment;
197 emit(' ');
198 advance();
199 break;
202 if (temp == '*') {
203 m_parseState = InMultiLineComment;
204 // Emit the comment start in case the user has
205 // an unclosed comment and we want to later
206 // signal an error.
207 emit('/');
208 emit('*');
209 advance();
210 break;
214 emit(c);
215 break;
217 case InPreprocessorDirective:
218 // No matter what the character is, just pass it
219 // through. Do not parse comments in this state. This
220 // might not be the right thing to do long term, but it
221 // should handle the #error preprocessor directive.
222 emit(c);
223 break;
225 case InSingleLineComment:
226 // The newline code at the top of this function takes care
227 // of resetting our state when we get out of the
228 // single-line comment. Swallow all other characters.
229 break;
231 case InMultiLineComment:
232 if (c == '*' && peek(temp) && temp == '/') {
233 emit('*');
234 emit('/');
235 m_parseState = MiddleOfLine;
236 advance();
237 break;
240 // Swallow all other characters. Unclear whether we may
241 // want or need to just emit a space per character to try
242 // to preserve column numbers for debugging purposes.
243 break;
247 /****** END CODE TAKEN FROM WEBKIT ******/
249 } // end namespace mozilla
251 #endif // WEBGLVALIDATESTRINGS_H_