Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Net / System / Net / _ChunkParse.cs / 1 / _ChunkParse.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { /*++ IReadChunkBytes - An interface for reading chunk streams. An interface implemented by objects that read from chuked streams. This interface is used by the chunk parsing utility functions. --*/ internal interface IReadChunkBytes { int NextByte {get; set;} } // interface IReadChunkBytes internal static class ChunkParse { /*++ SkipPastCRLF - Skip past the terminating CRLF. An internal utility function. This is used to skip over any chunk extensions or footers in a chunked response. We look through the source bytes looking for the terminating CRLF, honoring any quoted strings we see in the process. Input: Source - An IReadChunkBytes interface which we can use to read the bytes from. Returns: The number of bytes we consumed, or -1 if there wasn't enough in the buffer. We'll return a 0 if there's some sort of syntax error. --*/ internal static int SkipPastCRLF(IReadChunkBytes Source) { int BytesRead; int Current; bool Escape; bool InQS; bool HaveCR; bool HaveLF; BytesRead = 0; Escape = false; InQS = false; HaveCR = false; HaveLF = false; GlobalLog.Enter("SkipPastCRLF"); // Loop through the buffer, looking at each byte. We have a // pseudo state machine going here, and the action we take // with each byte depends on the state. Current = Source.NextByte; BytesRead++; while (Current != -1) { // If we saw a CR last time, it must be followed by an unescaped // LF, otherwise it's an error. If it is followed by a LF, and // we're not in a quoted string, then we've found our termination. // If we are in a quoted string, this could be the start of a LWS // production. Remember that, and next time through we'll // check to make sure that this is an LWS production. if (HaveCR) { if (Current != '\n') { // CR w/o a trailing LF is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } else { if (Escape) { // We have an CR, but they're trying to escape the // LF. This is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } // If we're not in a quoted string, we're done. if (!InQS) { // We've found the terminating CRLF pair. GlobalLog.Leave("SkipPastCRLF", 0); return BytesRead; } else { // We're in a quoted string, so set HaveLF // so we remember to check for a LWS production next // time. HaveLF = true; // We've proceessed this byte, set Escape so we don't // do it again. Escape = true; } } // We're past the CR now, don't remember it any more. HaveCR = false; } else { // If HaveLF is set, we must be in a quoted string and have // seen a CRLF pair. Make sure this character is a space or // tab. if (HaveLF) { // We have a LF. For this to be valid, we have to have a // space or tab be the next character. if (Current != ' ' && Current != '\t') { // Not a continuation, so return an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } Escape = true; // Don't process this byte again. HaveLF = false; } } // If we're escaping, just skip the next character. if (!Escape) { switch (Current) { case '"': if (InQS) { InQS = false; } else { InQS = true; } break; case '\\': if (InQS) { Escape = true; } break; case '\r': HaveCR = true; break; case '\n': // If we get here, we have a LF without a preceding CR. // This is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; default: break; } } else { // We're escaping, do nothing but rest the Escape flag. Escape = false; } Current = Source.NextByte; BytesRead++; } // If we get here, we never saw the terminating CRLF, so return -1. GlobalLog.Leave("SkipPastCRLF", -1); return -1; } /*++ GetChunkSize - Read the chunk size. An internal utility function. Reads the chunk size from a byte soruce, and returns the size or -1 if there isn't enough data. Input: Source - An IReadChunkBytes interface which we can use to read the bytes from. chunkSize - Out parameter for chunk size. Returns: The number of bytes we consumed, or -1 if there wasn't enough in the buffer. We'll also return 0 if we have some sort of syntax error. --*/ internal static int GetChunkSize(IReadChunkBytes Source, out int chunkSize) { int BytesRead; int Size; int Current; GlobalLog.Enter("GetChunkSize"); Size = 0; // // Loop while we have data. If we run out of data and exit the loop // at the bottom, then we've run out of data and haven't found the // length. Current = Source.NextByte; BytesRead = 0; if (Current == 10 || Current == 13) { GlobalLog.Print(" Got Char: " + Current.ToString("X")); BytesRead++; Current = Source.NextByte; } while (Current != -1) { // Get the next byte, and decode it. if (Current >= '0' && Current <= '9') { // Normalize it to 0 based. Current -= '0'; } else { // If we're here, this might be a hex digit. // If it is, normalize it to 10 based. if (Current >= 'a' && Current <= 'f') { Current -= 'a'; } else { if (Current >= 'A' && Current <= 'F') { Current -= 'A'; } else { // Done with the decoding. If we haven't actually // decoded a digit yet, we'll end up returning // 0, which will signal the error. // Push back the byte we read and didn't use. Source.NextByte = Current; chunkSize = Size; // Return how many bytes we took. GlobalLog.Print("Chunk Size = " + Size.ToString()); GlobalLog.Leave("GetChunkSize", BytesRead); return BytesRead; } } // If we get here we've had an A-F digit, add 10 // to it to normalize it. Current += 10; } // Update the size and our state. Size *= 16; Size += Current; BytesRead++; Current = Source.NextByte; } chunkSize = Size; GlobalLog.Print("*Chunk Size* = " + Size.ToString()); GlobalLog.Leave("GetChunkSize", -1); return -1; } } // ChunkParse } // namespace System.Net // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { /*++ IReadChunkBytes - An interface for reading chunk streams. An interface implemented by objects that read from chuked streams. This interface is used by the chunk parsing utility functions. --*/ internal interface IReadChunkBytes { int NextByte {get; set;} } // interface IReadChunkBytes internal static class ChunkParse { /*++ SkipPastCRLF - Skip past the terminating CRLF. An internal utility function. This is used to skip over any chunk extensions or footers in a chunked response. We look through the source bytes looking for the terminating CRLF, honoring any quoted strings we see in the process. Input: Source - An IReadChunkBytes interface which we can use to read the bytes from. Returns: The number of bytes we consumed, or -1 if there wasn't enough in the buffer. We'll return a 0 if there's some sort of syntax error. --*/ internal static int SkipPastCRLF(IReadChunkBytes Source) { int BytesRead; int Current; bool Escape; bool InQS; bool HaveCR; bool HaveLF; BytesRead = 0; Escape = false; InQS = false; HaveCR = false; HaveLF = false; GlobalLog.Enter("SkipPastCRLF"); // Loop through the buffer, looking at each byte. We have a // pseudo state machine going here, and the action we take // with each byte depends on the state. Current = Source.NextByte; BytesRead++; while (Current != -1) { // If we saw a CR last time, it must be followed by an unescaped // LF, otherwise it's an error. If it is followed by a LF, and // we're not in a quoted string, then we've found our termination. // If we are in a quoted string, this could be the start of a LWS // production. Remember that, and next time through we'll // check to make sure that this is an LWS production. if (HaveCR) { if (Current != '\n') { // CR w/o a trailing LF is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } else { if (Escape) { // We have an CR, but they're trying to escape the // LF. This is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } // If we're not in a quoted string, we're done. if (!InQS) { // We've found the terminating CRLF pair. GlobalLog.Leave("SkipPastCRLF", 0); return BytesRead; } else { // We're in a quoted string, so set HaveLF // so we remember to check for a LWS production next // time. HaveLF = true; // We've proceessed this byte, set Escape so we don't // do it again. Escape = true; } } // We're past the CR now, don't remember it any more. HaveCR = false; } else { // If HaveLF is set, we must be in a quoted string and have // seen a CRLF pair. Make sure this character is a space or // tab. if (HaveLF) { // We have a LF. For this to be valid, we have to have a // space or tab be the next character. if (Current != ' ' && Current != '\t') { // Not a continuation, so return an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; } Escape = true; // Don't process this byte again. HaveLF = false; } } // If we're escaping, just skip the next character. if (!Escape) { switch (Current) { case '"': if (InQS) { InQS = false; } else { InQS = true; } break; case '\\': if (InQS) { Escape = true; } break; case '\r': HaveCR = true; break; case '\n': // If we get here, we have a LF without a preceding CR. // This is an error. GlobalLog.Leave("SkipPastCRLF", 0); return 0; default: break; } } else { // We're escaping, do nothing but rest the Escape flag. Escape = false; } Current = Source.NextByte; BytesRead++; } // If we get here, we never saw the terminating CRLF, so return -1. GlobalLog.Leave("SkipPastCRLF", -1); return -1; } /*++ GetChunkSize - Read the chunk size. An internal utility function. Reads the chunk size from a byte soruce, and returns the size or -1 if there isn't enough data. Input: Source - An IReadChunkBytes interface which we can use to read the bytes from. chunkSize - Out parameter for chunk size. Returns: The number of bytes we consumed, or -1 if there wasn't enough in the buffer. We'll also return 0 if we have some sort of syntax error. --*/ internal static int GetChunkSize(IReadChunkBytes Source, out int chunkSize) { int BytesRead; int Size; int Current; GlobalLog.Enter("GetChunkSize"); Size = 0; // // Loop while we have data. If we run out of data and exit the loop // at the bottom, then we've run out of data and haven't found the // length. Current = Source.NextByte; BytesRead = 0; if (Current == 10 || Current == 13) { GlobalLog.Print(" Got Char: " + Current.ToString("X")); BytesRead++; Current = Source.NextByte; } while (Current != -1) { // Get the next byte, and decode it. if (Current >= '0' && Current <= '9') { // Normalize it to 0 based. Current -= '0'; } else { // If we're here, this might be a hex digit. // If it is, normalize it to 10 based. if (Current >= 'a' && Current <= 'f') { Current -= 'a'; } else { if (Current >= 'A' && Current <= 'F') { Current -= 'A'; } else { // Done with the decoding. If we haven't actually // decoded a digit yet, we'll end up returning // 0, which will signal the error. // Push back the byte we read and didn't use. Source.NextByte = Current; chunkSize = Size; // Return how many bytes we took. GlobalLog.Print("Chunk Size = " + Size.ToString()); GlobalLog.Leave("GetChunkSize", BytesRead); return BytesRead; } } // If we get here we've had an A-F digit, add 10 // to it to normalize it. Current += 10; } // Update the size and our state. Size *= 16; Size += Current; BytesRead++; Current = Source.NextByte; } chunkSize = Size; GlobalLog.Print("*Chunk Size* = " + Size.ToString()); GlobalLog.Leave("GetChunkSize", -1); return -1; } } // ChunkParse } // namespace System.Net // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FixUpCollection.cs
- KeyValueConfigurationElement.cs
- LineVisual.cs
- GlobalizationSection.cs
- TransformPatternIdentifiers.cs
- SecurityRuntime.cs
- ColumnReorderedEventArgs.cs
- InitialServerConnectionReader.cs
- DiscoveryExceptionDictionary.cs
- ContentTextAutomationPeer.cs
- CompiledQuery.cs
- MappingSource.cs
- DesignerView.cs
- ConstNode.cs
- SerializationObjectManager.cs
- SharedUtils.cs
- JumpItem.cs
- FacetDescription.cs
- ControlCachePolicy.cs
- XmlTextReader.cs
- DropShadowEffect.cs
- InstanceHandleReference.cs
- RowToFieldTransformer.cs
- CurrencyManager.cs
- WebPartRestoreVerb.cs
- TemplateParser.cs
- RootBuilder.cs
- SqlCommand.cs
- VectorAnimationUsingKeyFrames.cs
- HwndSubclass.cs
- ZoneButton.cs
- HandlerMappingMemo.cs
- hwndwrapper.cs
- ThreadStaticAttribute.cs
- SigningCredentials.cs
- DrawingCollection.cs
- AmbientLight.cs
- ComPlusSynchronizationContext.cs
- URI.cs
- XmlDataProvider.cs
- String.cs
- HotSpot.cs
- PlacementWorkspace.cs
- XmlObjectSerializerWriteContextComplex.cs
- WriterOutput.cs
- XMLDiffLoader.cs
- RelativeSource.cs
- objectquery_tresulttype.cs
- ValidationPropertyAttribute.cs
- CollectionViewProxy.cs
- Material.cs
- ModuleBuilder.cs
- WinCategoryAttribute.cs
- FixedTextSelectionProcessor.cs
- SingleAnimationUsingKeyFrames.cs
- ObjectQueryExecutionPlan.cs
- ToolStripPanelCell.cs
- ManualResetEvent.cs
- CleanUpVirtualizedItemEventArgs.cs
- DateTimePicker.cs
- BuildResultCache.cs
- RegexRunner.cs
- SelectionProcessor.cs
- ToolStripMenuItem.cs
- ServiceX509SecurityTokenProvider.cs
- WebReferenceOptions.cs
- DBBindings.cs
- Storyboard.cs
- AnyAllSearchOperator.cs
- FilteredDataSetHelper.cs
- FocusTracker.cs
- SourceItem.cs
- SettingsAttributes.cs
- DynamicQueryableWrapper.cs
- UriTemplateMatch.cs
- ToolboxComponentsCreatingEventArgs.cs
- GrammarBuilderPhrase.cs
- DesignerSerializationManager.cs
- ApplicationManager.cs
- MethodRental.cs
- ViewDesigner.cs
- QuadraticBezierSegment.cs
- AttachedPropertyMethodSelector.cs
- StateWorkerRequest.cs
- BasicHttpMessageSecurityElement.cs
- PathGradientBrush.cs
- FixedSOMPageConstructor.cs
- FontFamily.cs
- BamlWriter.cs
- COM2DataTypeToManagedDataTypeConverter.cs
- CorrelationValidator.cs
- PropertyGeneratedEventArgs.cs
- OutputCacheProfileCollection.cs
- SessionEndingCancelEventArgs.cs
- webeventbuffer.cs
- TypeUtils.cs
- FamilyTypefaceCollection.cs
- TcpWorkerProcess.cs
- SecurityChannelFactory.cs
- UserPersonalizationStateInfo.cs