blob: ffe2af38041866f25c1b356e607d58466e1ecd78 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Sleee9ce01c2007-05-16 02:29:53 +000019
Mark Slee31985722006-05-24 21:45:31 +000020#ifndef T_STRUCT_H
21#define T_STRUCT_H
22
Bryan Duxburyff219ac2009-04-10 21:51:00 +000023#include <algorithm>
Mark Slee31985722006-05-24 21:45:31 +000024#include <vector>
Bryan Duxburyff219ac2009-04-10 21:51:00 +000025#include <utility>
Mark Slee31985722006-05-24 21:45:31 +000026#include <string>
27
28#include "t_type.h"
Mark Sleee8540632006-05-30 09:24:40 +000029#include "t_field.h"
Mark Slee31985722006-05-24 21:45:31 +000030
Mark Sleef0712dc2006-10-25 19:03:57 +000031// Forward declare that puppy
32class t_program;
33
Mark Sleef5377b32006-10-10 01:42:59 +000034/**
35 * A struct is a container for a set of member fields that has a name. Structs
36 * are also used to implement exception types.
37 *
Mark Sleef5377b32006-10-10 01:42:59 +000038 */
Mark Slee31985722006-05-24 21:45:31 +000039class t_struct : public t_type {
40 public:
Bryan Duxburyff219ac2009-04-10 21:51:00 +000041 typedef std::vector<t_field*> members_type;
42
Mark Sleef0712dc2006-10-25 19:03:57 +000043 t_struct(t_program* program) :
44 t_type(program),
Mark Slee782abbb2007-01-19 00:17:02 +000045 is_xception_(false),
Bryan Duxburyd6203282012-06-26 00:32:57 +000046 is_union_(false),
Jens Geyer04f70972012-12-17 22:41:21 +010047 members_validated(false),
48 members_with_value(0),
David Reissf84b3602007-09-17 21:16:32 +000049 xsd_all_(false) {}
Mark Sleeb15a68b2006-06-07 06:46:24 +000050
Mark Sleef0712dc2006-10-25 19:03:57 +000051 t_struct(t_program* program, const std::string& name) :
52 t_type(program, name),
Mark Slee782abbb2007-01-19 00:17:02 +000053 is_xception_(false),
Bryan Duxburyd6203282012-06-26 00:32:57 +000054 is_union_(false),
Jens Geyer04f70972012-12-17 22:41:21 +010055 members_validated(false),
56 members_with_value(0),
David Reissf84b3602007-09-17 21:16:32 +000057 xsd_all_(false) {}
Mark Slee31985722006-05-24 21:45:31 +000058
Mark Slee9cb7c612006-09-01 22:17:45 +000059 void set_name(const std::string& name) {
60 name_ = name;
Jens Geyer04f70972012-12-17 22:41:21 +010061 validate_union_members();
Mark Slee9cb7c612006-09-01 22:17:45 +000062 }
63
Mark Slee9cb7c612006-09-01 22:17:45 +000064 void set_xception(bool is_xception) {
65 is_xception_ = is_xception;
66 }
Mark Sleee8540632006-05-30 09:24:40 +000067
Jens Geyer04f70972012-12-17 22:41:21 +010068 void validate_union_member( t_field * field) {
69 if( is_union_ && (! name_.empty())) {
70
71 // unions can't have required fields
72 if( field->get_req() == t_field::T_REQUIRED) {
73 pwarning( 1, "Required field %s of union %s set to optional.\n", field->get_name().c_str(), name_.c_str());
74 field->set_req( t_field::T_OPTIONAL);
75 }
76
77 // unions may have up to one member defaulted, but not more
78 if( field->get_value() != NULL) {
79 if( 1 < ++members_with_value) {
80 throw "Error: Field "+field->get_name()+" provides another default value for union "+name_;
81 }
82 }
83 }
84
85 }
86
87 void validate_union_members() {
88 if( is_union_ && (! name_.empty()) && (!members_validated)) {
89 members_type::const_iterator m_iter;
90 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
91 validate_union_member( *m_iter);
92 }
93 members_validated = true;
94 }
95 }
96
Bryan Duxburyab3666e2009-09-01 23:03:47 +000097 void set_union(bool is_union) {
98 is_union_ = is_union;
Jens Geyer04f70972012-12-17 22:41:21 +010099 validate_union_members();
Bryan Duxburyab3666e2009-09-01 23:03:47 +0000100 }
101
Mark Slee782abbb2007-01-19 00:17:02 +0000102 void set_xsd_all(bool xsd_all) {
103 xsd_all_ = xsd_all;
104 }
105
106 bool get_xsd_all() const {
107 return xsd_all_;
108 }
109
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000110 bool append(t_field* elem) {
David Reissebb6cc42009-04-09 20:02:56 +0000111 members_.push_back(elem);
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000112
113 typedef members_type::iterator iter_type;
114 std::pair<iter_type, iter_type> bounds = std::equal_range(
115 members_in_id_order_.begin(), members_in_id_order_.end(), elem, t_field::key_compare()
116 );
117 if (bounds.first != bounds.second) {
118 return false;
119 }
120 members_in_id_order_.insert(bounds.second, elem);
Jens Geyer04f70972012-12-17 22:41:21 +0100121 validate_union_member( elem);
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000122 return true;
Mark Slee9cb7c612006-09-01 22:17:45 +0000123 }
Mark Sleee8540632006-05-30 09:24:40 +0000124
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000125 const members_type& get_members() {
Mark Slee9cb7c612006-09-01 22:17:45 +0000126 return members_;
127 }
128
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000129 const members_type& get_sorted_members() {
130 return members_in_id_order_;
131 }
132
Mark Slee9cb7c612006-09-01 22:17:45 +0000133 bool is_struct() const {
134 return !is_xception_;
135 }
136
137 bool is_xception() const {
138 return is_xception_;
139 }
Bryan Duxburyab3666e2009-09-01 23:03:47 +0000140
141 bool is_union() const {
142 return is_union_;
143 }
Mark Slee31985722006-05-24 21:45:31 +0000144
David Reiss18bf22d2007-08-28 20:49:17 +0000145 virtual std::string get_fingerprint_material() const {
146 std::string rv = "{";
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000147 members_type::const_iterator m_iter;
148 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
David Reiss6ce97e32007-08-30 23:18:31 +0000149 rv += (*m_iter)->get_fingerprint_material();
David Reiss18bf22d2007-08-28 20:49:17 +0000150 rv += ";";
151 }
152 rv += "}";
153 return rv;
154 }
155
David Reiss9885c682007-08-30 23:12:37 +0000156 virtual void generate_fingerprint() {
157 t_type::generate_fingerprint();
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000158 members_type::const_iterator m_iter;
159 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
David Reiss6ce97e32007-08-30 23:18:31 +0000160 (*m_iter)->get_type()->generate_fingerprint();
David Reiss18bf22d2007-08-28 20:49:17 +0000161 }
162 }
163
Bryan Duxbury2d804702009-12-18 19:41:11 +0000164 t_field* get_field_by_name(std::string field_name) {
165 members_type::const_iterator m_iter;
166 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
167 if ((*m_iter)->get_name() == field_name) {
168 return *m_iter;
169 }
170 }
171 return NULL;
172 }
173
Mark Slee31985722006-05-24 21:45:31 +0000174 private:
David Reiss18bf22d2007-08-28 20:49:17 +0000175
Bryan Duxburyff219ac2009-04-10 21:51:00 +0000176 members_type members_;
177 members_type members_in_id_order_;
Mark Slee9cb7c612006-09-01 22:17:45 +0000178 bool is_xception_;
Bryan Duxburyab3666e2009-09-01 23:03:47 +0000179 bool is_union_;
Jens Geyer04f70972012-12-17 22:41:21 +0100180 bool members_validated;
181 int members_with_value;
Mark Slee782abbb2007-01-19 00:17:02 +0000182
183 bool xsd_all_;
Mark Slee31985722006-05-24 21:45:31 +0000184};
185
186#endif