}                                                             // DisplayProperties method

        /// <summary>
        /// Enumerate the dependent assemblies.
        /// </summary>
        public void EnumerateDependents( )
        {
            string strDispCount = NumberFormatters.Integer(_lstNamesOfDependentAssemblies.Count);
            int    intMaxWidth  = strDispCount.Length;
            string strDtlFmt    = string.Concat("    {0,", intMaxWidth, "}: {1}");

            Console.WriteLine(
                Properties.Resources.MSG_ASM_DEPENDENTS_LIST_HEADER,                    // Format Control String
                _asmRoot.FullName,                                                      // Format Item 0 = Assembly Full Name
                strDispCount,                                                           // Format Item 1 = Dependent Count
                Environment.NewLine);                                                   // Format Item 2 = Embedded Newline

            for (int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT;
                 intJ < _lstNamesOfDependentAssemblies.Count;
                 intJ++)
            {
                Console.WriteLine(
                    strDtlFmt,                                       // Format Control String
                    NumberFormatters.Integer(                        // Format Item 0 = Item number
                        ArrayInfo.OrdinalFromIndex(                  // int pintAnyInteger
                            intJ)),                                  // int pintIndex
                    _lstNamesOfDependentAssemblies [intJ].FullName); // Format Item 1 = Assembly Full Name
            }                                                        // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < _lstNamesOfDependentAssemblies.Count ; intJ++ )

            Console.WriteLine(
                Properties.Resources.MSG_ASM_DEPENDENTS_LIST_TAIL, // Format Control String
                _asmRoot.FullName,                                 // Format Item 0 = Assembly Full Name
                Environment.NewLine);                              // Format Item 1 = Embedded Newline
        }                                                          // EnumerateDependents
        };  // static readonly FileInfoExtensionMethods.FileDetailsToShow [ ] s_aenmDetailsToShow


        internal static int Exercise ( ref int pintTestNumber )
        {
            const string TEST_REPORT_PREAMBLE = @"{2}Testing ShowFileDetails extension method with FileDetailsToShow = {0} ({1}):";
            const string TEST_REPORT_TEMPLATE_ABS = @"    Case {0}: Information gathered based on absolute file name:    ";
            const string TEST_REPORT_TEMPLATE_REL = @"    Case {0}: Information gathered based on relative file name:    ";

            NewClassTests_20140914.BeginTest (
                System.Reflection.MethodBase.GetCurrentMethod ( ).Name ,
                ref pintTestNumber ,
                Program.BEGIN_TEST_TAKE_METHOD_NAME_AT_FACE_VALUE );

            string strRootAssemblyDirectory = Program.s_smTheApp.AppRootAssemblyFileDirName;
            string strRelativeFileName = @"..\..\..\Test_Data\MD5_File_Digests.DOCX";
            string strAbsoluteFileName = Path.Combine ( strRootAssemblyDirectory , strRelativeFileName );

            Console.WriteLine ( @"strRootAssemblyDirectory = {0}" , strRootAssemblyDirectory );
            Console.WriteLine ( @"strRelativeFileName      = {0}" , strRelativeFileName );
            Console.WriteLine ( @"strAbsoluteFileName      = {0}" , strAbsoluteFileName );

            //  ----------------------------------------------------------------
            //  Since everything uses the same two FileInfo objects, they may as
            //  well be hoisted above the For loop.
            //  ----------------------------------------------------------------

            FileInfo infoAbsolute1 = new FileInfo ( strAbsoluteFileName );
            FileInfo infoAbsolute2 = new FileInfo ( infoAbsolute1.FullName );

            for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; 
                      intJ < s_aenmDetailsToShow.Length ;
                      intJ++ )
            {
                Console.WriteLine (
                    TEST_REPORT_PREAMBLE ,                                      // Format Control String with 4 tokens
                    ( int ) s_aenmDetailsToShow [ intJ ] ,                      // Format Item 0: FileDetailsToShow = {0} (
                    s_aenmDetailsToShow [ intJ ] ,                              // Format Item 1: ({1}):
                    intJ == ArrayInfo.ARRAY_FIRST_ELEMENT                       // Format Item 2: {2}Testing ShowFileDetails
                        ? Environment.NewLine                                       // First iteration
                        : SpecialStrings.EMPTY_STRING );                            // Subsequent iterations
                Console.WriteLine (
                    infoAbsolute1.ShowFileDetails (
                        s_aenmDetailsToShow [ intJ ] ,                          // FileDetailsToShow penmFileDetailsToShow = FileDetailsToShow.Everything
                        string.Format (                                         // string pstrLabel = null
                            TEST_REPORT_TEMPLATE_REL ,                              // Format Control String with 1 token
                            ArrayInfo.OrdinalFromIndex ( intJ ) ) ,                 // Format Item 0: Case {0}: Information
                        true ,                                                  // bool pfPrefixWithNewline = false
                        true ) );                                               // bool pfSuffixWithNewline = false
                Console.WriteLine (
                    infoAbsolute1.ShowFileDetails (
                        s_aenmDetailsToShow [ intJ ] ,                          // FileDetailsToShow penmFileDetailsToShow = FileDetailsToShow.Everything
                        string.Format (                                         // string pstrLabel = null
                            TEST_REPORT_TEMPLATE_ABS ,                              // Format Control String with 1 token
                            ArrayInfo.OrdinalFromIndex ( intJ ) ) ,                 // Format Item 0: Case {0}: Information
                        false ,                                                 // bool pfPrefixWithNewline = false
                        true ) );                                               // bool pfSuffixWithNewline = false
            }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < s_aenmDetailsToShow.Length ; intJ++ )

            return NewClassTests_20140914.TestDone (
                MagicNumbers.ERROR_SUCCESS ,
                pintTestNumber );
        }   // internal static int Exercise
