random ai stuff

This commit is contained in:
matst80
2025-11-21 18:12:55 +01:00
commit 60f5783a26
187 changed files with 25197 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
IF(COMMAND cmake_policy)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
######## Non configurable options ########
SET( telldus-common_SRCS
Event.cpp
Message.cpp
Mutex.cpp
Strings.cpp
Thread.cpp
)
SET( telldus-common_HDRS
common.h
Event.h
EventHandler.h
Message.h
Mutex.h
Socket.h
Strings.h
Thread.h
)
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} )
######## Configurable options for the platform ########
######## Platforms-specific, non configurable ########
IF (APPLE)
#### Mac OS X ####
FIND_LIBRARY(ICONV_LIBRARY iconv)
ADD_DEFINITIONS( -D_MACOSX )
LIST(APPEND telldus-common_SRCS
Event_unix.cpp
EventHandler_unix.cpp
Socket_unix.cpp
stdlibc_workaround.cpp #Remove this when we drop support for 10.5
)
LIST(APPEND telldus-common_LIBRARIES
${ICONV_LIBRARY}
)
ELSEIF (WIN32)
#### Windows ####
ADD_DEFINITIONS( -DUNICODE )
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
ADD_DEFINITIONS( -D_WINDOWS )
LIST(APPEND telldus-common_SRCS
Event_win.cpp
EventHandler_win.cpp
Socket_win.cpp
)
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
#### FreeBSD ####
FIND_LIBRARY(ICONV_LIBRARY iconv)
ADD_DEFINITIONS( -D_FREEBSD )
LIST(APPEND telldus-common_SRCS
Event_unix.cpp
EventHandler_unix.cpp
Socket_unix.cpp
)
LIST(APPEND telldus-common_LIBRARIES
${ICONV_LIBRARY}
)
ELSE (APPLE)
#### Linux ####
ADD_DEFINITIONS( -D_LINUX )
LIST(APPEND telldus-common_SRCS
Event_unix.cpp
EventHandler_unix.cpp
Socket_unix.cpp
)
ENDIF (APPLE)
######## Configuring ########
ADD_LIBRARY(TelldusCommon STATIC
${telldus-common_SRCS}
${telldus-common_HDRS}
)
IF (UNIX)
SET_TARGET_PROPERTIES( TelldusCommon PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden")
ENDIF (UNIX)
TARGET_LINK_LIBRARIES( TelldusCommon ${telldus-common_LIBRARIES} )

View File

@@ -0,0 +1,88 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Event.h"
#include <list>
#include "common/EventHandler.h"
#include "common/Mutex.h"
namespace TelldusCore {
EventData::~EventData() {
}
bool EventData::isValid() const {
return false;
};
bool EventDataBase::isValid() const {
return true;
};
class EventBase::PrivateData {
public:
TelldusCore::Mutex mutex;
EventHandler *handler;
std::list<EventDataRef> eventDataList;
};
EventBase::EventBase(TelldusCore::EventHandler *handler) {
d = new PrivateData;
d->handler = handler;
}
EventBase::~EventBase(void) {
delete d;
}
void EventBase::clearHandler() {
TelldusCore::MutexLocker locker(&d->mutex);
d->handler = 0;
}
void EventBase::popSignal() {
this->takeSignal();
}
EventHandler *EventBase::handler() const {
return d->handler;
}
bool EventBase::isSignaled() {
TelldusCore::MutexLocker locker(&d->mutex);
return (d->eventDataList.size() > 0);
}
void EventBase::signal() {
signal(new EventData());
}
void EventBase::signal(EventData *eventData) {
this->signal(EventDataRef(eventData));
}
void EventBase::signal(EventDataRef eventData) {
{
TelldusCore::MutexLocker locker(&d->mutex);
d->eventDataList.push_back(eventData);
}
sendSignal();
}
EventDataRef EventBase::takeSignal() {
TelldusCore::MutexLocker locker(&d->mutex);
if (d->eventDataList.size() == 0) {
return EventDataRef(new EventData());
}
EventDataRef data = d->eventDataList.front();
d->eventDataList.pop_front();
if (d->eventDataList.size() == 0) {
this->clearSignal();
}
return data;
}
} // namespace TelldusCore

View File

@@ -0,0 +1,80 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_EVENT_H_
#define TELLDUS_CORE_COMMON_EVENT_H_
#ifndef _WINDOWS
#include <tr1/memory>
typedef void* EVENT_T;
#else
#include <windows.h>
#include <memory>
typedef HANDLE EVENT_T;
#endif
#include "common/Thread.h"
namespace TelldusCore {
class EventHandler;
class EventData {
public:
virtual ~EventData();
virtual bool isValid() const;
};
class EventDataBase : public EventData {
public:
virtual bool isValid() const;
};
typedef std::tr1::shared_ptr<EventData> EventDataRef;
class EventBase {
public:
virtual ~EventBase();
void popSignal();
bool isSignaled();
void signal();
void signal(EventData *eventData);
void signal(EventDataRef eventData);
EventDataRef takeSignal();
protected:
explicit EventBase(EventHandler *handler);
void clearHandler();
virtual void clearSignal() = 0;
EventHandler *handler() const;
virtual void sendSignal() = 0;
private:
class PrivateData;
PrivateData *d;
};
class Event : public EventBase {
public:
virtual ~Event();
protected:
explicit Event(EventHandler *handler);
EVENT_T retrieveNative();
virtual void clearSignal();
virtual void sendSignal();
private:
class PrivateData;
PrivateData *d;
friend class EventHandler;
};
typedef std::tr1::shared_ptr<Event> EventRef;
}
#endif // TELLDUS_CORE_COMMON_EVENT_H_

View File

@@ -0,0 +1,39 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_EVENTHANDLER_H_
#define TELLDUS_CORE_COMMON_EVENTHANDLER_H_
#ifdef _MSC_VER
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#include "common/Event.h"
namespace TelldusCore {
class EventHandler {
public:
EventHandler();
virtual ~EventHandler(void);
EventRef addEvent();
bool waitForAny();
protected:
void signal(Event *event);
private:
class PrivateData;
PrivateData *d;
bool listIsSignalled();
friend class Event;
};
}
#endif // TELLDUS_CORE_COMMON_EVENTHANDLER_H_

View File

@@ -0,0 +1,96 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <list>
#include "common/EventHandler.h"
#include "common/Event.h"
#include "common/Mutex.h"
#include "common/Thread.h"
namespace TelldusCore {
class EventHandler::PrivateData {
public:
pthread_cond_t event;
pthread_mutex_t mutex;
std::list<EventRef> eventList;
TelldusCore::Mutex listMutex;
bool isSignalled;
};
EventHandler::EventHandler() {
d = new PrivateData;
pthread_cond_init(&d->event, NULL);
pthread_cond_init(&d->event, NULL);
pthread_mutex_init(&d->mutex, NULL);
d->isSignalled = false;
}
EventHandler::~EventHandler(void) {
pthread_mutex_destroy(&d->mutex);
pthread_cond_destroy(&d->event);
std::list<EventRef>::const_iterator it = d->eventList.begin();
for(; it != d->eventList.end(); ++it) {
// We clear the handler if someone else still has a reference to the event
(*it)->clearHandler();
}
delete d;
}
EventRef EventHandler::addEvent() {
EventRef event(new Event(this));
TelldusCore::MutexLocker locker(&d->listMutex);
d->eventList.push_back(event);
return event;
}
bool EventHandler::listIsSignalled() {
TelldusCore::MutexLocker locker(&d->listMutex);
std::list<EventRef>::const_iterator it = d->eventList.begin();
for(; it != d->eventList.end(); ++it) {
if((*it)->isSignaled()) {
return true;
}
}
return false;
}
void EventHandler::signal(Event *event) {
pthread_mutex_lock(&d->mutex);
d->isSignalled = true;
// event->setSignaled();
pthread_cond_signal(&d->event);
pthread_mutex_unlock(&d->mutex);
}
bool EventHandler::waitForAny() {
pthread_mutex_lock(&d->mutex);
int ret;
while (!d->isSignalled) {
timeval now;
gettimeofday(&now, NULL);
uint64_t abstime_ns_large = now.tv_usec*1000 + 60000000000; // add 60 seconds wait (5 seconds before)?
timespec abstime = { now.tv_sec + (abstime_ns_large / 1000000000), abstime_ns_large % 1000000000 };
ret = pthread_cond_timedwait(&d->event, &d->mutex, &abstime);
if (ret == ETIMEDOUT) {
continue;
}
}
if (!listIsSignalled()) {
d->isSignalled = false;
}
pthread_mutex_unlock(&d->mutex);
return listIsSignalled();
}
} // namespace TelldusCore

View File

@@ -0,0 +1,76 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/EventHandler.h"
#include <windows.h>
#include <list>
#include "common/Event.h"
#include "common/Mutex.h"
namespace TelldusCore {
class EventHandler::PrivateData {
public:
HANDLE *eventArray;
EventRef *eventObjectArray;
TelldusCore::Mutex mutex;
int eventCount;
};
EventHandler::EventHandler() {
d = new PrivateData;
d->eventCount = 0;
d->eventArray = new HANDLE[0];
d->eventObjectArray = new EventRef[0];
}
EventHandler::~EventHandler(void) {
delete[] d->eventObjectArray;
delete[] d->eventArray;
delete d;
}
EventRef EventHandler::addEvent() {
EventRef event(new Event(this));
TelldusCore::MutexLocker locker(&d->mutex);
HANDLE *newArray = new HANDLE[d->eventCount+1];
EventRef *newObjectArray = new EventRef[d->eventCount+1];
for (int i = 0; i < d->eventCount; ++i) {
newArray[i] = d->eventArray[i];
newObjectArray[i] = d->eventObjectArray[i];
}
delete[] d->eventArray;
delete[] d->eventObjectArray;
d->eventArray = newArray;
d->eventObjectArray = newObjectArray;
d->eventArray[d->eventCount] = event->retrieveNative();
d->eventObjectArray[d->eventCount] = event;
++d->eventCount;
return event;
}
void EventHandler::signal(Event *event) {
}
bool EventHandler::waitForAny() {
while(1) {
int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, 1000);
if (result == WAIT_TIMEOUT) {
continue;
}
TelldusCore::MutexLocker locker(&d->mutex);
int eventIndex = result - WAIT_OBJECT_0;
if (eventIndex >= d->eventCount) {
return false;
}
return true;
}
}
} // namespace TelldusCore

