/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

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