From: Gerd <GerdM.O@t-online.de>
Subject: Re: Binary opperations under Ada?
Date: Sat, 28 Aug 2010 13:14:50 -0700 (PDT)
Date: 2010-08-28T13:14:50-07:00 [thread overview]
Message-ID: <90e1a564-651c-4e7c-9afb-d2dcb0f772e9@x42g2000yqx.googlegroups.com> (raw)
In-Reply-To: 65WdnYGzoPP4k_LRnZ2dnUVZ_ridnZ2d@giganews.com
On 21 Aug., 01:23, Trogdor <bga...@aol.com> wrote:
> Greetings!
>
> -) I want to read in a raw binary file and perform bit manipulation
> on the data.
>
> -) I vaguely remember seeing a post about a module package for low
> level stuff, cut han no longer find it in the group.
>
> -) All (four) of my Ada books were written in the '90's and don't
> help much with this subject.
>
> -) I am running GNAT under MinGW under WinXP 64.
>
> Could some kind soul please...
> - Let me know just what I am looking for.
> - Where do I get it?
> - Where do I read about it so I don't have to pester the group with
> dozens of questions?
>
> Thanks in Advance!
>
> --
> --------------------------------- --- -- -
> Posted with NewsLeecher v3.9 Final
> Web @http://www.newsleecher.com/?usenet
> ------------------- ----- ---- -- -
You can use the code below. I've found it on the net some years ago.
But - be aware, this is not the "Ada way", and - it's not portable,
it's pure Windows.
First the spec:
--------------------------------------------------------------------------
with Ada.IO_Exceptions;
with Win32.Winnt; use win32.Winnt;
package UnstructuredFile is
--
------------------------------------------------------------------------------
--
-- This package implements a file processing which is similar to
that of Modula-2 --
-- It provides fast and easy access on unstructured files
(e.g. .exe) --
--
--
-- Maintenance level:
1.04A00 19.10.2004 --
--
------------------------------------------------------------------------------
--
type File_Type is limited private;
procedure Open (f : in out File_Type; Name : STRING);
--
------------------------------------------------------------------------------
--
-- Opens the file "Name" for read access: It fails if the file does
not exist. --
-- In this case the exeption Name_Error is raised. If the file is
already open --
-- the exception Status_Error is
raised. --
--
------------------------------------------------------------------------------
--
procedure Create (f : in out File_Type; Name : STRING);
--
------------------------------------------------------------------------------
--
-- Creates a new file named "Name" and opens it for write access. If
a file with --
-- this name already exists it is overwritten. If the file is
already open the --
-- exception Status_Error is
raised. --
--
------------------------------------------------------------------------------
--
procedure Append (f : in out File_Type; Name : STRING);
--
------------------------------------------------------------------------------
--
-- Opens the file "Name" for append. This means, it has write access
and it is --
-- positioned at the end, so that subsequent writes append data at
the end. If --
-- If the file is already open the exception Status_Error is
raised. --
--
------------------------------------------------------------------------------
--
procedure Close (f : in out File_Type);
--
------------------------------------------------------------------------------
--
-- Closes the file represented by "f". Exception Status_Error is
raised if the --
-- file is not
open. --
--
------------------------------------------------------------------------------
--
procedure ReadNBytes (f : in out File_Type; Buffer : out STRING;
BytesRead : out INTEGER);
--
------------------------------------------------------------------------------
--
-- Reads as many bytes as will fit into buffer, execpt there are not
enough bytes --
-- remaining in file "f". "BytesRead" returns the number of bytes
actually read. --
-- Exception Status_Error is raised if the file is not open,
exception Mode_Error --
-- is raised if the file was "Created" for write
acccess. --
--
------------------------------------------------------------------------------
--
procedure WriteNBytes (f : in out File_Type; Buffer : STRING;
BytesWritten : out INTEGER);
--
------------------------------------------------------------------------------
--
-- Writes the bytes from "Buffer" to the file. "BytesWritten"
returns the number --
-- of bytes actually written (this should always be the number of
bytes of --
-- "Buffer" except in case of
errors). --
-- Exception Status_Error is raised if the file is not open,
exception Mode_Error --
-- is raised if the file was "Opened" for read
acccess. --
--
------------------------------------------------------------------------------
--
function Is_Eof (f : File_Type) return boolean;
--
------------------------------------------------------------------------------
--
-- Returns TRUE if a file opened for read access was beyond the end
of file on --
-- the last read operation. The exception Status_Error is raised if
the file is --
-- not open, the exception Mode_Error is raised if the file was
"Created" for --
-- write
access.
--
--
------------------------------------------------------------------------------
--
procedure SetFilePos (f : File_Type; FilePos : INTEGER);
--
------------------------------------------------------------------------------
--
-- Sets the file position to "FilePos". "FilePos" specifies the
number of bytes --
-- relative to the begining of the file. The exception Status_Error
is raised if --
-- the file is not
open. --
--
------------------------------------------------------------------------------
--
function GetFilePos (f : File_Type) return INTEGER;
--
------------------------------------------------------------------------------
--
-- Gets the current position within the file. The returned value is
relative to --
-- the beginning of the file. The exception Status_Error is raised
if the file is --
-- not
open.
--
--
------------------------------------------------------------------------------
--
function GetFileSize (f : File_Type) return INTEGER;
--
------------------------------------------------------------------------------
--
-- Returns the size of the file (up to
2GB). --
-- The exception Status_Error is raised if the file is not
open. --
--
------------------------------------------------------------------------------
--
Status_Error : exception renames Ada.IO_Exceptions.Status_Error;
Mode_Error : exception renames Ada.IO_Exceptions.Mode_Error;
Name_Error : exception renames Ada.IO_Exceptions.Name_Error;
Use_Error : exception renames Ada.IO_Exceptions.Use_Error;
Device_Error : exception renames Ada.IO_Exceptions.Device_Error;
End_Error : exception renames Ada.IO_Exceptions.End_Error;
Data_Error : exception renames Ada.IO_Exceptions.Data_Error;
Layout_Error : exception renames Ada.IO_Exceptions.Layout_Error;
private
type Access_Mode is (Read_Only, Write_Only);
type File_Type is record
Is_Open : boolean := FALSE;
Current_Mode : Access_Mode;
Is_At_Eof : boolean;
File_Handle : HANDLE;
end record;
end UnstructuredFile;
--------------------------------------------------------------------------
Next the body:
--------------------------------------------------------------------------
-- with TEXT_IO;
with SYSTEM; use SYSTEM;
with UNCHECKED_CONVERSION;
with Win32; use Win32;
with Win32.Winerror; use Win32.Winerror;
--with Win32.Winnt; use win32.Winnt;
with Win32.Winbase; use Win32.Winbase;
package body UnstructuredFile is
--
------------------------------------------------------------------------------
--
-- This package implements a file processing which is similar to
that of Modula-2 --
-- It provides fast and easy access on unstructured files
(e.g. .exe) --
--
--
-- Maintenance level:
1.04A00 19.10.2004 --
--
------------------------------------------------------------------------------
--
function LPVOID_from_ADDRESS is new UNCHECKED_CONVERSION (ADDRESS,
LPCVOID);
function LPCVOID_from_ADDRESS is new UNCHECKED_CONVERSION (ADDRESS,
LPCVOID);
function LPDWORD_from_ADDRESS is new UNCHECKED_CONVERSION (ADDRESS,
LPDWORD);
function LPCSTR_from_ADDRESS is new UNCHECKED_CONVERSION (ADDRESS,
LPCSTR);
function LPOVERLAPPED_from_INTEGER is new UNCHECKED_CONVERSION
(INTEGER, LPOVERLAPPED);
function To_Handle is new Unchecked_Conversion (Integer,
Win32.Winnt.HANDLE);
use type Win32.DWORD;
procedure Open (f : in out File_Type; Name : STRING) is
F_Name : STRING := Name & ASCII.NUL;
begin
if f.Is_Open
then
raise Status_Error;
else
f.FILE_HANDLE := CreateFile (LPCSTR_from_ADDRESS
(F_NAME'address),
WinNT.GENERIC_READ,
FILE_SHARE_READ, null,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, TO_HANDLE (0));
if f.FILE_HANDLE = INVALID_HANDLE_VALUE
then
if GETLASTERROR = ERROR_FILE_NOT_FOUND
then
raise Name_Error;
else
raise Device_Error;
end if;
else
f.Is_Open := TRUE;
f.Is_At_Eof := FALSE;
f.Current_Mode := Read_Only;
end if;
end if;
end Open;
procedure Create (f : in out File_Type; Name : STRING) is
F_Name : STRING := Name & ASCII.NUL;
begin
if f.Is_Open
then
raise Status_Error;
else
f.FILE_HANDLE := CreateFile (LPCSTR_from_ADDRESS
(F_NAME'address),
WinNT.GENERIC_WRITE,
0, null,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, TO_HANDLE (0));
if f.FILE_HANDLE = INVALID_HANDLE_VALUE
then
if GETLASTERROR = ERROR_FILE_NOT_FOUND
then
raise Name_Error;
else
raise Device_Error;
end if;
else
f.Is_Open := TRUE;
f.Is_At_Eof := FALSE;
f.Current_Mode := Write_Only;
end if;
end if;
end Create;
procedure Append (f : in out File_Type; Name : STRING) is
F_Name : STRING := Name & ASCII.NUL;
NewPos : DWORD;
begin
if f.Is_Open
then
raise Status_Error;
else
f.FILE_HANDLE := CreateFile (LPCSTR_from_ADDRESS
(F_NAME'address),
WinNT.GENERIC_WRITE,
0, null,
Open_ALWAYS, FILE_ATTRIBUTE_NORMAL,
TO_HANDLE (0));
if f.FILE_HANDLE = INVALID_HANDLE_VALUE
then
if GETLASTERROR = ERROR_FILE_NOT_FOUND
then
raise Name_Error;
else
raise Device_Error;
end if;
else
f.Is_Open := TRUE;
f.Is_At_Eof := FALSE;
f.Current_Mode := Write_Only;
end if;
end if;
NewPos := SetFilePointer (f.FILE_HANDLE, LONG (0), null,
FILE_END);
end Append;
procedure Close (f : in out File_Type) is
CloseResult : BOOL;
begin
if not f.Is_Open
then
raise Status_Error;
end if;
CloseResult := CloseHandle (f.FILE_HANDLE);
f.Is_Open := FALSE;
end Close;
procedure ReadNBytes (f : in out File_Type; Buffer : out STRING;
BytesRead : out INTEGER) is
ReadResult : BOOL;
BytesToRead : DWORD;
NumBytesRead : DWORD;
begin
if not f.Is_Open
then
raise Status_Error;
elsif f.Current_Mode = Write_Only
then
raise Mode_Error;
elsif f.Is_At_Eof
then
raise End_Error;
end if;
BytesToRead := DWORD (Buffer'LAST - Buffer'First + 1);
ReadResult := ReadFile (f.FILE_HANDLE, Buffer'ADDRESS,
BytesToRead, LPDWORD_from_ADDRESS
(NumBytesRead'ADDRESS),
LPOVERLAPPED_from_INTEGER (0));
BytesRead := INTEGER (NumBytesRead);
if ReadResult = Win32.FALSE
then
raise Device_Error;
end if;
f.Is_At_Eof := (ReadResult = Win32.TRUE) AND (BytesRead = 0);
end ReadNBytes;
procedure WriteNBytes (f : in out File_Type; Buffer : STRING;
BytesWritten : out INTEGER) is
WriteResult : BOOL;
BytesToWrite : DWORD;
NumBytesWritten : DWORD;
begin
if not f.Is_Open
then
raise Status_Error;
elsif f.Current_Mode = Read_Only
then
raise Mode_Error;
end if;
BytesToWrite := DWORD (Buffer'LAST - Buffer'First + 1);
WriteResult := WriteFile (f.FILE_HANDLE, Buffer'ADDRESS,
BytesToWrite, LPDWORD_from_ADDRESS
(NumBytesWritten'ADDRESS),
LPOVERLAPPED_from_INTEGER (0));
BytesWritten := INTEGER
(NumBytesWritten);
if WriteResult = Win32.FALSE
then
raise Device_Error;
end if;
end WriteNBytes;
function Is_Eof (f : File_Type) return boolean is
begin
if not f.Is_Open
then
raise Status_Error;
elsif f.Current_Mode = Write_Only
then
raise Mode_Error;
end if;
return f.Is_At_Eof;
end Is_Eof;
procedure SetFilePos (f : File_Type; FilePos : INTEGER) is
NewPos : DWORD;
begin
if not f.Is_Open
then
raise Status_Error;
end if;
NewPos := SetFilePointer (f.FILE_HANDLE, LONG (FilePos), null,
FILE_BEGIN);
end SetFilePos;
function GetFilePos (f : File_Type) return INTEGER is
NewPos : DWORD;
begin
if not f.Is_Open
then
raise Status_Error;
end if;
NewPos := SetFilePointer (f.FILE_HANDLE, 0, null, FILE_CURRENT);
return INTEGER (NewPos);
end GetFilePos;
function GetFileSize (f : File_Type) return INTEGER is
SizeVal : DWORD;
begin
if not f.Is_Open
then
raise Status_Error;
end if;
SizeVal := GetFileSize (f.FILE_HANDLE, null);
return INTEGER (SizeVal);
end GetFileSize;
end UnstructuredFile;
--------------------------------------------------------------------------
prev parent reply other threads:[~2010-08-28 20:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-20 23:23 Binary opperations under Ada? Trogdor
2010-08-20 23:39 ` Yannick Duchêne (Hibou57)
2010-08-21 0:17 ` Jeffrey Carter
2010-08-22 8:24 ` Jacob Sparre Andersen
2010-08-26 21:02 ` Trogdor
2010-08-28 20:14 ` Gerd [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox