From 28635d8aeefbd0aa807f333769a0ab9fea9324b0 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 1 Sep 2009 13:08:02 +1000 Subject: Fixes determination of end of odbc string on deficient driver Adds some cleanups (using QVarLengthArray), and reverting to the initial and correct calculation (when the driver doesn't deem fit to return SQL_NO_DATA). --- src/sql/drivers/odbc/qsql_odbc.cpp | 12 ++++---- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 41 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 742d596..2692c96 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -323,12 +323,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni colSize *= 2; // a tiny bit faster, since it saves a SQLGetData() call } } - char* buf = new char[colSize]; + QVarLengthArray buf(colSize); while (true) { r = SQLGetData(hStmt, column+1, unicode ? SQL_C_WCHAR : SQL_C_CHAR, - (SQLPOINTER)buf, + (SQLPOINTER)buf.data(), colSize, &lengthIndicator); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { @@ -343,11 +343,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni // colSize-1: remove 0 termination when there is more data to fetch int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator; if (unicode) { - fieldVal += QString((QChar*) buf, rSize / 2); + fieldVal += QString((const QChar*) buf.constData(), rSize / 2); } else { - fieldVal += QString::fromAscii(buf, rSize); + fieldVal += QString::fromAscii(buf.constData(), rSize); } - if (lengthIndicator - fieldVal.size() <= 0) { + memset(buf.data(), 0, colSize); + if (lengthIndicator < colSize) { // workaround for Drivermanagers that don't return SQL_NO_DATA break; } @@ -359,7 +360,6 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni break; } } - delete[] buf; return fieldVal; } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index a6b887a..e9a0670 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -180,6 +180,8 @@ private slots: void odbc_uintfield(); void odbc_bindBoolean_data() { generic_data("QODBC"); } void odbc_bindBoolean(); + void odbc_testqGetString_data() { generic_data("QODBC"); } + void odbc_testqGetString(); void oci_serverDetach_data() { generic_data("QOCI"); } void oci_serverDetach(); // For task 154518 @@ -347,6 +349,7 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) << qTableName("numericfields") << qTableName("qtest_ibaseblobs") << qTableName("qtestBindBool") + << qTableName("testqGetString") << qTableName("qtest_sqlguid") << qTableName("uint_table") << qTableName("uint_test") @@ -2024,6 +2027,44 @@ void tst_QSqlDatabase::odbc_bindBoolean() QCOMPARE(q.value(1).toBool(), false); } +void tst_QSqlDatabase::odbc_testqGetString() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlQuery q(db); + QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("testqGetString") + "(id int, vcvalue varchar(65538))")); + + QString largeString; + largeString.fill('A', 65536); + + // Bind and insert + QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("testqGetString") + " VALUES(?, ?)")); + q.bindValue(0, 1); + q.bindValue(1, largeString); + QVERIFY_SQL(q, exec()); + q.bindValue(0, 2); + q.bindValue(1, largeString+QLatin1Char('B')); + QVERIFY_SQL(q, exec()); + q.bindValue(0, 3); + q.bindValue(1, largeString+QLatin1Char('B')+QLatin1Char('C')); + QVERIFY_SQL(q, exec()); + + // Retrive + QVERIFY_SQL(q, exec("SELECT id, vcvalue FROM " + qTableName("testqGetString") + " ORDER BY id")); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 1); + QCOMPARE(q.value(1).toString().length(), 65536); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 2); + QCOMPARE(q.value(1).toString().length(), 65537); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 3); + QCOMPARE(q.value(1).toString().length(), 65538); +} + + void tst_QSqlDatabase::mysql_multiselect() { QFETCH(QString, dbName); -- cgit v0.12 From b2d9dc8c487a8b87347a7d45a6c4f9dc827ddbfe Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 1 Sep 2009 13:57:30 +1000 Subject: Add #define's for highp/mediump after #version/#extension headers GLSL shaders require that #version and #extension must appear before any other code. The #define's we insert for highp/mediump/etc must therefore be moved down to just after them. Reviewed-by: Gunnar Sletta --- src/opengl/qglshaderprogram.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index c4d9322..56b55d0 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -501,6 +501,25 @@ bool QGLShader::compile(const char *source) return d->compile(this); } else if (d->shader) { QVarLengthArray src; + int headerLen = 0; + while (source && source[headerLen] == '#') { + // Skip #version and #extension directives at the start of + // the shader code. We need to insert the qualifierDefines + // and redefineHighp just after them. + if (qstrncmp(source + headerLen, "#version", 8) != 0 && + qstrncmp(source + headerLen, "#extension", 10) != 0) { + break; + } + while (source[headerLen] != '\0' && source[headerLen] != '\n') + ++headerLen; + if (source[headerLen] == '\n') + ++headerLen; + } + QByteArray header; + if (headerLen > 0) { + header = QByteArray(source, headerLen); + src.append(header.constData()); + } #ifdef QGL_DEFINE_QUALIFIERS src.append(qualifierDefines); #endif @@ -509,7 +528,7 @@ bool QGLShader::compile(const char *source) d->shaderType == PartialFragmentShader) src.append(redefineHighp); #endif - src.append(source); + src.append(source + headerLen); QGLContextGroup *ctx = d->ctx; glShaderSource(d->shader, src.size(), src.data(), 0); return d->compile(this); -- cgit v0.12