00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef DCSWITCH_H
00016 #define DCSWITCH_H
00017
00018 #include "dcbase.h"
00019 #include "dcDeclaration.h"
00020 #include "dcPackerInterface.h"
00021
00022 class DCParameter;
00023 class HashGenerator;
00024 class DCField;
00025
00026
00027
00028
00029
00030
00031
00032
00033 class EXPCL_DIRECT DCSwitch : public DCDeclaration {
00034 public:
00035 DCSwitch(const string &name, DCField *key_parameter);
00036 virtual ~DCSwitch();
00037
00038 PUBLISHED:
00039 virtual DCSwitch *as_switch();
00040 virtual const DCSwitch *as_switch() const;
00041
00042 const string &get_name() const;
00043 DCField *get_key_parameter() const;
00044
00045 int get_num_cases() const;
00046 int get_case_by_value(const string &case_value) const;
00047 DCPackerInterface *get_case(int n) const;
00048 DCPackerInterface *get_default_case() const;
00049
00050 string get_value(int case_index) const;
00051 int get_num_fields(int case_index) const;
00052 DCField *get_field(int case_index, int n) const;
00053 DCField *get_field_by_name(int case_index, const string &name) const;
00054
00055 public:
00056 bool is_field_valid() const;
00057 int add_case(const string &value);
00058 void add_invalid_case();
00059 bool add_default();
00060 bool add_field(DCField *field);
00061 void add_break();
00062
00063 const DCPackerInterface *apply_switch(const char *value_data, size_t length) const;
00064
00065 virtual void output(ostream &out, bool brief) const;
00066 virtual void write(ostream &out, bool brief, int indent_level) const;
00067 void output_instance(ostream &out, bool brief, const string &prename,
00068 const string &name, const string &postname) const;
00069 void write_instance(ostream &out, bool brief, int indent_level,
00070 const string &prename, const string &name,
00071 const string &postname) const;
00072 virtual void generate_hash(HashGenerator &hashgen) const;
00073 virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
00074
00075 bool do_check_match_switch(const DCSwitch *other) const;
00076
00077 public:
00078 typedef pvector<DCField *> Fields;
00079 typedef pmap<string, DCField *> FieldsByName;
00080
00081 class SwitchFields : public DCPackerInterface {
00082 public:
00083 SwitchFields(const string &name);
00084 ~SwitchFields();
00085 virtual DCPackerInterface *get_nested_field(int n) const;
00086
00087 bool add_field(DCField *field);
00088 bool do_check_match_switch_case(const SwitchFields *other) const;
00089
00090 void output(ostream &out, bool brief) const;
00091 void write(ostream &out, bool brief, int indent_level) const;
00092
00093 protected:
00094 virtual bool do_check_match(const DCPackerInterface *other) const;
00095
00096 public:
00097 Fields _fields;
00098 FieldsByName _fields_by_name;
00099 bool _has_default_value;
00100 };
00101
00102 class SwitchCase {
00103 public:
00104 SwitchCase(const string &value, SwitchFields *fields);
00105 ~SwitchCase();
00106
00107 bool do_check_match_switch_case(const SwitchCase *other) const;
00108
00109 public:
00110 string _value;
00111 SwitchFields *_fields;
00112 };
00113
00114 private:
00115 SwitchFields *start_new_case();
00116
00117 private:
00118 string _name;
00119 DCField *_key_parameter;
00120
00121 typedef pvector<SwitchCase *> Cases;
00122 Cases _cases;
00123 SwitchFields *_default_case;
00124
00125
00126
00127 typedef pvector<SwitchFields *> CaseFields;
00128 CaseFields _case_fields;
00129
00130
00131
00132
00133 Fields _nested_fields;
00134
00135
00136
00137
00138
00139 CaseFields _current_fields;
00140 bool _fields_added;
00141
00142
00143 typedef pmap<string, int> CasesByValue;
00144 CasesByValue _cases_by_value;
00145 };
00146
00147 #endif