NCBI C++ ToolKit
hooks_commented.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: hooks_commented.cpp 93095 2021-03-04 15:36:47Z grichenk $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: David McElhany
27 *
28 * File Description:
29 * A commented demo program to illustrate how to use a serial hook.
30 *
31 * ===========================================================================
32 */
33 
34 #include <ncbi_pch.hpp>
35 #include <serial/objistr.hpp>
37 
40 
41 
42 // This class implements a read hook for class members.
43 //
44 // A read hook is created by passing a new instance of this class to a
45 // "set hook" method. Hooks may be created as global or local. Global hooks
46 // apply to all streams, whereas local hooks are associated with a specific
47 // stream. Thus, the "set hook" methods for creating class member read hooks
48 // are:
49 // SetGlobalReadHook()
50 // SetLocalReadHook()
51 //
52 // This class must override the virtual method ReadClassMember(). See the
53 // comment for the ReadClassMember() method below for more details.
54 //
55 // In principle, multiple instances of this hook class could be used to provide
56 // the same hook processing for more than one entity. However, it is probably
57 // best to create a separate class for each "thing" you want to hook and
58 // process.
59 //
60 // You should adopt a meaningful naming convention for your hook classes.
61 // In this example, the convention is C<mode><context>Hook_<object>__<member>
62 // where: <mode>=(Read|Write|Copy|Skip)
63 // <context>=(Obj|CM|CV) -- object, class member, or choice variant
64 // and hyphens in ASN.1 object types are replaced with underscores.
65 //
66 // Note: Since this is a read hook, ReadClassMember() will only be called when
67 // reading from the stream. If the stream is being skipped, ReadClassMember()
68 // will not be called. If you want to use a hook to read a specific type of
69 // class member while skipping everything else, use a skip hook and call
70 // DefaultRead() from within the SkipClassMember() method.
71 //
72 // Note: This example is a read hook, which means that the input stream is
73 // being read when the hook is called. Hooks for other processing modes
74 // (Write, Skip, and Copy) are similarly created by inheriting from the
75 // respecitive base classes. It is also a ClassMember hook. Hooks for
76 // other structural contexts (Object and ChoiceVariant) a similarly derived
77 // from the appropriate base.
78 
80 {
81 public:
82  // Implement the hook method.
83  //
84  // Once the read hook has been set, ReadClassMember() will be called
85  // whenever the specified class member is encountered while
86  // reading a hooked input stream. Without the hook, the encountered
87  // class member would have been automatically read. With the hook, it is
88  // now the responsibility of the ReadClassMember() method to remove the
89  // class member from the input stream and process it as desired. It can
90  // either read it or skip it to remove it from the stream. This is
91  // easily done by calling DefaultRead() or DefaultSkip() from within
92  // ReadClassMember(). Subsequent processing is up to the application.
94  const CObjectInfoMI& passed_info)
95  {
96  // Perform any pre-read processing here.
97  //cout << "In ReadClassMember() hook, before reading." << endl;
98 
99  // You must call DefaultRead() (or perform an equivalent operation)
100  // if you want the object to be read into memory. You could also
101  // call DefaultSkip() if you wanted to skip the hooked object while
102  // reading everything else.
103  DefaultRead(in, passed_info);
104 
105 #if 0
106 // call DefaultRead to read member data, or DefaultSkip to skip it
107  DefaultSkip(in, passed_info);
108 
109 // get information about the member
110  // typeinfo of the parent class
111  CObjectTypeInfo oti = passed_info.GetClassType();
112  // typeinfo and data of the parent class
113  const CObjectInfo& oi = passed_info.GetClassObject();
114  // typeinfo of the member
115  CObjectTypeInfo omti = passed_info.GetMemberType();
116  // typeinfo and data of the member
117  CObjectInfo om = passed_info.GetMember();
118  // index of the member in parent class
119  TMemberIndex mi = passed_info.GetMemberIndex();
120  // information about the member, including its name
121  const CMemberInfo* minfo = passed_info.GetMemberInfo();
122 #endif
123 
124  // Perform any post-read processing here. Once the object has been
125  // read, its data can be used for processing.
126  CNcbiOstrstream oss;
127  oss << MSerial_AsnText << passed_info.GetClassObject();
128  string s = CNcbiOstrstreamToString(oss);
129  cout << s << endl;
130  }
131 };
132 
133 
134 int main(int argc, char** argv)
135 {
136  // Create some ASN.1 data that can be parsed by this code sample.
137  const string asn = "Date-std ::= { year 1998, month 1, day 2, season \"winter\" }";
138 
139  // Setup an input stream, based on the sample ASN.1.
140  CNcbiIstrstream iss(asn);
141  unique_ptr<CObjectIStream> in(CObjectIStream::Open(eSerial_AsnText, iss));
142 
143  ////////////////////////////////////////////////////
144  // Create a hook for the 'year' class member of Date-std objects.
145  // The year class member was aribtrarily chosen to illustrate the
146  // use of hooks - many other entities would work equally well.
147 
148  // Get data structures that model the type information for Date-std
149  // objects and their 'year' class members.
150  // The type information will be used to recognize and forward 'year'
151  // class members of Date-std objects found in the stream to the hook.
152  CObjectTypeInfo stdInfo = CType<CDate_std>();
153  CObjectTypeInfoMI memberInfo = stdInfo.FindMember("year");
154 
155  // Set a local hook for Date-std 'year' class members. This involves
156  // creating an instance of the hook class and passing that hook to the
157  // "set hook" method, which registers the hook to be called when a hooked
158  // type is encountered in the stream.
159  memberInfo.SetLocalReadHook(*in, new CReadCMHook_Date_std__year());
160 
161  // Read from the input stream, storing data in the object. At this point,
162  // the hook is in place so simply reading from the input stream will
163  // cause the hook to be triggered whenever the 'year' class member is
164  // encountered.
165  in->Read(stdInfo);
166 
167  return 0;
168 }
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
CObjectIStream –.
Definition: objistr.hpp:93
CObjectInfoMI –.
Definition: objectiter.hpp:432
CObjectInfo –.
Definition: objectinfo.hpp:597
CObjectTypeInfoMI –.
Definition: objectiter.hpp:246
CObjectTypeInfo –.
Definition: objectinfo.hpp:94
virtual void ReadClassMember(CObjectIStream &in, const CObjectInfoMI &passed_info)
This method will be called at approriate time when the object of requested type is to be read.
Read hook for data member of a containing object (eg, SEQUENCE)
Definition: objhook.hpp:78
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:230
#define MSerial_AsnText
I/O stream manipulators –.
Definition: serialbase.hpp:696
@ eSerial_AsnText
ASN.1 text.
Definition: serialdef.hpp:73
void DefaultRead(CObjectIStream &in, const CObjectInfoMI &object)
Definition: objhook.cpp:183
TMemberIndex GetMemberIndex(void) const
Get index of the member in the class.
const CMemberInfo * GetMemberInfo(void) const
CObjectTypeInfo GetMemberType(void) const
Get data type information.
CMemberIterator FindMember(const string &memberName) const
Find class member by its name.
CObjectInfo GetMember(void) const
Get class member data.
const CObjectInfo & GetClassObject(void) const
Get containing class data.
void DefaultSkip(CObjectIStream &in, const CObjectTypeInfoMI &object)
Definition: objhook.cpp:195
CObjectTypeInfo GetClassType(void) const
Get containing class type.
static CObjectIStream * Open(ESerialDataFormat format, CNcbiIstream &inStream, bool deleteInStream)
Create serial object reader and attach it to an input stream.
Definition: objistr.cpp:195
void SetLocalReadHook(CObjectIStream &stream, CReadClassMemberHook *hook) const
Definition: objectiter.cpp:96
int main(int argc, char **argv)
USING_SCOPE(ncbi::objects)
USING_NCBI_SCOPE
std::istream & in(std::istream &in_, double &x_)
CRef< objects::CObjectManager > om
Modified on Sun May 05 05:23:21 2024 by modify_doxy.py rev. 669887