Example #3
0
        }   // BeginTest method


        /// <summary>
        /// Create a report of the contents of the deserialized response in
        /// <paramref name="timeSeriesDailyResponse"/>.
        /// </summary>
        /// <param name="timeSeriesDailyResponse">
        /// The populated TimeSeriesDailyResponse instance returned by the JSON
        /// deserializer.
        /// </param>
        internal static void ConsumeResponse (
            string pstrReportFileName ,
            TimeSeriesDailyResponse timeSeriesDailyResponse )
        {
            Console.WriteLine (
                Properties.Resources.MSG_RESPONSE_METADATA ,                    // Format control string
                new object [ ]
                {
                    timeSeriesDailyResponse.Meta_Data.Information ,             // Format item 0: Information   = {0}
                    timeSeriesDailyResponse.Meta_Data.Symbol ,                  // Format Item 1: Symbol        = {1}
                    timeSeriesDailyResponse.Meta_Data.LastRefreshed ,           // Format Item 2: LastRefreshed = {2}
                    timeSeriesDailyResponse.Meta_Data.OutputSize ,              // Format Item 3: OutputSize    = {3}
                    timeSeriesDailyResponse.Meta_Data.TimeZone ,                // Format Item 4: TimeZone      = {4}
                    timeSeriesDailyResponse.Time_Series_Daily.Length ,          // Format Item 5: Detail Count  = {5}
                    Environment.NewLine                                         // Format Item 6: Platform-dependent newline
                } );

            string strAbsoluteInputFileName = AssembleAbsoluteFileName ( pstrReportFileName );

            using ( StreamWriter swTimeSeriesDetail = new StreamWriter ( strAbsoluteInputFileName ,
                                                                         FileIOFlags.FILE_OUT_CREATE ,
                                                                         System.Text.Encoding.ASCII ,
                                                                         MagicNumbers.CAPACITY_08KB ) )
            {
                string strLabelRow = Properties.Resources.MSG_RESPONSE_DETAILS_LABELS.ReplaceEscapedTabsInStringFromResX ( );
                swTimeSeriesDetail.WriteLine ( strLabelRow );
                string strDetailRowFormatString = ReportHelpers.DetailTemplateFromLabels ( strLabelRow );

                for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ;
                          intJ < timeSeriesDailyResponse.Time_Series_Daily.Length ;
                          intJ++ )
                {
                    Time_Series_Daily daily = timeSeriesDailyResponse.Time_Series_Daily [ intJ ];
                    swTimeSeriesDetail.WriteLine (
                        strDetailRowFormatString ,
                        new object [ ]
                        {
                            ArrayInfo.OrdinalFromIndex ( intJ ) ,               // Format Item 0: Item
                            Beautify ( daily.Activity_Date) ,                   // Format Item 1: Activity_Date
                            Beautify ( daily.Open ) ,                           // Format Item 2: Open
                            Beautify ( daily.High ) ,                           // Format Item 3: High
                            Beautify ( daily.Low ) ,                            // Format Item 4: Low
                            Beautify ( daily.Close ) ,                          // Format Item 5: Close
                            Beautify ( daily.AdjustedClose ) ,                  // Format Item 6: AdjustedClose
                            Beautify ( daily.Volume ) ,                         // Format Item 7: Volume
                            Beautify ( daily.DividendAmount ) ,                 // Format Item 8: DividendAmount
                            Beautify ( daily.SplitCoefficient )                 // Format Item 9: SplitCoefficient
                        } );
                }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < timeSeriesDailyResponse.Time_Series_Daily.Length ; intJ++ )
            }   // using ( StreamWriter swTimeSeriesDetail = new StreamWriter ( strAbsoluteInputFileName , FileIOFlags.FILE_OUT_CREATE , System.Text.Encoding.ASCII , MagicNumbers.CAPACITY_08KB ) )

            Console.WriteLine (
                ShowFileDetails (                                               // Print the returned string.
                    Properties.Resources.FILE_LABEL_CONTENT_REPORT ,            // string pstrLabel
                    strAbsoluteInputFileName ,                                  // string pstrFileName
                    true ,                                                      // bool   pfPrefixWithNewline = false
                    false ) );                                                  // bool   pfSuffixWithNewline = true
        }   // private static void ConsumeResponse
		}   // TestFormatItemCounters


		private static void ListAllErrors ( List<FormatStringError> plstAllErrors )
		{
			const int ORDINAL_FROM_SUBSCRIPT = ArrayInfo.INDEX_FROM_ORDINAL;
			const int POS_LABEL = ArrayInfo.ARRAY_FIRST_ELEMENT;
			const int POS_VALUE = ArrayInfo.ARRAY_SECOND_ELEMENT;
			const char DELIMITER = FormatStringError.LABEL_VALUE_DELIMITER;

			ReportDetail.DetailFormat = "{3}    {0} = {1}";

			int intErrorCount = plstAllErrors.Count;

			for ( int intI = ArrayInfo.ARRAY_FIRST_ELEMENT ;
					  intI < intErrorCount ;
					  intI++ )
			{
				FormatStringError fse = plstAllErrors [ intI ];
				string [ ] astrErrorDetails = fse.Split ( );
				int intNDetails = astrErrorDetails.Length;						// Save a trip into the collection.
				ReportDetails rptDtlsColl = new ReportDetails ( intNDetails );

				string [ ] astrErrorSummaryFirst = new string [ ]
                { 
                    string.Format (
                        Properties.Resources.MSG_FORMAT_ERROR_DETAILS ,			// Format template string
                        FormatItem.XofY (										// Format Item 0
                            intI + ORDINAL_FROM_SUBSCRIPT ,						//		X = Item Number
                            intErrorCount ) )									//		Y = Item Count
                };  // string [ ] astrErrorSummaryFirst

				//  ------------------------------------------------------------
				//  Maybe there is a better way to accompish this. Nevertheless,
				//  this method works for generating a completely blank string
				//  of a length that must be determined at runtime.
				//  ------------------------------------------------------------

				string [ ] astrErrorSummaryAllOthers = new string [ ]
                {
                    string.Empty.PadRight ( astrErrorSummaryFirst [ ArrayInfo.ARRAY_FIRST_ELEMENT ].Length )
                };  // string [ ] astrErrorSummaryAllOthers

				for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < intNDetails ; intJ++ )
				{
					string [ ] astrLabelAndValue = astrErrorDetails [ intJ ].Split ( DELIMITER );
					rptDtlsColl.Add (
						new ReportDetail (
							astrLabelAndValue [ POS_LABEL ].Trim ( ) ,								// Label (Format Item = 0)
							astrLabelAndValue [ POS_VALUE ].Trim ( ) ,								// Value (Format Item = 1) as String
							( ReportDetail.ItemDisplayOrder ) ArrayInfo.OrdinalFromIndex ( intJ ) ,	// Item Number (Format Item = 2) - The arithmetic operation casts it to int (signed), so it must be forcibly cast back to unsigned int.
							null ,																	// Individual Format String (Null = Use Default from static property)
							( intJ == ArrayInfo.ARRAY_FIRST_ELEMENT )								// Additional Details - Condition
								? astrErrorSummaryFirst												//		Value if Condition is True
								: astrErrorSummaryAllOthers ) );									//		Value if Condition is False
				}   // for ( uint uintJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; uintJ < intNDetails ; uintJ++ )

				rptDtlsColl.ListAllItems ( );
			}   // for ( int intI = ArrayInfo.ARRAY_FIRST_ELEMENT ; intI < intErrorCount ; intI++ )
		}   // ListAllErrors
		}	// InitializeInstance

        /// <summary>
        /// Enumeate missing configuration values, if any.
        /// </summary>
        /// <returns>
        /// This method returns a message suitable for display on a console or a
        /// Windows message box. The returned message summarises the state of
        /// affairs, even when all defined values are represented in the
        /// configuration file.
        /// </returns>
        public string EnumerateMissingConfigurationValues ( )
        {
            MissingConfigSettings = MissingConfigSettings ?? UnconfiguredDLLSettings.TheOnlyInstance;
            List<UnconfiguredDLLSettings.UnconfiguredSetting> missing = MissingConfigSettings.GetMissingPropsForFile (
                System.IO.Path.GetFileName (
                    _strAssemblyLocation ) );

            if ( missing.Count > ListInfo.LIST_IS_EMPTY )
            {
                System.Text.StringBuilder sbMessages = new System.Text.StringBuilder ( MagicNumbers.CAPACITY_04KB );

                //  ------------------------------------------------------------
                //  Start with a heading.
                //  ------------------------------------------------------------

                sbMessages.AppendFormat (
                    Properties.Resources.MSG_SOME_CONFIG_SETTINGS_OMITTED ,
                    MissingConfigSettings.Count ,
                    _DllConfigSettings.Count ,
                    AssemblyLocation ,
                    Environment.NewLine );

                //  ------------------------------------------------------------
                //  List each item in turn.
                //  ------------------------------------------------------------

                for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ;
                          intJ < MissingConfigSettings.Count ;
                          intJ++ )
                {
                    sbMessages.AppendFormat (
                        Properties.Resources.MSG_ACCEPTED_DEFAULT_VALUE ,       // Format Control String: {0} of {1}: {2} = {3}{4}
                        ArrayInfo.OrdinalFromIndex ( intJ ) ,                   // Format Item 0: {0} of
                        MissingConfigSettings.Count ,                           // Format Item 1: of {1}
                        missing [ intJ ].PropName ,                             // Format Item 2: : {2}
                        missing [ intJ ].PropValue ,                            // Format Item 3: = {3}
                        Environment.NewLine );                                  // Format Item 4: newline
                }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < MissingConfigSettings.Count ; intJ++ )

                //  ------------------------------------------------------------
                //  End with a footing.
                //  ------------------------------------------------------------

                sbMessages.AppendFormat (
                    Properties.Resources.MSG_ACCEPTED_LIST_END ,
                    Environment.NewLine );

                return sbMessages.ToString ( );
            }   // TRUE (One or more settings is missing from the configuration file.) block, if ( base.MissingConfigSettings.Count > ListInfo.LIST_IS_EMPTY )
            else
            {
                return string.Format (
                    Properties.Resources.MSG_ALL_CONFIG_SETTINGS_COVERED ,
                    _DllConfigSettings.Count ,
                    AssemblyLocation );
            }   // FALSE (All configuration settings are covered by the configuration file.) block, if ( base.MissingConfigSettings.Count > ListInfo.LIST_IS_EMPTY )
        }   // public string EnumerateMissingConfigurationValues
        }               // public FileInfo GetFirstFileInfo

        /// <summary>
        /// Unless the list is empty, return the oldest file in it, which is the
        /// last file in the list, since it is reverse sorted by LastWriteTime.
        /// </summary>
        /// <returns>
        /// The returned FileInfo object represents the oldest file in the list,
        /// which occupies its last slot, since the list is sorted in reverse
        /// order by LastWriteTimeUTC.
        /// </returns>
        public FileInfo GetLastFileInfo( )
        {
            if (_lstMatchingFiles.Count > ListInfo.LIST_IS_EMPTY)
            {           // Unless the list is empty, there must be a "first" item to return.
                return(_lstMatchingFiles [ArrayInfo.OrdinalFromIndex(_lstMatchingFiles.Count)].Details);
            }           // TRUE (anticipated outcome) block, if ( _lstMatchingFiles.Count > ListInfo.LIST_IS_EMPTY )
            else
            {           // Since FileInfo is a nullable type, the degenerate case returns a null reference.
                return(null);
            }           // FALSE (unanticipated outcome) block, if ( _lstMatchingFiles.Count > ListInfo.LIST_IS_EMPTY )
        }               // public FileInfo GetLastFileInfo
        }                                                        // public static void ListKeyAssemblyProperties

        /// <summary>
        /// List selected properties of any assembly on a console.
        /// </summary>
        /// <param name="pasmSubject">
        /// Pass in a reference to the desired assembly, which may be the
        /// assembly that exports a specified type, the executing assembly, the
        /// calling assembly, the entry assembly, or any other assembly for
        /// which you can obtain a reference.
        /// </param>
        /// <param name="pintJ">
        /// Pass in the array subscript, a 32 bit signed integer.
        /// </param>
        /// <param name="pintNDependents">
        /// Pass in the array element count, a 32 bit signed integer.
        /// </param>
        public static void ShowKeyAssemblyProperties(
            Assembly pasmSubject,
            int pintJ,
            int pintNDependents)
        {
            AssemblyName MyNameIs = AssemblyName.GetAssemblyName(pasmSubject.Location);

            System.Diagnostics.FileVersionInfo myVersionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(pasmSubject.Location);
            int intItemOrdinal = ArrayInfo.OrdinalFromIndex(pintJ);

            Console.WriteLine(
                Properties.Resources.MSG_ASM_PROPS_SELECTED_DLL_PROPS_BEGIN,    // Format Control String
                intItemOrdinal,                                                 // Format Item 0: Selected properties of assembly {0}
                pintNDependents,                                                // Format Item 1: of {1}
                pasmSubject.FullName,                                           // Format Item 2: , {2}
                Environment.NewLine);                                           // Format Item 3: {3}

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_ASSEMBLYFILEBASENAME, Path.GetFileNameWithoutExtension(pasmSubject.Location));
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_VERSIONSTRING, myVersionInfo.FileVersion);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_ASSEMBLYVERSION, MyNameIs.Version);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_CULTURE, MyNameIs.CultureInfo.DisplayName);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_PUBLICKEYTOKEN, ByteArrayFormatters.ByteArrayToHexDigitString(MyNameIs.GetPublicKeyToken( )));

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_RUNTIME_VERSION, pasmSubject.ImageRuntimeVersion);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_ASSEMBLYGUIDSTRING, GetAssemblyGuidString(pasmSubject));

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_PRODUCTNAME, myVersionInfo.ProductName);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_LEGALCOPYRIGHT, myVersionInfo.LegalCopyright);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_LEGALTRADEMARKS, myVersionInfo.LegalTrademarks);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_COMPANYNAME, myVersionInfo.CompanyName);

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_DESCRIPTION, myVersionInfo.FileDescription);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_COMMENTS, myVersionInfo.Comments, Environment.NewLine);

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_ASSEMBYDIRNAME, Path.GetDirectoryName(pasmSubject.Location));
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_ASSEMBLYFILENAME, Path.GetFileName(pasmSubject.Location), Environment.NewLine);

            FileInfo fiLibraryFile = new FileInfo(pasmSubject.Location);

            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_FILE_CREATION_DATE, fiLibraryFile.CreationTime, fiLibraryFile.CreationTimeUtc);
            Console.WriteLine(Properties.Resources.MSG_ASM_PROPS_FILE_MODIFIED_DATE, fiLibraryFile.LastWriteTime, fiLibraryFile.LastWriteTimeUtc);

            Console.WriteLine(
                Properties.Resources.MSG_ASM_PROPS_SELECTED_DLL_PROPS_END, // Format Control String
                intItemOrdinal,                                            // Format Item 0: End of selected properties of assembly {0}
                pintNDependents,                                           // Format Item 1: of {1}
                Environment.NewLine);                                      // Format Item 2: Bookend the string with platform-dependent newlines.
        }                                                                  // public static void ShowKeAssemblyProperties method
        /// <summary>
        /// Unless sumething is wrong with it, return the input <paramref name="pafixupPairs"/>
        /// to the calling routine.
        /// </summary>
        /// <param name="pafixupPairs">
        /// Array of StringFixup structures to validate
        /// </param>
        /// <returns>
        /// If the method succeeds, the return value is a reference to the input <paramref name="pafixupPairs"/>.
        /// Otherwise, the method throws an ArgumentNullException exception or
        /// an ArgumentException exception, depending on the circumstances.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// An ArgumentNullException exception arises when the entire <paramref name="pafixupPairs"/>
        /// array is a null reference.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// An ArgumentException exception arises when the entire array is empty
        /// or one of its InputValue members is a null reference or the empty
        /// string.
        /// </exception>
        internal static StringFixup [ ] ValidateFixupPairArray ( StringFixup [ ] pafixupPairs )
        {
            if ( pafixupPairs == null )
            {
                throw new ArgumentNullException ( nameof ( pafixupPairs ) );
            }   // TRUE (unanticipated outcome) block, if ( pafixupPairs == null )
            else
            {
                if ( pafixupPairs.Length == ArrayInfo.ARRAY_IS_EMPTY )
                {
                    throw new ArgumentException (
                        Core.Properties.Resources.ERRMSG_ARRAY_IS_EMPTY ,
                        nameof ( pafixupPairs ) );
                }   // TRUE (unanticipated outcome) block, if ( pafixupPairs.Length == ArrayInfo.ARRAY_IS_EMPTY )
                else
                {
                    for ( int intK = ArrayInfo.ARRAY_FIRST_ELEMENT ;
                              intK < pafixupPairs.Length ;
                              intK++ )
                    {
                        if ( string.IsNullOrEmpty ( pafixupPairs [ intK ].InputValue ) )
                        {
                            throw new ArgumentException (
                                string.Format (
                                    Core.Properties.Resources.ERRMSG_STRING_FIXUP_PAIR_IS_INVALID ,
                                    new object [ ]
                                    {
                                        ArrayInfo.OrdinalFromIndex ( intK ),    // Format Item 0: at ordinal position {0} (
                                        intK ,                                  // Format Item 1: (subscript = {1})
                                        pafixupPairs [ intK ].OutputValue ,     // Format Item 2: The OutputValue at that position is {2},
                                        pafixupPairs [ intK ].OutputValue == null   // Format Item 3: which is {3}.
                                            ? Common.Properties.Resources.MSG_VALUE_IS_INVALID
                                            : Common.Properties.Resources.MSG_VALUE_IS_VALID ,
                                        Environment.NewLine                     // Format Item 4: is a null reference or the empty string.{4}
                                    } ) ,
                                nameof ( pafixupPairs ) );
                        }   // if ( string.IsNullOrEmpty ( pafixupPairs [ intK ].InputValue ) )
                    }   // for ( int intK = ArrayInfo.ARRAY_FIRST_ELEMENT ; intK < pafixupPairs.Length ; intK++ )

                    return pafixupPairs;
                }   // FALSE (anticipated outcome) block, if ( pafixupPairs.Length == ArrayInfo.ARRAY_IS_EMPTY )
            }   // FALSE (anticipated outcome) block, if ( pafixupPairs == null )
        }   // internal static StringFixup [ ] ValidateFixupPairArray
