2. ETHERNET SWITCHES SOLUTIONS
AGENDA
• O que é a POCO?
• Onde é utilizada
• POCO vs boost
• Como usar no DmOS
• Cache
• Process
• Filesystem
• Application
• Net
• Notification
• DirectoryWatcher
• DynamicAny
• String
3. ETHERNET SWITCHES SOLUTIONS
O que é a POCO?
• POrtable COmponents;
• Coleção de bibliotecas C++;
• Focada em redes e aplicações;
• Altamente portável;
• Lançada em 2005, Áustria;
• Atualmente com 120 colaboradores (github);
• Compacta, ~8MB;
• Documentação de fácil leitura;
• Links:
– http://pocoproject.org
– http://pocoproject.org/documentation
5. ETHERNET SWITCHES SOLUTIONS
Onde é utilizada?
• Sim, é utilizada em sistemas embarcados:
– ACTIA Automotive
●
Sistema de diagnóstico automotivo.
– Schneider Electric
●
Plataforma de automação embarcada.
– StreamUnlimited
●
Aplicação embarcada para TV.
– Starticket
●
Dispositivo para emissão de passagem.
6. ETHERNET SWITCHES SOLUTIONS
POCO vs boost
• Poco é mais compreensível;
• Mais fácil de aprender;
• Possui suporte em pontos que a boost não dá:
– SQLite; Process; Application; Directory Watch
• Desvantagens:
– Comunidade não tão ampla como a boost;
– Documentação não extensa;
– C++11 superou alguns pontos;
– Boost cobre igualmente alguns pontos.
7. ETHERNET SWITCHES SOLUTIONS
Como usar no DmOS
• Versão Debian: 1.3.6 (2009)
• Versão atual: 1.7.3 (maio/2016)
• Versão no DmOS: 1.6.1 (agosto/2015)
10. ETHERNET SWITCHES SOLUTIONS
Como usar no DmOS
• CMake
– find_library(Poco_FOUNDATION PocoFoundation)
– find_library(Poco_UTIL PocoUtil)
– find_library(Poco_Net PocoNet)
– find_library(Poco_DATA PocoData)
– set(Poco_LIBRARIES ${Poco_FOUNDATION} ${Poco_UTIL}
${Poco_Net} ${Poco_DATA})
– target_link_libraries(${PROJECT_NAME} ${Poco_LIBRARIES})
– Bibliotecas com sufixo d são de DEBUG
11. ETHERNET SWITCHES SOLUTIONS
Como usar no DmOS
• No Buildroot:
Simbolo: BR2_PACKAGE_POCO
Localização:
→ Target packages
→ Libraries
→ Other
Filhas:
BR2_PACKAGE_POCO_CRYPTO
BR2_PACKAGE_POCO_DATA
BR2_PACKAGE_POCO_UTIL
BR2_PACKAGE_POCO_NET
12. ETHERNET SWITCHES SOLUTIONS
POCO Cache
• Boost possui circular buffer e multi-index;
• STL possui apenas seus containers;
• Atualmente manipulamos LRU no braço;
• Vantagem de utilizar Poco Cache:
– Container com tamanho limitado;
– Container com tempo limitado;
– Notificação de alteração na cache;
– Acesso ao item mais recente.
13. ETHERNET SWITCHES SOLUTIONS
POCO Cache – Least Recently Used
#include "Poco/LRUCache.h"
Poco::LRUCache<int, std::string> cache(3);
cache.add(1, "Foo"); // |-1-| -> primeiro elemento MRU
Poco::SharedPtr<std::string> elem = cache.get(1); // |-1-|
cache.add(2, "Bar"); // |-2-1-|
cache.add(3, "Qux"); // |-3-2-1-|
// Insere novo elemento mais impopular : "Couse"
cache.add(4, "Couse"); // |-4-3-2-|
assert (*elem == "Foo"); // Conteúdo ainda válido
elem = cache.get(2); // |-2-4-3-|
// Substitui Bar por Baz
cache.add(2, "Baz"); // 2 Eventos: Remove e Add
14. ETHERNET SWITCHES SOLUTIONS
POCO Cache – Time Based Expiration
#include "Poco/ExpireCache.h"
// Por padrão, expira TODOS OS VALORES após 10 min
Poco::ExpireCache<int, std::string> cache;
// Customização para 1 sec
Poco::ExpireCache<int, std::string> cache(1000);
• Uso de Poco::SharedPtr garante o tempo de vida da variável;
• Cuidado ao combinar as funções has() e get()
– Timeout entre as duas chamadas resulta em null pointer.
15. ETHERNET SWITCHES SOLUTIONS
POCO Cache – Time Based Expiration
#include "Poco/UniqueExpireCache.h"
#include “Poco/ExpirationDecorator.h”
// Expira o tempo de vida POR ELEMENTO
Poco::UniqueExpireCache<int, std::string> cache;
// Utiliza pattern Decorator para inserção de elementos
using ExprDecStr = Poco::ExpirationDecorator<std::string>;
cache.add(1, ExprDecStr(“Foo”, 1000)); // 1 sec
cache.add(2, ExprDecStr(“Bar”, 15000)); // 15 sec
poco_assert (cache.size() == 2);
std::this_thread::sleep_for(1s);
assert (cache.size() == 1);
Poco::SharedPtr<ExprDecStr> elem = cache.get(1);
assert (elem.isNull());
16. ETHERNET SWITCHES SOLUTIONS
POCO Cache – Time Based Expiration
#include "Poco/AccessExpireCache.h"
#include “Poco/UniqueAccessExpireCache.h”
// Expira o tempo de vida quando NÃO ACESSADO
Poco::AccessExpireCache<int, std::string> cache;
Poco::UniqueAccessExpireCache<int, std::string> cache;
• Dicas:
– Evitar usar has() com ExpireCache;
– O arcabouço de Cache é extensível:
Poco::AbstractStrategy;
– Poco Cache utiliza std::map, para std::set, utilize
Poco::Void como placeholder.
17. ETHERNET SWITCHES SOLUTIONS
POCO Process
• Boost Process não é oficial;
• STL não possui invocação de processos;
• Atualmente usamos system, popen ou fork;
• Vantagem de utilizar Poco Process:
– Manipular o tempo de vida do processo de forma simples.
18. ETHERNET SWITCHES SOLUTIONS
POCO Process
#include <Poco/Process.h>
Poco::Process::Args args = {“--foo=true”};
Poco::ProcessHandle handle =
Poco::Process::launch("dmos-example", args, "/bin");
// Do something ....
Poco::Process::requestTermination(handle.id());
Poco::Process::wait(handle);
19. ETHERNET SWITCHES SOLUTIONS
POCO Filesystem
• Boost filesystem é oficial;
• STL receberá filesystem no C++17;
• Atualmente usamos string para manipular path;
• Vantagem de utilizar Poco File:
– Manipulação de path (prefix, sufix, absolute, extension);
– Iterar sobre diretórios;
– Validar tipo de arquivo (is [directory | regular file]);
– Buscar arquivo no sistema;
– Validar acessos (can [write | read | exec]);
Boost
24. ETHERNET SWITCHES SOLUTIONS
POCO Filesystem – Glob
#include <Poco/Glob.h>
#include <Poco/File.h>
std::set<std::string> files;
Poco::Glob::glob("/usr/local/include/*/*.h", files);
for (const auto& it : files) {
Poco::File file(it);
assert(file.isFile());
assert(file.canRead());
}
25. ETHERNET SWITCHES SOLUTIONS
POCO Application
• Boost Application não é oficial;
• STL não possui pattern para aplicação;
• Atualmente usamos main e nada mais;
• Vantagem de utilizar Poco Application:
– Manter um padrão para construção da main;
– Manipulação de parâmetros de graça;
– Manipulação de arquivo de configuração de graça;
– Logger de graça;
– Estender sub-sistemas como filhas;
26. ETHERNET SWITCHES SOLUTIONS
POCO Application – Subsystem
// Retorna o nome do aplicativo.
const char* name() const
// Inicializa o sub-sistema
void initialize(Poco::Util::Application& app);
// Prepara o sub-sistema para morrer
void uninitialize(Poco::Util::Application& app);
// Reconfigura o sub-sistema
void reinitialize(Poco::Util::Application& app);
27. ETHERNET SWITCHES SOLUTIONS
POCO Application – Main
class FooApp : public Poco::ServerApplication {
int main(const Poco::ArgVec& args) {
Poco::TaskManager task_manager;
task_manager.start(new FooTask);
WaitForTerminationRequest(); // Aguarda SIGTERM
task_manager.cancelAll();
task_manager.joinAll();
return Poco::Util::Application::EXIT_OK;
}
};
28. ETHERNET SWITCHES SOLUTIONS
POCO Application – Handle Options
class FooApp : public Poco::ServerApplication {
void defineOptions(OptionSet& options)
{
Application::defineOptions(options);
options.addOption(
Option("help", "h", "display help information")
.required(false)
.repeatable(false)
.callback(OptionCallback<FooApp>(this,
&FooApp::handleHelp)));
}
};
29. ETHERNET SWITCHES SOLUTIONS
POCO Application – Configuration File
class FooApp : public Poco::ServerApplication {
void initialize(Poco::Application& self )
{
loadConfiguration();
if (config().hasOption(“serveruri”)) {
std::string ss = config().getString(“serveruri”);
}
Poco::Util::Application::initialize(self );
}
};
30. ETHERNET SWITCHES SOLUTIONS
POCO Application – Logger
class FooApp : public Poco::ServerApplication {
void uninitialize(Poco::Application& self)
{
logger().debug(“Finish Foo Application”);
dmmw_finish(&dmmw);
Poco::Util::Application::uninitialize(self);
}
};
31. ETHERNET SWITCHES SOLUTIONS
POCO Net
• Boost ASIO é oficial porém “complexa”;
• STL networking possui proposta para C++17;
• Atualmente usamos nativo;
• Vantagem de utilizar Poco Net:
– Manipular interface de rede (ip, mac);
– Socket (client/server);
– Conexão (Design Pattern Reactor);
– HTTP (client/server);
– TCP (client/server);
– FTP (client/server).
33. ETHERNET SWITCHES SOLUTIONS
POCO Net – Network Interface
#include <Poco/Net/NetworkInterface.h>
using Poco::Net::NetworkInterface;
NetworkInterface::NetworkInterfaceList interface_list
= Poco::Net::NetworkInterface::list();
for (const auto& it : interface_list) {
printf(“%s - %sn”, it.name(), it.address().toString());
printf("%02X:%02X:%02X:%02X:%02X:02Xn",
it.macAddress()[0], it.macAddress()[1],
it.macAddress()[2], it.macAddress()[3],
it.macAddress()[4], it.macAddress()[5]);
}
34. ETHERNET SWITCHES SOLUTIONS
POCO Notification & Events
• Boost possui signals2;
• STL possui function object;
• Atualmente usamos std::function, functor ou ponteiro;
• Vantagem de utilizar Poco Delegate:
– Pattern Observer;
37. ETHERNET SWITCHES SOLUTIONS
POCO Notification & Events - Delegate
#include <Poco/Delegate.h>
Subject subject;
std::array<Observer, 3> observers;
for (auto& observer : observers) { // Cadastra
subject.event += Poco::delegate(&observer,
&Observer::OnEvent);
}
subject.Notify(42); // Notifica todos os observadores
for (auto& observer : observers) { // Remove
subject.event -= Poco::delegate(&observer,
&Observer::OnEvent);
}
38. ETHERNET SWITCHES SOLUTIONS
POCO DirectoryWatcher
• Boost dir_monitor não é oficial;
• STL não possui suporte a eventos por arquivo;
• Atualmente usamos inotify;
• Vantagem de utilizar Poco DirectoryWatcher:
– Assistir mudanças em diretórios (não bloqueante);
– Manipulação mais fácil do que inotify.
40. ETHERNET SWITCHES SOLUTIONS
POCO DynamicAny
• Boost possui any;
• STL integrará fundamentals TS no C++17;
• Atualmente não usamos este conceito;
• Vantagem de utilizar Poco DynamicAny:
– Utilizar container dinâmico para tipos;
– Converter sem precisar saber o tipo original.
41. ETHERNET SWITCHES SOLUTIONS
POCO DynamicAny – boost::any
#include <boost/any.hpp>
using any_vector = std::vector<boost::any>;
any_vector foo = { 1, "foobar", true, 42.3 };
for (const auto& it : foo) {
std::cout << boost::any_cast<std::string>(it);
}
terminate called after throwing an instance of
'boost::exception_detail::clone_impl<boost::exception_detail::er
ror_info_injector<boost::bad_any_cast> >'
what(): boost::bad_any_cast: failed conversion using
boost::any_cast
42. ETHERNET SWITCHES SOLUTIONS
POCO DynamicAny
#include <Poco/DynamicAny.h>
using dynamic_vector = std::vector<Poco::DynamicAny>;
dynamic_vector dyn_vec = { "foo", 42, 3.14 };
for (const auto& it : dyn_vec) {
std::cout << it.convert<std::string>() << std::endl;
}
43. ETHERNET SWITCHES SOLUTIONS
POCO String
• Boost possui String Algorithms;
• STL possui apenas algorithms;
• Atualmente usamos boost e STL;
• Vantagem de utilizar Poco String:
– Atalho para algoritmos para string;
– Sobre boost, não tem vantagens;
– Economia de fosfato.
44. ETHERNET SWITCHES SOLUTIONS
POCO String – Compare ignore case
• STL
#include <algorithm>
std::equal(left.begin(), left.end(), right.begin(),
[](std::string::value_type a, std::string::value_type b) {
return std::tolower(a) == std::tolower(b);
});
• Poco
#include <Poco/String.h>
Poco::icompare(str1, str2);
• Boost
#include <boost/algorithm/string.hpp>
boost::iequals(str1, str2);
45. ETHERNET SWITCHES SOLUTIONS
POCO String – To lower case
• STL
#include <algorithm>
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
• Poco
#include <Poco/String.h>
Poco::toLower(str);
• Boost
#include <boost/algorithm/string.hpp>
boost::algorithm::to_lower(str);
boost::algorithm::to_lower_copy(str);
46. ETHERNET SWITCHES SOLUTIONS
POCO String – Trim
• STL
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
• Poco
#include <Poco/String.h>
Poco::trim(str);
• Boost
#include <boost/algorithm/string.hpp>
boost::erase_all::(str, “ ”);