/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

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