Skip to content

Commit

Permalink
[common] add BinarySearch module and Stringfy (#7294)
Browse files Browse the repository at this point in the history
This commit adds set of generic binary search related functions in
OpenThread core under `BinarySearch` module. The binary search module
replaces and enhances the existing `Lookup` table module (which was
limited to search based on strings and mainly used by CLI to map from
command string to a handler function).

This commit also adds a new class `Stringfy` in `string.hpp` to help
convert from a set of `uint16_t` values (e.g., a non-sequential
`enum`) to strings using binary search in a table. The new methods are
used for converting `Coap::Code` and `IpProto` enumerations to
corresponding strings.
  • Loading branch information
abtink authored Jan 10, 2022
1 parent 91d444c commit a4cba16
Show file tree
Hide file tree
Showing 39 changed files with 410 additions and 518 deletions.
2 changes: 1 addition & 1 deletion Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ LOCAL_SRC_FILES := \
src/core/coap/coap_message.cpp \
src/core/coap/coap_secure.cpp \
src/core/common/appender.cpp \
src/core/common/binary_search.cpp \
src/core/common/crc16.cpp \
src/core/common/data.cpp \
src/core/common/error.cpp \
Expand Down Expand Up @@ -353,7 +354,6 @@ LOCAL_SRC_FILES := \
src/core/utils/heap.cpp \
src/core/utils/history_tracker.cpp \
src/core/utils/jam_detector.cpp \
src/core/utils/lookup_table.cpp \
src/core/utils/otns.cpp \
src/core/utils/parse_cmdline.cpp \
src/core/utils/ping_sender.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void Interpreter::ProcessLine(char *aBuf)
}
#endif

command = Utils::LookupTable::Find(args[0].GetCString(), sCommands);
command = BinarySearch::Find(args[0].GetCString(), sCommands);

