Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable limits - Refactor current options #643

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "roc_core/parse_duration.h"
#include "roc_core/parse_units.h"
#include "roc_core/log.h"
#include "roc_core/stddefs.h"

Expand Down Expand Up @@ -84,5 +84,67 @@ bool parse_duration(const char* str, nanoseconds_t& result) {
return true;
}

bool parse_size(const char* str, size_t& result) {
if (str == NULL) {
roc_log(LogError, "parse size: string is null");
return false;
}

const size_t kibibyte = 1024;
const size_t mebibyte = 1024 * kibibyte;
const size_t gibibyte = 1024 * mebibyte;

size_t multiplier = 1;

const size_t str_len = strlen(str);
const char* suffix;

// suffix is optional.
if ((suffix = find_suffix(str, str_len, "G"))) {
multiplier = gibibyte;
} else if ((suffix = find_suffix(str, str_len, "M"))) {
multiplier = mebibyte;
} else if ((suffix = find_suffix(str, str_len, "K"))) {
multiplier = kibibyte;
}

if (!isdigit(*str)) {
roc_log(LogError,
"parse size: invalid format, not a number, expected <number>[<suffix>], "
"where suffix=<K|M|G>");
return false;
}

char* number_end = NULL;
unsigned long long number = strtoull(str, &number_end, 10);

if (number == ULLONG_MAX || (!suffix && *number_end != '\0')
|| (suffix && number_end != suffix)) {
roc_log(LogError,
"parse size: invalid format, can't parse number, expected "
"<number>[<suffix>], where suffix=<K|M|G>");
return false;
}

size_t number_converted = number;
if (number_converted < number) {
roc_log(LogError,
"parse size: too large, can't parse number, expected "
"<number>[<suffix>], where suffix=<K|M|G>");
return false;
}

size_t output = number_converted * multiplier;
if (output / multiplier != number_converted) {
roc_log(LogError,
"parse size: too large, can't parse number, expected "
"<number>[<suffix>], where suffix=<K|M|G>");
return false;
}

result = output;
return true;
}

} // namespace core
} // namespace roc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

//! @file roc_core/parse_duration.h
//! @brief Parse duration.
//! @file roc_core/parse_units.h
//! @brief Parse units like duration, size, etc.

#ifndef ROC_CORE_PARSE_DURATION_H_
#define ROC_CORE_PARSE_DURATION_H_
#ifndef ROC_CORE_PARSE_UNITS_H_
#define ROC_CORE_PARSE_UNITS_H_

#include "roc_core/attributes.h"
#include "roc_core/time.h"
Expand All @@ -33,7 +33,20 @@ namespace core {
//! false if string can't be parsed.
ROC_ATTR_NODISCARD bool parse_duration(const char* string, nanoseconds_t& result);

//! Parse size from string.
//!
//! @remarks
//! The input string should be in one of the following forms:
//! - "<number>"
//! - "<number>K"
//! - "<number>M"
//! - "<number>G"
//!
//! @returns
//! false if string can't be parsed.
ROC_ATTR_NODISCARD bool parse_size(const char* string, size_t& result);

} // namespace core
} // namespace roc

#endif // ROC_CORE_PARSE_DURATION_H_
#endif // ROC_CORE_PARSE_UNITS_H_
57 changes: 0 additions & 57 deletions src/tests/roc_core/test_parse_duration.cpp

This file was deleted.

107 changes: 107 additions & 0 deletions src/tests/roc_core/test_parse_units.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2015 Roc Streaming authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <CppUTest/TestHarness.h>

#include "roc_core/parse_units.h"
#include "roc_core/time.h"

