]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/sg_file.cxx
Terrasync: implement HTTP service lookup via DNS
[simgear.git] / simgear / io / sg_file.cxx
index 79cec7b7328bcf6dd8662ea2aa92ce8e04391fdf..0cf66f77d6f0139dc654e914ff89c3d403f3437d 100644 (file)
@@ -2,7 +2,7 @@
 //
 // Written by Curtis Olson, started November 1999.
 //
-// Copyright (C) 1999  Curtis L. Olson - curt@flightgear.org
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
 //
 // 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$
 
 
 #include <simgear/compiler.h>
 
-#include STL_STRING
+#include <string>
 
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#ifdef _WIN32
 #  include <io.h>
 #endif
 
+#include <cstring>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#if !defined(_MSC_VER)
+# include <unistd.h>
+#endif
+
+#include <simgear/misc/stdint.hxx>
 #include <simgear/debug/logstream.hxx>
 
 #include "sg_file.hxx"
 
-SG_USING_STD(string);
-
 
-SGFile::SGFile( const string &file) {
+SGFile::SGFile(const std::string &file, int repeat_)
+    : file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
+{
     set_type( sgFileType );
-    file_name = file;
 }
 
+SGFile::SGFile( int existingFd ) :
+    fp(existingFd),
+    eof_flag(false),
+    repeat(1),
+    iteration(0)
+{
+    set_type( sgFileType );
+}
 
 SGFile::~SGFile() {
 }
@@ -51,7 +69,7 @@ bool SGFile::open( const SGProtocolDir d ) {
     set_dir( d );
 
     if ( get_dir() == SG_IO_OUT ) {
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#ifdef _WIN32
         int mode = 00666;
 #else
         mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
@@ -70,6 +88,7 @@ bool SGFile::open( const SGProtocolDir d ) {
        return false;
     }
 
+    eof_flag = false;
     return true;
 }
 
@@ -77,7 +96,24 @@ bool SGFile::open( const SGProtocolDir d ) {
 // read a block of data of specified size
 int SGFile::read( char *buf, int length ) {
     // read a chunk
-    return ::read( fp, buf, length );
+    ssize_t result = ::read( fp, buf, length );
+    if ( length > 0 && result == 0 ) {
+        if (repeat < 0 || iteration < repeat - 1) {
+            iteration++;
+            // loop reading the file, unless it is empty
+            off_t fileLen = ::lseek(fp, 0, SEEK_CUR);
+            if (fileLen == 0) {
+                eof_flag = true;
+                return 0;
+            } else {
+                ::lseek(fp, 0, SEEK_SET);
+                return ::read(fp, buf, length);
+            }
+        } else {
+            eof_flag = true;
+        }
+    }
+    return result;
 }
 
 
@@ -87,7 +123,16 @@ int SGFile::readline( char *buf, int length ) {
     int pos = lseek( fp, 0, SEEK_CUR );
 
     // read a chunk
-    int result = ::read( fp, buf, length );
+    ssize_t result = ::read( fp, buf, length );
+    if ( length > 0 && result == 0 ) {
+        if ((repeat < 0 || iteration < repeat - 1) && pos != 0) {
+            iteration++;
+            pos = ::lseek(fp, 0, SEEK_SET);
+            result = ::read(fp, buf, length);
+        } else {
+            eof_flag = true;
+        }
+    }
 
     // find the end of line and reset position
     int i;
@@ -119,7 +164,7 @@ int SGFile::write( const char *buf, const int length ) {
 
 // write null terminated string to a file
 int SGFile::writestring( const char *str ) {
-    int length = strlen( str );
+    int length = std::strlen( str );
     return write( str, length );
 }
 
@@ -130,5 +175,6 @@ bool SGFile::close() {
        return false;
     }
 
+    eof_flag = true;
     return true;
 }