if (command != nullptr)
{
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@
#include "common/debug.hpp"
#include "common/instance.hpp"
#include "common/type_traits.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

namespace ot {

Expand Down Expand Up @@ -229,11 +227,7 @@ class Interpreter : public Output
static constexpr uint32_t kNetworkDiagnosticTimeoutMsecs = 5000;
static constexpr uint32_t kLocateTimeoutMsecs = 2500;

struct Command
{
const char *mName;
otError (Interpreter::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<Interpreter>;

template <typename ValueType> using GetHandler = ValueType (&)(otInstance *);
template <typename ValueType> using SetHandler = void (&)(otInstance *, ValueType);
Expand Down Expand Up @@ -888,7 +882,7 @@ class Interpreter : public Output
{"version", &Interpreter::ProcessVersion},
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");

const otCliCommand *mUserCommands;
uint8_t mUserCommandsLength;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_coap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ otError Coap::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr, error = OT_ERROR_INVALID_COMMAND);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_coap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
#include <openthread/coap.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

namespace ot {
namespace Cli {
Expand Down Expand Up @@ -79,11 +77,7 @@ class Coap : private OutputWrapper
kMaxBufferSize = 16
};

struct Command
{
const char *mName;
otError (Coap::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<Coap>;

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
enum BlockType : uint8_t{
Expand Down Expand Up @@ -186,7 +180,7 @@ class Coap : private OutputWrapper
{"stop", &Coap::ProcessStop},
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");

bool mUseDefaultRequestTxParameters;
bool mUseDefaultResponseTxParameters;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_coap_secure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ otError CoapSecure::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr, error = OT_ERROR_INVALID_COMMAND);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_coap_secure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@
#include <openthread/coap_secure.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

#ifndef CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
#define CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER 0
Expand Down Expand Up @@ -87,11 +85,7 @@ class CoapSecure : private OutputWrapper
kPskIdMaxLength = 32
};

struct Command
{
const char *mName;
otError (CoapSecure::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<CoapSecure>;

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
enum BlockType : uint8_t{
Expand Down Expand Up @@ -175,7 +169,7 @@ class CoapSecure : private OutputWrapper
#endif
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapBlockwiseResource mResource;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_commissioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ otError Commissioner::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_commissioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
#include <openthread/commissioner.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD

Expand Down Expand Up @@ -81,11 +79,7 @@ class Commissioner : private OutputWrapper
kDefaultJoinerTimeout = 120, ///< Default timeout for Joiners, in seconds.
};

struct Command
{
const char *mName;
otError (Commissioner::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<Commissioner>;

otError ProcessHelp(Arg aArgs[]);
otError ProcessAnnounce(Arg aArgs[]);
Expand Down Expand Up @@ -131,7 +125,7 @@ class Commissioner : private OutputWrapper
{"state", &Commissioner::ProcessState}, {"stop", &Commissioner::ProcessStop},
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
};

} // namespace Cli
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ otError Dataset::Process(Arg aArgs[])
ExitNow(error = Print(sDataset));
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_dataset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
#include <openthread/dataset.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

namespace ot {
namespace Cli {
Expand Down Expand Up @@ -70,11 +68,7 @@ class Dataset : private OutputWrapper
otError Process(Arg aArgs[]);

private:
struct Command
{
const char *mName;
otError (Dataset::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<Dataset>;

otError Print(otOperationalDataset &aDataset);

Expand Down Expand Up @@ -136,7 +130,7 @@ class Dataset : private OutputWrapper
#endif
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");

static otOperationalDataset sDataset;
};
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ otError History::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_history.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@

#include "cli/cli_config.h"
#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE

Expand Down Expand Up @@ -81,11 +79,7 @@ class History : private OutputWrapper
static constexpr uint16_t kShortAddrBroadcast = 0xffff;
static constexpr int8_t kInvalidRss = OT_RADIO_RSSI_INVALID;

struct Command
{
const char *mName;
otError (History::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<History>;

enum RxTx : uint8_t
{
Expand Down Expand Up @@ -123,7 +117,7 @@ class History : private OutputWrapper
{"tx", &History::ProcessTx},
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
};

} // namespace Cli
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_joiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ otError Joiner::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_joiner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
#include <openthread/joiner.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

#if OPENTHREAD_CONFIG_JOINER_ENABLE

Expand Down Expand Up @@ -76,11 +74,7 @@ class Joiner : private OutputWrapper
otError Process(Arg aArgs[]);

private:
struct Command
{
const char *mName;
otError (Joiner::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<Joiner>;

otError ProcessDiscerner(Arg aArgs[]);
otError ProcessHelp(Arg aArgs[]);
Expand All @@ -97,7 +91,7 @@ class Joiner : private OutputWrapper
{"start", &Joiner::ProcessStart}, {"state", &Joiner::ProcessState}, {"stop", &Joiner::ProcessStop},
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
};

} // namespace Cli
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_network_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ otError NetworkData::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
10 changes: 2 additions & 8 deletions src/cli/cli_network_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
#include <openthread/netdata.h>

#include "cli/cli_output.hpp"
#include "utils/lookup_table.hpp"
#include "utils/parse_cmdline.hpp"

namespace ot {
namespace Cli {
Expand Down Expand Up @@ -98,11 +96,7 @@ class NetworkData : private OutputWrapper
void OutputService(const otServiceConfig &aConfig);

private:
struct Command
{
const char *mName;
otError (NetworkData::*mHandler)(Arg aArgs[]);
};
using Command = CommandEntry<NetworkData>;

otError ProcessHelp(Arg aArgs[]);
#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
Expand Down Expand Up @@ -136,7 +130,7 @@ class NetworkData : private OutputWrapper
#endif
};

static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted");
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
};

} // namespace Cli
Expand Down
22 changes: 20 additions & 2 deletions src/cli/cli_output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#include <openthread/cli.h>

#include "cli_config.h"

#include "common/binary_search.hpp"
#include "common/string.hpp"
#include "utils/parse_cmdline.hpp"

namespace ot {
Expand Down Expand Up @@ -79,6 +82,23 @@ class OutputBase

protected:
OutputBase(void) = default;

typedef Utils::CmdLineParser::Arg Arg;

template <typename Cli> struct CommandEntry
{
typedef otError (Cli::*Handler)(Arg aArgs[]);

int Compare(const char *aName) const { return strcmp(aName, mName); }

constexpr static bool AreInOrder(const CommandEntry &aFirst, const CommandEntry &aSecond)
{
return AreStringsInOrder(aFirst.mName, aSecond.mName);
}

const char *mName;
Handler mHandler;
};
};

/**
Expand Down Expand Up @@ -344,8 +364,6 @@ class Output : public OutputBase
}

protected:
typedef Utils::CmdLineParser::Arg Arg;

void OutputFormatV(const char *aFormat, va_list aArguments);

#if OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_srp_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ otError SrpClient::Process(Arg aArgs[])
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr);

error = (this->*command->mHandler)(aArgs + 1);
Expand Down
Loading

0 comments on commit a4cba16

Please sign in to comment.