[Back to FILES SWAG index] [Back to Main SWAG index] [Original]
PROGRAM BinToInclude; (* Version 1.0, 12.10.96 *)
(*
Author: Dirk "Rob!" Schwarzmann, (w) September 1996, Germany
E-Mail: rob@rbg.informatik.th-darmstadt.de
WWW : http://www.student.informatik.th-darmstadt.de/~rob/
About this small piece of code:
This program reads any type of file and writes it back as a include
file (text type for TurboPascal) where every byte read is written as
its value. So, if a .com file is read and byte #x is an @, BinToInclude
will write the number 64 for it.
In addition, it creates a header so that you can use the new data
file directly as an include file in your own programs. The binary file
is stored as an array of byte and you can write it back to disc by using
the small procedure shown below.
What's it all good for?
You can hold binary files of _any_ type in your own program and do not
have to take care that an external data (or program) file is truly there.
If it does not exist, you simple write it! No panic, if a user has
accidently deleted a file or a file is corrupted!
Using this program:
You have to specify at least one command line parameter giving the file
you like to read. If no second parameter (the target file name) is given,
BinToInclude will create an .INC file with the path and name similar to
the source file. Otherwise the given name is used.
Note that BinToInclude does very little error checking! It does not
assure that the source file exists nor does it prevent you from over-
writing existing include files! But because this program is only a small
quick-hacked utility for programmers, I guess this not very important.
If you include a file in your program, keep in mind that you may get
problems if you include files bigger than 64k!
There a some constants you can only change in this source code;
- COMPRESSED is a boolean flag and toggles the writing of data between
the well-to-read format:
001, 020, 234, 089, ...
and the space-saving format:
1, 20, 234, 89, ...
If you want to save even the blanks between comma and numbers, get
your editor, mark the whole area and do a search + replace. It's
that simple! It would have taken much more effort to do this here.
- ArrayFormat
Specify the number of rows the array definition should use. 65 - 70
rows are a good choice to keep a good readability.
- Ext2_Str
Here you can change the default data file suffix - but I think there
is no need to do so.
To write the data back in a file, you only need this small routine:
PROCEDURE WriteArrayToFile(TargetName:FILE OF BYTE);
VAR
i : LONGINT;
BEGIN
Assign(TargetFile,TargetName);
Rewrite(TargetFile);
FOR i := 1 TO BinFileSize DO
Write(TargetFile,BinFile[i]);
Close(TargetFile);
END;
That's all!
For any suggestions, please feel free to email me!
*)
USES DOS;
CONST
Compressed : BOOLEAN = FALSE; (* False: 010, 009, 255, ...
True: 10, 9, 255,...
If you want to have 10,9,255 you can
remove the blanks with search +
replace
in your editor! *)
ArrayFormat : BYTE = 65; (* The width of the array definition area
(number of rows) *)
Ext2_Str : ExtStr = '.INC'; (* The default suffix for the file to write *)
(* These lines are the header of the written include-file. After the
variable "BinFileSize =" the program will insert the file length
(=array length) and after the last header line the data will follow. *)
IncHeader1 : STRING = 'CONST';
IncHeader2 : STRING = ' BinFileSize = ';
IncHeader3 : STRING = ' BinFile : ARRAY[1..BinFileSize] OF BYTE = (';
VAR (* main.BinToInclude *)
SourceFile : FILE OF BYTE;
TargetFile : TEXT;
SourceName : STRING[128];
TargetName : STRING[128];
SourceByte : BYTE;
TgtByteStr : STRING[5];
TargetStr : STRING[80];
Dir_Str : DirStr;
Name_Str : NameStr;
Ext_Str : ExtStr;
BEGIN (* main.BinToInclude *)
(* The case statement is only to parse the command line: *)
CASE ParamCount OF
1: BEGIN
FSplit(FExpand(ParamStr(1)),Dir_Str,Name_Str,Ext_Str);
SourceName := Dir_Str + Name_Str + Ext_Str;
TargetName := Dir_Str + Name_Str + Ext2_Str;
END; (* case ParamCount of 1 *)
2: BEGIN
FSplit(FExpand(ParamStr(1)),Dir_Str,Name_Str,Ext_Str);
SourceName := Dir_Str + Name_Str + Ext_Str;
FSplit(FExpand(ParamStr(2)),Dir_Str,Name_Str,Ext_Str);
TargetName := Dir_Str + Name_Str + Ext_Str;
END; (* case ParamCount of 2 *)
ELSE (* case ParamCount *)
WriteLn('Please specify at least one Parameter as the source file.');
Write('If the optional second one is not given, <Source file>.INC is');
WriteLn(' assumed.');
Halt(1);
END; (* case ParamCount *)
Assign(SourceFile,SourceName);
Reset(SourceFile);
Assign(TargetFile,TargetName);
Rewrite(TargetFile);
WriteLn(TargetFile,IncHeader1);
WriteLn(TargetFile,IncHeader2,FileSize(SourceFile),';');
WriteLn(TargetFile,IncHeader3);
TargetStr := ' '; (* Set the left margin *)
Inc(ArrayFormat,2); (* This needs an explanation: because of the 4 blanks
on the left margin, we should add 4 to ArrayFormat.
But as every number will be followed by a comma
and a blank, we have to decrease it by 2. -> add 2 *)
WHILE NOT EoF(SourceFile) DO BEGIN
Read(SourceFile,SourceByte);
Str(Ord(SourceByte),TgtByteStr);
IF NOT Compressed THEN
TgtByteStr := Copy('00',1,3-Length(TgtByteStr)) + TgtByteStr;
IF (Length(TargetStr) + Length(TgtByteStr) > ArrayFormat) THEN BEGIN
WriteLn(TargetFile,TargetStr); (* Flush the string *)
TargetStr := ' ';
END;
TargetStr := TargetStr + TgtByteStr + ', ';
END; (* while not EoF(SourceFile) *)
(* Flush the buffer string but don't write the last comma: *)
Write(TargetFile,Copy(TargetStr,1,Length(TargetStr)-2));
WriteLn(TargetFile,');'); (* Close the array definition with the ")"
*)
Close(TargetFile);
Close(SourceFile);
END. (* main.BinToInclude *)
[Back to FILES SWAG index] [Back to Main SWAG index] [Original]