Apr 9, 2013

Mar 21, 2011

Simple Regex example

So I had to do a quick search and replace on an xml file. The goal was to replace a pattern with another.

Example: Replace /2/215.html with &id2=2&id3=215

So here is a function to look for this pattern and replace with this other pattern:

static string ReplacePattern(Match m)
{
    var x = m.ToString();
    Console.WriteLine("Match is : " + x);

    var c = x.Count(f => f == '/'); // Or equivalent: x.Split('/').Length - 1;
    var slashIdx = x.IndexOf('/');

    for (int i = 0; i < c; i++)
    {
         var newPatt = string.Format("&id{0}=", (i + 2).ToString());
         x = slashIdx > 0 ? x.Substring(0, slashIdx) + newPatt + x.Substring(slashIdx + 1) : newPatt + x.Substring(slashIdx + 1);
         slashIdx = x.IndexOf('/', slashIdx + 1);
    }

    x = x.Replace(".html", string.Empty);

    Console.WriteLine("Replaced is: " + x);
    return x;
}

And here is a quick tester function:

private static void TestReplacePattern()
{
    string s = @"<loc>http://www.blabla.com/index.php?id=0/123/23/1/456/5.html";
    Regex r = new Regex("/[0-9/]+.html");
    Console.WriteLine(r.Replace(s, new MatchEvaluator(ReplacePattern)));
}

Mar 17, 2011

Refactor routine to use LINQ

Here is a function that does a bitwise XOR on a string

public string doIt(string input)
{
     var aChars = input.ToCharArray();
     var aCharsRes = new char[aChars.Length];

     for (int i = 0; i < aChars.Length; i++)
     {
          aCharsRes[i] = (char)(aChars[i] ^ 1);
     }
     return new string(aCharsRes);
}

Here is the re-factored one liner:

public string doItOneLiner(string input)
{
    return new string(input.ToCharArray().Select(s => (char)(s ^ 1)).ToArray());
}

Is it more readable? After getting used to LINQ, I guess.

Jul 9, 2010

Log4net

This logging infrastructure can sometimes be frustrating to setup, especially with the RollingFileAppender who wouldn't create and write to that damn log file specified in the app.config

So, one thing that helps, in the app.config of the app, put the log4net in debug like this:
<log4net debug="true">

This way, errors in log4net will be sent to the Output (Ctrl+W, O) -> Show output from: Debug.
Here are 2 ways to configure before sending stuff to the log.

1. Call Configure() somewhere in the app (like Program.cs):
log4net.Config.DOMConfigurator.Configure();

But that means that you should modify the config section in the app.config:
<configSections>
   <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>

OR

2. You can add in AssemblyInfo.cs:
[assembly: log4net.Config.DOMConfigurator(Watch = true)]

And then modify in the app.config sections:
<configSections>
   <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
</configSections>


Here is the rest of the log4net config in the app.config:

<log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value="TestLog4net.log" />
      <param name="AppendToFile" value="true" />
      <param name="ImmediateFlush" value="true" />
      <param name="MaxSizeRollBackups" value="10" />
      <param name="MaximumFileSize" value="10MB" />
      <param name="RollingStyle" value="Size" />
      <param name="StaticLogFileName" value="false" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="[--- Log started ---]\r\n" />
        <param name="Footer" value="[--- Log ended ---]\r\n" />
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

Here is some C# to demo this log4net logging infrastructure:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;

namespace TestLog4Net
{
    class Program
    {
        private static readonly ILog _log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            // Using the first method to setup log4net
            DOMConfigurator.Configure();

            _log.Debug("Here is a debug log.");
            _log.Info("... and an Info log.");
            _log.Warn("... and a warning.");
            _log.Error("... and an error.");
            _log.Fatal("... and a fatal error.");
           
            Console.Read();
        }
    }
}

Here is the output in TestLog4net.log:

[--- Log started ---]
2010-07-09 12:44:40,072 [3996] DEBUG TestLog4Net.Program [] - Here is a debug log.
2010-07-09 12:44:40,088 [3996] INFO TestLog4Net.Program [] - ... and an Info log.
2010-07-09 12:44:40,088 [3996] WARN TestLog4Net.Program [] - ... and a warning.
2010-07-09 12:44:40,088 [3996] ERROR TestLog4Net.Program [] - ... and an error.
2010-07-09 12:44:40,088 [3996] FATAL TestLog4Net.Program [] - ... and a fatal error.
[--- Log ended ---]


Now, here are 2 resources providing more detail:
Log4Net Tutorial
A Brief Introduction to the log4net logging library, using C#

May 31, 2010

The Following Module was built either with optimizations enabled or without debug information

So I am trying to debug this Win service (built with VS2008) that references a module (DLL containing Managed C++ that was built with VS2010) and I keep getting a message box (see title) when attaching to the service process with VS2010.

Plowing through the web, found this solution that oddly enough worked:

I unchecked the "Enable just my code(managed only)" in (VS2010) Debug -> Options -> Debugging -> General

The code that had breakpoints was built in Debug Mode and I am pretty sure that I wrote it. So disabling just my code in the debug options makes no sense.

And, there's not much to be found on the subject on the net. Hopefully this SO post will develop in the future.