@@ -23,133 +23,92 @@ typedef off_t traceoff_t;
23
23
24
24
namespace SerializedTrace {
25
25
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;
41
42
}
42
43
43
- TraceContainerWriter::~TraceContainerWriter (void ) throw () {
44
44
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" ));
54
72
}
55
73
}
56
74
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) {
59
76
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. */
62
77
toc.push_back (TELL (ofs));
63
78
}
64
-
65
79
num_frames++;
66
80
67
- /* Serialize to string so we can get the length. */
68
81
std::string s;
69
82
if (!(f.SerializeToString (&s))) {
70
83
throw (TraceException (" Unable to serialize frame to ostream" ));
71
84
}
72
-
73
- /* Write the length before the frame. */
74
85
uint64_t len = s.length ();
75
- if (len == 0 ) {
76
- throw (TraceException (" Attempt to add zero-length frame to trace" ));
77
- }
78
86
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
-
86
87
if (fwrite (s.c_str (), 1 , len, ofs) != len) {
87
88
throw (TraceException (" Unable to write frame to trace file" ));
88
89
}
89
-
90
- /* Double-check our size. */
91
- assert ((uint64_t )old_offset + len == (uint64_t )TELL (ofs));
92
90
}
93
91
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 () {
100
93
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);
114
106
}
115
107
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" );
147
110
}
148
- is_finished = true ;
149
- }
150
-
151
- bool TraceContainerWriter::has_finished (void ) throw () {
152
- return is_finished;
111
+ ofs = NULL ;
153
112
}
154
113
155
114
TraceContainerReader::TraceContainerReader (std::string filename) throw (TraceException)
0 commit comments