PIString fix

git-svn-id: svn://db.shs.com.ru/pip@44 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
2015-03-30 08:49:19 +00:00
parent 8c051235aa
commit 595543bea9
8 changed files with 301 additions and 69 deletions

View File

@@ -135,6 +135,29 @@ public:
#include <netdb.h>
int main (int argc, char * argv[]) {
PIString s, s2;
s = "test";
PICout(0xFFFF) << s << s.length();
s += PIString(" test") + " !";
PICout(0xFFFF) << s << s.length();
s.clear();
PICout(0xFFFF) << s << s.length();
s += " test";
PICout(0xFFFF) << s << s.length();
s.insert(1, PIString("|") + ",|");
PICout(0xFFFF) << s << s.length() << (s == (PIString(" |,|")+"test"));
s.resize(4);
PICout(0xFFFF) << s << s.length();
s = PIString("new");
PICout(0xFFFF) << s << s.length();
PIByteArray ba;
ba << s;
piCout << ba.size() << ba;
ba >> s2;
PICout(0xFFFF) << s2 << s2.length();
return 0;
hostent * he = 0;
he = gethostbyname(argv[1]);
piCout << he->h_name;

View File

@@ -56,12 +56,13 @@ public:
PIVector<Row> content;
PIScreenTypes::Alignment alignment;
SelectionMode selection_mode;
PISet<int> selected;
int cur, offset;
protected:
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
int lhei, offset, cur;
PISet<int> selected;
int lhei;
};

View File

