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

210 lines
6.9 KiB
Ada

------------------------------------------------------------------------------
-- XML/Ada - An XML suite for Ada95 --
-- --
-- Copyright (C) 2005-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; use Unicode;
with Unicode.CES; use Unicode.CES;
with Ada.Unchecked_Deallocation;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Sax.Encodings; use Sax.Encodings;
package body Sax.Models is
function To_String
(Model : Element_Model) return Unicode.CES.Byte_Sequence;
-- Same as To_String, applies to an Element_Model_Ptr
---------
-- Ref --
---------
procedure Ref (Model : Content_Model) is
begin
if Model.Ref_Count /= null then
Model.Ref_Count.all := Model.Ref_Count.all + 1;
end if;
end Ref;
-----------
-- Unref --
-----------
procedure Unref (Model : in out Content_Model) is
procedure Unchecked_Free is new Ada.Unchecked_Deallocation
(Natural, Natural_Access);
begin
if Model.Ref_Count /= null
and then Model.Ref_Count.all > 0
then
Model.Ref_Count.all := Model.Ref_Count.all - 1;
if Model.Ref_Count.all = 0 then
Unchecked_Free (Model.Ref_Count);
Free (Model.Model);
end if;
end if;
end Unref;
------------------
-- Create_Model --
------------------
function Create_Model (Element : Element_Model_Ptr) return Content_Model is
begin
if Element = null then
return Unknown_Model;
else
return (Model => Element,
Ref_Count => new Natural'(1));
end if;
end Create_Model;
-----------------------
-- Get_Element_Model --
-----------------------
function Get_Element_Model
(Model : Content_Model) return Element_Model_Ptr is
begin
return Model.Model;
end Get_Element_Model;
--------------
-- Is_Mixed --
--------------
function Is_Mixed (M : Element_Model_Ptr) return Boolean is
begin
pragma Assert (M /= null);
return M.Content = Any_Of
and then M.List (M.List'First).Content = Character_Data;
end Is_Mixed;
---------------
-- To_String --
---------------
function To_String
(Model : Content_Model) return Unicode.CES.Byte_Sequence is
begin
if Model.Model = null then
return "";
else
return To_String (Model.Model.all);
end if;
end To_String;
---------------
-- To_String --
---------------
function To_String
(Model : Element_Model) return Unicode.CES.Byte_Sequence
is
Str : Unbounded_String;
begin
case Model.Content is
when Character_Data =>
return Pcdata_Sequence;
when Empty =>
return Empty_Sequence;
when Anything =>
return Any_Sequence;
when Element_Ref =>
return Sax.Symbols.Get (Model.Name).all;
when Any_Of | Sequence =>
for J in Model.List'Range loop
if Model.List (J).Content = Character_Data then
if Model.Content = Sequence
or else J /= Model.List'First
then
raise Invalid_Content_Model;
end if;
end if;
if Model.List (J).Content = Anything
or else Model.List (J).Content = Empty
then
raise Invalid_Content_Model;
end if;
Append (Str, To_String (Model.List (J).all));
if J /= Model.List'Last then
if Model.Content = Any_Of then
Append (Str, Vertical_Line_Sequence);
else
Append (Str, Comma_Sequence);
end if;
end if;
end loop;
return Opening_Parenthesis_Sequence
& To_String (Str) & Closing_Parenthesis_Sequence;
when Repeat =>
if Model.Elem.Content = Anything
or else Model.Elem.Content = Empty
then
raise Invalid_Content_Model;
end if;
if Model.Min = 0 and then Model.Max = Positive'Last then
return To_String (Model.Elem.all) & Star_Sequence;
elsif Model.Min = 0 and then Model.Max = 1 then
return To_String (Model.Elem.all) & Question_Mark_Sequence;
elsif Model.Min = 1 and then Model.Max = Positive'Last then
return To_String (Model.Elem.all) & Plus_Sign_Sequence;
else
raise Invalid_Content_Model;
end if;
end case;
end To_String;
----------
-- Free --
----------
procedure Free (Model : in out Element_Model_Ptr) is
procedure Free is new Ada.Unchecked_Deallocation
(Element_Model_Array, Element_Model_Array_Ptr);
procedure Internal is new Ada.Unchecked_Deallocation
(Element_Model, Element_Model_Ptr);
begin
if Model /= null then
case Model.Content is
when Character_Data | Anything | Empty | Element_Ref => null;
when Any_Of | Sequence =>
for J in Model.List'Range loop
Free (Model.List (J));
end loop;
Free (Model.List);
when Repeat =>
Free (Model.Elem);
end case;
Internal (Model);
end if;
end Free;
end Sax.Models;