00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <simgear/compiler.h>
00025
00026 #include <string>
00027
00028 #ifdef _WIN32
00029 # include <io.h>
00030 #endif
00031
00032 #include <cstring>
00033
00034 #include <simgear/misc/stdint.hxx>
00035 #include <simgear/debug/logstream.hxx>
00036
00037 #include "sg_file.hxx"
00038
00039 using std::string;
00040
00041
00042 SGFile::SGFile(const string &file, int repeat_)
00043 : file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
00044 {
00045 set_type( sgFileType );
00046 }
00047
00048
00049 SGFile::~SGFile() {
00050 }
00051
00052
00053
00054 bool SGFile::open( const SGProtocolDir d ) {
00055 set_dir( d );
00056
00057 if ( get_dir() == SG_IO_OUT ) {
00058 #ifdef _WIN32
00059 int mode = 00666;
00060 #else
00061 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
00062 #endif
00063 fp = ::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode );
00064 } else if ( get_dir() == SG_IO_IN ) {
00065 fp = ::open( file_name.c_str(), O_RDONLY );
00066 } else {
00067 SG_LOG( SG_IO, SG_ALERT,
00068 "Error: bidirection mode not available for files." );
00069 return false;
00070 }
00071
00072 if ( fp == -1 ) {
00073 SG_LOG( SG_IO, SG_ALERT, "Error opening file: " << file_name );
00074 return false;
00075 }
00076
00077 eof_flag = false;
00078 return true;
00079 }
00080
00081
00082
00083 int SGFile::read( char *buf, int length ) {
00084
00085 ssize_t result = ::read( fp, buf, length );
00086 if ( length > 0 && result == 0 ) {
00087 if (repeat < 0 || iteration < repeat - 1) {
00088 iteration++;
00089
00090 off_t fileLen = ::lseek(fp, 0, SEEK_CUR);
00091 if (fileLen == 0) {
00092 eof_flag = true;
00093 return 0;
00094 } else {
00095 ::lseek(fp, 0, SEEK_SET);
00096 return ::read(fp, buf, length);
00097 }
00098 } else {
00099 eof_flag = true;
00100 }
00101 }
00102 return result;
00103 }
00104
00105
00106
00107 int SGFile::readline( char *buf, int length ) {
00108
00109 int pos = lseek( fp, 0, SEEK_CUR );
00110
00111
00112 ssize_t result = ::read( fp, buf, length );
00113 if ( length > 0 && result == 0 ) {
00114 if ((repeat < 0 || iteration < repeat - 1) && pos != 0) {
00115 iteration++;
00116 pos = ::lseek(fp, 0, SEEK_SET);
00117 result = ::read(fp, buf, length);
00118 } else {
00119 eof_flag = true;
00120 }
00121 }
00122
00123
00124 int i;
00125 for ( i = 0; i < result && buf[i] != '\n'; ++i );
00126 if ( buf[i] == '\n' ) {
00127 result = i + 1;
00128 } else {
00129 result = i;
00130 }
00131 lseek( fp, pos + result, SEEK_SET );
00132
00133
00134 buf[ result ] = '\0';
00135
00136 return result;
00137 }
00138
00139
00140
00141 int SGFile::write( const char *buf, const int length ) {
00142 int result = ::write( fp, buf, length );
00143 if ( result != length ) {
00144 SG_LOG( SG_IO, SG_ALERT, "Error writing data: " << file_name );
00145 }
00146
00147 return result;
00148 }
00149
00150
00151
00152 int SGFile::writestring( const char *str ) {
00153 int length = std::strlen( str );
00154 return write( str, length );
00155 }
00156
00157
00158
00159 bool SGFile::close() {
00160 if ( ::close( fp ) == -1 ) {
00161 return false;
00162 }
00163
00164 eof_flag = true;
00165 return true;
00166 }