/src/lib/string/internal/partially_filled_string.e

http://github.com/tybor/Liberty · Specman e · 289 lines · 255 code · 30 blank · 4 comment · 11 complexity · 6c79a843e4ccbdf7d866389013f898b0 MD5 · raw file

  1. class PARTIALLY_FILLED_STRING
  2. inherit
  3. ABSTRACT_STRING
  4. redefine
  5. infix "#", out_in_tagged_out_memory
  6. end
  7. create {ABSTRACT_STRING}
  8. from_string_and_arg
  9. feature {ANY}
  10. infix "#" (a_argument: ABSTRACT_STRING): ABSTRACT_STRING
  11. do
  12. check
  13. not_filled: storage.count < storage.capacity
  14. end
  15. put_arg(a_argument)
  16. Result := Current
  17. ensure
  18. Result = Current
  19. storage.last = a_argument
  20. end
  21. out_in_tagged_out_memory
  22. local
  23. i, save_i, accu, state: INTEGER; c: CHARACTER
  24. do
  25. from
  26. i := template.lower
  27. until
  28. i > template.upper
  29. loop
  30. c := template.item(i)
  31. inspect
  32. state
  33. when 0 then
  34. if c = '#' then
  35. state := 1
  36. else
  37. tagged_out_memory.extend(c)
  38. end
  39. when 1 then
  40. if c = '(' then
  41. save_i := i
  42. state := 2
  43. accu := 0
  44. elseif c = '#' then
  45. tagged_out_memory.extend('#')
  46. state := 0
  47. else
  48. tagged_out_memory.extend('#')
  49. i := i - 1
  50. state := 0
  51. end
  52. when 2 then
  53. if c = ')' then
  54. if not storage.valid_index(accu - 1) then
  55. tagged_out_memory.extend('#')
  56. tagged_out_memory.extend('(')
  57. i := save_i
  58. elseif storage.item(accu - 1) = Void then
  59. tagged_out_memory.append(once "Void")
  60. else
  61. storage.item(accu - 1).out_in_tagged_out_memory
  62. end
  63. state := 0
  64. elseif c.is_digit then
  65. accu := accu * 10 + c.decimal_value
  66. else
  67. tagged_out_memory.extend('#')
  68. tagged_out_memory.extend('(')
  69. i := save_i
  70. state := 0
  71. end
  72. end
  73. i := i + 1
  74. end
  75. end
  76. fill_tagged_out_memory
  77. do
  78. out_in_tagged_out_memory
  79. end
  80. count: INTEGER
  81. do
  82. Result := memory.count
  83. end
  84. item (a_index: INTEGER): CHARACTER
  85. do
  86. Result := memory.item(a_index)
  87. end
  88. substring (start_index, end_index: INTEGER): like Current
  89. do
  90. create Result.from_string_and_arg(once "#(1)", memory.substring(start_index, end_index))
  91. end
  92. occurrences (c: CHARACTER): INTEGER
  93. do
  94. Result := memory.occurrences(c)
  95. end
  96. copy (other: like Current)
  97. local
  98. i: INTEGER
  99. do
  100. from_string_and_arg(other.template, other.storage.first)
  101. from
  102. i := other.storage.lower + 1
  103. until
  104. i > other.storage.upper
  105. loop
  106. put_arg(other.storage.item(i))
  107. i := i + 1
  108. end
  109. end
  110. feature {ANY}
  111. is_equal (other: ABSTRACT_STRING): BOOLEAN
  112. do
  113. Result := memory.is_equal(other)
  114. end
  115. hash_code: INTEGER
  116. do
  117. Result := memory.hash_code
  118. end
  119. same_as (other: ABSTRACT_STRING): BOOLEAN
  120. do
  121. Result := memory.same_as(other)
  122. end
  123. first: CHARACTER
  124. do
  125. Result := memory.first
  126. end
  127. last: CHARACTER
  128. do
  129. Result := memory.last
  130. end
  131. has, fast_has (c: CHARACTER): BOOLEAN
  132. do
  133. Result := memory.has(c)
  134. end
  135. index_of, fast_index_of (c: CHARACTER; start_index: INTEGER): INTEGER
  136. do
  137. Result := memory.index_of(c, start_index)
  138. end
  139. reverse_index_of, fast_reverse_index_of (c: CHARACTER; start_index: INTEGER): INTEGER
  140. do
  141. Result := memory.reverse_index_of(c, start_index)
  142. end
  143. feature {ANY} -- Concatenation
  144. infix "&" (another: ABSTRACT_STRING): ABSTRACT_STRING
  145. do
  146. Result := Current | another
  147. end
  148. feature {ANY} -- Iterating and other features
  149. intern: FIXED_STRING
  150. do
  151. Result := memory.intern
  152. end
  153. feature {ANY} -- Interfacing with C string:
  154. to_external: POINTER
  155. do
  156. Result := memory.to_external
  157. end
  158. feature {}
  159. put_arg (a_argument: ABSTRACT_STRING)
  160. do
  161. storage.add_last(a_argument)
  162. memory_ := Void
  163. debug
  164. debug_string := memory
  165. end
  166. ensure
  167. storage.last = a_argument
  168. end
  169. feature {} -- Creation
  170. from_string_and_arg (a_string, a_argument: ABSTRACT_STRING)
  171. require
  172. a_string /= Void
  173. a_argument /= Void
  174. do
  175. template := a_string
  176. parse_template
  177. put_arg(a_argument)
  178. end
  179. feature {}
  180. parse_template
  181. local
  182. i, accu, capacity, state: INTEGER; c: CHARACTER
  183. do
  184. from
  185. i := template.lower
  186. until
  187. i > template.upper
  188. loop
  189. c := template.item(i)
  190. inspect
  191. state
  192. when 0 then
  193. if c = '#' then
  194. state := 1
  195. end
  196. when 1 then
  197. if c = '(' then
  198. state := 2
  199. accu := 0
  200. else
  201. state := 0
  202. end
  203. when 2 then
  204. if c = ')' then
  205. if capacity < accu then
  206. capacity := accu
  207. end
  208. state := 0
  209. elseif c.is_digit then
  210. accu := accu * 10 + c.decimal_value
  211. else
  212. state := 0
  213. end
  214. end
  215. i := i + 1
  216. end
  217. if storage /= Void then
  218. storage.with_capacity(capacity)
  219. else
  220. create storage.with_capacity(capacity)
  221. end
  222. end
  223. feature {ANY}
  224. recycle
  225. do
  226. memory_ := Void
  227. storage.clear_count
  228. end
  229. feature {PARTIALLY_FILLED_STRING}
  230. template: ABSTRACT_STRING
  231. storage: FAST_ARRAY[ABSTRACT_STRING]
  232. feature {}
  233. memory_, memory__: STRING
  234. memory: STRING
  235. do
  236. -- There is only one memory string ever created per PARTIALLY_FILLED_STRING.
  237. -- This feature ensures that by using two attributes:
  238. -- * `memory_' keeps the string when already calculated (set to Void when dirty)
  239. -- * `memory__' keeps the one and only ever created instance
  240. Result := memory_
  241. if Result = Void then
  242. lock_tagged_out
  243. tagged_out_memory.clear_count
  244. out_in_tagged_out_memory
  245. Result := memory__
  246. if Result = Void then
  247. Result := tagged_out_memory.twin
  248. memory__ := Result
  249. else
  250. Result := memory__
  251. Result.copy(tagged_out_memory)
  252. end
  253. unlock_tagged_out
  254. memory_ := Result
  255. end
  256. end
  257. invariant
  258. storage /= Void
  259. end -- class PARTIALLY_FILLED_STRING