View File

@@ -0,0 +1,36 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Event.h"
#include "common/EventHandler.h"
#include "common/Thread.h"
namespace TelldusCore {
class Event::PrivateData {
public:
};
Event::Event(EventHandler *handler)
:EventBase(handler) {
d = new PrivateData;
}
Event::~Event(void) {
delete d;
}
void Event::clearSignal() {
}
void Event::sendSignal() {
EventHandler *handler = this->handler();
if (handler) {
handler->signal(this);
}
}
} // namespace TelldusCore

View File

@@ -0,0 +1,40 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Event.h"
#include "common/Thread.h"
namespace TelldusCore {
class Event::PrivateData {
public:
EVENT_T event;
};
Event::Event(EventHandler *handler)
:EventBase(handler) {
d = new PrivateData;
d->event = CreateEvent(NULL, true, false, NULL);
}
Event::~Event(void) {
CloseHandle(d->event);
delete d;
}
EVENT_T Event::retrieveNative() {
return d->event;
}
void Event::clearSignal() {
ResetEvent(d->event);
}
void Event::sendSignal() {
SetEvent(d->event);
}
} // namespace TelldusCore

View File

@@ -0,0 +1,131 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Message.h"
#include <wctype.h>
#include <stdlib.h>
#include <sstream>
#include "common/Socket.h"
#include "common/Strings.h"
namespace TelldusCore {
Message::Message()
: std::wstring() {
}
Message::Message(const std::wstring &functionName)
:std::wstring() {
this->addArgument(functionName);
}
Message::~Message(void) {
}
void Message::addArgument(const std::wstring &value) {
// std::wstringstream st;
// st << (int)value.size();
this->append(TelldusCore::intToWstring(value.size())); // st.str());
this->append(L":");
this->append(value);
}
void Message::addArgument(int value) {
// std::wstringstream st;
// st << (int)value;
this->append(L"i");
this->append(TelldusCore::intToWstring(value)); // st.str());
this->append(L"s");
}
/*
void Message::addSpecialArgument(const std::wstring &value){
int i = 0;
while(i<1000000){
i++;
char numstr[21]; // enough to hold all numbers up to 64-bits
//sprintf(numstr, "%d", value.size());
//this->append(TelldusCore::charToWstring(numstr)); //.str());
itoa(value.size(), numstr, 10);
std::string test(numstr);
std::wstring temp(test.length(), L' ');
std::copy(test.begin(), test.end(), temp.begin());
this->append(temp);
this->append(L":");
this->append(value);
std::wstringstream st;
st << (int)value.size();
this->append(st.str());
this->append(L":");
this->append(value);
}
}
void Message::addSpecialArgument(int value){
int i = 0;
while(i<1000000){
i++;
//std::wstringstream st;
//st << (int)value;
this->append(L"i");
//this->append(st.str());
this->append(L"s");
}
}
*/
/*
void Message::addSpecialArgument(const char *value){
this->addSpecialArgument(TelldusCore::charToWstring(value));
}
*/
void Message::addArgument(const char *value) {
this->addArgument(TelldusCore::charToWstring(value));
}
bool Message::nextIsInt(const std::wstring &message) {
if (message.length() == 0) {
return false;
}
return (message.at(0) == 'i');
}
bool Message::nextIsString(const std::wstring &message) {
if (message.length() == 0) {
return false;
}
return (iswdigit(message.at(0)) != 0);
}
std::wstring Message::takeString(std::wstring *message) {
if (!Message::nextIsString(*message)) {
return L"";
}
size_t index = message->find(':');
int length = wideToInteger(message->substr(0, index));
std::wstring retval(message->substr(index+1, length));
message->erase(0, index+length+1);
return retval;
}
int Message::takeInt(std::wstring *message) {
if (!Message::nextIsInt(*message)) {
return 0;
}
size_t index = message->find('s');
int value = wideToInteger(message->substr(1, index - 1));
message->erase(0, index+1);
return value;
}
} // namespace TelldusCore

