[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [publictransport] engine: Forward network error messages from scripts
From:       Friedrich_Karl_Tilman_Pülz <fpuelz () gmx ! de>
Date:       2012-11-30 20:36:57
Message-ID: 20121130203657.6F8EDA60CE () git ! kde ! org
[Download RAW message or body]

Git commit b622a11a584338f113e6340ddfec9f1787af43e2 by Friedrich Karl Tilman Pülz.
Committed on 27/11/2012 at 17:53.
Pushed by fkpulz into branch 'master'.

Forward network error messages from scripts

Add error parameters to Scripting::NetworkRequest::finished(),
throw an error from the script if a network request failed
but the script depends on the request to be finished successfully.
The exception gets detected by the engine and the error message
gets published in the data source, ie. shown in eg. the applet.

M  +9    -6    engine/script/scripting.cpp
M  +11   -3    engine/script/scripting.h
M  +15   -3    engine/script/serviceProviders/base_hafas_journeys.js
M  +10   -2    engine/script/serviceProviders/base_hafas_stopsuggestions.js
M  +18   -4    engine/script/serviceProviders/base_hafas_timetable.js
M  +5    -1    engine/script/serviceProviders/ch_opendata.js
M  +5    -1    engine/script/serviceProviders/cz_idnes.js
M  +4    -1    engine/script/serviceProviders/de_bvg.js
M  +4    -1    engine/script/serviceProviders/de_db.js
M  +5    -1    engine/script/serviceProviders/de_dvb.js
M  +5    -1    engine/script/serviceProviders/international_flightstats.js
M  +5    -1    engine/script/serviceProviders/it_orario.js
M  +20   -11   engine/timetablemate/src/debugger/timetabledatarequestjob.cpp
M  +1    -0    engine/timetablemate/src/debugger/timetabledatarequestjob.h
M  +1    -1    engine/timetablemate/src/project.cpp
M  +5    -1    engine/timetablemate/templates/template.js

http://commits.kde.org/publictransport/b622a11a584338f113e6340ddfec9f1787af43e2

diff --git a/engine/script/scripting.cpp b/engine/script/scripting.cpp
index 06d1493..9a7189a 100644
--- a/engine/script/scripting.cpp
+++ b/engine/script/scripting.cpp
@@ -94,7 +94,7 @@ void NetworkRequest::abort()
     m_mutex->unlockInline();
 
     emit aborted( timedOut );
-    emit finished();
+    emit finished( QByteArray(), true, i18nc("@info/plain", "The request was \
aborted") );  }
 
 void NetworkRequest::slotReadyRead()
@@ -229,6 +229,8 @@ void NetworkRequest::slotFinished()
     if ( m_reply->url().isEmpty() ) {
         kWarning() << "Empty URL in QNetworkReply!";
     }
+    const bool hasError = m_reply->error() != QNetworkReply::NoError;
+    const QString errorString = m_reply->errorString();
     m_reply->deleteLater();
     m_reply = 0;
 
@@ -236,7 +238,7 @@ void NetworkRequest::slotFinished()
     const QByteArray data = m_data;
     m_mutex->unlockInline();
 
-    emit finished( data, statusCode, size );
+    emit finished( data, hasError, errorString, statusCode, size );
 }
 
 void NetworkRequest::started( QNetworkReply* reply, int timeout )
@@ -400,8 +402,8 @@ NetworkRequest* Network::createRequest( const QString& url, const \
QString &userU  NetworkRequest::Ptr requestPtr( request );
     m_requests << requestPtr;
     connect( request, SIGNAL(started()), this, SLOT(slotRequestStarted()) );
-    connect( request, SIGNAL(finished(QByteArray,int,int)),
-             this, SLOT(slotRequestFinished(QByteArray,int,int)) );
+    connect( request, SIGNAL(finished(QByteArray,bool,QString,int,int)),
+             this, SLOT(slotRequestFinished(QByteArray,bool,QString,int,int)) );
     connect( request, SIGNAL(aborted()), this, SLOT(slotRequestAborted()) );
     connect( request, SIGNAL(redirected(QUrl)), this, \
SLOT(slotRequestRedirected(QUrl)) );  return request;
@@ -430,7 +432,8 @@ void Network::slotRequestStarted()
     emit requestStarted( sharedRequest );
 }
 
