1------------------------------------------------------------------------------ 2-- XML/Ada - An XML suite for Ada95 -- 3-- -- 4-- Copyright (C) 2001-2017, AdaCore -- 5-- -- 6-- This library is free software; you can redistribute it and/or modify it -- 7-- under terms of the GNU General Public License as published by the Free -- 8-- Software Foundation; either version 3, or (at your option) any later -- 9-- version. This library is distributed in the hope that it will be useful, -- 10-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- 11-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- 12-- -- 13-- As a special exception under Section 7 of GPL version 3, you are granted -- 14-- additional permissions described in the GCC Runtime Library Exception, -- 15-- version 3.1, as published by the Free Software Foundation. -- 16-- -- 17-- You should have received a copy of the GNU General Public License and -- 18-- a copy of the GCC Runtime Library Exception along with this program; -- 19-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 20-- <http://www.gnu.org/licenses/>. -- 21-- -- 22------------------------------------------------------------------------------ 23 24-- This package is the root hierarchy for the Core part of the DOM 25-- interface. 26-- It is in fact made of several subpackages, since DOM provides 27-- two views of the tree: Object-oriented throught the Element, Document,... 28-- types; and direct access through the Node interface. 29 30pragma Ada_05; 31 32with Unicode.CES; 33with Ada.Unchecked_Deallocation; 34with Sax.HTable; 35with Sax.Symbols; 36with Sax.Utils; 37 38package DOM.Core is 39 40 Default_Node_List_Growth_Factor : constant Float := 1.0; 41 -- Set to 1.0 the buffer is doubled in size (growth factor is 100%). 42 -- If set to 0.0 only a single empty items is added. 43 -- The higher this factor, the less memory allocations will be required 44 -- (and thus the faster your program will run). 45 -- Setting this to 0.0 will require more allocations, but will save memory, 46 -- since no empty node will remain in the final tree. 47 48 subtype DOM_String is Unicode.CES.Byte_Sequence; 49 -- A simple redefinition of the strings, to be compatible with the 50 -- standard DOM interface 51 -- See the package Encodings for the exact encoding used for DOM_Strings 52 53 subtype DOM_String_Access is Unicode.CES.Byte_Sequence_Access; 54 55 ----------- 56 -- Nodes -- 57 ----------- 58 -- This is the base type for all DOM.Core types. It is declared in this 59 -- package for visibility reasons, so that all DOM.Core.* packages have 60 -- access to the components. 61 62 type Node_Types is 63 (Element_Node, 64 Attribute_Node, 65 Cdata_Section_Node, 66 Entity_Reference_Node, 67 Entity_Node, 68 Processing_Instruction_Node, 69 Text_Node, 70 Comment_Node, 71 Document_Node, 72 Document_Type_Node, 73 Document_Fragment_Node, 74 Notation_Node); 75 76 subtype Character_Data_Types is Node_Types range Text_Node .. Comment_Node; 77 78 type Node_Record (Node_Type : Node_Types) is private; 79 type Node is access Node_Record; 80 81 subtype Character_Data is Node; 82 subtype Element is Node (Element_Node); 83 subtype Attr is Node (Attribute_Node); 84 subtype Cdata_Section is Character_Data (Cdata_Section_Node); 85 subtype Entity_Reference is Node (Entity_Reference_Node); 86 subtype Entity is Node (Entity_Node); 87 subtype Processing_Instruction is Node (Processing_Instruction_Node); 88 subtype Text is Character_Data (Text_Node); 89 subtype Comment is Character_Data (Comment_Node); 90 subtype Document is Node (Document_Node); 91 subtype Document_Type is Node (Document_Type_Node); 92 subtype Document_Fragment is Node (Document_Fragment_Node); 93 subtype Notation is Node (Notation_Node); 94 95 type Node_List is private; 96 -- A simple ordered list of nodes (see DOM.Core.Nodes for subprograms) 97 98 type Named_Node_Map is private; 99 -- A collection of nodes accessible by their names. 100 -- This is unordered. 101 102 procedure Free (List : in out Node_List); 103 -- Free the memory occupied by the list. The items contained in the list 104 -- are not freed, since they still exist in the XML tree. 105 106 ------------------------ 107 -- Dom implementation -- 108 ------------------------ 109 -- This provides a number of methods for performing operations that are 110 -- independent of any particular instance of the document object model. 111 112 type DOM_Implementation is private; 113 -- There are multiple implementations of DOM. 114 -- They can be specialized for some special cases (HTML, Stylesheets,...) 115 116 function Has_Feature 117 (Implementation : DOM_Implementation; 118 Feature : DOM_String; 119 Version : String := "2.0") return Boolean; 120 -- Return TRUE if this implementation of DOM has the Feature. 121 122 function Create_Document 123 (Implementation : DOM_Implementation; 124 NameSpace_URI : DOM_String := ""; 125 Qualified_Name : DOM_String := ""; 126 Doc_Type : Node := null; 127 Symbols : Sax.Utils.Symbol_Table := Sax.Utils.No_Symbol_Table) 128 return Node; 129 -- Create an new document with its element. 130 -- Note that NameSpace_URI can be the empty string if you do not want 131 -- to use namespaces. 132 -- The Document Type Definition can be null if there is none associated 133 -- with the document. 134 -- Wrong_Document_Err is raised if Doc_Type has already been used for 135 -- another document. 136 -- Symbols should be used to specify the symbol table used by the parser 137 -- that generates the DOM. It is needed because the various string elements 138 -- in the tree are represented as symbols and the correct symbol table must 139 -- be specified. You can get it from the parser itself by using 140 -- Get_Symbol_Table. Optionally, you can pass an explicit No_Symbol_Table 141 -- to create one automatically. It is recommended to share the table with 142 -- the parser whenever possible for maximum efficient. 143 -- In general, the document is created from the Start_Document callback 144 -- of a tree_reader, so the simplest is to call the inherited 145 -- Start_Document. 146 147 procedure Set_Node_List_Growth_Factor (Factor : Float); 148 -- Set the growth factor, see Default_Node_List_Growth_Factor 149 150 -------------------- 151 -- Dom exceptions -- 152 -------------------- 153 -- The following exceptions are declared in the DOM interface. If we 154 -- were to follow exactly the interface, we should a single exception to 155 -- which we associate an integer code. It seems easier to provide one 156 -- exception for each case. However, we kept the standard names. 157 158 Index_Size_Err : exception; 159 -- If Index or size is invalid (negative or greated than max value). 160 161 Domstring_Size_Err : exception; 162 -- If the specified range of text does not fit into a DomString. 163 164 Hierarchy_Request_Err : exception; 165 -- If a node is inserted somewhere it doesn't belong. 166 167 Wrong_Document_Err : exception; 168 -- If a node is used with a document other than its own. 169 170 Invalid_Character_Err : exception; 171 -- If an invalid character is used, for instance in a name. 172 173 No_Data_Allowed_Err : exception; 174 -- If data is specified for a node that doesn't support data. 175 176 No_Modification_Allowed_Err : exception; 177 -- If an attempt is made to modify a read-only object. 178 179 Not_Found_Err : exception; 180 -- If an attempt is made to reference a node in a concept where it doesn't 181 -- exist. 182 183 Not_Supported_Err : exception; 184 -- If the implementation does not support the type of object requested. 185 186 Inuse_Attribute_Err : exception; 187 -- If an attempt is made to add an attribute that is already used. 188 189 Invalid_State_Err : exception; 190 -- If an attempt is made to use an object that is not or no longer 191 -- available. 192 193 Syntax_Err : exception; 194 -- If an invalid string is specified. 195 196 Invalid_Modification_Err : exception; 197 -- If an attempt is made to modify the type of the underlying object. 198 199 Namespace_Err : exception; 200 -- If an attempt is made to create or modify an object in a way 201 -- incompatible with the namespace. 202 203 Invalid_Access_Err : exception; 204 -- If a parameter or an operation is not supported by the underlying 205 -- object. 206 207private 208 209 type DOM_Implementation is null record; 210 211 type Node_Array is array (Natural range <>) of Node; 212 type Node_Array_Access is access Node_Array; 213 214 procedure Free is new Ada.Unchecked_Deallocation 215 (Node_Array, Node_Array_Access); 216 217 type Node_List is record 218 Items : Node_Array_Access := null; 219 Last : Integer := -1; 220 -- The index of the last significant element in Items 221 end record; 222 223 Null_List : constant Node_List := (null, -1); 224 225 -- Not the most efficient way to implement a hash-table, but these are 226 -- generally short lists anyway (attributes,...) 227 type Named_Node_Map is new Node_List; 228 Null_Node_Map : constant Named_Node_Map := (null, -1); 229 230 ------------------ 231 -- Nodes htable -- 232 ------------------ 233 234 type Node_String is record 235 N : Node; 236 Key : Sax.Symbols.Symbol; 237 end record; 238 No_Node_String : constant Node_String := (null, Sax.Symbols.No_Symbol); 239 240 procedure Free (N : in out Node_String); 241 function Get_Key (N : Node_String) return Sax.Symbols.Symbol; 242 pragma Inline (Free, Get_Key); 243 244 package Nodes_Htable is new Sax.HTable 245 (Element => Node_String, 246 Empty_Element => No_Node_String, 247 Free => Free, 248 Key => Sax.Symbols.Symbol, 249 Get_Key => Get_Key, 250 Hash => Sax.Symbols.Hash, 251 Equal => Sax.Symbols."="); 252 type Nodes_Htable_Access is access Nodes_Htable.HTable; 253 254 ------------------- 255 -- Node_Name_Def -- 256 ------------------- 257 -- Attributes and Elements share the same kind description. These are 258 -- grouped in the same type for ease of use 259 260 type Node_Name_Def is record 261 Prefix : Sax.Symbols.Symbol; 262 Local_Name : Sax.Symbols.Symbol; 263 Namespace : Sax.Symbols.Symbol; 264 end record; 265 No_Node_Name : constant Node_Name_Def := 266 (Prefix => Sax.Symbols.No_Symbol, 267 Local_Name => Sax.Symbols.No_Symbol, 268 Namespace => Sax.Symbols.No_Symbol); 269 270 function Qualified_Name (N : Node_Name_Def) return DOM_String; 271 pragma Inline (Qualified_Name); 272 -- Return the qualified name of N 273 274 procedure Set_Prefix 275 (N : in out Node_Name_Def; Prefix : Sax.Symbols.Symbol); 276 pragma Inline (Set_Prefix); 277 -- Return or set the prefix of N 278 279 function From_Qualified_Name 280 (Doc : Document; 281 Symbols : Sax.Utils.Symbol_Table; 282 Name : Sax.Symbols.Symbol; 283 Namespace : Sax.Symbols.Symbol := Sax.Symbols.No_Symbol) 284 return Node_Name_Def; 285 -- Build a node name from its qualified name. This is shared if 286 -- Shared_Node_Names is True. 287 -- Symbols is the symbol table in which Name and Namespace were created. 288 289 ----------------- 290 -- Node_Record -- 291 ----------------- 292 293 type Node_Record (Node_Type : Node_Types) is record 294 Parent_Is_Owner : Boolean; 295 -- If True, the Parent node points to the owner document, not to the 296 -- real parent in the tree (which is null). 297 -- This boolean doesn't increase the size of this record, since because 298 -- of alignment issues Node_Type already occupies more space than it 299 -- really needs. 300 301 Parent : Node; 302 case Node_Type is 303 when Element_Node => 304 Name : Node_Name_Def; 305 Children : Node_List; 306 Attributes : Named_Node_Map; 307 308 when Attribute_Node => 309 Attr_Name : Node_Name_Def; 310 Attr_Value : Sax.Symbols.Symbol; 311 312 Owner_Element : Node; 313 -- Generally an Element, but it can be a Document if the attribute 314 -- hasn't been associated yet. 315 316 Is_Id : Boolean := False; 317 Specified : Boolean := False; 318 -- ??? In fact, attributes can have children (text or 319 -- entity_reference). 320 321 when Text_Node => 322 Text : DOM_String_Access; 323 324 when Cdata_Section_Node => 325 Cdata : DOM_String_Access; 326 327 when Entity_Reference_Node => 328 Entity_Reference_Name : Sax.Symbols.Symbol; 329 330 when Entity_Node => 331 Entity_Name : Sax.Symbols.Symbol; 332 -- ??? Allows children for the substitution of the entity 333 334 when Processing_Instruction_Node => 335 Target : Sax.Symbols.Symbol; 336 Pi_Data : Sax.Symbols.Symbol; 337 338 when Comment_Node => 339 Comment : DOM_String_Access; 340 341 when Document_Node => 342 Symbols : Sax.Utils.Symbol_Table; 343 -- Keep a handle on the symbol table to ensure the symbols remain 344 -- valid while the tree exists 345 346 Doc_Children : Node_List; 347 Doc_Type : Node; 348 Implementation : DOM_Implementation; 349 Ids : Nodes_Htable_Access; 350 351 when Document_Type_Node => 352 Document_Type_Name : DOM_String_Access; 353 Doc_Type_Children : Node_List; 354 355 when Document_Fragment_Node => 356 Doc_Frag_Children : Node_List; 357 358 when Notation_Node => 359 Public_ID : DOM_String_Access; 360 System_ID : DOM_String_Access; 361 end case; 362 end record; 363 364 procedure Append (List : in out Node_List; N : Node); 365 -- Insert N as the last element in List 366 367 procedure Remove (List : in out Node_List; N : Node); 368 -- Remove N from the list 369 -- N must be an element of List, this is not checked. 370 371 procedure Document_Add_Id 372 (Doc : Document; 373 Id : Sax.Symbols.Symbol; 374 Elem : Element); 375 -- Store in the document as fast access to Elem by its ID 376 377 procedure Document_Remove_Id 378 (Doc : Document; 379 Id : Sax.Symbols.Symbol); 380 -- Remove an ID associated with Elem in the fast htable access 381 382end DOM.Core; 383