Branch data Line data Source code
1 : : // $Id: Desc.cc 6245 2008-10-07 00:56:59Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include <stdlib.h>
8 : : #include <errno.h>
9 : :
10 : : #include "Desc.h"
11 : : #include "File.h"
12 : :
13 : : #define DEFAULT_SIZE 128
14 : : #define SLOP 10
15 : :
16 : 184784 : ODesc::ODesc(desc_type t, BroFile* arg_f)
17 : : {
18 : 184784 : type = t;
19 : 184784 : style = STANDARD_STYLE;
20 : 184784 : f = arg_f;
21 : :
22 [ + + ][ # # ]: 184784 : if ( f == 0 )
23 : : {
24 : 179819 : size = DEFAULT_SIZE;
25 : 179819 : base = safe_malloc(size);
26 : 179819 : ((char*) base)[0] = '\0';
27 : :
28 : 179819 : offset = 0;
29 : :
30 [ - + # # ]: 179819 : if ( ! base )
31 : 179819 : OutOfMemory();
32 : : }
33 : : else
34 : : {
35 : 4965 : offset = size = 0;
36 : 4965 : base = 0;
37 : : }
38 : :
39 : 184784 : indent_level = 0;
40 : 184784 : is_short = 0;
41 : 184784 : want_quotes = 0;
42 : 184784 : do_flush = 1;
43 : 184784 : include_stats = 0;
44 : 184784 : }
45 : :
46 : 184784 : ODesc::~ODesc()
47 : : {
48 [ + + ][ # # ]: 184784 : if ( f )
49 : : {
50 [ - + ][ # # ]: 4965 : if ( do_flush )
51 : 4965 : f->Flush();
52 : : }
53 [ + + ][ # # ]: 179819 : else if ( base )
54 : 108593 : free(base);
55 : 184784 : }
56 : :
57 : 16 : void ODesc::PushIndent()
58 : : {
59 : 16 : ++indent_level;
60 : 16 : NL();
61 : 16 : }
62 : :
63 : 16 : void ODesc::PopIndent()
64 : : {
65 [ - + ]: 16 : if ( --indent_level < 0 )
66 : 0 : internal_error("ODesc::PopIndent underflow");
67 : 16 : NL();
68 : 16 : }
69 : :
70 : 266517 : void ODesc::Add(const char* s, int do_indent)
71 : : {
72 : 266517 : unsigned int n = strlen(s);
73 : :
74 [ + + + - ]: 266517 : if ( do_indent && IsReadable() && offset > 0 &&
[ + + ][ - + ]
[ - + ]
75 : : ((const char*) base)[offset - 1] == '\n' )
76 : 0 : Indent();
77 : :
78 [ - + ]: 266517 : if ( IsBinary() )
79 : 0 : AddBytes(s, n+1);
80 : : else
81 : 266517 : AddBytes(s, n);
82 : 266517 : }
83 : :
84 : 0 : void ODesc::Add(int i)
85 : : {
86 [ # # ]: 0 : if ( IsBinary() )
87 : 0 : AddBytes(&i, sizeof(i));
88 : : else
89 : : {
90 : : char tmp[256];
91 : 0 : sprintf(tmp, "%d", i);
92 : 0 : Add(tmp);
93 : : }
94 : 0 : }
95 : :
96 : 1262 : void ODesc::Add(uint32 u)
97 : : {
98 [ - + ]: 1262 : if ( IsBinary() )
99 : 0 : AddBytes(&u, sizeof(u));
100 : : else
101 : : {
102 : : char tmp[256];
103 : 1262 : sprintf(tmp, "%u", u);
104 : 1262 : Add(tmp);
105 : : }
106 : 1262 : }
107 : :
108 : 0 : void ODesc::Add(int64 i)
109 : : {
110 [ # # ]: 0 : if ( IsBinary() )
111 : 0 : AddBytes(&i, sizeof(i));
112 : : else
113 : : {
114 : : char tmp[256];
115 : 0 : sprintf(tmp, "%lld", i);
116 : 0 : Add(tmp);
117 : : }
118 : 0 : }
119 : :
120 : 356 : void ODesc::Add(uint64 u)
121 : : {
122 [ - + ]: 356 : if ( IsBinary() )
123 : 0 : AddBytes(&u, sizeof(u));
124 : : else
125 : : {
126 : : char tmp[256];
127 : 356 : sprintf(tmp, "%llu", u);
128 : 356 : Add(tmp);
129 : : }
130 : 356 : }
131 : :
132 : 0 : void ODesc::Add(double d)
133 : : {
134 [ # # ]: 0 : if ( IsBinary() )
135 : 0 : AddBytes(&d, sizeof(d));
136 : : else
137 : : {
138 : : char tmp[256];
139 [ # # ]: 0 : sprintf(tmp, IsReadable() ? "%.15g" : "%.17g", d);
140 : 0 : Add(tmp);
141 : :
142 [ # # ]: 0 : if ( d == double(int(d)) )
143 : : // disambiguate from integer
144 : 0 : Add(".0");
145 : : }
146 : 0 : }
147 : :
148 : 0 : void ODesc::AddCS(const char* s)
149 : : {
150 : 0 : int n = strlen(s);
151 : 0 : Add(n);
152 [ # # ]: 0 : if ( ! IsBinary() )
153 : 0 : Add(" ");
154 : 0 : Add(s);
155 : 0 : }
156 : :
157 : 123071 : void ODesc::AddBytes(const BroString* s)
158 : : {
159 [ + - ]: 123071 : if ( IsReadable() )
160 : : {
161 : 123071 : int render_style = BroString::EXPANDED_STRING;
162 [ - + ]: 123071 : if ( Style() == ALTERNATIVE_STYLE )
163 : : // Only change NULs, since we can't in any case
164 : : // cope with them.
165 : 0 : render_style = BroString::ESC_NULL;
166 : :
167 : 123071 : const char* str = s->Render(render_style);
168 : 123071 : Add(str);
169 [ + - ]: 123071 : delete [] str;
170 : : }
171 : : else
172 : : {
173 : 0 : Add(s->Len());
174 [ # # ]: 0 : if ( ! IsBinary() )
175 : 0 : Add(" ");
176 : 0 : AddBytes(s->Bytes(), s->Len());
177 : : }
178 : 123071 : }
179 : :
180 : 0 : void ODesc::Indent()
181 : : {
182 [ # # ]: 0 : for ( int i = 0; i < indent_level; ++i )
183 : 0 : Add("\t", 0);
184 : 0 : }
185 : :
186 : :
187 : 374223 : void ODesc::AddBytes(const void* bytes, unsigned int n)
188 : : {
189 [ + + ]: 374223 : if ( n == 0 )
190 : 82654 : return;
191 : :
192 [ + + ]: 291569 : if ( f )
193 : : {
194 : : static bool write_failed = false;
195 : :
196 [ - + ]: 4965 : if ( ! f->Write((const char*) bytes, n) )
197 : : {
198 [ # # ]: 0 : if ( ! write_failed )
199 : : // Most likely it's a "disk full" so report
200 : : // subsequent failures only once.
201 : 0 : run_time(fmt("error writing to %s: %s", f->Name(), strerror(errno)));
202 : :
203 : 0 : write_failed = true;
204 : 0 : return;
205 : : }
206 : :
207 : 4965 : write_failed = false;
208 : : }
209 : :
210 : : else
211 : : {
212 : 286604 : Grow(n);
213 : :
214 : : // The following casting contortions are necessary because
215 : : // simply using &base[offset] generates complaints about
216 : : // using a void* for pointer arithemtic.
217 : 286604 : memcpy((void*) &((char*) base)[offset], bytes, n);
218 : 286604 : offset += n;
219 : :
220 : 374223 : ((char*) base)[offset] = '\0'; // ensure that always NUL-term.
221 : : }
222 : : }
223 : :
224 : 286604 : void ODesc::Grow(unsigned int n)
225 : : {
226 [ + + ]: 289388 : while ( offset + n + SLOP >= size )
227 : : {
228 : 2784 : size *= 2;
229 : 2784 : base = safe_realloc(base, size);
230 [ - + ]: 2784 : if ( ! base )
231 : 0 : OutOfMemory();
232 : : }
233 : 286604 : }
234 : :
235 : 0 : void ODesc::OutOfMemory()
236 : : {
237 : 0 : internal_error("out of memory");
238 [ + - ][ + - ]: 6 : }
|