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

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