bug-commoncpp
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new Path class


From: David Sugar
Subject: Re: new Path class
Date: Thu, 21 Feb 2002 17:04:29 -0500 (EST)

I am guessing 1 month.  Freddy is looking it over to see if we could do it
in the "2" initial release...

On Thu, 21 Feb 2002, David Durham wrote:

> I understand... Let me know of any changes I should make... Also, do you
> have a guess at when this might be able to go in? 1 month 3 months 1 yr?
>
> Thanks,
>    -- Davy
>
> David Sugar wrote:
>
> > Right now we are in the process of validating Common C++ "2" for
> > release very soon, so it may not be a good time to take this set of
> > classes in at the moment.  I will look at these though....
> >
> > David Durham wrote:
> >
> >>   Hi,   I've created the Path class that I mentioned a few weeks
> >> back...   This is actually my first code to ever release as open
> >> source... I have lots of other code that I plan to release (like my
> >> application which uses this class), but am just not ready yet.  So I
> >> thought I'd start with this little thing.
> >> I just copied the license notices from another source file in the
> >> library and changed the copyright year... I didn't change the name...
> >> you can have it ;)
> >>
> >>   As far as the code goes: It has plenty of room for more
> >> functionality... I can imagine that there would be many other
> >> operations one might want to do on a path name than the operations I
> >> provided.    I didn't put any doxygen formatted comments, but I did
> >> put a few simple comments that explains a little what each method
> >> does.    Also, I was a little confused on how the rest of the
> >> CommonC++ library uses exceptions.  (I, myself, am well versed in
> >> exceptions though)  I saw that there was a define,
> >> "COMMON_STD_EXCEPTION" which is used.. If that define is not defined,
> >> it looks as if errors will go unreported at all... I also see
> >> throwing the object itself which seems a little strange... Anyway,
> >> what I did was just used exceptions throughout regardless of the
> >> define.. Change it if you want...
> >>   One more thing about the exceptions...  I found that if I derived
> >> from CommonC++'s Exception class that when I threw an exception
> >> constructed from an std::string it wouldn't retain the whole message
> >> or something... So I commented out the code for PathException and
> >> just typedefed it to std::runtime_error which is very similar to
> >> ost::Exception
> >>   Finally, I only wrote this for linux, I could (if you want) make
> >> sure it works under Solaris if that's one of the 'supported'
> >> platforms, but I just need to know what defines would indicate the
> >> platform (I suppose I could look in config.h)
> >>
> >> So... change whatever you want... I hope it's useful.. it has been to
> >> me in my sound editor application where I often need to manipulate
> >> the dirname basename or extention, check for existance, etc... of
> >> path names.
> >>
> >> -- Davy
> >>
> >>
> >> ------------------------------------------------------------------------
> >>
> >> // Copyright (C) 2002 Open Source Telecom Corporation.
> >> //
> >> // This program is free software; you can redistribute it and/or modify
> >> // it under the terms of the GNU General Public License as published by
> >> // the Free Software Foundation; either version 2 of the License, or
> >> // (at your option) any later version.
> >> //
> >> // This program is distributed in the hope that it will be useful,
> >> // but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> // GNU General Public License for more details.
> >> //
> >> // You should have received a copy of the GNU General Public License
> >> // along with this program; if not, write to the Free Software
> >> // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
> >> 02111-1307, USA.
> >> //
> >> // As a special exception to the GNU General Public License,
> >> permission is
> >> // granted for additional uses of the text contained in its release
> >> // of Common C++.
> >> //
> >> // The exception is that, if you link the Common C++ library with other
> >> // files to produce an executable, this does not by itself cause the
> >> // resulting executable to be covered by the GNU General Public License.
> >> // Your use of that executable is in no way restricted on account of
> >> // linking the Common C++ library code into it.
> >> //
> >> // This exception does not however invalidate any other reasons why
> >> // the executable file might be covered by the GNU General Public
> >> License.
> >> //
> >> // This exception applies only to the code released under the
> >> // name Common C++.  If you copy code from other releases into a copy of
> >> // Common C++, as the General Public License permits, the exception does
> >> // not apply to the code that you add in this way.  To avoid misleading
> >> // anyone as to the status of such modified files, you must delete
> >> // this exception notice from them.
> >> //
> >> // If you write modifications of your own for Common C++, it is your
> >> // choice whether to permit this exception to apply to your
> >> modifications.
> >> // If you do not wish that, delete this exception notice.
> >>
> >> #ifndef CCXX_path_H_
> >> #define CCXX_path_H_
> >>
> >> #include <string>
> >>
> >> #ifndef CCXX_CONFIG_H_
> >>     #include <cc++/config.h>
> >> #endif
> >>
> >> //see BBB note below  #include <cc++/exception.h>
> >>
> >> #ifndef WIN32
> >>     #include <sys/types.h>
> >>     #include <sys/stat.h>
> >> #else
> >>     #error unimplemented for win32 platform
> >> #endif
> >>
> >>
> >> // see BBB note below (this is what I did instead)
> >> #include <stdexcept>
> >> typedef runtime_error PathException;
> >>
> >>
> >>
> >> #ifdef  CCXX_NAMESPACES
> >> namespace ost {
> >> #endif
> >>
> >> /* BBB: I tried using this, but it wouldn't retain the whole
> >> exception message at the throw... it did if I used runtime_error from
> >> stdexcept
> >>   so, did what's above instead instead ...
> >> class PathException : public Exception
> >> {
> >> public:
> >>     PathException(std::string str) : Exception(str) {};
> >> };
> >> */
> >>
> >>
> >>
> >> class Path
> >> {
> >> public:
> >>     static const char dirDelim; // either '\' or '/' depending on the
> >> platform
> >>
> >>     Path(const std::string &path="");
> >>     virtual ~Path();
> >>
> >>     /*
> >>         changes the path from what it was constructed with
> >>     */
> >>     void setPath(const std::string &path);
> >>
> >>     /*
> >>         returns the path constructed with or the last one passed to
> >> setPath
> >>     */
> >>     const char *getPath() const;
> >>
> >>     /*
> >>         returns true iff the pathname exists and we could access it
> >>     */
> >>     bool Exists() const;
> >>
> >>     /*
> >>         possbily creates the path and/or updates its time(s) to current
> >>     */
> >>     bool Touch(bool canCreate=true,bool throwIfError=true) const;
> >>
> >>     /*
> >>         returns the absolute path resolved from a possibly relative path
> >>     */
> >>     const std::string RealPath() const;
> >>
> >>     /*
> >>         returns the extension of the path name (i.e. returns "ext"
> >> for "/dir1/dir2/file.ext")
> >>     */
> >>     const std::string Extension() const;
> >>
> >>     /*
> >>         returns just the directory name(s) part of the path (i.e.
> >> returns "/dir1/dir2" for "/dir1/dir2/file.ext")
> >>     */
> >>     const std::string DirName() const;
> >>
> >>     /*
> >>         returns just the filename part of the path (i.e. returns
> >> "file.ext" for "/dir1/dir2/file.ext")
> >>     */
> >>     const std::string BaseName() const;
> >>
> >>     /*
> >>         returns the number of bytes allocated for the file
> >>         either returns 0 or throws an exception if it doesn't exist
> >> or wasn't accessible
> >>     */
> >>     long getSize(bool throwIfError=true) const;
> >>     // many other things could be returned from the stat
> >>     //time_t get ... Time() const;
> >>
> >>
> >> private:
> >>     char *path;
> >>     bool exists;
> >>     struct stat statBuf;
> >>
> >> };
> >>
> >> #ifdef  CCXX_NAMESPACES
> >> }
> >> #endif
> >>
> >>
> >> #endif
> >>
> >>
> >> ------------------------------------------------------------------------
> >>
> >> // Copyright (C) 2002 Open Source Telecom Corporation.
> >> //
> >> // This program is free software; you can redistribute it and/or modify
> >> // it under the terms of the GNU General Public License as published by
> >> // the Free Software Foundation; either version 2 of the License, or
> >> // (at your option) any later version.
> >> //
> >> // This program is distributed in the hope that it will be useful,
> >> // but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> // GNU General Public License for more details.
> >> //
> >> // You should have received a copy of the GNU General Public License
> >> // along with this program; if not, write to the Free Software
> >> // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
> >> 02111-1307, USA.
> >> //
> >> // As a special exception to the GNU General Public License,
> >> permission is
> >> // granted for additional uses of the text contained in its release
> >> // of Common C++.
> >> //
> >> // The exception is that, if you link the Common C++ library with other
> >> // files to produce an executable, this does not by itself cause the
> >> // resulting executable to be covered by the GNU General Public License.
> >> // Your use of that executable is in no way restricted on account of
> >> // linking the Common C++ library code into it.
> >> //
> >> // This exception does not however invalidate any other reasons why
> >> // the executable file might be covered by the GNU General Public
> >> License.
> >> //
> >> // This exception applies only to the code released under the
> >> // name Common C++.  If you copy code from other releases into a copy of
> >> // Common C++, as the General Public License permits, the exception does
> >> // not apply to the code that you add in this way.  To avoid misleading
> >> // anyone as to the status of such modified files, you must delete
> >> // this exception notice from them.
> >> //
> >> // If you write modifications of your own for Common C++, it is your
> >> // choice whether to permit this exception to apply to your
> >> modifications.
> >> // If you do not wish that, delete this exception notice.
> >>
> >> #include "path.h"
> >>
> >> /*
> >>     This was first written and tested under linux, however a few
> >> provisions
> >>     have been made for a win32 port.      Also, several functions
> >> used are probably only available under linux, i.e.
> >>         realpath, dirname, basename
> >>     But there should be some equivalent under other unices, and
> >> implementation
> >>     changes should be made when this file is compiled under these
> >> other platforms.
> >> */
> >>
> >> #include <errno.h>
> >>
> >> #ifndef WIN32
> >>     #include <unistd.h>
> >>
> >>     #include <fcntl.h>
> >>
> >>     #include <limits.h>
> >>     #include <stdlib.h>
> >>
> >>     #include <string.h>
> >>
> >>     #include <libgen.h>  // for basename and dirname
> >> #else
> >>     #error unimplemented for win32 platform
> >> #endif
> >>
> >>
> >> #ifdef  CCXX_NAMESPACES
> >> namespace ost {
> >> using namespace std;
> >> #endif
> >>
> >> #ifdef WIN32
> >>     const char Path::dirDelim='\\';
> >> #else
> >>     const char Path::dirDelim='/';
> >> #endif
> >>
> >> Path::Path(const string &_path) :
> >>     path(NULL),
> >>     exists(false)
> >> {
> >>     setPath(_path);
> >> }
> >>
> >> Path::~Path()
> >> {
> >>     free(path);
> >> }
> >>
> >> void Path::setPath(const string &_path)
> >> {
> >>     if(_path.size()>=PATH_MAX)
> >>         throw PathException(string(__func__)+" -- path is >= than
> >> PATH_MAX -- '"+path+"'");
> >>
> >>     if(path!=NULL)
> >>         free(path);
> >>     path=strdup(_path.c_str());
> >>
> >>     if(stat(path,&statBuf)!=0)
> >>     {
> >>         exists=false;
> >>         if(errno!=ENOENT)
> >>             throw PathException(string(__func__)+" -- error stat-ing
> >> path name -- '"+path+"' -- "+string(strerror(errno)));
> >>     }
> >>     else
> >>         exists=true;
> >> }
> >>
> >> const char *Path::getPath() const
> >> {
> >>     return(path);
> >> }
> >>
> >> bool Path::Exists() const
> >> {
> >>     return(exists);
> >> }
> >>
> >> bool Path::Touch(bool canCreate,bool throwIfError) const
> >> {
> >>     if(canCreate)
> >>     {
> >>         int fd = open (path, O_WRONLY | O_CREAT | O_NONBLOCK |
> >> O_NOCTTY,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
> >>         if (fd == -1)
> >>         {
> >>             if(throwIfError)
> >>                 throw PathException(string(__func__)+" -- error
> >> touching path name '"+path+"'-- "+string(strerror(errno)));
> >>             else
> >>                 return(false);
> >>         }
> >>         close(fd);
> >>     }
> >>     else
> >>     {
> >>         int fd = open (path, O_WRONLY | O_NONBLOCK | O_NOCTTY,S_IRUSR
> >> | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
> >>         if (fd == -1 && errno!=ENOENT)
> >>         {
> >>             if(throwIfError)
> >>                 throw PathException(string(__func__)+" -- error
> >> touching path name '"+path+"'-- "+string(strerror(errno)));
> >>             else
> >>                 return(false);
> >>         }
> >>
> >>         if(fd!=-1)
> >>             close(fd);
> >>     }
> >>
> >>     return(true);
> >> }
> >>
> >> const string Path::RealPath() const
> >> {
> >>     if(!exists)
> >>         return("");
> >>
> >>     char resolvedPath[PATH_MAX];
> >>     char *result=realpath(path,resolvedPath);
> >>     if(result!=NULL)
> >>         return(result);
> >>     else
> >>         return("");
> >> }
> >>
> >> const string Path::Extension() const
> >> {
> >>     // find the right-most '.' which is also after the right-most
> >> dirDelim
> >>     char *lastDot=strrchr(path,'.');
> >>     if(lastDot==NULL) // go ahead and bail if there wasn't even a '.'
> >> in the path
> >>         return("");
> >>
> >>     char *lastDirDelim=strrchr(path,dirDelim);
> >>
> >>     if(lastDot>lastDirDelim)
> >>         return(lastDot+1);
> >>     else
> >>         return("");
> >>
> >> }
> >>
> >> const string Path::DirName() const
> >> {
> >>     // make a copy because the function modifies the contents
> >>     char tmp[PATH_MAX];
> >>     strcpy(tmp,path);
> >>
> >>     return(dirname(tmp));
> >> }
> >>
> >> const string Path::BaseName() const
> >> {
> >>     // make a copy because the function modifies the contents
> >>     char tmp[PATH_MAX];
> >>     strcpy(tmp,path);
> >>
> >>     return(basename(tmp));
> >> }
> >>
> >>
> >> // many other things could possibly be returned from the stat
> >> long Path::getSize(bool throwIfError) const
> >> {
> >>     if(!exists)
> >>     {
> >>         if(throwIfError)
> >>             throw(PathException(string(__func__)+" -- path did not
> >> exist or was inaccessible -- '"+path+"'"));
> >>         else
> >>             return(0);
> >>     }
> >>
> >>     return(statBuf.st_size);
> >> }
> >>
> >> //time_t get ... Path::Time() const;
> >>
> >> #ifdef  CCXX_NAMESPACES
> >> }
> >> #endif
> >>
> >>
> >> ------------------------------------------------------------------------
> >>
> >> #include <iostream>
> >> #include <stdexcept>
> >>
> >> #include "path.h"
> >>
> >> using ost::Path;
> >>
> >> int main()
> >> {
> >>     cout << "testing class Path\n";
> >>
> >>     try
> >>     {
> >>         Path p;
> >>
> >>         p.setPath("/etc/../etc/resolv.conf");
> >>
> >>         cout << "path: " << p.getPath() << endl;
> >>
> >>          cout << "exists: " << p.Exists() << endl;
> >>          cout << "touch: " << p.Touch(false,false) << endl;
> >>          cout << "RealPath: " << p.RealPath() << endl;
> >>          cout << "Extension: " << p.Extension() << endl;
> >>         cout << "DirName: " << p.DirName() << endl;
> >>         cout << "BaseName: " << p.BaseName() << endl;
> >>         cout << "getSize: " << p.getSize() << endl;
> >>     }
> >>     catch(exception &e)
> >>     {
> >>         cerr << "UNEXPECTED exception -- " << e.what() << endl;
> >>     }
> >>
> >>     try
> >>     {
> >>         Path p;
> >>
> >>         p.setPath("/etc/../etc/resolv.conf_pleasedontexist");
> >>
> >>         cout << "path: " << p.getPath() << endl;
> >>
> >>          cout << "exists: " << p.Exists() << endl;
> >>          //cout << "touch: " << p.Touch(false,false) << endl;
> >>          cout << "RealPath: " << p.RealPath() << endl;
> >>          cout << "Extension: " << p.Extension() << endl;
> >>         cout << "DirName: " << p.DirName() << endl;
> >>         cout << "BaseName: " << p.BaseName() << endl;
> >>         cout << "getSize: " << p.getSize(false) << endl;
> >>     }
> >>     catch(exception &e)
> >>     {
> >>         cerr << "UNEXPECTED exception -- " << e.what() << endl;
> >>     }
> >>
> >>
> >>     try
> >>     {
> >>         Path p;
> >>
> >>         p.setPath("/etc/../etc/resolv.conf_pleasedontexist");
> >>
> >>         cout << "path: " << p.getPath() << endl;
> >>
> >>         cout << "getSize: " << p.getSize() << endl;
> >>     }
> >>     catch(exception &e)
> >>     {
> >>         cerr << "EXPECTED exception -- " << e.what() << endl;
> >>     }
> >>
> >>
> >>     return(0);
> >> }
> >>
> >
> >
> >
> >
> > _______________________________________________
> > Bug-commoncpp mailing list
> > address@hidden
> > http://mail.gnu.org/mailman/listinfo/bug-commoncpp
> >
>
>
>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]