------------------------------------------------------------------------------ -- 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 -- -- . -- -- -- ------------------------------------------------------------------------------ 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;