Panda3D

fltRecordWriter.cxx

00001 // Filename: fltRecordWriter.cxx
00002 // Created by:  drose (24Aug00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "fltRecordWriter.h"
00016 #include "fltInstanceDefinition.h"
00017 #include "fltHeader.h"
00018 #include "config_flt.h"
00019 
00020 #include "datagram.h"
00021 
00022 #include <assert.h>
00023 
00024 // Don't attempt to write more than this number of bytes in one
00025 // record.  If the record requires more than this, use continuation
00026 // records.
00027 static const int max_write_length = 65532;
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: FltRecordWriter::Constructor
00031 //       Access: Public
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 FltRecordWriter::
00035 FltRecordWriter(ostream &out) :
00036   _out(out)
00037 {
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: FltRecordWriter::Destructor
00042 //       Access: Public
00043 //  Description:
00044 ////////////////////////////////////////////////////////////////////
00045 FltRecordWriter::
00046 ~FltRecordWriter() {
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: FltRecordWriter::set_opcode
00051 //       Access: Public
00052 //  Description: Sets the opcode associated with the current record.
00053 ////////////////////////////////////////////////////////////////////
00054 void FltRecordWriter::
00055 set_opcode(FltOpcode opcode) {
00056   _opcode = opcode;
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: FltRecordWriter::set_datagram
00061 //       Access: Public
00062 //  Description: Sets the datagram that will be written when advance()
00063 //               is called.
00064 ////////////////////////////////////////////////////////////////////
00065 void FltRecordWriter::
00066 set_datagram(const Datagram &datagram) {
00067   _datagram = datagram;
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: FltRecordWriter::update_datagram
00072 //       Access: Public
00073 //  Description: Returns a modifiable reference to the datagram
00074 //               associated with the current record.  This datagram
00075 //               should then be stuffed with data corresponding to the
00076 //               data in the record, in preparation for calling
00077 //               advance() to write the data.
00078 ////////////////////////////////////////////////////////////////////
00079 Datagram &FltRecordWriter::
00080 update_datagram() {
00081   return _datagram;
00082 }
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: FltRecordWriter::advance
00086 //       Access: Public
00087 //  Description: Writes the current record to the flt file, and resets
00088 //               the current record to receive new data.  Returns
00089 //               FE_ok on success, or something else on error.
00090 ////////////////////////////////////////////////////////////////////
00091 FltError FltRecordWriter::
00092 advance() {
00093   int start_byte = 0;
00094   int write_length =
00095     min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
00096   FltOpcode opcode = _opcode;
00097 
00098   do {
00099     if (flt_cat.is_debug()) {
00100       flt_cat.debug()
00101         << "Writing " << opcode << " of length "
00102         << write_length + header_size << "\n";
00103     }
00104 
00105     // Build a mini-datagram to write the header.
00106     Datagram dg;
00107     dg.add_be_int16(opcode);
00108     dg.add_be_int16(write_length + header_size);
00109 
00110     nassertr((int)dg.get_length() == header_size, FE_internal);
00111 
00112     _out.write((const char *)dg.get_data(), dg.get_length());
00113     if (_out.fail()) {
00114       assert(!flt_error_abort);
00115       return FE_write_error;
00116     }
00117 
00118     // Now write the rest of the record.
00119     _out.write((const char *)_datagram.get_data() + start_byte, write_length);
00120     if (_out.fail()) {
00121       assert(!flt_error_abort);
00122       return FE_write_error;
00123     }
00124 
00125     start_byte += write_length;
00126     write_length =
00127       min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
00128     opcode = FO_continuation;
00129   } while (write_length > 0);
00130 
00131   _datagram.clear();
00132   _opcode = FO_none;
00133 
00134   return FE_ok;
00135 }
00136 
00137 ////////////////////////////////////////////////////////////////////
00138 //     Function: FltRecordWriter::write_record
00139 //       Access: Public
00140 //  Description: A convenience function to quickly write a simple
00141 //               record that consists of an opcode and possibly a
00142 //               datagram.
00143 ////////////////////////////////////////////////////////////////////
00144 FltError FltRecordWriter::
00145 write_record(FltOpcode opcode, const Datagram &datagram) {
00146   _opcode = opcode;
00147   _datagram = datagram;
00148   return advance();
00149 }
00150 
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: FltRecordWriter::write_instance_def
00153 //       Access: Public
00154 //  Description: Ensures that the given instance definition has
00155 //               already been written to the file.  If it has not,
00156 //               writes it now.
00157 ////////////////////////////////////////////////////////////////////
00158 FltError FltRecordWriter::
00159 write_instance_def(FltHeader *header, int instance_index) {
00160   bool inserted = _instances_written.insert(instance_index).second;
00161 
00162   if (!inserted) {
00163     // It's already been written.
00164     return FE_ok;
00165   }
00166 
00167   FltInstanceDefinition *instance = header->get_instance(instance_index);
00168   if (instance == (FltInstanceDefinition *)NULL) {
00169     assert(!flt_error_abort);
00170     return FE_undefined_instance;
00171   }
00172 
00173   return instance->write_record_and_children(*this);
00174 }
 All Classes Functions Variables Enumerations