Data-TableReader

 view release on metacpan or  search on metacpan

lib/Data/TableReader.pm  view on Meta::CPAN

	my ($headers, $ct, $charset)= @{$hints}{qw( http_headers content_type charset )};

	# Support for web framework upload objects
	if (!$headers && blessed($input) && $input->can('headers')) {
		# Catalyst and Plack have ->headers => HTTP::Headers, though in plack the ->headers is
		#  not documented....
		# Dancer & Dancer2 have ->headers => HASH
		# Mojo has ->headers => Mojo::Headers
		$headers= $input->headers;
	}
	# the full content-type header, where the user-supplied '$ct' may only be the portion before ';'
	my $full_ct= defined $ct && $ct =~ /;/ ? $ct : undef;
	if (!defined $full_ct && $headers) {
		# Dancer uses hashref of headers, case-normalized
		if (ref $headers eq 'HASH') {
			my $ct_key= defined $headers->{'Content-Type'}? 'Content-Type'
						 : (grep /^content[-_]type\z/i, keys %$headers)[0];
			$full_ct= $headers->{$ct_key} if $ct_key;
		}
		# HTTP::Headers object or Mojo::Headers object
		elsif (blessed($headers) && $headers->can('header')) {
			$full_ct= $headers->header('Content-Type');
		}
		$full_ct= lc($full_ct) if defined $full_ct;
	}
	# Extract charset and content type from full content-type header.
	# But, don't if the user supplied a content-type value and it doesn't match the HTTP header.
	if (defined $full_ct && $full_ct =~ /^\s*([^;\s]+)/ && (!defined $ct || $ct eq $full_ct || $ct eq $1)) {
		$ct= $1;
		if (!defined $charset && $full_ct =~ /;\s*charset\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^;\s]+))/i) {
			# Could remove the '\\' escapes, but any value that has escapes will be an invalid
			# charset anyway.
			$charset= defined $1? $1 : $2;
		}
	}
	if (defined $charset) {
		if (my $enc= Encode::find_encoding($charset)) {

lib/Data/TableReader.pm  view on Meta::CPAN

	}

	@{$hints}{qw( http_headers content_type charset )}= ($headers, $ct, $charset);

	# Consult any registered decoders first
	for my $cls (grep $_->can('detect_input_format'), @_decoder_classes) {
		my @answer= $cls->detect_input_format($self, $hints);
		return @answer if @answer;
	}

	# Lacking a content-type, fall back to probing the contents of the file.
	my $content_head= $self->_get_content_head($hints);

	# Excel is obvious so check it first.  This handles cases where an excel file is
	# erroneously named ".csv" and silliness like that.
	if (defined $content_head) {
		return ( 'XLSX' ) if $content_head =~ /^PK(\x03\x04|\x05\x06|\x07\x08)/;
		return ( 'XLS'  ) if $content_head =~ /^\xD0\xCF\x11\xE0/;
	}

	# Remaining options are CSV, TSV, and HTML.  Trust the file extension, because TSV with

lib/Data/TableReader.pm  view on Meta::CPAN

	$hints->{filename}= $self->_real_file_name   unless defined $hints->{filename};
	if (defined $hints->{filename} && $hints->{filename} =~ /\.(
		  csv   (?{"CSV"})
		| tsv   (?{"TSV"})
		| html? (?{"HTML"})
	)\z/xi) {
		return ($^R, defined $charset? (encoding => $charset) : ());
	}

	# Try to decide between CSV or TSV or HTML based on content alone.
	# To do this, we also have to guess the content-type if it wasn't supplied.
	if (defined $content_head && length $content_head) {
		$self->_log->('debug',"Probing file format because no known filename suffix");
	} else {
		my $reason= defined $content_head? "empty file" : "unseekable file handle";
		$self->_log->('debug',"Can't probe $reason");
		return ();
	}
	$charset= $self->detect_input_charset($hints)
		unless defined $charset;
	my $text= $self->_get_content_head_text($hints);

lib/Data/TableReader.pm  view on Meta::CPAN


=head2 detect_input_format

   my ($decoder_class, @args)= $tr->detect_input_format(\%hints);
   my ($decoder_class, @args)= $tr->detect_input_format( $filename, $head_of_file );

This is used internally to detect the format of a file, but you can call it manually if you
like.  The following hints can be supplied as a hashref:

  { http_headers => ...,  # hashref or various objects representing HTTP headers
    content_type => ...,  # a MIME content-type, optional charset
	 charset      => ...,  # a character set, as seen in charset=X on a MIME type
    filename     => ...,  # filename, using file extension to guess content-type
	 content_head => ...,  # the first block(s) of the file, to probe magic numbers
	 content_ofs  => ...,  # a byte offset from which the input file should be read
  }

Missing hints will be pulled from L</input> if possible, updating the supplied hashref.
The two-argument form was the previous calling convention, and doesn't provide a way to retrieve
the generated hint values.

The return value is the best guess of module name and constructor arguments that
should be used to parse the file.  However, this doesn't guarantee such module actually exists



( run in 2.486 seconds using v1.01-cache-2.11-cpan-800906f7e73 )