View File

@@ -0,0 +1,36 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_MESSAGE_H_
#define TELLDUS_CORE_COMMON_MESSAGE_H_
#include <string>
namespace TelldusCore {
class Message : public std::wstring {
public:
Message();
explicit Message(const std::wstring &functionName);
~Message(void);
void addArgument(const std::wstring &value);
// void addSpecialArgument(const std::wstring &);
// void addSpecialArgument(int);
// void addSpecialArgument(const char *);
void addArgument(int value);
void addArgument(const char *value);
static bool nextIsInt(const std::wstring &message);
static bool nextIsString(const std::wstring &message);
static std::wstring takeString(std::wstring *message);
static int takeInt(std::wstring *message);
private:
};
}
#endif // TELLDUS_CORE_COMMON_MESSAGE_H_

View File

@@ -0,0 +1,88 @@
//
// C++ Implementation: Thread
//
// Description:
//
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Mutex.h"
#ifdef _WINDOWS
#include <windows.h>
typedef HANDLE MUTEX_T;
#else
#include <pthread.h>
typedef pthread_mutex_t MUTEX_T;
#endif
#include "common/common.h"
namespace TelldusCore {
class Mutex::PrivateData {
public:
MUTEX_T mutex;
};
Mutex::Mutex() {
d = new PrivateData;
#ifdef _WINDOWS
d->mutex = CreateMutex(NULL, FALSE, NULL);
#else
pthread_mutex_init(&d->mutex, NULL);
#endif
}
Mutex::~Mutex() {
#ifdef _WINDOWS
CloseHandle(d->mutex);
#else
pthread_mutex_destroy(&d->mutex);
#endif
delete d;
}
void Mutex::lock() {
#ifdef _WINDOWS
WaitForSingleObject(d->mutex, INFINITE);
#else
pthread_mutex_lock(&d->mutex);
#endif
}
void Mutex::unlock() {
#ifdef _WINDOWS
ReleaseMutex(d->mutex);
#else
pthread_mutex_unlock(&d->mutex);
#endif
}
void LoggedMutex::lock() {
debuglog(0, "Locking");
Mutex::lock();
debuglog(0, "Locked");
}
void LoggedMutex::unlock() {
debuglog(0, "Unlocking");
Mutex::unlock();
debuglog(0, "Unlocked");
}
MutexLocker::MutexLocker(Mutex *m)
:mutex(m) {
mutex->lock();
}
MutexLocker::~MutexLocker() {
mutex->unlock();
}
} // namespace TelldusCore

