Panda3D
fltRecordWriter.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file fltRecordWriter.cxx
10  * @author drose
11  * @date 2000-08-24
12  */
13 
14 #include "fltRecordWriter.h"
15 #include "fltInstanceDefinition.h"
16 #include "fltHeader.h"
17 #include "config_flt.h"
18 
19 #include "datagram.h"
20 
21 #include <assert.h>
22 
23 // Don't attempt to write more than this number of bytes in one record. If
24 // the record requires more than this, use continuation records.
25 static const int max_write_length = 65532;
26 
27 /**
28  *
29  */
30 FltRecordWriter::
31 FltRecordWriter(std::ostream &out) :
32  _out(out)
33 {
34 }
35 
36 /**
37  *
38  */
39 FltRecordWriter::
40 ~FltRecordWriter() {
41 }
42 
43 /**
44  * Sets the opcode associated with the current record.
45  */
47 set_opcode(FltOpcode opcode) {
48  _opcode = opcode;
49 }
50 
51 /**
52  * Sets the datagram that will be written when advance() is called.
53  */
55 set_datagram(const Datagram &datagram) {
56  _datagram = datagram;
57 }
58 
59 /**
60  * Returns a modifiable reference to the datagram associated with the current
61  * record. This datagram should then be stuffed with data corresponding to
62  * the data in the record, in preparation for calling advance() to write the
63  * data.
64  */
67  return _datagram;
68 }
69 
70 /**
71  * Writes the current record to the flt file, and resets the current record to
72  * receive new data. Returns FE_ok on success, or something else on error.
73  */
74 FltError FltRecordWriter::
76  int start_byte = 0;
77  int write_length =
78  std::min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
79  FltOpcode opcode = _opcode;
80 
81  do {
82  if (flt_cat.is_debug()) {
83  flt_cat.debug()
84  << "Writing " << opcode << " of length "
85  << write_length + header_size << "\n";
86  }
87 
88  // Build a mini-datagram to write the header.
89  Datagram dg;
90  dg.add_be_int16(opcode);
91  dg.add_be_int16(write_length + header_size);
92 
93  nassertr((int)dg.get_length() == header_size, FE_internal);
94 
95  _out.write((const char *)dg.get_data(), dg.get_length());
96  if (_out.fail()) {
97  assert(!flt_error_abort);
98  return FE_write_error;
99  }
100 
101  // Now write the rest of the record.
102  _out.write((const char *)_datagram.get_data() + start_byte, write_length);
103  if (_out.fail()) {
104  assert(!flt_error_abort);
105  return FE_write_error;
106  }
107 
108  start_byte += write_length;
109  write_length =
110  std::min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
111  opcode = FO_continuation;
112  } while (write_length > 0);
113 
114  _datagram.clear();
115  _opcode = FO_none;
116 
117  return FE_ok;
118 }
119 
120 /**
121  * A convenience function to quickly write a simple record that consists of an
122  * opcode and possibly a datagram.
123  */
124 FltError FltRecordWriter::
125 write_record(FltOpcode opcode, const Datagram &datagram) {
126  _opcode = opcode;
127  _datagram = datagram;
128  return advance();
129 }
130 
131 /**
132  * Ensures that the given instance definition has already been written to the
133  * file. If it has not, writes it now.
134  */
135 FltError FltRecordWriter::
136 write_instance_def(FltHeader *header, int instance_index) {
137  bool inserted = _instances_written.insert(instance_index).second;
138 
139  if (!inserted) {
140  // It's already been written.
141  return FE_ok;
142  }
143 
144  FltInstanceDefinition *instance = header->get_instance(instance_index);
145  if (instance == nullptr) {
146  assert(!flt_error_abort);
147  return FE_undefined_instance;
148  }
149 
150  return instance->write_record_and_children(*this);
151 }
FltRecordWriter::write_instance_def
FltError write_instance_def(FltHeader *header, int instance_index)
Ensures that the given instance definition has already been written to the file.
Definition: fltRecordWriter.cxx:136
fltHeader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_flt.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Datagram::add_be_int16
void add_be_int16(int16_t value)
Adds a signed 16-bit big-endian integer to the datagram.
Definition: datagram.I:145
Datagram::clear
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
Definition: datagram.cxx:35
fltRecordWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
FltRecordWriter::set_datagram
void set_datagram(const Datagram &datagram)
Sets the datagram that will be written when advance() is called.
Definition: fltRecordWriter.cxx:55
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
FltHeader
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:44
FltHeader::get_instance
FltInstanceDefinition * get_instance(int instance_index) const
Returns the instance subtree associated with the given index, or NULL if there is no such instance.
Definition: fltHeader.cxx:422
FltRecordWriter::set_opcode
void set_opcode(FltOpcode opcode)
Sets the opcode associated with the current record.
Definition: fltRecordWriter.cxx:47
FltRecordWriter::update_datagram
Datagram & update_datagram()
Returns a modifiable reference to the datagram associated with the current record.
Definition: fltRecordWriter.cxx:66
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Datagram::get_length
size_t get_length() const
Returns the number of bytes in the datagram.
Definition: datagram.I:335
FltRecordWriter::write_record
FltError write_record(FltOpcode opcode, const Datagram &datagram=Datagram())
A convenience function to quickly write a simple record that consists of an opcode and possibly a dat...
Definition: fltRecordWriter.cxx:125
fltInstanceDefinition.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
FltInstanceDefinition
This special kind of record marks the top node of an instance subtree.
Definition: fltInstanceDefinition.h:28
Datagram::get_data
const void * get_data() const
Returns a pointer to the beginning of the datagram's data.
Definition: datagram.I:327
FltRecordWriter::advance
FltError advance()
Writes the current record to the flt file, and resets the current record to receive new data.
Definition: fltRecordWriter.cxx:75