DCCL v3
field_codec_message_stack.cpp
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 #include "field_codec_message_stack.h"
23 #include "dccl/field_codec.h"
24 
25 std::vector<const google::protobuf::FieldDescriptor*> dccl::internal::MessageStack::field_;
26 std::vector<const google::protobuf::Descriptor*> dccl::internal::MessageStack::desc_;
27 std::vector<dccl::MessagePart> dccl::internal::MessageStack::parts_;
28 
29 //
30 // MessageStack
31 //
32 
33 void dccl::internal::MessageStack::push(const google::protobuf::Descriptor* desc)
34 
35 {
36  desc_.push_back(desc);
37  ++descriptors_pushed_;
38 }
39 
40 void dccl::internal::MessageStack::push(const google::protobuf::FieldDescriptor* field)
41 {
42  field_.push_back(field);
43  ++fields_pushed_;
44 }
45 
46 void dccl::internal::MessageStack::push(MessagePart part)
47 {
48  parts_.push_back(part);
49  ++parts_pushed_;
50 }
51 
52 
53 void dccl::internal::MessageStack::__pop_desc()
54 {
55  if(!desc_.empty())
56  desc_.pop_back();
57 }
58 
59 void dccl::internal::MessageStack::__pop_field()
60 {
61  if(!field_.empty())
62  field_.pop_back();
63 }
64 
65 void dccl::internal::MessageStack::__pop_parts()
66 {
67  if(!parts_.empty())
68  parts_.pop_back();
69 }
70 
71 
72 dccl::internal::MessageStack::MessageStack(const google::protobuf::FieldDescriptor* field)
73  : descriptors_pushed_(0),
74  fields_pushed_(0),
75  parts_pushed_(0)
76 {
77  if(field)
78  {
79  if(field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
80  {
81  MessagePart part = UNKNOWN;
82  if(field->options().GetExtension(dccl::field).has_in_head())
83  {
84  // if explicitly set, set part (HEAD or BODY) of message for all children of this message
85  part = field->options().GetExtension(dccl::field).in_head() ? HEAD : BODY;
86  }
87  else
88  {
89  // use the parent's current part
90  part = current_part();
91  }
92  push(part);
93 
94  push(field->message_type());
95  }
96  push(field);
97  }
98 
99 }
100 
101 dccl::internal::MessageStack::~MessageStack()
102 {
103  for(int i = 0; i < fields_pushed_; ++i)
104  __pop_field();
105 
106  for(int i = 0; i < descriptors_pushed_; ++i)
107  __pop_desc();
108 
109  for(int i = 0; i < parts_pushed_; ++i)
110  __pop_parts();
111 }