File-BOM-Utils

 view release on metacpan or  search on metacpan

Changelog.ini  view on Meta::CPAN

[Module]
Name=File::BOM::Utils
Changelog.Creator=Module::Metadata::Changes V 2.05
Changelog.Parser=Config::IniFiles V 2.83

[V 1.02]
Date=2015-09-06T16:01:00
Comments= <<EOT
- Fix typo causing syntax error.
- Fix call which used write_binary instead of write_text.
- Update docs.
EOT

[V 1.01]
Date=2015-09-02T17:40:00
Comments= <<EOT
- Fix docs in Util.pm which wrongly said lower-case bom names were ok.
- Fix docs in bommer.pl for the same reason.
- Change output of test() method slightly, so 'Name' now says 'BOM name'.
- Remove Build.PL.
- Switch pre-req from File::Slurp to File::Slurper.
- Move .gitignore from MANIFEST to MANIFEST.SKIP.
EOT

[V 1.00]
Date=2015-06-24T12:09:00
Comments=- Original version

Changes  view on Meta::CPAN

Revision history for Perl extension File::BOM::Utils.

1.02  2015-09-06 16:01:00
	- Fix typo causing syntax error.
	- Fix call which used write_binary instead of write_text.
	- Update docs.

1.01  2015-09-02 17:40:00
	- Fix docs in Util.pm which wrongly said lower-case bom names were ok.
	- Fix docs in bommer.pl for the same reason.
	- Change output of test() method slightly, so 'Name' now says 'BOM name'.
	- Remove Build.PL.
	- Switch pre-req from File::Slurp to File::Slurper.
	- Move .gitignore from MANIFEST to MANIFEST.SKIP.

1.00  2015-06-24 12:09:00
	- Original version

MANIFEST  view on Meta::CPAN

bin/bommer.pl
Changelog.ini
Changes
data/bom-less.xml
data/bom-UTF-16-BE.xml
data/bom-UTF-16-LE.xml
data/bom-UTF-32-BE.xml
data/bom-UTF-32-LE.xml
data/bom-UTF-8.xml
lib/File/BOM/Utils.pm
LICENSE
Makefile.PL
MANIFEST			This list of files
META.json
META.yml
README
scripts/pod2html.sh
scripts/synopsis.pl
t/test.t
xt/author/changes.t

META.json  view on Meta::CPAN

{
   "abstract" : "Check, Add and Remove BOMs",
   "author" : [
      "Ron Savage (ron@savage.net.au)"
   ],
   "dynamic_config" : 1,
   "generated_by" : "ExtUtils::MakeMaker version 7.06, CPAN::Meta::Converter version 2.143240",
   "license" : [
      "artistic_2"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
      "version" : "2"
   },
   "name" : "File-BOM-Utils",
   "no_index" : {
      "directory" : [
         "t",
         "inc"
      ]
   },
   "prereqs" : {
      "build" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"

META.json  view on Meta::CPAN

         }
      }
   },
   "release_status" : "stable",
   "resources" : {
      "license" : [
         "http://opensource.org/licenses/Artistic-2.0"
      ],
      "repository" : {
         "type" : "git",
         "url" : "https://github.com/ronsavage/File-BOM-Utils.git",
         "web" : "https://github.com/ronsavage/File-BOM-Utils"
      }
   },
   "version" : "1.02"
}

META.yml  view on Meta::CPAN

---
abstract: 'Check, Add and Remove BOMs'
author:
  - 'Ron Savage (ron@savage.net.au)'
build_requires:
  ExtUtils::MakeMaker: '0'
configure_requires:
  ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.06, CPAN::Meta::Converter version 2.143240'
license: artistic_2
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: File-BOM-Utils
no_index:
  directory:
    - t
    - inc
requires:
  File::Slurper: '0.008'
  File::Spec: '0'
  Getopt::Long: '0'
  Moo: '1.007'
  Pod::Usage: '0'
  Test::More: '1.001014'
  Test::Pod: '1.48'
  Types::Standard: '1.000005'
  strict: '0'
  utf8: '0'
  warnings: '0'