View File

@@ -0,0 +1,45 @@
//
// C++ Interface: Thread
//
// Description:
//
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_MUTEX_H_
#define TELLDUS_CORE_COMMON_MUTEX_H_
namespace TelldusCore {
class Mutex {
public:
Mutex();
virtual ~Mutex();
virtual void lock();
virtual void unlock();
private:
Mutex(const Mutex&); // Disable copy
Mutex& operator = (const Mutex&);
class PrivateData;
PrivateData *d;
};
class LoggedMutex : public Mutex {
public:
void lock();
void unlock();
};
class MutexLocker {
public:
explicit MutexLocker(Mutex *m);
~MutexLocker();
private:
Mutex *mutex;
};
}
#endif // TELLDUS_CORE_COMMON_MUTEX_H_

View File

@@ -0,0 +1,39 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_SOCKET_H_
#define TELLDUS_CORE_COMMON_SOCKET_H_
#ifdef _WINDOWS
#include <windows.h>
typedef HANDLE SOCKET_T;
#else
typedef int SOCKET_T;
#endif
#include <string>
namespace TelldusCore {
class Socket {
public:
Socket();
explicit Socket(SOCKET_T hPipe);
virtual ~Socket(void);
void connect(const std::wstring &server);
bool isConnected();
std::wstring read();
std::wstring read(int timeout);
void stopReadWait();
void write(const std::wstring &msg);
private:
class PrivateData;
PrivateData *d;
};
}
#endif // TELLDUS_CORE_COMMON_SOCKET_H_

View File

