PageRenderTime 20ms CodeModel.GetById 2ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

/src/wrappers/common/library/obsolete/const_string.e

http://github.com/tybor/Liberty
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