PhoenixGenerator  2.8.0
Set of tools to generate code
Loading...
Searching...
No Matches
NanobindTraitDataStream.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Thibaut Oprinsen
3 Mail : thibaut.oprinsen@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
8
13
16
21void registerDeserializationMethods(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
22 PString name(classConfig.getName());
23 if(classConfig.getIsEnum()){
24 name = name + "::" + name;
25 }
26 fs << std::endl << std::endl << "\t\t///Deserialization method for " << name;
27 fs << std::endl << "\t\t.def_static(\"from_bytes\", [](const nb::bytearray &b) -> " << name << " {";
28 fs << std::endl << "\t\t\t\t" << name << " result;";
29 fs << std::endl << "\t\t\t\tDataStreamIter iter((DataStreamIter)b.data());";
30 fs << std::endl << "\t\t\t\tbool res(data_message_load(iter, result));";
31 fs << std::endl << "\t\t\t\tif(!res){";
32 fs << std::endl << "\t\t\t\t\tthrow nb::buffer_error(\"Failed to deserialize " << name << "\");";
33 fs << std::endl << "\t\t\t\t}";
34 fs << std::endl << "\t\t\t\treturn result;";
35 fs << std::endl << "\t\t\t}, ";
36 fs << std::endl << "\t\t\t\"Load a " << name << " from a bytearray\"";
37 fs << std::endl << "\t\t)";
38}
39
44void registerSerializationMethods(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
45 PString name(classConfig.getName());
46 if(classConfig.getIsEnum()){
47 name = name + "::" + name;
48 }
49 fs << std::endl << std::endl << "\t\t///Serialization method for " << name;
50 fs << std::endl << "\t\t.def(\"to_bytes\", [](const " << name << " & self) -> nb::bytearray {";
51 fs << std::endl << "\t\t\t\tsize_t size = data_size(self);";
52 fs << std::endl << "\t\t\t\tnb::bytearray msg(NULL, size);";
53 fs << std::endl << "\t\t\t\tDataStreamIter iter((DataStreamIter)msg.data());";
54 fs << std::endl << "\t\t\t\tbool success = data_message_save(iter, self);";
55 fs << std::endl << "\t\t\t\tif(success){";
56 fs << std::endl << "\t\t\t\t\treturn msg;";
57 fs << std::endl << "\t\t\t\t}else{";
58 fs << std::endl << "\t\t\t\t\tthrow nb::buffer_error(\"Failed to serialize " << name << "\");";
59 fs << std::endl << "\t\t\t\t}";
60 fs << std::endl << "\t\t\t}, ";
61 fs << std::endl << "\t\t\t\"Serialize the " << name << " to bytearray\"";
62 fs << std::endl << "\t\t)";
63}
64
69void registerSizeMethod(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
70 PString name(classConfig.getName());
71 if(classConfig.getIsEnum()){
72 name = name + "::" + name;
73 }
74 fs << std::endl << std::endl << "\t\t///Size method for " << name;
75 fs << std::endl << "\t\t.def(\"get_size\", [](const " << name << " & self) -> size_t {";
76 fs << std::endl << "\t\t\t\treturn data_size(self);";
77 fs << std::endl << "\t\t\t}, ";
78 fs << std::endl << "\t\t\t\"Get the size of the " << name << " in bytes\"";
79 fs << std::endl << "\t\t)";
80}
81
86void NanobindTraitDataStream::registerMethod(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode) const{
87 if(!mode.enableDataStream){return;}
88 PString name(classConfig.getName());
89
90 registerSerializationMethods(fs, classConfig, mode);
91 registerDeserializationMethods(fs, classConfig, mode);
92 registerSizeMethod(fs, classConfig, mode);
93}
94
95
101void failed_enum_deserialization(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode, const PString & baseFileName){
102 PString name(classConfig.getName());
103 PString moduleName = baseFileName.toLower();
104 fs << "def test_data_stream_deserialization_failed():" << std::endl;
105 fs << "\t\"\"\"Test data stream conversion\"\"\"" << std::endl;
106 fs << "\t#Test with the value 8 even if there are only two values in the enum" << std::endl;
107 fs << "\tdata_stream = bytearray(b'\\x08\\x00\\x00\\x00')" << std::endl;
108 fs << "\twith pytest.raises(ValueError, match=\".* is not a valid "<<name<<"\"):" << std::endl;
109 fs << "\t\ttest_value = " << moduleName << "." << name << ".from_bytes(data_stream)" << std::endl;
110 fs << std::endl;
111}
112
118void NanobindTraitDataStream::testFunction(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode, const PString & baseFileName) const{
119 if(!mode.enableDataStream){return;}
120 PString name(classConfig.getName());
121 PString moduleName = baseFileName.toLower();
123 fs << "def test_data_stream_conversion():" << std::endl;
124 fs << "\t\"\"\"Test data stream conversion\"\"\"" << std::endl;
125
126 const PVecClassAttribute & listAttr(classConfig.getListAttribute());
127 if(classConfig.getIsEnum()){
128 if(listAttr.size() != 0lu){
129 fs << "\ttest_value1 = " << moduleName << "." << name << "." << listAttr.front().getName() << std::endl;
130 }
131 fs << "\tdata_stream = test_value1.to_bytes()" << std::endl;
132 fs << "\tassert data_stream == bytearray(b'\\x00\\x00\\x00\\x00')" << std::endl;
133 fs << "\ttest_value2 = " << moduleName << "." << name << ".from_bytes(data_stream)" << std::endl;
134 fs << std::endl;
135 fs << "\tassert test_value1.get_size() == 4" << std::endl;
136 fs << "\tassert test_value1 == test_value2" << std::endl;
137 fs << std::endl;
138 }else{
139 fs << "\t" << name.toLower() << " = " << moduleName << "." << name << "()" << std::endl;
140 fs << "\t# Set some example values" << std::endl;
141 for(PVecClassAttribute::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
142 PString defaultValue = getTestDefaultValueTypeInPython(it->getType());
143 if(defaultValue != ""){
144 fs << "\t" << name.toLower() << "." << it->getName() << " = " << defaultValue << std::endl;
145 }
146 }
147 fs << std::endl;
148 fs << "\tdata_stream = " << name.toLower() << ".to_bytes()" << std::endl;
149 fs << std::endl;
150 fs << "\tnew_" << name.toLower() << " = " << moduleName << "." << name << "()" << std::endl;
151 fs << "\tnew_" << name.toLower() << " = " << moduleName << "." << name << ".from_bytes(data_stream)" << std::endl;
152 fs << std::endl;
153 for(PVecClassAttribute::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
154 PString defaultValue = getTestDefaultValueTypeInPython(it->getType());
155 if(defaultValue != ""){
156 fs << "\tassert new_" << name.toLower() << "." << it->getName() << " == " << defaultValue << std::endl;
157 }
158 }
160 fs << std::endl;
161 fs << "def test_serialization_type_errors():" << std::endl;
162 fs << "\t\"\"\"Test erro types for from_bytes\"\"\"" << std::endl;
163 fs << std::endl;
164 fs << "\t" << name.toLower() << " = " << moduleName << "." << name << "()" << std::endl;
165 fs << "\twith pytest.raises(TypeError, match=\".*from_bytes\\(\\): incompatible function arguments.*\"):" << std::endl;
166 fs << "\t\tresult = " << name.toLower() << ".from_bytes(\"A string is not a bytearray !!!\") # deserialize string instead of bytearray" << std::endl;
167 fs << std::endl;
168 fs << "\twith pytest.raises(TypeError, match=\".*from_bytes\\(\\): incompatible function arguments.*\"):" << std::endl;
169 fs << "\t\tresult = " << name.toLower() << ".from_bytes(42) # deserialize instead of bytearray" << std::endl;
170 fs << std::endl;
171 fs << "\twith pytest.raises(TypeError, match=\".*from_bytes\\(\\): incompatible function arguments.*\"):" << std::endl;
172 fs << "\t\tresult = " << name.toLower() << ".from_bytes([1, 2, 3, 4]) # deserialize list instead of bytearray" << std::endl;
173 fs << std::endl;
174 }
175 if(classConfig.getIsEnum()){
176 failed_enum_deserialization(fs, classConfig, mode, baseFileName);
177 }
178}
179
184void NanobindTraitDataStream::testCallFunction(std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode) const{
185 if(!mode.enableDataStream){return;}
186 PString name(classConfig.getName());
187 fs << "\ttest_data_stream_conversion()" << std::endl;
188 fs << "\ttest_serialization_type_errors()" << std::endl;
189}
190
void registerSizeMethod(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
registration of size method
void registerSerializationMethods(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
registration of serialization methods
void registerDeserializationMethods(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
registration of serialization methods
void failed_enum_deserialization(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode, const PString &baseFileName)
std::vector< PClassAttribute > PVecClassAttribute
Definition PDataConfig.h:13
virtual ~NanobindTraitDataStream()
Destructor of NanobindTraitDataStream.
virtual void testFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode, const PString &baseFileName) const
NanobindTraitDataStream()
Constructor of NanobindTraitDataStream.
virtual void registerMethod(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
virtual void testCallFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Class to describe a basic class.
const std::vector< PClassAttribute > & getListAttribute() const
Returns the list of attributes of the class.
const PString & getName() const
Returns the class name.
bool getIsEnum() const
Say if the current PClassConfig is an enum.
All the genertor modes.
bool enableDataStream
True to enable data stream interface generator.
PString getTestDefaultValueTypeInPython(const PString &type)
Get default test value for a given type in Python.