1 | /* |
---|
2 | * $Header$ |
---|
3 | * $Locker$ |
---|
4 | |
---|
5 | Copyright (c) 2010-2012, Rogue Wave Software, Inc. |
---|
6 | |
---|
7 | Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
8 | of the tv_data_display.h and tv_data_display.c files (the "Software"), to deal |
---|
9 | in the Software without restriction, including without limitation the rights |
---|
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
---|
11 | of the Software, and to permit persons to whom the Software is furnished to do |
---|
12 | so, subject to the following conditions: |
---|
13 | |
---|
14 | The above copyright notice and this permission notice shall be included in all |
---|
15 | copies or substantial portions of the Software. |
---|
16 | |
---|
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
---|
18 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
---|
19 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
---|
20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
---|
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
---|
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
---|
23 | |
---|
24 | * Update log |
---|
25 | * |
---|
26 | * Feb 1 2012 NYP: Updated Copyright |
---|
27 | * Apr 18 2011 SJT: TVT-13122, comment cleanup. |
---|
28 | * Sep 27 2010 ANB: lots of changes as part of totalview/12314. |
---|
29 | * Reworked to reduce the dependencies on outside |
---|
30 | * entities, both at compile and also at runtime. |
---|
31 | * Adjusted the naming scheme. |
---|
32 | * Jan 28 2010 SJT: Bug 12100, bump base size to 16K and recognize if it is |
---|
33 | * resized further. |
---|
34 | * Sep 24 2009 SJT: Remove pre/post callback to reduce function call overhead. |
---|
35 | * Jul 1 2009 SJT: Created. |
---|
36 | * |
---|
37 | */ |
---|
38 | |
---|
39 | #ifdef __cplusplus |
---|
40 | extern "C" { |
---|
41 | #endif |
---|
42 | |
---|
43 | #include "tv_data_display.h" |
---|
44 | |
---|
45 | #include <stdio.h> |
---|
46 | #include <stddef.h> /* for size_t */ |
---|
47 | |
---|
48 | #define DATA_FORMAT_BUFFER_SIZE 16384 |
---|
49 | #define TV_FORMAT_INACTIVE 0 |
---|
50 | #define TV_FORMAT_FIRST_CALL 1 |
---|
51 | #define TV_FORMAT_APPEND_CALL 2 |
---|
52 | |
---|
53 | volatile int TV_ttf_data_format_control = TV_FORMAT_INACTIVE; |
---|
54 | int TV_ttf_data_display_api_version = TV_TTF_DATA_DISPLAY_API_VERSION; |
---|
55 | |
---|
56 | /* TV_ttf_data_format_buffer should not be static for icc 11, and others */ |
---|
57 | char TV_ttf_data_format_buffer[DATA_FORMAT_BUFFER_SIZE]; |
---|
58 | static char *TV_ttf_data_buffer_ptr = TV_ttf_data_format_buffer; |
---|
59 | |
---|
60 | static const char digits [] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
---|
61 | static const size_t base_bound = sizeof ( digits ); |
---|
62 | |
---|
63 | /* ************************************************************************ */ |
---|
64 | |
---|
65 | int |
---|
66 | TV_ttf_is_format_result_ok ( TV_ttf_format_result fr ) |
---|
67 | { |
---|
68 | int ret_val; |
---|
69 | |
---|
70 | switch ( fr ) |
---|
71 | { |
---|
72 | case TV_ttf_format_ok: |
---|
73 | case TV_ttf_format_ok_elide: |
---|
74 | ret_val = 1; |
---|
75 | break; |
---|
76 | default: |
---|
77 | ret_val = 0; |
---|
78 | break; |
---|
79 | } |
---|
80 | return ret_val; |
---|
81 | } /* TV_ttf_is_format_result_ok */ |
---|
82 | |
---|
83 | /* ************************************************************************ */ |
---|
84 | |
---|
85 | static |
---|
86 | void * |
---|
87 | my_zeroit ( void *s, size_t n ) |
---|
88 | { |
---|
89 | char *cp = (char *) s; |
---|
90 | |
---|
91 | /* not the most efficient of solutions. What we should do is */ |
---|
92 | /* do the assugnments in units of int or long. The problem */ |
---|
93 | /* with that is ensuring that the alignments of the assignments */ |
---|
94 | /* are correct. The difficulty with that is doing arithmetic */ |
---|
95 | /* on pointers in a portable manner. */ |
---|
96 | while ( n > 0 ) |
---|
97 | { |
---|
98 | *cp++ = 0; |
---|
99 | n--; |
---|
100 | } |
---|
101 | |
---|
102 | return s; |
---|
103 | } /* my_zeroit */ |
---|
104 | |
---|
105 | static |
---|
106 | char * |
---|
107 | my_strpbrk ( const char *str, const char *accept ) |
---|
108 | { |
---|
109 | char *ret_val = NULL; |
---|
110 | char *s, *t; |
---|
111 | |
---|
112 | for ( s = (char *) str; (*s) && (! ret_val); s++ ) |
---|
113 | { |
---|
114 | for ( t = (char *) accept; (*t) && (! ret_val); t++ ) |
---|
115 | { |
---|
116 | if ( *s == *t ) |
---|
117 | ret_val = s; |
---|
118 | } |
---|
119 | } |
---|
120 | |
---|
121 | return ret_val; |
---|
122 | } /* my_strpbrk */ |
---|
123 | |
---|
124 | static |
---|
125 | int |
---|
126 | marshal_string ( char *buffer, size_t len, const char *s, |
---|
127 | char **nbuffer, size_t *nlen ) |
---|
128 | { |
---|
129 | int ret_val = 0; |
---|
130 | char *cursor = buffer; |
---|
131 | |
---|
132 | while ( *s ) |
---|
133 | { |
---|
134 | ret_val++; |
---|
135 | if ( len > 1 ) |
---|
136 | { |
---|
137 | *cursor++ = *s++; |
---|
138 | len--; |
---|
139 | } |
---|
140 | } |
---|
141 | if ( len > 0 ) |
---|
142 | *cursor = '\0'; |
---|
143 | |
---|
144 | if ( nbuffer ) |
---|
145 | *nbuffer = cursor; |
---|
146 | if ( nlen ) |
---|
147 | *nlen = len; |
---|
148 | |
---|
149 | return ret_val; |
---|
150 | } /* marshal_string */ |
---|
151 | |
---|
152 | static |
---|
153 | int |
---|
154 | marshal_unsigned_body ( char *buffer, size_t len, size_t val, int base, |
---|
155 | char **nbuffer, size_t *nlen ) |
---|
156 | { |
---|
157 | |
---|
158 | int ret_val = 0; |
---|
159 | size_t q, r; |
---|
160 | char digit [ 2 ]; |
---|
161 | char *my_buffer = buffer; |
---|
162 | size_t my_len = len; |
---|
163 | |
---|
164 | if ( val < base ) |
---|
165 | { |
---|
166 | r = val; |
---|
167 | } |
---|
168 | else |
---|
169 | { |
---|
170 | q = val / base; |
---|
171 | r = val - (q * base); |
---|
172 | ret_val += marshal_unsigned_body ( buffer, len, q, base, |
---|
173 | &my_buffer, &my_len ); |
---|
174 | } |
---|
175 | digit [ 0 ] = digits [ r ]; |
---|
176 | digit [ 1 ] = '\0'; |
---|
177 | ret_val += marshal_string ( my_buffer, my_len, digit, nbuffer, nlen ); |
---|
178 | |
---|
179 | return ret_val; |
---|
180 | } /* marshal_unsigned_body */ |
---|
181 | |
---|
182 | static |
---|
183 | int |
---|
184 | marshal_unsigned ( char *buffer, size_t len, size_t val, int base, |
---|
185 | char **nbuffer, size_t *nlen ) |
---|
186 | { |
---|
187 | int ret_val = 0; |
---|
188 | |
---|
189 | if ( 0 == base ) |
---|
190 | base = 10; |
---|
191 | if ( base < base_bound ) |
---|
192 | ret_val = marshal_unsigned_body ( buffer, len, val, base, nbuffer, nlen ); |
---|
193 | else |
---|
194 | ret_val = -1; |
---|
195 | |
---|
196 | return ret_val; |
---|
197 | } /* marshal_unsigned */ |
---|
198 | |
---|
199 | static |
---|
200 | int |
---|
201 | marshal_hex ( char *buffer, size_t len, size_t hex_val, |
---|
202 | char **nbuffer, size_t *nlen ) |
---|
203 | { |
---|
204 | int ret_val = 0; |
---|
205 | char *my_buffer; |
---|
206 | size_t my_len; |
---|
207 | |
---|
208 | ret_val += marshal_string ( buffer, len, "0x", &my_buffer, &my_len ); |
---|
209 | ret_val += marshal_unsigned ( my_buffer, my_len, hex_val, 16, nbuffer, nlen ); |
---|
210 | |
---|
211 | return ret_val; |
---|
212 | } /* marshal_hex */ |
---|
213 | |
---|
214 | static |
---|
215 | int |
---|
216 | marshal_row ( char *buffer, size_t len, const char *field_name, |
---|
217 | const char *type_name, |
---|
218 | const void *value, |
---|
219 | char **nbuffer, |
---|
220 | size_t *nlen ) |
---|
221 | { |
---|
222 | int ret_val = 0; |
---|
223 | char *my_buffer; |
---|
224 | size_t my_len; |
---|
225 | |
---|
226 | ret_val += marshal_string ( buffer, len, field_name, &my_buffer, &my_len ); |
---|
227 | ret_val += marshal_string ( my_buffer, my_len, "\t", &my_buffer, &my_len ); |
---|
228 | ret_val += marshal_string ( my_buffer, my_len, type_name, &my_buffer, &my_len ); |
---|
229 | ret_val += marshal_string ( my_buffer, my_len, "\t", &my_buffer, &my_len ); |
---|
230 | ret_val += marshal_hex ( my_buffer, my_len, (size_t) value, &my_buffer, &my_len ); |
---|
231 | ret_val += marshal_string ( my_buffer, my_len, "\n", nbuffer, nlen ); |
---|
232 | |
---|
233 | return ret_val; |
---|
234 | } /* marshal_row */ |
---|
235 | |
---|
236 | int TV_ttf_add_row(const char *field_name, |
---|
237 | const char *type_name, |
---|
238 | const void *value) |
---|
239 | { |
---|
240 | size_t remaining; |
---|
241 | int out; |
---|
242 | |
---|
243 | /* |
---|
244 | printf ( "TV_ttf_add_row: on entry TV_ttf_data_format_control == %d\n", TV_ttf_data_format_control ); |
---|
245 | */ |
---|
246 | |
---|
247 | /* Called at the wrong time */ |
---|
248 | if (TV_ttf_data_format_control == TV_FORMAT_INACTIVE) |
---|
249 | return TV_ttf_ec_not_active; |
---|
250 | |
---|
251 | if (my_strpbrk(field_name, "\n\t") != NULL) |
---|
252 | return TV_ttf_ec_invalid_characters; |
---|
253 | |
---|
254 | if (my_strpbrk(type_name, "\n\t") != NULL) |
---|
255 | return TV_ttf_ec_invalid_characters; |
---|
256 | |
---|
257 | if (TV_ttf_data_format_control == TV_FORMAT_FIRST_CALL) |
---|
258 | { |
---|
259 | /* Zero out the buffer to avoid confusion, and set the write point |
---|
260 | to the top of the buffer. */ |
---|
261 | |
---|
262 | my_zeroit(TV_ttf_data_format_buffer, sizeof (TV_ttf_data_format_buffer)); |
---|
263 | TV_ttf_data_buffer_ptr = TV_ttf_data_format_buffer; |
---|
264 | TV_ttf_data_format_control = TV_FORMAT_APPEND_CALL; |
---|
265 | } |
---|
266 | |
---|
267 | remaining = TV_ttf_data_buffer_ptr + |
---|
268 | DATA_FORMAT_BUFFER_SIZE - TV_ttf_data_format_buffer; |
---|
269 | |
---|
270 | /* |
---|
271 | out = snprintf(TV_ttf_data_buffer_ptr, |
---|
272 | remaining, "%s\t%s\t%p\n", |
---|
273 | field_name, type_name, value); |
---|
274 | */ |
---|
275 | out = marshal_row ( TV_ttf_data_buffer_ptr, remaining, |
---|
276 | field_name, type_name, value, 0, 0 ); |
---|
277 | |
---|
278 | if (out < 1) |
---|
279 | return TV_ttf_ec_buffer_exhausted; |
---|
280 | |
---|
281 | TV_ttf_data_buffer_ptr += out; |
---|
282 | |
---|
283 | return 0; |
---|
284 | } /* TV_ttf_add_row */ |
---|
285 | |
---|
286 | void TV_ttf_pre_display_callback(void) |
---|
287 | { |
---|
288 | TV_ttf_data_format_control = TV_FORMAT_FIRST_CALL; |
---|
289 | } |
---|
290 | |
---|
291 | void TV_ttf_post_display_callback(void) |
---|
292 | { |
---|
293 | TV_ttf_data_format_control = TV_FORMAT_INACTIVE; |
---|
294 | } |
---|
295 | |
---|
296 | #ifdef __cplusplus |
---|
297 | } |
---|
298 | #endif |
---|