Monday, March 16, 2009

Strings in c++

I made the mistake of taking a c++ class.  Well itn's not a mistake it is good to be reminded of how much effort things are in c++.  Take strings for example. In c# if you want to lower case a string you do a str.ToLower() and it is lower case in c++ you have to do some thign like this.
   30     static void ToLower(string &itext)
   31     {
   32         transform(itext.begin(), itext.end(), itext.begin(), (int(*)(int)) tolower);
   33     }

This one wasn't all that bad it is still just one line. This what the first one I needed
for the project I am working on at the moment.  The other one I wished I had on several
was str.Trim() just to clear off the white space. So I spend 5 minuets googling and found
something simlar to this.  
 
   35 static void Trim(string &itext)
   36 {
   37     int startLoc = itext.find_first_not_of(" \t\n");
   38     int endLoc = itext.find_last_not_of(" \t\n");
   39     if((std::string::npos == startLoc) || (std::string::npos == endLoc))
   40     {
   41         itext = "";
   42     }
   43     else
   44     {
   45         itext = itext.substr(startLoc,endLoc - startLoc + 1);
   46     }
   47 }

it dosn't do any thing but white space but still it is better then a kick in the face.


Wednesday, December 31, 2008

C# is so much easier then C++

I have been given the opportunity to work on an old c++ program for work this last couple works.  I just have to say that C# is so much easier to follow and understand then MFC any day of the week.  I did learn how to check if a directory exists before creating it though.

 1569 if(GetFileAttributes(_T(tPath)) == INVALID_FILE_ATTRIBUTES)
 1570     {
 1571         SECURITY_ATTRIBUTES sa;
 1572         sa.nLength = sizeof(SECURITY_ATTRIBUTES);        
 1573         sa.lpSecurityDescriptor = NULL;
 1574         sa.bInheritHandle = FALSE;
 1575         CreateDirectory(_T(tPath),&sa);
 1576     }

Just thought I put this here for when I need it again.

Wednesday, December 10, 2008

Delimiters

Let’s talk about string delimiters and why you shouldn’t hard code them. Take the following example.

   16 return String.Format("#Command#{0}#{1}#{2}#{3}#{4}#{5}#{6}#{7}#{8}#{9}", completePath,
   17                                                                       GUID,
   18                                                                       UID,
   19                                                                       otherinfo,
   20                                                                       option1,
   21                                                                       displayText,
   22                                                                       filter,
   23                                                                       someint.ToString(),
   24                                                                       file,
   25                                                                       seckret);

It and three other ones just like it can be found in the code I am currently working on. Now when you see this you think that isn’t all that bad. Until you need to change the delimiter for one reason or another. You could go with something like the following but it not the most readable thing you will ever see.

   28 return String.Format("{10}Command{10}{0}{10}{1}{10}{2}{10}{3}{10}{4}{10}{5}{10}{6}{10}{7}{10}{8}{10}{9}",
   29                                                                       completePath,
   30                                                                       GUID,
   31                                                                       UID,
   32                                                                       otherinfo,
   33                                                                       option1,
   34                                                                       displayText,
   35                                                                       filter,
   36                                                                       someint.ToString(),
   37                                                                       file,
   38                                                                       seckret,
   39                                                                       commandStringDelimiter);

This is a little better now you can just change “commandStringDelimiter” to a different value when you need to change the delimiter. But it’s not verry readabel a better soluction is to do build a function that can build the string for you. This allows you to hide how it is created and keep it all in one place. Like this.

   54 public string BuildFileCommandString(params string[] options)
   55         {
   56             List<string> cStr = new List<string>();
   57             cStr.Add("Command");
   58             cStr.AddRange(options);
   59             return this.commandStringDelimiter + string.Join(this.commandStringDelimiter, cStr.ToArray());
   60         }      

You would call it like this.

   41 BuildFileCommandString(completePath,
   42                        GUID,
   43                        UID,
   44                        otherinfo,
   45                        option1,
   46                        displayText,
   47                        filter,
   48                        someint.ToString(),
   49                        file,
   50                        Seckret);

You will also notice that I used a string.Join rather then a string.Format this just makes it more readable to me.

Wednesday, October 29, 2008

Cool if statement.

I ran into this little if statement while fixing moving some code around today. It does something like 18 string functions and that is assuming that Path.GetExtension is just one string function call.

   30 if (Path.GetExtension(path).ToLower() == ".tif"
   31     || Path.GetExtension(path).ToLower() == ".pdf"
   32     || Path.GetExtension(path).ToLower() == ".jpg"
   33     || Path.GetExtension(path).ToLower() == ".png"
   34     || Path.GetExtension(path).ToLower() == ".gif"
   35     || Path.GetExtension(path).ToLower() == ".jpeg")

I decided that it needed to be removed and I replaced it with this.

   25 string ext = Path.GetExtension(path).ToLower();            
   26 List<string> validExt = new List<string> { ".tif", ".pdf", ".jpg", ".png", ".gif", ".jpeg" };
   27 if(validExt.Contains(ext)) 