namespace roc {
namespace core {

TEST_GROUP(parse_units) {};

TEST(parse_units, parse_duration_error) {
nanoseconds_t result = 0;

CHECK(!parse_duration(NULL, result));
CHECK(!parse_duration("", result));
CHECK(!parse_duration("1", result));
CHECK(!parse_duration("s", result));
CHECK(!parse_duration("1 s", result));
CHECK(!parse_duration(" 1s", result));
CHECK(!parse_duration("1s ", result));
CHECK(!parse_duration("!s", result));
CHECK(!parse_duration("s1", result));
CHECK(!parse_duration("1x", result));
}

TEST(parse_units, parse_duration) {
nanoseconds_t result = 0;

CHECK(parse_duration("123ns", result));
CHECK(result == 123 * Nanosecond);

CHECK(parse_duration("123us", result));
CHECK(result == 123 * Microsecond);

CHECK(parse_duration("123ms", result));
CHECK(result == 123 * Millisecond);

CHECK(parse_duration("123s", result));
CHECK(result == 123 * Second);

CHECK(parse_duration("123m", result));
CHECK(result == 123 * Minute);

CHECK(parse_duration("123h", result));
CHECK(result == 123 * Hour);
}

TEST(parse_units, parse_size_error) {
size_t result = 0;

CHECK(!parse_size(NULL, result));
CHECK(!parse_size("", result));
CHECK(!parse_size("K", result));
CHECK(!parse_size("1 K", result));
CHECK(!parse_size(" 1K", result));
CHECK(!parse_size("1K ", result));
CHECK(!parse_size("!K", result));
CHECK(!parse_size("K1", result));
CHECK(!parse_size("1x", result));
}

TEST(parse_units, parse_size) {
size_t result = 0;

const size_t kibibyte = 1024;
const size_t mebibyte = 1024 * kibibyte;
const size_t gibibyte = 1024 * mebibyte;

CHECK(parse_size("123", result));
CHECK(result == 123);

CHECK(parse_size("123K", result));
CHECK(result == 123 * kibibyte);

CHECK(parse_size("123M", result));
CHECK(result == 123 * mebibyte);

CHECK(parse_size("1G", result));
CHECK(result == 1 * gibibyte);
}

TEST(parse_units, parse_size_overflows_due_to_sizeof_size_t) {
if (SIZE_MAX < ULLONG_MAX) {
char s[32];
snprintf(s, 32, "%llu", ULLONG_MAX - 1);
size_t result = 0;
CHECK_FALSE(parse_size(s, result));
}
}

TEST(parse_units, parse_size_overflows_due_to_multiplier) {
char s[32];
snprintf(s, 32, "%zuK", SIZE_MAX - 1);
size_t result = 0;
CHECK_FALSE(parse_size(s, result));
}

} // namespace core
} // namespace roc
2 changes: 1 addition & 1 deletion src/tools/roc_copy/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "roc_core/crash_handler.h"
#include "roc_core/heap_arena.h"
#include "roc_core/log.h"
#include "roc_core/parse_duration.h"
#include "roc_core/parse_units.h"
#include "roc_core/scoped_ptr.h"
#include "roc_pipeline/transcoder_sink.h"
#include "roc_sndio/backend_dispatcher.h"
Expand Down
15 changes: 9 additions & 6 deletions src/tools/roc_recv/cmdline.ggo
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ section "Options"
option "choppy-play-timeout" - "Choppy playback timeout, TIME units"
string optional

option "packet-limit" - "Maximum packet size, in bytes"
int optional
option "frame-len" - "Duration of the internal frames, TIME units"
typestr="TIME" string optional

option "frame-limit" - "Maximum internal frame size, in bytes"
int optional
option "max-packet-size" - "Maximum packet size, in SIZE units"
typestr="SIZE" string optional

option "frame-length" - "Duration of the internal frames, TIME units"
typestr="TIME" string optional
option "max-frame-size" - "Maximum internal frame size, in SIZE units"
typestr="SIZE" string optional

option "rate" - "Override output sample rate, Hz"
int optional
Expand Down Expand Up @@ -92,6 +92,9 @@ FILE_FORMAT is the output file format name, e.g.:
TIME is an integer number with a suffix, e.g.:
123ns; 123us; 123ms; 123s; 123m; 123h;

SIZE is an integer number with an optional suffix, e.g.:
123; 123K; 123M; 123G;

Use --list-supported option to print the list of the supported
URI schemes and file formats.

Expand Down
Loading
Loading