first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / octopi / library / octopus / infoton.h
1 #ifndef INFOTON_CLASS
2 #define INFOTON_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : infoton                                                           *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/contracts.h>
19 #include <structures/string_array.h>
20
21 namespace octopi {
22
23 //! An infoton is an individual request parcel with accompanying information.
24 /*!
25   This is the unit of data exchange in the octopus scheme.
26 */
27
28 class infoton
29 : public virtual basis::packable,
30   public virtual basis::clonable,
31   public virtual basis::text_formable
32 {
33 public:
34   infoton(const structures::string_array &classifier);
35     //!< creates an infoton with the "classifier".
36     /*!< keep in mind that although anything can be passed in here, the
37     consistency of one's collection of octopi depends on a regular
38     classification scheme.  it is recommended that the "classifier" be
39     effectively constant.  also, classifiers that begin with the octothorpe
40     (aka the pound sign '#') are reserved for octopus internal usage. */
41
42   // takes care of the most common cases of 1, 2 & 3 level classifiers.
43   infoton(const basis::astring &class_1);
44   infoton(const basis::astring &class_1, const basis::astring &class_2);
45   infoton(const basis::astring &class_1, const basis::astring &class_2, const basis::astring &cl_3);
46
47   infoton(const infoton &to_copy);
48     //!< copies only the base class portion of the infoton.
49     /*!< clone() is the proper method for copying an instantiated infoton--
50     this constructor only supports copying the base's information. */
51
52   virtual ~infoton();
53
54   DEFINE_CLASS_NAME("infoton");
55
56   infoton &operator =(const infoton &to_copy);
57     //!< assigns only the base class portion.
58     /*!< clone() is the proper method for copying an instantiated infoton. */
59
60   const structures::string_array &classifier() const;
61     //!< this array of strings is the "name" for this infoton.
62     /*!< the naming scheme for an infoton hierarchically and uniquely
63     identifies the exact type of this object.  the last string (at the end()
64     index) is the most specific name for this object, while the preceding
65     names describe the object's membership in groups.  the outermost group
66     name is at the zeroth index in the array.  a classifier can have one or
67     more elements. */
68
69   void set_classifier(const structures::string_array &new_classifier);
70     //!< sets the infoton's classifier to the "new_classifier".
71     /*!< do not do this unless you know what you're doing; changing the
72     classifier may keep an infoton from being recognized properly. */
73
74   // these are also dangerous if you're not careful; they mimic the
75   // string constructors.
76   void set_classifier(const basis::astring &class_1);
77   void set_classifier(const basis::astring &class_1, const basis::astring &class_2);
78   void set_classifier(const basis::astring &class_1, const basis::astring &class_2,
79           const basis::astring &cl_3);
80
81   bool check_classifier(const basis::astring &class_name, const basis::astring &caller);
82     //!< checks that the classifier seems valid.
83     /*!< the "class_name" and "caller" should be set to the location where
84     the check is being done. */
85
86   virtual void pack(basis::byte_array &packed_form) const = 0;
87     //!< stuffs the data in the infoton into the "packed_form".
88     /*!< the derived method must know how to pack this particular type
89     of infoton. */
90   virtual bool unpack(basis::byte_array &packed_form) = 0;
91     //!< restores an infoton from a packed form.
92     /*!< the unpack() method will be utilized by tentacles that support
93     this type of object. */
94
95   virtual void text_form(basis::base_string &state_fill) const = 0;
96     //!< requires derived infotons to be able to show their state as a string.
97
98   virtual clonable *clone() const = 0;
99     //!< must be provided to allow creation of a copy of this object.
100
101   virtual int packed_size() const = 0;
102     //!< reports how large the infoton will be when packed.
103     /*!< must be overridden by derived classes to provide a guess at how
104     large the packed size of this will be.  this is important to estimate
105     accurately. */
106
107   //! local version just makes text_form() more functional.
108   virtual basis::astring text_form() const { basis::astring fill; text_form(fill); return fill; }
109
110   //////////////
111
112   // This defines the wire format for a flattened infoton.  It is in essence
113   // a packet header format which all infotons must adhere to to ensure that
114   // they can be successfully unflattened when appropriate item managers are
115   // available.
116   static void fast_pack(basis::byte_array &packed_form, const infoton &to_pack);
117     //!< flattens an infoton "to_pack" into the byte array "packed_form".
118
119   static bool fast_unpack(basis::byte_array &packed_form, structures::string_array &classifier,
120           basis::byte_array &info);
121     //!< undoes a previous fast_pack to restore the previous information.
122     /*!< extracts the data from a packed infoton in "packed_form" into the
123     "classifier" and "info" that are contained therein. */
124
125   static bool test_fast_unpack(const basis::byte_array &packed_form,
126           int &packed_length);
127     //!< checks that the "packed_form" could hold a valid packed infoton.
128     /*!< tests that the smallest prefix of the "packed_form" looks like an
129     appropriate packed classifier and packet length.  the "packed_length"
130     is set to the length found in the packet.  note that the byte array
131     does not need to contain the complete packed infoton yet; just the first
132     portion where the header info is located must be present.  this method
133     does not disturb the data in the packed array. */
134
135   static int fast_pack_overhead(const structures::string_array &classifier);
136     //!< reports how much space is needed to pack the "classifier".
137     /*!< returns the overhead in bytes that will be added to an infoton's
138     packed size when it is packed with fast_pack().  the "classifier" is the
139     name of the infoton in question and must be accurate or the overhead will
140     not be calculated properly. */
141
142 private:
143   structures::string_array *_classifier;  //!< our classifier held.
144 };
145
146 //////////////
147
148 //! a templated method for cloning any infoton with a valid copy constructor.
149
150 template <class contents>
151 basis::clonable *cloner(const contents &this_obj) { return new contents(this_obj); }
152
153 } //namespace.
154
155 #endif
156