metareg.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:9k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: metareg.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:08:30  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: metareg.cpp,v 1000.2 2004/06/01 19:08:30 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Aaron Ucko
  35.  *
  36.  * File Description:
  37.  *   CMetaRegistry
  38.  *
  39.  * ===========================================================================
  40.  */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/metareg.hpp>
  43. #include <corelib/ncbiapp.hpp>
  44. #include <corelib/ncbifile.hpp>
  45. BEGIN_NCBI_SCOPE
  46. auto_ptr<CMetaRegistry> CMetaRegistry::sm_Instance;
  47. DEFINE_CLASS_STATIC_MUTEX(CMetaRegistry::sm_Mutex);
  48. CMetaRegistry::~CMetaRegistry()
  49. {
  50.     ITERATE (vector<SEntry>, it, m_Contents) {
  51.         // optionally save if modified?
  52.         if ( !(it->flags & fDontOwn) ) {
  53.             delete it->registry;
  54.         }
  55.     }
  56. }
  57. CMetaRegistry::SEntry
  58. CMetaRegistry::x_Load(const string& name, CMetaRegistry::ENameStyle style,
  59.                       CMetaRegistry::TFlags flags,
  60.                       CNcbiRegistry::TFlags reg_flags, CNcbiRegistry* reg,
  61.                       const string& name0, CMetaRegistry::ENameStyle style0)
  62. {
  63.     _TRACE("CMetaRegistry::Load: looking for " << name);
  64.     CMutexGuard GUARD(sm_Mutex);
  65.     if (flags & fPrivate) {
  66.         GUARD.Release();
  67.     }
  68.     else { // see if we already have it
  69.         TIndex::const_iterator iit
  70.             = m_Index.find(SKey(name, style, flags, reg_flags));
  71.         if (iit != m_Index.end()) {
  72.             _TRACE("found in cache");
  73.             _ASSERT(iit->second < m_Contents.size());
  74.             return m_Contents[iit->second];
  75.         }
  76.         ITERATE (vector<SEntry>, it, m_Contents) {
  77.             if (it->flags != flags  ||  it->reg_flags != reg_flags)
  78.                 continue;
  79.             if (style == eName_AsIs  &&  it->actual_name == name) {
  80.                 _TRACE("found in cache");
  81.                 return *it;
  82.             }
  83.         }
  84.     }
  85.     string dir;
  86.     CDirEntry::SplitPath(name, &dir, 0, 0);
  87.     if ( dir.empty() ) {
  88.         ITERATE (TSearchPath, it, m_SearchPath) {
  89.             SEntry result = x_Load(CDirEntry::MakePath(*it, name), style,
  90.                                    flags, reg_flags, reg, name0, style0);
  91.             if ( result.registry ) {
  92.                 return result;
  93.             }
  94.         }
  95.     } else {
  96.         switch (style) {
  97.         case eName_AsIs: {
  98.             CNcbiIfstream in(name.c_str(), IOS_BASE::in | IOS_BASE::binary);
  99.             if ( !in.good() ) {
  100.                 _TRACE("CMetaRegistry::Load() -- cannot open registry file: "
  101.                        << name);
  102.                 break;
  103.             }
  104.             _TRACE("CMetaRegistry::Load() -- reading registry file: " << name);
  105.             SEntry result;
  106.             result.flags     = flags;
  107.             result.reg_flags = reg_flags;
  108.             if ( reg ) {
  109.                 if ( !reg->Empty() ) { // shouldn't share
  110.                     result.flags |= fPrivate;
  111.                 }
  112.                 result.registry = reg;
  113.                 reg->Read(in, reg_flags);
  114.             } else {
  115.                 result.registry = new CNcbiRegistry(in, reg_flags);
  116.             }
  117.             if ( CDirEntry::IsAbsolutePath(name) ) {
  118.                 result.actual_name = name;
  119.             } else {
  120.                 result.actual_name = CDirEntry::ConcatPath(CDir::GetCwd(),
  121.                                                            name);
  122.             }
  123.             if ( !(flags & fPrivate) ) {
  124.                 m_Contents.push_back(result);
  125.                 m_Index[SKey(name0, style0, flags, reg_flags)]
  126.                     = m_Contents.size() - 1;
  127.             }
  128.             return result;
  129.         }
  130.         case eName_Ini: {
  131.             string name2(name);
  132.             for (;;) {
  133.                 SEntry result = x_Load(name2 + ".ini", eName_AsIs, flags,
  134.                                        reg_flags, reg, name0, style0);
  135.                 if (result.registry) {
  136.                     return result;
  137.                 }
  138.                 string base, ext; // dir already known
  139.                 CDirEntry::SplitPath(name2, 0, &base, &ext);
  140.                 if ( ext.empty() ) {
  141.                     break;
  142.                 }
  143.                 name2 = CDirEntry::MakePath(dir, base);
  144.             }
  145.             break;
  146.         }
  147.         case eName_DotRc: {
  148.             string base, ext;
  149.             CDirEntry::SplitPath(name, 0, &base, &ext);
  150.             return x_Load(CDirEntry::MakePath(dir, '.' + base, ext) + "rc",
  151.                           eName_AsIs, flags, reg_flags, reg, name0, style0);
  152.         }
  153.         }  // switch (style)
  154.     }
  155.     // not found
  156.     SEntry result;
  157.     result.flags     = flags;
  158.     result.reg_flags = reg_flags;
  159.     result.registry  = 0;
  160.     if (reg  &&  !(flags & fDontOwn) ) {
  161.         delete reg;
  162.     }
  163.     return result;
  164. }
  165. void CMetaRegistry::GetDefaultSearchPath(CMetaRegistry::TSearchPath& path)
  166. {
  167.     // set up the default search path:
  168.     //    - The current working directory.
  169.     //    - The directory, if any, given by the environment variable "NCBI".
  170.     //    - The user's home directory.
  171.     //    - The directory containing the application, if known
  172.     path.push_back(".");
  173.     {{
  174.         const char* ncbi = getenv("NCBI");
  175.         if (ncbi  &&  *ncbi) {
  176.             path.push_back(ncbi);
  177.         }
  178.     }}
  179.     path.push_back(CDir::GetHome());
  180.     {{
  181.         CNcbiApplication* the_app = CNcbiApplication::Instance();
  182.         if ( the_app ) {
  183.             const CNcbiArguments& args = the_app->GetArguments();
  184.             string                dir  = args.GetProgramDirname(eIgnoreLinks);
  185.             string                dir2 = args.GetProgramDirname(eFollowLinks);
  186.             if (dir.size()) {
  187.                 path.push_back(dir);
  188.             }
  189.             if (dir2.size() && dir2 != dir) {
  190.                 path.push_back(dir2);
  191.             }
  192.         }
  193.     }}
  194. }
  195. bool CMetaRegistry::SKey::operator <(const SKey& k) const
  196. {
  197.     if (requested_name < k.requested_name) {
  198.         return true;
  199.     } else if (requested_name > k.requested_name) {
  200.         return false;
  201.     }
  202.     if (style < k.style) {
  203.         return true;
  204.     } else if (style > k.style) {
  205.         return false;
  206.     }
  207.     if (flags < k.flags) {
  208.         return true;
  209.     } else if (flags > k.flags) {
  210.         return false;
  211.     }
  212.     if (reg_flags < k.reg_flags) {
  213.         return true;
  214.     } else if (reg_flags > k.reg_flags) {
  215.         return false;
  216.     }
  217.     return false;
  218. }
  219. END_NCBI_SCOPE
  220. /*
  221.  * ===========================================================================
  222.  *
  223.  * $Log: metareg.cpp,v $
  224.  * Revision 1000.2  2004/06/01 19:08:30  gouriano
  225.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  226.  *
  227.  * Revision 1.12  2004/05/14 13:59:26  gorelenk
  228.  * Added include of ncbi_pch.hpp
  229.  *
  230.  * Revision 1.11  2003/12/08 18:40:22  ucko
  231.  * Use DEFINE_CLASS_STATIC_MUTEX to avoid possible premature locking.
  232.  *
  233.  * Revision 1.10  2003/10/01 14:32:09  ucko
  234.  * +EFollowLinks
  235.  *
  236.  * Revision 1.9  2003/10/01 01:02:49  ucko
  237.  * Fix (syntactically) broken assertion.
  238.  *
  239.  * Revision 1.8  2003/09/30 21:06:24  ucko
  240.  * Refactored cache to allow flushing of path searches when the search
  241.  * path changes.
  242.  * If the application ran through a symlink to another directory, search
  243.  * the real directory as a fallback.
  244.  *
  245.  * Revision 1.7  2003/09/29 20:15:20  vakatov
  246.  * CMetaRegistry::x_Load() -- thinko fix:  "result.flags |= fPrivate;" (added '|')
  247.  *
  248.  * Revision 1.6  2003/08/21 20:50:54  ucko
  249.  * eName_DotRc: avoid accidentally adding a dot before the rc...
  250.  *
  251.  * Revision 1.5  2003/08/18 19:49:09  ucko
  252.  * Remove an unreachable statement.
  253.  *
  254.  * Revision 1.4  2003/08/12 15:15:50  ucko
  255.  * Open registry files in binary mode per CNcbiRegistry's expectations.
  256.  *
  257.  * Revision 1.3  2003/08/06 20:26:17  ucko
  258.  * Allow Load to take an existing registry to reuse; properly handle flags.
  259.  *
  260.  * Revision 1.2  2003/08/05 20:28:51  ucko
  261.  * CMetaRegistry::GetDefaultSearchPath: don't add the program's directory
  262.  * if it's empty.
  263.  *
  264.  * Revision 1.1  2003/08/05 19:57:59  ucko
  265.  * CMetaRegistry: Singleton class for loading CRegistry data from files;
  266.  * keeps track of what it loaded from where, for potential reuse.
  267.  *
  268.  * ===========================================================================
  269.  */