1------------------------------------------------------------------------
2--                                                                    --
3--                     McKae Software Utilities                       --
4--                                                                    --
5--           Copyright (C) 2005 McKae Technologies                    --
6--                                                                    --
7-- The  McKae   software  utilities   are  free  software;   you  can --
8-- redistribute it  and/or modify it  under terms of the  GNU General --
9-- Public  License  as published  by  the  Free Software  Foundation; --
10-- either version  2, or (at  your option) any later  version.  McKae --
11-- Software Utilities are  distributed in the hope that  they will be --
12-- useful,  but  WITHOUT  ANY  WARRANTY;  without  even  the  implied --
13-- warranty of  MERCHANTABILITY or FITNESS FOR  A PARTICULAR PURPOSE. --
14-- See the GNU  General Public License for more  details.  You should --
15-- have received a copy of the GNU General Public License distributed --
16-- with DTraq; see file COPYING.   If not, write to the Free Software --
17-- Foundation, 59  Temple Place -  Suite 330, Boston,  MA 02111-1307, --
18-- USA.                                                               --
19--                                                                    --
20-- As a  special exception, if other files  instantiate generics from --
21-- this unit,  or you link this  unit with other files  to produce an --
22-- executable,  this unit  does  not by  itself  cause the  resulting --
23-- executable to be covered by  the GNU General Public License.  This --
24-- exception does  not however invalidate  any other reasons  why the --
25-- executable file might be covered by the GNU Public License.        --
26--                                                                    --
27-- The McKae Software Utilities  are maintained by McKae Technologies --
28-- (http://www.mckae.com).                                            --
29------------------------------------------------------------------------
30
31with McKae.XML.EZ_Out.Generic_Medium;
32with Ada.Text_IO; use Ada.Text_IO;
33
34package McKae.XML.EZ_Out.String_Stream is
35
36   --  A basic in-memory string-based XML document construction
37   --  utility.  This is not intended to be a robust, full-function
38   --  memory buffering package.
39
40   ---------------------------------------------------------------------------
41
42   --  This nested package provides a basic string-based buffering
43   --  capability.  The purpose of the EZ_Out String_Stream package is
44   --  to provide a simple means of constructing an XML document in a
45   --  memory buffer.  To do this, a memory buffering capability was
46   --  needed--there were three approaches:
47   --
48   --  o Locate and employ an existing memory buffering component,
49   --  modifying it as needed to provide the required Put and New_Line
50   --  functions
51   --  o Write a McKae component to do memory buffering and reference
52   --  it in this package.
53   --  o Embed a memory buffering capability within the String_Stream
54   --  package.
55   --
56   --  The first option was discarded not because there's anything
57   --  wrong with existing memory buffer components, but rather
58   --  because of questions about which one should be chosen, what are
59   --  its distribution and modification requirements, and so on.  The
60   --  truth of the matter is that this approach is what a project
61   --  using EZ_Out for a project actually ought to do--take their
62   --  memory buffering capability, enhance it with Put and New_Line
63   --  functionality, and then instantiate EZ_Out.Generic_Medium with
64   --  it.
65   --
66   --  The second option was discarded because the focus of EZ_Out is
67   --  on XML document generation, not providing a general purpose
68   --  memory buffering component.  While a limited capability one
69   --  could have been created, it would be over-specific to EZ_Out
70   --  and its (intentional) limitations would distract from its
71   --  intended use as an EZ_Out adjunct package.
72   --
73   --  This left the third option.  By embedding the above-mentioned
74   --  limited capability memory buffering capability within
75   --  String_Stream, it's clearly associated as just an aspect of the
76   --  String_Stream implementation, as any relevant capabilities
77   --  are simply exported by the String_Stream package.
78
79   package String_Buffering is
80
81      --  There's little point in having a small buffer for building XML
82      --  documents, so the minimum size and expansion is 500 characters.
83
84      subtype Buffer_Size_Range is Positive range 500 .. Positive'Last;
85
86      type String_Buffer
87        (Initial_Size : Buffer_Size_Range := 5000;
88         Expansion    : Buffer_Size_Range := 5000) is limited private;
89
90      --  Copy the given string into the buffer, expanding it if needed.
91      procedure Put (F : String_Buffer; S : String);
92
93      --  Insert a new line indicator into the buffer.  However, in
94      --  this case do nothing, since this buffering package is being
95      --  instantiated for Continuous_Stream formatting.
96      procedure New_Line
97        (F : String_Buffer;
98         Spacing : Ada.Text_IO.Positive_Count := 1);
99
100      --  Clear the buffer. Note that this does not free any allocated
101      --  resources.
102      procedure Clear (S : String_Buffer);
103
104      --  Return the current contents of the string buffer
105      function Get_String (S : String_Buffer) return String;
106
107   private
108
109      --  Handle to the buffer
110      type Buffer_Ptr is access all String;
111
112      --  String buffer self-access ("Rosen Trick");
113
114      type String_Self_Access
115        (SB : access String_Buffer) is limited null record;
116
117      --  String buffer type definition.  By default, a newly created
118      --  string buffer is initialized to be empty.
119
120      type String_Buffer
121        (Initial_Size : Buffer_Size_Range := 5000;
122         Expansion    : Buffer_Size_Range := 5000) is limited record
123         Allocation   : Buffer_Size_Range := Initial_Size;
124         Size         : Natural           := 0;
125         Buff         : Buffer_Ptr        := new String (1 .. Initial_Size);
126         Self : String_Self_Access (String_Buffer'Access);
127      end record;
128   end String_Buffering;
129
130   ---------------------------------------------------------------------------
131
132   subtype Buffer_Size_Range is String_Buffering.Buffer_Size_Range;
133
134   subtype String_Buffer is String_Buffering.String_Buffer;
135
136   --  Clear the buffer. Note that this does not free any allocated
137   --  resources.
138   procedure Clear (S : String_Buffer) renames String_Buffering.Clear;
139
140   --  Return the current contents of the string buffer
141   function Get_String
142     (S : String_Buffer) return String renames
143     String_Buffering.Get_String;
144
145   ---------------------------------------------------------------------------
146
147   --  "Use" this XML_String_Buffer package for constructing an EZ_Out
148   --  XML document.
149   package XML_String_Buffer is new McKae.XML.EZ_Out.Generic_Medium
150     (Output_Medium => String_Buffering.String_Buffer,
151      Put           => String_Buffering.Put,
152      New_Line      => String_Buffering.New_Line,
153      Format        => Continuous_Stream);
154
155   ---------------------------------------------------------------------------
156
157end McKae.XML.EZ_Out.String_Stream;
158