Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Configuration / System / Configuration / XmlUtil.cs / 1305376 / XmlUtil.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Configuration { using System.Configuration.Internal; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.Configuration; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Xml; using System.Net; // // XmlTextReader Helper class. // // Provides the following services: // // * Reader methods that verify restrictions on the XML that can be contained in a config file. // * Methods to copy the reader stream to a writer stream. // * Method to copy a configuration section to a string. // * Methods to format a string of XML. // // Errors found during read are accumlated in a ConfigurationSchemaErrors object. // internal sealed class XmlUtil : IDisposable, IConfigErrorInfo { private const int MAX_LINE_WIDTH=60; // Offset from where the reader reports the LinePosition of an Xml Node to // the start of that representation in text. static readonly int[] s_positionOffset = { 0, // None, 1, // Element,-1, // EndEntity, N/A 2, // XmlDeclaration 0, "trueLinePosition > 0"); return trueLinePosition; } } internal XmlTextReader Reader { get { return _reader; } } internal ConfigurationSchemaErrors SchemaErrors { get { return _schemaErrors; } } // // Read until the Next Element element, or we hit // the end of the file. // internal void ReadToNextElement() { while (_reader.Read()) { if (_reader.MoveToContent() == XmlNodeType.Element) { // We found an element, so return return; } } // We must of hit end of file } // // Skip this element and its children, then read to next start element, // or until we hit end of file. // internal void SkipToNextElement() { _reader.Skip(); _reader.MoveToContent(); while (!_reader.EOF && _reader.NodeType != XmlNodeType.Element) { _reader.Read(); _reader.MoveToContent(); } } // // Read to the next start element, and verify that all XML nodes read are permissible. // internal void StrictReadToNextElement(ExceptionAction action) { while (_reader.Read()) { // optimize for the common case if (_reader.NodeType == XmlNodeType.Element) { return; } VerifyIgnorableNodeType(action); } } // // Skip this element and its children, then read to next start element, // or until we hit end of file. Verify that nodes that are read after the // skipped element are permissible. // internal void StrictSkipToNextElement(ExceptionAction action) { _reader.Skip(); while (!_reader.EOF && _reader.NodeType != XmlNodeType.Element) { VerifyIgnorableNodeType(action); _reader.Read(); } } // // StrictSkipToOurParentsEndElement // // Skip until we hit the end element for our parent, and verify // that nodes at the parent level are permissible. // internal void StrictSkipToOurParentsEndElement(ExceptionAction action) { int currentDepth = _reader.Depth; // Skip everything at out current level while (_reader.Depth >= currentDepth) { _reader.Skip(); } while (!_reader.EOF && _reader.NodeType != XmlNodeType.EndElement) { VerifyIgnorableNodeType(action); _reader.Read(); } } // // Add an error if the node type is not permitted by the configuration schema. // internal void VerifyIgnorableNodeType(ExceptionAction action) { XmlNodeType nodeType = _reader.NodeType; if (nodeType != XmlNodeType.Comment && nodeType != XmlNodeType.EndElement) { ConfigurationException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_base_unrecognized_element), this); SchemaErrors.AddError(ex, action); } } // // Add an error if there are attributes that have not been examined, // and are therefore unrecognized. // internal void VerifyNoUnrecognizedAttributes(ExceptionAction action) { if (_reader.MoveToNextAttribute()) { AddErrorUnrecognizedAttribute(action); } } // // Add an error if the retrieved attribute is null, // and therefore not present. // internal bool VerifyRequiredAttribute( object o, string attrName, ExceptionAction action) { if (o == null) { AddErrorRequiredAttribute(attrName, action); return false; } else { return true; } } // // Functions to handle parsing errors // internal void AddErrorUnrecognizedAttribute(ExceptionAction action) { ConfigurationErrorsException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_base_unrecognized_attribute, _reader.Name), this); SchemaErrors.AddError(ex, action); } internal void AddErrorRequiredAttribute(string attrib, ExceptionAction action) { ConfigurationErrorsException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_missing_required_attribute, attrib, _reader.Name), this); SchemaErrors.AddError(ex, action); } internal void AddErrorReservedAttribute(ExceptionAction action) { ConfigurationErrorsException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_reserved_attribute, _reader.Name), this); SchemaErrors.AddError(ex, action); } internal void AddErrorUnrecognizedElement(ExceptionAction action) { ConfigurationErrorsException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_base_unrecognized_element), this); SchemaErrors.AddError(ex, action); } internal void VerifyAndGetNonEmptyStringAttribute(ExceptionAction action, out string newValue) { if (!String.IsNullOrEmpty(_reader.Value)) { newValue = _reader.Value; } else { newValue = null; ConfigurationException ex = new ConfigurationErrorsException( SR.GetString(SR.Empty_attribute, _reader.Name), this); SchemaErrors.AddError(ex, action); } } // VerifyAndGetBooleanAttribute // // Verify and Retrieve the Boolean Attribute. If it is not // a valid value then log an error and set the value to a given default. // internal void VerifyAndGetBooleanAttribute( ExceptionAction action, bool defaultValue, out bool newValue) { if (_reader.Value == "true") { newValue = true; } else if (_reader.Value == "false") { newValue = false; } else { // Unrecognized value newValue = defaultValue; ConfigurationErrorsException ex = new ConfigurationErrorsException( SR.GetString(SR.Config_invalid_boolean_attribute, _reader.Name), this); SchemaErrors.AddError(ex, action); } } // // Copy an XML element, then continue copying until we've hit the next element // or exited this depth. // internal bool CopyOuterXmlToNextElement(XmlUtilWriter utilWriter, bool limitDepth) { CopyElement(utilWriter); // Copy until reaching the next element, or if limitDepth == true until we've exited this depth. return CopyReaderToNextElement(utilWriter, limitDepth); } // // Copy an XML element but skip all its child elements, then continue copying until we've hit the next element. // internal bool SkipChildElementsAndCopyOuterXmlToNextElement(XmlUtilWriter utilWriter) { bool isEmptyElement = _reader.IsEmptyElement; int startingLine = _reader.LineNumber; #if DBG int depth = _reader.Depth; #endif Debug.Assert(_reader.NodeType == XmlNodeType.Element, "_reader.NodeType == XmlNodeType.Element"); CopyXmlNode(utilWriter); // See if we need to skip any child element if (!isEmptyElement) { while (_reader.NodeType != XmlNodeType.EndElement) { // Skip all the inner child elements if (_reader.NodeType == XmlNodeType.Element) { _reader.Skip(); // We need to skip all the whitespaces following a skipped element. // - If the whitespaces don't contain /r/n, then it's okay to skip them // as part of the element. // - If the whitespaces contain /r/n, not skipping them will result // in a redundant emtpy line being copied. if (_reader.NodeType == XmlNodeType.Whitespace) { _reader.Skip(); } } else { // We want to preserve other content, e.g. comments. CopyXmlNode(utilWriter); } } if (_reader.LineNumber != startingLine) { // The whitespace in front of the EndElement was skipped above. // We need to append spaces to compensate for that. utilWriter.AppendSpacesToLinePosition(TrueLinePosition); } #if DBG Debug.Assert(_reader.Depth == depth, "We should be at the same depth as the opening Element"); #endif // Copy the end element. CopyXmlNode(utilWriter); } return CopyReaderToNextElement(utilWriter, true); } // // Copy the reader until we hit an element, or we've exited the current depth. // internal bool CopyReaderToNextElement(XmlUtilWriter utilWriter, bool limitDepth) { bool moreToRead = true; // Set the depth if we limit copying to this depth int depth; if (limitDepth) { // there is nothing in the element if (_reader.NodeType == XmlNodeType.EndElement) return true; depth = _reader.Depth; } else { depth = 0; } // Copy nodes until we've reached the desired depth, or until we hit an element. do { if (_reader.NodeType == XmlNodeType.Element) break; if (_reader.Depth < depth) { break; } moreToRead = CopyXmlNode(utilWriter); } while (moreToRead); return moreToRead; } // // Skip over the current element and copy until the next element. // This function removes the one blank line that would otherwise // be inserted by simply skipping and copying to the next element // in a situation like this: // // // // // //// // // internal bool SkipAndCopyReaderToNextElement(XmlUtilWriter utilWriter, bool limitDepth) { Debug.Assert(_reader.NodeType == XmlNodeType.Element, "_reader.NodeType == XmlNodeType.Element"); // If the last line before the element is not blank, then we do not have to // remove the blank line. if (!utilWriter.IsLastLineBlank) { _reader.Skip(); return CopyReaderToNextElement(utilWriter, limitDepth); } // Set the depth if we limit copying to this depth int depth; if (limitDepth) { depth = _reader.Depth; } else { depth = 0; } // Skip over the element _reader.Skip(); int lineNumberOfEndElement = _reader.LineNumber; // Read until we hit a a non-whitespace node or reach the end while (!_reader.EOF) { if (_reader.NodeType != XmlNodeType.Whitespace) { // // If the next non-whitepace node is on another line, // seek back to the beginning of the current blank line, // skip a blank line of whitespace, and copy the remaining whitespace. // if (_reader.LineNumber > lineNumberOfEndElement) { utilWriter.SeekToLineStart(); utilWriter.AppendWhiteSpace(lineNumberOfEndElement + 1, 1, LineNumber, TrueLinePosition); } break; } _reader.Read(); } // Copy nodes until we've reached the desired depth, or until we hit an element. while (!_reader.EOF) { if (_reader.NodeType == XmlNodeType.Element) break; if (_reader.Depth < depth) { break; } CopyXmlNode(utilWriter); }; return !_reader.EOF; } // // Copy an XML element and its children, up to and including the end element. // private void CopyElement(XmlUtilWriter utilWriter) { Debug.Assert(_reader.NodeType== XmlNodeType.Element, "_reader.NodeType== XmlNodeType.Element"); int depth = _reader.Depth; bool isEmptyElement = _reader.IsEmptyElement; // Copy current node CopyXmlNode(utilWriter); // Copy nodes while the depth is greater than the current depth. while (_reader.Depth > depth) { CopyXmlNode(utilWriter); } // Copy the end element. if (!isEmptyElement) { CopyXmlNode(utilWriter); } } // // Copy a single XML node, attempting to preserve whitespace. // A side effect of this method is to advance the reader to the next node. // // PERFORMANCE NOTE: this function is used at runtime to copy a configuration section, // and at designtime to copy an entire XML document. // // At designtime, this function needs to be able to copy a " // the XmlReader API does not give us the location of the closing string, e.g. ">". // To correctly determine the location of the closing part, we advance the reader, // determine the position of the next node, then work backwards to add whitespace // and add the closing string. // string close = null; int lineNumber = -1; int linePosition = -1; int readerLineNumber = 0; int readerLinePosition = 0; int writerLineNumber = 0; int writerLinePosition = 0; if (utilWriter.TrackPosition) { readerLineNumber = _reader.LineNumber; readerLinePosition = _reader.LinePosition; writerLineNumber = utilWriter.LineNumber; writerLinePosition = utilWriter.LinePosition; } // We test the node type in the likely order of decreasing occurrence. XmlNodeType nodeType = _reader.NodeType; if (nodeType == XmlNodeType.Whitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.Element) { close = (_reader.IsEmptyElement) ? "/>" : ">"; // get the line position after the element declaration: // // // is reported with the same position as // // // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write(""); utilWriter.Write(_reader.Name); } else if (nodeType == XmlNodeType.Comment) { utilWriter.AppendComment(_reader.Value); } else if (nodeType == XmlNodeType.Text) { utilWriter.AppendEscapeTextString(_reader.Value); } else if (nodeType == XmlNodeType.XmlDeclaration) { close = "?>"; // get line position after the xml declaration: // // // is reported with the same position as // // // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // // // is reported with the same position as // // // // The first example has one space between 'pi' and "value", the second has multiple spaces. // utilWriter.AppendProcessingInstruction(_reader.Name, _reader.Value); } else if (nodeType == XmlNodeType.EntityReference) { utilWriter.AppendEntityRef(_reader.Name); } else if (nodeType == XmlNodeType.CDATA) { utilWriter.AppendCData(_reader.Value); } else if (nodeType == XmlNodeType.DocumentType) { // // XmlNodeType.DocumentType has the following format: // // // // The reader only gives us the position of 'rootElementName', so we must track what was // written before " // ^ // linePosition lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; // Note that there is no way to get the spacing after PUBLIC or SYSTEM attributes and their values if (_reader.MoveToFirstAttribute()) { // Write the space before SYSTEM or PUBLIC utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, _reader.LineNumber, _reader.LinePosition); // Write SYSTEM or PUBLIC and the 1st value of the attribute string attrName = _reader.Name; utilWriter.Write(attrName); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(0); // If PUBLIC, write the second value of the attribute if (attrName == "PUBLIC") { _reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(1); } } // If there is a dtd, write it if (dtdValue != null && dtdValue.Length > 0) { utilWriter.Write(" ["); utilWriter.Write(dtdValue); utilWriter.Write(']'); } utilWriter.Write('>'); } // Advance the _reader so we can get the position of the next node. bool moreToRead = _reader.Read(); nodeType = _reader.NodeType; // Close the node we are copying. if (close != null) { // // Find the position of the close string, for example: // // // ^ // closeLinePosition // int startOffset = GetPositionOffset(nodeType); int closeLineNumber = _reader.LineNumber; int closeLinePosition = _reader.LinePosition - startOffset - close.Length; // Add whitespace up to the position of the close string utilWriter.AppendWhiteSpace(lineNumber, linePosition, closeLineNumber, closeLinePosition); // Write the close string utilWriter.Write(close); } // // Track the position of the reader based on the position of the reader // before we copied this node and what we have written in copying the node. // This allows us to determine the position of the "); return element.ToString(); } // // Copy or replace an element node. // If the element is an empty element, replace it with a formatted start element if either: // * The contents of the start element string need updating. // * The element needs to contain child elements. // // If the element is empty and is replaced with a start/end element pair, return a // end element string with whitespace formatting; otherwise return null. // internal string UpdateStartElement(XmlUtilWriter utilWriter, string updatedStartElement, bool needsChildren, int linePosition, int indent) { Debug.Assert(_reader.NodeType == XmlNodeType.Element, "_reader.NodeType == NodeType.Element"); string endElement = null; bool needsEndElement = false; string elementName; elementName = _reader.Name; // If the element is empty, determine if a new end element is needed. if (_reader.IsEmptyElement) { if (updatedStartElement == null && needsChildren) { updatedStartElement = RetrieveFullOpenElementTag(); } needsEndElement = (updatedStartElement != null); } if (updatedStartElement == null) { // // If no changes to the start element are required, just copy it. // CopyXmlNode(utilWriter); } else { // // Format a new start element/end element pair // string updatedEndElement = "" + elementName + ">"; string updatedElement = updatedStartElement + updatedEndElement; string formattedElement = FormatXmlElement(updatedElement, linePosition, indent, true); // // Get the start and end element strings from the formatted element. // int iEndElement = formattedElement.LastIndexOf('\n') + 1; string startElement; if (needsEndElement) { endElement = formattedElement.Substring(iEndElement); // Include a newline in the start element as we are expanding an empty element. startElement = formattedElement.Substring(0, iEndElement); } else { // Omit the newline from the start element. startElement = formattedElement.Substring(0, iEndElement - 2); } // Write the new start element. utilWriter.Write(startElement); // Skip over the existing start element. _reader.Read(); } return endElement; } // // Create the cached string writer if it does not exist, // otherwise reuse the existing buffer. // private void ResetCachedStringWriter() { if (_cachedStringWriter == null) { _cachedStringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); } else { _cachedStringWriter.GetStringBuilder().Length = 0; } } // // Copy a configuration section to a string, and advance the reader. // internal string CopySection() { ResetCachedStringWriter(); // Preserve whitespace for sections for backcompat WhitespaceHandling originalHandling = _reader.WhitespaceHandling; _reader.WhitespaceHandling = WhitespaceHandling.All; // Create string writer to write to XmlUtilWriter utilWriter = new XmlUtilWriter(_cachedStringWriter, false); // Copy the element CopyElement(utilWriter); // Reset whitespace handling _reader.WhitespaceHandling = originalHandling; if ((originalHandling == WhitespaceHandling.None) && (Reader.NodeType == XmlNodeType.Whitespace)) { // If we were previously suppose to skip whitespace, and now we // are at it, then lets jump to the next item _reader.Read(); } utilWriter.Flush(); string s = ((StringWriter)utilWriter.Writer).ToString(); return s; } // Format an Xml element to be written to the config file. // Params: // xmlElement - the element // linePosition - start position of the element // indent - indent for each depth // skipFirstIndent - skip indent for the first element? // static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false); // append newline before indent? bool newLine = false; // last node visited was text? bool lastWasText = false; // width of line from end of indentation int lineWidth; // length of the stringbuilder after last indent with newline int sbLengthLastNewLine = 0; while (reader.Read()) { XmlNodeType nodeType = reader.NodeType; if (lastWasText) { utilWriter.Flush(); lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { lineWidth = 0; } switch (nodeType) { case XmlNodeType.CDATA: case XmlNodeType.Element: case XmlNodeType.EndElement: case XmlNodeType.Comment: // Do not indent if the last node was text - doing so would add whitespace // that is included as part of the text. if (!skipFirstIndent && !lastWasText) { utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } } break; default: break; } lastWasText = false; switch (nodeType) { case XmlNodeType.Whitespace: break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(reader.Value); break; case XmlNodeType.CDATA: utilWriter.AppendCData(reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: utilWriter.AppendComment(reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(reader.Value); lastWasText = true; break; case XmlNodeType.Element: { // Write " MAX_LINE_WIDTH) { utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true); lineWidth = indent; writeSpace = false; utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { writeSpace = true; } // Write the attribute reader.MoveToNextAttribute(); utilWriter.Flush(); int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; if (writeSpace) { utilWriter.AppendSpace(); } utilWriter.Write(reader.Name); utilWriter.Write('='); utilWriter.AppendAttributeValue(reader); utilWriter.Flush(); lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength; } } // position reader back on element reader.MoveToElement(); // write closing tag if (reader.IsEmptyElement) { utilWriter.Write(" />"); } else { utilWriter.Write('>'); } break; case XmlNodeType.EndElement: utilWriter.Write(""); utilWriter.Write(reader.Name); utilWriter.Write('>'); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(reader.Name); break; // Ignore
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SelectedDatesCollection.cs
- FindCriteria.cs
- TagNameToTypeMapper.cs
- CharUnicodeInfo.cs
- DateTimeFormatInfoScanner.cs
- linebase.cs
- FragmentQueryKB.cs
- RectangleHotSpot.cs
- SapiAttributeParser.cs
- SqlTopReducer.cs
- DoubleAverageAggregationOperator.cs
- SqlServices.cs
- TraceSource.cs
- ProcessDesigner.cs
- BamlReader.cs
- HttpProcessUtility.cs
- QueryCoreOp.cs
- GC.cs
- CodeDirectoryCompiler.cs
- DbgCompiler.cs
- VisualBasicReference.cs
- x509utils.cs
- WizardStepBase.cs
- ColorConverter.cs
- ObjectSecurityT.cs
- OleDbFactory.cs
- SamlAdvice.cs
- Grant.cs
- WSSecureConversationFeb2005.cs
- RadioButton.cs
- DocumentPageView.cs
- _DomainName.cs
- NeutralResourcesLanguageAttribute.cs
- Vector3DAnimationBase.cs
- VariantWrapper.cs
- TrustManagerMoreInformation.cs
- WebWorkflowRole.cs
- TaskHelper.cs
- InputBuffer.cs
- ExtentKey.cs
- MenuItemStyle.cs
- FieldTemplateUserControl.cs
- DataStreamFromComStream.cs
- XmlSchemaChoice.cs
- TextViewBase.cs
- EDesignUtil.cs
- StoragePropertyMapping.cs
- ItemType.cs
- WebPartAddingEventArgs.cs
- EmptyControlCollection.cs
- StickyNoteAnnotations.cs
- BoolExpr.cs
- ComAdminWrapper.cs
- TextDecoration.cs
- Utility.cs
- WebPartConnection.cs
- PropertyContainer.cs
- RemoveStoryboard.cs
- DBCSCodePageEncoding.cs
- DispatcherObject.cs
- FormsAuthenticationEventArgs.cs
- UpWmlMobileTextWriter.cs
- TimersDescriptionAttribute.cs
- BaseTemplatedMobileComponentEditor.cs
- TextClipboardData.cs
- RawMouseInputReport.cs
- QilValidationVisitor.cs
- SqlXml.cs
- Attribute.cs
- TreeViewItem.cs
- SiteMapNodeItem.cs
- MultiSelectRootGridEntry.cs
- FindCriteriaCD1.cs
- XmlChoiceIdentifierAttribute.cs
- WebPartsPersonalizationAuthorization.cs
- HttpStreams.cs
- BooleanConverter.cs
- ProfileServiceManager.cs
- SafeCoTaskMem.cs
- HighlightVisual.cs
- FormsAuthenticationTicket.cs
- _CommandStream.cs
- AliasGenerator.cs
- DictionaryTraceRecord.cs
- GridSplitterAutomationPeer.cs
- Array.cs
- ItemList.cs
- HtmlLabelAdapter.cs
- cryptoapiTransform.cs
- StorageTypeMapping.cs
- MruCache.cs
- FrameworkElementAutomationPeer.cs
- TablePattern.cs
- Table.cs
- DataGridViewSelectedCellCollection.cs
- SQLDateTimeStorage.cs
- GroupedContextMenuStrip.cs
- PictureBox.cs
- dsa.cs
- LambdaCompiler.Lambda.cs