resources:
  license: http://opensource.org/licenses/Artistic-2.0
  repository: https://github.com/ronsavage/File-BOM-Utils.git
version: '1.02'

Makefile.PL  view on Meta::CPAN

# -----------------------------------------------

# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.

my(%params) =
(
	($] ge '5.005') ?
	(
		AUTHOR   => 'Ron Savage (ron@savage.net.au)',
		ABSTRACT => 'Check, Add and Remove BOMs',
	) : (),
	clean =>
	{
		FILES => 'blib/* Makefile MANIFEST File-BOM-Utils-*'
	},
	dist =>
	{
		COMPRESS => 'gzip',
		SUFFIX   => 'gz'
	},
	DISTNAME  => 'File-BOM-Utils',
	EXE_FILES => ['bin/bommer.pl'],
	NAME      => 'File::BOM::Utils',
	PL_FILES  => {},
	PREREQ_PM =>
	{
		'File::Slurper' => 0.008,
		'File::Spec' => 0,
		'Getopt::Long' => 0,
		'Moo' => 1.007000,
		'Pod::Usage' => 0,
		'strict' => 0,
		'Test::More' => 1.001014,
		'Test::Pod' => 1.48,
		'Types::Standard' => 1.000005,
		'utf8' => 0,
		'warnings' => 0,
	},
	VERSION_FROM => 'lib/File/BOM/Utils.pm',
);

if ( ($ExtUtils::MakeMaker::VERSION =~ /^\d\.\d\d$/) && ($ExtUtils::MakeMaker::VERSION > 6.30) )
{
	$params{LICENSE} = 'artistic_2';
}

if ($ExtUtils::MakeMaker::VERSION ge '6.46')
{
	$params{META_MERGE} =
	{
		'meta-spec' =>
		{
		'version' => 2,
		},
		resources   =>
		{
		'bugtracker' => 'https://rt.cpan.org/Public/Dist/Display.html?Name=File-BOM-Utils',
		'license' => 'http://opensource.org/licenses/Artistic-2.0',
			repository =>
			{
		'type' => 'git',
		'url' => 'https://github.com/ronsavage/File-BOM-Utils.git',
		'web' => 'https://github.com/ronsavage/File-BOM-Utils',
			},
		},
	};
}

WriteMakefile(%params);

README  view on Meta::CPAN

README file for File::BOM::Utils.

See also: Changes and Changelog.ini.

Warning: WinZip 8.1 and 9.0 both contain an 'accidental' bug which stops
them recognizing POSIX-style directory structures in valid tar files.
You are better off using a reliable tool such as InfoZip:
ftp://ftp.info-zip.org/pub/infozip/

1 Installing from a Unix-like distro
------------------------------------
shell>gunzip File-BOM-Utils-1.00.tgz
shell>tar mxvf File-BOM-Utils-1.00.tar

On Unix-like systems, assuming you have installed Module::Build V 0.25+:

shell>perl Build.PL
shell>./Build
shell>./Build test
shell>./Build install

On MS Windows-like systems, assuming you have installed Module::Build V 0.25+:

README  view on Meta::CPAN

shell>su              (for Unix-like systems)
shell>make install
shell>exit            (for Unix-like systems)

On all systems:

Run Utils.pm through your favourite pod2html translator.

2 Installing from an ActiveState distro
---------------------------------------
shell>unzip File-BOM-Utils-1.00.zip
shell>ppm install --location=. File-BOM-Utils
shell>del File-BOM-Utils-1.00.ppd
shell>del PPM-File-BOM-Utils-1.00.tar.gz

bin/bommer.pl  view on Meta::CPAN

#!/usr/bin/env perl

use strict;
use warnings;
use warnings qw(FATAL utf8); # Fatalize encoding glitches.

use File::BOM::Utils;

