Changeset 9:f909044a9f7b in rrlib_rtti_conversion for tConversionOperationSequence.cpp
- Timestamp:
- 22.09.2017 01:26:15 (2 years ago)
- Branch:
- 17.03
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tConversionOperationSequence.cpp
r8 r9 71 71 72 72 /*! Enum for binary serialization */ 73 enum tOperationSerializationFlags : uint8_t { cFULL_OPERATION = 1, cPARAMETER = 2 };73 enum tOperationSerializationFlags : uint8_t { cFULL_OPERATION = 1, cPARAMETER = 2, cSTRING_PARAMETER = 4 }; 74 74 75 75 //---------------------------------------------------------------------- … … 125 125 if (second_operation && ambiguous_operation_lookup[1]) 126 126 { 127 second_operation = &tRegisteredConversionOperation::Find( first_operation->Name(), intermediate_type, destination_type);127 second_operation = &tRegisteredConversionOperation::Find(second_operation->Name(), intermediate_type, destination_type); 128 128 } 129 129 … … 298 298 result.operations[1].operation = second_operation; 299 299 result.destination_type = last_conversion->destination_type; 300 static_cast<tConversionOperationSequence&>(result).intermediate_type = this->intermediate_type; 300 301 301 302 // Handle special case: only const offsets … … 306 307 result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object + (conversion2 ? conversion2->const_offset_reference_to_source_object : 0)); 307 308 result.flags = tFlag::cRESULT_INDEPENDENT | tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY | tFlag::cDEEPCOPY_ONLY; 308 return result; 309 } 310 311 // Handle cases where first operation is const offset 312 bool first_op_is_const_offset = conversion1->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT; 313 result.type_after_first_fixed_offset = first_op_is_const_offset ? conversion1->destination_type : conversion1->source_type; 314 if (first_op_is_const_offset) 315 { 316 result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object); 317 318 // first operation is done, so move second to first 319 conversion1 = nullptr; 320 std::swap(conversion1, conversion2); 321 result.flags |= tFlag::cFIRST_OPERATION_OPTIMIZED_AWAY; 322 } 323 result.intermediate_type = conversion1->destination_type; 324 325 // Single operation REFERENCES_SOURCE 326 if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT && (!conversion2)) 327 { 328 result.conversion_function_first = allow_reference_to_source ? conversion1->final_conversion_function : conversion1->first_conversion_function; 329 result.flags = allow_reference_to_source ? tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY : (tFlag::cRESULT_INDEPENDENT | tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION); 330 } 331 // First operation is standard or REFERENCES_SOURCE 332 else if (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 333 { 334 result.conversion_function_first = conversion2 ? conversion1->first_conversion_function : conversion1->final_conversion_function; 335 result.flags = tFlag::cRESULT_INDEPENDENT; 336 if (conversion2 && conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 337 { 338 result.conversion_function_final = conversion2->final_conversion_function; 339 } 340 else if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 341 { 342 if (conversion2->const_offset_reference_to_source_object == 0 && conversion2->source_type == conversion2->destination_type && (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || allow_reference_to_source)) 343 { 344 result.conversion_function_first = conversion1->final_conversion_function; // second operation can be optimized away 345 result.intermediate_type = result.destination_type; 346 if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 347 { 348 assert(allow_reference_to_source); 349 result.flags = tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 350 } 351 } 352 else 353 { 354 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 355 result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 356 } 357 } 358 else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) 359 { 360 result.conversion_function_final = conversion2->first_conversion_function; 361 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 362 } 363 } 364 // First operation is variable offset 365 else if (conversion1->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 366 { 367 bool reference_result = allow_reference_to_source && ((!conversion2) || conversion2->type != tConversionOptionType::STANDARD_CONVERSION_FUNCTION); 368 if (reference_result) 369 { 370 if (conversion2 && conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 371 { 372 result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 373 result.conversion_function_first = conversion1->first_conversion_function; 309 } 310 else 311 { 312 // Handle cases where first operation is const offset 313 bool first_op_is_const_offset = conversion1->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT; 314 result.type_after_first_fixed_offset = first_op_is_const_offset ? conversion1->destination_type : conversion1->source_type; 315 if (first_op_is_const_offset) 316 { 317 result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object); 318 319 // first operation is done, so move second to first 320 conversion1 = nullptr; 321 std::swap(conversion1, conversion2); 322 result.flags |= tFlag::cFIRST_OPERATION_OPTIMIZED_AWAY; 323 } 324 result.intermediate_type = conversion1->destination_type; 325 326 // Single operation REFERENCES_SOURCE 327 if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT && (!conversion2)) 328 { 329 result.conversion_function_first = allow_reference_to_source ? conversion1->final_conversion_function : conversion1->first_conversion_function; 330 result.flags = allow_reference_to_source ? tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY : (tFlag::cRESULT_INDEPENDENT | tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION); 331 } 332 // First operation is standard or REFERENCES_SOURCE 333 else if (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 334 { 335 result.conversion_function_first = conversion2 ? conversion1->first_conversion_function : conversion1->final_conversion_function; 336 result.flags = tFlag::cRESULT_INDEPENDENT; 337 if (conversion2 && conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 338 { 374 339 result.conversion_function_final = conversion2->final_conversion_function; 375 340 } 376 else 377 { 378 result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY; 379 result.get_destination_reference_function_first = conversion2->destination_reference_function; 380 if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 381 { 341 else if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 342 { 343 if (conversion2->const_offset_reference_to_source_object == 0 && conversion2->source_type == conversion2->destination_type && (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || allow_reference_to_source)) 344 { 345 result.conversion_function_first = conversion1->final_conversion_function; // second operation can be optimized away 346 result.intermediate_type = result.destination_type; 347 if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 348 { 349 assert(allow_reference_to_source); 350 result.flags = tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 351 } 352 } 353 else 354 { 355 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 382 356 result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 383 357 } 384 else if (conversion2 && conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT)385 {386 result.get_destination_reference_function_final = conversion2->destination_reference_function;387 }388 }389 }390 else391 {392 result.conversion_function_first = conversion1->first_conversion_function;393 result.flags |= tFlag::cRESULT_INDEPENDENT;394 if (!conversion2)395 {396 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION;397 }398 else if (conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION)399 {400 result.conversion_function_final = conversion2->final_conversion_function;401 }402 else if (conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT)403 {404 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION;405 result.fixed_offset_final = conversion2->const_offset_reference_to_source_object;406 358 } 407 359 else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) … … 409 361 result.conversion_function_final = conversion2->first_conversion_function; 410 362 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 363 } 364 } 365 // First operation is variable offset 366 else if (conversion1->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 367 { 368 bool reference_result = allow_reference_to_source && ((!conversion2) || conversion2->type != tConversionOptionType::STANDARD_CONVERSION_FUNCTION); 369 if (reference_result) 370 { 371 if (conversion2 && conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 372 { 373 result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 374 result.conversion_function_first = conversion1->first_conversion_function; 375 result.conversion_function_final = conversion2->final_conversion_function; 376 } 377 else 378 { 379 result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY; 380 result.get_destination_reference_function_first = conversion2->destination_reference_function; 381 if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 382 { 383 result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 384 } 385 else if (conversion2 && conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 386 { 387 result.get_destination_reference_function_final = conversion2->destination_reference_function; 388 } 389 } 390 } 391 else 392 { 393 result.conversion_function_first = conversion1->first_conversion_function; 394 result.flags |= tFlag::cRESULT_INDEPENDENT; 395 if (!conversion2) 396 { 397 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 398 } 399 else if (conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 400 { 401 result.conversion_function_final = conversion2->final_conversion_function; 402 } 403 else if (conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 404 { 405 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 406 result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 407 } 408 else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) 409 { 410 result.conversion_function_final = conversion2->first_conversion_function; 411 result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 412 } 411 413 } 412 414 } … … 471 473 auto operation = sequence[i]; 472 474 auto parameter_value = sequence.GetParameterValue(i); 473 uint8_t flags = (operation.second ? cFULL_OPERATION : 0) | (parameter_value ? cPARAMETER : 0);475 uint8_t flags = (operation.second ? cFULL_OPERATION : 0) | (parameter_value && operation.second && parameter_value.GetType() == operation.second->Parameter().GetType() ? cPARAMETER : (parameter_value ? cSTRING_PARAMETER : 0)); 474 476 stream.WriteByte(flags); 475 477 if (operation.second) … … 482 484 stream << operation.first; 483 485 } 484 if ( parameter_value)486 if (flags & cPARAMETER) 485 487 { 486 488 parameter_value.Serialize(stream); 489 } 490 else if (flags & cSTRING_PARAMETER) 491 { 492 assert(parameter_value.GetType() == tDataType<std::string>()); 493 stream << *parameter_value.Get<std::string>(); 487 494 } 488 495 } … … 534 541 throw std::runtime_error("No parameter defined in conversion operation to deserialize"); 535 542 } 536 if ((!sequence.operations[i].parameter) )543 if ((!sequence.operations[i].parameter) || sequence.operations[i].parameter->GetType() != sequence.operations[i].operation->Parameter().GetType()) 537 544 { 538 545 sequence.operations[i].parameter.reset(sequence.operations[i].operation->Parameter().GetType().CreateGenericObject()); … … 540 547 sequence.operations[i].parameter->Deserialize(stream); 541 548 } 549 else if (flags & cSTRING_PARAMETER) 550 { 551 if (!sequence.operations[i].operation) 552 { 553 throw std::runtime_error("No conversion operation found"); 554 } 555 if ((!sequence.operations[i].parameter) || sequence.operations[i].parameter->GetType() != tDataType<std::string>()) 556 { 557 sequence.operations[i].parameter.reset(tDataType<std::string>().CreateGenericObject()); 558 } 559 stream >> sequence.operations[i].parameter->GetData<std::string>(); 560 } 542 561 else 543 562 {
Note: See TracChangeset
for help on using the changeset viewer.