static cv_converter* trivialClone( cv_converter* const conv) { (void)conv; return cv_get_trivial(); }
// CONSTRUCTOR DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUnits, const char *FromUnitsHint ) { ut_unit * to = NULL ; ut_unit * from = NULL ; const char * recorded_units = ds->getUnit().c_str(); source_ds = ds; if (ToUnits != NULL) { to = ut_parse(u_system, ToUnits, UT_ASCII) ; to_units = ToUnits ; } // If the user has specified a units conversion and those units are valid ... if ( to != NULL ) { // If the recorded data file doesn't contain the units in which the data is recorded ... if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) { // If the user didn't give us a hint as to what the units are (using var@from_units) ... if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) { // set the from units to the same as the to units. cf = cv_get_trivial() ; std::cerr << "ERROR: Unable to to perform units conversion" << " because the recorded data doesn't indicate it's" << " units and no @from_units hint is provided." << std::endl; std::cerr.flush(); } else { // the user did give us a hint. from = ut_parse(u_system, FromUnitsHint, UT_ASCII) ; if ( ! from ) { std::cerr << "ERROR: Unable to to perform units conversion" << " because the recorded data doesn't indicate it's" << " units and although a @from_units hint is provided (" << "(\"" << FromUnitsHint << "\"), they are invalid." << std::endl; std::cerr.flush(); } } } else { // the recorded data file does "know" the units in which the data was recorded, // so those will be the units that we convert from. from = ut_parse(u_system, recorded_units, UT_ASCII) ; if ( !from ) { std::cerr << "ERROR: Unable to to perform units conversion because the" << " units in the data recording file appear to be corrupt." << std::endl; std::cerr.flush(); } } // If we know what units the data was recorded in ... if ( from != NULL ) { cf = ut_get_converter(from,to) ; if ( cf == NULL ) { std::cerr << "ERROR: Unable to convert from \"" << FromUnitsHint << "\" to \"" << to_units << "\" because they are incompatible." << std::endl; std::cerr.flush(); cf = cv_get_trivial() ; } } else { std::cerr << "ERROR: Unable to perform units conversion becuase the units" << " that the data is recorded in is unknown." << std::endl; cf = cv_get_trivial() ; } } else { // The user has not specified a units conversion or the units were not valid. // If the recorded data file doesn't contain the units in which the data is recorded ... if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) { // If the user didn't give us a hint as to what the units are (using var@from_units) ... if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) { cf = cv_get_trivial() ; } else { // the user did give us a hint. to_units = FromUnitsHint ; cf = cv_get_trivial() ; } } else { // the recorded data file does "know" the units in which the data was recorded, to_units = recorded_units ; cf = cv_get_trivial() ; } } if (to) ut_free(to) ; if (from) ut_free(from) ; this->begin(); }
/* * Returns a converter corresponding to the sequential application of two * other converters. The returned converter should be passed to cv_free() when * it is no longer needed. * * Arguments: * first The converter to be applied first. May be passed to cv_free() * upon return. * second The converter to be applied second. May be passed to cv_free() * upon return. * Returns: * NULL Either "first" or "second" is NULL or necessary memory couldn't * be allocated. * else A converter corresponding to the sequential application of the * given converters. If one of the input converters is the trivial * converter, then the returned converter will be the other input * converter. */ cv_converter* cv_combine( cv_converter* const first, cv_converter* const second) { cv_converter* conv; if (first == NULL || second == NULL) { conv = NULL; } else if (IS_TRIVIAL(first)) { conv = CV_CLONE(second); } else if (IS_TRIVIAL(second)) { conv = CV_CLONE(first); } else { conv = NULL; if (IS_RECIPROCAL(first)) { if (IS_RECIPROCAL(second)) { conv = cv_get_trivial(); } } else if (IS_SCALE(first)) { if (IS_SCALE(second)) { conv = cv_get_scale(first->scale.value * second->scale.value); } else if (IS_OFFSET(second)) { conv = cv_get_galilean(first->scale.value, second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean( first->scale.value * second->galilean.slope, second->galilean.intercept); } } else if (IS_OFFSET(first)) { if (IS_SCALE(second)) { conv = cv_get_galilean(second->scale.value, first->offset.value * second->scale.value); } else if (IS_OFFSET(second)) { conv = cv_get_offset(first->offset.value + second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean(second->galilean.slope, first->offset.value * second->galilean.slope + second->galilean.intercept); } } else if (IS_GALILEAN(first)) { if (IS_SCALE(second)) { conv = cv_get_galilean( second->scale.value * first->galilean.slope, second->scale.value * first->galilean.intercept); } else if (IS_OFFSET(second)) { conv = cv_get_galilean(first->galilean.slope, first->galilean.intercept + second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean( second->galilean.slope * first->galilean.slope, second->galilean.slope * first->galilean.intercept + second->galilean.intercept); } } if (conv == NULL) { /* * General case: create a composite converter. */ cv_converter* c1 = CV_CLONE(first); int error = 1; if (c1 != NULL) { cv_converter* c2 = CV_CLONE(second); if (c2 != NULL) { conv = malloc(sizeof(CompositeConverter)); if (conv != NULL) { conv->composite.ops = &compositeOps; conv->composite.first = c1; conv->composite.second = c2; error = 0; } /* "conv" allocated */ if (error) cv_free(c2); } /* "c2" allocated */ if (error) cv_free(c1); } /* "c1" allocated */ } /* "conv != NULL" */ } /* "first" & "second" not trivial */ return conv; }