@@ -0,0 +1,144 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <math.h>
#include <string>
#include "common/Socket.h"
#include "common/Mutex.h"
#include "common/Strings.h"
#define BUFSIZE 512
#if defined(_MACOSX) && !defined(SOCK_CLOEXEC)
#define SOCK_CLOEXEC 0
#endif
namespace TelldusCore {
int connectWrapper(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
return connect(sockfd, addr, addrlen);
}
class Socket::PrivateData {
public:
SOCKET_T socket;
bool connected;
fd_set infds;
Mutex mutex;
};
Socket::Socket() {
d = new PrivateData;
d->socket = 0;
d->connected = false;
FD_ZERO(&d->infds);
}
Socket::Socket(SOCKET_T socket) {
d = new PrivateData;
d->socket = socket;
FD_ZERO(&d->infds);
d->connected = true;
}
Socket::~Socket(void) {
if(d->socket) {
close(d->socket);
}
delete d;
}
void Socket::connect(const std::wstring &server) {
struct sockaddr_un remote;
socklen_t len;
if ((d->socket = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
return;
}
#if defined(_MACOSX)
int op = fcntl(d->socket, F_GETFD);
fcntl(d->socket, F_SETFD, op | FD_CLOEXEC); // OS X doesn't support SOCK_CLOEXEC yet
#endif
std::string name = "/tmp/" + std::string(server.begin(), server.end());
remote.sun_family = AF_UNIX;
snprintf(remote.sun_path, sizeof(remote.sun_path), "%s", name.c_str());
len = SUN_LEN(&remote);
if (connectWrapper(d->socket, (struct sockaddr *)&remote, len) == -1) {
return;
}
TelldusCore::MutexLocker locker(&d->mutex);
d->connected = true;
}
bool Socket::isConnected() {
TelldusCore::MutexLocker locker(&d->mutex);
return d->connected;
}
std::wstring Socket::read() {
return this->read(0);
}
std::wstring Socket::read(int timeout) {
struct timeval tv;
char inbuf[BUFSIZE];
FD_SET(d->socket, &d->infds);
std::string msg;
while(isConnected()) {
tv.tv_sec = floor(timeout / 1000.0);
tv.tv_usec = timeout % 1000;
int response = select(d->socket+1, &d->infds, NULL, NULL, &tv);
if (response == 0 && timeout > 0) {
return L"";
} else if (response <= 0) {
FD_SET(d->socket, &d->infds);
continue;
}
int received = BUFSIZE;
while(received >= (BUFSIZE - 1)) {
memset(inbuf, '\0', sizeof(inbuf));
received = recv(d->socket, inbuf, BUFSIZE - 1, 0);
if(received > 0) {
msg.append(std::string(inbuf));
}
}
if (received < 0) {
TelldusCore::MutexLocker locker(&d->mutex);
d->connected = false;
}
break;
}
return TelldusCore::charToWstring(msg.c_str());
}
void Socket::stopReadWait() {
TelldusCore::MutexLocker locker(&d->mutex);
d->connected = false;
// TODO(stefan): somehow signal the socket here?
}
void Socket::write(const std::wstring &msg) {
std::string newMsg(TelldusCore::wideToString(msg));
int sent = send(d->socket, newMsg.c_str(), newMsg.length(), 0);
if (sent < 0) {
TelldusCore::MutexLocker locker(&d->mutex);
d->connected = false;
}
}
} // namespace TelldusCore

View File

@@ -0,0 +1,187 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <AccCtrl.h>
#include <Aclapi.h>
#include <windows.h>
#include "common/common.h"
#include "common/Socket.h"
#define BUFSIZE 512
namespace TelldusCore {
class Socket::PrivateData {
public:
HANDLE hPipe;
HANDLE readEvent;
bool connected;
bool running;
};
Socket::Socket() {
d = new PrivateData;
d->hPipe = INVALID_HANDLE_VALUE;
d->connected = false;
d->running = true;
}
Socket::Socket(SOCKET_T hPipe) {
d = new PrivateData;
d->hPipe = hPipe;
d->connected = true;
d->running = true;
}
Socket::~Socket(void) {
d->running = false;
SetEvent(d->readEvent); // signal for break
if (d->hPipe != INVALID_HANDLE_VALUE) {
CloseHandle(d->hPipe);
d->hPipe = 0;
}
delete d;
}
void Socket::connect(const std::wstring &server) {
BOOL fSuccess = false;
std::wstring name(L"\\\\.\\pipe\\" + server);
d->hPipe = CreateFile(
(const wchar_t *)name.c_str(), // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_FLAG_OVERLAPPED, // default attributes
NULL); // no template file
if (d->hPipe == INVALID_HANDLE_VALUE) {
return;
}
DWORD dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(
d->hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if (!fSuccess) {
return;
}
d->connected = true;
}
void Socket::stopReadWait() {
d->running = false;
SetEvent(d->readEvent);
}
std::wstring Socket::read() {
return read(INFINITE);
}
std::wstring Socket::read(int timeout) {
wchar_t buf[BUFSIZE];
int result;
DWORD cbBytesRead = 0;
OVERLAPPED oOverlap;
memset(&oOverlap, 0, sizeof(OVERLAPPED));
d->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
oOverlap.hEvent = d->readEvent;
BOOL fSuccess = false;
std::wstring returnString;
bool moreData = true;
while(moreData) {
moreData = false;
memset(&buf, 0, sizeof(buf));
ReadFile( d->hPipe, &buf, sizeof(buf)-sizeof(wchar_t), &cbBytesRead, &oOverlap);
result = WaitForSingleObject(oOverlap.hEvent, timeout);
if(!d->running) {
CancelIo(d->hPipe);
WaitForSingleObject(oOverlap.hEvent, INFINITE);
d->readEvent = 0;
CloseHandle(oOverlap.hEvent);
return L"";
}
if (result == WAIT_TIMEOUT) {
CancelIo(d->hPipe);
// Cancel, we still need to cleanup
}
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, true);
if (!fSuccess) {
DWORD err = GetLastError();
if(err == ERROR_MORE_DATA) {
moreData = true;
} else {
buf[0] = 0;
}
if (err == ERROR_BROKEN_PIPE) {
d->connected = false;
break;
}
}
returnString.append(buf);
}
d->readEvent = 0;
CloseHandle(oOverlap.hEvent);
return returnString;
}
void Socket::write(const std::wstring &msg) {
OVERLAPPED oOverlap;
DWORD bytesWritten = 0;
int result;
BOOL fSuccess = false;
memset(&oOverlap, 0, sizeof(OVERLAPPED));
HANDLE writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
oOverlap.hEvent = writeEvent;
BOOL writeSuccess = WriteFile(d->hPipe, msg.data(), (DWORD)msg.length()*sizeof(wchar_t), &bytesWritten, &oOverlap);
result = GetLastError();
if (writeSuccess || result == ERROR_IO_PENDING) {
result = WaitForSingleObject(writeEvent, 30000);
if (result == WAIT_TIMEOUT) {
CancelIo(d->hPipe);
WaitForSingleObject(oOverlap.hEvent, INFINITE);
CloseHandle(writeEvent);
CloseHandle(d->hPipe);
d->hPipe = 0;
d->connected = false;
return;
}
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE);
}
CloseHandle(writeEvent);
if (!fSuccess) {
CloseHandle(d->hPipe);
d->hPipe = 0;
d->connected = false;
return;
}
}
bool Socket::isConnected() {
return d->connected;
}
} // namespace TelldusCore

View File

