NRP Core  1.4.1
repeated_field_proxy.h
Go to the documentation of this file.
1 /* * NRP Core - Backend infrastructure to synchronize simulations
2  *
3  * Copyright 2020-2023 NRP Team
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * This project has received funding from the European Union’s Horizon 2020
18  * Framework Programme for Research and Innovation under the Specific Grant
19  * Agreement No. 945539 (Human Brain Project SGA3).
20  */
21 
22 #ifndef REPEATED_FIELD_PROXY_H
23 #define REPEATED_FIELD_PROXY_H
24 
25 #include "google/protobuf/message.h"
26 #include <boost/python.hpp>
29 
30 
31 namespace bpy = boost::python;
32 namespace gpb = google::protobuf;
33 using namespace proto_field_ops;
34 
40 Py_ssize_t ExtractIndices(PyObject* indices, Py_ssize_t& from, Py_ssize_t& to, Py_ssize_t& step, Py_ssize_t length);
41 
46 {
47 public:
48 
56  static void create() {
57  bpy::class_<RepeatedScalarFieldProxy> binder("RepeatedScalarField", bpy::no_init);
58  binder.def("__len__", &RepeatedScalarFieldProxy::Len);
59  binder.def("__getitem__", &RepeatedScalarFieldProxy::GetItem);
60  binder.def("__setitem__", &RepeatedScalarFieldProxy::SetItem);
61  binder.def("__iter__", &RepeatedScalarFieldProxy::Iter);
62  binder.def("append", &RepeatedScalarFieldProxy::Append);
63  binder.def("extend", &RepeatedScalarFieldProxy::Extend);
64  binder.def("pop", &RepeatedScalarFieldProxy::Pop);
65  binder.def("clear", &RepeatedScalarFieldProxy::Clear);
66  }
67 
74  RepeatedScalarFieldProxy(gpb::Message & msg, const gpb::FieldDescriptor *field)
75  : _m(msg), _f(field) {
76  if(!field->is_repeated())
77  throw NRPException::logCreate("Accessing RepeatedScalarFieldProxy from a non-repeating field");
78  else if(field->cpp_type() == gpb::FieldDescriptor::CPPTYPE_MESSAGE)
79  throw NRPException::logCreate("Accessing RepeatedScalarFieldProxy from a non-scalar field");
80  }
81 
85  int Len()
86  { return _m.GetReflection()->FieldSize(_m, _f); }
87 
91  bpy::object GetItem(PyObject* indices);
92 
96  void SetItem(PyObject* indices, PyObject* value);
97 
101  bpy::object Iter();
102 
106  void Append(const bpy::object& value)
107  { AddRepeatedScalarField(_m, _f, value); }
108 
112  void Extend(const bpy::object& value) {
113  for(int i=0; i<bpy::len(value); ++i)
114  AddRepeatedScalarField(_m, _f, value[i]);
115  }
116 
120  void Clear()
121  { _m.GetReflection()->ClearField(&_m,_f); }
122 
126  void Pop()
127  { _m.GetReflection()->RemoveLast(&_m, _f); }
128 
129 private:
130 
131  gpb::Message & _m;
132  const gpb::FieldDescriptor * _f;
133 };
134 
135 
140 {
141 public:
142 
146  static void create() {
147  bpy::class_<RepeatedScalarFieldIterProxy> binder("RepeatedScalarFieldIter", bpy::no_init);
148  binder.def("__next__", &RepeatedScalarFieldIterProxy::Next);
149  }
150 
154  RepeatedScalarFieldIterProxy(gpb::Message & msg, const gpb::FieldDescriptor *field)
155  : _p(msg, field), _ind(0) { }
156 
160  bpy::object Next() {
161  if(_ind == _p.Len()) {
162  PyErr_SetObject(PyExc_StopIteration, Py_None);
163  boost::python::throw_error_already_set();
164  }
165 
166  return _p.GetItem(Py_BuildValue("i", _ind++));
167  }
168 
169 private:
170 
172  int _ind;
173 };
174 
175 #endif // REPEATED_FIELD_PROXY_H
RepeatedScalarFieldProxy::RepeatedScalarFieldProxy
RepeatedScalarFieldProxy(gpb::Message &msg, const gpb::FieldDescriptor *field)
Constructor.
Definition: repeated_field_proxy.h:74
RepeatedScalarFieldProxy::SetItem
void SetItem(PyObject *indices, PyObject *value)
Definition: repeated_field_proxy.cpp:69
RepeatedScalarFieldProxy::create
static void create()
Creates the python wrapper.
Definition: repeated_field_proxy.h:56
RepeatedScalarFieldProxy::Pop
void Pop()
Definition: repeated_field_proxy.h:126
RepeatedScalarFieldIterProxy::create
static void create()
Creates the python wrapper.
Definition: repeated_field_proxy.h:146
nrp_exceptions.h
proto_field_ops.h
RepeatedScalarFieldProxy
Proxy class implementing a list-like python wrapper for a protobuf repeated scalar field (ie....
Definition: repeated_field_proxy.h:45
RepeatedScalarFieldProxy::Len
int Len()
Definition: repeated_field_proxy.h:85
RepeatedScalarFieldProxy::Append
void Append(const bpy::object &value)
Definition: repeated_field_proxy.h:106
proto_field_ops
Implement single field Get/Set operations using field descriptor and reflection interface.
Definition: proto_field_ops.cpp:25
RepeatedScalarFieldIterProxy::Next
bpy::object Next()
Implementation of next
Definition: repeated_field_proxy.h:160
NRPException::logCreate
static EXCEPTION logCreate(LOG_EXCEPTION_T &exception, const std::string &msg, NRPLogger::spdlog_out_fcn_t spdlogCall=NRPLogger::critical)
Definition: nrp_exceptions.h:73
RepeatedScalarFieldProxy::Clear
void Clear()
Definition: repeated_field_proxy.h:120
RepeatedScalarFieldProxy::Extend
void Extend(const bpy::object &value)
Definition: repeated_field_proxy.h:112
proto_field_ops::AddRepeatedScalarField
void AddRepeatedScalarField(gpb::Message &m, const gpb::FieldDescriptor *field, const bpy::object &value)
Append repeated scalar field.
Definition: proto_field_ops.cpp:211
RepeatedScalarFieldIterProxy::RepeatedScalarFieldIterProxy
RepeatedScalarFieldIterProxy(gpb::Message &msg, const gpb::FieldDescriptor *field)
Constructor.
Definition: repeated_field_proxy.h:154
RepeatedScalarFieldProxy::Iter
bpy::object Iter()
Definition: repeated_field_proxy.cpp:122
RepeatedScalarFieldProxy::GetItem
bpy::object GetItem(PyObject *indices)
Definition: repeated_field_proxy.cpp:44
RepeatedScalarFieldIterProxy
Class implementing a python iterator for a RepeatedScalarFieldProxy.
Definition: repeated_field_proxy.h:139
ExtractIndices
Py_ssize_t ExtractIndices(PyObject *indices, Py_ssize_t &from, Py_ssize_t &to, Py_ssize_t &step, Py_ssize_t length)
Function which processes an index or slice object and sets from, to and step appropriately.
Definition: repeated_field_proxy.cpp:24