| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************** | ||
| 2 | Auteur : Pierre Aubert | ||
| 3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
| 4 | Licence : CeCILL-C | ||
| 5 | ****************************************/ | ||
| 6 | |||
| 7 | |||
| 8 | #include <string.h> | ||
| 9 | #include "phoenix_varint.h" | ||
| 10 | |||
| 11 | #include "FieldParser.h" | ||
| 12 | |||
| 13 | |||
| 14 | ///Default constructor of FieldParser | ||
| 15 | 49 | FieldParser::FieldParser(){ | |
| 16 |
1/1✓ Branch 0 (4→5) taken 49 times.
|
49 | initialisationFieldParser(); |
| 17 | 49 | } | |
| 18 | |||
| 19 | ///Destructor of FieldParser | ||
| 20 | 93 | FieldParser::~FieldParser(){ | |
| 21 | 49 | clear(); | |
| 22 | 93 | } | |
| 23 | |||
| 24 | ///Add a sub message into the FieldParser | ||
| 25 | /** @param fieldId : id of the field that contain the sub message | ||
| 26 | * @param fieldName : name of the field | ||
| 27 | * @return pointer to the parser which will be used to parse the sub message | ||
| 28 | */ | ||
| 29 | 8 | FieldParser * FieldParser::addSubMessage(size_t fieldId, const PString & fieldName){ | |
| 30 |
1/1✓ Branch 0 (2→3) taken 8 times.
|
8 | FieldParser* parser = createSubFieldParser(fieldId, fieldName); |
| 31 |
1/1✓ Branch 0 (3→4) taken 8 times.
|
8 | parser->p_field.setType(FieldType::SUBMESSAGE); |
| 32 |
1/1✓ Branch 0 (4→5) taken 8 times.
|
8 | p_vecChildren.push_back(parser); |
| 33 | 8 | return parser; | |
| 34 | } | ||
| 35 | |||
| 36 | ///Add a sub message into the FieldParser | ||
| 37 | /** @param field : description of the field | ||
| 38 | * @return pointer to the parser which will be used to parse the sub message, of NULL if the field is not coherent | ||
| 39 | */ | ||
| 40 | 4 | FieldParser * FieldParser::addSubMessage(const FieldConfig & field){ | |
| 41 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 4 times.
|
4 | if(!checkInputType(FieldType::SUBMESSAGE, field)){return NULL;} |
| 42 | 4 | return addSubMessage(field.getId(), field.getName()); | |
| 43 | } | ||
| 44 | |||
| 45 | ///Add a sub message into the FieldParser | ||
| 46 | /** @param field : main description of the field | ||
| 47 | * @param childName : name of the child of the field to be used as description | ||
| 48 | * @return pointer to the parser which will be used to parse the sub message, of NULL if the field is not coherent | ||
| 49 | */ | ||
| 50 | ✗ | FieldParser * FieldParser::addSubMessage(const FieldConfig & field, const PString & childName){ | |
| 51 | ✗ | const std::map<PString, FieldConfig> & mapChildren = field.getVecChildren(); | |
| 52 | ✗ | std::map<PString, FieldConfig>::const_iterator itFind = mapChildren.find(childName); | |
| 53 | ✗ | if(itFind != mapChildren.end()){ | |
| 54 | ✗ | return addSubMessage(itFind->second); | |
| 55 | }else{ | ||
| 56 | ✗ | std::cerr << "FieldParser::addSubMessage : FieldConfig has no child named '"<<childName<<"'" << std::endl; | |
| 57 | ✗ | return NULL; | |
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | ///Add a sub message into the FieldParser | ||
| 62 | /** @param childConfig : configuration of the child with name childName | ||
| 63 | * @param field : main description of the field | ||
| 64 | * @param childName : name of the child of the field to be used as description | ||
| 65 | * @return pointer to the parser which will be used to parse the sub message, of NULL if the field is not coherent | ||
| 66 | */ | ||
| 67 | 1 | FieldParser * FieldParser::addSubMessage(FieldConfig & childConfig, const FieldConfig & field, const PString & childName){ | |
| 68 |
1/1✓ Branch 0 (2→3) taken 1 times.
|
1 | const std::map<PString, FieldConfig> & mapChildren = field.getVecChildren(); |
| 69 |
1/1✓ Branch 0 (3→4) taken 1 times.
|
1 | std::map<PString, FieldConfig>::const_iterator itFind = mapChildren.find(childName); |
| 70 |
1/2✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→12) not taken.
|
1 | if(itFind != mapChildren.end()){ |
| 71 |
1/1✓ Branch 0 (8→9) taken 1 times.
|
1 | childConfig = itFind->second; |
| 72 |
1/1✓ Branch 0 (10→11) taken 1 times.
|
1 | return addSubMessage(itFind->second); |
| 73 | }else{ | ||
| 74 | ✗ | std::cerr << "FieldParser::addSubMessage : FieldConfig has no child named '"<<childName<<"'" << std::endl; | |
| 75 | ✗ | return NULL; | |
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | ///Add a sub FieldParser for a enum type | ||
| 80 | /** @param varPtr : pointer to the variable to be updated on the parsing of the protocol buffer message | ||
| 81 | * @param fieldId : id of the field that contain the sub message | ||
| 82 | * @param fieldName : name of the field | ||
| 83 | * @return pointer to the parser which will be used to parse the sub message | ||
| 84 | */ | ||
| 85 | 5 | void FieldParser::addParseFieldEnum(size_t* varPtr, size_t fieldId, const PString & fieldName){ | |
| 86 |
1/1✓ Branch 0 (2→3) taken 5 times.
|
5 | FieldParser* parser = createSubFieldParser(fieldId, fieldName); |
| 87 |
1/1✓ Branch 0 (3→4) taken 5 times.
|
5 | parser->p_field.setType(FieldType::ENUM_TYPE); |
| 88 |
1/1✓ Branch 0 (4→5) taken 5 times.
|
5 | parser->p_field.setNbElement(0lu); |
| 89 |
1/1✓ Branch 0 (5→6) taken 5 times.
|
5 | parser->p_field.setTypeSize(sizeof(size_t)); |
| 90 |
1/1✓ Branch 0 (6→7) taken 5 times.
|
5 | parser->p_field.setVarPtr(varPtr); |
| 91 |
1/1✓ Branch 0 (7→8) taken 5 times.
|
5 | parser->p_field.setIsArray(false); |
| 92 |
1/1✓ Branch 0 (8→9) taken 5 times.
|
5 | parser->p_field.setOffset(0lu); |
| 93 |
1/1✓ Branch 0 (9→10) taken 5 times.
|
5 | parser->p_field.setIsOffsetReady(false); |
| 94 |
1/1✓ Branch 0 (10→11) taken 5 times.
|
5 | p_vecChildren.push_back(parser); |
| 95 | 5 | } | |
| 96 | |||
| 97 | ///Add a sub FieldParser for a enum type | ||
| 98 | /** @param varPtr : pointer to the variable to be updated on the parsing of the protocol buffer message | ||
| 99 | * @param field : FieldConfig which describes the field | ||
| 100 | * @return pointer to the parser which will be used to parse the sub message | ||
| 101 | */ | ||
| 102 | 2 | bool FieldParser::addParseFieldEnum(size_t* varPtr, const FieldConfig & field){ | |
| 103 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 2 times.
|
2 | if(!checkInputType(FieldType::ENUM_TYPE, field)){return false;} |
| 104 | 2 | addParseFieldEnum(varPtr, field.getId(), field.getName()); | |
| 105 | 2 | return true; | |
| 106 | } | ||
| 107 | |||
| 108 | ///Add a sub FieldParser for a enum type | ||
| 109 | /** @param varPtr : pointer to the variable to be updated on the parsing of the protocol buffer message | ||
| 110 | * @param field : FieldConfig which describes the field | ||
| 111 | * @param childName : name of the child of the field to be used as description | ||
| 112 | * @return pointer to the parser which will be used to parse the sub message | ||
| 113 | */ | ||
| 114 | 1 | bool FieldParser::addParseFieldEnum(size_t* varPtr, const FieldConfig & field, const PString & childName){ | |
| 115 |
1/1✓ Branch 0 (2→3) taken 1 times.
|
1 | const std::map<PString, FieldConfig> & mapChildren = field.getVecChildren(); |
| 116 |
1/1✓ Branch 0 (3→4) taken 1 times.
|
1 | std::map<PString, FieldConfig>::const_iterator itFind = mapChildren.find(childName); |
| 117 |
1/2✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→10) not taken.
|
1 | if(itFind != mapChildren.end()){ |
| 118 |
1/1✓ Branch 0 (8→9) taken 1 times.
|
1 | return addParseFieldEnum(varPtr, itFind->second); |
| 119 | }else{ | ||
| 120 | ✗ | std::cerr << "FieldParser::addParseFieldEnum : FieldConfig has no child named '"<<childName<<"'" << std::endl; | |
| 121 | ✗ | return false; | |
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | ///Load the Fields of the FieldParser (without offset on the first time and with offsets after) | ||
| 126 | /** @param message : message to be parsed | ||
| 127 | * @param out : output stream to be used | ||
| 128 | * @return true on success, false otherwise | ||
| 129 | */ | ||
| 130 | 50 | bool FieldParser::load(const std::vector<char> & message, std::ostream & out){ | |
| 131 | 50 | return load(message.data(), message.size(), out); | |
| 132 | } | ||
| 133 | |||
| 134 | ///Load the Fields of the FieldParser (without offset on the first time and with offsets after) | ||
| 135 | /** @param message : message to be parsed | ||
| 136 | * @param nbByte : number of bytes of the message | ||
| 137 | * @param out : output stream to be used | ||
| 138 | * @return true on success, false otherwise | ||
| 139 | */ | ||
| 140 | 50 | bool FieldParser::load(const char * message, size_t nbByte, std::ostream & out){ | |
| 141 | 50 | char* iter = (char*)message; | |
| 142 | 50 | const char* endMessage = message + nbByte; | |
| 143 |
3/3✓ Branch 0 (2→3) taken 50 times.
✓ Branch 2 (3→4) taken 5 times.
✓ Branch 3 (3→6) taken 45 times.
|
50 | if(!p_field.getIsOffsetReady()){ //If we do not have the offsets, we commute them |
| 144 |
1/1✓ Branch 0 (4→5) taken 5 times.
|
5 | return loadComputeOffset(iter, endMessage, message, out); |
| 145 | }else{ //If we have the offset, we use them directly | ||
| 146 |
1/1✓ Branch 0 (6→7) taken 45 times.
|
45 | return loadFromOffset(iter); |
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | ///Reset the offset of the FieldParser | ||
| 151 | 36 | void FieldParser::resetOffset(){ | |
| 152 | 36 | p_field.setOffset(0lu); | |
| 153 | 36 | p_field.setIsOffsetReady(false); | |
| 154 |
2/2✓ Branch 0 (18→5) taken 33 times.
✓ Branch 1 (18→19) taken 36 times.
|
138 | for(VecFieldParser::iterator it(p_vecChildren.begin()); it != p_vecChildren.end(); ++it){ |
| 155 |
1/1✓ Branch 0 (7→8) taken 33 times.
|
33 | (*it)->resetOffset(); |
| 156 | } | ||
| 157 | 36 | } | |
| 158 | |||
| 159 | ///Clear all the children of the FieldParser | ||
| 160 | 49 | void FieldParser::clear(){ | |
| 161 |
2/2✓ Branch 0 (17→3) taken 44 times.
✓ Branch 1 (17→18) taken 49 times.
|
186 | for(VecFieldParser::iterator it(p_vecChildren.begin()); it != p_vecChildren.end(); ++it){ |
| 162 |
1/2✓ Branch 0 (5→6) taken 44 times.
✗ Branch 1 (5→7) not taken.
|
44 | delete (*it); |
| 163 | } | ||
| 164 | 49 | p_vecChildren.clear(); | |
| 165 | 49 | } | |
| 166 | |||
| 167 | ///Print the FieldParser | ||
| 168 | /** @param[out] out : output stream to be used to print FieldParser information | ||
| 169 | * @param indentation : indentatio to be used for the print | ||
| 170 | */ | ||
| 171 | 128 | void FieldParser::print(std::ostream & out, const PString & indentation) const{ | |
| 172 |
2/2✓ Branch 0 (3→4) taken 33 times.
✓ Branch 1 (3→49) taken 95 times.
|
128 | if(p_vecChildren.size() != 0lu){ |
| 173 | 33 | out << indentation << "Field"; | |
| 174 | |||
| 175 |
2/2✓ Branch 0 (7→8) taken 22 times.
✓ Branch 1 (7→25) taken 11 times.
|
33 | if(p_field.getId() != 0lu){ |
| 176 | 22 | out << "(Id = " << p_field.getId(); | |
| 177 |
1/2✓ Branch 0 (13→14) taken 22 times.
✗ Branch 1 (13→18) not taken.
|
22 | if(p_field.getName() != ""){ |
| 178 | 22 | out << ", '" << p_field.getName() << "'"; | |
| 179 | } | ||
| 180 |
2/2✓ Branch 0 (19→20) taken 8 times.
✓ Branch 1 (19→23) taken 14 times.
|
22 | if(p_field.getIsOffsetReady()){ |
| 181 | 8 | out << ", offset = " << p_field.getOffset(); | |
| 182 | }else{ | ||
| 183 | 14 | out << ", NOT_RESOLVED"; | |
| 184 | } | ||
| 185 | 22 | out << ")"; | |
| 186 | } | ||
| 187 | 33 | out << "{" << std::endl; | |
| 188 |
2/2✓ Branch 0 (45→28) taken 117 times.
✓ Branch 1 (45→46) taken 33 times.
|
300 | for(VecFieldParser::const_iterator it(p_vecChildren.begin()); it != p_vecChildren.end(); ++it){ |
| 189 |
3/3✓ Branch 0 (30→31) taken 117 times.
✓ Branch 2 (31→32) taken 117 times.
✓ Branch 4 (32→33) taken 117 times.
|
117 | (*it)->print(out, indentation + "\t"); |
| 190 | } | ||
| 191 | 33 | out << indentation << "}" << std::endl; | |
| 192 | }else{ | ||
| 193 | 95 | out << indentation << "Field(Id = " << p_field.getId(); | |
| 194 |
1/2✓ Branch 0 (55→56) taken 95 times.
✗ Branch 1 (55→60) not taken.
|
95 | if(p_field.getName() != ""){ |
| 195 | 95 | out << ", '"<<p_field.getName()<<"'"; | |
| 196 | } | ||
| 197 |
2/2✓ Branch 0 (61→62) taken 34 times.
✓ Branch 1 (61→65) taken 61 times.
|
95 | if(p_field.getIsOffsetReady()){ |
| 198 | 34 | out << ", offset = " << p_field.getOffset(); | |
| 199 | }else{ | ||
| 200 | 61 | out << ", NOT_RESOLVED"; | |
| 201 | } | ||
| 202 |
2/2✓ Branch 0 (67→68) taken 11 times.
✓ Branch 1 (67→74) taken 84 times.
|
95 | if(p_field.getIsArray()){ |
| 203 | 11 | out << ", arrayPtr = " << p_field.getArrayPtr() << ", sizePtr = " << p_field.getNbElement(); | |
| 204 | }else{ | ||
| 205 | 84 | out << ", varPtr = " << p_field.getVarPtr(); | |
| 206 | } | ||
| 207 | 95 | out << ")" << std::endl; | |
| 208 | } | ||
| 209 | 128 | } | |
| 210 | |||
| 211 | ///Initialisation function of the class FieldParser | ||
| 212 | 49 | void FieldParser::initialisationFieldParser(){ | |
| 213 | |||
| 214 | 49 | } | |
| 215 | |||
| 216 | ///Add a sub FieldParser | ||
| 217 | /** @param fieldId : id of the field that contain the sub message | ||
| 218 | * @param fieldName : name of the field | ||
| 219 | * @return pointer to the parser which will be used to parse sub Fields | ||
| 220 | */ | ||
| 221 | 44 | FieldParser * FieldParser::createSubFieldParser(size_t fieldId, const PString & fieldName){ | |
| 222 |
2/5✓ Branch 0 (3→4) taken 44 times.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 44 times.
✗ Branch 4 (9→10) not taken.
✗ Branch 5 (9→11) not taken.
|
44 | FieldParser* parser = new FieldParser; |
| 223 | 44 | parser->setBaseField(fieldId, fieldName); | |
| 224 | 44 | return parser; | |
| 225 | } | ||
| 226 | |||
| 227 | ///Set the basis of a Field to be parsed | ||
| 228 | /** @param fieldId : id of the field that contain the sub message | ||
| 229 | * @param fieldName : name of the field | ||
| 230 | */ | ||
| 231 | 44 | void FieldParser::setBaseField(size_t fieldId, const PString & fieldName){ | |
| 232 | 44 | p_field.setId(fieldId); | |
| 233 | 44 | p_field.setName(fieldName); | |
| 234 | 44 | } | |
| 235 | |||
| 236 | ///Check if the type is compatible with the type in the FieldConfig | ||
| 237 | /** @param type : type to be checked | ||
| 238 | * @param field : configuration to be used | ||
| 239 | * @return true if the type is compatible with the field, false otherwise | ||
| 240 | */ | ||
| 241 | 22 | bool FieldParser::checkInputType(FieldType::FieldType type, const FieldConfig & field){ | |
| 242 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→18) taken 22 times.
|
22 | if(type != field.getType()){ |
| 243 | ✗ | std::cerr << "checkInputType : cannot add field '"<<field.getName()<<"' wrong type " << phoenix_fieldTypeToStr(type) << " of variables, expected type " << phoenix_fieldTypeToStr(field.getType()) << std::endl; | |
| 244 | ✗ | return false; | |
| 245 | } | ||
| 246 | 22 | return true; | |
| 247 | } | ||
| 248 | |||
| 249 | ///Load the Fields and compute the offset | ||
| 250 | /** @param[out] iter : iterator over the message to be parsed | ||
| 251 | * @param endMessage : address of the end of the message | ||
| 252 | * @param message : message to be read | ||
| 253 | * @param out : ostream to be used | ||
| 254 | * @return true on success, false otherwise | ||
| 255 | */ | ||
| 256 | 13 | bool FieldParser::loadComputeOffset(char* & iter, const char* endMessage, const char * message, std::ostream & out){ | |
| 257 | //We have to read the message from begining to end and each time we find a Field, we have to check if we want to read this particular field | ||
| 258 | 13 | MapFieldParser mapFieldParser; | |
| 259 |
1/1✓ Branch 0 (3→4) taken 13 times.
|
13 | createMapFieldParser(mapFieldParser); |
| 260 | |||
| 261 | //Then, we have to call the parseField to get the type and id of the current field | ||
| 262 | do{ | ||
| 263 | 55 | size_t fieldId(0lu), fieldType(0lu); | |
| 264 |
1/1✓ Branch 0 (5→6) taken 55 times.
|
55 | phoenix_field(fieldId, fieldType, iter); |
| 265 |
1/1✓ Branch 0 (6→7) taken 55 times.
|
55 | MapFieldParser::iterator itFind = mapFieldParser.find(fieldId); |
| 266 |
2/2✓ Branch 0 (9→10) taken 44 times.
✓ Branch 1 (9→23) taken 11 times.
|
55 | if(itFind != mapFieldParser.end()){ //The field has to be read |
| 267 |
2/3✓ Branch 0 (11→12) taken 44 times.
✓ Branch 2 (12→13) taken 44 times.
✗ Branch 3 (12→14) not taken.
|
44 | if((*itFind).second->loadComputeFieldOffset(iter, endMessage, message, fieldId, fieldType, out)){ |
| 268 |
1/1✓ Branch 0 (13→25) taken 44 times.
|
44 | mapFieldParser.erase(itFind); //The parsing it OK, so we can remove the FieldParser from the mapFieldParser |
| 269 | }else{ //Error when parsing the field | ||
| 270 | ✗ | out << "FieldParser::loadComputeOffset : error when parsing field " << fieldId << " of type " << phoenix_fieldTypeToStr(phoenix_pbTypeToFieldType(fieldType)) << std::endl; | |
| 271 | ✗ | return false; | |
| 272 | } | ||
| 273 | }else{ //The field has to be skipped | ||
| 274 |
1/2✓ Branch 0 (23→24) taken 11 times.
✗ Branch 1 (23→25) not taken.
|
11 | if(iter < endMessage){ |
| 275 |
1/1✓ Branch 0 (24→25) taken 11 times.
|
11 | phoenix_fieldSkip(iter, fieldType); |
| 276 | } | ||
| 277 | } | ||
| 278 |
6/6✓ Branch 0 (26→27) taken 51 times.
✓ Branch 1 (26→30) taken 4 times.
✓ Branch 2 (28→29) taken 42 times.
✓ Branch 3 (28→30) taken 9 times.
✓ Branch 4 (31→32) taken 42 times.
✓ Branch 5 (31→33) taken 13 times.
|
55 | }while(iter < endMessage && mapFieldParser.size() != 0lu); |
| 279 | |||
| 280 | //When the field is parsed successfully, we can compute the offset and remove it from the mapFieldParser | ||
| 281 | |||
| 282 | //Check if all fields were parsed successfully (we can just check if mapFieldParser.size() == 0lu) | ||
| 283 | 13 | bool b(mapFieldParser.size() == 0lu); | |
| 284 |
1/1✓ Branch 0 (34→35) taken 13 times.
|
13 | p_field.setIsOffsetReady(b); |
| 285 | //Then we can print the unresolved Fields by iterating the mapFieldParser | ||
| 286 |
1/2✗ Branch 0 (35→36) not taken.
✓ Branch 1 (35→51) taken 13 times.
|
13 | if(!b){ |
| 287 | ✗ | out << "FieldParser::loadComputeOffset : there are "<<mapFieldParser.size()<<" unresolved Fields in '"<<p_field.getName()<<"', id = "<<p_field.getId()<<" (those without offset) :" << std::endl; | |
| 288 | ✗ | print(out); | |
| 289 | } | ||
| 290 | 13 | return b; | |
| 291 | 13 | } | |
| 292 | |||
| 293 | ///Compute FIeld offset | ||
| 294 | /** @param[out] iter : iterator on the message to be used | ||
| 295 | * @param endMessage : end of the message | ||
| 296 | * @param message : message to be read | ||
| 297 | * @param fieldId : id of the current field | ||
| 298 | * @param fieldType : type of the current field | ||
| 299 | * @param out : ostream to be used | ||
| 300 | * @return true on success, false otherwise | ||
| 301 | */ | ||
| 302 | 44 | bool FieldParser::loadComputeFieldOffset(char* & iter, const char* endMessage, const char * message, size_t fieldId, size_t fieldType, std::ostream & out){ | |
| 303 | 44 | bool b(false); | |
| 304 |
3/4✓ Branch 0 (2→3) taken 5 times.
✓ Branch 1 (2→7) taken 27 times.
✓ Branch 2 (2→12) taken 12 times.
✗ Branch 3 (2→14) not taken.
|
44 | switch(fieldType){ |
| 305 | 5 | case 0lu: //This is an enum, and its value is in a varint | |
| 306 | 5 | p_field.setOffset((const char*)iter - message); | |
| 307 | 5 | *((size_t*)p_field.getVarPtr()) = phoenix_readVarInt(iter); | |
| 308 | 5 | b = true; | |
| 309 | 5 | break; | |
| 310 | 27 | case 1lu: //This is a uint64_t | |
| 311 | case 5lu: //This is a uint32_t | ||
| 312 | 27 | p_field.setOffset((const char*)iter - message); | |
| 313 | 27 | memcpy(p_field.getVarPtr(), iter, p_field.getTypeSize()); | |
| 314 | 27 | iter += p_field.getTypeSize(); | |
| 315 | 27 | b = true; | |
| 316 | 27 | break; | |
| 317 | 12 | case 2lu: //This is a binary array, which starts by a varint | |
| 318 | //It can be a sub message | ||
| 319 | 12 | b = loadComputeFieldOffsetArray(iter, endMessage, message, out); | |
| 320 | 12 | break; | |
| 321 | ✗ | default: | |
| 322 | ✗ | b = false; | |
| 323 | ✗ | out << "FieldParser::loadComputeFieldOffset : unknown type of Field " << fieldId << std::endl; | |
| 324 | ✗ | break; | |
| 325 | } | ||
| 326 | 44 | p_field.setIsOffsetReady(b); | |
| 327 | 44 | return b; | |
| 328 | } | ||
| 329 | |||
| 330 | ///Compute FIeld offset of an array | ||
| 331 | /** @param[out] iter : iterator on the message to be used | ||
| 332 | * @param endMessage : end of the message | ||
| 333 | * @param message : message to be read | ||
| 334 | * @param out : ostream to be used | ||
| 335 | * @return true on success, false otherwise | ||
| 336 | */ | ||
| 337 | 12 | bool FieldParser::loadComputeFieldOffsetArray(char* & iter, const char* endMessage, const char * message, std::ostream & out){ | |
| 338 | 12 | size_t nbByte = phoenix_readVarInt(iter); | |
| 339 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 12 times.
|
12 | if(nbByte == 0lu){return true;} //Whatever it is, this it empty |
| 340 | 12 | bool b(true); | |
| 341 |
2/2✓ Branch 0 (6→7) taken 8 times.
✓ Branch 1 (6→12) taken 4 times.
|
12 | if(p_field.getType() == FieldType::SUBMESSAGE){ //If this is a sub message, we parse it |
| 342 | //We have to load the sub message | ||
| 343 | 8 | b &= loadComputeOffset(iter, iter + nbByte, message, out); | |
| 344 |
1/2✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→17) taken 8 times.
|
8 | if(!b){ |
| 345 | ✗ | out << "FieldParser::loadComputeFieldOffsetArray : cannot parse submessage at offset " << ((const char*)iter - message) << std::endl; | |
| 346 | } | ||
| 347 | }else{ //If it is not a sub message, we skip it | ||
| 348 | 4 | *p_field.getNbElement() = nbByte/p_field.getTypeSize(); //Let's compute the number of element in the array | |
| 349 | 4 | p_field.setOffset((const char*)iter - message); | |
| 350 | 4 | *p_field.getArrayPtr() = (void*)iter; | |
| 351 | 4 | iter += nbByte; | |
| 352 | 4 | p_field.setIsOffsetReady(true); | |
| 353 | } | ||
| 354 | 12 | return b; | |
| 355 | } | ||
| 356 | |||
| 357 | ///Create the map of Field parser | ||
| 358 | /** @param[out] mapFieldParser : Map of FieldParser to be created | ||
| 359 | */ | ||
| 360 | 13 | void FieldParser::createMapFieldParser(MapFieldParser & mapFieldParser){ | |
| 361 |
2/2✓ Branch 0 (19→3) taken 44 times.
✓ Branch 1 (19→20) taken 13 times.
|
114 | for(VecFieldParser::iterator it(p_vecChildren.begin()); it != p_vecChildren.end(); ++it){ |
| 362 |
2/2✓ Branch 0 (7→8) taken 44 times.
✓ Branch 2 (8→9) taken 44 times.
|
88 | mapFieldParser[(*it)->p_field.getId()] = (*it); |
| 363 | } | ||
| 364 | 13 | } | |
| 365 | |||
| 366 | ///Load the Fields directly from the offset | ||
| 367 | /** @param[out] iter : iterator over the message to be parsed | ||
| 368 | * @return true on success, false otherwise | ||
| 369 | */ | ||
| 370 | 441 | bool FieldParser::loadFromOffset(char* & iter){ | |
| 371 | 441 | bool b(true); | |
| 372 |
2/2✓ Branch 0 (3→4) taken 117 times.
✓ Branch 1 (3→20) taken 324 times.
|
441 | if(p_vecChildren.size() != 0lu){ |
| 373 |
2/2✓ Branch 0 (18→5) taken 396 times.
✓ Branch 1 (18→19) taken 117 times.
|
1026 | for(VecFieldParser::iterator it(p_vecChildren.begin()); it != p_vecChildren.end(); ++it){ |
| 374 |
1/1✓ Branch 0 (7→8) taken 396 times.
|
396 | b &= (*it)->loadFromOffset(iter); |
| 375 | } | ||
| 376 | }else{ | ||
| 377 | 324 | b &= loadFieldFromOffset(iter); | |
| 378 | } | ||
| 379 | 441 | return b; | |
| 380 | } | ||
| 381 | |||
| 382 | ///Load the Field directly from the offset | ||
| 383 | /** @param[out] iter : iterator over the message to be parsed | ||
| 384 | * @return true on success, false otherwise | ||
| 385 | */ | ||
| 386 | 324 | bool FieldParser::loadFieldFromOffset(char* & iter){ | |
| 387 |
2/2✓ Branch 0 (3→4) taken 36 times.
✓ Branch 1 (3→7) taken 288 times.
|
324 | if(p_field.getIsArray()){ |
| 388 | 36 | (*p_field.getArrayPtr()) = (void*)(iter + p_field.getOffset()); //We just set the address of the array with respect to the offset | |
| 389 | }else{ | ||
| 390 |
2/2✓ Branch 0 (8→9) taken 45 times.
✓ Branch 1 (8→13) taken 243 times.
|
288 | if(p_field.getType() == FieldType::ENUM_TYPE){ |
| 391 |
1/1✓ Branch 0 (9→10) taken 45 times.
|
45 | char * tmp = iter + p_field.getOffset(); |
| 392 |
2/2✓ Branch 0 (10→11) taken 45 times.
✓ Branch 2 (11→12) taken 45 times.
|
45 | *((size_t*)p_field.getVarPtr()) = phoenix_readVarInt(tmp); |
| 393 | }else{ | ||
| 394 | 243 | memcpy(p_field.getVarPtr(), iter + p_field.getOffset(), p_field.getTypeSize()); //We copy the Field value into the variable pointer | |
| 395 | } | ||
| 396 | } | ||
| 397 | 324 | return true; | |
| 398 | } | ||
| 399 | |||
| 400 | |||
| 401 |