PageRenderTime 11ms CodeModel.GetById 1ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/src/wrappers/common/library/string_array.e

http://github.com/tybor/Liberty
Specman e | 405 lines | 254 code | 64 blank | 87 comment | 5 complexity | bf5c10da8e1c4f2709a98fb889a38156 MD5 | raw file
  1indexing
  2	description: "An array of C strings. Wraps 'char **'."
  3	copyright: "[
  4					Copyright (C) 2006 Paolo Redaelli 
  5					
  6					This library 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 STRING_ARRAY 
 23
 24	-- Note: the only implemented features are:
 25
 26	-- Creation: from_external_array
 27
 28	-- Accessing: item, first,last, new_iterator, is_empty
 29
 30	-- Features implementable without making any assumption on memory 
 31	-- handling: reverse, swap,
 32
 33	-- all the remaining features are either not yet implemented or not
 34	-- tested. It is debatable if such a low-level collection shall be
 35	-- passed to the end-user Eiffel developers or if it is better to
 36	-- copy its contents into a more proper Eiffel COLLECTION. The key
 37	-- issue for the choice is memory handling of the array and its
 38	-- contents. Any choice on how to implement features that changes
 39	-- the collection (i.e. `add', `remove_first' and so on) require to
 40	-- make several assumption on how memory of the container and its
 41	-- containee shall be handled. In this case it would be far better
 42	-- to use an eventual anchestor of COLLECTION that does not offer
 43	-- changing features. Paolo 2007-04-28
 44
 45inherit
 46	COLLECTION [STRING]
 47		redefine
 48			swap 
 49		end
 50
 51insert WRAPPER_HANDLER -- only to get null_or_string
 52
 53creation
 54	-- make, with_capacity,	from_collection,
 55	from_external_array,
 56	from_external_null_array
 57
 58feature {STRING_ARRAY, WRAPPER_HANDLER} -- Implementation
 59	-- Note: to correctly handle memory of the string array wrapper and
 60	-- to avoid memory leaks we maintain an updated, paraller and
 61	-- hidden FAST_ARRAY[STRING] that holds a reference to the strings
 62	-- actually retrieved; when a string is retrieved with `item' or
 63	-- added in any way, a reference to that string is put into such an
 64	-- array. So Eiffel STRINGs are created only once and their memory
 65	-- is handled by the garbage collector.
 66
 67	storage: NATIVE_ARRAY[POINTER]
 68	strings: FAST_ARRAY[STRING]
 69
 70feature	-- 
 71	capacity: INTEGER is do Result := strings.capacity end
 72
 73	lower: INTEGER is do Result := strings.lower end
 74	
 75	upper: INTEGER is do Result := strings.upper end
 76
 77	count: INTEGER is do Result:= upper-lower+1 end
 78
 79	is_syncronized: BOOLEAN is
 80		local i: INTEGER
 81		do
 82			from Result:=True; i:=upper; 
 83			until Result=False or else i<lower 
 84			loop
 85				Result := (storage.item(i)=strings.item(i).to_external)
 86				i:=i-1
 87			end
 88		end
 89
 90	fill_strings is
 91			-- Fill the internal `strings' storage with the wrappers of
 92			-- the strings referred by the underlying C array.
 93		require strings/=Void
 94		local i: INTEGER; p: POINTER
 95		do
 96			from i:=upper until i<lower loop
 97				p:=storage.item(i)
 98				if p.is_not_null then 
 99					strings.put(create {STRING}.from_external(p),i)
100				end
101				i:=i-1
102			end
103		end
104
105feature {} -- Creation
106	from_external_array (an_array: POINTER; a_length: INTEGER) is
107		require 
108			array_not_null: an_array.is_not_null
109			positive_length: a_length > 0
110		do
111			storage := storage.from_pointer (an_array)
112			create strings.make(a_length)
113			fill_strings
114		ensure count=a_length
115		end
116
117	from_external_null_array (an_array: POINTER) is
118		require 
119			array_not_null: an_array.is_not_null
120		local
121			length: INTEGER
122		do
123			storage := storage.from_pointer (an_array)
124			from length := 0 until
125				storage.item (length).is_null
126			loop length := length + 1 end
127			create strings.make(length)
128			fill_strings
129		end
130
131feature {ANY} -- Writing:
132	put (element: like item; i: INTEGER) is
133		do
134			storage.put(null_or_string(element),i)
135			strings.put(element,i)
136		end
137
138	swap (i1, i2: INTEGER) is
139		-- local p: POINTER
140		do
141			not_yet_implemented 
142			-- p:=storage.item(i1) storage.put(storage.item(i2),i1)
143			-- storage.put(p,i2) strings.swap(i1,i2)
144		end
145
146	set_all_with (v: like item) is
147		-- local i: INTEGER; p: POINTER
148		do
149			not_yet_implemented
150			-- if v/=Void then p:=v.to_external end from i:=upper until
151			-- i<lower loop storage.put(p,i) strings.put(v,i) i:=i-1 end
152		end
153
154feature -- Accessing
155	item (an_index: INTEGER): STRING is
156		local p: POINTER
157		do
158			p:=storage.item(an_index)
159			if p.is_null then 
160				-- Note: theorically nothing; nevertheless we check that 
161				-- storage and strings are consistent
162				check strings.item(an_index) = Void end
163			else
164				Result:=strings.item(an_index) 
165				check Result/=Void end 
166				-- The following if command should be required if storage
167				-- and strings are not kept synchronized: if Result=Void
168				-- then create Result.from_external(p)
169				-- strings.put(Result,an_index) end
170			end				
171		end
172
173	new_iterator: ITERATOR[STRING] is
174		do
175			create {STRING_ARRAY_ITERATOR} Result.make(Current)
176		end
177
178	first: like item is 
179		do
180			Result:=item(lower)
181		end
182
183	last: like item is
184		do
185			Result:=item(upper)
186		end
187
188	is_empty: BOOLEAN is
189		do
190			Result:=strings.is_empty
191		end
192
193feature {ANY} -- Adding:
194	add_first (element: like item) is
195			-- Add a new item in first position : `count' is increased by
196			-- one and all other items are shifted right.
197
198			-- See also `add_last', `first', `last', `add'.
199
200			-- Performance: O(count)
201		do
202			not_yet_implemented	
203			-- local i, old_capacity: INTEGER do old_capacity:=capacity
204			-- from i:=upper; strings.add_first(element) if
205			-- old_capacity/=capacity then storage:=storage.realloc
206			-- (old_capacity,capacity) end until i<=lower loop
207			-- storage.put(storage.item(i),i-1) i:=i-1 end
208			-- storage.put(null_or_string(element),lower)
209		end
210
211	add_last (element: like item) is
212		-- local old_capacity: INTEGER
213		do
214			not_yet_implemented 
215			-- old_capacity:=capacity strings.add_last(element) if
216			-- capacity>old_capacity then storage:=storage.realloc
217			-- (old_capacity,capacity) end
218			-- storage.put(null_or_string(element),upper) end
219		end
220	
221	add (element: like item; index: INTEGER) is
222			-- Add a new `element' at rank `index' : `count' is increased
223			-- by one and range [`index' .. `upper'] is shifted right by one position.
224
225			-- See also `add_first', `add_last', `append_collection'.
226		do		
227			not_yet_implemented 
228			-- local old_capacity,i: INTEGER do old_capacity:=capacity
229			-- strings.add(element,index) storage:=storage.realloc
230			-- (old_capacity,capacity) from i:=upper until i>=index loop
231			-- storage.put(storage.item(i-1),i) i:=i-1 end
232			-- storage.put(null_or_string(element),index)
233		end
234
235feature {ANY} -- Modification:
236	force (element: like item; index: INTEGER) is
237		--local previous_count,i: INTEGER
238		do
239			not_yet_implemented
240			-- previous_count:=count strings.force(element,index)
241			-- strings.realloc(previous_count,count) from i:=lower until
242			-- i>=upper loop storage.put(storage.item(i),i+1) i:=i+1 end
243		end
244
245	copy (other: like Current) is
246		do
247			not_yet_implemented 
248			-- local i,old_capacity: INTEGER do
249			-- storage:=storage.realloc(capacity,other.capacity)
250			-- strings.copy(other.strings) from i:=upper until i<lower
251			-- loop storage.put(other.storage.item(i),i) i:=i-1 end
252		end
253
254	from_collection (model: COLLECTION[like item]) is
255		local i: ITERATOR[like item]
256		do
257			not_yet_implemented 
258			-- with_capacity(model.count) from i:=model.new_iterator;
259			-- i.start until i.is_off loop add_last i.next end
260		end
261
262feature {ANY} -- Removing:
263	remove_first is
264		-- local i: INTEGER
265		do
266			not_yet_implemented 
267			-- storage.remove_first(upper) strings.remove_first
268		end
269
270	remove_head (n: INTEGER) is
271		-- local i,j: INTEGER
272		do
273			not_yet_implemented
274			-- from i:=lower; j:=lower+n until j>upper loop
275			-- storage.put(storage.item(j),i) i:=i+1; j:=j+1 end
276			-- strings.remove_head(n)
277		end
278
279	remove (index: INTEGER) is
280		-- local i: INTEGER
281		do
282			not_yet_implemented
283			-- storage.remove(n,upper) storage.put(default_pointer,upper)
284			-- strings.remove(i)
285		end
286
287	remove_last is
288		do
289			not_yet_implemented
290			-- storage.put(default_pointer,upper) strings.remove_last
291		end
292
293	remove_tail (n: INTEGER) is
294		do
295			not_yet_implemented 
296			-- local i: INTEGER do from i:=upper-n+1 until i>upper loop
297			-- storage.put(default_pointer,i) i:=i+1 end
298			-- strings.remove_tail(n)
299		end
300
301	clear_count is
302		do
303			not_yet_implemented 
304			-- 			strings.clear_count
305		end
306
307	clear_count_and_capacity is
308		do
309			not_yet_implemented 
310			--	strings.clear_count_and_capacity
311			--	storage:=storage.calloc(capacity)
312		end
313
314feature {ANY} -- Looking and Searching:
315	first_index_of (element: like item): INTEGER is
316		do
317			Result:=strings.first_index_of(element)
318		end
319
320	index_of (element: like item; start_index: INTEGER): INTEGER is
321		do
322			not_yet_implemented
323		end
324
325	reverse_index_of (element: like item; start_index: INTEGER): INTEGER is
326		do
327			not_yet_implemented
328		end
329
330	fast_first_index_of (element: like item): INTEGER is
331		do
332			not_yet_implemented
333		end
334
335	fast_index_of (element: like item; start_index: INTEGER): INTEGER is
336		do
337			not_yet_implemented
338		end
339
340	fast_reverse_index_of (element: like item; start_index: INTEGER): INTEGER is
341		do
342			not_yet_implemented
343		end
344
345feature {ANY} -- Looking and comparison:
346	is_equal (other: like Current): BOOLEAN is
347		do
348			not_yet_implemented
349		end
350
351	is_equal_map (other: like Current): BOOLEAN is
352		do
353			not_yet_implemented
354		end
355
356	all_default: BOOLEAN is
357		do
358			not_yet_implemented
359		end
360
361	occurrences (element: like item): INTEGER is
362		do
363			not_yet_implemented
364		end
365
366	fast_occurrences (element: like item): INTEGER is
367		do
368			not_yet_implemented
369		end
370
371
372feature {ANY} -- Other features:
373	replace_all (old_value, new_value: like item) is
374		do
375			not_yet_implemented
376		end
377
378	fast_replace_all (old_value, new_value: like item) is
379		do
380			not_yet_implemented
381		end
382
383	slice (min, max: INTEGER): like Current is
384		do
385			not_yet_implemented
386		end
387	
388	reverse is
389		local i,j: INTEGER
390		do
391			from i:=lower; j:=upper until i>=j loop
392				swap(i,j)
393				i:=i+1; j:=j-1
394			end			
395		end
396
397feature {} -- Implement manifest generic creation:
398	manifest_put (index: INTEGER; element: like item) is
399		do
400			put (element,index)
401		end
402
403invariant
404	is_syncronized
405end -- class STRING_ARRAY