[1874] | 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 |
---|