1----------------------------------------------------------------------- 2-- Util.Beans.Objects -- Generic Typed Data Representation 3-- Copyright (C) 2009, 2010, 2011, 2013 Stephane Carrez 4-- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5-- 6-- Licensed under the Apache License, Version 2.0 (the "License"); 7-- you may not use this file except in compliance with the License. 8-- You may obtain a copy of the License at 9-- 10-- http://www.apache.org/licenses/LICENSE-2.0 11-- 12-- Unless required by applicable law or agreed to in writing, software 13-- distributed under the License is distributed on an "AS IS" BASIS, 14-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15-- See the License for the specific language governing permissions and 16-- limitations under the License. 17----------------------------------------------------------------------- 18 19-- Provides a data type to manage entities of different types using the 20-- same abstraction. 21-- 22-- An ''Object' can hold one of the following values: 23-- o a boolean 24-- o a long long integer 25-- o a date 26-- o a string 27-- o a wide wide string 28-- o a generic data 29-- 30-- 31-- Value : Object := To_Object ("something"); 32-- Value := Value + To_Object ("12"); 33-- 34with Ada.Strings.Unbounded; 35with Ada.Strings.Wide_Wide_Unbounded; 36with Ada.Finalization; 37private with Util.Concurrent.Counters; 38limited with Util.Beans.Basic; 39package Util.Beans.Objects is 40 41 pragma Preelaborate; 42 43 use Ada.Strings.Unbounded; 44 use Ada.Strings.Wide_Wide_Unbounded; 45 46 -- Exception raised when an object cannot be converted to a given type. 47 Conversion_Error : exception; 48 49 type Data_Type is (TYPE_NULL, 50 -- The object holds a boolean value. 51 TYPE_BOOLEAN, 52 -- The object holds an integer value (64-bits). 53 TYPE_INTEGER, 54 -- The object holds a floating point value. 55 TYPE_FLOAT, 56 -- The object holds a date and time 57 TYPE_TIME, 58 -- The object holds a string 59 TYPE_STRING, 60 -- The object holds a wide wide string 61 TYPE_WIDE_STRING, 62 -- The object holds a generic bean 63 TYPE_BEAN); 64 65 type Storage_Type is (STATIC, DYNAMIC); 66 67 -- Exception raised when the value identified by a name is not 68 -- recognized. 69 No_Value : exception; 70 71 -- ------------------------------ 72 -- Generic Object holding a value 73 -- ------------------------------ 74 -- The object has a type represented by 'Object_Type'. 75 -- It can hold any value while being tightly coupled with a type. 76 -- The object can be converted to standard Ada types. 77 type Object is private; 78 type Object_Value is private; 79 80 -- The null object. 81 Null_Object : constant Object; 82 83 -- ------------------------------ 84 -- Type definition 85 -- ------------------------------ 86 -- The Object_Type describes a type. It serves as a basis 87 -- for type conversion. 88 type Object_Type is limited interface; 89 type Object_Type_Access is not null access constant Object_Type'Class; 90 91 -- Get the type name 92 function Get_Name (Type_Def : Object_Type) return String is abstract; 93 94 -- Get the base data type. 95 function Get_Data_Type (Type_Def : Object_Type) return Data_Type is abstract; 96 97 -- Convert the value into a string. 98 function To_String (Type_Def : in Object_Type; 99 Value : in Object_Value) return String is abstract; 100 101 -- Convert the value into a wide string. 102 function To_Wide_Wide_String (Type_Def : in Object_Type; 103 Value : in Object_Value) return Wide_Wide_String is abstract; 104 105 -- Convert the value into an integer. 106 function To_Long_Long (Type_Def : in Object_Type; 107 Value : in Object_Value) return Long_Long_Integer is abstract; 108 109 -- Convert the value into a float. 110 function To_Long_Float (Type_Def : in Object_Type; 111 Value : in Object_Value) return Long_Long_Float is abstract; 112 113 -- Convert the value into a boolean. 114 function To_Boolean (Type_Def : in Object_Type; 115 Value : in Object_Value) return Boolean is abstract; 116 117 -- Convert the value into a duration. 118 function To_Duration (Type_Def : in Object_Type; 119 Value : in Object_Value) return Duration is abstract; 120 121 -- Returns True if the value is empty. 122 function Is_Empty (Type_Def : in Object_Type; 123 Value : in Object_Value) return Boolean is abstract; 124 125 -- ------------------------------ 126 -- Generic Object holding a value 127 -- ------------------------------ 128 129 -- Check whether the object contains a value. 130 -- Returns true if the object does not contain a value. 131 function Is_Null (Value : in Object) return Boolean; 132 133 -- Check whether the object is empty. 134 -- If the object is null, returns true. 135 -- If the object is the empty string, returns true. 136 -- If the object is a list bean whose Get_Count is 0, returns true. 137 -- Otherwise returns false. 138 function Is_Empty (Value : in Object) return Boolean; 139 140-- function Is_Constant (Value : in Object) return Boolean; 141 -- Get a type identification for the object value. 142 function Get_Type (Value : in Object) return Data_Type; 143 144 -- Get the type definition of the object value. 145 function Get_Type (Value : in Object) return Object_Type_Access; 146 147 -- Get the type name of this object. 148 function Get_Type_Name (Value : Object) return String; 149 150 -- Get the value identified by the name in the bean object. 151 -- If the value object is not a bean, returns the null object. 152 function Get_Value (Value : in Object; 153 Name : in String) return Object; 154 155 -- Convert the object to the corresponding type. 156 function To_String (Value : in Object) return String; 157 function To_Wide_Wide_String (Value : in Object) return Wide_Wide_String; 158 function To_Unbounded_String (Value : in Object) return Unbounded_String; 159 function To_Unbounded_Wide_Wide_String (Value : in Object) return Unbounded_Wide_Wide_String; 160 function To_Integer (Value : in Object) return Integer; 161 function To_Boolean (Value : in Object) return Boolean; 162 function To_Long_Integer (Value : in Object) return Long_Integer; 163 function To_Long_Long_Integer (Value : in Object) return Long_Long_Integer; 164 function To_Float (Value : in Object) return Float; 165 function To_Long_Float (Value : in Object) return Long_Float; 166 function To_Long_Long_Float (Value : in Object) return Long_Long_Float; 167 function To_Duration (Value : in Object) return Duration; 168 169 function To_Bean (Value : in Object) return access Util.Beans.Basic.Readonly_Bean'Class; 170 171 -- Convert the object to an object of another time. 172 -- Force the object to be an integer. 173 function Cast_Integer (Value : Object) return Object; 174 175 -- Force the object to be a float. 176 function Cast_Float (Value : Object) return Object; 177 178 -- Force the object to be a duration. 179 function Cast_Duration (Value : Object) return Object; 180 181 -- Force the object to be a string. 182 function Cast_String (Value : Object) return Object; 183 184 -- Convert a value to a generic typed object. 185 function To_Object (Value : in Integer) return Object; 186 function To_Object (Value : in Long_Integer) return Object; 187 function To_Object (Value : in Long_Long_Integer) return Object; 188 function To_Object (Value : in Float) return Object; 189 function To_Object (Value : in Long_Float) return Object; 190 function To_Object (Value : in Long_Long_Float) return Object; 191 function To_Object (Value : in String) return Object; 192 function To_Object (Value : in Wide_Wide_String) return Object; 193 function To_Object (Value : in Unbounded_String) return Object; 194 function To_Object (Value : in Unbounded_Wide_Wide_String) return Object; 195 function To_Object (Value : in Boolean) return Object; 196 function To_Object (Value : in Duration) return Object; 197 198 -- Create an object that refers to the bean object. With the storage type 199 -- <b>DYNAMIC</b>, the default, the bean object will be freed when there is 200 -- no <b>Object</b> that refers to that bean. With <b>STATIC</b>, the bean 201 -- is a static bean and it will not be freed automaticaly. 202 function To_Object (Value : access Util.Beans.Basic.Readonly_Bean'Class; 203 Storage : in Storage_Type := DYNAMIC) return Object; 204 205 -- Comparison of objects 206 function "<" (Left, Right : Object) return Boolean; 207 function "<=" (Left, Right : Object) return Boolean; 208 function ">" (Left, Right : Object) return Boolean; 209 function ">=" (Left, Right : Object) return Boolean; 210 function "=" (Left, Right : Object) return Boolean; 211 212 -- Arithmetic operations on objects 213 function "+" (Left, Right : Object) return Object; 214 function "-" (Left, Right : Object) return Object; 215 function "*" (Left, Right : Object) return Object; 216 function "/" (Left, Right : Object) return Object; 217 function "&" (Left, Right : Object) return Object; 218 function "mod" (Left, Right : Object) return Object; 219 function "-" (Left : Object) return Object; 220 221private 222 223 use Ada.Finalization; 224 225 type Name_Access is access constant String; 226 227 type Basic_Type is abstract limited new Object_Type with null record; 228 229 -- Convert the value into a wide string. 230 function To_Wide_Wide_String (Type_Def : in Basic_Type; 231 Value : in Object_Value) return Wide_Wide_String; 232 233 -- Convert the value into an integer. 234 function To_Long_Long (Type_Def : in Basic_Type; 235 Value : in Object_Value) return Long_Long_Integer; 236 237 -- Convert the value into a float. 238 function To_Long_Float (Type_Def : in Basic_Type; 239 Value : in Object_Value) return Long_Long_Float; 240 241 -- Convert the value into a boolean. 242 function To_Boolean (Type_Def : in Basic_Type; 243 Value : in Object_Value) return Boolean; 244 245 -- Convert the value into a duration. 246 function To_Duration (Type_Def : in Basic_Type; 247 Value : in Object_Value) return Duration; 248 249 -- Returns False 250 function Is_Empty (Type_Def : in Basic_Type; 251 Value : in Object_Value) return Boolean; 252 253 -- ------------------------------ 254 -- Null Type 255 -- ------------------------------ 256 type Null_Type is new Basic_Type with null record; 257 258 -- Get the type name 259 function Get_Name (Type_Def : Null_Type) return String; 260 261 -- Get the base data type. 262 function Get_Data_Type (Type_Def : Null_Type) return Data_Type; 263 264 -- Convert the value into a string. 265 function To_String (Type_Def : in Null_Type; 266 Value : in Object_Value) return String; 267 268 -- Returns True 269 function Is_Empty (Type_Def : in Null_Type; 270 Value : in Object_Value) return Boolean; 271 272 -- ------------------------------ 273 -- Integer Type 274 -- ------------------------------ 275 type Int_Type is new Basic_Type with null record; 276 277 -- Get the type name 278 function Get_Name (Type_Def : Int_Type) return String; 279 280 -- Get the base data type. 281 function Get_Data_Type (Type_Def : Int_Type) return Data_Type; 282 283 function To_String (Type_Def : in Int_Type; 284 Value : in Object_Value) return String; 285 286 -- Convert the value into an integer. 287 function To_Long_Long (Type_Def : in Int_Type; 288 Value : in Object_Value) return Long_Long_Integer; 289 290 -- Convert the value into a float. 291 function To_Long_Float (Type_Def : in Int_Type; 292 Value : in Object_Value) return Long_Long_Float; 293 294 -- Convert the value into a boolean. 295 function To_Boolean (Type_Def : in Int_Type; 296 Value : in Object_Value) return Boolean; 297 298 -- Convert the value into a duration. 299 function To_Duration (Type_Def : in Int_Type; 300 Value : in Object_Value) return Duration; 301 302 -- ------------------------------ 303 -- Float Type 304 -- ------------------------------ 305 type Float_Type is new Basic_Type with null record; 306 307 -- Get the type name 308 function Get_Name (Type_Def : in Float_Type) return String; 309 310 -- Get the base data type. 311 function Get_Data_Type (Type_Def : in Float_Type) return Data_Type; 312 313 -- Convert the value into a string. 314 function To_String (Type_Def : in Float_Type; 315 Value : in Object_Value) return String; 316 317 -- Convert the value into an integer. 318 function To_Long_Long (Type_Def : in Float_Type; 319 Value : in Object_Value) return Long_Long_Integer; 320 321 -- Convert the value into a float. 322 function To_Long_Float (Type_Def : in Float_Type; 323 Value : in Object_Value) return Long_Long_Float; 324 325 -- Convert the value into a boolean. 326 function To_Boolean (Type_Def : in Float_Type; 327 Value : in Object_Value) return Boolean; 328 329 -- Convert the value into a duration. 330 function To_Duration (Type_Def : in Float_Type; 331 Value : in Object_Value) return Duration; 332 333 -- ------------------------------ 334 -- String Type 335 -- ------------------------------ 336 type String_Type is new Basic_Type with null record; 337 338 -- Get the type name 339 function Get_Name (Type_Def : in String_Type) return String; 340 341 -- Get the base data type. 342 function Get_Data_Type (Type_Def : in String_Type) return Data_Type; 343 344 -- Convert the value into a string. 345 function To_String (Type_Def : in String_Type; 346 Value : in Object_Value) return String; 347 348 -- Convert the value into an integer. 349 function To_Long_Long (Type_Def : in String_Type; 350 Value : in Object_Value) return Long_Long_Integer; 351 352 -- Convert the value into a float. 353 function To_Long_Float (Type_Def : in String_Type; 354 Value : in Object_Value) return Long_Long_Float; 355 356 -- Convert the value into a boolean. 357 function To_Boolean (Type_Def : in String_Type; 358 Value : in Object_Value) return Boolean; 359 360 -- Convert the value into a duration. 361 function To_Duration (Type_Def : in String_Type; 362 Value : in Object_Value) return Duration; 363 364 -- Returns True if the value is empty. 365 function Is_Empty (Type_Def : in String_Type; 366 Value : in Object_Value) return Boolean; 367 368 -- ------------------------------ 369 -- Wide String Type 370 -- ------------------------------ 371 type Wide_String_Type is new Basic_Type with null record; 372 373 -- Get the type name 374 function Get_Name (Type_Def : in Wide_String_Type) return String; 375 376 -- Get the base data type. 377 function Get_Data_Type (Type_Def : in Wide_String_Type) return Data_Type; 378 379 -- Convert the value into a string. 380 function To_String (Type_Def : in Wide_String_Type; 381 Value : in Object_Value) return String; 382 383 -- Convert the value into a wide string. 384 function To_Wide_Wide_String (Type_Def : in Wide_String_Type; 385 Value : in Object_Value) return Wide_Wide_String; 386 387 -- Convert the value into an integer. 388 function To_Long_Long (Type_Def : in Wide_String_Type; 389 Value : in Object_Value) return Long_Long_Integer; 390 391 -- Convert the value into a float. 392 function To_Long_Float (Type_Def : in Wide_String_Type; 393 Value : in Object_Value) return Long_Long_Float; 394 395 -- Convert the value into a boolean. 396 function To_Boolean (Type_Def : in Wide_String_Type; 397 Value : in Object_Value) return Boolean; 398 399 -- Convert the value into a duration. 400 function To_Duration (Type_Def : in Wide_String_Type; 401 Value : in Object_Value) return Duration; 402 403 -- Returns True if the value is empty. 404 function Is_Empty (Type_Def : in Wide_String_Type; 405 Value : in Object_Value) return Boolean; 406 407 -- ------------------------------ 408 -- Boolean Type 409 -- ------------------------------ 410 type Boolean_Type is new Basic_Type with null record; 411 412 -- Get the type name 413 function Get_Name (Type_Def : in Boolean_Type) return String; 414 415 -- Get the base data type. 416 function Get_Data_Type (Type_Def : in Boolean_Type) return Data_Type; 417 418 -- Convert the value into a string. 419 function To_String (Type_Def : in Boolean_Type; 420 Value : in Object_Value) return String; 421 422 -- Convert the value into an integer. 423 function To_Long_Long (Type_Def : in Boolean_Type; 424 Value : in Object_Value) return Long_Long_Integer; 425 426 -- Convert the value into a float. 427 function To_Long_Float (Type_Def : in Boolean_Type; 428 Value : in Object_Value) return Long_Long_Float; 429 430 -- Convert the value into a boolean. 431 function To_Boolean (Type_Def : in Boolean_Type; 432 Value : in Object_Value) return Boolean; 433 434 -- ------------------------------ 435 -- Duration Type 436 -- ------------------------------ 437 type Duration_Type_Def is new Basic_Type with null record; 438 439 -- Get the type name 440 function Get_Name (Type_Def : in Duration_Type_Def) return String; 441 442 -- Get the base data type. 443 function Get_Data_Type (Type_Def : in Duration_Type_Def) return Data_Type; 444 445 -- Convert the value into a string. 446 function To_String (Type_Def : in Duration_Type_Def; 447 Value : in Object_Value) return String; 448 449 -- Convert the value into an integer. 450 function To_Long_Long (Type_Def : in Duration_Type_Def; 451 Value : in Object_Value) return Long_Long_Integer; 452 453 -- Convert the value into a float. 454 function To_Long_Float (Type_Def : in Duration_Type_Def; 455 Value : in Object_Value) return Long_Long_Float; 456 457 -- Convert the value into a boolean. 458 function To_Boolean (Type_Def : in Duration_Type_Def; 459 Value : in Object_Value) return Boolean; 460 461 -- Convert the value into a duration. 462 function To_Duration (Type_Def : in Duration_Type_Def; 463 Value : in Object_Value) return Duration; 464 465 -- ------------------------------ 466 -- Bean Type 467 -- ------------------------------ 468 type Bean_Type is new Basic_Type with null record; 469 470 -- Get the type name 471 function Get_Name (Type_Def : in Bean_Type) return String; 472 473 -- Get the base data type. 474 function Get_Data_Type (Type_Def : in Bean_Type) return Data_Type; 475 476 -- Convert the value into a string. 477 function To_String (Type_Def : in Bean_Type; 478 Value : in Object_Value) return String; 479 480 -- Convert the value into an integer. 481 function To_Long_Long (Type_Def : in Bean_Type; 482 Value : in Object_Value) return Long_Long_Integer; 483 484 -- Convert the value into a float. 485 function To_Long_Float (Type_Def : in Bean_Type; 486 Value : in Object_Value) return Long_Long_Float; 487 488 -- Convert the value into a boolean. 489 function To_Boolean (Type_Def : in Bean_Type; 490 Value : in Object_Value) return Boolean; 491 492 -- Returns True if the value is empty. 493 function Is_Empty (Type_Def : in Bean_Type; 494 Value : in Object_Value) return Boolean; 495 496 subtype Proxy_Data_Type is Data_Type range TYPE_STRING .. TYPE_BEAN; 497 498 type Proxy is tagged limited record 499 Ref_Counter : Util.Concurrent.Counters.Counter; 500 end record; 501 502 -- Release the object pointed to by the proxy (if necessary). 503 procedure Release (P : in out Proxy) is null; 504 505 type Bean_Proxy_Access is access all Proxy'Class; 506 507 type String_Proxy (Len : Natural) is new Proxy with record 508 Value : String (1 .. Len); 509 end record; 510 type String_Proxy_Access is access all String_Proxy; 511 512 type Wide_String_Proxy (Len : Natural) is new Proxy with record 513 Value : Wide_Wide_String (1 .. Len); 514 end record; 515 type Wide_String_Proxy_Access is access all Wide_String_Proxy; 516 517 type Bean_Proxy is new Proxy with record 518 Bean : access Util.Beans.Basic.Readonly_Bean'Class; 519 Storage : Storage_Type; 520 end record; 521 522 -- Release the object pointed to by the proxy (if necessary). 523 overriding 524 procedure Release (P : in out Bean_Proxy); 525 526 type Object_Value (Of_Type : Data_Type := TYPE_NULL) is record 527 case Of_Type is 528 when TYPE_NULL => 529 null; 530 531 -- Integers and enums are stored as 64-bit integer. 532 when TYPE_INTEGER => 533 Int_Value : Long_Long_Integer; 534 535 when TYPE_BOOLEAN => 536 Bool_Value : Boolean; 537 538 when TYPE_FLOAT => 539 Float_Value : Long_Long_Float; 540 541 when TYPE_TIME => 542 Time_Value : Duration; 543 544 when TYPE_STRING => 545 String_Proxy : String_Proxy_Access; 546 547 when TYPE_WIDE_STRING => 548 Wide_Proxy : Wide_String_Proxy_Access; 549 550 when TYPE_BEAN => 551 Proxy : Bean_Proxy_Access; 552 553 end case; 554 end record; 555 556 No_Type : aliased constant Null_Type := Null_Type '(others => <>); 557 558 Null_Value : constant Object_Value := Object_Value '(Of_Type => TYPE_NULL); 559 560 type Object is new Controlled with record 561 Type_Def : Object_Type_Access := No_Type'Access; 562 V : Object_Value := Null_Value; 563 end record; 564 565 overriding 566 procedure Adjust (Obj : in out Object); 567 568 overriding 569 procedure Finalize (Obj : in out Object); 570 571 Null_Object : constant Object := Object '(Controlled with 572 V => Object_Value '(Of_Type => TYPE_NULL), 573 Type_Def => No_Type'Access); 574 575end Util.Beans.Objects; 576