AssetPackager.ScriptDeferFilter.Write C# (CSharp) Method

Write() public method

Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
public Write ( byte buffer, int offset, int count ) : void
buffer byte An array of bytes. This method copies /// bytes from to the current stream.
offset int The zero-based byte offset in at /// which to begin copying bytes to the current stream.
count int The number of bytes to be written to the current stream.
return void
		public override void Write(byte[] buffer, int offset, int count)
		{
			// If we are not capturing script blocks anymore, just redirect to response stream
			if (!_captureScripts)
			{
				_responseStream.Write(buffer, offset, count);
				return;
			}

			// Script and HTML can be in one of the following combinations in the specified buffer:          
			// .....<script ....>.....</script>.....
			// <script ....>.....</script>.....
			// <script ....>.....</script>
			// <script ....>.....</script> .....
			// ....<script ....>..... 
			// <script ....>..... 
			// .....</script>.....
			// .....</script>
			// <script>.....
			// .... </script>
			// ......
			// Here, "...." means html content between and outside script tags

			char[] content;
			char[] charBuffer = _encoding.GetChars(buffer, offset, count);

			// If some bytes were left for processing during last Write call
			// then consider those into the current buffer
			if (null != _pendingBuffer)
			{
				content = new char[charBuffer.Length + _pendingBuffer.Length];
				Array.Copy(_pendingBuffer, 0, content, 0, _pendingBuffer.Length);
				Array.Copy(charBuffer, 0, content, _pendingBuffer.Length, charBuffer.Length);
				_pendingBuffer = null;
			}
			else
			{
				content = charBuffer;
			}

			int scriptTagStart = 0;
			int lastScriptTagEnd = 0;
			bool scriptTagStarted = false;

			int pos;
			for (pos = 0; pos < content.Length; pos++)
			{
				// See if tag start
				char c = content[pos];
				if (c != '<') continue;

				// Make sure there are enough characters available in the buffer to finish 
				// tag start. This will happen when a tag partially starts but does not end
				// For example, a partial script tag
				// <script
				// Or it's the ending html tag or some tag closing that ends the whole response
				// </html>
				if (pos + TAG_SCRIPT.Length >= content.Length)
				{
					// a tag started but there are less than 10 characters available. So, let's
					// store the remaining content in a buffer and wait for another Write(...) or
					// flush call.
					_pendingBuffer = new char[content.Length - pos];
					Array.Copy(content, pos, _pendingBuffer, 0, content.Length - pos);
					break;
				}

				int tagStart = pos;
				// Check if it's a tag ending
				if (content[pos + 1] == '/')
				{
					pos += 2; // go past the </ 

					// See if script tag is ending
					if (CompareChars(TAG_SCRIPT, content, pos))
					{
						// Script tag just ended. Get the whole script
						// and store in buffer
						pos += TAG_SCRIPT.Length + 1;
						_scriptBlocks.Append(content, scriptTagStart, pos - scriptTagStart);
						_scriptBlocks.Append(Environment.NewLine);
						lastScriptTagEnd = pos;

						scriptTagStarted = false;

						pos--; // continue will increase pos by one again
						continue;
					}
					if (_isInServerForm && CompareChars(TAG_FORM, content, pos))
					{
						// Server form tag has just end. Time for rendering all the script
						// blocks we have suppressed so far and stop capturing script blocks.
						_isInServerForm = false;
						if (_scriptBlocks.Length > 0)
						{
							// Render all pending html output till now
							WriteOutput(content, lastScriptTagEnd, tagStart - lastScriptTagEnd);

							// Render the script blocks
							RenderAllScriptBlocks();

							// Stop capturing for script blocks
							_captureScripts = false;

							// Write from the body tag start to the end of the inut buffer and return
							// from the function. We are done.
							WriteOutput(content, tagStart, content.Length - tagStart);
							return;
						}
					}
					else
					{
						// some other tag's closing. safely skip one character as smallest
						// html tag is one character e.g. <b>. just an optimization to save one loop
						pos++;
					}
				}
				else
				{
					if (CompareChars(TAG_SCRIPT, content, pos + 1))
					{
						// Script tag started. Record the position as we will 
						// capture the whole script tag including its content
						// and store in an internal buffer.
						scriptTagStart = pos;

						// Write html content since last script tag closing upto this script tag 
						WriteOutput(content, lastScriptTagEnd, scriptTagStart - lastScriptTagEnd);

						// Skip the tag start to save some loops
						pos += TAG_SCRIPT.Length + 1;

						scriptTagStarted = true;
					}
					else if (!_isInServerForm && CompareChars(TAG_INPUT, content, pos + 1))
					{
						// <input> tag started, so we need to check if it is __VIEWSTATE field
						// to make sure that the form that contains it is a server form.

						// First we need to sure if there is enough bytes in the buffer.
						if (pos + TAG_INPUT_VIEWSTATE.Length >= content.Length)
						{
							_pendingBuffer = new char[content.Length - pos];
							Array.Copy(content, pos, _pendingBuffer, 0, content.Length - pos);
							break;
						}

						// Check if input tag contains viewstate information.
						if (CompareChars(TAG_INPUT_VIEWSTATE, content, pos + 1))
						{
							// Yep! We are in the server form.
							_isInServerForm = true;
							pos += TAG_INPUT_VIEWSTATE.Length + 1;
						}
						else
						{
							// Skip the input tag.
							pos += TAG_INPUT.Length + 1;
						}
					}
					else
					{
						// Some other tag started.
						// We can safely skip 2 character because the smallest tag is one 
						// character e.g. <b>. It's just an optimization to eliminate one loop.
						pos++;
					}
				}
			}

			// If a script tag is partially sent to buffer, then the remaining content
			// is part of the last script block
			if (scriptTagStarted)
			{
				_scriptBlocks.Append(content, scriptTagStart, pos - scriptTagStart);
			}
			else
			{
				// Render the characters since the last script tag ending
				WriteOutput(content, lastScriptTagEnd, pos - lastScriptTagEnd);
			}
		}