Example #9
0
        }   // static void Main


        private static void ReportScenarioOutcome (
            string pstrScenarioLabel ,
            string [ ] pastrTestOutput ,
            int pintNFields )
        {
            Console.WriteLine (
                pstrScenarioLabel ,
                Environment.NewLine );

            for ( int intCurrField = ArrayInfo.ARRAY_FIRST_ELEMENT ;
                      intCurrField < pintNFields ;
                      intCurrField++ )
            {
                Console.WriteLine (
                    Properties.Resources.MSG_CASE_DETAIL ,
                    ArrayInfo.OrdinalFromIndex ( intCurrField ) ,
                    pintNFields ,
                    pastrTestOutput [ intCurrField ] );
            }   // for ( int intCurrField = StandardConstants.ARRAY_FIRST_ELEMENT ; intCurrField < intNFields ; intCurrField++ )
        }   //private static void ReportScenarioOutcome
Example #10
0
        }   // private int FixNextItem


        /// <summary>
        /// After it finds and replaces its string, FixNextItem calls upon this
        /// routine to look just past it for string FIRST_ITEM_BREAK_POST, and
        /// replace it with SUBSEQUENT_ITEM_BREAK_POST.
        /// </summary>
        /// <param name="pstrInput">
        /// This routine receives the string copy made by FixNextItem, so that
        /// it can reinitialize the StringBuilder before it starts appending
        /// text from it.
        /// </param>
        /// <param name="pintMatchPosition">
        /// The character position where FixNextItem found its match becomes the
        /// starting point for the search performed by this routine.
        /// </param>
        /// <param name="pintMatchLength">
        /// The length of the string matched by FixNextItem is fed into this
        /// routine, which adds it to <paramref name="pintMatchPosition"/> to
        /// determine where to begin its own search.
        /// </param>
        /// <param name="psbOut">
        /// Although it is initialized and repopulated, passing around a
        /// StringBuilder is simpler than using an out parameter.
        /// </param>
        /// <returns></returns>
        private int FixThisItem (
            string pstrInput ,
            int pintMatchPosition ,
            int pintMatchLength ,
            StringBuilder psbOut )
        {
            const string FIRST_ITEM_BREAK_POST = "\n        {\n            \"Activity_Date\": \"";        // Post: },\n        {\n        {\n        "Activity_Date": "
            const string SUBSEQUENT_ITEM_BREAK_POST = ",\n        {\n            \"Activity_Date\": \"";    // Post: },\n        {\n        {\n        "Activity_Date": "

            const int DATE_TOKEN_LENGTH = 11;
            const int DATE_TOKEN_SKIP_CHARS = DATE_TOKEN_LENGTH + 3;

            int intSkipOverMatchedCharacters = pintMatchPosition + pintMatchLength;

            psbOut.Clear ( );

            psbOut.Append ( pstrInput.Substring (
                ListInfo.SUBSTR_BEGINNING ,
                ArrayInfo.OrdinalFromIndex ( pintMatchPosition ) ) );
            psbOut.Append ( _fIsFirstPass
                ? FIRST_ITEM_BREAK_POST
                : SUBSEQUENT_ITEM_BREAK_POST );
            psbOut.Append ( pstrInput.Substring (
                intSkipOverMatchedCharacters ,
                DATE_TOKEN_LENGTH ) );
            psbOut.Append ( SpecialCharacters.COMMA );
            psbOut.Append ( pstrInput.Substring ( intSkipOverMatchedCharacters + DATE_TOKEN_SKIP_CHARS ) );

            int rintSearchResumePosition = pintMatchPosition
                                           + ( _fIsFirstPass
                                                    ? FIRST_ITEM_BREAK_POST.Length
                                                    : SUBSEQUENT_ITEM_BREAK_POST.Length );
            _fIsFirstPass = false;     // Putting this here allows execution to be unconditional.

            return ArrayInfo.OrdinalFromIndex ( rintSearchResumePosition );
        }   // private int FixThisItem
        }   // public string GetDLLSetting


		/// <summary>
		/// Set the like named properties from the linked configuration file.
		/// </summary>
		/// <param name="pderivedType">
		/// When the derived class constructor calls this method, it must pass in a
		/// reference to its own Type property.
		/// </param>
		/// <returns>
		/// The return value is the count of properties that were set.
		/// </returns>
		/// <remarks>
		/// This can almost certainly be simplified by enumerating the settings,
		/// but either way risks a NOT FOUND exception.
		/// 
		/// This method uses some fairly tricky Reflection gymnastics to map the
		/// key names in a configuration file to property names on an object.
		/// </remarks>
		protected PropertySourceCounts SetPropertiesFromDLLConfiguration ( Type pderivedType )
		{
			const BindingFlags BASELINE_BINDING_FLAGS = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            PropertySourceCounts rutpCounts = new PropertySourceCounts ( );

            rutpCounts.Defaulted = MagicNumbers.ZERO;
            rutpCounts.SpecifiedInConfiguration = MagicNumbers.ZERO;

            string [ ] astrDefaultErrorMessageColors = DLLSettings.AllKeys;

			for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ;
					  intJ < astrDefaultErrorMessageColors.Length ;
					  intJ++ )
			{
				string strPropertyName = null;                                  // This must be visible to the catch block.

                try
                {
                    strPropertyName = astrDefaultErrorMessageColors [ intJ ];
                    string strConfigValueString = DLLSettings [ strPropertyName ].Value;
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            @"At iteration {0} in {1}: {2} = {3}" ,             // Format control string
                            new object [ ]                                      // Array of values to substitute for tokens in format control string
                            {
                                ArrayInfo.OrdinalFromIndex ( intJ ) ,           // Format Item 0: At iteration {0}
                                MethodBase.GetCurrentMethod ( ).Name ,          // Format Item 1: in {1}
                                strPropertyName ,                               // Format Item 2: : {2}
                                strConfigValueString                            // Format Item 3: = {3}
                            } ) );
                    PropertyInfo piThisProperty = this.GetType ( ).GetProperty (
                        strPropertyName ,                                       // string      name         = The string containing the name of the property to get
                        BASELINE_BINDING_FLAGS );                               // bindingAttr BindingFlags = A bitmask comprised of one or more BindingFlags that specify how the search is conducted

                    if ( piThisProperty != null )
                    {
                        piThisProperty.SetValue (
                            this ,                                                  // Object      obj          = Object to which to apply setting
                            FromString (
                                piThisProperty ,
                                strConfigValueString ) ,                            // Object      value        = Value to assign to the property to which piThisProperty refers
                            BASELINE_BINDING_FLAGS | BindingFlags.SetProperty ,     // invokeAttr  invokeAtt	= A bitwise combination of the following enumeration members that specify the invocation attribute: InvokeMethod, reateInstance, Static, GetField, SetField, GetProperty, or SetProperty. You must specify a suitable invocation attribute.
                            null ,                                                  // Binder      binder		= An object that enables the binding, coercion of argument types, invocation of members, and retrieval of MemberInfo objects through reflection. If binder is null, the default binder is used.
                            null ,                                                  // Object[]    index		= Optional index values for indexed properties. This value should be null for non-indexed properties.
                            null );                                                 // CultureInfo culture		= The culture for which the resource is to be localized. If the resource is not localized for this culture, the Parent property will be called successively in search of a match. If this value is null, the culture-specific information is obtained from the CurrentUICulture property.
                        rutpCounts.SpecifiedInConfiguration++;                      // Count properties successfully set; the final value is returned as the function value.
                    }   // TRUE (The configuration file has a value for this property.) block, if ( piThisProperty != null )
                    else
                    {
                        MissingConfigSettings = MissingConfigSettings ?? UnconfiguredDLLSettings.TheOnlyInstance;

                        MissingConfigSettings.Add (
                            Path.GetFileName ( _strAssemblyLocation ) ,
                                strPropertyName ,                               // Format Item 0: property {1} default value
                                strConfigValueString );                         // Format Item 1: default value of {2} accepted
                        rutpCounts.Defaulted++;                                 // Count properties that retained their hard coded default values.
                    }   // FALSE (A value for this property is absent from the configuration file.) block, if ( piThisProperty != null )
                }
                catch ( Exception exAllKinds )
                {	// Since the catch block is within the body of the For loop, processing advances to the next item.
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            @"{0}.{1} = {2}" ,
                            nameof ( Environment ) ,
                            nameof ( Environment.StackTrace ) ,
                            Environment.StackTrace ) );
                    if ( RecoveredConfigurationExceptions == null )
                    {   // Create as and when needed.
                        RecoveredConfigurationExceptions = new System.Collections.Generic.List<RecoveredException> ( );
                    }   // if ( RecoveredConfigurationExceptions == null )

                    RecoveredConfigurationExceptions.Add (
                       new RecoveredException (
                           string.Format (
                               Properties.Resources.ERRMSG_EXCEPTION_NOT_THROWN ,
                               SaveErrorReport (
                                   this.GetType ( ) ,
                                   strPropertyName ,
                                   exAllKinds ).Message ) ,
                           exAllKinds.Source ,
                           exAllKinds.StackTrace ,
                           exAllKinds.TargetSite.Name ) );
                    Exception exWrapped = RecoveredConfigurationExceptions [ ArrayInfo.IndexFromOrdinal ( RecoveredConfigurationExceptions.Count ) ];
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_1 ,
                            exWrapped.Message ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_2 ,
                            exWrapped.Source ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_3 ,
                            exWrapped.TargetSite != null
                                ? exWrapped.TargetSite.Name
                                : Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_4 ,
                            exWrapped.StackTrace ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );

                    //  --------------------------------------------------------
                    //  Since SaveErrorReport appends the inner exception, this
                    //  test is technically redundant, but I chose to leave it,
                    //  as a reminder that new exceptions are not necessarily
                    //  so decordated. Hence, with the test, this code is a bit
                    //  more portable.
                    //  --------------------------------------------------------

                    if ( exWrapped.InnerException != null )
                    {
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_5 ,
                            exWrapped.InnerException.Message ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_6 ,
                                exWrapped.InnerException.Source ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_7 ,
                                exWrapped.InnerException.TargetSite.Name ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_8 ,
                                exWrapped.InnerException.StackTrace ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    }   // TRUE (anticipated outcome) block, if ( exWrapped.InnerException != null )
                    else
                    {
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst ( Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_9 );
                    }   // FALSE (unanticipated outcome) block, if ( exWrapped.InnerException != null )
                }   // catch ( Exception exAllKinds )
            }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < astrDefaultErrorMessageColors.Length ; intJ++ )

            return rutpCounts;
		}	// SetPropertiesFromDLLConfiguration
