2016-01-31 03:34:24 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
|
|
|
*
|
|
|
|
* This file is part of PortaPack.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "string_format.hpp"
|
|
|
|
|
|
|
|
static char* to_string_dec_uint_internal(
|
|
|
|
char* p,
|
|
|
|
uint32_t n
|
|
|
|
) {
|
|
|
|
*p = 0;
|
|
|
|
auto q = p;
|
|
|
|
|
|
|
|
do {
|
|
|
|
const uint32_t d = n % 10;
|
|
|
|
const char c = d + 48;
|
|
|
|
*(--q) = c;
|
|
|
|
n /= 10;
|
|
|
|
} while( n != 0 );
|
|
|
|
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char* to_string_dec_uint_pad_internal(
|
|
|
|
char* const term,
|
|
|
|
const uint32_t n,
|
|
|
|
const int32_t l,
|
|
|
|
const char fill
|
|
|
|
) {
|
|
|
|
auto q = to_string_dec_uint_internal(term, n);
|
|
|
|
|
|
|
|
if( fill ) {
|
|
|
|
while( (term - q) < l ) {
|
|
|
|
*(--q) = fill;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
|
2016-12-05 06:56:41 -05:00
|
|
|
std::string to_string_bin(
|
|
|
|
const uint32_t n,
|
|
|
|
const uint8_t l)
|
|
|
|
{
|
|
|
|
char p[33];
|
|
|
|
for (uint8_t c = 0; c < l; c++) {
|
2017-09-02 03:28:29 -04:00
|
|
|
if (n & (1 << (l - 1 - c)))
|
2016-12-05 06:56:41 -05:00
|
|
|
p[c] = '1';
|
|
|
|
else
|
|
|
|
p[c] = '0';
|
|
|
|
}
|
|
|
|
p[l] = 0;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2016-01-31 03:34:24 -05:00
|
|
|
std::string to_string_dec_uint(
|
|
|
|
const uint32_t n,
|
|
|
|
const int32_t l,
|
|
|
|
const char fill
|
|
|
|
) {
|
|
|
|
char p[16];
|
|
|
|
auto term = p + sizeof(p) - 1;
|
|
|
|
auto q = to_string_dec_uint_pad_internal(term, n, l, fill);
|
|
|
|
|
|
|
|
// Right justify.
|
|
|
|
while( (term - q) < l ) {
|
|
|
|
*(--q) = ' ';
|
|
|
|
}
|
|
|
|
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string to_string_dec_int(
|
|
|
|
const int32_t n,
|
|
|
|
const int32_t l,
|
|
|
|
const char fill
|
|
|
|
) {
|
|
|
|
const size_t negative = (n < 0) ? 1 : 0;
|
|
|
|
uint32_t n_abs = negative ? -n : n;
|
|
|
|
|
|
|
|
char p[16];
|
|
|
|
auto term = p + sizeof(p) - 1;
|
|
|
|
auto q = to_string_dec_uint_pad_internal(term, n_abs, l - negative, fill);
|
|
|
|
|
|
|
|
// Add sign.
|
|
|
|
if( negative ) {
|
|
|
|
*(--q) = '-';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Right justify.
|
|
|
|
while( (term - q) < l ) {
|
|
|
|
*(--q) = ' ';
|
|
|
|
}
|
|
|
|
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
|
2017-05-18 16:56:55 -04:00
|
|
|
std::string to_string_short_freq(const uint64_t f) {
|
scanner-enhanced-version
New ui_scanner, inspired on AlainD's (alain00091) PR: https://github.com/eried/portapack-mayhem/pull/80
It includes the following:
1) A big frequency numbers display.
2) A Manual scan section (you can input a frequency range (START / END), choose a STEP value from an available of standard frequency intervals, and press SCAN button.
3) An AM / WFM / NFM scan mode selector, changing "on the fly".
4) A PAUSE / RESUME button, which will make the scanner to stop upon you listening something of interest
5) AUDIO APP button, a quick shortcut into the analog audio visualizing / recording app, with the mode, frequency, amp, LNA, VGA settings already in tune with the scanner.
6) Two enums are added to freqman.hpp, reserved for compatibility with AlainD's proposed freqman's app and / or further enhancement. More on this topic:
ORIGINAL scanner just used one frequency step, when creating scanning frequency ranges, which was unacceptable. AlainD enhanced freqman in order to pass different steppings along with ranges. This seems an excellent idea, and I preserved that aspect on my current implementation of thisscanner, while adding those enums into the freqman just to keep the door open for AlainD's freqman in the future.
7) I did eliminate the extra blank spaces added by function to_string_short_freq() which created unnecessary spacing in every app where there is need for a SHORT string, from a frequency number. (SHORT!, no extra spaces!!)
8) I also maintained AlainD idea of capping the number of frequencies which are dynamically created for each range and stored inside a memory based db. While AlainD capped the number into 400 frequencies, I was able to up that value a bit more, into 500.
Cheers!
2020-07-20 15:43:24 -04:00
|
|
|
//was... to_string_dec_int(f / 1000000,4)
|
|
|
|
auto final_str = to_string_dec_int(f / 1000000) + "." + to_string_dec_int((f / 100) % 10000, 4, '0');
|
2017-04-24 13:15:57 -04:00
|
|
|
return final_str;
|
|
|
|
}
|
|
|
|
|
2017-12-10 23:14:54 -05:00
|
|
|
std::string to_string_time_ms(const uint32_t ms) {
|
|
|
|
std::string final_str { "" };
|
|
|
|
|
|
|
|
if (ms < 1000) {
|
|
|
|
final_str = to_string_dec_uint(ms) + "ms";
|
|
|
|
} else {
|
|
|
|
auto seconds = ms / 1000;
|
|
|
|
|
|
|
|
if (seconds >= 60)
|
|
|
|
final_str = to_string_dec_uint(seconds / 60) + "m";
|
|
|
|
|
|
|
|
return final_str + to_string_dec_uint(seconds % 60) + "s";
|
|
|
|
}
|
|
|
|
|
|
|
|
return final_str;
|
|
|
|
}
|
|
|
|
|
2016-11-30 01:41:55 -05:00
|
|
|
static void to_string_hex_internal(char* p, const uint64_t n, const int32_t l) {
|
2016-01-31 03:34:24 -05:00
|
|
|
const uint32_t d = n & 0xf;
|
2016-08-23 02:45:33 -04:00
|
|
|
p[l] = (d > 9) ? (d + 55) : (d + 48);
|
2016-01-31 03:34:24 -05:00
|
|
|
if( l > 0 ) {
|
|
|
|
to_string_hex_internal(p, n >> 4, l - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-01 05:42:09 -04:00
|
|
|
std::string to_string_hex(const uint64_t n, int32_t l) {
|
2016-11-30 01:41:55 -05:00
|
|
|
char p[32];
|
2017-05-01 05:42:09 -04:00
|
|
|
|
|
|
|
l = std::min(l, 31L);
|
2016-01-31 03:34:24 -05:00
|
|
|
to_string_hex_internal(p, n, l - 1);
|
|
|
|
p[l] = 0;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2017-05-01 05:42:09 -04:00
|
|
|
std::string to_string_hex_array(uint8_t * const array, const int32_t l) {
|
|
|
|
std::string str_return = "";
|
|
|
|
uint8_t bytes;
|
|
|
|
|
|
|
|
for (bytes = 0; bytes < l; bytes++)
|
|
|
|
str_return += to_string_hex(array[bytes], 2);
|
|
|
|
|
|
|
|
return str_return;
|
|
|
|
}
|
|
|
|
|
2017-08-17 07:56:47 -04:00
|
|
|
std::string to_string_datetime(const rtc::RTC& value, const TimeFormat format) {
|
|
|
|
std::string string { "" };
|
|
|
|
|
|
|
|
if (format == YMDHMS) {
|
2018-01-09 16:12:19 -05:00
|
|
|
string += to_string_dec_uint(value.year(), 4) + "/" +
|
2018-06-12 02:55:12 -04:00
|
|
|
to_string_dec_uint(value.month(), 2, '0') + "/" +
|
|
|
|
to_string_dec_uint(value.day(), 2, '0') + " ";
|
2017-08-17 07:56:47 -04:00
|
|
|
}
|
|
|
|
|
2018-06-12 02:55:12 -04:00
|
|
|
string += to_string_dec_uint(value.hour(), 2, '0') + ":" +
|
2020-06-30 16:33:38 -04:00
|
|
|
to_string_dec_uint(value.minute(), 2, '0');
|
2017-08-17 07:56:47 -04:00
|
|
|
|
|
|
|
if ((format == YMDHMS) || (format == HMS))
|
2018-06-12 02:55:12 -04:00
|
|
|
string += ":" + to_string_dec_uint(value.second(), 2, '0');
|
2017-08-17 07:56:47 -04:00
|
|
|
|
|
|
|
return string;
|
2016-08-23 08:35:14 -04:00
|
|
|
}
|
|
|
|
|
2016-01-31 03:34:24 -05:00
|
|
|
std::string to_string_timestamp(const rtc::RTC& value) {
|
2018-06-12 02:55:12 -04:00
|
|
|
return to_string_dec_uint(value.year(), 4, '0') +
|
|
|
|
to_string_dec_uint(value.month(), 2, '0') +
|
|
|
|
to_string_dec_uint(value.day(), 2, '0') +
|
|
|
|
to_string_dec_uint(value.hour(), 2, '0') +
|
|
|
|
to_string_dec_uint(value.minute(), 2, '0') +
|
|
|
|
to_string_dec_uint(value.second(), 2, '0');
|
2018-01-09 16:12:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string to_string_FAT_timestamp(const FATTimestamp& timestamp) {
|
|
|
|
return to_string_dec_uint((timestamp.FAT_date >> 9) + 1980) + "/" +
|
|
|
|
to_string_dec_uint((timestamp.FAT_date >> 5) & 0xF, 2) + "/" +
|
|
|
|
to_string_dec_uint((timestamp.FAT_date & 0x1F), 2) + " " +
|
|
|
|
to_string_dec_uint((timestamp.FAT_time >> 11), 2) + ":" +
|
|
|
|
to_string_dec_uint((timestamp.FAT_time >> 5) & 0x3F, 2);
|
2016-01-31 03:34:24 -05:00
|
|
|
}
|
2017-11-02 13:11:26 -04:00
|
|
|
|
|
|
|
std::string unit_auto_scale(double n, const uint32_t base_nano, uint32_t precision) {
|
|
|
|
const uint32_t powers_of_ten[5] = { 1, 10, 100, 1000, 10000 };
|
|
|
|
std::string string { "" };
|
|
|
|
uint32_t prefix_index = base_nano;
|
|
|
|
double integer_part;
|
|
|
|
double fractional_part;
|
|
|
|
|
|
|
|
precision = std::min((uint32_t)4, precision);
|
|
|
|
|
|
|
|
while (n > 1000) {
|
|
|
|
n /= 1000.0;
|
|
|
|
prefix_index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
fractional_part = modf(n, &integer_part) * powers_of_ten[precision];
|
|
|
|
if (fractional_part < 0)
|
|
|
|
fractional_part = -fractional_part;
|
|
|
|
|
|
|
|
string = to_string_dec_int(integer_part);
|
|
|
|
if (precision)
|
2018-01-09 16:12:19 -05:00
|
|
|
string += '.' + to_string_dec_uint(fractional_part, precision);
|
2017-11-02 13:11:26 -04:00
|
|
|
|
|
|
|
if (prefix_index != 3)
|
|
|
|
string += unit_prefix[prefix_index];
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|