use Getopt::Long;

use Pod::Usage;

# ------------------------------------------------

my($option_parser) = Getopt::Long::Parser -> new();

my(%option);

bin/bommer.pl  view on Meta::CPAN

	\%option,
	'action=s',
	'bom_name=s',
	'help',
	'input_file=s',
	'output_file=s',
) )
{
	pod2usage(1) if ($option{'help'});

	exit File::BOM::Utils -> new(%option) -> run;
}
else
{
	pod2usage(2);
}

__END__

=pod

=head1 NAME

bommer.pl - Check, Add and Remove BOMs

=head1 SYNOPSIS

bommer.pl [options]

	Options:
	-action   $string
	-bom_name $string
	-help
	-input_file  $file_name

bin/bommer.pl  view on Meta::CPAN

=over 4

=item -action $string

Specify the action wanted:

=over 4

=item o add

Add the BOM named with the bom_name option to input_file.
Write the result to output_file.

=item o remove

Remove the BOM from the input_file. Write the result to output_file.

=item o test

Report the BOM status of input_file.

=back

Default: ''.

This option is mandatory.

=item -bom_name => $string

Specify which BOM to add to C<input_file>.

This option is mandatory if the C<action> is C<add>.

Values (always upper-case):

=over 4

=item o UTF-32-BE

=item o UTF-32-LE

lib/File/BOM/Utils.pm  view on Meta::CPAN

package File::BOM::Utils;

use strict;
use warnings;
use warnings qw(FATAL utf8); # Fatalize encoding glitches.

use File::Slurper qw/read_binary write_binary/;

use Moo;

use Types::Standard qw/Int ScalarRef Str/;

lib/File/BOM/Utils.pm  view on Meta::CPAN

);

has output_file =>
(
	default  => sub{return ''},
	is       => 'rw',
	isa      => Str,
	required => 1,
);

# http://search.cpan.org/perldoc?PPI::Token::BOM or String::BOM.

our(%bom2name) =
(
	"\x00\x00\xfe\xff" => 'UTF-32-BE',
	"\xff\xfe\x00\x00" => 'UTF-32-LE',
	"\xfe\xff"         => 'UTF-16-BE',
	"\xff\xfe"         => 'UTF-16-LE',
	"\xef\xbb\xbf"     => 'UTF-8',
);

lib/File/BOM/Utils.pm  view on Meta::CPAN

{
	my($self, %opt) = @_;

	$self -> _read(%opt);
	$self -> bom_name($opt{bom_name})       if (defined $opt{bom_name});
	$self -> output_file($opt{output_file}) if (defined $opt{input_file});

	my($output_file) = $self -> output_file;
	my($name)        = $self -> bom_name;

	die "Unknown BOM name: $name\n" if (! $name2bom{$name});

	write_binary($output_file, $name2bom{$name} . ${$self -> data});

	# Return 0 for success and 1 for failure.

	return 0;

} # End of add.

# ------------------------------------------------

lib/File/BOM/Utils.pm  view on Meta::CPAN

			$name                     = $bom2name{$key};
			substr($data, 0, $length) = '';

			last;
		}
	}

	return
	{
		length  => $name ? $length : 0,
		message => $name ? "BOM name $name found" : 'No BOM found',
		name    => $name,
		value   => $value,
	};

	return 0;

} # End of file_report.

# ------------------------------------------------

lib/File/BOM/Utils.pm  view on Meta::CPAN

} # End of run.

# ------------------------------------------------

sub test
{
	my($self, %opt) = @_;
	my($result)     = $self -> file_report(%opt);
	my($file_name)  = $self -> input_file;

	print "BOM report for $file_name: \n";
	print 'File size: ', -s $file_name, " bytes \n";

	my($prefix);

	for my $key (qw/message name/)
	{
		$prefix = ($key eq 'message') ? 'Message' : 'BOM name';

		print "$prefix: $$result{$key}\n";
	}

	if ($$result{name})
	{
		my($stats) = $self -> bom_report(bom_name => $$result{name});

		print "Length: $$stats{length} bytes \n";
	}

lib/File/BOM/Utils.pm  view on Meta::CPAN

} # End of test.

