/src/lib/storage/internal/repository_layout.e
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.