But you could also do  this with LINQ

   25 var extensions = new List<string> { ".jpg", ".jpeg", ".tif", ".png", ".gif" };
   26 if ((from i in extensions where i == Path.GetExtension(dir).ToLower() select i).Count() > 0)

I like the second version the best but that is just personal preference.  Both alternatives are way better then the first option.

Tuesday, October 28, 2008

Fun with directory security

So for the last couple weeks we have been having a problem with our installer and it’s setting of access rights on directories. This was mostly a problem with vista and well I got made the “vista access rights expert” so that translates into you get to figure out what is wrong.

   15 static void Main(string[] args)
   16 {
   17     string aPath = @"C:\ProgramData\TestApp";
   18     string fPath = Path.Combine(aPath, "files");
   19     Directory.CreateDirectory(fPath);
   20     SetPermissions(aPath);            
   21 }
   22 public static void SetPermissions(string dir)
   23 {
   24     DirectoryInfo info = new DirectoryInfo(dir);
   25     DirectorySecurity ds = info.GetAccessControl();            
   26     ds.AddAccessRule(new FileSystemAccessRule(@"BUILTIN\Users", 
   27                      FileSystemRights.FullControl,
   28                      InheritanceFlags.ContainerInherit,                            
   29                      PropagationFlags.None,
   30                      AccessControlType.Allow));
   31     info.SetAccessControl(ds);            
   32 }

The code started out looking something like this. It adds a security rule for all users to the folder allowing use users access to data on the local system. Problem is that if a program tries to access the files it throws an access denied error. Even though the user’s effective permission to the folder is FullControl. He doesn’t have any access to the files in the folder, and can’t access the files dir at all. After several hours of reading and trying different things all the smart people I drug into help me with the problem came up with three small changes that make it all work without a problem.

   15 static void Main(string[] args)
   16 {
   17     string aPath = @"C:\ProgramData\TestApp";
   18     string fPath = Path.Combine(aPath, "files");
   19     Directory.CreateDirectory(aPath);
   20     SetPermissions(aPath);
   21     Directory.CreateDirectory(fPath);
   22 }
   23 public static void SetPermissions(string dir)
   24 {
   25     DirectoryInfo info = new DirectoryInfo(dir);
   26     DirectorySecurity ds = info.GetAccessControl();
   27     ds.AddAccessRule(new FileSystemAccessRule(@"BUILTIN\Users",
   28                      FileSystemRights.FullControl,
   29                      InheritanceFlags.ObjectInherit |
   30                      InheritanceFlags.ContainerInherit,
   31                      PropagationFlags.None,
   32                      AccessControlType.Allow));
   33     info.SetAccessControl(ds);
   34 }

The changes that needed to be made wore creating the base directory and setting permissions before the sub folder was added. In the set permissions folder there was also a second flag added to the inheritance option of FileSystemAccessRule that changed it so that both files and folders inherited the settings.

Monday, October 6, 2008

The DAO Class

In the project I am currently working on we have lots of objects and each object has it's own DAO class.  This is fine every class should have a DAO object.  Or I should say that there should be a DAO object that every class can use to access it's data from it's storage location. The thing is that most systems I have worked with don't do it this way.  They have a DAO object that creates objects.  Not objects that use the DAO system to create them selves.

I will give you an example.  Say you have a class called foo and you want to get an instance of it from the database. With the DAO as create system you have to do the following.

   20 foo bar = fooDAO.GetFooByID(fooID);



bar gets created in the fooDAO object so basically any place where you want to work with foo you have to have fooDAO around and visible in scope as well.  No in the way I like to see things like this done a foo object has a reference to the fooDAO in his class so when you are creating the foo object you just say:




   19 foo bar = new foo(fooID);



So some people will say you haven't accomplished all that much by pushing it down into the class.  Which is true you still have the same amount of code, but when the guy that writes the business logic is working with foo now he doesn't have to know about fooDAO or care about it. He gets to make calls like.




   22 bar.Save();



rather then calls like this.




   23 fooDAO.UpdateFoo(bar);



Then when the day comes where it is time to stop using the cheep read free database you decided to use and switch over to a more powerful database. All of your updates can be done one place for each class type, and if you designed it right and use an well defined interface for your DAO object you will be able just to change the DAO object reference in each class.

Wednesday, October 1, 2008

Best varible name ever.

So today I was looking at a coworker’s code. I am doing CURD processes for the system I am working on this isn’t creative code or even variable code beyond you change the names of what you are keeping in the database. But while grabbing his code to use as a template for the new function I ran across this little pearl of code. My work went from boring to enjoyable in second all because of one line of code that made me laugh. Her it is.


  716 object of_my_affection = command.ExecuteScalar();


Sometimes having a bit of fun in your code makes it better than all the naming conventions you could ever use.