tags:

views:

35

answers:

3

I'm working on a problem where I need to have a way to convert a user inputted filename to a unique path name. Let's say I let the user specify a path name that points to a file that contains some data. I can then do Data* pData=Open(PathName). Now if the user specifies the same path name again, I'd like to be able to have a table of already opened files and just return a pointer to the same data: Data* pData2=GetOpenedData(PathName). This is easy to accomplish with a simple std::map<std::string,Data*>, the problem is that different values of PathName can point to the same file. The simplest case is on Windows case insensitivity comes into play.

The code is cross platform C++ and I don't have access to .NET stuff (but I'm happy to #ifdef the differences between Windows and UNIX if needed). Does anyone know of either Windows API or POSIX functions that can take a path name and return a unique (to the system) string that I can key off of. The key doesn't have to be the same in both systems (Windows/POSIX), just unique within a running instance of my code.

For now, I'm not worried about links or two ways to get to the same file. Such as in Windows, if I had \myserver\share mapped to S: then \myserver\share\blah and S:\blah are the same file, but I can live with those being thought of as different. But S:\blah and S:\Blah should be the same. If there is a way to make \myserver\share and S:\ also be unique, that's a bonus and I'd be really happy, but I can live without it. (Likewise, if there are multiple links to the same file in UNIX).

Edited to add:

It's not as simple as just doing a case insensitive search in windows. For example: c://data/mydata.dat while that's an "invalid" filename, windows will accept it and it will actualy point to c:\data\mydata.dat

Edited to add another thing:

I'd also like c:\mydirectory\..\blah.dat to be recognized at the same as c:\blah.dat

A: 

For Windows you can store the full path of a resource making all lowercase (or uppercase).

I don't use *nix so can't tell about that. But I believe in *nix systems case does matter (\home\a and \home\A are different). If that is the case then you can omit converting case of user input for *nix.

Donotalo
A: 

You can optionally instantiate std::map with a third template argument, which is the comparison function/functor (see e.g. http://www.cplusplus.com/reference/stl/map/). You could provide a case-insensitive string comparison function.

I believe Scott Meyers provides a good example of such a function in Effective STL; I can check this when I get home.

Oli Charlesworth
A: 

For Windows, PathCanonicalize() is your friend. The shell path handing package in Windows has a few additional routines that'll help you out.

Unfortunately, I'm not sure what the Unix equivalents to this package is.

Bukes