/src/lib/storage/internal/repository_layout.e

http://github.com/tybor/Liberty · Specman e · 356 lines · 283 code · 33 blank · 40 comment · 9 complexity · 4f76a824f313c8e710e8145463d05b1d MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. class REPOSITORY_LAYOUT
  5. --
  6. -- Used by the update engine of REPOSITORY_IMPL to ensure correct object references and cycles handling.
  7. --
  8. insert
  9. INTERNALS_HANDLER
  10. RECYCLABLE
  11. create {REPOSITORY_IMPL}
  12. make
  13. feature {REPOSITORY_IMPL, REPOSITORY_LAYOUT}
  14. type: STRING
  15. -- data type, if useful
  16. capacity: INTEGER
  17. -- for native arrays only
  18. ref: INTEGER
  19. -- object reference, for reference objects only
  20. trans_ref: STRING
  21. -- object transient reference, for reference objects only
  22. name: STRING
  23. -- object name
  24. value: STRING
  25. -- object value, for basic types only
  26. layouts: AVL_DICTIONARY[REPOSITORY_LAYOUT, STRING]
  27. -- child layouts
  28. assigned: HASHED_SET[STRING]
  29. -- each layout for which the INTERNALS object was assigned
  30. solved: BOOLEAN
  31. solve (a_solver: FUNCTION[TUPLE[INTEGER], INTERNALS]): INTERNALS
  32. local
  33. i: INTEGER; layout: REPOSITORY_LAYOUT; attribute_name: STRING; an_attribute: INTERNALS
  34. s: like solved
  35. do
  36. if internals_set then
  37. Result := internals_memory
  38. else
  39. Result := internals(a_solver)
  40. internals_memory := Result
  41. end
  42. if not solved and then Result /= Void then
  43. check
  44. Result.object_can_be_modified
  45. end
  46. from
  47. s := True
  48. i := 1
  49. until
  50. i > Result.type_attribute_count
  51. loop
  52. attribute_name := Result.type_attribute_name(i)
  53. if not assigned.has(attribute_name) then
  54. layout := layouts.reference_at(attribute_name)
  55. if layout /= Void then
  56. check
  57. layout.name.is_equal(attribute_name)
  58. end
  59. an_attribute := layout.solve(a_solver)
  60. if layout.internals_set then --|** should it be layout.solved?
  61. Result.set_object_attribute(an_attribute, i)
  62. assigned.add(attribute_name.twin)
  63. else
  64. s := False
  65. end
  66. end
  67. end
  68. i := i + 1
  69. end
  70. if s then
  71. Result.set_object_can_be_retrieved
  72. solved := True
  73. end
  74. end
  75. ensure
  76. (Result /= Void and then Result.object_can_be_retrieved) implies solved
  77. end
  78. feature {REPOSITORY_LAYOUT}
  79. internals_set: BOOLEAN
  80. -- True when `internals_memory' was set
  81. feature {}
  82. internals_memory: INTERNALS
  83. internals (a_solver: FUNCTION[TUPLE[INTEGER], INTERNALS]): INTERNALS
  84. require
  85. not solved
  86. local
  87. c: CHARACTER; b: BOOLEAN; i: INTEGER; r: REAL; i8: INTEGER_8; i16: INTEGER_16; i32: INTEGER_32
  88. i64: INTEGER_64; r32: REAL_32; r64: REAL_64; r80: REAL_80; r128: REAL_128; re: REAL_EXTENDED
  89. array_type: STRING
  90. transient: REPOSITORY_TRANSIENT
  91. do
  92. internals_set := True
  93. inspect
  94. kind
  95. when "layout" then
  96. Result := internals_from_generating_type(type)
  97. when "reference" then
  98. if trans_ref /= Void then
  99. if transient.has_object(trans_ref) then
  100. Result := transient.object(trans_ref)
  101. end
  102. elseif ref > 0 then
  103. Result := a_solver.item([ref])
  104. if Result = Void then
  105. internals_set := False
  106. end
  107. end
  108. -- by definition, a reference is resolved as soon as the internals is recovered (i.e. the layout
  109. -- it points to is solved)
  110. solved := internals_set
  111. when "embedded" then
  112. Result := internals_from_generating_type(type)
  113. when "array" then
  114. array_type := once ""
  115. array_type.copy(once "NATIVE_ARRAY[")
  116. array_type.append(type)
  117. array_type.extend(']')
  118. Result := native_array_internals_from_generating_type(array_type, capacity)
  119. when "basic" then
  120. inspect
  121. type
  122. when "CHARACTER" then
  123. c := value.to_integer.to_character
  124. Result := c.to_internals
  125. when "BOOLEAN" then
  126. b := value.is_equal("True")
  127. Result := b.to_internals
  128. when "INTEGER_8" then
  129. i8 := value.to_integer.to_integer_8
  130. Result := i8.to_internals
  131. when "INTEGER_16" then
  132. i16 := value.to_integer.to_integer_16
  133. Result := i16.to_internals
  134. when "INTEGER" then
  135. i := value.to_integer
  136. Result := i.to_internals
  137. when "INTEGER_32" then
  138. i32 := value.to_integer
  139. Result := i32.to_internals
  140. when "INTEGER_64" then
  141. i64 := value.to_integer_64
  142. Result := i64.to_internals
  143. when "REAL" then
  144. r := value.to_real
  145. Result := r.to_internals
  146. when "REAL_32" then
  147. r32 := value.to_real.force_to_real_32
  148. Result := r32.to_internals
  149. when "REAL_64" then
  150. r64 := value.to_real
  151. Result := r64.to_internals
  152. when "REAL_80" then
  153. r80 := value.to_real
  154. Result := r80.to_internals
  155. when "REAL_128" then
  156. r128 := value.to_real
  157. Result := r128.to_internals
  158. when "REAL_EXTENDED" then
  159. re := value.to_real
  160. Result := re.to_internals
  161. end
  162. Result.set_object_can_be_retrieved
  163. solved := True
  164. end
  165. end
  166. feature {REPOSITORY_IMPL}
  167. kind: STRING
  168. -- The layout kind. Almost everything is common between layout kinds. If things begin to diverge too
  169. -- much, change that to a real polymorphism.
  170. is_clear: BOOLEAN
  171. do
  172. Result := kind.is_empty
  173. end
  174. set_kind (a_kind: like kind)
  175. require
  176. is_clear
  177. { FAST_ARRAY[STRING] << "repository", "reference", "layout", "embedded", "basic", "array" >>}.has(a_kind)
  178. do
  179. kind.copy(a_kind)
  180. ensure
  181. not is_clear
  182. kind.is_equal(a_kind)
  183. end
  184. set_type (a_type: like type)
  185. require
  186. not is_clear
  187. type = Void
  188. a_type /= Void
  189. do
  190. type := type_memory
  191. type.copy(a_type)
  192. ensure
  193. type.is_equal(a_type)
  194. end
  195. set_capacity (a_capacity: like capacity)
  196. do
  197. capacity := a_capacity
  198. ensure
  199. capacity = a_capacity
  200. end
  201. set_ref (a_ref: like ref)
  202. require
  203. not is_clear
  204. ref = 0
  205. a_ref > 0
  206. trans_ref = Void
  207. do
  208. ref := a_ref
  209. ensure
  210. ref = a_ref
  211. end
  212. set_trans_ref (a_trans_ref: like trans_ref)
  213. require
  214. not is_clear
  215. trans_ref = Void
  216. a_trans_ref /= Void
  217. ref = 0
  218. do
  219. trans_ref := trans_ref_memory
  220. trans_ref.copy(a_trans_ref)
  221. ensure
  222. trans_ref.is_equal(a_trans_ref)
  223. end
  224. set_name (a_name: like name)
  225. require
  226. not is_clear
  227. name = Void
  228. a_name /= Void
  229. do
  230. name := name_memory
  231. name.copy(a_name)
  232. ensure
  233. name.is_equal(a_name)
  234. end
  235. set_value (a_value: like value)
  236. require
  237. not is_clear
  238. value = Void
  239. a_value /= Void
  240. do
  241. value := value_memory
  242. value.copy(a_value)
  243. ensure
  244. value.is_equal(a_value)
  245. end
  246. add_layout (a_layout: REPOSITORY_LAYOUT)
  247. require
  248. not is_clear
  249. a_layout.name /= Void
  250. not kind.is_equal("reference")
  251. do
  252. layouts.add(a_layout, a_layout.name)
  253. ensure
  254. layouts.at(a_layout.name) = a_layout
  255. end
  256. feature {RECYCLING_POOL}
  257. recycle
  258. do
  259. kind.clear_count
  260. type_memory.clear_count
  261. trans_ref_memory.clear_count
  262. name_memory.clear_count
  263. value_memory.clear_count
  264. type := Void
  265. ref := 0
  266. trans_ref := Void
  267. name := Void
  268. value := Void
  269. layouts.clear_count
  270. assigned.clear_count
  271. internals_memory := Void
  272. internals_set := False
  273. solved := False
  274. ensure
  275. is_clear
  276. end
  277. feature {}
  278. make
  279. do
  280. create layouts.make
  281. create assigned.make
  282. kind := ""
  283. type_memory := ""
  284. trans_ref_memory := ""
  285. name_memory := ""
  286. value_memory := ""
  287. ensure
  288. is_clear
  289. end
  290. type_memory: STRING
  291. trans_ref_memory: STRING
  292. name_memory: STRING
  293. value_memory: STRING
  294. invariant
  295. has_kind: kind /= Void
  296. solved_internals_coherence: (not solved and internals_memory /= Void) implies internals_memory.object_can_be_modified
  297. --reference_has_ref: kind.is_equal("reference") implies (ref > 0 or trans_ref /= Void)
  298. reference_is_solved: (kind.is_equal("reference") and internals_set) implies solved
  299. reference_dont_have_layouts: kind.is_equal("reference") implies layouts.is_empty
  300. transient_or_ref: trans_ref /= Void implies ref = 0
  301. assigned_are_layouts: assigned.for_all(agent layouts.has(?))
  302. coherence: solved implies internals_set
  303. end -- class REPOSITORY_LAYOUT
  304. --
  305. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  306. --
  307. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  308. -- of this software and associated documentation files (the "Software"), to deal
  309. -- in the Software without restriction, including without limitation the rights
  310. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  311. -- copies of the Software, and to permit persons to whom the Software is
  312. -- furnished to do so, subject to the following conditions:
  313. --
  314. -- The above copyright notice and this permission notice shall be included in
  315. -- all copies or substantial portions of the Software.
  316. --
  317. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  318. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  319. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  320. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  321. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  322. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  323. -- THE SOFTWARE.