PIConstChars

This commit is contained in:
2022-04-29 23:53:07 +03:00
parent 8c8553a6af
commit 6881fd13b7
9 changed files with 294 additions and 29 deletions

View File

@@ -0,0 +1,47 @@
/*
PIP - Platform Independent Primitives
C-String class
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piconstchars.h"
//! \addtogroup Core
//! \{
//! \~\class PIConstChars piconstchars.h
//! \~\brief
//! \~english C-String class
//! \~russian Класс C-строки
//!
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english
//! This is wrapper around \c const char * string. %PIConstChars doesn`t
//! copy string, just save pointer and size.
//!
//! Provides API similar to string, with information and compare methods.
//!
//! Used to more handly works with ordinary C-strings.
//!
//! \~russian
//! Это обертка вокруг \c const char * строки. %PIConstChars не скопирует
//! строку, а только хранит указатель и размер.
//!
//! Предоставляет API схожий с обычной строкой, с методами сравнения и информационными.
//!
//! Используется для более удобной работы с обычными C-строками.
//!
//! \}

View File

@@ -0,0 +1,187 @@
/*! \file piconstchars.h
* \ingroup Core
* \brief
* \~english C-String class
* \~russian Класс C-строки
*/
/*
PIP - Platform Independent Primitives
C-String class
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICONSTCHARS_H
#define PICONSTCHARS_H
#include "picout.h"
class PIP_EXPORT PIConstChars {
public:
//! \~english Contructs an null string.
//! \~russian Создает нулевую строку.
PIConstChars() {}
//! \~english Contructs string from C-string "string".
//! \~russian Создает строку из C-строки "string".
PIConstChars(const char * string) {
str = string;
len = strlen(string);
}
//! \~english Contructs string from "size" characters of buffer "data".
//! \~russian Создает строку из "size" символов массива "data".
PIConstChars(const char * data, size_t size) {
str = data;
len = size;
}
//! \~english Contructs a copy of string.
//! \~russian Создает копию строки.
PIConstChars(const PIConstChars & o) {
str = o.str;
len = o.len;
}
//! \~english Read-only access to character by `index`.
//! \~russian Доступ на чтение к символу по индексу `index`.
inline const char & operator [](size_t index) const {return str[index];}
//! \~english Returns \c char * string pointer.
//! \~russian Возвращает \c char * указатель строки.
inline const char * data() const {return str;}
//! \~english Returns \c true if string doesn`t have any data.
//! \~russian Возвращает \c true если строка не имеет данных.
inline bool isNull() const {return !str;}
//! \~english Returns \c true if string is empty, i.e. length = 0, or null.
//! \~russian Возвращает \c true если строка пустая, т.е. длина = 0, или нулевая.
inline bool isEmpty() const {return len == 0;}
//! \~english Returns \c true if string is not empty, i.e. length > 0.
//! \~russian Возвращает \c true если строка непустая, т.е. длина > 0.
inline bool isNotEmpty() const {return len > 0;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline size_t length() const {return len;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline size_t size() const {return len;}
//! \~english Returns characters length of string.
//! \~russian Возвращает длину строки в символах.
inline ssize_t size_s() const {return len;}
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIConstChars & operator =(const PIConstChars & s) {
if (this == &s) return *this;
len = s.len;
str = s.str;
return *this;
}
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
inline PIConstChars & operator =(PIConstChars && s) {
swap(s);
return *this;
}
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIConstChars & operator =(const char * s) {
str = s;
len = strlen(s);
return *this;
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator ==(const PIConstChars & s) const {
if (isNull() && s.isNull()) return true;
if (isNull() xor s.isNull()) return false;
if (size() != s.size()) return false;
return strcmp(str, s.str) == 0;
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator !=(const PIConstChars & s) const {return !(*this == s);}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator <(const PIConstChars & s) const {
if (isNull() && s.isNull()) return false;
if (isNull() xor s.isNull()) return false;
if (size() == s.size())
return strcmp(str, s.str) < 0;
return size() < s.size();
}
//! \~english Compare operator.
//! \~russian Оператор сравнения.
inline bool operator >(const PIConstChars & s) const {
if (isNull() && s.isNull()) return false;
if (isNull() xor s.isNull()) return false;
if (size() == s.size())
return strcmp(str, s.str) > 0;
return size() > s.size();
}
//! \~english Returns hash of string content.
//! \~russian Возвращает хэш содержимого строки.
inline uint hash() const {
if (isEmpty()) return 0;
return piHashData((const uchar *)str, len);
}
inline void swap(PIConstChars& v) {
piSwap<const char *>(str, v.str);
piSwap<size_t>(len, v.len);
}
private:
const char * str = nullptr;
size_t len = 0;
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout.
//! \~russian Оператор вывода в \a PICout.
inline PICout operator <<(PICout s, const PIConstChars & v) {
s.space();
if (v.isNull())
s.write("(null)");
else {
s.quote();
s.write(v.data(), v.size());
s.quote();
}
return s;
}
template<> inline uint piHash(const PIConstChars & s) {return s.hash();}
#endif // PICONSTCHARS_H

View File

@@ -526,8 +526,14 @@ PICout & PICout::newLine() {
} }
PICout & PICout::write(const char * str) {
if (!act_ || !str) return *this;
return write(str, strlen(str));
}
PICout & PICout::write(const char * str, int len) { PICout & PICout::write(const char * str, int len) {
if (!act_) return *this; if (!act_ || !str) return *this;
if (buffer_) { if (buffer_) {
buffer_->append(PIString(str, len)); buffer_->append(PIString(str, len));
} else { } else {

View File

@@ -283,6 +283,10 @@ public:
//! \~russian Условно добавляет новую строку //! \~russian Условно добавляет новую строку
PICout & newLine(); PICout & newLine();
//! \~english Write raw data
//! \~russian Пишет сырые символы
PICout & write(const char * str);
//! \~english Write raw data //! \~english Write raw data
//! \~russian Пишет сырые символы //! \~russian Пишет сырые символы
PICout & write(const char * str, int len); PICout & write(const char * str, int len);

View File

@@ -206,16 +206,6 @@ PIObject::~PIObject() {
} }
PIMap<PIString, PIVariant> PIObject::properties() const {
PIMap<PIString, PIVariant> ret;
for (const PropertyHash & p : properties_) {
ret[PIStringAscii(p.second.first)] = p.second.second;
}
return ret;
}
bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple> & vl) { bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple> & vl) {
@@ -698,7 +688,7 @@ void PIObject::dump(const PIString & line_prefix) const {
auto it = properties_.makeIterator(); auto it = properties_.makeIterator();
while (it.next()) { while (it.next()) {
if (it.key() != piHashData((const uchar *)o_name, strlen(o_name))) if (it.key() != piHashData((const uchar *)o_name, strlen(o_name)))
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << it.value().first << ": " << it.value().second; PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << it.key() << ": " << it.value();
} }
//printf("dump %d properties ok\n", properties_.size()); //printf("dump %d properties ok\n", properties_.size());
PICout(PICoutManipulators::AddNewLine) << line_prefix << " }"; PICout(PICoutManipulators::AddNewLine) << line_prefix << " }";

View File

@@ -142,21 +142,13 @@ public:
//! \~russian Включает или отключает вывод \a piCoutObj для этого объекта //! \~russian Включает или отключает вывод \a piCoutObj для этого объекта
void setDebug(bool debug) {setProperty("debug", debug);} void setDebug(bool debug) {setProperty("debug", debug);}
//! \~english Returns properties of the object
//! \~russian Возвращает словарь свойств объекта
PIMap<PIString, PIVariant> properties() const;
//! \~english Returns properties count of the object
//! \~russian Возвращает количество свойств объекта
int propertiesCount() const {return properties_.size_s();}
//! \~english Returns property with name "name" //! \~english Returns property with name "name"
//! \~russian Возвращает свойство объекта по имени "name" //! \~russian Возвращает свойство объекта по имени "name"
PIVariant property(const char * name) const {return properties_.value(piHashData((const uchar *)name, strlen(name)), Property(nullptr, PIVariant())).second;} PIVariant property(const char * name) const {return properties_.value(piHashData((const uchar *)name, strlen(name)));}
//! \~english Set property with name "name" to "value". If there is no such property in object it will be added //! \~english Set property with name "name" to "value". If there is no such property in object it will be added
//! \~russian Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется //! \~russian Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется
void setProperty(const char * name, const PIVariant & value) {properties_[piHashData((const uchar *)name, strlen(name))] = Property(name, value); propertyChanged(name);} void setProperty(const char * name, const PIVariant & value) {properties_[piHashData((const uchar *)name, strlen(name))] = value; propertyChanged(name);}
//! \~english Returns if property with name "name" exists //! \~english Returns if property with name "name" exists
//! \~russian Возвращает присутствует ли свойство по имени "name" //! \~russian Возвращает присутствует ли свойство по имени "name"
@@ -565,9 +557,6 @@ private:
PRIVATE_DECLARATION(PIP_EXPORT) PRIVATE_DECLARATION(PIP_EXPORT)
}; };
typedef PIPair<const char *, PIVariant> Property;
typedef PIPair<uint, Property > PropertyHash;
bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret); bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret);
PIVector<__MetaFunc> findEH(const PIString & name) const; PIVector<__MetaFunc> findEH(const PIString & name) const;
__MetaFunc methodEH(const void * addr) const; __MetaFunc methodEH(const void * addr) const;
@@ -587,7 +576,7 @@ private:
PIVector<Connection> connections; PIVector<Connection> connections;
PIMap<uint, Property> properties_; PIMap<uint, PIVariant> properties_;
PISet<PIObject * > connectors; PISet<PIObject * > connectors;
PIVector<__QueuedEvent> events_queue; PIVector<__QueuedEvent> events_queue;
PIMutex mutex_, mutex_connect, mutex_queue; PIMutex mutex_, mutex_connect, mutex_queue;

View File

@@ -27,6 +27,7 @@
#define PIVARIANT_H #define PIVARIANT_H
#include "pivarianttypes.h" #include "pivarianttypes.h"
#include "piconstchars.h"
#include "pitime.h" #include "pitime.h"
#include "pigeometry.h" #include "pigeometry.h"
#include "pimathmatrix.h" #include "pimathmatrix.h"
@@ -801,7 +802,10 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVariant & v) {
inline PICout operator <<(PICout s, const PIVariant & v) { inline PICout operator <<(PICout s, const PIVariant & v) {
s.space(); s.setControl(0, true); s.space(); s.setControl(0, true);
s << "PIVariant(" << v.typeName() << ", " << v.toString() << ")"; s << "PIVariant(" << v.typeName();
if (v.isValid())
s << ", " << v.toString();
s << ")";
s.restoreControl(); return s; s.restoreControl(); return s;
} }

View File

@@ -66,7 +66,7 @@ PIVector<PIIntrospection::ObjectInfo> PIIntrospection::getObjects() {
for (int i = 0; i < ao.size_s(); ++i) { for (int i = 0; i < ao.size_s(); ++i) {
ret[i].classname = PIStringAscii(ao[i]->className()); ret[i].classname = PIStringAscii(ao[i]->className());
ret[i].name = ao[i]->name(); ret[i].name = ao[i]->name();
ret[i].properties = ao[i]->properties(); //ret[i].properties = ao[i]->properties();
ret[i].parents = ao[i]->scopeList(); ret[i].parents = ao[i]->scopeList();
ao[i]->mutex_queue.lock(); ao[i]->mutex_queue.lock();
ret[i].queued_events = ao[i]->events_queue.size_s(); ret[i].queued_events = ao[i]->events_queue.size_s();

View File

@@ -4,11 +4,49 @@ static const char * smallstr = "abcdef";
static const char * bigstr = "zsxdcgfhvbncjdbasljcvavcjadnwnxudvbabdhjlavudvdaljsvclavjlasdhvcjhldsavhjldasvfjlhsavdjhavdjhvfjhldasvfjlasvfhjldasvfhjasvfdjdasfhvjldasvhfjlasvfhjlahsvdfhjfvfvdjalsvfjlhasdvfdjsalvfhhjldasvfdjhaldsvfhjdvsfjhlavfjhlavfladlsvfjlasdvfdhjlavfhjldasvfhjlavfhjldvfhjlalsdvfjlhvasfhjlvchjlavchjladvchjldladvschjlladscvjlhdcahjchjllcahjllvcdjladsvhldbcljadsbcjdhlsachjlvdsa hjlcldajc hljdascbhaldb cldhashd l cajlhs chdsbfhlbfdasdffadsfjkbfkjldsabflhbcldhsbhclabchljadsbchldahsbcladsbhclhabhasbclasbdhl"; static const char * bigstr = "zsxdcgfhvbncjdbasljcvavcjadnwnxudvbabdhjlavudvdaljsvclavjlasdhvcjhldsavhjldasvfjlhsavdjhavdjhvfjhldasvfjlasvfhjldasvfhjasvfdjdasfhvjldasvhfjlasvfhjlahsvdfhjfvfvdjalsvfjlhasdvfdjsalvfhhjldasvfdjhaldsvfhjdvsfjhlavfjhlavfladlsvfjlasdvfdhjlavfhjldasvfhjlavfhjldvfhjlalsdvfjlhvasfhjlvchjlavchjladvchjldladvschjlladscvjlhdcahjchjllcahjllvcdjladsvhldbcljadsbcjdhlsachjlvdsa hjlcldajc hljdascbhaldb cldhashd l cajlhs chdsbfhlbfdasdffadsfjkbfkjldsabflhbcldhsbhclabchljadsbchldahsbcladsbhclhabhasbclasbdhl";
PIKbdListener kbd; PIKbdListener kbd(0, 0, false);
#include <iostream> #include <iostream>
#include <codecvt> #include <codecvt>
using namespace PICoutManipulators;
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
/*PIVariant vi;
piCout << vi;
vi = 1;
piCout << vi << vi.toString();
vi = "string";
piCout << vi << vi.toStringList();
vi = PIStringList("2");
piCout << vi << vi.toInt();*/
/*auto cmp = [](const PIConstChars & c0, const PIConstChars & c1){
PICout(DefaultControls) << c0 << "==" << c1 << "->" << (c0 != c1);
};
PIConstChars s;
PICout(DefaultControls | AddQuotes) << s;
s = PIConstChars("str", 2);
PICout(DefaultControls | AddQuotes) << s;
cmp(PIConstChars(), PIConstChars());
cmp(PIConstChars("str"), PIConstChars());
cmp(PIConstChars(), PIConstChars("s_tr"));
cmp(PIConstChars("str1"), PIConstChars("str"));
cmp(PIConstChars("str"), PIConstChars("str2"));
cmp(PIConstChars("str"), PIConstChars("sTr"));
cmp(PIConstChars("str"), PIConstChars("str"));
cmp(PIConstChars("1a"), PIConstChars("1b"));
cmp(PIConstChars("1c"), PIConstChars("1b"));*/
PIMap<PIConstChars, int> map;
map["_2"] = 22;
map["1"] = 11;
map["__3"] = 33;
map["10"] = 10;
piCout << map;
return 0;
auto rstr = PIString::fromUTF8("ascii русский!"); auto rstr = PIString::fromUTF8("ascii русский!");
/*for (PIChar c: rstr) /*for (PIChar c: rstr)
std::wcout << c.toWChar(); std::wcout << c.toWChar();