]> git.mxchange.org Git - flightgear.git/blobdiff - src/Network/jpg-httpd.cxx
(Re)allow duplicate names for A/P stages
[flightgear.git] / src / Network / jpg-httpd.cxx
index 32642751a46f8dbbf57ba0451ed84fc1dc5dc360..abf2911e3893210411f82a2c9d21c0e192d90923 100644 (file)
@@ -20,7 +20,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
@@ -33,7 +33,7 @@
 
 #include <stdlib.h>            // atoi() atof()
 
-#include STL_STRING
+#include <string>
 
 #include <simgear/debug/logstream.hxx>
 #include <simgear/io/iochannel.hxx>
 
 #include <Main/fg_props.hxx>
 #include <Main/globals.hxx>
+#include <Main/renderer.hxx>
 
 #include "jpg-httpd.hxx"
 
-SG_USING_STD(string);
+#define __MAX_HTTP_BLOCK_SIZE       4096
+#define __MAX_STRING_SIZE           2048
+#define __TIMEOUT_COUNT             5
+#define __HTTP_GET_STRING           "GET "
+
+#include <osgUtil/SceneView>
+#include <osgViewer/Viewer>
+extern osg::ref_ptr<osgUtil::SceneView> sceneView;
+
+using std::string;
 
 
 bool FGJpegHttpd::open() {
@@ -77,44 +87,125 @@ bool FGJpegHttpd::close() {
     return true;
 }
 
-
 // Handle http GET requests
-void HttpdImageChannel::foundTerminator (void) {
+void HttpdImageChannel :: foundTerminator( void ) {
 
-    closeWhenDone ();
+    closeWhenDone();
 
-    string response;
+    char      szTemp[256];
+    char      szResponse[__MAX_STRING_SIZE];
+    char      *pRequest     = buffer.getData();
+    int       nStep         = 0;
+    int       nBytesSent    = 0;
+    int       nTimeoutCount = 0;
+    int       nBufferCount  = 0;
+    int       nImageLen;
+    int       nBlockSize;
 
-    const string s = buffer.getData();
-    if ( s.find( "GET " ) == 0 ) {
+
+    if ( strstr( pRequest, __HTTP_GET_STRING ) != NULL ) {
         
-        printf("echo: %s\n", s.c_str());
-
-        int ImageLen = JpgFactory->render();
-
-        if( ImageLen ) {
-            response = "HTTP/1.1 200 OK";
-            response += getTerminator();
-            response += "Content-Type: image/jpeg";
-            response += getTerminator();
-            push( response.c_str() );
-
-            char ctmp[256];
-            printf( "info->numbytes = %d\n", ImageLen );
-            sprintf( ctmp, "Content-Length: %d", ImageLen );
-            push( ctmp );
-
-            response = getTerminator();
-            response += "Connection: close";
-            response += getTerminator();
-            response += getTerminator();
-            push( response.c_str() );
-
-            /* can't use strlen on binary data */
-            bufferSend ( (char *)JpgFactory->data(), ImageLen ) ;
+        SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< HTTP Request : " << pRequest );
+
+        double left, right, bottom, top, zNear, zFar;
+       osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+        viewer->getCamera()->getProjectionMatrixAsFrustum(left, right,
+                                                          bottom, top,
+                                                          zNear, zFar);
+        JpgFactory->setFrustum( left, right, bottom, top, zNear, zFar );
+
+        nImageLen  = JpgFactory -> render();
+       nBlockSize = ( nImageLen < __MAX_HTTP_BLOCK_SIZE ? nImageLen : __MAX_HTTP_BLOCK_SIZE );
+
+        if( nImageLen ) {
+           strcpy( szResponse, "HTTP/1.1 200 OK" );
+           strcat( szResponse, getTerminator() );
+           strcat( szResponse, "Content-Type: image/jpeg" );
+            strcat( szResponse, getTerminator() );
+
+            SG_LOG( SG_IO, SG_DEBUG, "info->numbytes = " << nImageLen );
+            sprintf( szTemp, "Content-Length: %d", nImageLen );
+           strcat( szResponse, szTemp );
+
+            strcat( szResponse, getTerminator() );
+           strcat( szResponse, "Connection: close" );
+           strcat( szResponse, getTerminator() );
+           strcat( szResponse, getTerminator() );
+
+           if( getHandle() == -1 )  {
+               SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Invalid socket handle. Ignoring request.\n" );
+               buffer.remove();
+               SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" );
+               return;
+           }
+
+           if( send( ( char * ) szResponse, strlen( szResponse ) ) <= 0 )  {
+               SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Error to send HTTP response. Ignoring request.\n" );
+               buffer.remove();
+               SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" );
+               return;
+           }
+
+           /*
+            * Send block with size defined by __MAX_HTTP_BLOCK_SIZE
+            */
+           while( nStep <= nImageLen ) {
+                nBufferCount++;
+
+               if( getHandle() == -1 )  {
+                   SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Invalid socket handle. Ignoring request.\n" );
+                   break;
+               }
+
+               nBytesSent = send( ( char * ) JpgFactory -> data() + nStep, nBlockSize );
+
+               if( nBytesSent <= 0 )  {
+                   if( nTimeoutCount == __TIMEOUT_COUNT )  {
+                       SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Timeout reached. Exiting before end of image transmission.\n" );
+                       nTimeoutCount = 0;
+                       break;
+                   }
+
+               SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Zero bytes sent.\n" );
+
+#ifdef _WIN32
+                Sleep(1000);
+#else
+               sleep(1);
+#endif
+               nTimeoutCount++;
+               continue;
+           }
+
+           SG_LOG( SG_IO, SG_DEBUG, ">>>>>>>>> (" << nBufferCount << ") BLOCK STEP " << nStep << " - IMAGELEN " << nImageLen << " - BLOCKSIZE " << nBlockSize << " - SENT " << nBytesSent );
+
+           /*
+            * Calculate remaining image.
+            */
+           if( ( nStep + nBlockSize ) >= nImageLen ) {
+               nBlockSize = ( nImageLen - nStep );
+               nStep += nBlockSize;
+           }
+
+           nStep += nBytesSent;
+           nTimeoutCount = 0;
+#ifdef _WIN32
+            Sleep(1);
+#else
+           usleep( 1000 );
+#endif
+       }
+
+       SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" );
+
         } else {
-            printf("!!! NO IMAGE !!!\n\tinfo->numbytes = %d\n", ImageLen );
+            SG_LOG( SG_IO, SG_DEBUG, "!!! NO IMAGE !!!  info -> numbytes = " << nImageLen );
         }
+
+       /*
+        * Release JPEG buffer.
+        */
+       JpgFactory -> destroy();
     }
 
     buffer.remove();