1----------------------------------------------------------------------- 2-- util-encoders -- Encode/Decode streams and strings from one format to another 3-- Copyright (C) 2009, 2010, 2011, 2012 Stephane Carrez 4-- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5-- 6-- Licensed under the Apache License, Version 2.0 (the "License"); 7-- you may not use this file except in compliance with the License. 8-- You may obtain a copy of the License at 9-- 10-- http://www.apache.org/licenses/LICENSE-2.0 11-- 12-- Unless required by applicable law or agreed to in writing, software 13-- distributed under the License is distributed on an "AS IS" BASIS, 14-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15-- See the License for the specific language governing permissions and 16-- limitations under the License. 17----------------------------------------------------------------------- 18with Ada.Streams; 19with Ada.Finalization; 20with Ada.Strings.Unbounded; 21with Interfaces; 22 23-- The <b>Util.Encoders</b> package defines the <b>Encoder</b> object 24-- which represents a mechanism to transform a stream from one format into 25-- another format. 26package Util.Encoders is 27 28 pragma Preelaborate; 29 30 Not_Supported : exception; 31 Encoding_Error : exception; 32 33 -- Encoder/decoder for Base64 (RFC 4648) 34 BASE_64 : constant String := "base64"; 35 36 -- Encoder/decoder for Base64 (RFC 4648) using the URL alphabet 37 -- (+ and / are replaced by - and _) 38 BASE_64_URL : constant String := "base64url"; 39 40 -- Encoder/decoder for Base16 (RFC 4648) 41 BASE_16 : constant String := "base16"; 42 HEX : constant String := "hex"; 43 44 -- Encoder for SHA1 (RFC 3174) 45 HASH_SHA1 : constant String := "sha1"; 46 47 -- ------------------------------ 48 -- Encoder context object 49 -- ------------------------------ 50 -- The <b>Encoder</b> provides operations to encode and decode 51 -- strings or stream of data from one format to another. 52 -- The <b>Encoded</b> contains two <b>Transformer</b> 53 -- which either <i>encodes</i> or <i>decodes</i> the stream. 54 type Encoder is tagged limited private; 55 56 -- Encodes the input string <b>Data</b> using the transformation 57 -- rules provided by the <b>E</b> encoder. 58 -- 59 -- Returns the encoded string. 60 -- 61 -- Raises the <b>Encoding_Error</b> exception if the source string 62 -- cannot be encoded. 63 -- Raises the <b>Not_Supported</b> exception if the encoding is not 64 -- supported. 65 function Encode (E : in Encoder; 66 Data : in String) return String; 67 68 -- Decodes the input string <b>Data</b> using the transformation 69 -- rules provided by the <b>E</b> encoder. 70 -- 71 -- Returns the encoded string. 72 -- 73 -- Raises the <b>Encoding_Error</b> exception if the source string 74 -- cannot be decoded. 75 -- Raises the <b>Not_Supported</b> exception if the decoding is not 76 -- supported. 77 function Decode (E : in Encoder; 78 Data : in String) return String; 79 80 -- Create the encoder object for the specified encoding format. 81 function Create (Name : String) return Encoder; 82 83 -- ------------------------------ 84 -- Stream Transformation interface 85 -- ------------------------------ 86 -- The <b>Transformer</b> interface defines the operation to transform 87 -- a stream from one data format to another. 88 type Transformer is limited interface; 89 type Transformer_Access is access all Transformer'Class; 90 91 -- Transform the input stream represented by <b>Data</b> into 92 -- the output stream <b>Into</b>. The transformation made by 93 -- the object can be of any nature (Hex encoding, Base64 encoding, 94 -- Hex decoding, Base64 decoding, ...). 95 -- 96 -- If the transformer does not have enough room to write the result, 97 -- it must return in <b>Encoded</b> the index of the last encoded 98 -- position in the <b>Data</b> stream. 99 -- 100 -- The transformer returns in <b>Last</b> the last valid position 101 -- in the output stream <b>Into</b>. 102 -- 103 -- The <b>Encoding_Error</b> exception is raised if the input 104 -- stream cannot be transformed. 105 procedure Transform (E : in Transformer; 106 Data : in Ada.Streams.Stream_Element_Array; 107 Into : out Ada.Streams.Stream_Element_Array; 108 Last : out Ada.Streams.Stream_Element_Offset; 109 Encoded : out Ada.Streams.Stream_Element_Offset) is abstract; 110 111 procedure Transform (E : in Transformer; 112 Data : in String; 113 Result : out Ada.Strings.Unbounded.Unbounded_String) is null; 114 115 -- Transform the input string <b>Data</b> using the transformation 116 -- rules provided by the <b>E</b> transformer. 117 -- 118 -- Returns the transformed string. 119 -- 120 -- Raises the <b>Encoding_Error</b> exception if the source string 121 -- cannot be transformed 122 function Transform (E : in Transformer'Class; 123 Data : in String) return String; 124 125 -- Transform the input string <b>Data</b> using the transformation 126 -- rules provided by the <b>E</b> transformer. 127 -- 128 -- Returns the transformed string. 129 -- 130 -- Raises the <b>Encoding_Error</b> exception if the source string 131 -- cannot be transformed 132 function Transform (E : in Transformer'Class; 133 Data : in Ada.Streams.Stream_Element_Array) return String; 134 135 -- Encode the value represented by <tt>Val</tt> in the stream array <tt>Into</tt> starting 136 -- at position <tt>Pos</tt> in that array. The value is encoded using LEB128 format, 7-bits 137 -- at a time until all non zero bits are written. The <tt>Last</tt> parameter is updated 138 -- to indicate the position of the last valid byte written in <tt>Into</tt>. 139 procedure Encode_LEB128 (Into : in out Ada.Streams.Stream_Element_Array; 140 Pos : in Ada.Streams.Stream_Element_Offset; 141 Val : in Interfaces.Unsigned_64; 142 Last : out Ada.Streams.Stream_Element_Offset); 143 144 -- Decode from the byte array <tt>From</tt> the value represented as LEB128 format starting 145 -- at position <tt>Pos</tt> in that array. After decoding, the <tt>Last</tt> index is updated 146 -- to indicate the last position in the byte array. 147 procedure Decode_LEB128 (From : in Ada.Streams.Stream_Element_Array; 148 Pos : in Ada.Streams.Stream_Element_Offset; 149 Val : out Interfaces.Unsigned_64; 150 Last : out Ada.Streams.Stream_Element_Offset); 151 152private 153 154 type Encoder is new Ada.Finalization.Limited_Controlled with record 155 Encode : Transformer_Access := null; 156 Decode : Transformer_Access := null; 157 end record; 158 159 -- Delete the transformers 160 overriding 161 procedure Finalize (E : in out Encoder); 162 163end Util.Encoders; 164