@@ -0,0 +1,276 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Strings.h"
#include <string.h>
#include <stdio.h>
#ifdef _WINDOWS
#include <windows.h>
#else
#include <iconv.h>
#endif
#include <algorithm>
#include <sstream>
#include <string>
#ifdef _MACOSX
#define WCHAR_T_ENCODING "UCS-4-INTERNAL"
#else
#define WCHAR_T_ENCODING "WCHAR_T"
#endif
#ifndef va_copy
#ifdef __va_copy
#define va_copy(a, b) __va_copy(a, b)
#else /* !__va_copy */
#define va_copy(a, b) ((a)=(b))
#endif /* __va_copy */
#endif /* va_copy */
std::wstring TelldusCore::charToWstring(const char *value) {
#ifdef _WINDOWS
// Determine size
int size = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
if (size == 0) {
return L"";
}
wchar_t *buffer;
buffer = new wchar_t[size];
memset(buffer, 0, sizeof(wchar_t)*(size));
int bytes = MultiByteToWideChar(CP_UTF8, 0, value, -1, buffer, size);
std::wstring retval(buffer);
delete[] buffer;
return retval;
#else
size_t utf8Length = strlen(value);
size_t outbytesLeft = utf8Length*sizeof(wchar_t);
// Copy the instring
char *inString = new char[utf8Length+1];
snprintf(inString, utf8Length+1, "%s", value);
// Create buffer for output
char *outString = reinterpret_cast<char*>(new wchar_t[utf8Length+1]);
memset(outString, 0, sizeof(wchar_t)*(utf8Length+1));
#ifdef _FREEBSD
const char *inPointer = inString;
#else
char *inPointer = inString;
#endif
char *outPointer = outString;
iconv_t convDesc = iconv_open(WCHAR_T_ENCODING, "UTF-8");
iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft);
iconv_close(convDesc);
std::wstring retval( reinterpret_cast<wchar_t *>(outString) );
// Cleanup
delete[] inString;
delete[] outString;
return retval;
#endif
}
int TelldusCore::charToInteger(const char *input) {
std::stringstream inputstream;
inputstream << input;
int retval;
inputstream >> retval;
return retval;
}
std::wstring TelldusCore::charUnsignedToWstring(const unsigned char value) {
std::wstringstream st;
st << value;
return st.str();
}
/**
* This method doesn't support all locales
*/
bool TelldusCore::comparei(std::wstring stringA, std::wstring stringB) {
transform(stringA.begin(), stringA.end(), stringA.begin(), toupper);
transform(stringB.begin(), stringB.end(), stringB.begin(), toupper);
return stringA == stringB;
}
std::wstring TelldusCore::intToWstring(int value) {
#ifdef _WINDOWS
// no stream used
// TODO(stefan): Make effective and safe...
wchar_t numstr[21]; // enough to hold all numbers up to 64-bits
_itow_s(value, numstr, sizeof(numstr), 10);
std::wstring newstring(numstr);
return newstring;
// return TelldusCore::charToWstring(stdstring.c_str());
// std::wstring temp = TelldusCore::charToWstring(stdstring.c_str());
// std::wstring temp(stdstring.length(), L' ');
// std::copy(stdstring.begin(), stdstring.end(), temp.begin());
// return temp;
#else
std::wstringstream st;
st << value;
return st.str();
#endif
}
std::string TelldusCore::intToString(int value) {
// Not sure if this is neecssary (for ordinary stringstream that is)
#ifdef _WINDOWS
char numstr[21]; // enough to hold all numbers up to 64-bits
_itoa_s(value, numstr, sizeof(numstr), 10);
std::string stdstring(numstr);
return stdstring;
#else
std::stringstream st;
st << value;
return st.str();
#endif
}
/*
std::wstring TelldusCore::intToWStringSafe(int value){
#ifdef _WINDOWS
//no stream used
//TODO! Make effective and safe...
char numstr[21]; // enough to hold all numbers up to 64-bits
itoa(value, numstr, 10);
std::string stdstring(numstr);
return TelldusCore::charToWstring(stdstring.c_str());
//std::wstring temp = TelldusCore::charToWstring(stdstring.c_str());
//std::wstring temp(stdstring.length(), L' ');
//std::copy(stdstring.begin(), stdstring.end(), temp.begin());
//return temp;
#else
return TelldusCore::intToWString(value);
#endif
}
*/
uint64_t TelldusCore::hexTo64l(const std::string data) {
#ifdef _WINDOWS
return _strtoui64(data.c_str(), NULL, 16);
#elif defined(_MACOSX)
return strtoq(data.c_str(), NULL, 16);
#else
return strtoull(data.c_str(), NULL, 16);
#endif
}
int TelldusCore::wideToInteger(const std::wstring &input) {
std::wstringstream inputstream;
inputstream << input;
int retval;
inputstream >> retval;
return retval;
}
std::string TelldusCore::wideToString(const std::wstring &input) {
#ifdef _WINDOWS
// Determine size
int size = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL);
if (size == 0) {
return "";
}
char *buffer;
buffer = new char[size];
memset(buffer, 0, sizeof(*buffer)*size);
int bytes = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, buffer, size, NULL, NULL);
std::string retval(buffer);
delete[] buffer;
return retval;
#else
size_t wideSize = sizeof(wchar_t)*input.length();
// We cannot know how many wide character there is yet
size_t outbytesLeft = wideSize+sizeof(char); // NOLINT(runtime/sizeof)
// Copy the instring
char *inString = reinterpret_cast<char*>(new wchar_t[input.length()+1]);
memcpy(inString, input.c_str(), wideSize+sizeof(wchar_t));
// Create buffer for output
char *outString = new char[outbytesLeft];
memset(outString, 0, sizeof(*outString)*(outbytesLeft));
#ifdef _FREEBSD
const char *inPointer = inString;
#else
char *inPointer = inString;
#endif
char *outPointer = outString;
iconv_t convDesc = iconv_open("UTF-8", WCHAR_T_ENCODING);
iconv(convDesc, &inPointer, &wideSize, &outPointer, &outbytesLeft);
iconv_close(convDesc);
std::string retval(outString);
// Cleanup
delete[] inString;
delete[] outString;
return retval;
#endif
}
std::string TelldusCore::formatf(const char *format, ...) {
va_list ap;
va_start(ap, format);
std::string retval = sformatf(format, ap);
va_end(ap);
return retval;
}
std::string TelldusCore::sformatf(const char *format, va_list ap) {
// This code is based on code from the Linux man-pages project (man vsprintf)
int n;
int size = 100; /* Guess we need no more than 100 bytes. */
char *p, *np;
if ((p = reinterpret_cast<char*>(malloc(size))) == NULL) {
return "";
}
while (1) {
/* Try to print in the allocated space. */
va_list ap2;
va_copy(ap2, ap);
n = vsnprintf(p, size, format, ap2);
va_end(ap2);
/* If that worked, return the string. */
if (n > -1 && n < size) {
std::string retval(p);
free(p);
return retval;
}
/* Else try again with more space. */
if (n > -1) { /* glibc 2.1 */
size = n+1; /* precisely what is needed */
} else { /* glibc 2.0 */
size *= 2; /* twice the old size */
}
if ((np = reinterpret_cast<char *>(realloc (p, size))) == NULL) {
free(p);
return "";
} else {
p = np;
}
}
}