# ------------------------------------------------

1;

=pod

=head1 NAME

C<File::BOM::Utils> - Check, Add and Remove BOMs

=head1 Synopsis

This is scripts/synopsis.pl:

	#!/usr/bin/env perl

	use strict;
	use warnings;

	use File::BOM::Utils;
	use File::Spec;

	# -------------------

	my($bommer)    = File::BOM::Utils -> new;
	my($file_name) = File::Spec -> catfile('data', 'bom-UTF-8.xml');

	$bommer -> action('test');
	$bommer -> input_file($file_name);

	my($report) = $bommer -> file_report;

	print "BOM report for $file_name: \n";
	print join("\n", map{"$_: $$report{$_}"} sort keys %$report), "\n";

Try 'bommer.pl -h'. It is installed automatically when the module is installed.

=head1 Description

L<File::BOM::Utils> provides a means of testing, adding and removing BOMs (Byte-Order-Marks)
within files.

It also provides two hashes accessible from outside the module, which convert in both directions
between BOM names and values. These hashes are called C<%bom2name> and C<%name2bom>.

See also bommer.pl, which is installed automatically when the module is installed.

=head1 Distributions

This module is available as a Unix-style distro (*.tgz).

See L<http://savage.net.au/Perl-modules/html/installing-a-module.html>
for help on unpacking and installing distros.

=head1 Installation

Install L<File::BOM::Utils> as you would any C<Perl> module:

Run:

	cpanm File::BOM::Utils

or run:

	sudo cpan File::BOM::Utils

or unpack the distro, and then either:

	perl Build.PL
	./Build
	./Build test
	sudo ./Build install

or:

	perl Makefile.PL
	make (or dmake or nmake)
	make test
	make install

=head1 Constructor and Initialization

C<new()> is called as C<< my($parser) = File::BOM::Utils -> new(k1 => v1, k2 => v2, ...) >>.

It returns a new object of type C<File::BOM::Utils>.

Key-value pairs accepted in the parameter list (see corresponding methods for details
[e.g. L</action([$string])>]):

=over 4

=item o action => $string

Specify the action wanted:

=over 4

=item o add

Add the BOM named with the C<bom_name> option to C<input_file>.
Write the result to C<output_file>.

=item o remove

Remove any BOM found from the C<input_file>. Write the result to C<output_file>.

The output is created even if the input file has no BOM, in order to not violate the
L<Principle of Least Surprise|https://en.wikipedia.org/wiki/Principle_of_least_astonishment>.

=item o test

Print the BOM status of C<input_file>.

The methods L</bom_report([%opt])> and L</file_report([%opt])> return hashrefs if you wish to
avoid printed output.

=back

Default: ''.

A value for this option is mandatory.

Note: As syntactic sugar, you may specify just the 1st letter of the action. And that's why
C<test> is called C<test> and not C<report>.

=item o bom_name => $string

Specify which BOM to add to C<input_file>.

This option is mandatory if the C<action> is C<add>.

Values (always upper-case):

=over 4

=item o UTF-32-BE

=item o UTF-32-LE

lib/File/BOM/Utils.pm  view on Meta::CPAN


If you supplied an abbreviated (1st letter only) version of the action, the return value is the
full name of the action.

C<action> is a parameter to L</new([%opt])>.

=head2 add([%opt])

Here, the [] indicate an optional parameter.

Adds a named BOM to the input file, and writes the result to the output file.

Returns 0.

C<%opt> may contain these (key => value) pairs:

=over 4

=item o bom_name => $string

The name of the BOM.

The names are listed above, under L</Constructor and Initialization>.

=item o input_file => $string

=item o output_file => $string

=back

=head2 bom_name([$string])