Example #12
0
		}   // ListPropertiesPerDefaultToString method (3 of 4)


		/// <summary>
		/// Format names and values of the properties reported by the ToString
		/// method on any object for rendering on a report, such as the console
		/// display of a character-mode application.
		/// </summary>
		/// <param name="pobjToList">
		/// Pass in a reference to the object of interest. Its ToString method,
		/// presumably a custom (overrridden) method is called, and the string
		/// that it returns is parsed and formatted.
		/// 
		/// Its ToString method is expected to return a string that begins with
		/// the object's internal name (type), followed by a colon and a list of
		/// properties. Each property is expected to be listed as a name-value
		/// pair, with the name and its value sapearated by an equals sign, and
		/// properties delimited by either a single character, such as a comma,
		/// or the platform-dependent newline sequence, e. g., CR/LF for Windows
		/// or LF for Linux.
		/// </param>
		/// <param name="pchrDelimiter">
		/// Pass in the single-character delimiter that separates property names
		/// and their values from each other. To specify that the pairs are
		/// delimited by newlines, specify SpecialCharacters.NULL_CHAR, the NULL
		/// (numeric value zero) character.
		/// </param>
		/// <param name="pintAdditionalPaddingChars">
		/// Specify the number of characters of extra white space, if any, to be
		/// prepended to subsequent output lines to cause the report to aligne
		/// vertically. This is useful when the format string through which it
		/// will be written contains text that precedes the output string, which
		/// would otherwise cause subsequent detail lines to be misaligned.
		/// </param>
		/// <returns>
		/// The return value is a string that can be fed through a standard
		/// format item to string.Format, Console.WriteLine, or any of their
		/// cousins.
		/// </returns>
		public static string ListPropertiesPerDefaultToString (
			object pobjToList ,
			char pchrDelimiter ,
			int pintAdditionalPaddingChars )
		{
			const string THIRD_FORMAT_ITEM = @" {2}{3}";

			StringBuilder rsb = null;

			string [ ] astrProperties = null;

			astrProperties = pchrDelimiter == SpecialCharacters.NULL_CHAR
				? WizardWrx.EmbeddedTextFile.Readers.StringOfLinesToArray ( pobjToList.ToString ( ) )
				: pobjToList.ToString ( ).Split ( pchrDelimiter );
			LabelAndValue [ ] autpLabelAndValue = new LabelAndValue [ astrProperties.Length ];
			string strTypeName = null;  // The string.IsNullOrEmpty method requires an initialized argument.

			for ( int intIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ;
					  intIndex < astrProperties.Length ;
					  intIndex++ )
			{
				string [ ] astrLabelAndItsValue = null;

				if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT )
				{   // The first item contains also the property type name, followed by a colon and a space.
					int intPosColon = astrProperties [ intIndex ].IndexOf ( SpecialCharacters.COLON );
					int intPosNext = intPosColon + ArrayInfo.NEXT_INDEX;

					//	------------------------------------------------
					//	As always, use a belt and suspenders, covering 
					//	the chance that the first label immediately
					//	follows the colon that delimits it from the
					//	object type name.
					//
					//	Whether the break occurs at the colon or the
					//	immediately following space, the position is set
					//	such that the last charecter goes into the type
					//	name field, leaving the remainder of the string
					//	to be divided into the propertry value and its
					//	label.
					//	------------------------------------------------

					int intPosBreak = ArrayInfo.OrdinalFromIndex (
						astrProperties [ intIndex ] [ intPosNext ] == SpecialCharacters.SPACE_CHAR
							? intPosNext
							: intPosColon );
					strTypeName = astrProperties [ intIndex ].Substring (
						ListInfo.SUBSTR_BEGINNING ,
						intPosBreak );
					astrLabelAndItsValue = astrProperties [ intIndex ].Substring (
						intPosBreak ).Split ( SpecialCharacters.EQUALS_SIGN );
				}   // TRUE (This iteration processess the first property item.) block, if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT )
				else
				{
					astrLabelAndItsValue = astrProperties [ intIndex ].Split ( SpecialCharacters.EQUALS_SIGN );
				}   // FALSE (This iteration processes a subsequent property item.) block, if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT )

				autpLabelAndValue [ intIndex ].Label = astrLabelAndItsValue [ ArrayInfo.ARRAY_FIRST_ELEMENT ].Trim ( );
				autpLabelAndValue [ intIndex ].Value = astrLabelAndItsValue [ ArrayInfo.ARRAY_SECOND_ELEMENT ].Trim ( );
			}   // for ( int intIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intIndex < astrProperties.Length ; intIndex++ )

			//	--------------------------------------------------------
			//	Compute the length of the longest label string, so that
			//	a format string that renders the labels and their values
			//	in a neatly aligned list can be constructed.
			//	--------------------------------------------------------

			int intLabelFieldWidth = ComputeLabelFieldWidth ( autpLabelAndValue );
			string strPropertyPadding = SpecialStrings.EMPTY_STRING.PadRight ( strTypeName.Length );

            //	--------------------------------------------------------
            //	A string is constructed with two right-padded format
            //	items and a third and fourth default format items.
            //
            //	1)	The first format item gets the type name string,
            //		strTypeName, on the first iteration of a loop over 
            //		the autpLabelAndValue array, while subsequent
            //		iterations use the strPropertyPadding string.
            //
            //	2)	The second format item gets the property name from
            //		the Label member of a LabelAndValue structure stored
            //		in the current element of the autpLabelAndValue
            //		array.
            //
            //	3)	The third format item gets the Value member of the
            //		LabelAndValue structure stored in the current 
            //		element of the autpLabelAndValue array.
            //
            //	4)	The fourth format item gets the platform-specific
            //		newline character or sequence thereof.
            //	--------------------------------------------------------

            string strDynamicFormatString = string.Concat ( new string [ ]
            {
                FormatItem.AdjustToMaximumWidth (
                    ArrayInfo.ARRAY_FIRST_ELEMENT ,
                    strTypeName.Length ,
                    FormatItem.Alignment.Left ,
                    SpecialStrings.EMPTY_STRING ) ,
                SpecialCharacters.SPACE_CHAR.ToString ( ) ,
                FormatItem.AdjustToMaximumWidth (
                    ArrayInfo.ARRAY_SECOND_ELEMENT ,
                    intLabelFieldWidth ,
                    FormatItem.Alignment.Left ,
                    SpecialStrings.EMPTY_STRING ) ,
                THIRD_FORMAT_ITEM
            } );

			//	--------------------------------------------------------
			//	The initial capacity of the StringBuilder is twice the
			//	label width plus the length of the type name, times the
			//	number of label/value pairs in the autpLabelAndValue
			//	array.
			//	--------------------------------------------------------

			rsb = new StringBuilder ( ( intLabelFieldWidth * MagicNumbers.PLUS_TWO + strTypeName.Length ) * autpLabelAndValue.Length );

			for ( int intItemIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ;
					  intItemIndex < autpLabelAndValue.Length ;
					  intItemIndex++ )
			{
				rsb.AppendFormat (
					strDynamicFormatString ,
					new string [ ]
					{
						intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT
							? strTypeName
							: strPropertyPadding ,
						autpLabelAndValue [ intItemIndex ].Label ,
						autpLabelAndValue [ intItemIndex ].Value ,
						Environment.NewLine } );

				//	------------------------------------------------------------
				//	Unless pintAdditionalPaddingChars is zero, the first pass
				//	generates a new format control string that allows more
				//	characters to its first format item.
				//	------------------------------------------------------------

				if ( pintAdditionalPaddingChars > ListInfo.EMPTY_STRING_LENGTH && intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT )
				{
					strDynamicFormatString = string.Concat ( new string [ ]
					{
						FormatItem.AdjustToMaximumWidth (
							ArrayInfo.ARRAY_FIRST_ELEMENT ,
							strTypeName.Length + pintAdditionalPaddingChars ,
							FormatItem.Alignment.Left ,
							SpecialStrings.EMPTY_STRING ) ,
						SpecialCharacters.SPACE_CHAR.ToString ( ) ,
						FormatItem.AdjustToMaximumWidth (
							ArrayInfo.ARRAY_SECOND_ELEMENT ,
							intLabelFieldWidth ,
							FormatItem.Alignment.Left ,
							SpecialStrings.EMPTY_STRING ) ,
						THIRD_FORMAT_ITEM
					} );
				}   // if ( pintAdditionalPaddingChars > ListInfo.EMPTY_STRING_LENGTH && intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT )
			}   // for ( int intItemIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intItemIndex < autpLabelAndValue.Length ; intItemIndex++ )

			return rsb.ToString ( );
		}   // ListPropertiesPerDefaultToString method (4 of 4)