@@ -127,6 +127,32 @@ void PIString::appendFromChars(const char * c, int s) {
}
void PIString::buildData() const {
data_.clear();
uint wc;
uchar tc;
//printf("PIString::data %d\n", size_s());
for (int i = 0, j = 0; i < size_s(); ++i) {
wc = uint(at(i).toInt());
//printf("__%d_%d\n", i, wc);
tc = wc & 0xFF;
while (tc) {
data_ << uchar(tc); ++j;
wc >>= 8;
tc = wc & 0xFF;
//printf("____%d\n", wc);
}
/*if (at(i).isAscii())
data_.push_back(uchar(at(i).toAscii()));
else {
data_.push_back((at(i).toCharPtr()[0])); ++j;
data_.push_back((at(i).toCharPtr()[1]));
}*/
}
data_ << uchar('\0');
}
PIString & PIString::operator +=(const char * str) {
int l = 0;
while (str[l] != '\0') ++l;
@@ -625,39 +651,6 @@ PIString PIString::toLowerCase() const {
}
int PIString::lengthAscii() const {
int j = 0;
for (int i = 0; i < size_s(); ++i, ++j)
if (!at(i).isAscii()) ++j;
return j;
}
const char * PIString::data() const {
data_.clear();
uint wc;
uchar tc;
//printf("PIString::data %d\n", size_s());
for (int i = 0, j = 0; i < size_s(); ++i) {
wc = uint(at(i).toInt());
//printf("__%d_%d\n", i, wc);
while (tc = wc & 0xFF, tc) {
data_.push_back(uchar(tc)); ++j;
wc >>= 8;
//printf("____%d\n", wc);
}
/*if (at(i).isAscii())
data_.push_back(uchar(at(i).toAscii()));
else {
data_.push_back((at(i).toCharPtr()[0])); ++j;
data_.push_back((at(i).toCharPtr()[1]));
}*/
}
data_.push_back(uchar('\0'));
return (const char * )data_.data();
}
std::string PIString::convertToStd() const {
std::string s;
uint wc;

View File

@@ -32,6 +32,7 @@ class PIStringList;
class PIP_EXPORT PIString: public PIDeque<PIChar>
{
friend PIByteArray & operator >>(PIByteArray & s, PIString & v);
public:
//! Contructs an empty string
PIString(): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--;}
@@ -122,7 +123,7 @@ public:
operator const char*() {return data();}
//! Return std::string representation of string
operator const std::string() {if (size() == 0) return std::string(); std::string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;}
//operator const std::string() {if (size() == 0) return std::string(); std::string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;}
//! Return symbol at index "pos"
PIChar operator [](const int pos) const {return at(pos);}
@@ -452,10 +453,10 @@ public:
/*! \brief Return real bytes count of this string
* \details It`s equivalent length of char sequence
* returned by function \a data() \n
* returned by function \a data() - 1, without terminating null-char \n
* Example: \snippet pistring.cpp PIString::lengthAscii
* \sa \a data() */
int lengthAscii() const;
int lengthAscii() const {buildData(); return data_.size_s() - 1;}
/*! \brief Return \c char * representation of this string
* \details This function fill buffer by sequence
@@ -464,7 +465,7 @@ public:
* execution of this function.\n
* Example: \snippet pistring.cpp PIString::data
* \sa \a lengthAscii() */
const char * data() const;
const char * data() const {buildData(); return (const char *)(data_.data());}
//! \brief Return \c std::string representation of this string
std::string stdString() const {return convertToStd();}
@@ -473,8 +474,8 @@ public:
wstring stdWString() const {return convertToWString();}
#endif
//! \brief Return \a PIByteArray contains \a data() of this string
PIByteArray toByteArray() const {const char * d = data(); return PIByteArray(d, lengthAscii());}
//! \brief Return \a PIByteArray contains \a data() of this string without terminating null-char
PIByteArray toByteArray() const {buildData(); return data_.resized(data_.size_s() - 1);}
/*! \brief Split string with delimiter "delim" to \a PIStringList and return it
* \details Example: \snippet pistring.cpp PIString::split */
@@ -779,6 +780,7 @@ private:
return ret;
}
void appendFromChars(const char * c, int s);
void buildData() const;
std::string convertToStd() const;
#ifdef HAS_LOCALE
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
@@ -802,10 +804,10 @@ inline PICout operator <<(PICout s, const PIString & v) {s.space(); s.quote(); s
//! \relatesalso PIString \relatesalso PIByteArray \brief Output operator to PIByteArray
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {int l = v.lengthAscii(); s << l; if (l <= 0) return s; int os = s.size_s(); s.enlarge(l); memcpy(s.data(os), v.data(), l); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.toByteArray(); return s;}
//! \relatesalso PIString \relatesalso PIByteArray \brief Input operator from PIByteArray
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {if (s.size() < 4) {v.clear(); return s;} int l; s >> l; if (l <= 0) return s; v = PIString((const char * )s.data(), l); s.remove(0, l); return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {PIByteArray sc; s >> sc; v.clear(); v.appendFromChars((const char *)sc.data(), sc.size_s()); return s;}
//! \relatesalso PIString \brief Return concatenated string

View File

@@ -10,6 +10,7 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
mode = offset = cur = height = 0;
CONNECTU(&screen, keyPressed, this, keyEvent)
CONNECTU(&timer, tickEvent, this, timerEvent)
CONNECTU(&fm, tileKey, this, fmKeyEvent)
timer.addDelimiter(5);
timer.start(200);
@@ -35,6 +36,7 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
tile_info = new TileSimple("daemon info");
tile_info->hide();
fm.setRemote(true);
tile_fm = fm.tile();
tile_fm->hide();
@@ -49,6 +51,14 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
}
Daemon::~Daemon() {
PIVector<Remote*> rl = remotes.values();
piForeach (Remote * r, rl)
delete r;
remotes.clear();
}
PIScreenTile * Daemon::tile() const {
return tile_root;
}
@@ -110,7 +120,11 @@ void Daemon::tileEvent(PIScreenTile * t, TileEvent e) {
if (e.type == TileList::RowPressed) {
switch (e.data.toInt()) {
case 0: mode = 2; showTile(tile_info, "Information"); break;
case 1: mode = 3; showTile(tile_fm, "File manager"); break;
case 1:
mode = 3;
showTile(tile_fm, "File manager");
requestChDir(".");
break;
default: break;
}
}
@@ -141,6 +155,26 @@ void Daemon::keyEvent(PIKbdListener::KeyEvent key) {
}
void Daemon::fmKeyEvent(PIKbdListener::KeyEvent key) {
PIByteArray ba;
//Remote * r = remotes.value(conn_name);
//piCout << key.key << key.modifiers;
switch (key.key) {
case PIKbdListener::Return:
{
PIFile::FileInfo fi = fm.currentRemoteEntry();
if (!fi.isDir()) break;
requestChDir(fi.name());
}
break;
case 'R':
requestChDir(".");
break;
default: break;
}
}
void Daemon::timerEvent(void * _d, int delim) {
screen.lock();
list_daemons->content.clear();
@@ -192,6 +226,10 @@ void Daemon::peerConnected(const PIString & name) {
/*piCout << "connected" << name;
mode = 2;
conn_name = name;*/
Remote * r = new Remote(name);
CONNECTU(&(r->dt), sendRequest, this, dtSendRequest)
CONNECTU(&(r->dt), receiveFinished, this, dtReceived)
remotes.insert(name, r);
}
@@ -199,6 +237,26 @@ void Daemon::peerDisconnected(const PIString & name) {
if (name == conn_name) {
disconnect();
}
Remote * dt = remotes.value(name);
if (dt) delete dt;
remotes.remove(name);
}
void Daemon::dtSendRequest(PIByteArray & data) {
PIDataTransfer * dt = (PIDataTransfer*)emitter();
if (!dt) return;
PIByteArray hdr; hdr << int(DataTransfer);
data.insert(0, hdr);
send(dt->name(), data);
}
void Daemon::dtReceived(bool ok) {
if (!ok) return;
PIDataTransfer * dt = (PIDataTransfer*)emitter();
if (!dt) return;
dataReceived(emitter()->name(), dt->data());
}
@@ -206,6 +264,8 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
//if (conn_name != from) return;
if (data.size() < 4) return;
PIByteArray ba(data), rba;
Remote * r(0);
PIString dir;
int type; ba >> type;
//std::cout << "rec from " << from << type;
switch (type) {
@@ -213,11 +273,40 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
makeMyHostInfo();
rba << int(ReplyHostInfo) << info_my;
break;
case RequestChangeDir:
r = remotes.value(from);
if (!r) break;
ba >> dir;
r->dir.cd(dir);
{
PIVector<PIFile::FileInfo> fil = r->dir.entries();
piForeach (PIFile::FileInfo & f, fil)
f.path = f.name();
rba << int(ReplyChangeDir) << r->dir.absolutePath() << fil;
}
break;
case ReplyHostInfo:
ba >> info_other;
makeOtherHostInfo();
fillInfoTile(info_other);
break;
case ReplyChangeDir:
r = remotes.value(from);
if (!r) break;
{
PIVector<PIFile::FileInfo> fil;
ba >> dir >> fil;
r->dir.setDir(dir);
fm.setRemoteDir(dir);
fm.setRemoteContent(fil);
fm.remoteRestoreDir();
}
break;
case DataTransfer:
r = remotes.value(from);
if (r)
r->dt.received(ba);
break;
};
if (!rba.isEmpty()) send(from, rba);
}
@@ -310,3 +399,14 @@ void Daemon::tabInfo() {
console.addVariable("of this process", &sys_mon_other, 2);
finishTab();*/
}
void Daemon::requestChDir(const PIString & d) {
if (d.isEmpty()) return;
fm.remoteSaveDir();
fm.readingRemote();
PIByteArray ba;
ba << int(RequestChangeDir) << d;
send(conn_name, ba);
//piCout << "request chdir" << d;
}

View File

@@ -4,6 +4,8 @@
#include "piscreentiles.h"
#include "pipeer.h"
#include "pisystemmonitor.h"
#include "pidatatransfer.h"
#include "pifiletransfer.h"
#include "file_manager.h"
extern PISystemMonitor sys_mon;
@@ -12,6 +14,7 @@ class Daemon: public PIPeer {
PIOBJECT(Daemon)
public:
Daemon();
~Daemon();
struct HostInfo {
HostInfo() {
@@ -52,14 +55,32 @@ public:
private:
enum PacketType {
RequestHostInfo = 10,
RequestChangeDir,
ReplyHostInfo = 20
ReplyHostInfo = 20,
ReplyChangeDir,
DataTransfer = 30
};
class Remote: public PIThread {
public:
Remote(const PIString & n = PIString()) {dt.setName(n); ft.setName(n); dir = PIDir::current();}
void sendData(const PIByteArray & d) {_d = d; startOnce();}
PIDir dir;
PIDataTransfer dt;
PIFileTransfer ft;
PIByteArray _d;
void run() {dt.send(_d);}
};
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER1(void, fmKeyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER2(void, timerEvent, void * , _d, int, delim);
EVENT_HANDLER1(void, dtSendRequest, PIByteArray &, data);
EVENT_HANDLER1(void, dtReceived, bool, ok);
EVENT(menuRequest);
void hideAll();
void showTile(PIScreenTile * t, const PIString & header = PIString());
@@ -75,10 +96,13 @@ private:
void tabFeature();
void tabInfo();
void requestChDir(const PIString & d);
mutable PIStringList available_daemons;
PITimer timer;
PIString conn_name;
PIMap<int, PIString> dnames;
PIMap<PIString, Remote*> remotes;
PISystemMonitor sys_mon_other;
HostInfo info_my, info_other;
FileManager fm;

View File

@@ -8,13 +8,24 @@ FileManager::TileDir::TileDir(): TileList() {
label_path = 0;
selection_mode = TileList::MultiSelection;
dir = PIDir::current();
resized = false;
resized = remote = false;
}
bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
if (key.key == 'R') {
if (remote) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
} else {
updateDir();
}
return true;
}
if (key.key == PIKbdListener::Return) {
if (cur < entries.size_s() && cur >= 0) {
if (remote) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
} else {
//piCout << entries[cur];
if (entries[cur].isDir()) {
prev_pos[dir.path()] = PIPair<int, int>(cur, offset);
@@ -26,6 +37,7 @@ bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
updateDir();
}
}
}
return true;
}
return TileList::keyEvent(key);
@@ -42,34 +54,45 @@ void FileManager::TileDir::unlock() {
}
void FileManager::TileDir::updateDir() {
//if (!enabled) return;
entries.clear();
lock();
int pc = cur, po = offset;
void FileManager::TileDir::showReading() {
cur = -1;
offset = 0;
entries.clear();
content.resize(1);
content[0] = Row("... Reading ...", CellFormat());
unlock();
}
void FileManager::TileDir::setContent(const PIVector<PIFile::FileInfo> & l) {
PIVector<PIFile::FileInfo> el = dir.entries(), fl, dl;
if (el.isEmpty()) {
entries.clear();
if (l.isEmpty()) {
PIFile::FileInfo fi;
fi.path = "..";
fi.flags |= PIFile::FileInfo::DotDot | PIFile::FileInfo::Dir;
entries << fi;
} else {
for (int i = 0; i < el.size_s(); ++i) {
if (el[i].name() == ".") continue;
if (el[i].name() == "..") {
dl.push_front(el[i]);
for (int i = 0; i < l.size_s(); ++i) {
if (l[i].name() == ".") continue;
if (l[i].name() == "..") {
dl.push_front(l[i]);
continue;
}
if (el[i].isDir()) dl << el[i];
else fl << el[i];
if (l[i].isDir()) dl << l[i];
else fl << l[i];
}
entries << dl << fl;
}
}
void FileManager::TileDir::updateDir() {
//if (!enabled) return;
lock();
int pc = cur, po = offset;
showReading();
unlock();
setContent(dir.entries());
if (label_path) {
label_path->content.resize(1);
label_path->content[0].first = dir.absolutePath();
@@ -152,6 +175,8 @@ FileManager::FileManager(Daemon * d) {
plabel->maximumWidth = 1;
panel->direction = Vertical;
panels[i] = new TileDir();
panels[i]->fm = this;
panels[i]->key_func = (void*)tileKey_s;
panels[i]->name = "file panel " + PIString(i);
panels[i]->label_path = plabel;
panel->addTile(plabel);
@@ -184,6 +209,53 @@ PIScreenTile * FileManager::tile() const {
}
void FileManager::setRemoteDir(const PIString & d) {
panels[1]->dir.setDir(d);
if (panels[1]->label_path) {
panels[1]->label_path->content.resize(1);
panels[1]->label_path->content[0].first = panels[1]->dir.absolutePath();
}
}
void FileManager::setRemoteContent(const PIVector< PIFile::FileInfo > & el) {
panels[1]->setContent(el);
panels[1]->buildNames();
}
PIStringList FileManager::selectedRemote() const {
PIStringList ret;
panels[1]->lock();
PIVector<int> sil = panels[1]->selected.toVector();
piForeachC (int i, sil)
ret << panels[1]->entries[i].path;
panels[1]->unlock();
return ret;
}
PIFile::FileInfo FileManager::currentRemoteEntry() const {
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s())) return PIFile::FileInfo();
return panels[1]->entries[panels[1]->cur];
}
void FileManager::remoteSaveDir() {
panels[1]->prev_pos[panels[1]->dir.path()] = PIPair<int, int>(panels[1]->cur, panels[1]->offset);
}
void FileManager::remoteRestoreDir() {
PIPair<int, int> cp = panels[1]->prev_pos.value(panels[1]->dir.path());
panels[1]->selected.clear();
panels[1]->cur = cp.first;
panels[1]->offset = cp.second;
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s()))
panels[1]->cur = 0;
}
void FileManager::keyEvent(PIKbdListener::KeyEvent key) {
if (!tile_root->visible) return;
switch (key.key) {

View File

@@ -12,6 +12,18 @@ public:
FileManager(Daemon * d = 0);
PIScreenTile * tile() const;
PIScreenTile * remoteTile() const {return panels[1];}
void setRemote(bool r) {panels[1]->remote = r;}
void setRemoteDir(const PIString & d);
void setRemoteContent(const PIVector<PIFile::FileInfo> & el);
PIString remoteDir() const {return panels[1]->dir.absolutePath();}
PIStringList selectedRemote() const;
PIFile::FileInfo currentRemoteEntry() const;
PIFile::FileInfo selectedRemoteEntry(int index) const {return panels[1]->entries[index];}
void remoteSaveDir();
void remoteRestoreDir();
void readingRemote() const {panels[1]->showReading();}
private:
class TileDir: public TileList {
@@ -24,15 +36,20 @@ private:
void resizeEvent(int w, int h);
void lock();
void unlock();
void showReading();
void setContent(const PIVector<PIFile::FileInfo> & l);
TileSimple * label_path;
PIVector<PIFile::FileInfo> entries;
PIDir dir;
PIMap<PIString, PIPair<int, int> > prev_pos;
bool resized;
bool resized, remote;
void * fm, * key_func;
};
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT1(tileKey, PIKbdListener::KeyEvent, key);
EVENT(menuRequest);
static void tileKey_s(void * fm, PIKbdListener::KeyEvent key) {((FileManager*)fm)->tileKey(key);}
void updateConsole();
bool del_commit;