View File

@@ -0,0 +1,39 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_STRINGS_H_
#define TELLDUS_CORE_COMMON_STRINGS_H_
#include <stdarg.h>
#ifdef _MSC_VER
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#include <string>
namespace TelldusCore {
std::wstring charToWstring(const char *value);
int charToInteger(const char *value);
std::wstring charUnsignedToWstring(const unsigned char value);
bool comparei(std::wstring stringA, std::wstring stringB);
std::wstring intToWstring(int value);
// std::wstring intToWStringSafe(int value);
std::string intToString(int value);
uint64_t hexTo64l(const std::string data);
std::string wideToString(const std::wstring &input);
int wideToInteger(const std::wstring &input);
std::string formatf(const char *format, ...);
std::string sformatf(const char *format, va_list ap);
}
#endif // TELLDUS_CORE_COMMON_STRINGS_H_

View File

@@ -0,0 +1,98 @@
//
// C++ Implementation: Thread
//
// Description:
//
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "common/Thread.h"
#ifdef _WINDOWS
#include <windows.h>
#endif
#include "common/EventHandler.h"
namespace TelldusCore {
class ThreadPrivate {
public:
bool running;
EventRef threadStarted;
Mutex *mutex;
#ifdef _WINDOWS
HANDLE thread;
DWORD threadId;
#else
pthread_t thread;
#endif
};
Thread::Thread() {
d = new ThreadPrivate;
d->thread = 0;
d->mutex = 0;
}
Thread::~Thread() {
delete d;
}
void Thread::start() {
#ifdef _WINDOWS
d->running = true;
d->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Thread::exec, this, 0, &d->threadId);
#else
pthread_create(&d->thread, NULL, &Thread::exec, this );
#endif
}
void Thread::startAndLock(Mutex *lock) {
EventHandler handler;
d->threadStarted = handler.addEvent();
d->mutex = lock;
this->start();
while (!handler.waitForAny()) {
continue;
}
d->threadStarted.reset();
}
bool Thread::wait() {
if (!d->thread) {
return true;
}
#ifdef _WINDOWS
while(d->running) {
WaitForSingleObject(d->thread, 200);
}
CloseHandle(d->thread);
#else
pthread_join(d->thread, 0);
#endif
return true;
}
void *Thread::exec( void *ptr ) {
Thread *t = reinterpret_cast<Thread *>(ptr);
if (t) {
if (t->d->threadStarted) {
t->d->mutex->lock();
t->d->threadStarted->signal();
}
t->run();
if (t->d->mutex) {
t->d->mutex->unlock();
}
t->d->running = false;
}
#ifdef _WINDOWS
ExitThread(0);
#endif
return 0;
}
} // namespace TelldusCore

View File

@@ -0,0 +1,37 @@
//
// C++ Interface: Thread
//
// Description:
//
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_THREAD_H_
#define TELLDUS_CORE_COMMON_THREAD_H_
#include <string>
#include "common/Mutex.h"
namespace TelldusCore {
class ThreadPrivate;
class Thread {
public:
Thread();
virtual ~Thread();
void start();
void startAndLock(Mutex *lock);
bool wait();
protected:
virtual void run() = 0;
private:
static void* exec( void *ptr );
ThreadPrivate *d;
};
}
#endif // TELLDUS_CORE_COMMON_THREAD_H_

View File

