00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "datagramOutputFile.h"
00016 #include "streamWriter.h"
00017 #include "zStream.h"
00018
00019
00020
00021
00022
00023
00024
00025 bool DatagramOutputFile::
00026 open(const FileReference *file) {
00027 close();
00028
00029 _file = file;
00030 _filename = _file->get_filename();
00031
00032
00033 _filename.set_binary();
00034
00035 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00036 _vfile = vfs->create_file(_filename);
00037 if (_vfile == (VirtualFile *)NULL) {
00038
00039 return false;
00040 }
00041 _out = _vfile->open_write_file(true, true);
00042 _owns_out = (_out != (ostream *)NULL);
00043 return _owns_out && !_out->fail();
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 bool DatagramOutputFile::
00056 open(ostream &out, const Filename &filename) {
00057 close();
00058
00059 _out = &out;
00060 _owns_out = false;
00061 _filename = filename;
00062
00063 if (!filename.empty()) {
00064 _file = new FileReference(filename);
00065 }
00066
00067 return !_out->fail();
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 void DatagramOutputFile::
00077 close() {
00078 _vfile.clear();
00079 if (_owns_out) {
00080 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00081 vfs->close_write_file(_out);
00082 }
00083 _out = (ostream *)NULL;
00084 _owns_out = false;
00085
00086 _file.clear();
00087 _filename = Filename();
00088
00089 _wrote_first_datagram = false;
00090 _error = false;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 bool DatagramOutputFile::
00103 write_header(const string &header) {
00104 nassertr(_out != (ostream *)NULL, false);
00105 nassertr(!_wrote_first_datagram, false);
00106
00107 _out->write(header.data(), header.size());
00108 thread_consider_yield();
00109 return !_out->fail();
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 bool DatagramOutputFile::
00119 put_datagram(const Datagram &data) {
00120 nassertr(_out != (ostream *)NULL, false);
00121 _wrote_first_datagram = true;
00122
00123
00124 StreamWriter writer(_out, false);
00125 writer.add_uint32(data.get_length());
00126
00127
00128 _out->write((const char *)data.get_data(), data.get_length());
00129 thread_consider_yield();
00130
00131 return !_out->fail();
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 bool DatagramOutputFile::
00147 copy_datagram(SubfileInfo &result, const Filename &filename) {
00148 nassertr(_out != (ostream *)NULL, false);
00149 _wrote_first_datagram = true;
00150
00151 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00152 PT(VirtualFile) vfile = vfs->get_file(filename);
00153 if (vfile == NULL) {
00154 return false;
00155 }
00156 istream *in = vfile->open_read_file(true);
00157 if (in == NULL) {
00158 return false;
00159 }
00160
00161 off_t size = vfile->get_file_size(in);
00162 size_t num_remaining = (size_t)size;
00163 nassertr(num_remaining == size, false);
00164
00165 StreamWriter writer(_out, false);
00166 writer.add_uint32(num_remaining);
00167
00168 static const size_t buffer_size = 4096;
00169 char buffer[buffer_size];
00170
00171 streampos start = _out->tellp();
00172 in->read(buffer, min(buffer_size, num_remaining));
00173 size_t count = in->gcount();
00174 while (count != 0) {
00175 _out->write(buffer, count);
00176 if (_out->fail()) {
00177 vfile->close_read_file(in);
00178 return false;
00179 }
00180 num_remaining -= count;
00181 if (num_remaining == 0) {
00182 break;
00183 }
00184 in->read(buffer, min(buffer_size, num_remaining));
00185 count = in->gcount();
00186 }
00187
00188 vfile->close_read_file(in);
00189
00190 if (num_remaining != 0) {
00191 util_cat.error()
00192 << "Truncated input stream.\n";
00193 return false;
00194 }
00195
00196 result = SubfileInfo(_file, start, size);
00197 return true;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 bool DatagramOutputFile::
00214 copy_datagram(SubfileInfo &result, const SubfileInfo &source) {
00215 nassertr(_out != (ostream *)NULL, false);
00216 _wrote_first_datagram = true;
00217
00218 pifstream in;
00219 if (!source.get_filename().open_read(in)) {
00220 return false;
00221 }
00222
00223 size_t num_remaining = source.get_size();
00224
00225 StreamWriter writer(_out, false);
00226 writer.add_uint32(num_remaining);
00227
00228 static const size_t buffer_size = 4096;
00229 char buffer[buffer_size];
00230
00231 streampos start = _out->tellp();
00232 in.seekg(source.get_start());
00233 in.read(buffer, min(buffer_size, num_remaining));
00234 size_t count = in.gcount();
00235 while (count != 0) {
00236 _out->write(buffer, count);
00237 if (_out->fail()) {
00238 return false;
00239 }
00240 num_remaining -= count;
00241 if (num_remaining == 0) {
00242 break;
00243 }
00244 in.read(buffer, min(buffer_size, num_remaining));
00245 count = in.gcount();
00246 }
00247
00248 if (num_remaining != 0) {
00249 util_cat.error()
00250 << "Truncated input stream.\n";
00251 return false;
00252 }
00253
00254 result = SubfileInfo(_file, start, source.get_size());
00255 return true;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264 bool DatagramOutputFile::
00265 is_error() {
00266 if (_out == (ostream *)NULL) {
00267 return true;
00268 }
00269
00270 if (_out->fail()) {
00271 _error = true;
00272 }
00273 return _error;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 void DatagramOutputFile::
00283 flush() {
00284 if (_out != (ostream *)NULL) {
00285 _out->flush();
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 const Filename &DatagramOutputFile::
00298 get_filename() {
00299 return _filename;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 const FileReference *DatagramOutputFile::
00310 get_file() {
00311 return _file;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 streampos DatagramOutputFile::
00327 get_file_pos() {
00328 if (_out == (ostream *)NULL) {
00329 return 0;
00330 }
00331 return _out->tellp();
00332 }