mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-01 02:41:48 +00:00
Move common utility classes to wpiutil library. (#79)
This is a breaking change to dependencies that use the static ntcore library. Unless the wpiutil library is also linked, linker errors will result. This does not affect the shared ntcore library.
This commit is contained in:
23
wpiutil/include/support/Base64.h
Normal file
23
wpiutil/include/support/Base64.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_BASE64_H_
|
||||
#define WPIUTIL_SUPPORT_BASE64_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "llvm/StringRef.h"
|
||||
|
||||
namespace wpi {
|
||||
|
||||
std::size_t Base64Decode(llvm::StringRef encoded, std::string* plain);
|
||||
void Base64Encode(llvm::StringRef plain, std::string* encoded);
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_BASE64_H_
|
||||
83
wpiutil/include/support/ConcurrentQueue.h
Normal file
83
wpiutil/include/support/ConcurrentQueue.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com
|
||||
// Subject to the BSD 2-Clause License
|
||||
// - see < http://opensource.org/licenses/BSD-2-Clause>
|
||||
//
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
#define WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
template <typename T>
|
||||
class ConcurrentQueue {
|
||||
public:
|
||||
bool empty() const {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
return queue_.empty();
|
||||
}
|
||||
|
||||
typename std::queue<T>::size_type size() const {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
return queue_.size();
|
||||
}
|
||||
|
||||
T pop() {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty()) {
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
auto item = std::move(queue_.front());
|
||||
queue_.pop();
|
||||
return item;
|
||||
}
|
||||
|
||||
void pop(T& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty()) {
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
item = queue_.front();
|
||||
queue_.pop();
|
||||
}
|
||||
|
||||
void push(const T& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(item);
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
void push(T&& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(std::forward<T>(item));
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void emplace(Args&&... args) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.emplace(std::forward<Args>(args)...);
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
ConcurrentQueue() = default;
|
||||
ConcurrentQueue(const ConcurrentQueue&) = delete;
|
||||
ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;
|
||||
|
||||
private:
|
||||
std::queue<T> queue_;
|
||||
mutable std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
82
wpiutil/include/support/Logger.h
Normal file
82
wpiutil/include/support/Logger.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_LOGGER_H_
|
||||
#define WPIUTIL_SUPPORT_LOGGER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
enum LogLevel {
|
||||
WPI_LOG_CRITICAL = 50,
|
||||
WPI_LOG_ERROR = 40,
|
||||
WPI_LOG_WARNING = 30,
|
||||
WPI_LOG_INFO = 20,
|
||||
WPI_LOG_DEBUG = 10,
|
||||
WPI_LOG_DEBUG1 = 9,
|
||||
WPI_LOG_DEBUG2 = 8,
|
||||
WPI_LOG_DEBUG3 = 7,
|
||||
WPI_LOG_DEBUG4 = 6
|
||||
};
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
typedef std::function<void(unsigned int level, const char* file,
|
||||
unsigned int line, const char* msg)> LogFunc;
|
||||
|
||||
void SetLogger(LogFunc func) { m_func = func; }
|
||||
|
||||
void set_min_level(unsigned int level) { m_min_level = level; }
|
||||
unsigned int min_level() const { return m_min_level; }
|
||||
|
||||
void Log(unsigned int level, const char* file, unsigned int line,
|
||||
const char* msg) {
|
||||
if (!m_func || level < m_min_level) return;
|
||||
m_func(level, file, line, msg);
|
||||
}
|
||||
|
||||
bool HasLogger() const { return m_func != nullptr; }
|
||||
|
||||
private:
|
||||
LogFunc m_func;
|
||||
unsigned int m_min_level = 20;
|
||||
};
|
||||
|
||||
#define WPI_LOG(logger_inst, level, x) \
|
||||
do { \
|
||||
::wpi::Logger& WPI_logger_ = logger_inst; \
|
||||
if (WPI_logger_.min_level() <= level && WPI_logger_.HasLogger()) { \
|
||||
std::ostringstream oss; \
|
||||
oss << x; \
|
||||
WPI_logger_.Log(level, __FILE__, __LINE__, oss.str().c_str()); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WPI_ERROR(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_ERROR, x)
|
||||
#define WPI_WARNING(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_WARNING, x)
|
||||
#define WPI_INFO(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_INFO, x)
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define WPI_DEBUG(inst, x) do {} while (0)
|
||||
#define WPI_DEBUG1(inst, x) do {} while (0)
|
||||
#define WPI_DEBUG2(inst, x) do {} while (0)
|
||||
#define WPI_DEBUG3(inst, x) do {} while (0)
|
||||
#define WPI_DEBUG4(inst, x) do {} while (0)
|
||||
#else
|
||||
#define WPI_DEBUG(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG, x)
|
||||
#define WPI_DEBUG1(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG1, x)
|
||||
#define WPI_DEBUG2(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG2, x)
|
||||
#define WPI_DEBUG3(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG3, x)
|
||||
#define WPI_DEBUG4(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG4, x)
|
||||
#endif
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_LOGGER_H_
|
||||
93
wpiutil/include/support/SafeThread.h
Normal file
93
wpiutil/include/support/SafeThread.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_SAFETHREAD_H_
|
||||
#define WPIUTIL_SUPPORT_SAFETHREAD_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
// Base class for SafeThreadOwner threads.
|
||||
class SafeThread {
|
||||
public:
|
||||
virtual ~SafeThread() = default;
|
||||
virtual void Main() = 0;
|
||||
|
||||
std::mutex m_mutex;
|
||||
bool m_active = true;
|
||||
std::condition_variable m_cond;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Non-template proxy base class for common proxy code.
|
||||
class SafeThreadProxyBase {
|
||||
public:
|
||||
SafeThreadProxyBase(SafeThread* thr) : m_thread(thr) {
|
||||
if (!m_thread) return;
|
||||
std::unique_lock<std::mutex>(m_thread->m_mutex).swap(m_lock);
|
||||
if (!m_thread->m_active) {
|
||||
m_lock.unlock();
|
||||
m_thread = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
explicit operator bool() const { return m_thread != nullptr; }
|
||||
std::unique_lock<std::mutex>& GetLock() { return m_lock; }
|
||||
|
||||
protected:
|
||||
SafeThread* m_thread;
|
||||
std::unique_lock<std::mutex> m_lock;
|
||||
};
|
||||
|
||||
// A proxy for SafeThread.
|
||||
// Also serves as a scoped lock on SafeThread::m_mutex.
|
||||
template <typename T>
|
||||
class SafeThreadProxy : public SafeThreadProxyBase {
|
||||
public:
|
||||
SafeThreadProxy(SafeThread* thr) : SafeThreadProxyBase(thr) {}
|
||||
T& operator*() const { return *static_cast<T*>(m_thread); }
|
||||
T* operator->() const { return static_cast<T*>(m_thread); }
|
||||
};
|
||||
|
||||
// Non-template owner base class for common owner code.
|
||||
class SafeThreadOwnerBase {
|
||||
public:
|
||||
void Stop();
|
||||
|
||||
protected:
|
||||
SafeThreadOwnerBase() { m_thread = nullptr; }
|
||||
SafeThreadOwnerBase(const SafeThreadOwnerBase&) = delete;
|
||||
SafeThreadOwnerBase& operator=(const SafeThreadOwnerBase&) = delete;
|
||||
~SafeThreadOwnerBase() { Stop(); }
|
||||
|
||||
void Start(SafeThread* thr);
|
||||
SafeThread* GetThread() { return m_thread.load(); }
|
||||
|
||||
private:
|
||||
std::atomic<SafeThread*> m_thread;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
class SafeThreadOwner : public detail::SafeThreadOwnerBase {
|
||||
public:
|
||||
void Start() { Start(new T); }
|
||||
void Start(T* thr) { detail::SafeThreadOwnerBase::Start(thr); }
|
||||
|
||||
using Proxy = typename detail::SafeThreadProxy<T>;
|
||||
Proxy GetThread() { return Proxy(detail::SafeThreadOwnerBase::GetThread()); }
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_SAFETHREAD_H_
|
||||
49
wpiutil/include/support/atomic_static.h
Normal file
49
wpiutil/include/support/atomic_static.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_ATOMIC_STATIC_H_
|
||||
#define WPIUTIL_SUPPORT_ATOMIC_STATIC_H_
|
||||
|
||||
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
||||
|
||||
// Just use a local static. This is thread-safe per
|
||||
// http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/
|
||||
|
||||
// Per https://msdn.microsoft.com/en-us/library/Hh567368.aspx "Magic Statics"
|
||||
// are supported in Visual Studio 2015 but not in earlier versions.
|
||||
#define ATOMIC_STATIC(cls, inst) static cls inst
|
||||
#define ATOMIC_STATIC_DECL(cls)
|
||||
#define ATOMIC_STATIC_INIT(cls)
|
||||
|
||||
#else
|
||||
// From http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#define ATOMIC_STATIC(cls, inst) \
|
||||
cls* inst##tmp = m_instance.load(std::memory_order_acquire); \
|
||||
if (inst##tmp == nullptr) { \
|
||||
std::lock_guard<std::mutex> lock(m_instance_mutex); \
|
||||
inst##tmp = m_instance.load(std::memory_order_relaxed); \
|
||||
if (inst##tmp == nullptr) { \
|
||||
inst##tmp = new cls; \
|
||||
m_instance.store(inst##tmp, std::memory_order_release); \
|
||||
} \
|
||||
} \
|
||||
cls& inst = *inst##tmp
|
||||
|
||||
#define ATOMIC_STATIC_DECL(cls) \
|
||||
static std::atomic<cls*> m_instance; \
|
||||
static std::mutex m_instance_mutex;
|
||||
|
||||
#define ATOMIC_STATIC_INIT(cls) \
|
||||
std::atomic<cls*> cls::m_instance; \
|
||||
std::mutex cls::m_instance_mutex;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_ATOMIC_STATIC_H_
|
||||
26
wpiutil/include/support/leb128.h
Normal file
26
wpiutil/include/support/leb128.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_LEB128_H_
|
||||
#define WPIUTIL_SUPPORT_LEB128_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "llvm/SmallVector.h"
|
||||
|
||||
namespace wpi {
|
||||
|
||||
class raw_istream;
|
||||
|
||||
std::size_t SizeUleb128(unsigned long val);
|
||||
std::size_t WriteUleb128(llvm::SmallVectorImpl<char>& dest, unsigned long val);
|
||||
std::size_t ReadUleb128(const char* addr, unsigned long* ret);
|
||||
bool ReadUleb128(raw_istream& is, unsigned long* ret);
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_LEB128_H_
|
||||
40
wpiutil/include/support/raw_istream.h
Normal file
40
wpiutil/include/support/raw_istream.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_RAW_ISTREAM_H_
|
||||
#define WPIUTIL_SUPPORT_RAW_ISTREAM_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
class raw_istream {
|
||||
public:
|
||||
raw_istream() = default;
|
||||
virtual ~raw_istream() = default;
|
||||
virtual bool read(void* data, std::size_t len) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
raw_istream(const raw_istream&) = delete;
|
||||
raw_istream& operator=(const raw_istream&) = delete;
|
||||
};
|
||||
|
||||
class raw_mem_istream : public raw_istream {
|
||||
public:
|
||||
raw_mem_istream(const char* mem, std::size_t len) : m_cur(mem), m_left(len) {}
|
||||
virtual ~raw_mem_istream() = default;
|
||||
virtual bool read(void* data, std::size_t len);
|
||||
virtual void close() {}
|
||||
|
||||
private:
|
||||
const char* m_cur;
|
||||
std::size_t m_left;
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_RAW_ISTREAM_H_
|
||||
31
wpiutil/include/support/raw_socket_istream.h
Normal file
31
wpiutil/include/support/raw_socket_istream.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_
|
||||
#define WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_
|
||||
|
||||
#include "support/raw_istream.h"
|
||||
#include "tcpsockets/NetworkStream.h"
|
||||
|
||||
namespace wpi {
|
||||
|
||||
class raw_socket_istream : public raw_istream {
|
||||
public:
|
||||
raw_socket_istream(NetworkStream& stream, int timeout = 0)
|
||||
: m_stream(stream), m_timeout(timeout) {}
|
||||
virtual ~raw_socket_istream() = default;
|
||||
virtual bool read(void* data, std::size_t len);
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
NetworkStream& m_stream;
|
||||
int m_timeout;
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_
|
||||
28
wpiutil/include/support/timestamp.h
Normal file
28
wpiutil/include/support/timestamp.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#ifndef WPIUTIL_SUPPORT_TIMESTAMP_H_
|
||||
#define WPIUTIL_SUPPORT_TIMESTAMP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
unsigned long long WPI_Now(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi {
|
||||
|
||||
unsigned long long Now();
|
||||
|
||||
} // namespace wpi
|
||||
#endif
|
||||
|
||||
#endif // WPIUTIL_SUPPORT_TIMESTAMP_H_
|
||||
Reference in New Issue
Block a user