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