1 #ifndef CONNECT_SERVICES__COMPOUND_ID__HPP
2 #define CONNECT_SERVICES__COMPOUND_ID__HPP
3 
4 /*  $Id: compound_id.hpp 575325 2018-11-27 18:22:00Z ucko $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors:  Dmitry Kazimirov
30  *
31  * File Description:
32  *   Compound IDs are Base64-encoded string that contain application-specific
33  *   information to identify and/or locate objects.
34  *
35  */
36 
37 /// @file compound_id.hpp
38 /// Declarations of CCompoundIDPool, CCompoundID, and CCompoundIDField.
39 
40 #include "netcomponent.hpp"
41 
42 BEGIN_NCBI_SCOPE
43 
44 struct SCompoundIDPoolImpl;     ///< @internal
45 struct SCompoundIDImpl;         ///< @internal
46 struct SCompoundIDFieldImpl;    ///< @internal
47 
48 
49 // Registered CompoundID Classes
50 enum ECompoundIDClass {
51     eCIC_GenericID,
52     eCIC_NetCacheBlobKey,
53     eCIC_NetScheduleJobKey,
54     eCIC_NetStorageObjectLocV1, ///< Old version of NetStorageObjectLoc
55     eCIC_NetStorageObjectLoc,
56 
57     eCIC_NumberOfClasses
58 };
59 
60 
61 // Compound ID Field Types
62 enum ECompoundIDFieldType {
63     eCIT_ID,            /* 64-bit natural number: counter, ID, size, offset   */
64     eCIT_Integer,       /* General-purpose 64-bit signed integer              */
65     eCIT_ServiceName,   /* LBSM service name                                  */
66     eCIT_DatabaseName,  /* Database name (NetSchedule queue, cache name, etc) */
67     eCIT_Timestamp,     /* POSIX time_t value (time in seconds since Epoch)   */
68     eCIT_Random,        /* 32-bit random integer                              */
69     eCIT_IPv4Address,   /* 32-bit IPv4 address                                */
70     eCIT_Host,          /* Host name or literal IPv4 or IPv6 address          */
71     eCIT_Port,          /* 16-bit port number                                 */
72     eCIT_IPv4SockAddr,  /* 32-bit IPv4 address followed by 16-bit port number */
73     eCIT_ObjectRef,     /* Object or resource: URI (URL, URN), OID, pathname  */
74     eCIT_String,        /* Arbitrary single-byte character string             */
75     eCIT_Boolean,       /* Boolean value                                      */
76     eCIT_Flags,         /* Combination of binary flags stored as a number     */
77     eCIT_Label,         /* Application-specific field prefix, tag, label      */
78     eCIT_Cue,           /* Application-specific numeric field prefix or tag   */
79     eCIT_SeqID,         /* Sequence identifier (string)                       */
80     eCIT_TaxID,         /* Taxon identifier (unsigned integer)                */
81     eCIT_NestedCID,     /* Nested CompoundID                                  */
82 
83     eCIT_NumberOfTypes  /* Must be the last element of the enumeration.       */
84 };
85 
86 
87 /// Exception class for use by CCompoundIDPool, CCompoundID, and
88 /// CCompoundIDField.
89 ///
90 class NCBI_XCONNECT_EXPORT CCompoundIDException : public CException
91 {
92 public:
93     enum EErrCode {
94         eInvalidType,       ///< Field type mismatch.
95         eIDTooLong,         ///< ID exceeds length restrictions.
96         eInvalidFormat,     ///< Format of the packed ID is not recognized.
97         eInvalidDumpSyntax, ///< Dump parsing error.
98     };
99     virtual const char* GetErrCodeString() const override;
100     NCBI_EXCEPTION_DEFAULT(CCompoundIDException, CException);
101 };
102 
103 class CCompoundID;
104 
105 /// Compound ID field -- an element of the compound ID that
106 /// has a type and a value.
107 ///
108 class NCBI_XCONNECT_EXPORT CCompoundIDField
109 {
110     NCBI_NET_COMPONENT(CompoundIDField);
111 
112     /// Return the type of this field.
113     ECompoundIDFieldType GetType();
114 
115     /// Return the next immediately adjacent field.
116     CCompoundIDField GetNextNeighbor();
117 
118     /// Return the next field of the same type.
119     CCompoundIDField GetNextHomogeneous();
120 
121     /// Remove this field from the compound ID that contains it.
122     /// This will cause the GetNext*() methods to always return NULL.
123     void Remove();
124 
125     /// Return the ID value that this field contains.
126     /// @throw CCompoundIDException if GetType() != eCIT_ID.
127     Uint8 GetID() const;
128 
129     /// Return the integer value that this field contains.
130     /// @throw CCompoundIDException if GetType() != eCIT_Integer.
131     Int8 GetInteger() const;
132 
133     /// Return the LBSM service name that this field contains.
134     /// @throw CCompoundIDException if GetType() != eCIT_ServiceName.
135     string GetServiceName() const;
136 
137     /// Return the database name that this field contains.
138     /// @throw CCompoundIDException if GetType() != eCIT_DatabaseName.
139     string GetDatabaseName() const;
140 
141     /// Return the UNIX timestamp that this field contains.
142     /// @throw CCompoundIDException if GetType() != eCIT_Timestamp.
143     Int8 GetTimestamp() const;
144 
145     /// Return the random number value that this field contains.
146     /// @throw CCompoundIDException if GetType() != eCIT_Random
147     Uint4 GetRandom() const;
148 
149     /// Return the 32-bit IP address that this field contains.
150     /// @throw CCompoundIDException if GetType() is neither
151     /// eCIT_IPv4Address nor eCIT_IPv4SockAddr.
152     Uint4 GetIPv4Address() const;
153 
154     /// Return the host name or address that this field contains.
155     /// @throw CCompoundIDException if GetType() != eCIT_Host.
156     string GetHost() const;
157 
158     /// Return the network port number that this field contains.
159     /// @throw CCompoundIDException if GetType() is neither
160     /// eCIT_Port nor eCIT_IPv4SockAddr.
161     Uint2 GetPort() const;
162 
163     /// Return the object or resource ID that this field contains.
164     /// @throw CCompoundIDException if GetType() != eCIT_ObjectRef.
165     string GetObjectRef() const;
166 
167     /// Return the string value that this field contains.
168     /// @throw CCompoundIDException if GetType() != eCIT_String.
169     string GetString() const;
170 
171     /// Return the Boolean value that this field contains.
172     /// @throw CCompoundIDException if GetType() != eCIT_Boolean.
173     bool GetBoolean() const;
174 
175     /// Return the combination of binary flags stored in this field.
176     /// @throw CCompoundIDException if GetType() != eCIT_Flags.
177     Uint8 GetFlags() const;
178 
179     /// Return the application-specific tag that this field contains.
180     /// @throw CCompoundIDException if GetType() != eCIT_Label.
181     string GetLabel() const;
182 
183     /// Return the application-specific numeric tag value
184     /// that this field contains.
185     /// @throw CCompoundIDException if GetType() != eCIT_Cue.
186     Uint8 GetCue() const;
187 
188     /// Return the Sequence ID that this field contains.
189     /// @throw CCompoundIDException if GetType() != eCIT_SeqID.
190     string GetSeqID() const;
191 
192     /// Return the Taxonomy ID that this field contains.
193     /// @throw CCompoundIDException if GetType() != eCIT_TaxID.
194     Uint8 GetTaxID() const;
195 
196     /// Return the nested compound ID that this field contains.
197     /// @throw CCompoundIDException if GetType() != eCIT_NestedCID.
198     const CCompoundID& GetNestedCID() const;
199 };
200 
201 
202 /// Base64-encoded ID string that contains extractable typed fields.
203 ///
204 class NCBI_XCONNECT_EXPORT CCompoundID
205 {
206     NCBI_NET_COMPONENT(CompoundID);
207 
208     /// One of the registered ID classes.
209     ECompoundIDClass GetClass() const;
210 
211     /// Return TRUE if this compound ID contains no fields.
212     bool IsEmpty() const;
213 
214     /// Return the number of fields this ID contains.
215     unsigned GetLength() const;
216 
217     /// Return the first field or NULL if this ID is empty.
218     CCompoundIDField GetFirstField();
219 
220     /// Return the first field of the specified type or NULL
221     /// if this compound ID contains no fields of such type.
222     CCompoundIDField GetFirst(ECompoundIDFieldType field_type);
223 
224     /// Append an eCIT_ID field at the end of this compound ID.
225     void AppendID(Uint8 id);
226 
227     /// Append an eCIT_Integer field at the end of this compound ID.
228     void AppendInteger(Int8 number);
229 
230     /// Append an eCIT_ServiceName field at the end of this compound ID.
231     void AppendServiceName(const string& service_name);
232 
233     /// Append an eCIT_DatabaseName field at the end of this compound ID.
234     void AppendDatabaseName(const string& db_name);
235 
236     /// Append an eCIT_Timestamp field at the end of this compound ID.
237     void AppendTimestamp(Int8 timestamp);
238 
239     /// Get the current time and append it as an eCIT_Timestamp field
240     /// at the end of this compound ID.
241     void AppendCurrentTime();
242 
243     /// Append an eCIT_Random field at the end of this compound ID.
244     void AppendRandom(Uint4 random_number);
245 
246     /// Generate a 32-bit pseudo-random number and append it as an
247     /// eCIT_Random field at the end of this compound ID.
248     void AppendRandom();
249 
250     /// Append an eCIT_IPv4Address field at the end of this compound ID.
251     void AppendIPv4Address(Uint4 ipv4_address);
252 
253     /// Append an eCIT_Host field at the end of this compound ID.
254     void AppendHost(const string& host);
255 
256     /// Append an eCIT_Port field at the end of this compound ID.
257     void AppendPort(Uint2 port_number);
258 
259     /// Append an eCIT_IPv4SockAddr field at the end of this compound ID.
260     void AppendIPv4SockAddr(Uint4 ipv4_address, Uint2 port_number);
261 
262     /// Append an eCIT_ObjectRef field at the end of this compound ID.
263     void AppendObjectRef(const string& loc);
264 
265     /// Append an eCIT_String field at the end of this compound ID.
266     void AppendString(const string& string_value);
267 
268     /// Append an eCIT_Boolean field at the end of this compound ID.
269     void AppendBoolean(bool boolean_value);
270 
271     /// Append an eCIT_Flags field at the end of this compound ID.
272     void AppendFlags(Uint8 flags);
273 
274     /// Append an eCIT_Label field at the end of this compound ID.
275     void AppendLabel(const string& tag);
276 
277     /// Append an eCIT_Cue field at the end of this compound ID.
278     void AppendCue(Uint8 tag);
279 
280     /// Append an eCIT_SeqID field at the end of this compound ID.
281     void AppendSeqID(const string& seq_id);
282 
283     /// Append an eCIT_TaxID field at the end of this compound ID.
284     void AppendTaxID(Uint8 tax_id);
285 
286     /// Append an eCIT_NestedCID field at the end of this compound ID.
287     void AppendNestedCID(const CCompoundID& cid);
288 
289     /// Get the field that was added last.
290     CCompoundIDField GetLastField();
291 
292     /// Pack the ID and return its string representation.
293     string ToString();
294 
295     /// Dump the contents of the ID in the human-readable format that
296     /// can also be parsed by CCompoundIDPool::FromDump().
297     string Dump();
298 };
299 
300 
301 /// Pool of recycled CCompoundID objects. On some systems, this pool
302 /// also contains the shared pseudo-random number generator used by
303 /// CCompoundID::AppendRandom().
304 ///
305 class NCBI_XCONNECT_EXPORT CCompoundIDPool
306 {
307     NCBI_NET_COMPONENT_IMPL(CompoundIDPool);
308 
309     /// Construct a new pool of CompoundID objects.
310     CCompoundIDPool();
311 
312     /// Create and return a new CCompoundID objects.
313     CCompoundID NewID(ECompoundIDClass new_id_class);
314 
315     /// Unpack the base64-encoded ID and return a CCompoundID
316     /// object for field extraction.
317     CCompoundID FromString(const string& cid);
318 
319     /// Restore the compound ID from its textual representation
320     /// created by CCompoundID::Dump().
321     CCompoundID FromDump(const string& cid_dump);
322 };
323 
324 
325 END_NCBI_SCOPE
326 
327 #endif  /* CONNECT_SERVICES__COMPOUND_ID__HPP */
328