Archive for category Generic Collections

INI Files Meet Regex and Linq in C# to Avoid the WayBack Machine of Kernal32.Dll

BetweenStonesWhat if you are stuck having to deal with older technology such as INI files while using the latest and greatest C# and .Net there is available? This article discusses an alternate way to read INI files and extract the data from those dusty tomes while  easily accessing the resulting data from dictionaries. Once the data resides in the dictionaries we can easily extract the data using the power of the indexer on section name followed by key name within the section. Such as IniFile[“TargetSection”][“TargetKey”] which will return a string of the value of that key in the ini file for that section.

Note all the code is one easy code section at the bottom of the article so don’t feel you have to copy each sections code.

Overview

If you are reading this, chances are you know what INI files are and don’t need a refresher. You may have looked into using the Win32 Kern32.dll method GetPrivateProfileSection to achieve your goals. Ack!  “Set the Wayback machine Sherman!” Thanks but no thanks.

Here is how to do this operation using Regular Expressions (Kinda a way back machine but very useful) and Linq to Object to get the values into a dictionary format so we can write this line of code to access the data within the INI file:

string myValue = IniFile[“SectionName”][“KeyName”];

The Pattern

Let me explain the Regex Pattern. If you are not so inclined to understand the semantics of it skip to the next section.

string pattern = @"
^                           # Beginning of the line
((?:\[)                     # Section Start
 (?<Section>[^\]]*)         # Actual Section text into Section Group
 (?:\])                     # Section End then EOL/EOB
 (?:[\r\n]{0,}|\Z))         # Match but don't capture the CRLF or EOB
 (                          # Begin capture groups (Key Value Pairs)
   (?!\[)                    # Stop capture groups if a [ is found; new section
   (?<Key>[^=]*?)            # Any text before the =, matched few as possible
   (?:=)                     # Get the = now
   (?<Value>[^\r\n]*)        # Get everything that is not an Line Changes
   (?:[\r\n]{0,4})           # MBDC \r\n
  )+                        # End Capture groups";

Our goal is to use Named Match groups. Each match will have its section name in the named group called  “Section”  and all of the data, which is the key and value pairs will be named “Key” and “Value” respectively.  The trick to the above pattern is found in line eight. That stops the match when a new section is hit using the Match Invalidator (?!). Otherwise our key/values would bleed into the next section if not stopped.

The Data

Here is the data for your perusal.

string data = @"[WindowSettings]
Window X Pos=0
Window Y Pos=0
Window Maximized=false
Window Name=Jabberwocky

[Logging]
Directory=C:\Rosetta Stone\Logs
";

We are interested in “Window Name” and “Directory”.

The Linq

Ok, if you thought the regex pattern was complicated, the Linq to Objects has some tricks up its sleeve as well. Primarily since our pattern matches create a single match per section with the accompany key and value data in two separate named match capture collections, that presents a problem. We need to join the the capture collections together, but there is no direct way to do that for the join in Linq because that link is only an indirect by the collections index number.

How do we get the two collections to be joined?

Here is the code:

Dictionary<string, Dictionary<string, string>> InIFile
= ( from Match m in Regex.Matches( data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline )
 select new
 {
  Section = m.Groups["Section"].Value,

  kvps = ( from cpKey in m.Groups["Key"].Captures.Cast<Capture>().Select( ( a, i ) => new { a.Value, i } )
     join cpValue in m.Groups["Value"].Captures.Cast<Capture>().Select( ( b, i ) => new { b.Value, i } ) on cpKey.i equals cpValue.i
     select new KeyValuePair<string, string>( cpKey.Value, cpValue.Value ) ).ToDictionary( kvp => kvp.Key, kvp => kvp.Value )

  } ).ToDictionary( itm => itm.Section, itm => itm.kvps );

Explanation:

  • Line 1: Our end goal object is a Dictionary where the key is the Section name and the value is a sub-dictionary with all the keys and values found in that section.
  • Line 2: The regex needs IPW because we have commented the pattern. It needs multiline because we are spanning multiple lines and need ^ to match each individual line and not just the beginning.
  • Line 5: This is the easiest item, simply access the named capture group “Section” for the section name.
  • Line 7 (.Captures) : Each one of the keys and values are in the specialized capture collection property off of the match.
  • Line 7 (.Cast<Capture>) : Since capture is specialized list and not a true generic list, such as List<string> we are going to Cast it(Cast<(Of <(TResult>) it (to IEnumerable<(Of <(T>)>),so we can access the standard query operators, i.e. the extension methods which are available to IEnumerable<T>. Short answer, so we can call .Select.
  • Line 7 (.Select): Because each list does not have a direct way to associate the data, we are going to create a new object that has a property which will have that index number, along with the target data value. That will allow us join it to the other list.
  • Line 7 (Lambda) : The lambda has two parameters, the first is our actual regex Capture object represented by a. The i is the index value which we need for the join. We then call new and create a new entity with two properties, the first is actual value of the Key found of the Capture class property “Value” and the second is i the index value.
  • Line 8 (Join) : We are going to join the data together using the direct properties of our new entity, but first we need to recreate the magic found in Line 7 for our Values capture collection. It is the same logic as the previous line so I will not delve into its explanation in detail.
  • Line 8 (on cpKey.i equals cpValue.i) : This is our association for the join on the new entities and yay, where index value i equals the other index value i allows us to do that. This is the keystone of all we are doing.
  • Line 9 (new KeyValuePair) : Ok we are now creating each individual linq projection item of the data as a KeyValuePair object. This could be removed for a new entity, but I choose to use the KeyValuePair class.
  • Line 9 (ToDictionary) : We want to easily access these key value pairs in the future, so we are going to place the Key into a Key of a dictionary and the dictionary key’s value from the actual Value.
  • Line 11 (ToDictionary) : Here is where we take the projection of the previous lines of code and create the end goal dictionary where the key name is the section and the value is the sub dictionary created in Line 9.

Whew…what is the result?

Console.WriteLine( InIFile["WindowSettings"]["Window Name"] ); // Jabberwocky
Console.WriteLine( InIFile["Logging"]["Directory"] );          // C:\Rosetta Stone\Logs

Summary

Thanks to the power of regular expressions and Linq we don’t have to use the old methods to extract and process the data. We can easily access the information using the newer structures. Hope this helps and that you may have learned something new from something old.

Code All in One Place

Here is all the code so you don’t have to copy it from each section above. Don’t forget to include the using System.Text.RegularExpressions to do it all.

string data = @"[WindowSettings]
Window X Pos=0
Window Y Pos=0
Window Maximized=false
Window Name=Jabberwocky

[Logging]
Directory=C:\Rosetta Stone\Logs
";
string pattern = @"
^                           # Beginning of the line
((?:\[)                     # Section Start
     (?<Section>[^\]]*)     # Actual Section text into Section Group
 (?:\])                     # Section End then EOL/EOB
 (?:[\r\n]{0,}|\Z))         # Match but don't capture the CRLF or EOB
 (                          # Begin capture groups (Key Value Pairs)
  (?!\[)                    # Stop capture groups if a [ is found; new section
  (?<Key>[^=]*?)            # Any text before the =, matched few as possible
  (?:=)                     # Get the = now
  (?<Value>[^\r\n]*)        # Get everything that is not an Line Changes
  (?:[\r\n]{0,4})           # MBDC \r\n
  )+                        # End Capture groups";

Dictionary<string, Dictionary<string, string>> InIFile
= ( from Match m in Regex.Matches( data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline )
    select new
    {
        Section = m.Groups["Section"].Value,

        kvps = ( from cpKey in m.Groups["Key"].Captures.Cast<Capture>().Select( ( a, i ) => new { a.Value, i } )
                 join cpValue in m.Groups["Value"].Captures.Cast<Capture>().Select( ( b, i ) => new { b.Value, i } ) on cpKey.i equals cpValue.i
                 select new KeyValuePair<string, string>( cpKey.Value, cpValue.Value ) ).ToDictionary( kvp => kvp.Key, kvp => kvp.Value )

    } ).ToDictionary( itm => itm.Section, itm => itm.kvps );

Console.WriteLine( InIFile["WindowSettings"]["Window Name"] ); // Jabberwocky
Console.WriteLine( InIFile["Logging"]["Directory"] );          // C:\Rosetta Stone\Logs
  • Share/Bookmark

Tags: , ,

Generic Touple used as a Thread's Sole Argument in C#

This article shows how to use a generic touple object, which will allow us to pass differing objects to a thread. Also demonstrated is the proper setup of a thread and how to handle the cancel (abort) call to a thread.

To accomplish passing multiple arguments to a thread one could create a simple struct and pass that struct in and then cast it. This operations borrows from that but we will pass in a dynamic object via the use of generics.

The argument we will use is called a touple. Meaning that it can contain two objects. The touple object can be used in situations where a method should return one object with two values. But in this article, we are passing in an argument to a thread invocation method, and by its design it can only contain one argument, so the touple is a good idiom to use. Since we need two separate arguments, we will use the touple paradigm to get around the one argument only for thread target.

Generic Touple

Here is the generic touple in code:

// This is a touple, meaning one object holds two items. 
//
// Normally this a struct instead of a class but because 
// we want to use one function for all the thread processing, 
// in this article, we are making this a class so we can 
// use the 'as' keyword on the thread argument object
// to differentiate between different touple variations.
public class Operations<T1, T2> 
{
    public Operations(T1 f, T2 s)
    {
        first = f;
        second = s;
    }
   
    // Access Argument 1 here.
    public T1 First
    {
        get { return first; }
    }
 
    // Access Argument 2 here.
    public T2 Second
    {
        get { return second; }
    }
 
    // Hold the data here:
    private readonly T1 first;
    private readonly T2 second;
 
}

As one can see it can be created with any type one desires. That will allow us to create generic functionality base don the generic object above. As mentioned in the comments if you use this elsewhere, just change the class to be a struct.

Threading Example With The Touple as the Main Argument

Here is the code for the thread example. Below is a class called ThreadTouple. Its job is to create two threads which will use the same target method. In the method depending on the touple type it will create output results which can the be printed by the consumer. In the class below contains a static method called Usage. It is there for demonstration purposes.

Note to use the code below and above you will need these includes:

using System;
using System.Collections.Generic; // For the List<>
using System.Text;
using System.Threading;           // For the thread class

Also shown are few things to do when threading to avoid problems:

  1. Thread set to background status. It does not affect processing or priority, just that if the main application gets shut down, these threads will not block until finished. The will just close.
  2. Handling of the ThreadAbortException. Its overkill for this demonstration, but it shows how to gracefully handle the Thread.Abort message.
  3. Waiting for the threads to finish by joining the threads once finished so data can be written out with confidence that the operations are done. 
  4. Thread safety by locking the list that will hold the messages.

The below code shows that we will use a different touple for each of the threads. Inside the common thread invokation method ( Operations(object arguments) ) we will determine which type of touple is coming in and process it specifically, or report an error.

// Demonstrate how to pass multipe arguments to 
// a thread.
public class ThreadTouple
{
 
    private Thread _T1;
    private Thread _T2;
    private List<string> _Results = new List<string>();
 
    // This is only here for informational purposes
    // To show how this class is used.
    public static void Usage()
    {
        ThreadTouple tt = new ThreadTouple();
 
        tt.PrintResults(); // Safely wait for the results
    }
    
 
    // Create the threads and assign targets with the touple.
    public ThreadTouple()
    {
        // Create Two threads, wait on the outcome then print them out.
        _T1 = new Thread(Operations);
        
        // Doesn't hold up primary thread if being shutdown.
        _T1.IsBackground = true; 
        _T1.Start(new Operations<string, string>("Jenny", "8675309"));
 
        _T2 = new Thread(Operations);
 
        // Doesn't hold up primary thread if being shutdown.
        _T2.IsBackground = true; 
        _T2.Start(new Operations<int, string>(71077345, "Shell Oil"));
 
    }
 
    // Thread safe way for a consumer to show the final results.
    // We wait for the threads to finish.
    public void PrintResults()
    {
 
        _T1.Join();
        _T2.Join();
 
        foreach (string line in _Results)
            Console.WriteLine(line);
 
    }
 
    // Safely add the result to the results list.
    private void ReportResults(string result)
    {  
        lock (_Results)
            _Results.Add(result);
    }
 
    // Thread target method to handle different types of data.
    public void Operations(object arguments)
    {
        string result = string.Empty;
 
        try
        {
            Operations<string, string> args = arguments as Operations<string, string>;
 
            if (args != null)
                result = string.Format("{0} is {1}", args.First, args.Second);
            else
            {
                Operations<int, string> args2 = arguments as Operations<int, string>;
                if (args2 != null)
                    result = string.Format("Calculator shows {0} upside down for {1}", 
                        args2.Second, args2.First);
                else
                    result = "Unknown object passed into thread"; // Report Error
            }
        }
 
        // Catch this exception if the parent calls thread.abort()
        // So we handle a cancel gracefully.
        catch (ThreadAbortException)
        {
 
            // We have handled the exception and will simply return without data.
            // Otherwise the abort will be rethrown out of this block.
            Thread.ResetAbort();
            result = "Cancel received...aborting";
        }
        catch (System.Exception ex)
        {
            result = ex.Message;
        }
        finally
        {
            ReportResults(result);
        }
    }
}
  • Share/Bookmark

OmegaMan's Musings is Digg proof thanks to caching by WP Super Cache