00001 // Filename: dcSwitchParameter.cxx 00002 // Created by: drose (18Jun04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "dcSwitchParameter.h" 00016 #include "dcSwitch.h" 00017 #include "hashGenerator.h" 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: DCSwitchParameter::Constructor 00021 // Access: Public 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 DCSwitchParameter:: 00025 DCSwitchParameter(const DCSwitch *dswitch) : 00026 _dswitch(dswitch) 00027 { 00028 set_name(dswitch->get_name()); 00029 00030 _has_fixed_byte_size = true; 00031 _fixed_byte_size = 0; 00032 _has_fixed_structure = false; 00033 00034 // The DCSwitch presents just one nested field initially, which is 00035 // the key parameter. When we pack or unpack that, the DCPacker 00036 // calls apply_switch(), which returns a new record that presents 00037 // the remaining nested fields. 00038 _has_nested_fields = true; 00039 _num_nested_fields = 1; 00040 00041 _pack_type = PT_switch; 00042 00043 DCField *key_parameter = dswitch->get_key_parameter(); 00044 _has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size(); 00045 _has_range_limits = _has_range_limits || key_parameter->has_range_limits(); 00046 _has_default_value = _has_default_value || key_parameter->has_default_value(); 00047 00048 int num_cases = _dswitch->get_num_cases(); 00049 if (num_cases > 0) { 00050 _fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size(); 00051 00052 // Consider each case for fixed size, etc. 00053 for (int i = 0; i < num_cases; i++) { 00054 const DCSwitch::SwitchFields *fields = 00055 (const DCSwitch::SwitchFields *)_dswitch->get_case(i); 00056 00057 if (!fields->has_fixed_byte_size() || 00058 fields->get_fixed_byte_size() != _fixed_byte_size) { 00059 00060 // Nope, we have a variable byte size. 00061 _has_fixed_byte_size = false; 00062 } 00063 00064 _has_range_limits = _has_range_limits || fields->has_range_limits(); 00065 _has_default_value = _has_default_value || fields->_has_default_value; 00066 } 00067 } 00068 00069 // Also consider the default case, if there is one. 00070 const DCSwitch::SwitchFields *fields = 00071 (DCSwitch::SwitchFields *)_dswitch->get_default_case(); 00072 if (fields != (DCSwitch::SwitchFields *)NULL) { 00073 if (!fields->has_fixed_byte_size() || 00074 fields->get_fixed_byte_size() != _fixed_byte_size) { 00075 _has_fixed_byte_size = false; 00076 } 00077 00078 _has_range_limits = _has_range_limits || fields->has_range_limits(); 00079 _has_default_value = _has_default_value || fields->_has_default_value; 00080 } 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: DCSwitchParameter::Copy Constructor 00085 // Access: Public 00086 // Description: 00087 //////////////////////////////////////////////////////////////////// 00088 DCSwitchParameter:: 00089 DCSwitchParameter(const DCSwitchParameter ©) : 00090 DCParameter(copy), 00091 _dswitch(copy._dswitch) 00092 { 00093 } 00094 00095 //////////////////////////////////////////////////////////////////// 00096 // Function: DCSwitchParameter::as_switch_parameter 00097 // Access: Published, Virtual 00098 // Description: 00099 //////////////////////////////////////////////////////////////////// 00100 DCSwitchParameter *DCSwitchParameter:: 00101 as_switch_parameter() { 00102 return this; 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: DCSwitchParameter::as_switch_parameter 00107 // Access: Published, Virtual 00108 // Description: 00109 //////////////////////////////////////////////////////////////////// 00110 const DCSwitchParameter *DCSwitchParameter:: 00111 as_switch_parameter() const { 00112 return this; 00113 } 00114 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: DCSwitchParameter::make_copy 00117 // Access: Published, Virtual 00118 // Description: 00119 //////////////////////////////////////////////////////////////////// 00120 DCParameter *DCSwitchParameter:: 00121 make_copy() const { 00122 return new DCSwitchParameter(*this); 00123 } 00124 00125 //////////////////////////////////////////////////////////////////// 00126 // Function: DCSwitchParameter::is_valid 00127 // Access: Published, Virtual 00128 // Description: Returns false if the type is an invalid type 00129 // (e.g. declared from an undefined typedef), true if 00130 // it is valid. 00131 //////////////////////////////////////////////////////////////////// 00132 bool DCSwitchParameter:: 00133 is_valid() const { 00134 return true; //_dswitch->is_valid(); 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: DCSwitchParameter::get_switch 00139 // Access: Published 00140 // Description: Returns the switch object this parameter represents. 00141 //////////////////////////////////////////////////////////////////// 00142 const DCSwitch *DCSwitchParameter:: 00143 get_switch() const { 00144 return _dswitch; 00145 } 00146 00147 //////////////////////////////////////////////////////////////////// 00148 // Function: DCSwitchParameter::get_nested_field 00149 // Access: Public, Virtual 00150 // Description: Returns the DCPackerInterface object that represents 00151 // the nth nested field. This may return NULL if there 00152 // is no such field (but it shouldn't do this if n is in 00153 // the range 0 <= n < get_num_nested_fields()). 00154 //////////////////////////////////////////////////////////////////// 00155 DCPackerInterface *DCSwitchParameter:: 00156 get_nested_field(int) const { 00157 return _dswitch->get_key_parameter(); 00158 } 00159 00160 //////////////////////////////////////////////////////////////////// 00161 // Function: DCSwitchParameter::apply_switch 00162 // Access: Public 00163 // Description: Returns the DCPackerInterface that presents the 00164 // alternative fields for the case indicated by the 00165 // given packed value string, or NULL if the value 00166 // string does not match one of the expected cases. 00167 //////////////////////////////////////////////////////////////////// 00168 const DCPackerInterface *DCSwitchParameter:: 00169 apply_switch(const char *value_data, size_t length) const { 00170 return _dswitch->apply_switch(value_data, length); 00171 } 00172 00173 //////////////////////////////////////////////////////////////////// 00174 // Function: DCSwitchParameter::output_instance 00175 // Access: Public, Virtual 00176 // Description: Formats the parameter in the C++-like dc syntax as a 00177 // typename and identifier. 00178 //////////////////////////////////////////////////////////////////// 00179 void DCSwitchParameter:: 00180 output_instance(ostream &out, bool brief, const string &prename, 00181 const string &name, const string &postname) const { 00182 if (get_typedef() != (DCTypedef *)NULL) { 00183 output_typedef_name(out, brief, prename, name, postname); 00184 00185 } else { 00186 _dswitch->output_instance(out, brief, prename, name, postname); 00187 } 00188 } 00189 00190 //////////////////////////////////////////////////////////////////// 00191 // Function: DCSwitchParameter::write_instance 00192 // Access: Public, Virtual 00193 // Description: Formats the parameter in the C++-like dc syntax as a 00194 // typename and identifier. 00195 //////////////////////////////////////////////////////////////////// 00196 void DCSwitchParameter:: 00197 write_instance(ostream &out, bool brief, int indent_level, 00198 const string &prename, const string &name, 00199 const string &postname) const { 00200 if (get_typedef() != (DCTypedef *)NULL) { 00201 write_typedef_name(out, brief, indent_level, prename, name, postname); 00202 00203 } else { 00204 _dswitch->write_instance(out, brief, indent_level, prename, name, postname); 00205 } 00206 } 00207 00208 //////////////////////////////////////////////////////////////////// 00209 // Function: DCSwitchParameter::generate_hash 00210 // Access: Public, Virtual 00211 // Description: Accumulates the properties of this type into the 00212 // hash. 00213 //////////////////////////////////////////////////////////////////// 00214 void DCSwitchParameter:: 00215 generate_hash(HashGenerator &hashgen) const { 00216 DCParameter::generate_hash(hashgen); 00217 _dswitch->generate_hash(hashgen); 00218 } 00219 00220 //////////////////////////////////////////////////////////////////// 00221 // Function: DCSwitchParameter::pack_default_value 00222 // Access: Public, Virtual 00223 // Description: Packs the switchParameter's specified default value (or a 00224 // sensible default if no value is specified) into the 00225 // stream. Returns true if the default value is packed, 00226 // false if the switchParameter doesn't know how to pack its 00227 // default value. 00228 //////////////////////////////////////////////////////////////////// 00229 bool DCSwitchParameter:: 00230 pack_default_value(DCPackData &pack_data, bool &pack_error) const { 00231 if (has_default_value()) { 00232 return DCField::pack_default_value(pack_data, pack_error); 00233 } 00234 00235 return _dswitch->pack_default_value(pack_data, pack_error); 00236 } 00237 00238 //////////////////////////////////////////////////////////////////// 00239 // Function: DCSwitchParameter::do_check_match 00240 // Access: Protected, Virtual 00241 // Description: Returns true if the other interface is bitwise the 00242 // same as this one--that is, a uint32 only matches a 00243 // uint32, etc. Names of components, and range limits, 00244 // are not compared. 00245 //////////////////////////////////////////////////////////////////// 00246 bool DCSwitchParameter:: 00247 do_check_match(const DCPackerInterface *other) const { 00248 return other->do_check_match_switch_parameter(this); 00249 } 00250 00251 //////////////////////////////////////////////////////////////////// 00252 // Function: DCSwitchParameter::do_check_match_switch_parameter 00253 // Access: Protected, Virtual 00254 // Description: Returns true if this field matches the indicated 00255 // switch parameter, false otherwise. 00256 //////////////////////////////////////////////////////////////////// 00257 bool DCSwitchParameter:: 00258 do_check_match_switch_parameter(const DCSwitchParameter *other) const { 00259 return _dswitch->do_check_match_switch(other->_dswitch); 00260 }