diff --git a/redis-desktop-manager/ValueTabView.h b/redis-desktop-manager/include/widgets/ValueTabView.h similarity index 100% rename from redis-desktop-manager/ValueTabView.h rename to redis-desktop-manager/include/widgets/ValueTabView.h diff --git a/redis-desktop-manager/redis-desktop-manager.vcxproj b/redis-desktop-manager/redis-desktop-manager.vcxproj index c0c19ccb..65f6df8f 100644 --- a/redis-desktop-manager/redis-desktop-manager.vcxproj +++ b/redis-desktop-manager/redis-desktop-manager.vcxproj @@ -214,7 +214,6 @@ - $(QTDIR)\bin\moc.exe;%(FullPath) Moc%27ing RedisKeyItem.h... @@ -323,6 +322,7 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I$(SolutionDir)\deps\libssh\include" "-I.\source\models" + $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath) diff --git a/redis-desktop-manager/redis-desktop-manager.vcxproj.filters b/redis-desktop-manager/redis-desktop-manager.vcxproj.filters index 7da0afa8..35fe2b1b 100644 --- a/redis-desktop-manager/redis-desktop-manager.vcxproj.filters +++ b/redis-desktop-manager/redis-desktop-manager.vcxproj.filters @@ -405,15 +405,15 @@ Header Files\redis - - Header Files\widgets - Generated Files Header Files\models + + Header Files\widgets + diff --git a/redis-desktop-manager/source/connection.cpp b/redis-desktop-manager/source/connection.cpp index 9b47cfc1..997fbf42 100644 --- a/redis-desktop-manager/source/connection.cpp +++ b/redis-desktop-manager/source/connection.cpp @@ -64,8 +64,6 @@ void connection::OnOkButtonClick() connection = server->getConnection(); - bool connectionTypeChanged = connection->getConfig().useSshTunnel() != conf.useSshTunnel(); - connection->setConnectionConfig(conf); } else { diff --git a/redis-desktop-manager/source/redis/Response.cpp b/redis-desktop-manager/source/redis/Response.cpp index c7df63a5..1bd876ec 100644 --- a/redis-desktop-manager/source/redis/Response.cpp +++ b/redis-desktop-manager/source/redis/Response.cpp @@ -42,283 +42,282 @@ void Response::appendToSource(QByteArray& src) responseString.append(src); } -QVariant Response::getValue() -{ - if (responseString.isEmpty()) { - return QVariant(); - } - - ResponseType t = getResponseType(responseString); - - QVariant parsedResponse; - - switch (t) { - - case Status: - case Error: - parsedResponse = QVariant(getStringResponse(responseString)); - break; - - case Integer: - parsedResponse = QVariant(getStringResponse(responseString).toInt()); - break; - - case Bulk: - parsedResponse = parseBulk(responseString); - break; - - case MultiBulk: - parsedResponse = QVariant(parseMultiBulk(responseString)); - break; - case Unknown: - break; - } - - return parsedResponse; -} - -QVariant Response::parseBulk(QString response) -{ - int endOfFirstLine = response.indexOf("\r\n"); - int responseSize = getSizeOfBulkReply(response, endOfFirstLine); - - if (responseSize != -1) { - return QVariant(response.mid(endOfFirstLine + 2, responseSize)); - } - - return QVariant(); -} - -QStringList Response::parseMultiBulk(QString response) -{ - int endOfFirstLine = response.indexOf("\r\n"); - int responseSize = getSizeOfBulkReply(response, endOfFirstLine); - - if (responseSize == 0) - { - return QStringList(); - } - - QStringList parsedResult; ResponseType type; int firstItemLen, firstPosOfEndl, bulkLen; - - parsedResult.reserve(responseSize+5); - - for (int currPos = endOfFirstLine + 2, respStringSize = response.size(); currPos < respStringSize;) - { - type = getResponseType(response.at(currPos)); - - firstPosOfEndl = response.indexOf("\r\n", currPos); - firstItemLen = firstPosOfEndl - currPos-1; - - if (type == Integer) - { - parsedResult << response.mid(currPos+1, firstItemLen); - - currPos = firstPosOfEndl + 2; - continue; - } - - if (type == Bulk) - { - bulkLen = response.mid(currPos+1, firstItemLen).toInt(); - - if (bulkLen == 0) - { - parsedResult << ""; - currPos = firstPosOfEndl + 4; - } else { - parsedResult << response.mid(firstPosOfEndl+2, bulkLen); - currPos = firstPosOfEndl + bulkLen + 4; - } - - continue; - } - - if (type == MultiBulk) - { - throw RedisException("Recursive parsing of MultiBulk replies not supported"); - } - } - - return parsedResult; -} - -Response::ResponseType Response::getResponseType(QString r) -{ - return getResponseType(r.at(0)); -} - -Response::ResponseType Response::getResponseType(const QChar typeChar) -{ - if (typeChar == '+') return Status; - if (typeChar == '-') return Error; - if (typeChar == ':') return Integer; - if (typeChar == '$') return Bulk; - if (typeChar == '*') return MultiBulk; - - return Unknown; -} - -QString Response::getStringResponse(QString response) -{ - return response.mid(1, response.length() - 3); -} - -bool Response::isValid() -{ - return isReplyValid(responseString); -} - -bool Response::isReplyValid(const QString & responseString) -{ - if (responseString.isEmpty()) - { - return false; - } - - ResponseType type = getResponseType(responseString); - - switch (type) - { - case Status: - case Error: - case Unknown: - default: - return isReplyGeneralyValid(responseString); - - case Integer: - return isReplyGeneralyValid(responseString) - && isIntReplyValid(responseString); - - case Bulk: - return isReplyGeneralyValid(responseString) - && isBulkReplyValid(responseString); - - case MultiBulk: - return isReplyGeneralyValid(responseString) - && isMultiBulkReplyValid(responseString); - } -} - -bool Response::isReplyGeneralyValid(const QString& r) -{ - return r.endsWith("\r\n"); -} - -int Response::getPosOfNextItem(const QString &r, int startPos = 0) -{ - if (startPos >= r.size()) { - return -1; - } - - ResponseType type = getResponseType(r.at(startPos)); - - int endOfFirstLine = r.indexOf("\r\n", startPos); - - int responseSize; - - switch (type) - { - case Integer: - return endOfFirstLine+2; - - case Bulk: - responseSize = getSizeOfBulkReply(r, endOfFirstLine, startPos); - - if (responseSize == -1) { - return endOfFirstLine+2; - } else { - return endOfFirstLine+responseSize+4; - } - break; - default: - return -1; - } - -} - -bool Response::isIntReplyValid(const QString& r) -{ - return true; -} - -bool Response::isBulkReplyValid(const QString& r) -{ - int endOfFirstLine = r.indexOf("\r\n"); - int responseSize = getSizeOfBulkReply(r, endOfFirstLine); - - if (responseSize == -1) { - return true; - } - - int actualSizeOfResponse = r.size() - endOfFirstLine - 4; - - // we need not strict check for using this method for validation multi-bulk items - if (actualSizeOfResponse < responseSize) { - return false; - } - - return true; -} - -bool Response::isMultiBulkReplyValid(const QString& r) -{ - int endOfFirstLine = r.indexOf("\r\n"); - int responseSize = getSizeOfBulkReply(r, endOfFirstLine); - - if (responseSize <= 0) { - return true; - } - - //fast validation based on string size - int minimalReplySize = responseSize * 4 + endOfFirstLine; // 4 is [type char] + [digit char] + [\r\n] - - int responseStringSize = r.size(); - - if (responseStringSize < minimalReplySize) { - return false; - } - - //detailed validation - int currPos = (lastValidPos > 0) ? lastValidPos : endOfFirstLine + 2; - int lastPos = 0; - - do { - - currPos = getPosOfNextItem(r, currPos); - - if (currPos != -1) { - lastPos = currPos; - } - - if (currPos != -1 && currPos != responseStringSize) { - lastValidPos = currPos; - } - - } while (currPos != -1 && ++itemsCount); - - - if (itemsCount < responseSize || (lastPos != responseStringSize)) { - return false; - } - - return true; +QVariant Response::getValue() +{ + if (responseString.isEmpty()) { + return QVariant(); + } + + ResponseType t = getResponseType(responseString); + + QVariant parsedResponse; + + switch (t) { + + case Status: + case Error: + parsedResponse = QVariant(getStringResponse(responseString)); + break; + + case Integer: + parsedResponse = QVariant(getStringResponse(responseString).toInt()); + break; + + case Bulk: + parsedResponse = parseBulk(responseString); + break; + + case MultiBulk: + parsedResponse = QVariant(parseMultiBulk(responseString)); + break; + case Unknown: + break; + } + + return parsedResponse; +} + +QVariant Response::parseBulk(QString response) +{ + int endOfFirstLine = response.indexOf("\r\n"); + int responseSize = getSizeOfBulkReply(response, endOfFirstLine); + + if (responseSize != -1) { + return QVariant(response.mid(endOfFirstLine + 2, responseSize)); + } + + return QVariant(); } -int Response::getSizeOfBulkReply(const QString& reply, int endOfFirstLine, int beginFrom) -{ - if (endOfFirstLine == -1) { - endOfFirstLine = reply.indexOf("\r\n", beginFrom); - } - - int size = 0; - QString strRepresentaton; - - for (int pos = beginFrom + 1; pos < endOfFirstLine; pos++) { - strRepresentaton += reply.at(pos); - } - - return strRepresentaton.toInt(); +QStringList Response::parseMultiBulk(QString response) +{ + int endOfFirstLine = response.indexOf("\r\n"); + int responseSize = getSizeOfBulkReply(response, endOfFirstLine); + + if (responseSize == 0) + { + return QStringList(); + } + + QStringList parsedResult; ResponseType type; int firstItemLen, firstPosOfEndl, bulkLen; + + parsedResult.reserve(responseSize+5); + + for (int currPos = endOfFirstLine + 2, respStringSize = response.size(); currPos < respStringSize;) + { + type = getResponseType(response.at(currPos)); + + firstPosOfEndl = response.indexOf("\r\n", currPos); + firstItemLen = firstPosOfEndl - currPos-1; + + if (type == Integer) + { + parsedResult << response.mid(currPos+1, firstItemLen); + + currPos = firstPosOfEndl + 2; + continue; + } + + if (type == Bulk) + { + bulkLen = response.mid(currPos+1, firstItemLen).toInt(); + + if (bulkLen == 0) + { + parsedResult << ""; + currPos = firstPosOfEndl + 4; + } else { + parsedResult << response.mid(firstPosOfEndl+2, bulkLen); + currPos = firstPosOfEndl + bulkLen + 4; + } + + continue; + } + + if (type == MultiBulk) + { + throw RedisException("Recursive parsing of MultiBulk replies not supported"); + } + } + + return parsedResult; +} + +Response::ResponseType Response::getResponseType(QString r) +{ + return getResponseType(r.at(0)); +} + +Response::ResponseType Response::getResponseType(const QChar typeChar) +{ + if (typeChar == '+') return Status; + if (typeChar == '-') return Error; + if (typeChar == ':') return Integer; + if (typeChar == '$') return Bulk; + if (typeChar == '*') return MultiBulk; + + return Unknown; +} + +QString Response::getStringResponse(QString response) +{ + return response.mid(1, response.length() - 3); +} + +bool Response::isValid() +{ + return isReplyValid(responseString); +} + +bool Response::isReplyValid(const QString & responseString) +{ + if (responseString.isEmpty()) + { + return false; + } + + ResponseType type = getResponseType(responseString); + + switch (type) + { + case Status: + case Error: + case Unknown: + default: + return isReplyGeneralyValid(responseString); + + case Integer: + return isReplyGeneralyValid(responseString) + && isIntReplyValid(responseString); + + case Bulk: + return isReplyGeneralyValid(responseString) + && isBulkReplyValid(responseString); + + case MultiBulk: + return isReplyGeneralyValid(responseString) + && isMultiBulkReplyValid(responseString); + } +} + +bool Response::isReplyGeneralyValid(const QString& r) +{ + return r.endsWith("\r\n"); +} + +int Response::getPosOfNextItem(const QString &r, int startPos = 0) +{ + if (startPos >= r.size()) { + return -1; + } + + ResponseType type = getResponseType(r.at(startPos)); + + int endOfFirstLine = r.indexOf("\r\n", startPos); + + int responseSize; + + switch (type) + { + case Integer: + return endOfFirstLine+2; + + case Bulk: + responseSize = getSizeOfBulkReply(r, endOfFirstLine, startPos); + + if (responseSize == -1) { + return endOfFirstLine+2; + } else { + return endOfFirstLine+responseSize+4; + } + break; + default: + return -1; + } + +} + +bool Response::isIntReplyValid(const QString& r) +{ + return !r.isEmpty(); +} + +bool Response::isBulkReplyValid(const QString& r) +{ + int endOfFirstLine = r.indexOf("\r\n"); + int responseSize = getSizeOfBulkReply(r, endOfFirstLine); + + if (responseSize == -1) { + return true; + } + + int actualSizeOfResponse = r.size() - endOfFirstLine - 4; + + // we need not strict check for using this method for validation multi-bulk items + if (actualSizeOfResponse < responseSize) { + return false; + } + + return true; +} + +bool Response::isMultiBulkReplyValid(const QString& r) +{ + int endOfFirstLine = r.indexOf("\r\n"); + int responseSize = getSizeOfBulkReply(r, endOfFirstLine); + + if (responseSize <= 0) { + return true; + } + + //fast validation based on string size + int minimalReplySize = responseSize * 4 + endOfFirstLine; // 4 is [type char] + [digit char] + [\r\n] + + int responseStringSize = r.size(); + + if (responseStringSize < minimalReplySize) { + return false; + } + + //detailed validation + int currPos = (lastValidPos > 0) ? lastValidPos : endOfFirstLine + 2; + int lastPos = 0; + + do { + + currPos = getPosOfNextItem(r, currPos); + + if (currPos != -1) { + lastPos = currPos; + } + + if (currPos != -1 && currPos != responseStringSize) { + lastValidPos = currPos; + } + + } while (currPos != -1 && ++itemsCount); + + + if (itemsCount < responseSize || (lastPos != responseStringSize)) { + return false; + } + + return true; +} + +int Response::getSizeOfBulkReply(const QString& reply, int endOfFirstLine, int beginFrom) +{ + if (endOfFirstLine == -1) { + endOfFirstLine = reply.indexOf("\r\n", beginFrom); + } + + QString strRepresentaton; + + for (int pos = beginFrom + 1; pos < endOfFirstLine; pos++) { + strRepresentaton += reply.at(pos); + } + + return strRepresentaton.toInt(); } QString Response::valueToString(QVariant& value) @@ -331,4 +330,4 @@ QString Response::valueToString(QVariant& value) } return value.toString(); -} \ No newline at end of file +} diff --git a/redis-desktop-manager/source/widgets/valueViewTab.cpp b/redis-desktop-manager/source/widgets/valueViewTab.cpp index 7ab31173..21ec75aa 100644 --- a/redis-desktop-manager/source/widgets/valueViewTab.cpp +++ b/redis-desktop-manager/source/widgets/valueViewTab.cpp @@ -51,7 +51,7 @@ void ValueTab::valueLoaded(const QVariant& value, QObject * owner) PaginatedModel * ValueTab::getModelForKey(RedisKeyItem::Type t, const QVariant& val) { - switch (type) + switch (t) { case RedisKeyItem::Hash: return new HashKeyModel(val.toStringList());