File : g-rewdat.ads


   1 ------------------------------------------------------------------------------
   2 --                         GNAT COMPILER COMPONENTS                         --
   3 --                                                                          --
   4 --                     G N A T . R E W R I T E _ D A T A                    --
   5 --                                                                          --
   6 --                                 S p e c                                  --
   7 --                                                                          --
   8 --            Copyright (C) 2014, Free Software Foundation, Inc.            --
   9 --                                                                          --
  10 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  11 -- terms of the  GNU General Public License as published  by the Free Soft- --
  12 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  13 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  14 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  15 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  16 --                                                                          --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 -- You should have received a copy of the GNU General Public License and    --
  22 -- a copy of the GCC Runtime Library Exception along with this program;     --
  23 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  24 -- <http://www.gnu.org/licenses/>.                                          --
  25 --                                                                          --
  26 -- GNAT was originally developed  by the GNAT team at  New York University. --
  27 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  28 --                                                                          --
  29 ------------------------------------------------------------------------------
  30 
  31 --  This package can be used to rewrite data on the fly. All occurrences of a
  32 --  string (named pattern) will be replaced by another string.
  33 
  34 --  It is not necessary to load all data in memory and so this package can be
  35 --  used for large data chunks like disk files for example. The pattern is
  36 --  a standard string and not a regular expression.
  37 
  38 --  There is no dynamic allocation in the implementation.
  39 
  40 --  For example, to replace all occurrences of "Gnat" with "GNAT":
  41 
  42 --    Rewriter : Buffer := Create (Pattern => "Gnat", Value => "GNAT");
  43 
  44 --  The output procedure that will receive the rewritten data:
  45 
  46 --    procedure Do (Data : Stream_Element_Array) is
  47 --    begin
  48 --       <implementation to handle Data>
  49 --    end Do;
  50 
  51 --  Then:
  52 
  53 --    Write (Rewriter, "Let's talk about Gnat compiler", Do'Access);
  54 --    Write (Rewriter, "Gnat is an Ada compiler", Do'Access);
  55 --    Flush (Rewriter, Do'Access);
  56 
  57 --  Another possible usage is to specify a method to get the input data:
  58 
  59 --    procedure Get
  60 --      (Buffer : out Stream_Element_Array;
  61 --       Last   : out Stream_Element_Offset)
  62 --    is
  63 --    begin
  64 --       <get some data from a file, a socket, etc...>
  65 --       Last := ...
  66 --       Buffer := ...
  67 --    end Get;
  68 
  69 --  Then we can rewrite the whole file with:
  70 
  71 --    Rewrite (Rewriter, Input => Get'Access, Output => Do'Access);
  72 
  73 with Ada.Streams; use Ada.Streams;
  74 
  75 package GNAT.Rewrite_Data is
  76 
  77    type Buffer (<>) is limited private;
  78    type Buffer_Ref is access all Buffer;
  79 
  80    function Create
  81      (Pattern, Value : String;
  82       Size           : Stream_Element_Offset := 1_024) return Buffer;
  83    --  Create a rewrite buffer. Pattern is the string to be rewritten as Value.
  84    --  Size represents the size of the internal buffer used to store the data
  85    --  ready to be output. A larger buffer may improve the performance, as the
  86    --  Output routine (see Write, Rewrite below) will be called only when this
  87    --  buffer is full. Note that Size cannot be lower than Pattern'Length, and
  88    --  if this is the case, then Size value is set to Pattern'Length.
  89 
  90    function Size (B : Buffer) return Natural;
  91    --  Returns the current size of the buffer (count of Stream_Array_Element)
  92 
  93    procedure Flush
  94      (B      : in out Buffer;
  95       Output : not null access procedure (Data : Stream_Element_Array));
  96    --  Call Output for all remaining data in the buffer. The buffer is
  97    --  reset and ready for another use after this call.
  98 
  99    procedure Reset (B : in out Buffer);
 100    pragma Inline (Reset);
 101    --  Clear all data in buffer, B is ready for another use. Note that this is
 102    --  not needed after a Flush. Note: all data remaining in Buffer is lost.
 103 
 104    procedure Write
 105      (B      : in out Buffer;
 106       Data   : Stream_Element_Array;
 107       Output : not null access procedure (Data : Stream_Element_Array));
 108    --  Write Data into the buffer, call Output for any prepared data. Flush
 109    --  must be called when the last piece of Data as been sent in the Buffer.
 110 
 111    procedure Rewrite
 112      (B      : in out Buffer;
 113       Input  : not null access procedure
 114                           (Buffer : out Stream_Element_Array;
 115                            Last   : out Stream_Element_Offset);
 116       Output : not null access procedure (Data : Stream_Element_Array));
 117    --  Read data from Input, rewrite it, and then call Output. When there is
 118    --  no more data to be read from Input, Last must be set to 0. Before
 119    --  leaving this routine, call Flush above to send all remaining data to
 120    --  Output.
 121 
 122    procedure Link (From : in out Buffer; To : Buffer_Ref);
 123    --  Link two rewrite buffers. That is, all data sent to From buffer will be
 124    --  rewritten and then passed to the To rewrite buffer.
 125 
 126 private
 127 
 128    type Buffer
 129      (Size, Size_Pattern, Size_Value : Stream_Element_Offset) is
 130    limited record
 131       Buffer : Stream_Element_Array (1 .. Size);
 132       --  Fully prepared/rewritten data waiting to be output
 133 
 134       Current : Stream_Element_Array (1 .. Size_Pattern);
 135       --  Current data checked, this buffer contains every piece of data
 136       --  starting with the pattern. It means that at any point:
 137       --  Current (1 .. Pos_C) = Pattern (1 .. Pos_C).
 138 
 139       Pattern : Stream_Element_Array (1 .. Size_Pattern);
 140       --  The pattern to look for
 141 
 142       Value : Stream_Element_Array (1 .. Size_Value);
 143       --  The value the pattern is replaced by
 144 
 145       Pos_C : Stream_Element_Offset; -- last valid element in Current
 146       Pos_B : Stream_Element_Offset; -- last valid element in Buffer
 147 
 148       Next  : Buffer_Ref;
 149       --  A link to another rewriter if any
 150    end record;
 151 
 152 end GNAT.Rewrite_Data;