Here, the [] indicate an optional parameter.

Gets or sets the name of the BOM to add to the input file as that file is copied to the output file.

The names are listed above, under L</Constructor and Initialization>.

C<bom_name> is a parameter to L</new([%opt])>.

=head2 bom_report([%opt])

Here, the [] indicate an optional parameter.

Returns a hashref of statitics about the named BOM.

C<%opt> may contain these (key => value) pairs:

=over 4

=item o bom_name => $string

=back

The hashref returned has these (key => value) pairs:

=over 4

=item o length => $integer

The # of bytes in the BOM.

=item o name => $string

The name of the BOM.

The names are listed above, under L</Constructor and Initialization>.

=item o value => $integer

The value of the named BOM.

=back

=head2 bom_values()

Returns an array of BOM values, sorted from longest to shortest.

=head2 data()

Returns a reference to a string holding the contents input file, or returns a reference to the
empty string.

=head2 file_report([%opt])

Here, the [] indicate an optional parameter.

lib/File/BOM/Utils.pm  view on Meta::CPAN

=item o input_file => $string

=back

The hashref returned has these (key => value) pairs:

=over 4

=item o length => $name ? $length : 0

This is the length of the BOM in bytes.

=item o message => $name ? "BOM name $name found" : 'No BOM found'

=item o name => $name || ''

The name of the BOM.

The names are listed above, under L</Constructor and Initialization>.

=item o value => $value || 0

This is the value of the BOM.

=back

=head2 input_file([$string])

Here, the [] indicate an optional parameter.

Gets or sets the name of the input file.

C<input_file> is a parameter to L</new([%opt])>.

=head2 new([%opt])

Here, the [] indicate an optional parameter.

Returns an object of type C<File::BOM::Utils>.

C<%opt> may contain these (key => value) pairs:

=over 4

=item o action => $string

The action wanted.

The actions are listed above, under L</Constructor and Initialization>.

=item o bom_name => $string

The name of the BOM.

The names are listed above, under L</Constructor and Initialization>.

=item o input_file => $string

=item o output_file => $string

=back

=head2 output_file([$string])

lib/File/BOM/Utils.pm  view on Meta::CPAN


And yes, it can be the same as the input file, but does not default to the input file.
That would be dangerous.

C<output_file> is a parameter to L</new([%opt])>.

=head2 remove(%opt)

Here, the [] indicate an optional parameter.

Removes any BOM from the input file, and writes the result to the output_file.

C<%opt> may contain these (key => value) pairs:

=over 4

=item o input_file => $string

=item o output_file => $string

=back

lib/File/BOM/Utils.pm  view on Meta::CPAN

=over 4

=item o action => $string

The action wanted.

The actions are listed above, under L</Constructor and Initialization>.

=item o bom_name => $string

The name of the BOM.

The names are listed above, under L</Constructor and Initialization>.

=item o input_file => $string

=item o output_file => $string

=back

=head1 test([%opt])

lib/File/BOM/Utils.pm  view on Meta::CPAN

=head1 FAQ

=head2 How does this module read and write files?

It uses L<File::Slurper>'s read_binary() and write_binary().

=head2 What are the hashes accessible from outside the module?

They are called C<%bom2name> and C<%name2bom>.

The BOM names used are listed under L</Constructor and Initialization>.

=head2 Which program is installed when the module is installed?

It is called C<bommer.pl>. Run it with the -h option, to display help.

=head2 How is the parameter %opt, which may be passed to many methods, handled?

The keys in C<%opt> are used to find values which are passed to the methods named after the
keys.

For instance, if you call:

	my($bommer) = File::BOM::Utils -> new(action => 'add');

	$bommer -> run(action => 'test');

Then the code calls C<action('test')>, which sets the 'current' value of C<action> to C<test>.

This means that if you later call C<action()>, the value returned is whatever was the most recent
value provided (to any method) in C<$opt{action}>. Similarly for the other parameters to
L</new([%opt])>.

