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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: User_object.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:32:32  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: User_object.cpp,v 1000.4 2004/06/01 19:32:32 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:  .......
  35.  *
  36.  * File Description:
  37.  *   .......
  38.  *
  39.  * Remark:
  40.  *   This code was originally generated by application DATATOOL
  41.  *   using specifications from the ASN data definition file
  42.  *   'general.asn'.
  43.  */
  44. // standard includes
  45. // generated includes
  46. #include <ncbi_pch.hpp>
  47. #include <objects/general/User_object.hpp>
  48. #include <objects/general/User_field.hpp>
  49. #include <objects/general/Object_id.hpp>
  50. #include <corelib/ncbiexpt.hpp>
  51. // generated classes
  52. BEGIN_NCBI_SCOPE
  53. BEGIN_objects_SCOPE // namespace ncbi::objects::
  54. // destructor
  55. CUser_object::~CUser_object(void)
  56. {
  57. }
  58. //
  59. // retrieve a named field.  The named field can recurse, depending
  60. // on a set of user-defined delimiters
  61. //
  62. const CUser_field& CUser_object::GetField(const string& str,
  63.                                           const string& delim) const
  64. {
  65.     list<string> toks;
  66.     NStr::Split(str, delim, toks);
  67.     CConstRef<CUser_object> obj_ref(this);
  68.     CConstRef<CUser_field>  field_ref;
  69.     ITERATE(list<string>, iter, toks) {
  70.         if (obj_ref) {
  71.             ITERATE(TData, field_iter, obj_ref->GetData()) {
  72.                 const CUser_field& field = **field_iter;
  73.                 if (field.IsSetLabel()  &&  field.GetLabel().IsStr()  &&
  74.                     field.GetLabel().GetStr() == *iter) {
  75.                     field_ref.Reset(&field);
  76.                     obj_ref.Reset();
  77.                     break;
  78.                 }
  79.             }
  80.         } else if (field_ref) {
  81.             switch (field_ref->GetData().Which()) {
  82.             case CUser_field::TData::e_Object:
  83.                 break;
  84.             case CUser_field::TData::e_Objects:
  85.                 break;
  86.             case CUser_field::TData::e_Fields:
  87.                 break;
  88.             default:
  89.                 NCBI_THROW(CException, eUnknown,
  90.                     "illegal recursion");
  91.             }
  92.         }
  93.     }
  94.     if ( field_ref ) {
  95.         return *field_ref;
  96.     }
  97.     NCBI_THROW(CException, eUnknown,
  98.         "field not found");
  99. }
  100. bool CUser_object::HasField(const string& str,
  101.                             const string& delim) const
  102. {
  103.     list<string> toks;
  104.     NStr::Split(str, delim, toks);
  105.     CConstRef<CUser_object> obj_ref(this);
  106.     CConstRef<CUser_field>  field_ref;
  107.     ITERATE(list<string>, iter, toks) {
  108.         if (obj_ref) {
  109.             ITERATE(TData, field_iter, obj_ref->GetData()) {
  110.                 const CUser_field& field = **field_iter;
  111.                 if (field.IsSetLabel()  &&  field.GetLabel().IsStr()  &&
  112.                     field.GetLabel().GetStr() == *iter) {
  113.                     field_ref.Reset(&field);
  114.                     obj_ref.Reset();
  115.                     break;
  116.                 }
  117.             }
  118.         } else if (field_ref) {
  119.             switch (field_ref->GetData().Which()) {
  120.             case CUser_field::TData::e_Object:
  121.                 break;
  122.             case CUser_field::TData::e_Objects:
  123.                 break;
  124.             case CUser_field::TData::e_Fields:
  125.                 break;
  126.             default:
  127.                 return false;
  128.             }
  129.         }
  130.     }
  131.     if ( field_ref ) {
  132.         return true;
  133.     }
  134.     return false;
  135. }
  136. //
  137. // retrieve a named field.  The named field can recurse, depending
  138. // on a set of user-defined delimiters
  139. //
  140. CUser_field& CUser_object::SetField(const string& str,
  141.                                     const string& delim)
  142. {
  143.     list<string> toks;
  144.     NStr::Split(str, delim, toks);
  145.     CRef<CUser_object> obj_ref(this);
  146.     CRef<CUser_field>  field_ref;
  147.     ITERATE(list<string>, iter, toks) {
  148.         // recurse - make our field an object
  149.         if (field_ref) {
  150.             obj_ref.Reset(&field_ref->SetData().SetObject());
  151.         }
  152.         // find the named field at this object's level
  153.         NON_CONST_ITERATE(TData, field_iter, obj_ref->SetData()) {
  154.             CUser_field& field = **field_iter;
  155.             if (field.IsSetLabel()  &&  field.GetLabel().IsStr()  &&
  156.                 field.GetLabel().GetStr() == *iter) {
  157.                 field_ref.Reset(&field);
  158.                 break;
  159.             }
  160.         }
  161.         // if we didn't find it, add a new field
  162.         if ( !field_ref ) {
  163.             field_ref.Reset(new CUser_field());
  164.             field_ref->SetLabel().SetStr(*iter);
  165.             obj_ref->SetData().push_back(field_ref);
  166.         }
  167.     }
  168.     return *field_ref;
  169. }
  170. // add a data field to the user object that holds a given value
  171. CUser_object& CUser_object::AddField(const string& label,
  172.                                      const string& value)
  173. {
  174.     CRef<CUser_field> field(new CUser_field());
  175.     field->SetLabel().SetStr(label);
  176.     field->SetData().SetStr(value);
  177.     SetData().push_back(field);
  178.     return *this;
  179. }
  180. CUser_object& CUser_object::AddField(const string& label,
  181.                                      int           value)
  182. {
  183.     CRef<CUser_field> field(new CUser_field());
  184.     field->SetLabel().SetStr(label);
  185.     field->SetData().SetInt(value);
  186.     SetData().push_back(field);
  187.     return *this;
  188. }
  189. CUser_object& CUser_object::AddField(const string& label,
  190.                                      double        value)
  191. {
  192.     CRef<CUser_field> field(new CUser_field());
  193.     field->SetLabel().SetStr(label);
  194.     field->SetData().SetReal(value);
  195.     SetData().push_back(field);
  196.     return *this;
  197. }
  198. CUser_object& CUser_object::AddField(const string& label,
  199.                                      bool          value)
  200. {
  201.     CRef<CUser_field> field(new CUser_field());
  202.     field->SetLabel().SetStr(label);
  203.     field->SetData().SetBool(value);
  204.     SetData().push_back(field);
  205.     return *this;
  206. }
  207. CUser_object& CUser_object::AddField(const string& label,
  208.                                      CUser_object& object)
  209. {
  210.     CRef<CUser_field> field(new CUser_field());
  211.     field->SetLabel().SetStr(label);
  212.     field->SetData().SetObject(object);
  213.     SetData().push_back(field);
  214.     return *this;
  215. }
  216. CUser_object& CUser_object::AddField(const string& label,
  217.                                      const vector<string>& value)
  218. {
  219.     CRef<CUser_field> field(new CUser_field());
  220.     field->SetLabel().SetStr(label);
  221.     field->SetNum(value.size());
  222.     ITERATE (vector<string>, iter, value) {
  223.         field->SetData().SetStrs().push_back(*iter);
  224.     }
  225.     SetData().push_back(field);
  226.     return *this;
  227. }
  228. CUser_object& CUser_object::AddField(const string& label,
  229.                                      const vector<int>&    value)
  230. {
  231.     CRef<CUser_field> field(new CUser_field());
  232.     field->SetLabel().SetStr(label);
  233.     field->SetNum(value.size());
  234.     ITERATE (vector<int>, iter, value) {
  235.         field->SetData().SetInts().push_back(*iter);
  236.     }
  237.     SetData().push_back(field);
  238.     return *this;
  239. }
  240. CUser_object& CUser_object::AddField(const string& label,
  241.                                      const vector<double>& value)
  242. {
  243.     CRef<CUser_field> field(new CUser_field());
  244.     field->SetLabel().SetStr(label);
  245.     field->SetNum(value.size());
  246.     ITERATE (vector<double>, iter, value) {
  247.         field->SetData().SetReals().push_back(*iter);
  248.     }
  249.     SetData().push_back(field);
  250.     return *this;
  251. }
  252. CUser_object& CUser_object::AddField(const string& label,
  253.                                      const list< CRef<CUser_object> >& objects)
  254. {
  255.     CRef<CUser_field> field(new CUser_field());
  256.     field->SetLabel().SetStr(label);
  257.     field->SetNum(objects.size());
  258.     field->SetData().SetObjects() = objects;
  259.     SetData().push_back(field);
  260.     return *this;
  261. }
  262. CUser_object& CUser_object::AddField(const string& label,
  263.                                      const list< CRef<CUser_field> >& objects)
  264. {
  265.     CRef<CUser_field> field(new CUser_field());
  266.     field->SetLabel().SetStr(label);
  267.     field->SetNum(objects.size());
  268.     field->SetData().SetFields() = objects;
  269.     SetData().push_back(field);
  270.     return *this;
  271. }
  272. // static consts here allow us to use reference counting
  273. static const string s_ncbi("NCBI");
  274. static const string s_expres("experimental_results");
  275. static const string s_exp("experiment");
  276. static const string s_sage("SAGE");
  277. static const string s_tag("tag");
  278. static const string s_count("count");
  279. // accessors: classify a given user object
  280. CUser_object::ECategory CUser_object::GetCategory(void) const
  281. {
  282.     if (!IsSetClass()  ||
  283.         GetClass() != s_ncbi) {
  284.         // we fail to recognize non-NCBI classes of user-objects
  285.         return eCategory_Unknown;
  286.     }
  287.     //
  288.     // experimental results
  289.     //
  290.     if (GetType().IsStr()  &&
  291.         NStr::CompareNocase(GetType().GetStr(), s_expres) == 0  &&
  292.         GetData().size() == 1) {
  293.         ITERATE (CUser_object::TData, iter, GetData()) {
  294.             const CUser_field& field       = **iter;
  295.             const CUser_field::TData& data = field.GetData();
  296.             if (data.Which() != CUser_field::TData::e_Object  ||
  297.                 !field.IsSetLabel()  ||
  298.                 !field.GetLabel().IsStr()  ||
  299.                 NStr::CompareNocase(field.GetLabel().GetStr(),
  300.                                     s_exp) != 0) {
  301.                 // poorly formed experiment spec
  302.                 return eCategory_Unknown;
  303.             }
  304.         }
  305.         return eCategory_Experiment;
  306.     }
  307.     //
  308.     // unrecognized - catch-all
  309.     //
  310.     return eCategory_Unknown;
  311. }
  312. // sub-category accessors:
  313. CUser_object::EExperiment CUser_object::GetExperimentType(void) const
  314. {
  315.     // check to see if we have an experiment
  316.     if ( GetCategory() != eCategory_Experiment) {
  317.         return eExperiment_Unknown;
  318.     }
  319.     // we do - so we have one nested user object that contains the
  320.     // specification of the experimental data
  321.     const CUser_field& field = *GetData().front();
  322.     const CUser_object& obj = field.GetData().GetObject();
  323.     if (obj.GetType().IsStr()  &&
  324.         NStr::CompareNocase(obj.GetType().GetStr(), s_sage) == 0) {
  325.         return eExperiment_Sage;
  326.     }
  327.     //
  328.     // catch-all
  329.     //
  330.     return eExperiment_Unknown;
  331. }
  332. // sub-category accessors:
  333. const CUser_object& CUser_object::GetExperiment(void) const
  334. {
  335.     switch (GetExperimentType()) {
  336.     case eExperiment_Sage:
  337.         // we have one nested user object that contains the
  338.         // specification of the experimental data
  339.         return GetData().front()->GetData().GetObject();
  340.         break;
  341.     case eExperiment_Unknown:
  342.     default:
  343.         return *this;
  344.     }
  345. }
  346. //
  347. // format the type specification fo a given user object
  348. //
  349. static string s_GetUserObjectType(const CUser_object& obj)
  350. {
  351.     switch (obj.GetCategory()) {
  352.     case CUser_object::eCategory_Experiment:
  353.         switch (obj.GetExperimentType()) {
  354.         case CUser_object::eExperiment_Sage:
  355.             return "SAGE";
  356.         case CUser_object::eExperiment_Unknown:
  357.         default:
  358.             return "Experiment";
  359.         }
  360.         break;
  361.     case CUser_object::eCategory_Unknown:
  362.     default:
  363.         break;
  364.     }
  365.     return "User";
  366. }
  367. static string s_GetUserObjectContent(const CUser_object& obj)
  368. {
  369.     switch (obj.GetCategory()) {
  370.     case CUser_object::eCategory_Experiment:
  371.         switch (obj.GetExperimentType()) {
  372.         case CUser_object::eExperiment_Sage:
  373.             {{
  374.                 string label;
  375.                 const CUser_object& nested_obj =
  376.                     obj.GetData().front()->GetData().GetObject();
  377.                 // grab the tag and count fields
  378.                 const CUser_field* tag = NULL;
  379.                 const CUser_field* count = NULL;
  380.                 ITERATE (CUser_object::TData, iter, nested_obj.GetData()) {
  381.                     const CUser_field& field = **iter;
  382.                     if (!field.GetLabel().IsStr()) {
  383.                         continue;
  384.                     }
  385.                     const string& label = field.GetLabel().GetStr();
  386.                     if (NStr::CompareNocase(label, s_tag) == 0) {
  387.                         tag = &field;
  388.                     } else if (NStr::CompareNocase(label, s_count) == 0) {
  389.                         count = &field;
  390.                     }
  391.                 }
  392.                 if (tag  &&  tag->GetData().IsStr()) {
  393.                     if ( !label.empty() ) {
  394.                         label += " ";
  395.                     }
  396.                     label += s_tag + "=" + tag->GetData().GetStr();
  397.                 }
  398.                 if (count  &&  count->GetData().IsInt()) {
  399.                     if ( !label.empty() ) {
  400.                         label += " ";
  401.                     }
  402.                     label += s_count + "=" +
  403.                         NStr::IntToString(count->GetData().GetInt());
  404.                 }
  405.                 return label;
  406.             }}
  407.         case CUser_object::eExperiment_Unknown:
  408.         default:
  409.             return "[experiment]";
  410.             break;
  411.         }
  412.         break;
  413.     case CUser_object::eCategory_Unknown:
  414.     default:
  415.         return "[User]";
  416.         break;
  417.     }
  418. }
  419. //
  420. // append a formatted string to a label describing this object
  421. //
  422. void CUser_object::GetLabel(string* label, ELabelContent mode) const
  423. {
  424.     // Check the label is not null
  425.     if (!label) {
  426.         return;
  427.     }
  428.     switch (mode) {
  429.     case eType:
  430.         *label += s_GetUserObjectType(*this);
  431.         break;
  432.     case eContent:
  433.         *label += s_GetUserObjectContent(*this);
  434.         break;
  435.     case eBoth:
  436.         *label += s_GetUserObjectType(*this) + ": " +
  437.             s_GetUserObjectContent(*this);
  438.         break;
  439.     }
  440. }
  441. CUser_object& CUser_object::SetCategory(ECategory category)
  442. {
  443.     Reset();
  444.     SetClass(s_ncbi);
  445.     switch (category) {
  446.     case eCategory_Experiment:
  447.         SetType().SetStr(s_expres);
  448.         {{
  449.             CRef<CUser_object> subobj(new CUser_object());
  450.             AddField(s_exp, *subobj);
  451.             SetClass(s_ncbi);
  452.             return *subobj;
  453.         }}
  454.         break;
  455.     case eCategory_Unknown:
  456.     default:
  457.         break;
  458.     }
  459.     return *this;
  460. }
  461. CUser_object& CUser_object::SetExperiment(EExperiment category)
  462. {
  463.     Reset();
  464.     SetClass(s_ncbi);
  465.     switch (category) {
  466.     case eExperiment_Sage:
  467.         SetType().SetStr(s_sage);
  468.         break;
  469.     case eExperiment_Unknown:
  470.     default:
  471.         break;
  472.     }
  473.     return *this;
  474. }
  475. END_objects_SCOPE // namespace ncbi::objects::
  476. END_NCBI_SCOPE
  477. /*
  478. * ===========================================================================
  479. *
  480. * $Log: User_object.cpp,v $
  481. * Revision 1000.4  2004/06/01 19:32:32  gouriano
  482. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.7
  483. *
  484. * Revision 6.7  2004/05/19 17:21:39  gorelenk
  485. * Added include of PCH - ncbi_pch.hpp
  486. *
  487. * Revision 6.6  2004/01/20 20:38:09  vasilche
  488. * Added required includes.
  489. *
  490. * Revision 6.5  2003/11/21 14:45:01  grichenk
  491. * Replaced runtime_error with CException
  492. *
  493. * Revision 6.4  2003/11/14 16:12:45  shomrat
  494. * fixed GetLabel so it will append to string and not replace it
  495. *
  496. * Revision 6.3  2003/09/29 15:57:15  dicuccio
  497. * Fleshed out CUser_object API.  Added function to retrieve fields based on
  498. * delimited keys.  Added functions to format a CUser_object as a known category
  499. * (the only supported category is experiment)
  500. *
  501. * Revision 6.2  2003/06/19 01:05:51  dicuccio
  502. * Added interfaces for adding key/value items to a user object as a nested
  503. * CUser_field object
  504. *
  505. * Revision 6.1  2002/10/03 17:02:45  clausen
  506. * Added GetLabel()
  507. *
  508. *
  509. * ===========================================================================
  510. */
  511. /* Original file checksum: lines: 64, chars: 1893, CRC32: f7a70d1d */