Click or drag to resize

PreprocessReader Class

Preprocesses text returned by a TextReader by removing comments, expanding variables, and implementing simple conditionals.
Inheritance Hierarchy

Namespace:  Neon.IO
Assembly:  Neon.Common (in Neon.Common.dll) Version: 2.14.0
Syntax
public class PreprocessReader : TextReader

The PreprocessReader type exposes the following members.

Constructors
Properties
  NameDescription
Public propertyStatic memberAngleVariableExpansionRegex
A variable expansion Regex that matches normal variables like $<test>, environment variables like <<test>>>, and profile references like <<$lt;secret:my-secret:my-vault>>>> You can set the VariableExpansionRegex property to this value to change the PreprocessReader behavior.
Public propertyStatic memberCurlyVariableExpansionRegex
A variable expansion Regex that matches normal variables like ${test}, environment variables like ${{test}} and profile references like ${{{secret:my-secret:my-vault}}}. You can set the VariableExpansionRegex property to this value to change the PreprocessReader behavior.
Public propertyDefaultEnvironmentVariable
The default value to use for an undefined environment variable or null if a KeyNotFoundException is to be thrown when a undefined environment variable is referenced. This defaults to null.
Public propertyDefaultVariable
The default value to use for an undefined normal variable or null if a KeyNotFoundException is to be thrown when a undefined non-environment variable is referenced. This defaults to null.
Public propertyStatic memberDefaultVariableExpansionRegex
The default variable expansion Regex that matches normal variables like $<test>, environment variables like <<test>>>, and profile references like <<$lt;secret:my-secret:my-vault>>>> You can set the VariableExpansionRegex property to this value to change the PreprocessReader behavior.
Public propertyExpandVariables
Controls whether variables in the source are expanded. This defaults to true.
Public propertyIndent
The number of spaces to indent the output. This defaults to 0.
Public propertyLineEnding
Public propertyStatic memberParenVariableExpansionRegex
A variable expansion Regex that matches normal variables like ${test}, environment variables like $((test)) and profile references like $(((secret:my-secret:my-vault))). You can set the VariableExpansionRegex property to this value to change the PreprocessReader behavior.
Public propertyProcessStatements
Controls whether preprocessor statements are processed. This defaults to true.
Public propertyRemoveBlank
Controls whether blank lines or lines with only whitespace are to be removed while reading. This defaults to false.
Public propertyRemoveComments
Controls whether comments are removed while reading. This defaults to false.
Public propertyStatementMarker
The leading character used to identify a preprocessing statement. This defaults to the pound sign (#).
Public propertyStripComments
Controls whether comments are stripped out while reading. This defaults to true.
Public propertyTabStop
Controls whether embedded TAB (\t) characters will be converted into spaces to format tab stops correctly. This defaults to zero which will not process any tabs.
Public propertyVariableExpansionRegex
The Regex used to match variable expansions. This defaults to matching variables of the form: ${NAME}.
Public propertyStatic memberVariableValidationRegex
INTERNAL USE ONLY: The Regex used to validate variable names.
Top
Methods
  NameDescription
Public methodClose
Closes the TextReader and releases any system resources associated with the TextReader.
(Inherited from TextReader.)
Public methodDispose
Releases all resources used by the TextReader object.
(Inherited from TextReader.)
Protected methodDispose(Boolean)
Releases the unmanaged resources used by the TextReader and optionally releases the managed resources.
(Inherited from TextReader.)
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetLifetimeService
Retrieves the current lifetime service object that controls the lifetime policy for this instance.
(Inherited from MarshalByRefObject.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodInitializeLifetimeService
Obtains a lifetime service object to control the lifetime policy for this instance.
(Inherited from MarshalByRefObject.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Protected methodMemberwiseClone(Boolean)
Creates a shallow copy of the current MarshalByRefObject object.
(Inherited from MarshalByRefObject.)
Public methodPeek
Reads the next character without changing the state of the reader or the character source. Returns the next available character without actually reading it from the reader.
(Overrides TextReaderPeek.)
Public methodRead
Reads the next character from the text reader and advances the character position by one character.
(Overrides TextReaderRead.)
Public methodRead(Char, Int32, Int32)
Reads a specified maximum number of characters from the current reader and writes the data to a buffer, beginning at the specified index.
(Overrides TextReaderRead(Char, Int32, Int32).)
Public methodReadAsync
Reads a specified maximum number of characters from the current text reader asynchronously and writes the data to a buffer, beginning at the specified index.
(Overrides TextReaderReadAsync(Char, Int32, Int32).)
Public methodReadBlock
Reads a specified maximum number of characters from the current text reader and writes the data to a buffer, beginning at the specified index.
(Overrides TextReaderReadBlock(Char, Int32, Int32).)
Public methodReadBlockAsync
Reads a specified maximum number of characters from the current text reader asynchronously and writes the data to a buffer, beginning at the specified index.
(Overrides TextReaderReadBlockAsync(Char, Int32, Int32).)
Public methodReadLine
Reads a line of characters from the text reader and returns the data as a string.
(Overrides TextReaderReadLine.)
Public methodReadLineAsync
Reads a line of characters asynchronously and returns the data as a string.
(Overrides TextReaderReadLineAsync.)
Public methodReadToEnd
Reads all characters from the current position to the end of the text reader and returns them as one string.
(Overrides TextReaderReadToEnd.)
Public methodReadToEndAsync
Reads all characters from the current position to the end of the text reader asynchronously and returns them as one string.
(Overrides TextReaderReadToEndAsync.)
Public methodSet(String, Boolean)
Sets a variable to an boolean value.
Public methodSet(String, Object)
Sets a variable to an object value.
Public methodSet(String, String)
Sets a variable to a string value.
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Top
Extension Methods
  NameDescription
Public Extension MethodLines
Returns an enumerator that returns the lines of text from a TextReader.
(Defined by IOExtensions.)
Top
Remarks

The processor removes comment lines from the text returned. A comment line starts with zero or more whitespace characters followed by "//".

The processor implements simple macro definition and conditional statements. These statements are identifying by a line with the pound sign (#) as the first non-whitespace character.

Note Note
The processor statement character can be changed by setting StatementMarker.

The following processing statements are supported:

#define NAME [=VALUE]

Defines a normal variable and setting an optional value. The empty string will be set by default. These variables can be referenced in processing statements or normal text lines as $<name>.

Variable names are case sensitive and may include letter, number, dash, period, and underscore characters.

By default, defined variables may be referenced like $<name> and environment variables like $<<name>>.

#if EXPRESSION

Conditionally includes text up to the next #else or #endif statement. The following expressions are supported:

  • VALUE1 == VALUE2
  • VALUE1 != VALUE2
  • defined(NAME)
  • undefined(NAME)

The comparisions are performed after any variables are expanded. The values are trimmed on bothe ends and the string comparision is case sensitive.

#else This can optionally be used within an #if statement to include lines when the condition is false.
#endif This terminates an #if statement.
#switch VALUE Provides an easy to conditionally include statements for multiple conditions. The subsequent #case and #default statements up to the next #endswitch statement will be processed.
#case VALUE This command causes the lines up to the next #case, #default, or #endswitch to be outputed if the value matches that specified for the parent #switch statement.
#default This command causes the lines up to the next #endswitch to be outputed if the value wasn't matched by any of the previous case statements.
Note Note
#default must appear after all #case statements.
#endswitch This command terminates a #switch statement.

Normal variables can be defined within the source text itself using the #define command described above and variables may also be added in code using Set(String, String). These variables can be referenced as $<name>. Environment variables are also supported. These are referenced as $<$lt;name>>.

Note Note
You may encounter situations where the default ways of referencing variables conflicts with the syntax of the underlying source text being processed. In these cases, you can set VariableExpansionRegex to CurlyVariableExpansionRegex or ParenVariableExpansionRegex to change the format.

Variables are always expanded in #if and switch statements and are expanded by default in the other source lines. Variables are expanded using the ${NAME} syntax by default. The syntax can be modified by setting VariableExpansionRegex. Variable expansion can be disabled by setting ExpandVariables=false.

Note Note
By default, the reader will throw a KeyNotFoundException if an undefined normal variable is encountered. This behavior can be modified by setting DefaultVariable to a non-null string. In this case, undefined variable references will always be replaced by the value set. DefaultVariable defaults to null.
Note Note
By default, the reader will throw a KeyNotFoundException if an undefined environment variable is encountered. This behavior can be modified by setting DefaultEnvironmentVariable to a non-null string. In this case, undefined environment variable references will always be replaced by the value set. DefaultEnvironmentVariable defaults to null.

Processing can also be customized via the StripComments, RemoveComments, RemoveBlank, ProcessStatements, Indent, TabStop, and StatementMarker properties.

Secret and profile Values

This class can integrate with a IProfileClient implementation added to serviceContainer. This provides a way to abstract access to secrets and profile values from an external source. Three item types are supported:

secret-password

Secret passwords are often protected by a password manager. neonFORGE has standardized internally on 1Password for example. Passwords are often required to satisfy complexity and other rules.

Passwords are named by a string and are often persisted to a named location. 1Password stores to secrets in vaults. You'll need the password name and optionally, its location when referencing a password value.

You may also request a specific secret property using an array syntax like:

Examples
SECRETNAME[PROPERTY]

Doing this overrides the default password property.

secret-value

Secret values are often protected by a password manager. neonFORGE has standardized internally on 1Password for example. Secret values are similar to passwords but the typically don't comply with complexity or other requirements.

Secret values are named by a string and are often persisted to a named location. 1Password stores to secrets in vaults. You'll need the value name and optionally, its location when referencing a password value.

You may also request a specific secret property using an array syntax like:

Examples
SECRETNAME[PROPERTY]

Doing this overrides the default value property.

profile-value

Profile values are string name/value pairs that include non-secret definitions for the user, workstation, or overall environment such as the LAN. These can come in handy when implementing CI/CD where each server/user can be assigned unique profile values that reference specific test endpoints, etc. This is quite powerful.

Profile values are simply named by a string. There is currently no concept of a source, like secrets have.

Secrets and profile values can be referenced by as as $<$lt;<type:name[:source]>>> where type is one of password, secret (value), or profile and name identifies the secret or profile value and source optionall specifies the secret source (this is ignored for profile values).

$<$<$<password:my-password;my-vault>>>    # password from specific source
$<$<$<password:my-password>>>             # password from default source
$<$<$<secret:my-secret;my-vault>>>        # secret from specific source
$<$<$<secret:my-secret>>>                 # secret from default source
$<$<$<profile:my-profile>>>               # profile value

This class will throw ProfileException when it encounters a secret/profile reference and there no injected IProfileClient implementation or if the implementation has trouble communicating with the profile server. This class also also throws a KeyNotFoundException when a named secret or profile value doesn't exist.

Thread Safety
Instance members of this type are not safe for multi-threaded operations.
See Also