@@ -0,0 +1,108 @@
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TELLDUS_CORE_COMMON_COMMON_H_
#define TELLDUS_CORE_COMMON_COMMON_H_
#ifdef _WINDOWS
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#include <ole2.h>
#include <windows.h>
#else
#include <unistd.h>
#include <pthread.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _WINDOWS
#include <fstream> // NOLINT(readability/streams)
#endif
#include <string>
#include "common/Strings.h"
inline void msleep( const int msec) {
#ifdef _WINDOWS
Sleep(msec);
#else
usleep(msec*1000);
#endif
}
inline void dlog(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf("\n");
fflush(stdout);
}
inline void debuglogfilename(const int intMessage, const std::string strMessage, const std::string filename) {
#ifdef _WINDOWS
static bool firstRun = true;
std::ofstream file;
if (firstRun) {
file.open(filename.c_str(), std::ios::out);
firstRun = false;
} else {
file.open(filename.c_str(), std::ios::out | std::ios::app);
}
__time32_t now = _time32(0);
// Convert now to tm struct for local timezone
struct tm localtm;
_localtime32_s(&localtm, &now);
char thetime[32];
errno_t err = asctime_s(thetime, 32, &localtm);
if (!err) {
file << thetime << " [" << GetCurrentThreadId() << "] " << intMessage << " - " << strMessage << "\n";
file.flush();
file.close();
}
#elif !defined(_MACOSX) && !defined(__FreeBSD__)
pthread_t thread = pthread_self();
printf("[%i] %i - %s\n", static_cast<int>(thread), intMessage, strMessage.c_str());
fflush(stdout);
#else
printf("%i - %s\n", intMessage, strMessage.c_str());
#endif
}
inline void debuglogservice(const int intMessage, const std::string strMessage) {
std::string filename("C:/telldus_service_debug.txt");
debuglogfilename(intMessage, strMessage, filename);
}
inline void debuglog(const int intMessage, const std::string strMessage) {
std::string filename("C:/telldus_client_debug.txt");
debuglogfilename(intMessage, strMessage, filename);
}
inline char *wrapStdString( const std::string &string) {
#ifdef _WINDOWS
return reinterpret_cast<char *>(SysAllocStringByteLen(string.c_str(), (unsigned int)string.size()));
#else
char *returnVal;
returnVal = reinterpret_cast<char *>(malloc(sizeof(*returnVal) * (string.size()+1)));
snprintf(returnVal, string.size()+1, "%s", string.c_str());
return returnVal;
#endif
}
inline char *wrapStdWstring( const std::wstring &wstring) {
return wrapStdString(TelldusCore::wideToString(wstring));
}
#endif // TELLDUS_CORE_COMMON_COMMON_H_

View File

@@ -0,0 +1,73 @@
//
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <istream> // NOLINT(readability/streams)
// Workarounds for symbols that are missing from Leopard stdlibc++.dylib.
_GLIBCXX_BEGIN_NAMESPACE(std)
// From ostream_insert.h
template ostream& __ostream_insert(ostream&, const char*, streamsize);
#ifdef _GLIBCXX_USE_WCHAR_T
template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize);
#endif
// From ostream.tcc
template ostream& ostream::_M_insert(long); // NOLINT(runtime/int)
template ostream& ostream::_M_insert(unsigned long); // NOLINT(runtime/int)
template ostream& ostream::_M_insert(bool); // NOLINT(readability/function)
#ifdef _GLIBCXX_USE_LONG_LONG
template ostream& ostream::_M_insert(long long); // NOLINT(runtime/int)
template ostream& ostream::_M_insert(unsigned long long); // NOLINT(runtime/int)
#endif
template ostream& ostream::_M_insert(double); // NOLINT(readability/function)
template ostream& ostream::_M_insert(long double);
template ostream& ostream::_M_insert(const void*);
#ifdef _GLIBCXX_USE_WCHAR_T
template wostream& wostream::_M_insert(long); // NOLINT(runtime/int)
template wostream& wostream::_M_insert(unsigned long); // NOLINT(runtime/int)
template wostream& wostream::_M_insert(bool); // NOLINT(readability/function)
#ifdef _GLIBCXX_USE_LONG_LONG
template wostream& wostream::_M_insert(long long); // NOLINT(runtime/int)
template wostream& wostream::_M_insert(unsigned long long); // NOLINT(runtime/int)
#endif
template wostream& wostream::_M_insert(double); // NOLINT(readability/function)
template wostream& wostream::_M_insert(long double);
template wostream& wostream::_M_insert(const void*);
#endif
// From istream.tcc
template istream& istream::_M_extract(unsigned short&); // NOLINT(runtime/int)
template istream& istream::_M_extract(unsigned int&);
template istream& istream::_M_extract(long&); // NOLINT(runtime/int)
template istream& istream::_M_extract(unsigned long&); // NOLINT(runtime/int)
template istream& istream::_M_extract(bool&);
#ifdef _GLIBCXX_USE_LONG_LONG
template istream& istream::_M_extract(long long&); // NOLINT(runtime/int)
template istream& istream::_M_extract(unsigned long long&); // NOLINT(runtime/int)
#endif
template istream& istream::_M_extract(float&);
template istream& istream::_M_extract(double&);
template istream& istream::_M_extract(long double&);
template istream& istream::_M_extract(void*&);
#ifdef _GLIBCXX_USE_WCHAR_T
template wistream& wistream::_M_extract(unsigned short&); // NOLINT(runtime/int)
template wistream& wistream::_M_extract(unsigned int&);
template wistream& wistream::_M_extract(long&); // NOLINT(runtime/int)
template wistream& wistream::_M_extract(unsigned long&); // NOLINT(runtime/int)
template wistream& wistream::_M_extract(bool&);
#ifdef _GLIBCXX_USE_LONG_LONG
template wistream& wistream::_M_extract(long long&); // NOLINT(runtime/int)
template wistream& wistream::_M_extract(unsigned long long&); // NOLINT(runtime/int)
#endif
template wistream& wistream::_M_extract(float&);
template wistream& wistream::_M_extract(double&);
template wistream& wistream::_M_extract(long double&);
template wistream& wistream::_M_extract(void*&);
#endif
_GLIBCXX_END_NAMESPACE