MAV'RIC
/home/travis/build/lis-epfl/MAVRIC_Library/util/string_util.hxx
00001 /*******************************************************************************
00002 * Copyright (c) 2009-2016, MAV'RIC Development Team
00003 * All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 * 1. Redistributions of source code must retain the above copyright notice,
00009 * this list of conditions and the following disclaimer.
00010 *
00011 * 2. Redistributions in binary form must reproduce the above copyright notice,
00012 * this list of conditions and the following disclaimer in the documentation
00013 * and/or other materials provided with the distribution.
00014 *
00015 * 3. Neither the name of the copyright holder nor the names of its contributors
00016 * may be used to endorse or promote products derived from this software without
00017 * specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 * POSSIBILITY OF SUCH DAMAGE.
00030 ******************************************************************************/
00031 
00032 /*******************************************************************************
00033  * \file    string_utils.hxx
00034  *
00035  * \author  MAV'RIC Team
00036  *
00037  * \brief   Implementation of template functions for string_util
00038  *          (see string_util.cpp for non-template implementations)
00039  *
00040  ******************************************************************************/
00041 
00042 #include "util/maths.h"
00043 
00044 namespace str
00045 {
00046 
00047 template<typename T>
00048 uint8_t* format_integer(T number, uint8_t* dest, uint8_t* length, uint8_t max_digits)
00049 {
00050     uint8_t i = max_digits + 1;
00051 
00052     /* Take Care of the sign */
00053     bool is_negativ = false;
00054     if (number < 0)
00055     {
00056         is_negativ = true;
00057         number = number * -1;
00058     }
00059 
00060     do
00061     {
00062         dest[--i] = (number % 10) + '0';
00063         number = number / 10;
00064     }
00065     while ((i >= 1) && (number > 0));
00066 
00067     /* add sign to char* */
00068     if (is_negativ)
00069     {
00070         dest[--i] = '-';
00071     }
00072 
00073     *length = max_digits + 1 - i;
00074 
00075     return dest + i;
00076 }
00077 
00078 
00079 template <typename T>
00080 uint8_t* format_floating(T num, uint8_t* dest, uint8_t* length, uint8_t after_digits, uint8_t max_int_digits)
00081 {
00082     bool is_negativ = false;
00083     if (num < 0)
00084     {
00085         is_negativ = true;
00086         num = num * -1;
00087     }
00088 
00089     /* write the integer part to char array 'dest' / 'data' */
00090     int32_t whole = floor(num);
00091     uint8_t i, j;
00092     uint8_t* data = format_integer(whole, dest + 1, &i, max_int_digits);
00093 
00094     /* add minus sign to array if needed */
00095     if (is_negativ)
00096     {
00097         data = data - 1;
00098         data[0] = '-';
00099         i++;
00100     }
00101 
00102     /* get floating point part */
00103     T after = (num - (T)whole);
00104 
00105     data[i++] = '.';
00106     for (j = 0; j < after_digits; j++)
00107     {
00108         after *= 10;
00109         char digit = (char)after;
00110         data[i++] = digit + '0';
00111         after = after - digit;
00112     }
00113 
00114     /* calc length */
00115     *length = i;
00116 
00117     return data;
00118 }
00119 
00120 
00121 template <typename T>
00122 uint8_t* format_scientific(T num, uint8_t* dest, uint8_t* length, uint8_t after_digits)
00123 {
00124     // Determine if the number is less than or equal to 1 or
00125     // greater than or equal to 10
00126     bool is_greater_10 = false;
00127     bool is_less_1 = false;
00128 
00129     // Multiply factor, for bringing the number to scientific
00130     // Notation
00131     float multiply_factor = 1.0f;
00132 
00133     // Count for number of decimal moves
00134     int decimal_moves = 0;
00135 
00136     // If number is exactly 0, do nothing
00137     if (num == 0)
00138     {
00139 
00140     }
00141     else if (num >= 10 || num <= -10) // If the number is greater than 10
00142     {
00143         is_greater_10 = true;
00144         multiply_factor = 0.1f;
00145     }
00146     else if (num < 1 && num > -1) // If the number is less than 1
00147     {
00148         is_less_1 = false;
00149         multiply_factor = 10.0f;
00150     } // If the number is between 10 and 1, do nothing
00151 
00152     // Bring number to one digit before decimal, if not already
00153     while (num >= 10 || num <= -10 || (num < 1 && num > -1 && num != 0))
00154     {
00155         // Multiply
00156         num = num * multiply_factor;
00157 
00158         // Update counter
00159         is_greater_10 ? decimal_moves++ : decimal_moves--;
00160     }
00161 
00162     // Get floating point string without the E and the rest
00163     uint8_t* data = format_floating(num, dest, length, after_digits, 1);
00164 
00165     // Append E and the exponent
00166     data[*length] = 'E';
00167     int decimal_moves_original = decimal_moves; // Create copy as decimal_moves will go to 0
00168     uint8_t exp_length = 0; // Determine how long the exponent should be
00169     if (decimal_moves_original < 0) // If there is a negative exponent, we need to add 1 for the length
00170     {
00171         exp_length++;
00172     }
00173     while (decimal_moves != 0) // Add one to length for each digit
00174     {
00175         exp_length++;
00176         decimal_moves = decimal_moves / 10;
00177     }
00178     if (exp_length == 0) // If decimal moves is still 0
00179     {
00180         exp_length++; // Make exponent length one
00181     }
00182     uint8_t* exp_length_ptr = &exp_length; // Point to the number of digits in exponent
00183     format_integer(decimal_moves_original, data + *length, exp_length_ptr, exp_length);
00184 
00185     // Update length and dest
00186     *length = *length + 1 + exp_length; // Add the E and the exponent to length
00187 
00188     return data; // Return data
00189 }
00190 };
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines