@@ -23,133 +23,92 @@ typedef off_t traceoff_t;
2323
2424namespace SerializedTrace {
2525
26- TraceContainerWriter::TraceContainerWriter (std::string filename,
27- frame_architecture arch,
28- uint64_t machine,
29- uint64_t frames_per_toc_entry_in,
30- bool auto_finish_in) throw (TraceException)
31- : num_frames (0 ),
32- frames_per_toc_entry (frames_per_toc_entry_in),
33- arch (arch),
34- mach (machine),
35- auto_finish (auto_finish_in),
36- is_finished (false )
37- {
38- ofs = fopen (filename.c_str (), " wb" );
39- if (!ofs) { throw (TraceException (" Unable to open trace file for writing" )); }
40- SEEK (ofs, first_frame_offset);
26+ FILE *open_trace (const std::string& filename,
27+ frame_architecture arch,
28+ uint64_t machine,
29+ uint64_t trace_version) {
30+ FILE *ofs = fopen (filename.c_str (), " wb" );
31+ if (!ofs) throw TraceException (" Unable to open trace file for writing" );
32+ int64_t toc_off = 0LL , toc_num_frames = 0LL ;
33+
34+ WRITE (magic_number);
35+ WRITE (trace_version);
36+ uint64_t archt = (uint64_t ) arch;
37+ WRITE (archt);
38+ WRITE (machine);
39+ WRITE (toc_num_frames);
40+ WRITE (toc_off);
41+ return ofs;
4142 }
4243
43- TraceContainerWriter::~TraceContainerWriter (void ) throw () {
4444
45- /* * Call finish if it has not been called already ANd if
46- auto_finish is set. */
47- if (!is_finished && auto_finish) {
48- try {
49- finish ();
50- }
51- catch (std::exception const &e) {
52- std::cerr << " Exception " << e.what () << " occured during TraceContainerWriter's auto-finish" << std::endl;
53- }
45+ TraceContainerWriter::TraceContainerWriter (const std::string& filename,
46+ frame_architecture arch,
47+ uint64_t machine,
48+ uint64_t frames_per_toc_entry_in)
49+ throw (TraceException)
50+ : num_frames (0 )
51+ , frames_per_toc_entry (frames_per_toc_entry_in)
52+ , ofs(open_trace(filename,arch,machine,1LL )) {}
53+
54+ TraceContainerWriter::TraceContainerWriter (const std::string& filename,
55+ const meta_frame& meta,
56+ frame_architecture arch,
57+ uint64_t machine,
58+ uint64_t frames_per_toc_entry_in)
59+ throw (TraceException)
60+ : num_frames (0 )
61+ , frames_per_toc_entry (frames_per_toc_entry_in)
62+ , ofs(open_trace(filename,arch,machine,2LL )) {
63+ std::string meta_data;
64+ if (!(meta.SerializeToString (&meta_data))) {
65+ throw TraceException (" Unable to serialize meta frame to ostream" );
66+ }
67+
68+ uint64_t meta_size = meta_data.length ();
69+ WRITE (meta_size);
70+ if (fwrite (meta_data.c_str (), 1 , meta_size, ofs) != meta_size) {
71+ throw (TraceException (" Unable to write meta frame to trace file" ));
5472 }
5573 }
5674
57- void TraceContainerWriter::add (frame &f) throw (TraceException) {
58- /* Is is time for a toc entry? */
75+ void TraceContainerWriter::add (const frame &f) throw (TraceException) {
5976 if (num_frames > 0 && (num_frames % frames_per_toc_entry) == 0 ) {
60- /* Yes. Add the file offset where we will insert this frame to
61- toc. */
6277 toc.push_back (TELL (ofs));
6378 }
64-
6579 num_frames++;
6680
67- /* Serialize to string so we can get the length. */
6881 std::string s;
6982 if (!(f.SerializeToString (&s))) {
7083 throw (TraceException (" Unable to serialize frame to ostream" ));
7184 }
72-
73- /* Write the length before the frame. */
7485 uint64_t len = s.length ();
75- if (len == 0 ) {
76- throw (TraceException (" Attempt to add zero-length frame to trace" ));
77- }
7886 WRITE (len);
79-
80- /* Write the frame. */
81- traceoff_t old_offset = TELL (ofs);
82- if (old_offset == -1 ) {
83- throw (TraceException (" Unable to determine the current offset in the trace" ));
84- }
85-
8687 if (fwrite (s.c_str (), 1 , len, ofs) != len) {
8788 throw (TraceException (" Unable to write frame to trace file" ));
8889 }
89-
90- /* Double-check our size. */
91- assert ((uint64_t )old_offset + len == (uint64_t )TELL (ofs));
9290 }
9391
94- void TraceContainerWriter::finish (void ) throw (TraceException) {
95- if (is_finished) {
96- throw (TraceException (" finish called twice" ));
97- }
98-
99- /* Save the offset where we will write the toc. */
92+ void TraceContainerWriter::finish () {
10093 uint64_t toc_offset = TELL (ofs);
101- if (toc_offset == -1 ) {
102- throw (TraceException (" Unable to determine the current offset in the trace" ));
103- }
104-
105- /* Make sure the toc is the right size. */
106- assert ((num_frames == 0 ) || ((num_frames - 1 ) / frames_per_toc_entry) == toc.size ());
107-
108- /* Write frames per toc entry. */
109- WRITE (frames_per_toc_entry);
110-
111- /* Write each offset to the file. */
112- for (std::vector<uint64_t >::size_type i = 0 ; i < toc.size (); i++) {
113- WRITE (toc[i]);
94+ // if we have a positive offset, then the device is seekable, so
95+ // we will write the TOC, otherwise we will skip it.
96+ if (toc_offset > 0 ) {
97+ assert ((num_frames - 1 ) / frames_per_toc_entry == toc.size ());
98+ WRITE (frames_per_toc_entry);
99+ for (std::vector<uint64_t >::size_type i = 0 ; i < toc.size (); i++) {
100+ WRITE (toc[i]);
101+ }
102+ SEEK (ofs, num_trace_frames_offset);
103+ WRITE (num_frames);
104+ SEEK (ofs, toc_offset_offset);
105+ WRITE (toc_offset);
114106 }
115107
116- /* Now we need to write the magic number, number of trace frames
117- and the offset of field m at the start of the trace. */
118-
119- /* Magic number. */
120- SEEK (ofs, magic_number_offset);
121- WRITE (magic_number);
122-
123- /* Trace version. */
124- SEEK (ofs, trace_version_offset);
125- WRITE (out_trace_version);
126-
127- /* CPU architecture. */
128- SEEK (ofs, frame_arch_offset);
129- uint64_t archt = (uint64_t ) arch;
130- WRITE (archt);
131-
132- /* Machine type. */
133- SEEK (ofs, frame_machine_offset);
134- WRITE (mach);
135-
136- /* Numer of trace frames */
137- SEEK (ofs, num_trace_frames_offset);
138- WRITE (num_frames);
139-
140- /* Offset of toc. */
141- SEEK (ofs, toc_offset_offset);
142- WRITE (toc_offset);
143-
144- /* Finally, close the file and mark us as finished. */
145- if (fclose (ofs)) {
146- throw (TraceException (" Unable to close trace file" ));
108+ if (fclose (ofs) != 0 ) {
109+ throw TraceException (" Error while closing the trace" );
147110 }
148- is_finished = true ;
149- }
150-
151- bool TraceContainerWriter::has_finished (void ) throw () {
152- return is_finished;
111+ ofs = NULL ;
153112 }
154113
155114 TraceContainerReader::TraceContainerReader (std::string filename) throw (TraceException)
0 commit comments