Files
xmlada/dom/dom-core.adb
Emmanuel Briot 53dc51bf5c Update copyright notices
Change-Id: Iae1283292b460ead48dedc565d6f24259e497e69
2017-01-03 10:02:38 +01:00

264 lines
8.1 KiB
Ada

------------------------------------------------------------------------------
-- XML/Ada - An XML suite for Ada95 --
-- --
-- Copyright (C) 2001-2017, AdaCore --
-- --
-- This library is free software; you can redistribute it and/or modify it --
-- under terms of the GNU General Public License as published by the Free --
-- Software Foundation; either version 3, or (at your option) any later --
-- version. This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
------------------------------------------------------------------------------
with Unicode.CES; use Unicode.CES;
with Sax.Encodings; use Sax.Encodings;
with Unicode.Names.Basic_Latin; use Unicode.Names.Basic_Latin;
with Unicode; use Unicode;
with Sax.Symbols; use Sax.Symbols;
with Sax.Utils; use Sax.Utils;
package body DOM.Core is
use Nodes_Htable, Symbol_Table_Pointers;
Node_List_Growth_Factor : Float := Default_Node_List_Growth_Factor;
---------------------------------
-- Set_Node_List_Growth_Factor --
---------------------------------
procedure Set_Node_List_Growth_Factor (Factor : Float) is
begin
Node_List_Growth_Factor := Factor;
end Set_Node_List_Growth_Factor;
---------------------
-- Create_Document --
---------------------
function Create_Document
(Implementation : DOM_Implementation;
NameSpace_URI : DOM_String := "";
Qualified_Name : DOM_String := "";
Doc_Type : Node := null;
Symbols : Sax.Utils.Symbol_Table := Sax.Utils.No_Symbol_Table)
return Node
is
pragma Warnings (Off, NameSpace_URI);
pragma Warnings (Off, Qualified_Name);
Sym : Sax.Utils.Symbol_Table := Symbols;
Tmp : Symbol_Table_Access;
begin
pragma Assert
(Doc_Type = null or else Doc_Type.Node_Type = Document_Type_Node);
if Sym = No_Symbol_Table then
Tmp := new Symbol_Table_Record;
Sym := Symbol_Table_Pointers.Allocate (Tmp);
end if;
return new Node_Record'
(Node_Type => Document_Node,
Parent => null,
Doc_Children => Null_List,
Doc_Type => Doc_Type,
Parent_Is_Owner => False,
Implementation => Implementation,
Ids => null,
Symbols => Sym);
end Create_Document;
-----------------
-- Has_Feature --
-----------------
function Has_Feature
(Implementation : DOM_Implementation;
Feature : DOM_String;
Version : String := "2.0") return Boolean
is
pragma Warnings (Off, Implementation);
begin
return Feature = "XML" and then Version = "2.0";
end Has_Feature;
------------
-- Append --
------------
procedure Append (List : in out Node_List; N : Node) is
Old : Node_Array_Access := List.Items;
begin
if Old = null or else Old'Last = List.Last then
List.Items := new Node_Array
(0 .. List.Last + 1
+ (Integer'Max (0,
Integer (Float (List.Last) * Node_List_Growth_Factor))));
if Old /= null then
List.Items (0 .. List.Last) := Old.all;
Free (Old);
end if;
end if;
List.Last := List.Last + 1;
List.Items (List.Last) := N;
end Append;
------------
-- Remove --
------------
procedure Remove (List : in out Node_List; N : Node) is
begin
if List.Items = null or else List.Last = 0 then
Free (List.Items);
List.Last := -1;
else
for J in 0 .. List.Last loop
if List.Items (J) = N then
List.Items (J .. List.Last - 1) :=
List.Items (J + 1 .. List.Last);
List.Last := List.Last - 1;
return;
end if;
end loop;
end if;
end Remove;
----------
-- Free --
----------
procedure Free (List : in out Node_List) is
begin
Free (List.Items);
end Free;
--------------------
-- Qualified_Name --
--------------------
function Qualified_Name (N : Node_Name_Def) return DOM_String is
begin
pragma Assert (N.Local_Name /= No_Symbol);
if N.Prefix = No_Symbol or N.Prefix = Empty_String then
return Get (N.Local_Name).all;
else
return Get (N.Prefix).all & Colon_Sequence & Get (N.Local_Name).all;
end if;
end Qualified_Name;
----------------
-- Set_Prefix --
----------------
procedure Set_Prefix (N : in out Node_Name_Def; Prefix : Symbol) is
begin
-- ??? We're supposed to check that Prefix is valid, and raise
-- Invalid_Character_Err otherwise
N.Prefix := Prefix;
end Set_Prefix;
-------------------------
-- From_Qualified_Name --
-------------------------
function From_Qualified_Name
(Doc : Document;
Symbols : Sax.Utils.Symbol_Table;
Name : Sax.Symbols.Symbol;
Namespace : Sax.Symbols.Symbol := Sax.Symbols.No_Symbol)
return Node_Name_Def
is
N : constant Cst_Byte_Sequence_Access := Get (Name);
Index : Natural := N'First;
Colon_Pos : Natural;
C : Unicode_Char := 0;
begin
-- ??? Test for Invalid_Character_Err
-- ??? Must convert Tag_Name to uppercase for HTML documents
-- ??? Test for Namespace_Err
while Index <= N'Last loop
Colon_Pos := Index;
Encoding.Read (N.all, Index, C);
exit when C = Colon;
end loop;
if C = Colon then
return
(Prefix => Find (Doc.Symbols, N (N'First .. Colon_Pos - 1)),
Local_Name => Find (Doc.Symbols, N (Index .. N'Last)),
Namespace => Namespace);
elsif Symbols /= Doc.Symbols then
return
(Prefix => Find (Doc.Symbols, Get (Name).all),
Local_Name => Find (Doc.Symbols, Get (Namespace).all),
Namespace => Namespace);
else
return
(Prefix => No_Symbol,
Local_Name => Name,
Namespace => Namespace);
end if;
end From_Qualified_Name;
----------
-- Free --
----------
procedure Free (N : in out Node_String) is
pragma Unreferenced (N);
begin
null;
end Free;
-------------
-- Get_Key --
-------------
function Get_Key (N : Node_String) return Symbol is
begin
return N.Key;
end Get_Key;
---------------------
-- Document_Add_Id --
---------------------
procedure Document_Add_Id
(Doc : Document;
Id : Symbol;
Elem : Element) is
begin
if Doc.Ids = null then
Doc.Ids := new Nodes_Htable.HTable (203);
end if;
Set (Doc.Ids.all, (N => Node (Elem), Key => Id));
end Document_Add_Id;
------------------------
-- Document_Remove_Id --
------------------------
procedure Document_Remove_Id
(Doc : Document;
Id : Symbol) is
begin
if Doc.Ids /= null then
Remove (Doc.Ids.all, Id);
end if;
end Document_Remove_Id;
end DOM.Core;