-void Network::slotRequestFinished( const QByteArray &data, int statusCode, int size \
) +void Network::slotRequestFinished( const QByteArray &data, bool error, const \
QString &errorString,  +                                   int statusCode, int size )
 {
     NetworkRequest *request = qobject_cast< NetworkRequest* >( sender() );
     NetworkRequest::Ptr sharedRequest = getSharedRequest( request );
@@ -446,7 +449,7 @@ void Network::slotRequestFinished( const QByteArray &data, int \
statusCode, int s  m_finishedRequests << sharedRequest;
     m_mutex->unlockInline();
 
-    emit requestFinished( sharedRequest, data, timestamp, statusCode, size );
+    emit requestFinished( sharedRequest, data, error, errorString, timestamp, \
statusCode, size );  
     if ( !hasRunningRequests() ) {
         emit allRequestsFinished();
diff --git a/engine/script/scripting.h b/engine/script/scripting.h
index cc37c3b..5f059ea 100644
--- a/engine/script/scripting.h
+++ b/engine/script/scripting.h
@@ -450,11 +450,14 @@ Q_SIGNALS:
      * @brief Emitted when this request has finished.
      *
      * @param data The complete data downloaded for this request.
-     * @param statusCode The HTTP status code received.
+     * @param error @c True, if there was an error executing the request, @c false \
otherwise. +     * @param errorString A human readable description of the error if @p \
error is @c true. +     * @param statusCode The HTTP status code that was received or \
                -1 if there was an error.
      * @param size The size in bytes of the received data.
      * @ingroup scripting
      **/
-    void finished( const QByteArray &data = QByteArray(), int statusCode = 200, int \
size = 0 ); +    void finished( const QByteArray &data = QByteArray(), bool error = \
false, +                   const QString &errorString = QString(), int statusCode = \
-1, int size = 0 );  
     /**
      * @brief Emitted when new data is available for this request.
@@ -701,6 +704,9 @@ Q_SIGNALS:
      * This signal is @em not emitted if the network gets accessed synchronously.
      * @param request The request that has finished.
      * @param data Received data decoded to a string.
+     * @param error @c True, if there was an error executing the request, @c false \
otherwise. +     * @param errorString A human readable description of the error if @p \
error is @c true. +     * @param timestamp The date and time on which the request was \
                finished.
      * @param statusCode The HTTP status code received.
      * @param size The size in bytes of the received data.
      * @ingroup scripting
@@ -708,6 +714,7 @@ Q_SIGNALS:
      **/
     void requestFinished( const NetworkRequest::Ptr &request,
                           const QByteArray &data = QByteArray(),
+                          bool error = false, const QString &errorString = \
QString(),  const QDateTime &timestamp = QDateTime(),
                           int statusCode = 200, int size = 0 );
 
@@ -778,7 +785,8 @@ public Q_SLOTS:
 
 protected Q_SLOTS:
     void slotRequestStarted();
-    void slotRequestFinished( const QByteArray &data = QByteArray(), int statusCode \
= 200, +    void slotRequestFinished( const QByteArray &data = QByteArray(), bool \
error = false, +                              const QString &errorString = QString(), \
int statusCode = -1,  int size = 0 );
     void slotRequestAborted();
     void slotRequestRedirected( const QUrl &newUrl );
diff --git a/engine/script/serviceProviders/base_hafas_journeys.js \
b/engine/script/serviceProviders/base_hafas_journeys.js index 2f8cbd0..5325804 100644
--- a/engine/script/serviceProviders/base_hafas_journeys.js
+++ b/engine/script/serviceProviders/base_hafas_journeys.js
@@ -113,7 +113,11 @@ var __hafas_journeys = function(hafas) {
         },
 
         parser: new HafasPrivate.Parser({
-            parseBinary: function( data ) {
+            parseBinary: function( data, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 if ( data.isEmpty() ) {
                     throw Error("hafas.journeys.parser.parseBinary(): Empty data \
received");  }
@@ -794,7 +798,11 @@ var __hafas_journeys = function(hafas) {
                 buffer.close();
             },
 
-            parseXml: function( xml ) {
+            parseXml: function( xml, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 var options = prepareOptions( undefined, public.journeys.options );
                 if ( !expectFormat(_formats.XmlFormat, xml) ) {
                     if ( isHtml(xml) )
@@ -838,7 +846,11 @@ var __hafas_journeys = function(hafas) {
                 return true;
             },
 
-            parse: function( js ) { // TODO rename to parseJson() and add format \
JSON? +            parse: function( js, hasError, errorString ) { // TODO rename to \
parseJson() and add format JSON? +                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 // First check format and cut away the JavaScript code (do not eval \
it)  var begin = /^\s*BAHN_MNB\.fm\s*=\s*/.exec( js );
                 var end = /;\s*BAHN_MNB\.Callback\(\);\s*$/.exec( js );
diff --git a/engine/script/serviceProviders/base_hafas_stopsuggestions.js \
b/engine/script/serviceProviders/base_hafas_stopsuggestions.js index 7d2fcf7..80e407b \
                100644
--- a/engine/script/serviceProviders/base_hafas_stopsuggestions.js
+++ b/engine/script/serviceProviders/base_hafas_stopsuggestions.js
@@ -117,7 +117,11 @@ var __hafas_stopsuggestions = function(hafas) {
             *   the HAFAS provider.
             * @return {Boolean} True, if stop suggestions were found, false \
                otherwise.
             **/
-            parseJavaScript: function( js ) {
+            parseJavaScript: function( js, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 // First check format and cut away the JavaScript code (do not eval \
                it)
                 if ( js.left(23).string() != "SLs.sls={\"suggestions\":" ||
                         js.right(23).string() != "};SLs.showSuggestion();" )
@@ -205,7 +209,11 @@ var __hafas_stopsuggestions = function(hafas) {
             *   the HAFAS provider.
             * @return {Boolean} True, if stop suggestions were found, false \
                otherwise.
             **/
-            parseJavaScript: function( js ) {
+            parseJavaScript: function( js, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 if ( js.length < 2 ) {
                     throw Error("Hafas.stopSuggestions.parseGeoPosition(): " +
                             "Incorrect stop suggestions document received");
diff --git a/engine/script/serviceProviders/base_hafas_timetable.js \
b/engine/script/serviceProviders/base_hafas_timetable.js index 917f789..d46f6ba \
                100644
--- a/engine/script/serviceProviders/base_hafas_timetable.js
+++ b/engine/script/serviceProviders/base_hafas_timetable.js
@@ -102,9 +102,16 @@ var __hafas_timetable = function(hafas) {
             *
             * @param {String} xml Contents of a departures/arrivals document in XML \
                format received from
             *   the HAFAS provider.
+            * @param {Boolean} hasError Whether or not there was an error executing
+            *   the network request.
+            * @param {String} errorString A human readable description of the error, \
                if any.
             * @return {Boolean} True, if departures/arrivals were found, false \
                otherwise.
             **/
-            parseXml: function( xml ) {
+            parseXml: function( xml, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 var options = HafasPrivate.prepareOptions( processor.options, \
hafas.options );  if ( !HafasPrivate.expectFormat(Hafas.XmlFormat, xml) ) {
                     if ( HafasPrivate.isHtml(xml) &&
@@ -213,11 +220,18 @@ var __hafas_timetable = function(hafas) {
             * Found departures/arrivals will be added to the "result" object.
             * @note The script extension "qt.xml" is needed.
             *
-            * @param {String} xml Contents of a departures/arrivals document in XML \
                format received from
-            *   the HAFAS provider.
+            * @param {String} xml Contents of a departures/arrivals document in XML \
format  +            *   received from the HAFAS provider.
+            * @param {Boolean} hasError Whether or not there was an error executing
+            *   the network request.
+            * @param {String} errorString A human readable description of the error, \
                if any.
             * @return {Boolean} True, if departures/arrivals were found, false \
                otherwise.
             **/
-            parseXmlResC: function( xml ) {
+            parseXmlResC: function( xml, hasError, errorString ) {
+                if ( hasError ) {
+                    throw Error( errorString );
+                }
+
                 if ( !HafasPrivate.expectFormat(Hafas.XmlFormat, xml) ) {
                     if ( HafasPrivate.isHtml(xml) ) {
                         return processor.parseHtml( xml );
diff --git a/engine/script/serviceProviders/ch_opendata.js \
b/engine/script/serviceProviders/ch_opendata.js index 101d296..6176227 100644
--- a/engine/script/serviceProviders/ch_opendata.js
+++ b/engine/script/serviceProviders/ch_opendata.js
@@ -24,7 +24,11 @@ function getTimetable( values ) {
     network.get( request );
 }
 
-function parseTimetable( jsonDocument ) {
+function parseTimetable( jsonDocument, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     // Decode the received QByteArray and parse it's JSON content
     jsonDocument = helper.decode( jsonDocument );
     var json = JSON.parse( jsonDocument );
diff --git a/engine/script/serviceProviders/cz_idnes.js \
b/engine/script/serviceProviders/cz_idnes.js index dcf64f4..fb9fa09 100644
--- a/engine/script/serviceProviders/cz_idnes.js
+++ b/engine/script/serviceProviders/cz_idnes.js
@@ -17,7 +17,11 @@ function getTimetable( values ) {
     network.get( request );
 }
 
-function parseTimetable( html ) {
+function parseTimetable( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     if ( helper.findFirstHtmlTag(html, "a",
          {attributes: {"class": "selectobject", "title": "Input specification"},
           contentsRegExp: "The input is ambiguous, please specify it\."}).found )
diff --git a/engine/script/serviceProviders/de_bvg.js \
b/engine/script/serviceProviders/de_bvg.js index e793feb..40ea58a 100644
--- a/engine/script/serviceProviders/de_bvg.js
+++ b/engine/script/serviceProviders/de_bvg.js
@@ -30,7 +30,10 @@ hafas.timetable.options.format = Hafas.HtmlMobileFormat;
 hafas.routeData.options.format = Hafas.HtmlMobileFormat;
 
 // Implement parser for departure/arrival data in mobile HTML format
-hafas.timetable.parser.parseHtmlMobile = function( html ) {
+hafas.timetable.parser.parseHtmlMobile = function( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
     if ( html.length == 0 ) {
         throw Error("Received HTML document is empty");
     }
diff --git a/engine/script/serviceProviders/de_db.js \
b/engine/script/serviceProviders/de_db.js index 703e2fa..aca16c3 100644
--- a/engine/script/serviceProviders/de_db.js
+++ b/engine/script/serviceProviders/de_db.js
@@ -22,7 +22,10 @@ var getAdditionalData = hafas.timetable.additionalData.get;
 var getJourneys = hafas.journeys.get;
 
 // Needed to get route data URLs for additional data
-hafas.timetable.parser.parseHtmlMobile = function( html ) {
+hafas.timetable.parser.parseHtmlMobile = function( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
     if ( html.length == 0 ) {
         throw Error("hafas.parseTimetableMobile(): Received HTML document is \
empty");  }
diff --git a/engine/script/serviceProviders/de_dvb.js \
b/engine/script/serviceProviders/de_dvb.js index a2f30ee..fb05ebd 100644
--- a/engine/script/serviceProviders/de_dvb.js
+++ b/engine/script/serviceProviders/de_dvb.js
@@ -17,7 +17,11 @@ function getTimetable( values ) {
     network.get( request );
 }
 
-function parseTimetable( json ) {
+function parseTimetable( json, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     // Initialize regular expressions (compile them only once)
     var departureRegExp = /\["([^"]*)","([^"]*)","([^"]*)"\]/ig;
 
diff --git a/engine/script/serviceProviders/international_flightstats.js \
b/engine/script/serviceProviders/international_flightstats.js index 1b17cdb..d0e3fd4 \
                100644
--- a/engine/script/serviceProviders/international_flightstats.js
+++ b/engine/script/serviceProviders/international_flightstats.js
@@ -16,7 +16,11 @@ function getTimetable( values ) {
     network.get( request );
 }
 
-function parseTimetable( html ) {
+function parseTimetable( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     // Decode document
     html = helper.decode( html, "utf8" );
 
diff --git a/engine/script/serviceProviders/it_orario.js \
b/engine/script/serviceProviders/it_orario.js index ae32c41..43a1c13 100644
--- a/engine/script/serviceProviders/it_orario.js
+++ b/engine/script/serviceProviders/it_orario.js
@@ -39,7 +39,11 @@ function typeOfVehicleFromString( string ) {
     }
 }
 
-function parseTimetable( html ) {
+function parseTimetable( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     var returnValue = new Array;
     // Dates are set from today, not the requested date. They need to be adjusted by \
                X days,
     // where X is the difference in days between today and the requested date.
diff --git a/engine/timetablemate/src/debugger/timetabledatarequestjob.cpp \
b/engine/timetablemate/src/debugger/timetabledatarequestjob.cpp index \
                9aa8646..50388e8 100644
--- a/engine/timetablemate/src/debugger/timetabledatarequestjob.cpp
+++ b/engine/timetablemate/src/debugger/timetabledatarequestjob.cpp
@@ -253,8 +253,8 @@ void CallScriptFunctionJob::connectScriptObjects( bool doConnect \
)  QMutexLocker locker( m_mutex );
     if ( doConnect ) {
         // Connect to request finished signals to store the time spent for network \
                requests
-        connect( m_objects.network.data(), \
                SIGNAL(requestFinished(NetworkRequest::Ptr,QByteArray,QDateTime,int,int)),
                
-                 this, \
SLOT(requestFinished(NetworkRequest::Ptr,QByteArray,QDateTime,int,int)) ); +        \
connect( m_objects.network.data(), \
SIGNAL(requestFinished(NetworkRequest::Ptr,QByteArray,bool,QString,QDateTime,int,int)),
 +                 this, \
SLOT(requestFinished(NetworkRequest::Ptr,QByteArray,bool,QString,QDateTime,int,int)) \
                );
         connect( m_objects.network.data(), \
                SIGNAL(synchronousRequestFinished(QString,QByteArray,bool,int,int,int)),
                
                  this, \
SLOT(synchronousRequestFinished(QString,QByteArray,bool,int,int,int)) );  
@@ -270,8 +270,8 @@ void CallScriptFunctionJob::connectScriptObjects( bool doConnect \
                )
         connect( m_agent, \
                SIGNAL(stopped(QDateTime,bool,bool,int,QString,QStringList)),
                  this, \
SLOT(scriptStopped(QDateTime,bool,bool,int,QString,QStringList)) );  } else {
-        disconnect( m_objects.network.data(), \
                SIGNAL(requestFinished(NetworkRequest::Ptr,QByteArray,QDateTime,int,int)),
                
-                    this, \
SLOT(requestFinished(NetworkRequest::Ptr,QByteArray,QDateTime,int,int)) ); +        \
disconnect( m_objects.network.data(), \
SIGNAL(requestFinished(NetworkRequest::Ptr,QByteArray,bool,QString,QDateTime,int,int)),
 +                    this, \
SLOT(requestFinished(NetworkRequest::Ptr,QByteArray,bool,QString,QDateTime,int,int)) \
                );
         disconnect( m_objects.network.data(), \
                SIGNAL(synchronousRequestFinished(QString,QByteArray,bool,int,int,int)),
                
                     this, \
                SLOT(synchronousRequestFinished(QString,QByteArray,bool,int,int,int)) \
                );
         disconnect( m_objects.helper.data(), \
SIGNAL(messageReceived(QString,QScriptContextInfo,QString,Helper::ErrorSeverity)), @@ \
-498,18 +498,27 @@ void CallScriptFunctionJob::invalidDataReceived( \
Enums::TimetableInformation inf  }
 
 void CallScriptFunctionJob::requestFinished( const NetworkRequest::Ptr &request,
-                                             const QByteArray &data, const QDateTime \
                &timestamp,
-                                             int statusCode, int size )
+                                             const QByteArray &data,
+                                             bool error, const QString &errorString,
+                                             const QDateTime &timestamp, int \
statusCode, int size )  {
     Q_UNUSED( data );
     emit asynchronousRequestWaitFinished( timestamp, statusCode, size );
 
     QMutexLocker locker( m_mutex );
-    m_additionalMessages << TimetableDataRequestMessage(
-            i18nc("@info/plain", "Download finished (status %1): %2, \
                <link>%3</link>",
-                  statusCode, KGlobal::locale()->formatByteSize(size), \
                request->url()),
-            TimetableDataRequestMessage::Information, QString(), -1,
-            TimetableDataRequestMessage::OpenLink, request->url() );
+    if ( error ) {
+        m_additionalMessages << TimetableDataRequestMessage(
+                i18nc("@info/plain", "Download failed (<message>%1</message>): \
<link>%2</link>", +                      errorString, request->url()),
+                TimetableDataRequestMessage::Information, QString(), -1,
+                TimetableDataRequestMessage::OpenLink, request->url() );
+    } else {
+        m_additionalMessages << TimetableDataRequestMessage(
+                i18nc("@info/plain", "Download finished (status %1): %2, \
<link>%3</link>", +                      statusCode, \
KGlobal::locale()->formatByteSize(size), request->url()), +                \
TimetableDataRequestMessage::Information, QString(), -1, +                \
TimetableDataRequestMessage::OpenLink, request->url() ); +    }
 }
 
 void CallScriptFunctionJob::synchronousRequestFinished( const QString &url, const \
                QByteArray &data,
diff --git a/engine/timetablemate/src/debugger/timetabledatarequestjob.h \
b/engine/timetablemate/src/debugger/timetabledatarequestjob.h index 251db13..bde0776 \
                100644
--- a/engine/timetablemate/src/debugger/timetabledatarequestjob.h
+++ b/engine/timetablemate/src/debugger/timetabledatarequestjob.h
@@ -104,6 +104,7 @@ protected slots:
                               int index, const QVariantMap& map );
 
     void requestFinished( const NetworkRequest::Ptr &request, const QByteArray &data \
= QByteArray(), +                          bool error = false, const QString \
&errorString = QString(),  const QDateTime &timestamp = QDateTime(),
                           int statusCode = 200, int size = 0 );
     void synchronousRequestFinished( const QString &url, const QByteArray &data = \
                QByteArray(),
diff --git a/engine/timetablemate/src/project.cpp \
b/engine/timetablemate/src/project.cpp index 2d75936..a157e04 100644
--- a/engine/timetablemate/src/project.cpp
+++ b/engine/timetablemate/src/project.cpp
@@ -234,7 +234,7 @@ public:
                     "\n"
                     "// This function is connected to the finished signal of network \
requests\n"  "// started in getTimetable()\n"
-                    "function parseTimetable( html ) {\n"
+                    "function parseTimetable( html, hasError, errorString ) {\n"
                     "    // TODO: Parse the contents of the received document and \
add results \n"  "    // using result.addData()\n"
                     "    // Use helper.findHtmlTags(), helper.findFirstHtmlTag() or \
                \n"
diff --git a/engine/timetablemate/templates/template.js \
b/engine/timetablemate/templates/template.js index 6ed65aa..3c39527 100644
--- a/engine/timetablemate/templates/template.js
+++ b/engine/timetablemate/templates/template.js
@@ -24,7 +24,11 @@ function getUrlForDetailedJourneyResults( html ) {
 
 // This function parses a given HTML document for timetable infos.
 // The infos are added to the result-array as shown below.
-function parseTimetable( html ) {
+function parseTimetable( html, hasError, errorString ) {
+    if ( hasError ) {
+        throw Error( errorString );
+    }
+
     // Add departure
     // A list of all available key-strings to use in the result-array is at
     //    /publictransport-data-engine-sources/enums.h.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic