File indexing completed on 2024-06-02 04:44:36

0001 /*
0002  * ====================================================================
0003  * Copyright (c) 2002-2009 The RapidSvn Group.  All rights reserved.
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program (in the file GPL.txt.  
0017  * If not, see <http://www.gnu.org/licenses/>.
0018  *
0019  * This software consists of voluntary contributions made by many
0020  * individuals.  For exact contribution history, see the revision
0021  * history and logs, available at http://rapidsvn.tigris.org/.
0022  * ====================================================================
0023  */
0024 
0025 // subversion api
0026 #include "svn_types.h"
0027 
0028 // apr api
0029 #include "apr_file_info.h"
0030 
0031 // svncpp
0032 
0033 #include "kdevsvncpp/exception.hpp"
0034 #include "kdevsvncpp/path.hpp"
0035 #include "kdevsvncpp/pool.hpp"
0036 #include "kdevsvncpp/status.hpp"
0037 #include "kdevsvncpp/status_selection.hpp"
0038 #include "kdevsvncpp/targets.hpp"
0039 #include "kdevsvncpp/url.hpp"
0040 
0041 
0042 namespace svn
0043 {
0044   struct StatusSel::Data
0045   {
0046     Targets targets;
0047     StatusVector status;
0048 
0049     bool hasDirs;
0050     bool hasFiles;
0051     bool hasVersioned;
0052     bool hasUnversioned;
0053     bool hasUrl;
0054     bool hasLocal;
0055 
0056     Path emptyTarget;
0057 
0058     /** default constructor */
0059     Data() {}
0060 
0061     /** copy constructor */
0062     Data(const Data & src)
0063     {
0064       if (this != &src)
0065         assign(src);
0066     }
0067 
0068     /** assign new values */
0069     void
0070     assign(const Data & src)
0071     {
0072       // clear existing...
0073       clear();
0074 
0075       // ... and set from source
0076       StatusVector::const_iterator it;
0077       for (it = src.status.begin(); it != src.status.end(); ++it)
0078       {
0079         push_back(*it);
0080       }
0081     }
0082 
0083     void
0084     clear()
0085     {
0086       targets.clear();
0087       status.clear();
0088 
0089       hasDirs = false;
0090       hasFiles = false;
0091       hasVersioned = false;
0092       hasUnversioned = false;
0093       hasLocal = false;
0094       hasUrl = false;
0095     }
0096 
0097     void
0098     push_back(const Status & status_)
0099     {
0100       // skip pseudo entries
0101       if (!status_.isSet())
0102         return;
0103 
0104       if (!status_.isVersioned())
0105       {
0106         // for an unversioned entry we do not know
0107         // whether it's a file or a directory so
0108         // we have to check using APR
0109         apr_finfo_t finfo;
0110         Pool pool;
0111         apr_status_t apr_status = apr_stat(
0112                                     &finfo, status_.path(), APR_FINFO_TYPE, pool);
0113 
0114         // if we get an error the file might
0115         // have been deleted in the meantime
0116         // anyhow: we do not want to display it
0117         if (apr_status != APR_SUCCESS)
0118           return;
0119 
0120         hasUnversioned = true;
0121 
0122         if (APR_DIR == finfo.filetype)
0123           hasDirs = true;
0124         else
0125           hasFiles = true;
0126 
0127       }
0128       else
0129       {
0130         hasVersioned = true;
0131         if (Url::isValid(status_.path()))
0132           hasUrl = true;
0133         else
0134           hasLocal = true;
0135 
0136         if (svn_node_dir == status_.entry().kind())
0137           hasDirs = true;
0138         else
0139           hasFiles = true;
0140       }
0141 
0142       // add stuff only now (because of possible apr_error
0143       // which causes the function to exit)
0144       targets.push_back(status_.path());
0145       status.push_back(status_);
0146     }
0147   };
0148 
0149 
0150   StatusSel::StatusSel()
0151       : m(new Data)
0152   {
0153   }
0154 
0155   StatusSel::StatusSel(const StatusSel & src)
0156       : m(new Data)
0157   {
0158     // different instance?
0159     if (this != &src)
0160       m->assign(*src.m);
0161   }
0162 
0163   StatusSel &
0164   StatusSel::operator = (const StatusSel & src)
0165   {
0166     if (this != &src)
0167     {
0168       delete m;
0169       m = new Data(*src.m);
0170     }
0171 
0172     return *this;
0173   }
0174 
0175   StatusSel::~StatusSel()
0176   {
0177     delete m;
0178   }
0179 
0180   const apr_array_header_t *
0181   StatusSel::array(const Pool & pool) const
0182   {
0183     return m->targets.array(pool);
0184   }
0185 
0186   const StatusVector &
0187   StatusSel::statusVector() const
0188   {
0189     return m->status;
0190   }
0191 
0192   const Targets &
0193   StatusSel::targets() const
0194   {
0195     return m->targets;
0196   }
0197 
0198   size_t
0199   StatusSel::size() const
0200   {
0201     return m->targets.size();
0202   }
0203 
0204   void
0205   StatusSel::push_back(const Status & status)
0206   {
0207     m->push_back(status);
0208   }
0209 
0210   void
0211   StatusSel::clear()
0212   {
0213     m->clear();
0214   }
0215 
0216   void
0217   StatusSel::reserve(size_t size)
0218   {
0219     m->targets.reserve(size);
0220     m->status.reserve(size);
0221   }
0222 
0223   StatusSel::operator const PathVector & () const
0224   {
0225     return m->targets;
0226   }
0227 
0228   const Path &
0229   StatusSel::target() const
0230   {
0231     if (size() > 0)
0232       return m->targets.targets()[0];
0233     else
0234       return m->emptyTarget;
0235   }
0236 
0237   bool
0238   StatusSel::hasDirs() const
0239   {
0240     return m->hasDirs;
0241   }
0242 
0243   bool
0244   StatusSel::hasFiles() const
0245   {
0246     return m->hasFiles;
0247   }
0248 
0249   bool
0250   StatusSel::hasVersioned() const
0251   {
0252     return m->hasVersioned;
0253   }
0254 
0255   bool
0256   StatusSel::hasUnversioned() const
0257   {
0258     return m->hasUnversioned;
0259   }
0260 
0261   bool
0262   StatusSel::hasLocal() const
0263   {
0264     return m->hasLocal;
0265   }
0266 
0267   bool
0268   StatusSel::hasUrl() const
0269   {
0270     return m->hasUrl;
0271   }
0272 }
0273 
0274 /* -----------------------------------------------------------------
0275  * local variables:
0276  * eval: (load-file "../../rapidsvn-dev.el")
0277  * end:
0278  */