-----------------------------------------------------------------------
--  awa-permissions-services -- Permissions controller
--  Copyright (C) 2011 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with AWA.Applications;

with ADO;
with ADO.Sessions;
with ADO.Objects;

with Security.Permissions;
with Security.Contexts;
package AWA.Permissions.Services is

   type Permission_Manager is new Security.Permissions.Permission_Manager with private;
   type Permission_Manager_Access is access all Permission_Manager'Class;

   --  Get the permission manager associated with the security context.
   --  Returns null if there is none.
   function Get_Permission_Manager (Context : in Security.Contexts.Security_Context'Class)
                                    return Permission_Manager_Access;

   --  Get the application instance.
   function Get_Application (Manager : in Permission_Manager)
                             return AWA.Applications.Application_Access;

   --  Set the application instance.
   procedure Set_Application (Manager : in out Permission_Manager;
                              App : in AWA.Applications.Application_Access);

   --  Add a permission for the current user to access the entity identified by
   --  Entity and Kind.
   procedure Add_Permission (Manager    : in Permission_Manager;
                             Entity     : in ADO.Identifier;
                             Kind       : in ADO.Entity_Type;
                             Permission : in Permission_Type);

   --  Check that the current user has the specified permission.
   --  Raise NO_PERMISSION exception if the user does not have the permission.
   procedure Check_Permission (Manager    : in Permission_Manager;
                               Entity     : in ADO.Identifier;
                               Kind       : in ADO.Entity_Type;
                               Permission : in Permission_Type);
   --  Read the policy file
   overriding
   procedure Read_Policy (Manager : in out Permission_Manager;
                          File    : in String);

   --  Add a permission for the user User to access the entity identified by
   --  Entity which is of type Kind.
   procedure Add_Permission (Session    : in out ADO.Sessions.Master_Session;
                             User       : in ADO.Identifier;
                             Entity     : in ADO.Identifier;
                             Kind       : in ADO.Entity_Type;
                             Permission : in Permission_Type := READ);

   --  Add a permission for the user User to access the entity identified by
   --  Entity.
   procedure Add_Permission (Session    : in out ADO.Sessions.Master_Session;
                             User       : in ADO.Identifier;
                             Entity     : in ADO.Objects.Object_Ref'Class;
                             Permission : in Permission_Type := READ);

   --  Create a permission manager for the given application.
   function Create_Permission_Manager (App : in AWA.Applications.Application_Access)
                                       return Security.Permissions.Permission_Manager_Access;

private

   type Permission_Manager is new Security.Permissions.Permission_Manager with record
      App : AWA.Applications.Application_Access := null;
   end record;

end AWA.Permissions.Services;

-----------------------------------------------------------------------
--  awa-permissions-services -- Permissions controller
--  Copyright (C) 2011, 2012 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with AWA.Applications;

with ADO;
with ADO.Sessions;
with ADO.Objects;

with Security.Policies;
with Security.Contexts;
package AWA.Permissions.Services is

   type Permission_Manager is new Security.Policies.Policy_Manager with private;
   type Permission_Manager_Access is access all Permission_Manager'Class;

   --  Get the permission manager associated with the security context.
   --  Returns null if there is none.
   function Get_Permission_Manager (Context : in Security.Contexts.Security_Context'Class)
                                    return Permission_Manager_Access;

   --  Get the application instance.
   function Get_Application (Manager : in Permission_Manager)
                             return AWA.Applications.Application_Access;

   --  Set the application instance.
   procedure Set_Application (Manager : in out Permission_Manager;
                              App : in AWA.Applications.Application_Access);

   --  Add a permission for the current user to access the entity identified by
   --  Entity and Kind.
   procedure Add_Permission (Manager    : in Permission_Manager;
                             Entity     : in ADO.Identifier;
                             Kind       : in ADO.Entity_Type;
                             Permission : in Permission_Type);

   --  Check that the current user has the specified permission.
   --  Raise NO_PERMISSION exception if the user does not have the permission.
   procedure Check_Permission (Manager    : in Permission_Manager;
                               Entity     : in ADO.Identifier;
                               Kind       : in ADO.Entity_Type;
                               Permission : in Permission_Type);
   --  Read the policy file
   overriding
   procedure Read_Policy (Manager : in out Permission_Manager;
                          File    : in String);

   --  Add a permission for the user User to access the entity identified by
   --  Entity which is of type Kind.
   procedure Add_Permission (Session    : in out ADO.Sessions.Master_Session;
                             User       : in ADO.Identifier;
                             Entity     : in ADO.Identifier;
                             Kind       : in ADO.Entity_Type;
                             Permission : in Permission_Type := READ);

   --  Add a permission for the user User to access the entity identified by
   --  Entity.
   procedure Add_Permission (Session    : in out ADO.Sessions.Master_Session;
                             User       : in ADO.Identifier;
                             Entity     : in ADO.Objects.Object_Ref'Class;
                             Permission : in Permission_Type := READ);

   --  Create a permission manager for the given application.
   function Create_Permission_Manager (App : in AWA.Applications.Application_Access)
                                       return Security.Policies.Policy_Manager_Access;

private

   type Permission_Manager is new Security.Policies.Policy_Manager with record
      App : AWA.Applications.Application_Access := null;
   end record;

end AWA.Permissions.Services;

Use the Security.Policies package

Use the Security.Policies package


-----------------------------------------------------------------------
--  mat-memory-tools - Tools for memory maps
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

package body MAT.Memory.Tools is

   --  ------------------------------
   --  Collect the information about memory slot sizes for the memory slots in the map.
   --  ------------------------------
   procedure Size_Information (Memory : in MAT.Memory.Allocation_Map;
                               Sizes  : in out Size_Info_Map) is
      Iter : Allocation_Cursor := Memory.First;

      procedure Update_Count (Size : in MAT.Types.Target_Size;
                              Info : in out Size_Info_Type) is
      begin
         Info.Count := Info.Count + 1;
      end Update_Count;

      procedure Collect (Addr : in MAT.Types.Target_Addr;
                         Slot : in Allocation) is
         Pos : Size_Info_Cursor := Sizes.Find (Slot.Size);
      begin
         if Size_Info_Maps.Has_Element (Pos) then
            Sizes.Update_Element (Pos, Update_Count'Access);
         else
            declare
               Info : Size_Info_Type;
            begin
               Info.Count := 1;
               Sizes.Insert (Slot.Size, Info);
            end;
         end if;
      end Collect;

   begin
      while Allocation_Maps.Has_Element (Iter) loop
         Allocation_Maps.Query_Element (Iter, Collect'Access);
         Allocation_Maps.Next (Iter);
      end loop;
   end Size_Information;

   --  ------------------------------
   --  Find from the <tt>Memory</tt> map the memory slots whose address intersects
   --  the region [From .. To] and add the memory slot in the <tt>Into</tt> list if
   --  it does not already contains the memory slot.
   --  ------------------------------
   procedure Find (Memory : in MAT.Memory.Allocation_Map;
                   From   : in MAT.Types.Target_Addr;
                   To     : in MAT.Types.Target_Addr;
                   Into   : in out MAT.Memory.Allocation_Map) is
      Iter : MAT.Memory.Allocation_Cursor := Memory.Ceiling (From);
      Pos  : MAT.Memory.Allocation_Cursor;
      Addr : MAT.Types.Target_Addr;
      Size : MAT.Types.Target_Size;
   begin
      --  If there was no slot with the ceiling From address, we have to start from the last
      --  node because the memory slot may intersect our region.
      if not Allocation_Maps.Has_Element (Iter) then
         Iter := Memory.Last;
         if not Allocation_Maps.Has_Element (Iter) then
            return;
         end if;
         Addr := Allocation_Maps.Key (Iter);
         Size := Allocation_Maps.Element (Iter).Size;
         if Addr + Size < From then
            return;
         end if;
      end if;

      --  Move backward until the previous memory slot does not overlap anymore our region.
      --  In theory, going backward once is enough but if there was a target malloc issue,
      --  several malloc may overlap the same region (which is bad for the target).
      loop
         Pos := Allocation_Maps.Previous (Iter);
         exit when not Allocation_Maps.Has_Element (Pos);
         Addr := Allocation_Maps.Key (Pos);
         Size := Allocation_Maps.Element (Pos).Size;
         exit when Addr + Size < From;
         Iter := Pos;
      end loop;

      --  Add the memory slots until we moved to the end of the region.
      while Allocation_Maps.Has_Element (Iter) loop
         Addr := Allocation_Maps.Key (Iter);
         exit when Addr > To;
         Pos := Into.Find (Addr);
         if not Allocation_Maps.Has_Element (Pos) then
            Into.Insert (Addr, Allocation_Maps.Element (Iter));
         end if;
         Allocation_Maps.Next (Iter);
      end loop;
   end Find;

end MAT.Memory.Tools;

-----------------------------------------------------------------------
--  mat-memory-tools - Tools for memory maps
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

package body MAT.Memory.Tools is

   --  ------------------------------
   --  Collect the information about memory slot sizes for the memory slots in the map.
   --  ------------------------------
   procedure Size_Information (Memory : in MAT.Memory.Allocation_Map;
                               Sizes  : in out Size_Info_Map) is
      procedure Update_Count (Size : in MAT.Types.Target_Size;
                              Info : in out Size_Info_Type);
      procedure Collect (Addr : in MAT.Types.Target_Addr;
                         Slot : in Allocation);

      procedure Update_Count (Size : in MAT.Types.Target_Size;
                              Info : in out Size_Info_Type) is
         pragma Unreferenced (Size);
      begin
         Info.Count := Info.Count + 1;
      end Update_Count;

      procedure Collect (Addr : in MAT.Types.Target_Addr;
                         Slot : in Allocation) is
         pragma Unreferenced (Addr);

         Pos : constant Size_Info_Cursor := Sizes.Find (Slot.Size);
      begin
         if Size_Info_Maps.Has_Element (Pos) then
            Sizes.Update_Element (Pos, Update_Count'Access);
         else
            declare
               Info : Size_Info_Type;
            begin
               Info.Count := 1;
               Sizes.Insert (Slot.Size, Info);
            end;
         end if;
      end Collect;

      Iter : Allocation_Cursor := Memory.First;

   begin
      while Allocation_Maps.Has_Element (Iter) loop
         Allocation_Maps.Query_Element (Iter, Collect'Access);
         Allocation_Maps.Next (Iter);
      end loop;
   end Size_Information;

   --  ------------------------------
   --  Find from the <tt>Memory</tt> map the memory slots whose address intersects
   --  the region [From .. To] and add the memory slot in the <tt>Into</tt> list if
   --  it does not already contains the memory slot.
   --  ------------------------------
   procedure Find (Memory : in MAT.Memory.Allocation_Map;
                   From   : in MAT.Types.Target_Addr;
                   To     : in MAT.Types.Target_Addr;
                   Into   : in out MAT.Memory.Allocation_Map) is
      Iter : MAT.Memory.Allocation_Cursor := Memory.Ceiling (From);
      Pos  : MAT.Memory.Allocation_Cursor;
      Addr : MAT.Types.Target_Addr;
      Size : MAT.Types.Target_Size;
   begin
      --  If there was no slot with the ceiling From address, we have to start from the last
      --  node because the memory slot may intersect our region.
      if not Allocation_Maps.Has_Element (Iter) then
         Iter := Memory.Last;
         if not Allocation_Maps.Has_Element (Iter) then
            return;
         end if;
         Addr := Allocation_Maps.Key (Iter);
         Size := Allocation_Maps.Element (Iter).Size;
         if Addr + Size < From then
            return;
         end if;
      end if;

      --  Move backward until the previous memory slot does not overlap anymore our region.
      --  In theory, going backward once is enough but if there was a target malloc issue,
      --  several malloc may overlap the same region (which is bad for the target).
      loop
         Pos := Allocation_Maps.Previous (Iter);
         exit when not Allocation_Maps.Has_Element (Pos);
         Addr := Allocation_Maps.Key (Pos);
         Size := Allocation_Maps.Element (Pos).Size;
         exit when Addr + Size < From;
         Iter := Pos;
      end loop;

      --  Add the memory slots until we moved to the end of the region.
      while Allocation_Maps.Has_Element (Iter) loop
         Addr := Allocation_Maps.Key (Iter);
         exit when Addr > To;
         Pos := Into.Find (Addr);
         if not Allocation_Maps.Has_Element (Pos) then
            Into.Insert (Addr, Allocation_Maps.Element (Iter));
         end if;
         Allocation_Maps.Next (Iter);
      end loop;
   end Find;

end MAT.Memory.Tools;

Fix compilation warnings

Fix compilation warnings


-----------------------------------------------------------------------
--  ado.schemas -- Database Schemas
--  Copyright (C) 2009, 2010, 2018 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Unchecked_Deallocation;
with Ada.Strings.Equal_Case_Insensitive;
package body ADO.Schemas is

   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Column,
                                 Name   => Column_Definition);
   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Table,
                                 Name   => Table_Definition);
   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Schema,
                                 Name   => Schema_Access);

   --  ------------------------------
   --  Get the hash value associated with the class mapping.
   --  ------------------------------
   function Hash (Mapping : Class_Mapping_Access) return Ada.Containers.Hash_Type is
   begin
      if Mapping = null then
         return 0;
      else
         return Util.Strings.Hash (Mapping.Table);
      end if;
   end Hash;

   --  ------------------------------
   --  Column Representation
   --  ------------------------------

   --  ------------------------------
   --  Get the column name
   --  ------------------------------
   function Get_Name (Column : Column_Definition) return String is
   begin
      return To_String (Column.Name);
   end Get_Name;

   --  ------------------------------
   --  Get the column type
   --  ------------------------------
   function Get_Type (Column : Column_Definition) return Column_Type is
   begin
      return Column.Col_Type;
   end Get_Type;

   --  ------------------------------
   --  Get the default column value
   --  ------------------------------
   function Get_Default (Column : Column_Definition) return String is
   begin
      return To_String (Column.Default);
   end Get_Default;

   --  ------------------------------
   --  Get the column collation (for string based columns)
   --  ------------------------------
   function Get_Collation (Column : Column_Definition) return String is
   begin
      return To_String (Column.Collation);
   end Get_Collation;

   --  ------------------------------
   --  Check whether the column can be null
   --  ------------------------------
   function Is_Null (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Null;
   end Is_Null;

   --  ------------------------------
   --  Check whether the column is an unsigned number
   --  ------------------------------
   function Is_Unsigned (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Unsigned;
   end Is_Unsigned;

   --  ------------------------------
   --  Returns true if the column can hold a binary string
   --  ------------------------------
   function Is_Binary (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Binary;
   end Is_Binary;

   --  ------------------------------
   --  Get the column length
   --  ------------------------------
   function Get_Size (Column : Column_Definition) return Natural is
   begin
      return Column.Size;
   end Get_Size;

   --  ------------------------------
   --  Column iterator
   --  ------------------------------

   --  ------------------------------
   --  Returns true if the iterator contains more column
   --  ------------------------------
   function Has_Element (Cursor : Column_Cursor) return Boolean is
   begin
      return Cursor.Current /= null;
   end Has_Element;

   --  ------------------------------
   --  Move to the next column
   --  ------------------------------
   procedure Next (Cursor : in out Column_Cursor) is
   begin
      if Cursor.Current /= null then
         Cursor.Current := Cursor.Current.Next_Column;
      end if;
   end Next;

   --  ------------------------------
   --  Get the current column definition
   --  ------------------------------
   function Element (Cursor : Column_Cursor) return Column_Definition is
   begin
      return Cursor.Current;
   end Element;

   --  ------------------------------
   --  Table Representation
   --  ------------------------------

   --  ------------------------------
   --  Get the table name
   --  ------------------------------
   function Get_Name (Table : Table_Definition) return String is
   begin
      return To_String (Table.Name);
   end Get_Name;

   --  ------------------------------
   --  Get the column iterator
   --  ------------------------------
   function Get_Columns (Table : Table_Definition) return Column_Cursor is
   begin
      return Column_Cursor '(Current => Table.First_Column);
   end Get_Columns;

   --  ------------------------------
   --  Find the column having the given name
   --  ------------------------------
   function Find_Column (Table : Table_Definition;
                         Name  : String) return Column_Definition is
      Column : Column_Definition := Table.First_Column;
   begin
      while Column /= null loop
         if Ada.Strings.Equal_Case_Insensitive (To_String (Column.Name), Name) then
            return Column;
         end if;
         Column := Column.Next_Column;
      end loop;
      return null;
   end Find_Column;

   --  ------------------------------
   --  Table iterator
   --  ------------------------------

   --  ------------------------------
   --  Returns true if the iterator contains more tables
   --  ------------------------------
   function Has_Element (Cursor : Table_Cursor) return Boolean is
   begin
      return Cursor.Current /= null;
   end Has_Element;

   --  ------------------------------
   --  Move to the next column
   --  ------------------------------
   procedure Next (Cursor : in out Table_Cursor) is
   begin
      if Cursor.Current /= null then
         Cursor.Current := Cursor.Current.Next_Table;
      end if;
   end Next;

   --  ------------------------------
   --  Get the current table definition
   --  ------------------------------
   function Element (Cursor : Table_Cursor) return Table_Definition is
   begin
      return Cursor.Current;
   end Element;

   --  ------------------------------
   --  Database Schema
   --  ------------------------------

   --  ------------------------------
   --  Find a table knowing its name
   --  ------------------------------
   function Find_Table (Schema : Schema_Definition;
                        Name   : String) return Table_Definition is
      Table : Table_Definition;
   begin
      if Schema.Schema /= null then
         Table := Schema.Schema.First_Table;
         while Table /= null loop
            if Ada.Strings.Equal_Case_Insensitive (To_String (Table.Name), Name) then
               return Table;
            end if;
            Table := Table.Next_Table;
         end loop;
      end if;
      return null;
   end Find_Table;

   function Get_Tables (Schema : Schema_Definition) return Table_Cursor is
   begin
      if Schema.Schema = null then
         return Table_Cursor '(Current => null);
      else
         return Table_Cursor '(Current => Schema.Schema.First_Table);
      end if;
   end Get_Tables;

   procedure Finalize (Schema : in out Schema_Definition) is
   begin
      if Schema.Schema /= null then
         declare
            Table : Table_Definition;
            Column : Column_Definition;
         begin
            loop
               Table := Schema.Schema.First_Table;
               exit when Table = null;
               loop
                  Column := Table.First_Column;
                  exit when Column = null;
                  Table.First_Column := Column.Next_Column;
                  Free (Column);
               end loop;
               Schema.Schema.First_Table := Table.Next_Table;
               Free (Table);
            end loop;
         end;
         Free (Schema.Schema);
      end if;
   end Finalize;

end ADO.Schemas;

-----------------------------------------------------------------------
--  ado.schemas -- Database Schemas
--  Copyright (C) 2009, 2010, 2018 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Unchecked_Deallocation;
with Ada.Strings.Equal_Case_Insensitive;
package body ADO.Schemas is

   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Column,
                                 Name   => Column_Definition);
   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Table,
                                 Name   => Table_Definition);
   procedure Free is new
     Ada.Unchecked_Deallocation (Object => Schema,
                                 Name   => Schema_Access);

   --  ------------------------------
   --  Get the hash value associated with the class mapping.
   --  ------------------------------
   function Hash (Mapping : Class_Mapping_Access) return Ada.Containers.Hash_Type is
   begin
      if Mapping = null then
         return 0;
      else
         return Util.Strings.Hash (Mapping.Table);
      end if;
   end Hash;

   --  ------------------------------
   --  Column Representation
   --  ------------------------------

   --  ------------------------------
   --  Get the column name
   --  ------------------------------
   function Get_Name (Column : Column_Definition) return String is
   begin
      return To_String (Column.Name);
   end Get_Name;

   --  ------------------------------
   --  Get the column type
   --  ------------------------------
   function Get_Type (Column : Column_Definition) return Column_Type is
   begin
      return Column.Col_Type;
   end Get_Type;

   --  ------------------------------
   --  Get the default column value
   --  ------------------------------
   function Get_Default (Column : Column_Definition) return String is
   begin
      return To_String (Column.Default);
   end Get_Default;

   --  ------------------------------
   --  Get the column collation (for string based columns)
   --  ------------------------------
   function Get_Collation (Column : Column_Definition) return String is
   begin
      return To_String (Column.Collation);
   end Get_Collation;

   --  ------------------------------
   --  Check whether the column can be null
   --  ------------------------------
   function Is_Null (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Null;
   end Is_Null;

   --  ------------------------------
   --  Check whether the column is an unsigned number
   --  ------------------------------
   function Is_Unsigned (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Unsigned;
   end Is_Unsigned;

   --  ------------------------------
   --  Returns true if the column can hold a binary string
   --  ------------------------------
   function Is_Binary (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Binary;
   end Is_Binary;

   --  ------------------------------
   --  Returns true if the column is a primary key.
   --  ------------------------------
   function Is_Primary (Column : Column_Definition) return Boolean is
   begin
      return Column.Is_Primary;
   end Is_Primary;

   --  ------------------------------
   --  Get the column length
   --  ------------------------------
   function Get_Size (Column : Column_Definition) return Natural is
   begin
      return Column.Size;
   end Get_Size;

   --  ------------------------------
   --  Column iterator
   --  ------------------------------

   --  ------------------------------
   --  Returns true if the iterator contains more column
   --  ------------------------------
   function Has_Element (Cursor : Column_Cursor) return Boolean is
   begin
      return Cursor.Current /= null;
   end Has_Element;

   --  ------------------------------
   --  Move to the next column
   --  ------------------------------
   procedure Next (Cursor : in out Column_Cursor) is
   begin
      if Cursor.Current /= null then
         Cursor.Current := Cursor.Current.Next_Column;
      end if;
   end Next;

   --  ------------------------------
   --  Get the current column definition
   --  ------------------------------
   function Element (Cursor : Column_Cursor) return Column_Definition is
   begin
      return Cursor.Current;
   end Element;

   --  ------------------------------
   --  Table Representation
   --  ------------------------------

   --  ------------------------------
   --  Get the table name
   --  ------------------------------
   function Get_Name (Table : Table_Definition) return String is
   begin
      return To_String (Table.Name);
   end Get_Name;

   --  ------------------------------
   --  Get the column iterator
   --  ------------------------------
   function Get_Columns (Table : Table_Definition) return Column_Cursor is
   begin
      return Column_Cursor '(Current => Table.First_Column);
   end Get_Columns;

   --  ------------------------------
   --  Find the column having the given name
   --  ------------------------------
   function Find_Column (Table : Table_Definition;
                         Name  : String) return Column_Definition is
      Column : Column_Definition := Table.First_Column;
   begin
      while Column /= null loop
         if Ada.Strings.Equal_Case_Insensitive (To_String (Column.Name), Name) then
            return Column;
         end if;
         Column := Column.Next_Column;
      end loop;
      return null;
   end Find_Column;

   --  ------------------------------
   --  Table iterator
   --  ------------------------------

   --  ------------------------------
   --  Returns true if the iterator contains more tables
   --  ------------------------------
   function Has_Element (Cursor : Table_Cursor) return Boolean is
   begin
      return Cursor.Current /= null;
   end Has_Element;

   --  ------------------------------
   --  Move to the next column
   --  ------------------------------
   procedure Next (Cursor : in out Table_Cursor) is
   begin
      if Cursor.Current /= null then
         Cursor.Current := Cursor.Current.Next_Table;
      end if;
   end Next;

   --  ------------------------------
   --  Get the current table definition
   --  ------------------------------
   function Element (Cursor : Table_Cursor) return Table_Definition is
   begin
      return Cursor.Current;
   end Element;

   --  ------------------------------
   --  Database Schema
   --  ------------------------------

   --  ------------------------------
   --  Find a table knowing its name
   --  ------------------------------
   function Find_Table (Schema : Schema_Definition;
                        Name   : String) return Table_Definition is
      Table : Table_Definition;
   begin
      if Schema.Schema /= null then
         Table := Schema.Schema.First_Table;
         while Table /= null loop
            if Ada.Strings.Equal_Case_Insensitive (To_String (Table.Name), Name) then
               return Table;
            end if;
            Table := Table.Next_Table;
         end loop;
      end if;
      return null;
   end Find_Table;

   function Get_Tables (Schema : Schema_Definition) return Table_Cursor is
   begin
      if Schema.Schema = null then
         return Table_Cursor '(Current => null);
      else
         return Table_Cursor '(Current => Schema.Schema.First_Table);
      end if;
   end Get_Tables;

   procedure Finalize (Schema : in out Schema_Definition) is
   begin
      if Schema.Schema /= null then
         declare
            Table : Table_Definition;
            Column : Column_Definition;
         begin
            loop
               Table := Schema.Schema.First_Table;
               exit when Table = null;
               loop
                  Column := Table.First_Column;
                  exit when Column = null;
                  Table.First_Column := Column.Next_Column;
                  Free (Column);
               end loop;
               Schema.Schema.First_Table := Table.Next_Table;
               Free (Table);
            end loop;
         end;
         Free (Schema.Schema);
      end if;
   end Finalize;

end ADO.Schemas;

Implement the Is_Primary function

Implement the Is_Primary function


--  bkp-files -- File and directories
-----------------------------------------------------------------------
--  Copyright (C) 2014 Stephane.Carrez
--  Written by Stephane.Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Strings.Unbounded;
with Ada.Directories;
with Ada.Containers.Vectors;
with Ada.Text_IO;
with Ada.Exceptions;
with Ada.Streams.Stream_IO;
with Util.Log.Loggers;
with Util.Files;
with Interfaces.C;
package body Babel.Files is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Bkp.Files");

   --  ------------------------------
   --  Allocate a File_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return File_Type is
      Result : constant File_Type := new File '(Len    => Name'Length,
                                                Id     => NO_IDENTIFIER,
                                                Dir    => Dir,
                                                Name   => Name,
                                                others => <>);
   begin
      return Result;
   end Allocate;

   --  ------------------------------
   --  Return true if the file was modified and need a backup.
   --  ------------------------------
   function Is_Modified (Element : in File_Type) return Boolean is
      use type ADO.Identifier;
   begin
      if Element.Id = NO_IDENTIFIER then
         return True;
      elsif (Element.Status and FILE_MODIFIED) /= 0 then
         return True;
      else
         return False;
      end if;
   end Is_Modified;

   --  ------------------------------
   --  Set the file as modified.
   --  ------------------------------
   procedure Set_Modified (Element : in File_Type) is
   begin
      Element.Status := Element.Status or FILE_MODIFIED;
   end Set_Modified;

   --  ------------------------------
   --  Return the path for the file.
   --  ------------------------------
   function Get_Path (Element : in File) return String is
   begin
      return Util.Files.Compose (Ada.Strings.Unbounded.To_String (Element.Path),
                                 Ada.Strings.Unbounded.To_String (Element.Name));
   end Get_Path;

   overriding
   procedure Add_File (Into    : in out File_Queue;
                       Path    : in String;
                       Element : in File) is
   begin
      Into.Queue.Enqueue (Element);
   end Add_File;

   overriding
   procedure Add_Directory (Into : in out File_Queue;
                            Path : in String;
                            Name : in String) is
   begin
      Into.Directories.Append (Util.Files.Compose (Path, Name));
   end Add_Directory;

   procedure Scan_Files (Path : in String;
                         Into : in out Directory) is
      Iter : File_Vectors.Cursor := Into.Files.First;

      procedure Compute_Sha1 (Item : in out File) is
      begin
         Compute_Sha1 (Path, Item);
      end Compute_Sha1;

   begin
      while File_Vectors.Has_Element (Iter) loop
         Into.Files.Update_Element (Iter, Compute_Sha1'Access);
         File_Vectors.Next (Iter);
      end loop;
   end Scan_Files;

   procedure Scan_Children (Path : in String;
                            Into : in out Directory) is
      procedure Update (Dir : in out Directory) is
         use Ada.Strings.Unbounded;
         use type Ada.Directories.File_Size;
      begin
         Scan (Path & "/" & To_String (Dir.Name), Dir);
         Into.Tot_Files := Into.Tot_Files + Dir.Tot_Files;
         Into.Tot_Size  := Into.Tot_Size + Dir.Tot_Size;
         Into.Tot_Dirs  := Into.Tot_Dirs + Dir.Tot_Dirs;
      end Update;

   begin
      if Into.Children /= null then
         declare
            Iter : Directory_Vectors.Cursor := Into.Children.First;
         begin
            while Directory_Vectors.Has_Element (Iter) loop
               Into.Children.Update_Element (Iter, Update'Access);
               Directory_Vectors.Next (Iter);
            end loop;
         end;
      end if;
   end Scan_Children;

   procedure Scan (Path : in String;
                   Into : in out Directory) is
      use Ada.Directories;

      Filter : constant Ada.Directories.Filter_Type := (Ordinary_File => True,
                                                        Ada.Directories.Directory => True,
                                                        Special_File => False);
      Search   : Search_Type;
      Ent      : Directory_Entry_Type;
      New_File : File;
      Child    : Directory;
   begin
      Into.Tot_Size  := 0;
      Into.Tot_Files := 0;
      Into.Tot_Dirs  := 0;
      Start_Search (Search, Directory => Path, Pattern => "*", Filter => Filter);
      while More_Entries (Search) loop
         Get_Next_Entry (Search, Ent);
         declare
            Name : constant String    := Simple_Name (Ent);
            Kind : constant File_Kind := Ada.Directories.Kind (Ent);
         begin
            if Kind = Ordinary_File then
               New_File.Name := Ada.Strings.Unbounded.To_Unbounded_String (Name);
               begin
                  New_File.Size := Ada.Directories.Size (Ent);
               exception
                  when Constraint_Error =>
                     New_File.Size := Ada.Directories.File_Size (Interfaces.Unsigned_32'Last);
               end;
               Into.Files.Append (New_File);
               if New_File.Size > 0 then
                  begin
                     Into.Tot_Size  := Into.Tot_Size + New_File.Size;
                  exception
                     when Constraint_Error =>
                        Ada.Text_IO.Put_Line ("Size: " & Ada.Directories.File_Size'Image (New_File.Size)
                                              & " for " & Path & "/" & Name);
                        Ada.Text_IO.Put_Line ("Size: " & Ada.Directories.File_Size'Image (Into.Tot_Size));

                  end;
               end if;
               Into.Tot_Files := Into.Tot_Files + 1;
            elsif Name /= "." and Name /= ".." then
               if Into.Children = null then
                  Into.Children := new Directory_Vector;
               end if;
               Child.Name := Ada.Strings.Unbounded.To_Unbounded_String (Name);
               Into.Children.Append (Child);
               Into.Tot_Dirs := Into.Tot_Dirs + 1;
            end if;
         end;
      end loop;
      Scan_Children (Path, Into);
      Scan_Files (Path, Into);

   exception
      when E : others =>
            Log.Error ("Exception ", E);
   end Scan;

end Babel.Files;

--  bkp-files -- File and directories
-----------------------------------------------------------------------
--  Copyright (C) 2014 Stephane.Carrez
--  Written by Stephane.Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Strings.Unbounded;
with Ada.Directories;
with Ada.Containers.Vectors;
with Ada.Text_IO;
with Ada.Exceptions;
with Ada.Streams.Stream_IO;
with Util.Log.Loggers;
with Util.Files;
with Interfaces.C;
package body Babel.Files is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Bkp.Files");

   --  ------------------------------
   --  Allocate a File_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return File_Type is
      Result : constant File_Type := new File '(Len    => Name'Length,
                                                Id     => NO_IDENTIFIER,
                                                Dir    => Dir,
                                                Name   => Name,
                                                others => <>);
   begin
      return Result;
   end Allocate;

   --  ------------------------------
   --  Return true if the file was modified and need a backup.
   --  ------------------------------
   function Is_Modified (Element : in File_Type) return Boolean is
      use type ADO.Identifier;
   begin
      if Element.Id = NO_IDENTIFIER then
         return True;
      elsif (Element.Status and FILE_MODIFIED) /= 0 then
         return True;
      else
         return False;
      end if;
   end Is_Modified;

   --  ------------------------------
   --  Set the file as modified.
   --  ------------------------------
   procedure Set_Modified (Element : in File_Type) is
   begin
      Element.Status := Element.Status or FILE_MODIFIED;
   end Set_Modified;

   --  ------------------------------
   --  Return the path for the file.
   --  ------------------------------
   function Get_Path (Element : in File) return String is
   begin
      return Util.Files.Compose (Ada.Strings.Unbounded.To_String (Element.Path),
                                 Ada.Strings.Unbounded.To_String (Element.Name));
   end Get_Path;

   overriding
   procedure Add_File (Into    : in out File_Queue;
                       Path    : in String;
                       Element : in File) is
   begin
      Into.Queue.Enqueue (Element);
   end Add_File;

   overriding
   procedure Add_Directory (Into : in out File_Queue;
                            Path : in String;
                            Name : in String) is
   begin
      Into.Directories.Append (Util.Files.Compose (Path, Name));
   end Add_Directory;

end Babel.Files;

Remove the old Scan_Files, Scan_Children and Scan operations


--  bkp-files -- File and directories
-----------------------------------------------------------------------
--  Copyright (C) 2014 Stephane.Carrez
--  Written by Stephane.Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Util.Log.Loggers;
with Util.Files;
with Util.Encoders.Base16;
package body Babel.Files is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Bkp.Files");

   Hex_Encoder : Util.Encoders.Base16.Encoder;

   --  ------------------------------
   --  Allocate a File_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return File_Type is
      Result : constant File_Type := new File '(Len    => Name'Length,
                                                Id     => NO_IDENTIFIER,
                                                Dir    => Dir,
                                                Name   => Name,
                                                others => <>);
   begin
      return Result;
   end Allocate;

   --  ------------------------------
   --  Allocate a Directory_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return Directory_Type is
      use Ada.Strings.Unbounded;

      Result : constant Directory_Type := new Directory '(Len    => Name'Length,
                                                          Id     => NO_IDENTIFIER,
                                                          Parent => Dir,
                                                          Name   => Name,
                                                          others => <>);
   begin
      if Dir /= null then
         Result.Path := To_Unbounded_String
           (Util.Files.Compose (To_String (Dir.Path), Name));
      end if;
      return Result;
   end Allocate;

   --  ------------------------------
   --  Return true if the file was modified and need a backup.
   --  ------------------------------
   function Is_Modified (Element : in File_Type) return Boolean is
      use type ADO.Identifier;
   begin
      if Element.Id = NO_IDENTIFIER then
         return True;
      elsif (Element.Status and FILE_MODIFIED) /= 0 then
         return True;
      else
         return False;
      end if;
   end Is_Modified;

   --  ------------------------------
   --  Set the file as modified.
   --  ------------------------------
   procedure Set_Modified (Element : in File_Type) is
   begin
      Element.Status := Element.Status or FILE_MODIFIED;
   end Set_Modified;

   --  ------------------------------
   --  Set the SHA1 signature that was computed for this file.
   --  If the computed signature is different from the current signature,
   --  the FILE_MODIFIED flag is set on the file.  The FILE_HAS_SHA1 flag
   --  is set on the file.
   --  ------------------------------
   procedure Set_Signature (Element   : in File_Type;
                            Signature : in Util.Encoders.SHA1.Hash_Array) is
      use type Util.Encoders.SHA1.Hash_Array;
   begin
      if (Element.Status and FILE_HAS_SHA1) /= 0 and then Element.SHA1 /= Signature then
         Element.Status := Element.Status or FILE_MODIFIED;
      end if;
      Element.Status := Element.Status or FILE_HAS_SHA1;
      Element.SHA1   := Signature;
   end Set_Signature;

   --  ------------------------------
   --  Set the file size.  If the new size is different, the FILE_MODIFIED
   --  flag is set on the file.
   --  ------------------------------
   procedure Set_Size (Element : in File_Type;
                       Size    : in File_Size) is
   begin
      if Element.Size /= Size then
         Element.Size := Size;
         Element.Status := Element.Status or FILE_MODIFIED;
      end if;
   end Set_Size;

   --  ------------------------------
   --  Return the path for the file.
   --  ------------------------------
   function Get_Path (Element : in File_Type) return String is
   begin
      if Element.Dir = null then
         return Element.Name;
      else
         return Util.Files.Compose (Get_Path (Element.Dir), Element.Name);
      end if;
   end Get_Path;

   --  ------------------------------
   --  Return the path for the directory.
   --  ------------------------------
   function Get_Path (Element : in Directory_Type) return String is
   begin
      return Ada.Strings.Unbounded.To_String (Element.Path);
   end Get_Path;

   --  ------------------------------
   --  Return the SHA1 signature computed for the file.
   --  ------------------------------
   function Get_SHA1 (Element : in File_Type) return String is
   begin
      return Hex_Encoder.Transform (Element.SHA1);
   end Get_SHA1;

   --  ------------------------------
   --  Add the file with the given name in the container.
   --  ------------------------------
   overriding
   procedure Add_File (Into    : in out Default_Container;
                       Element : in File_Type) is
   begin
      Into.Files.Append (Element);
   end Add_File;

   --  ------------------------------
   --  Add the directory with the given name in the container.
   --  ------------------------------
   overriding
   procedure Add_Directory (Into    : in out Default_Container;
                            Element : in Directory_Type) is
   begin
      Into.Dirs.Append (Element);
   end Add_Directory;

   --  ------------------------------
   --  Create a new file instance with the given name in the container.
   --  ------------------------------
   overriding
   function Create (Into : in Default_Container;
                    Name : in String) return File_Type is
   begin
      return Allocate (Name => Name,
                       Dir  => Into.Current);
   end Create;

   --  ------------------------------
   --  Create a new directory instance with the given name in the container.
   --  ------------------------------
   overriding
   function Create (Into : in Default_Container;
                    Name : in String) return Directory_Type is
   begin
      return Allocate (Name => Name,
                       Dir  => Into.Current);
   end Create;

   --  ------------------------------
   --  Find the file with the given name in this file container.
   --  Returns NO_FILE if the file was not found.
   --  ------------------------------
   overriding
   function Find (From : in Default_Container;
                  Name : in String) return File_Type is
      pragma Unreferenced (From, Name);
   begin
      return NO_FILE;
   end Find;

   --  ------------------------------
   --  Find the directory with the given name in this file container.
   --  Returns NO_DIRECTORY if the directory was not found.
   --  ------------------------------
   overriding
   function Find (From : in Default_Container;
                  Name : in String) return Directory_Type is
      pragma Unreferenced (From, Name);
   begin
      return NO_DIRECTORY;
   end Find;

   --  ------------------------------
   --  Set the directory object associated with the container.
   --  ------------------------------
   procedure Set_Directory (Into      : in out Default_Container;
                            Directory : in Directory_Type) is
   begin
      Into.Current := Directory;
      Into.Files.Clear;
      Into.Dirs.Clear;
   end Set_Directory;

end Babel.Files;

--  bkp-files -- File and directories
-----------------------------------------------------------------------
--  Copyright (C) 2014 Stephane.Carrez
--  Written by Stephane.Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Util.Log.Loggers;
with Util.Files;
with Util.Encoders.Base16;
package body Babel.Files is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Bkp.Files");

   Hex_Encoder : Util.Encoders.Base16.Encoder;

   --  ------------------------------
   --  Allocate a File_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return File_Type is
      Result : constant File_Type := new File '(Len    => Name'Length,
                                                Id     => NO_IDENTIFIER,
                                                Dir    => Dir,
                                                Name   => Name,
                                                others => <>);
   begin
      return Result;
   end Allocate;

   --  ------------------------------
   --  Allocate a Directory_Type entry with the given name for the directory.
   --  ------------------------------
   function Allocate (Name : in String;
                      Dir  : in Directory_Type) return Directory_Type is
      use Ada.Strings.Unbounded;

      Result : constant Directory_Type := new Directory '(Len    => Name'Length,
                                                          Id     => NO_IDENTIFIER,
                                                          Parent => Dir,
                                                          Name   => Name,
                                                          others => <>);
   begin
      if Dir /= null then
         Result.Path := To_Unbounded_String
           (Util.Files.Compose (To_String (Dir.Path), Name));
      end if;
      return Result;
   end Allocate;

   --  ------------------------------
   --  Return true if the file was modified and need a backup.
   --  ------------------------------
   function Is_Modified (Element : in File_Type) return Boolean is
      use type ADO.Identifier;
   begin
      if Element.Id = NO_IDENTIFIER then
         return True;
      elsif (Element.Status and FILE_MODIFIED) /= 0 then
         return True;
      else
         return False;
      end if;
   end Is_Modified;

   --  ------------------------------
   --  Set the file as modified.
   --  ------------------------------
   procedure Set_Modified (Element : in File_Type) is
   begin
      Element.Status := Element.Status or FILE_MODIFIED;
   end Set_Modified;

   --  ------------------------------
   --  Set the SHA1 signature that was computed for this file.
   --  If the computed signature is different from the current signature,
   --  the FILE_MODIFIED flag is set on the file.  The FILE_HAS_SHA1 flag
   --  is set on the file.
   --  ------------------------------
   procedure Set_Signature (Element   : in File_Type;
                            Signature : in Util.Encoders.SHA1.Hash_Array) is
      use type Util.Encoders.SHA1.Hash_Array;
   begin
      if (Element.Status and FILE_HAS_SHA1) /= 0 and then Element.SHA1 /= Signature then
         Element.Status := Element.Status or FILE_MODIFIED;
      end if;
      Element.Status := Element.Status or FILE_HAS_SHA1;
      Element.SHA1   := Signature;
   end Set_Signature;

   --  ------------------------------
   --  Set the file size.  If the new size is different, the FILE_MODIFIED
   --  flag is set on the file.
   --  ------------------------------
   procedure Set_Size (Element : in File_Type;
                       Size    : in File_Size) is
   begin
      if Element.Size /= Size then
         Element.Size := Size;
         Element.Status := Element.Status or FILE_MODIFIED;
      end if;
   end Set_Size;

   --  ------------------------------
   --  Return the path for the file.
   --  ------------------------------
   function Get_Path (Element : in File_Type) return String is
   begin
      if Element.Dir = null then
         return Element.Name;
      else
         return Util.Files.Compose (Get_Path (Element.Dir), Element.Name);
      end if;
   end Get_Path;

   --  ------------------------------
   --  Return the path for the directory.
   --  ------------------------------
   function Get_Path (Element : in Directory_Type) return String is
   begin
      return Ada.Strings.Unbounded.To_String (Element.Path);
   end Get_Path;

   --  ------------------------------
   --  Return the SHA1 signature computed for the file.
   --  ------------------------------
   function Get_SHA1 (Element : in File_Type) return String is
   begin
      return Hex_Encoder.Transform (Element.SHA1);
   end Get_SHA1;

   --  ------------------------------
   --  Add the file with the given name in the container.
   --  ------------------------------
   overriding
   procedure Add_File (Into    : in out Default_Container;
                       Element : in File_Type) is
   begin
      Into.Files.Append (Element);
   end Add_File;

   --  ------------------------------
   --  Add the directory with the given name in the container.
   --  ------------------------------
   overriding
   procedure Add_Directory (Into    : in out Default_Container;
                            Element : in Directory_Type) is
   begin
      Into.Dirs.Append (Element);
   end Add_Directory;

   --  ------------------------------
   --  Create a new file instance with the given name in the container.
   --  ------------------------------
   overriding
   function Create (Into : in Default_Container;
                    Name : in String) return File_Type is
   begin
      return Allocate (Name => Name,
                       Dir  => Into.Current);
   end Create;

   --  ------------------------------
   --  Create a new directory instance with the given name in the container.
   --  ------------------------------
   overriding
   function Create (Into : in Default_Container;
                    Name : in String) return Directory_Type is
   begin
      return Allocate (Name => Name,
                       Dir  => Into.Current);
   end Create;

   --  ------------------------------
   --  Find the file with the given name in this file container.
   --  Returns NO_FILE if the file was not found.
   --  ------------------------------
   overriding
   function Find (From : in Default_Container;
                  Name : in String) return File_Type is
      pragma Unreferenced (From, Name);
   begin
      return NO_FILE;
   end Find;

   --  ------------------------------
   --  Find the directory with the given name in this file container.
   --  Returns NO_DIRECTORY if the directory was not found.
   --  ------------------------------
   overriding
   function Find (From : in Default_Container;
                  Name : in String) return Directory_Type is
      pragma Unreferenced (From, Name);
   begin
      return NO_DIRECTORY;
   end Find;

   --  ------------------------------
   --  Set the directory object associated with the container.
   --  ------------------------------
   procedure Set_Directory (Into      : in out Default_Container;
                            Directory : in Directory_Type) is
   begin
      Into.Current := Directory;
      Into.Files.Clear;
      Into.Dirs.Clear;
   end Set_Directory;

   --  ------------------------------
   --  Execute the Process procedure on each directory found in the container.
   --  ------------------------------
   overriding
   procedure Each_Directory (Container : in Default_Container;
                             Process   : not null access
                               procedure (Dir : in Directory_Type)) is
      Iter : Directory_Vectors.Cursor := Container.Dirs.First;
   begin
      while Directory_Vectors.Has_Element (Iter) loop
         Process (Directory_Vectors.Element (Iter));
         Directory_Vectors.Next (Iter);
      end loop;
   end Each_Directory;

end Babel.Files;

Implement the Each_Directory operation

Implement the Each_Directory operation


----------------------------------------------------------------------
-- Ada for POSIX (AdaFPX)
----------------------------------------------------------------------
-- Warren W. Gay VE3WWG     Tue Dec  3 18:49:48 2013
--
-- This is generated source code. Edit at your own risk.

package body Posix is

   function C_Last(C_String: String) return Natural is
   begin
      for X in C_String'Range loop
         if Character'Pos(C_String(X)) = 0 then
            return Natural(X-1);
         end if;
      end loop;
      return C_String'Last;
   end C_Last;

   function To_Count(Status: ssize_t) return Natural is
   begin
      if Status <= 0 then
         return 0;
      else
         return Natural(Status);
      end if;
   end To_Count;

   pragma Inline(To_Count);

   function To_Count(Status: int_t) return Natural is
   begin
      if Status <= 0 then
         return 0;
      else
         return Natural(Status);
      end if;
   end To_Count;

   pragma Inline(To_Count);

   function C_Error(Ret_Val: int_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val >= 0 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(Ret_Val: ssize_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val >= 0 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(PID: pid_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if PID /= -1 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(Ret_Val: clock_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      pragma Warnings(Off);
      if Ret_Val < 0 or  else Ret_Val = clock_t'Last then
         return c_errno;
      else
         return 0;
      end if;
      pragma Warnings(On);
   end C_Error;

   function C_Error(Ret_Val: sig_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val = SIG_ERR then
         return c_errno;
      else
         return 0;
      end if;
   end C_Error;

   function C_Error(Ret_Val: mode_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      pragma Warnings(Off);
      if Ret_Val < 0 or else Ret_Val = mode_t'Last then
         return c_errno;
      else
         return 0;
      end if;
      pragma Warnings(On);
   end C_Error;

   function C_String(Ada_String: String) return String is
      T : String(Ada_String'First..Ada_String'Last+1);
   begin
      T(T'First..T'Last-1) := Ada_String;
      T(T'Last) := Character'Val(0);
      return T;
   end C_String;

   function Ada_String(C_String: String) return String is
   begin
      for X in C_String'Range loop
         if Character'Pos(C_String(X)) = 0 then
            return C_String(C_String'First..X-1);
         end if;
      end loop;
      return C_String;
   end Ada_String;

   function Pos_PID(Status: int_t) return pid_t is
   begin
      if Status >= 0 then
         return pid_t(Status);
      else
         return 0;
      end if;
   end Pos_PID;

   pragma Inline(Pos_PID);

   function Neg_PID(Status: int_t) return pid_t is
   begin
      if Status < 0 then
         return pid_t(-Status);
      else
         return 0;
      end if;
   end Neg_PID;

   pragma Inline(Neg_PID);

   function Argv_Length(Argvs: String) return Natural is
      Count : Natural := 0;
   begin
      for X in Argvs'Range loop
         if Character'Pos(Argvs(x)) = 0 then
            Count := Count + 1;
         end if;
      end loop;
      return Count + 1;
   end Argv_Length;

   function Argv_Length(Argv: argv_array) return Natural is
      use System;
   begin
      for X in Argv'Range loop
         if Argv(X) = System.Null_Address then
            return X - Argv'First;
         end if;
      end loop;
      return Argv'Length;
   end Argv_Length;

   procedure Find_Nul(S: String; X: out Natural; Found: out Boolean) is
   begin
      for Y in S'Range loop
         if Character'Pos(S(Y)) = 0 then
            X := Y;
            Found := True;
         end if;
      end loop;
      X := S'Last;
      Found := False;
   end Find_Nul;

   function To_Argv(Argvs: String) return argv_array is
      Count : constant Natural := Argv_Length(Argvs);
      X :     Natural := Argvs'First;
      Y :     Natural;
      Found : Boolean;
   begin
      declare
         Argv :  argv_array(0..Count-1);
         Arg_X : Natural := Argv'First;
      begin
         while X <= Argvs'Last loop
            Find_Nul(Argvs(X..Argv'Last),Y,Found);
            exit when not Found;
            Argv(Arg_X) := Argvs(X)'Address;
            Arg_X       := Arg_X + 1;
            X           := Y + 1;
         end loop;
         Argv(Arg_X) := System.Null_Address;
         return Argv;
      end;
   end To_Argv;

   procedure To_Argv(Argvs: String; Argv: out argv_array) is
      Count : Natural := Argv_Length(Argvs);
      Arg_X : Natural := Argv'First;
      C :     Natural := 0;
      X :     Natural := Argvs'First;
      Y :     Natural;
      Found : Boolean;
   begin
      pragma Assert(Argv'Length>1);

      if Count > Argv'Length then
         Count := Argv'Length - 1;
      end if;

      while C < Count and X <= Argvs'Last loop
          Find_Nul(Argvs(X..Argv'Last),Y,Found);
          exit when not Found;
          Argv(Arg_X) := Argvs(X)'Address;
          Arg_X       := Arg_X + 1;
          X           := Y + 1;
          C           := C + 1;
      end loop;

      Argv(Arg_X) := System.Null_Address;

   end To_Argv;

   function To_Clock(Ticks: clock_t) return clock_t is
   begin
        pragma Warnings(Off);
        if Ticks < 0 or else Ticks = clock_t'Last then
            return 0;
        else
            return Ticks;
        end if;
        pragma Warnings(On);
   end To_Clock;

----------------------------------------------------------------------
-- Ada for POSIX (AdaFPX)
----------------------------------------------------------------------
-- Warren W. Gay VE3WWG     Tue Dec  3 18:49:48 2013
--
-- This is generated source code. Edit at your own risk.

package body Posix is

   function "="(L,R : DIR) return Boolean is
      use System;
   begin
      return System.Address(L) = System.Address(R);
   end "=";

   function C_Last(C_String: String) return Natural is
   begin
      for X in C_String'Range loop
         if Character'Pos(C_String(X)) = 0 then
            return Natural(X-1);
         end if;
      end loop;
      return C_String'Last;
   end C_Last;

   function To_Count(Status: ssize_t) return Natural is
   begin
      if Status <= 0 then
         return 0;
      else
         return Natural(Status);
      end if;
   end To_Count;

   pragma Inline(To_Count);

   function To_Count(Status: int_t) return Natural is
   begin
      if Status <= 0 then
         return 0;
      else
         return Natural(Status);
      end if;
   end To_Count;

   pragma Inline(To_Count);

   function C_Error(Ret_Val: int_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val >= 0 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   function C_Error(Ret_Val: long_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val >= 0 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(Ret_Val: ssize_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val >= 0 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(PID: pid_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if PID /= -1 then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   pragma Inline(C_Error);

   function C_Error(Ret_Val: clock_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      pragma Warnings(Off);
      if Ret_Val < 0 or  else Ret_Val = clock_t'Last then
         return c_errno;
      else
         return 0;
      end if;
      pragma Warnings(On);
   end C_Error;

   function C_Error(Ret_Val: sig_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val = SIG_ERR then
         return c_errno;
      else
         return 0;
      end if;
   end C_Error;

   function C_Error(Ret_Val: mode_t) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      pragma Warnings(Off);
      if Ret_Val < 0 or else Ret_Val = mode_t'Last then
         return c_errno;
      else
         return 0;
      end if;
      pragma Warnings(On);
   end C_Error;

   function C_Error(Ret_Val: DIR) return errno_t is
      function c_errno return errno_t;
      pragma Import(C,c_errno,"c_errno");
   begin
      if Ret_Val /= Null_DIR then
         return 0;
      else
         return c_errno;
      end if;
   end C_Error;

   function C_String(Ada_String: String) return String is
      T : String(Ada_String'First..Ada_String'Last+1);
   begin
      T(T'First..T'Last-1) := Ada_String;
      T(T'Last) := Character'Val(0);
      return T;
   end C_String;

   function Ada_String(C_String: String) return String is
   begin
      for X in C_String'Range loop
         if Character'Pos(C_String(X)) = 0 then
            return C_String(C_String'First..X-1);
         end if;
      end loop;
      return C_String;
   end Ada_String;

   function Pos_PID(Status: int_t) return pid_t is
   begin
      if Status >= 0 then
         return pid_t(Status);
      else
         return 0;
      end if;
   end Pos_PID;

   pragma Inline(Pos_PID);

   function Neg_PID(Status: int_t) return pid_t is
   begin
      if Status < 0 then
         return pid_t(-Status);
      else
         return 0;
      end if;
   end Neg_PID;

   pragma Inline(Neg_PID);

   function Argv_Length(Argvs: String) return Natural is
      Count : Natural := 0;
   begin
      for X in Argvs'Range loop
         if Character'Pos(Argvs(x)) = 0 then
            Count := Count + 1;
         end if;
      end loop;
      return Count + 1;
   end Argv_Length;

   function Argv_Length(Argv: argv_array) return Natural is
      use System;
   begin
      for X in Argv'Range loop
         if Argv(X) = System.Null_Address then
            return X - Argv'First;
         end if;
      end loop;
      return Argv'Length;
   end Argv_Length;

   procedure Find_Nul(S: String; X: out Natural; Found: out Boolean) is
   begin
      for Y in S'Range loop
         if Character'Pos(S(Y)) = 0 then
            X := Y;
            Found := True;
         end if;
      end loop;
      X := S'Last;
      Found := False;
   end Find_Nul;

   function To_Argv(Argvs: String) return argv_array is
      Count : constant Natural := Argv_Length(Argvs);
      X :     Natural := Argvs'First;
      Y :     Natural;
      Found : Boolean;
   begin
      declare
         Argv :  argv_array(0..Count-1);
         Arg_X : Natural := Argv'First;
      begin
         while X <= Argvs'Last loop
            Find_Nul(Argvs(X..Argv'Last),Y,Found);
            exit when not Found;
            Argv(Arg_X) := Argvs(X)'Address;
            Arg_X       := Arg_X + 1;
            X           := Y + 1;
         end loop;
         Argv(Arg_X) := System.Null_Address;
         return Argv;
      end;
   end To_Argv;

   procedure To_Argv(Argvs: String; Argv: out argv_array) is
      Count : Natural := Argv_Length(Argvs);
      Arg_X : Natural := Argv'First;
      C :     Natural := 0;
      X :     Natural := Argvs'First;
      Y :     Natural;
      Found : Boolean;
   begin
      pragma Assert(Argv'Length>1);

      if Count > Argv'Length then
         Count := Argv'Length - 1;
      end if;

      while C < Count and X <= Argvs'Last loop
          Find_Nul(Argvs(X..Argv'Last),Y,Found);
          exit when not Found;
          Argv(Arg_X) := Argvs(X)'Address;
          Arg_X       := Arg_X + 1;
          X           := Y + 1;
          C           := C + 1;
      end loop;

      Argv(Arg_X) := System.Null_Address;

   end To_Argv;

   function To_Clock(Ticks: clock_t) return clock_t is
   begin
        pragma Warnings(Off);
        if Ticks < 0 or else Ticks = clock_t'Last then
            return 0;
        else
            return Ticks;
        end if;
        pragma Warnings(On);
   end To_Clock;

Support for more types

Support for more types


-----------------------------------------------------------------------
--  mat-types -- Global types
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.IO_Exceptions;

with MAT.Commands;
with MAT.Targets;
with MAT.Consoles.Text;
procedure Matp is
   Target  : MAT.Targets.Target_Type;
   Console : aliased MAT.Consoles.Text.Console_Type;
begin
   Target.Console (Console'Unchecked_Access);
   Target.Initialize_Options;
   MAT.Commands.Initialize_Files (Target);
   Target.Start;
   Target.Interactive;
   Target.Stop;

exception
   when Ada.IO_Exceptions.End_Error | MAT.Targets.Usage_Error =>
      Target.Stop;
end Matp;

-----------------------------------------------------------------------
--  matp -- Main program
--  Copyright (C) 2014, 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.IO_Exceptions;

with MAT.Commands;
with MAT.Targets;
with MAT.Consoles.Text;
procedure Matp is
   Target  : MAT.Targets.Target_Type;
   Console : aliased MAT.Consoles.Text.Console_Type;
begin
   Target.Console (Console'Unchecked_Access);
   Target.Initialize_Options;
   MAT.Commands.Initialize_Files (Target);
   Target.Start;
   Target.Interactive;
   Target.Stop;

exception
   when Ada.IO_Exceptions.End_Error | MAT.Targets.Usage_Error =>
      Target.Stop;
end Matp;

Fix comment header

Fix comment header


-----------------------------------------------------------------------
--  util-streams-encoders -- Streams with encoding and decoding capabilities
--  Copyright (C) 2017, 2019 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Util.Encoders;

--  == Encoding Streams ==
--  The <tt>Encoding_Stream</tt> tagged record represents a stream with encoding capabilities.
--  The stream passes the data to be written to the <tt>Transformer</tt> interface that
--  allows to make transformations on the data before being written.
--
--     Encode : Util.Streams.Buffered.Encoders.Encoding_Stream;
--
--  The encoding stream manages a buffer that is used to hold the encoded data before it is
--  written to the target stream.  The <tt>Initialize</tt> procedure must be called to indicate
--  the target stream, the size of the buffer and the encoding format to be used.
--
--     Encode.Initialize (Output => File'Access, Size => 4096, Format => "base64");
--
package Util.Streams.Buffered.Encoders is

   pragma Preelaborate;

   --  -----------------------
   --  Encoding stream
   --  -----------------------
   --  The <b>Encoding_Stream</b> is an output stream which uses an encoder to
   --  transform the data before writing it to the output.  The transformer can
   --  change the data by encoding it in Base64, Base16 or encrypting it.
   type Encoding_Stream is limited new Util.Streams.Buffered.Output_Buffer_Stream with private;

   --  Initialize the stream to write on the given stream.
   --  An internal buffer is allocated for writing the stream.
   procedure Initialize (Stream  : in out Encoding_Stream;
                         Output  : access Output_Stream'Class;
                         Size    : in Natural;
                         Format  : in String);

   --  Close the sink.
   overriding
   procedure Close (Stream : in out Encoding_Stream);

   --  Write the buffer array to the output stream.
   overriding
   procedure Write (Stream : in out Encoding_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Flush the buffer by writing on the output stream.
   --  Raises Data_Error if there is no output stream.
   overriding
   procedure Flush (Stream : in out Encoding_Stream);

private

   type Encoding_Stream is limited new Util.Streams.Buffered.Output_Buffer_Stream with record
      Transform   : Util.Encoders.Transformer_Access;
   end record;

   --  Flush the stream and release the buffer.
   overriding
   procedure Finalize (Object : in out Encoding_Stream);

end Util.Streams.Buffered.Encoders;

-----------------------------------------------------------------------
--  util-streams-encoders -- Streams with encoding and decoding capabilities
--  Copyright (C) 2017, 2019 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Util.Encoders;

--  == Encoding Streams ==
--  The <tt>Encoding_Stream</tt> tagged record represents a stream with encoding capabilities.
--  The stream passes the data to be written to the <tt>Transformer</tt> interface that
--  allows to make transformations on the data before being written.
--
--     Encode : Util.Streams.Buffered.Encoders.Encoding_Stream;
--
--  The encoding stream manages a buffer that is used to hold the encoded data before it is
--  written to the target stream.  The <tt>Initialize</tt> procedure must be called to indicate
--  the target stream, the size of the buffer and the encoding format to be used.
--
--     Encode.Initialize (Output => File'Access, Size => 4096, Format => "base64");
--
generic
   type Encoder is limited new Util.Encoders.Transformer with private;
package Util.Streams.Buffered.Encoders is

   --  -----------------------
   --  Encoding stream
   --  -----------------------
   --  The <b>Encoding_Stream</b> is an output stream which uses an encoder to
   --  transform the data before writing it to the output.  The transformer can
   --  change the data by encoding it in Base64, Base16 or encrypting it.
   type Encoder_Stream is limited new Util.Streams.Buffered.Output_Buffer_Stream with record
      Transform   : Encoder;
   end record;

   --  Initialize the stream to write on the given stream.
   --  An internal buffer is allocated for writing the stream.
   overriding
   procedure Initialize (Stream  : in out Encoder_Stream;
                         Output  : access Output_Stream'Class;
                         Size    : in Positive);

   --  Close the sink.
   overriding
   procedure Close (Stream : in out Encoder_Stream);

   --  Write the buffer array to the output stream.
   overriding
   procedure Write (Stream : in out Encoder_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Flush the buffer by writing on the output stream.
   --  Raises Data_Error if there is no output stream.
   overriding
   procedure Flush (Stream : in out Encoder_Stream);

end Util.Streams.Buffered.Encoders;

Change the Encoders package to a generic package that must be instantiated with an encoder


-----------------------------------------------------------------------
--  Memory Events - Definition and Analysis of memory events
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with MAT.Types; use MAT.Types;
with MAT.Memory.Events.Servant;
package body MAT.Memory.Clients is

   use MAT.Memory.Events.Servant;

   procedure Create_Instance (Refs : in ClientInfo_Ref_Map) is
      --  Adapter : Manager       := Get_Manager (Refs);
      --  Client  : Client_Memory := new Client_Memory;
   begin
      --  Register_Client (Refs, "memory", Client.all'Access);
      --  Register_Servant (Adapter, Proxy);
      null;
   end Create_Instance;

end MAT.Memory.Clients;

-----------------------------------------------------------------------
--  Memory Events - Definition and Analysis of memory events
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with MAT.Types; use MAT.Types;
package body MAT.Memory.Targets is

   procedure Create_Instance (Refs : in ClientInfo_Ref_Map) is
      --  Adapter : Manager       := Get_Manager (Refs);
      --  Client  : Client_Memory := new Client_Memory;
   begin
      --  Register_Client (Refs, "memory", Client.all'Access);
      --  Register_Servant (Adapter, Proxy);
      null;
   end Create_Instance;

end MAT.Memory.Targets;

Rename package to MAT.Memory.Targets

Rename package to MAT.Memory.Targets