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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: KeyValue.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 20:42:51  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: KeyValue.cpp,v 1000.2 2004/06/01 20:42:51 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:  Robert G. Smith
  35.  *
  36.  * File Description:
  37.  *   CKeyValue represents a key/value pair, where the key is a string
  38.  *   and the value can be a string or a recursive list of key/value pairs.
  39.  *   Values can be retrieved and stored with compound keys (e.g. "view.grapic.color.gene")
  40.  *   to get at deeper levels.
  41.  *
  42.  *
  43.  * Remark:
  44.  *   This code was originally generated by application DATATOOL
  45.  *   using specifications from the data definition file
  46.  *   'plugin.asn'.
  47.  */
  48. // standard includes
  49. // generated includes
  50. #include <ncbi_pch.hpp>
  51. #include <gui/config/KeyValue.hpp>
  52. // generated classes
  53. BEGIN_NCBI_SCOPE
  54. BEGIN_objects_SCOPE // namespace ncbi::objects::
  55. CKeyValue::CKeyValue(const string& key)
  56. {
  57.     SetKey(key);
  58. }
  59. CKeyValue::CKeyValue(const string& key, const string& value)
  60. {
  61.     SetKey(key);
  62.     SetVal().SetStr(value);
  63. }
  64. // destructor
  65. CKeyValue::~CKeyValue(void)
  66. {
  67. }
  68. // Merge an other key value object into this one.
  69. // the other one's values take precedence.
  70. // ignore the key value, it should be the same.
  71. CKeyValue& CKeyValue::Merge(const CKeyValue& other_kv)
  72. {
  73.     if (this == &other_kv)
  74.         return *this;
  75.         
  76.     if (other_kv.CanGetVal()) {
  77.         const TVal& other_val = other_kv.GetVal();
  78.         if (other_val.IsStr()) {
  79.             SetVal().SetStr(other_val.GetStr());
  80.         }
  81.         else if (other_val.IsKeyvals()) {
  82.             const TVal::TKeyvals& other_kvs = other_val.GetKeyvals();
  83.             ITERATE(TVal::TKeyvals, other_kv_it, other_kvs) {
  84.                 const CKeyValue& other_kv = **other_kv_it;
  85.                 if (other_kv.CanGetKey()) {
  86.                     CKeyValue& my_kv = AddKey(other_kv.GetKey());
  87.                     my_kv.Merge(other_kv);
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     return *this;
  93. }
  94.     
  95. // non-trivial Accessor methods.
  96. // Assuming this KeyValue holds a list of KeyValues, not just a string
  97. // search for one with a matching key.
  98. const CKeyValue& CKeyValue::GetKeyvalueByKey1(const string & key) const
  99. {
  100.     const TVal::TKeyvals& keyvals = GetVal().GetKeyvals();
  101.     
  102.     TVal::TKeyvals::const_iterator kv_it = 
  103.         s_FindKeyvalueByKey(key, keyvals);
  104.     if (kv_it == keyvals.end())
  105.         ThrowUnassigned(1);
  106.     return **kv_it;
  107. }
  108. // Given a key of type: "label.label2.label3"
  109. // search our nested hierarchy of key-value pairs and return the pair that corresponds.
  110. const CKeyValue& CKeyValue::GetKeyvalueByKey(const string & key, const string& delim) const
  111. {
  112.     _ASSERT(delim.size() == 1);
  113.     // Split the key.
  114.     list<string> keys;
  115.     NStr::Split(key, delim, keys);
  116.     _ASSERT (! keys.empty());
  117.     
  118.     CConstRef<CKeyValue> kvp(this);    
  119.     ITERATE( list<string>, key_it, keys) {
  120.         const TVal::TKeyvals& keyvals = kvp->GetVal().GetKeyvals();
  121.         
  122.         TVal::TKeyvals::const_iterator kv_it = 
  123.             s_FindKeyvalueByKey(*key_it, keyvals);
  124.         if (kv_it == keyvals.end())
  125.             ThrowUnassigned(1);
  126.         kvp = *kv_it;
  127.     }
  128.     return *kvp;
  129. }
  130. void CKeyValue::GetAllKeys(TKeyList& key_list, const string& key_prefix, const string& delim ) const
  131. {
  132.     if (CanGetKey()  &&  CanGetVal()) {
  133.         string my_key = GetKey();
  134.         if ( ! key_prefix.empty()) { // don't put a delimiter in front by itself.
  135.             my_key = key_prefix + delim + my_key;
  136.         }
  137.         if (GetVal().IsStr()) {
  138.             key_list.push_back(my_key);
  139.         } else if (GetVal().IsKeyvals()) {
  140.             ITERATE(TVal::TKeyvals, kv_it, GetVal().GetKeyvals()) {
  141.                 (*kv_it)->GetAllKeys(key_list, my_key, delim);
  142.             }
  143.         }
  144.     }
  145. }
  146. // Mutator (Set) methods
  147. CKeyValue& CKeyValue::s_AddKey(const string & key, TVal::TKeyvals& keyvals)
  148. {
  149.     _ASSERT(! key.empty());
  150.     TVal::TKeyvals::iterator kv_it =
  151.         s_FindKeyvalueByKey(key, keyvals);
  152.     if (kv_it == keyvals.end()) {   // key not found, add it.
  153.         CRef<CKeyValue> kv( new CKeyValue(key) );
  154.         keyvals.push_back(kv);
  155.         return *kv;
  156.     }
  157.     //  found.  Just return it since no value to set.
  158.     return **kv_it;
  159. }
  160. CKeyValue& CKeyValue::AddKey(const string& key, const string& delim)
  161. {
  162.     _ASSERT(delim.size() == 1);
  163.     // Split the key.
  164.     list<string> keys;
  165.     NStr::Split(key, delim, keys);
  166.     _ASSERT (! keys.empty());
  167.     
  168.     CRef<CKeyValue> kvp(this);    
  169.     ITERATE( list<string>, key_it, keys) {
  170.         kvp = & s_AddKey(*key_it, kvp->SetVal().SetKeyvals());
  171.     }
  172.     return *kvp;
  173. }
  174. // delete the keyval within this CKeyValue that has a particular key.
  175. // return true if key exists, false otherwise.
  176. bool CKeyValue::DelKeyval(const string& key, const string& delim)
  177. {
  178.     // If there is no list of Keyvals here, there is nothing to delete.
  179.     if ( ! GetVal().IsKeyvals()) {
  180.         return false;
  181.     }
  182.     
  183.     // Split the key into the part before the first delimiter and the part after.
  184.     string key1, key2;
  185.     NStr::SplitInTwo(key, delim, key1, key2);
  186.     _ASSERT( ! key1.empty()); // no empty key parts.
  187.     
  188.     TVal::TKeyvals& keyvals = SetVal().SetKeyvals();
  189.     TVal::TKeyvals::iterator kv_it =
  190.         s_FindKeyvalueByKey(key1, keyvals);
  191.     if (kv_it == keyvals.end()) { // key not found, nothing to delete.
  192.         return false;
  193.     }
  194.     if (key2.empty()) { // here is what we were looking for.
  195.         keyvals.erase(kv_it);
  196.         return true;
  197.     }
  198.     
  199.     // recurse with the rest of the key on the found CKeyValue
  200.     if ((*kv_it)->DelKeyval(key2, delim)) {
  201.         // found and deleted. Now, is *kv_it itself empty?
  202.         if ((*kv_it)->GetVal().GetKeyvals().empty()) {
  203.             keyvals.erase(kv_it);
  204.         }
  205.         return true;
  206.     }
  207.     return false;
  208. }
  209. END_objects_SCOPE // namespace ncbi::objects::
  210. END_NCBI_SCOPE
  211. /*
  212. * ===========================================================================
  213. *
  214. * $Log: KeyValue.cpp,v $
  215. * Revision 1000.2  2004/06/01 20:42:51  gouriano
  216. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  217. *
  218. * Revision 1.4  2004/05/21 22:27:39  gorelenk
  219. * Added PCH ncbi_pch.hpp
  220. *
  221. * Revision 1.3  2004/04/20 14:06:39  rsmith
  222. * add GetAllKeys method.
  223. *
  224. * Revision 1.2  2003/11/21 12:49:12  rsmith
  225. * Add ability to delete values by key.
  226. *
  227. * Revision 1.1  2003/10/10 17:43:04  rsmith
  228. * moved from gui/plugin to gui/config
  229. *
  230. * Revision 1.3  2003/08/19 18:09:04  rsmith
  231. * add delim argument to AddKey and AddKeyString.
  232. *
  233. * Revision 1.2  2003/08/13 20:18:53  rsmith
  234. * Merge two KeyValue objects method.
  235. *
  236. * Revision 1.1  2003/08/05 17:35:59  rsmith
  237. * Classes to allow saving of plugin's configuration values as ASN.1.
  238. *
  239. *
  240. * ===========================================================================
  241. */
  242. /* Original file checksum: lines: 64, chars: 1874, CRC32: 5a5b30be */