Note: As syntactic sugar, you may specify just the 1st letter of the action. And that's why
C<test> is called C<test> and not C<report>.

=head2 What happens if I add the same BOM twice?

The program will do as you order it to do. Hopefully, you remove one or both of the BOMs immediately
after testing the output.

=head1 See Also

L<String::BOM>.

L<PPI::Token::BOM>.

L<File::BOM>.

L<XML::Tiny>, whose test data I've adopted.

L<File::Slurper>.

=head1 Machine-Readable Change Log

The file Changes was converted into Changelog.ini by L<Module::Metadata::Changes>.

=head1 Version Numbers

Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.

=head1 Repository

L<https://github.com/ronsavage/File-BOM-Utils>

=head1 Support

Email the author, or log a bug on RT:

L<https://rt.cpan.org/Public/Dist/Display.html?Name=File::BOM::Utils>.

=head1 Author

L<File::BOM::Utils> was written by Ron Savage I<E<lt>ron@savage.net.auE<gt>> in 2015.

Marpa's homepage: L<http://savage.net.au/Marpa.html>.

My homepage: L<http://savage.net.au/>.

=head1 Copyright

Australian copyright (c) 2015, Ron Savage.

	All Programs of mine are 'OSI Certified Open Source Software';

scripts/pod2html.sh  view on Meta::CPAN

#!/bin/bash

DIR=Perl-modules/html/File/BOM
FILE=Utils.html

mkdir -p $DR/$DIR ~/savage.net.au/$DIR

pod2html.pl -i lib/File/BOM/Utils.pm -o $DR/$DIR/$FILE

cp $DR/$DIR/$FILE ~/savage.net.au/$DIR

scripts/synopsis.pl  view on Meta::CPAN

#!/usr/bin/env perl

use strict;
use warnings;

use File::BOM::Utils;
use File::Spec;

# -------------------

my($bommer)    = File::BOM::Utils -> new;
my($file_name) = File::Spec -> catfile('data', 'bom-UTF-8.xml');

$bommer -> action('test');
$bommer -> input_file($file_name);

my($report) = $bommer -> file_report;

print "BOM report for $file_name: \n";
print join("\n", map{"$_: $$report{$_}"} sort keys %$report), "\n";

t/test.t  view on Meta::CPAN

use strict;
use utf8;
use warnings;
use warnings qw(FATAL utf8); # Fatalize encoding glitches.

use File::BOM::Utils;
use File::Slurper 'read_dir';
use File::Spec;

use Test::More;

# ------------------------------------------------

my($count) = 0;
my(%expect) =
(
	'bom-less.xml' =>
	{
		length  => 0,
		message => 'No BOM found',
		name    => '',
	},
	'bom-UTF-16-BE.xml' =>
	{
		length  => 2,
		message => 'BOM name UTF-16-BE found',
		name    => 'UTF-16-BE',
	},
	'bom-UTF-16-LE.xml' =>
	{
		length  => 2,
		message => 'BOM name UTF-16-LE found',
		name    => 'UTF-16-LE',
	},
	'bom-UTF-32-BE.xml' =>
	{
		length  => 4,
		message => 'BOM name UTF-32-BE found',
		name    => 'UTF-32-BE',
	},
	'bom-UTF-32-LE.xml' =>
	{
		length  => 4,
		message => 'BOM name UTF-32-LE found',
		name    => 'UTF-32-LE',
	},
	'bom-UTF-8.xml' =>
	{
		length  => 3,
		message => 'BOM name UTF-8 found',
		name    => 'UTF-8',
	},
);
my($bommer) = File::BOM::Utils -> new;

$bommer -> action('test');

my($report);

for my $path (read_dir('data') )
{
	$bommer -> input_file(File::Spec -> catfile('data', $path) );

	$report = $bommer -> file_report;



( run in 0.958 second using v1.01-cache-2.11-cpan-e9daa2b36ef )