/src/wrappers/common/library/obsolete/const_string.e
Specman e | 535 lines | 384 code | 79 blank | 72 comment | 50 complexity | 0a7cd15eab14ea81e50469d1e7f1ded4 MD5 | raw file
1indexing 2 description: "A string made from a `C' const char pointer." 3 copyright: "[ 4 Copyright (C) 2006 Paolo Redaelli 5 6 This class is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public License 8 as published by the Free Software Foundation; either version 2.1 of 9 the License, or (at your option) any later version. 10 11 This library is distributed in the hopeOA that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA 20 ]" 21 22class CONST_STRING 23obsolete "Shall be adapted for Liberty Eiffel" 24 25 -- An efficient wrapper for const pointer to strings returned by 26 -- many C functions. No further memory is allocated when a CONST_STRING is created: the buffer of the C library is used directly. 27 28 -- For example, GTK+ has many calls like this (taken from its 29 -- documentation): 30 31 -- const gchar* gtk_entry_get_text (GtkEntry *entry); 32 33 -- Memory efficiency is gained with slower changing features. If you need 34 -- to change its content consider using feature string to get a new 35 -- (non-const) STRING with the same content. 36 37inherit 38 ABSTRACT_STRING 39 redefine 40 resize, clear_count, wipe_out, 41 clear_count_and_capacity, 42 fill_with, replace_all, 43 append, append_string, 44 append_substring, 45 infix "+", 46 infix "<", 47 infix ">", 48 infix "<=", 49 infix ">=", 50 compare, three_way_comparison, 51 as_upper, as_lower, 52 --is_equal, 53 prepend, 54 insert_string, replace_substring, 55 put, swap, insert_character, shrink, 56 remove, 57 add_first, precede, 58 add_last, append_character, 59 extend, 60 to_lower, to_upper, 61 -- remove_first, remove_head, 62 -- remove_last, remove_tail, 63 remove_substring, remove_between, 64 remove_suffix, remove_prefix, 65 left_adjust, right_adjust, 66 do_all, 67 extend_multiple, precede_multiple, 68 extend_to_count, precede_to_count, 69 reverse, 70 remove_all_occurrences, 71 extend_unless, 72 from_external 73 end 74 75 -- DISPOSABLE 76 -- rename is_equal as disposable_is_equal 77 -- export {} disposable_is_equal 78 -- undefine fill_tagged_out_memory, copy, out_in_tagged_out_memory 79 -- end 80 81 -- insert WRAPPER_HANDLER undefine --- is_equal, 82 -- copy,fill_tagged_out_memory, out_in_tagged_out_memory end 83 84creation from_external 85 86feature 87 from_external (a_c_string: POINTER) is 88 do 89 is_unchanged := True 90 -- Allocating a small area of memory that will be freed in 91 -- place of the "const char *" when Eiffel Garbage Collector 92 -- disposes an unmodified CONST_STING. 93 94 sacrificial_lamb:= calloc(1,1) 95 original_c_string := a_c_string 96 Precursor (a_c_string) 97 -- from_external_copy (a_c_string) 98 -- XXX: Not optimal, but otherwise will try to free `a_c_string' 99 end 100 101 is_changed: BOOLEAN is 102 -- Has the Current constant string been changed? 103 do 104 Result := not is_unchanged 105 end 106 107 is_unchanged: BOOLEAN 108 -- Has Current CONST_STRING not been changed? 109 110 modify is 111 -- Make Current changeable. The underlying "const char*" 112 -- string is copyied into a new changeable buffer. The 113 -- original C string pointer will be available at `original_c_string' 114 local previous: like storage; i: INTEGER 115 do 116 original_c_string := to_external 117 from 118 previous := storage 119 storage := storage.calloc(capacity+1) 120 i:=count-1 121 until i < 0 122 loop 123 storage.put(previous.item(i),i) 124 i := i - 1 125 end 126 is_unchanged := False 127 ensure 128 changeable: is_changed 129 end 130 131feature 132 resize (new_count: INTEGER_32) is 133 do 134 if is_unchanged then modify end 135 Precursor (new_count) 136 end 137 138 clear_count is 139 do 140 if is_unchanged then modify end 141 Precursor 142 end 143 144 wipe_out is 145 do 146 if is_unchanged then modify end 147 Precursor 148 end 149 150 clear_count_and_capacity is 151 do 152 if is_unchanged then modify end 153 Precursor 154 end 155 156 copy (other: like Current) is 157 do 158 if is_unchanged then modify end 159 Precursor (other) 160 end 161 162 fill_with (c: CHARACTER) is 163 do 164 if is_unchanged then modify end 165 Precursor (c) 166 end 167 168 replace_all (old_character, new_character: CHARACTER) is 169 do 170 if is_unchanged then modify end 171 Precursor (old_character, new_character) 172 end 173 174 append (s: STRING) is 175 do 176 if is_unchanged then modify end 177 Precursor (s) 178 end 179 180 append_string (s: STRING) is 181 do 182 if is_unchanged then modify end 183 Precursor (s) 184 end 185 186 append_substring (s: STRING; start_index, end_index: INTEGER_32) is 187 do 188 if is_unchanged then modify end 189 Precursor (s, start_index, end_index) 190 end 191 192 prepend (other: STRING) is 193 do 194 if is_unchanged then modify end 195 Precursor (other) 196 end 197 198 insert_string (s: STRING; i: INTEGER_32) is 199 do 200 if is_unchanged then modify end 201 Precursor (s,i) 202 end 203 204 replace_substring (s: STRING; start_index, end_index: INTEGER_32) is 205 do 206 if is_unchanged then modify end 207 Precursor (s, start_index, end_index) 208 end 209 210 put (c: CHARACTER; i: INTEGER_32) is 211 do 212 if is_unchanged then modify end 213 Precursor (c,i) 214 end 215 216 infix "+" (other: STRING): STRING is 217 -- Create a new STRING which is the concatenation of 218 -- `Current' and `other'. 219 -- 220 -- See also `append'. 221 do 222 create Result.make(count + other.count) 223 Result.append(Current) 224 Result.append(other) 225 end 226 227 infix ">" (other: STRING): BOOLEAN is 228 do 229 Result := other < Current 230 end 231 232 infix ">=" (other: STRING): BOOLEAN is 233 do 234 Result := not (Current < other) 235 end 236 237 infix "<=" (other: STRING): BOOLEAN is 238 do 239 Result := not (other < Current) 240 end 241 242 infix "<" (other: STRING): BOOLEAN is 243 local 244 i: INTEGER; maxi: INTEGER 245 do 246 from 247 i := 1 248 maxi := count.min(other.count) 249 until 250 i > maxi or else item(i) /= other.item(i) 251 loop 252 i := i + 1 253 end 254 if i <= maxi then 255 Result := item(i) < other.item(i) 256 else 257 Result := i <= other.count 258 end 259 end 260 261 compare, three_way_comparison (other: STRING): INTEGER is 262 do 263 if Current < other then 264 Result := -1 265 elseif other < Current then 266 Result := 1 267 end 268 end 269 270 as_upper: STRING is 271 do 272 create Result.copy(Current) 273 Result.to_upper 274 end 275 276 as_lower: STRING is 277 do 278 create Result.copy(Current) 279 Result.to_lower 280 end 281 282 substring (start_index, end_index: INTEGER): STRING is 283 -- New string consisting of items [`start_index'.. `end_index']. 284 -- 285 -- See also `substring_index'. 286 local 287 c: INTEGER 288 do 289 c := end_index - start_index + 1 290 create Result.make(c) 291 if c > 0 then 292 Result.set_count(c) 293 Result.storage.slice_copy(0, storage, start_index - 1, end_index - 1) 294 end 295 end 296 297 swap (i1, i2: INTEGER_32) is 298 do 299 if is_unchanged then modify end 300 Precursor (i1, i2) 301 end 302 303 insert_character (c: CHARACTER; i: INTEGER_32) is 304 do 305 if is_unchanged then modify end 306 Precursor (c,i) 307 end 308 309 shrink (min_index, max_index: INTEGER_32) is 310 do 311 if is_unchanged then modify end 312 Precursor (min_index,max_index) 313 end 314 315 remove (i: INTEGER_32) is 316 do 317 if is_unchanged then modify end 318 Precursor (i) 319 end 320 321 add_first (c: CHARACTER) is 322 do 323 if is_unchanged then modify end 324 Precursor (c) 325 end 326 327 precede (c: CHARACTER) is 328 do 329 if is_unchanged then modify end 330 Precursor (c) 331 end 332 333 add_last (c: CHARACTER) is 334 do 335 if is_unchanged then modify end 336 Precursor (c) 337 end 338 339 append_character (c: CHARACTER) is 340 do 341 if is_unchanged then modify end 342 Precursor (c) 343 end 344 345 extend (c: CHARACTER) is 346 do 347 if is_unchanged then modify end 348 Precursor (c) 349 end 350 351 to_lower is 352 do 353 if is_unchanged then modify end 354 Precursor 355 end 356 357 to_upper is 358 do 359 if is_unchanged then modify end 360 Precursor 361 end 362 363 keep_head (n: INTEGER_32) is 364 do 365 if is_unchanged then modify end 366 not_yet_implemented 367 end 368 369 keep_tail (n: INTEGER_32) is 370 do 371 if is_unchanged then modify end 372 not_yet_implemented 373 end 374 375feature -- commented out to achieve compatibility with both SE 2.2 and 2.3 376 -- remove_head (n: INTEGER_32) is 377 -- do 378 -- if is_unchanged then modify end 379 -- Precursor (n) 380 -- end 381 382 -- remove_tail (n: INTEGER_32) is 383 -- do 384 -- if is_unchanged then modify end 385 -- Precursor (n) 386 -- end 387 388feature 389 remove_substring (start_index, end_index: INTEGER_32) is 390 do 391 if is_unchanged then modify end 392 Precursor (start_index, end_index) 393 end 394 395 remove_between (start_index, end_index: INTEGER_32) is 396 do 397 if is_unchanged then modify end 398 Precursor (start_index, end_index) 399 end 400 401 remove_suffix (s: STRING) is 402 do 403 if is_unchanged then modify end 404 Precursor (s) 405 end 406 407 remove_prefix (s: STRING) is 408 do 409 if is_unchanged then modify end 410 Precursor (s) 411 end 412 413 left_adjust is 414 do 415 if is_unchanged then modify end 416 Precursor 417 end 418 419 right_adjust is 420 do 421 if is_unchanged then modify end 422 Precursor 423 end 424 425feature {} -- functions from STRING that change signature in 2.3. Note: commented out to achieve compatibility with both SE 2.2 and 2.3 426 427 -- remove_first (n: INTEGER_32) is 428 -- do 429 -- if is_unchanged then modify end 430 -- Precursor (n) 431 -- end 432 433 -- remove_last (n: INTEGER_32) is 434 -- do 435 -- if is_unchanged then modify end 436 -- Precursor (n) 437 -- end 438 439feature {ANY} -- from STRING 440 do_all (action: ROUTINE[TUPLE[CHARACTER]]) is 441 do 442 if is_unchanged then modify end 443 Precursor (action) 444 end 445 446 extend_multiple (c: CHARACTER; n: INTEGER_32) is 447 do 448 if is_unchanged then modify end 449 Precursor (c,n) 450 end 451 452 precede_multiple (c: CHARACTER; n: INTEGER_32) is 453 do 454 if is_unchanged then modify end 455 Precursor (c, n) 456 end 457 458 extend_to_count (c: CHARACTER; needed_count: INTEGER_32) is 459 do 460 if is_unchanged then modify end 461 Precursor (c,needed_count) 462 end 463 464 precede_to_count (c: CHARACTER; needed_count: INTEGER_32) is 465 do 466 if is_unchanged then modify end 467 Precursor (c,needed_count) 468 end 469 470 reverse is 471 do 472 if is_unchanged then modify end 473 Precursor 474 end 475 476 remove_all_occurrences (ch: CHARACTER) is 477 do 478 if is_unchanged then modify end 479 Precursor (ch) 480 end 481 482 extend_unless (ch: CHARACTER) is 483 do 484 if is_unchanged then modify end 485 Precursor (ch) 486 end 487 488 is_equal (other: STRING ): BOOLEAN is -- like Current 489 do 490 if count = other.count 491 then Result := storage.fast_memcmp(other.storage,count) 492 end 493 end 494 495feature {} -- Implementation 496 original_c_string: POINTER 497 -- The address that contains the original C string 498 499 sacrificial_lamb: POINTER 500 -- Temporary keeping it NULL 501 -- A address of a small area of memory allocated at creation 502 -- time that will take the place of the "const char *" when 503 -- Eiffel Garbage Collector disposes an unmodified 504 -- CONST_STING. 505 -- Note: the symbolical name is intentional.... Think about 506 -- it as a small Eiffellish Easter Egg.... 8) 507 508 dispose is 509 do 510 original_c_string := to_external 511 if is_unchanged then 512 -- an hack to force the Garbage Collector to leave the 513 -- storage as it is and not free it, since it hasn't been 514 -- allocated by Eiffel and must NOT be freed. 515 -- change it to a dummy array 516 print(dispose_notice) 517 storage := storage.from_pointer(sacrificial_lamb) 518 end 519 end 520 521 dispose_notice: STRING is 522 "CONST_STRING.dispose: the string is unchanged; using a tentative hack to avoid crash during quitting or disposing; a pre-allocated 1-char-long memory area will be set as storage.%N" 523 524 calloc (a_number, a_size: INTEGER): POINTER is 525 -- void *calloc(size_t nmemb, size_t size); 526 -- 527 -- calloc() allocates memory for an array of nmemb elements 528 -- of size bytes each and returns a pointer to the allocated 529 -- memory. The memory is set to zero. 530 external "C use <stdlib.h>" 531 alias "se_calloc" 532 ensure Result.is_not_null 533 end 534 535end -- class CONST_STRING