95
96
my $class = ref $_[0] ? ref shift : shift;
96
97
my $self = bless [], $class;
97
98
my $string = $_[0];
98
unless ( defined $string ) {
99
return $self->_error("Did not provide a string to load");
103
# NOTE: Keeping this here to educate maintainers
105
# "\357\273\277" => 'UTF-8',
106
# "\376\377" => 'UTF-16BE',
107
# "\377\376" => 'UTF-16LE',
108
# "\377\376\0\0" => 'UTF-32LE'
109
# "\0\0\376\377" => 'UTF-32BE',
111
if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) {
112
return $self->_error("Stream has a non UTF-8 BOM");
114
# Strip UTF-8 bom if found, we'll just ignore it
115
$string =~ s/^\357\273\277//;
118
# Try to decode as utf8
119
utf8::decode($string) if HAVE_UTF8;
121
# Check for some special cases
122
return $self unless length $string;
123
unless ( $string =~ /[\012\015]+\z/ ) {
124
return $self->_error("Stream does not end with newline character");
127
# Split the file into lines
128
my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
129
split /(?:\015{1,2}\012|\015|\012)/, $string;
131
# Strip the initial YAML header
132
@lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
136
# Do we have a document header?
137
if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
138
# Handle scalar documents
140
if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
141
push @$self, $self->_read_scalar( "$1", [ undef ], \@lines );
146
if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
149
while ( @lines and $lines[0] !~ /^---/ ) {
100
unless ( defined $string ) {
101
die \"Did not provide a string to load";
105
# NOTE: Keeping this here to educate maintainers
107
# "\357\273\277" => 'UTF-8',
108
# "\376\377" => 'UTF-16BE',
109
# "\377\376" => 'UTF-16LE',
110
# "\377\376\0\0" => 'UTF-32LE'
111
# "\0\0\376\377" => 'UTF-32BE',
113
if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) {
114
die \"Stream has a non UTF-8 BOM";
116
# Strip UTF-8 bom if found, we'll just ignore it
117
$string =~ s/^\357\273\277//;
120
# Try to decode as utf8
121
utf8::decode($string) if HAVE_UTF8;
123
# Check for some special cases
124
return $self unless length $string;
125
unless ( $string =~ /[\012\015]+\z/ ) {
126
die \"Stream does not end with newline character";
129
# Split the file into lines
130
my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
131
split /(?:\015{1,2}\012|\015|\012)/, $string;
133
# Strip the initial YAML header
134
@lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
138
# Do we have a document header?
139
if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
140
# Handle scalar documents
153
} elsif ( $lines[0] =~ /^\s*\-/ ) {
154
# An array at the root
156
push @$self, $document;
157
$self->_read_array( $document, [ 0 ], \@lines );
159
} elsif ( $lines[0] =~ /^(\s*)\S/ ) {
162
push @$self, $document;
163
$self->_read_hash( $document, [ length($1) ], \@lines );
166
croak("YAML::Tiny failed to classify the line '$lines[0]'");
142
if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
143
push @$self, $self->_read_scalar( "$1", [ undef ], \@lines );
148
if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
151
while ( @lines and $lines[0] !~ /^---/ ) {
155
} elsif ( $lines[0] =~ /^\s*\-/ ) {
156
# An array at the root
158
push @$self, $document;
159
$self->_read_array( $document, [ 0 ], \@lines );
161
} elsif ( $lines[0] =~ /^(\s*)\S/ ) {
164
push @$self, $document;
165
$self->_read_hash( $document, [ length($1) ], \@lines );
168
die \"YAML::Tiny failed to classify the line '$lines[0]'";
172
if ( ref $@ eq 'SCALAR' ) {
173
return $self->_error(${$@});
173
182
# Deparse a scalar string to the actual scalar
206
215
if ( $string =~ /^[\'\"!&]/ ) {
207
croak("YAML::Tiny does not support a feature in line '$lines->[0]'");
216
die \"YAML::Tiny does not support a feature in line '$string'";
209
return {} if $string eq '{}';
210
return [] if $string eq '[]';
218
return {} if $string =~ /^{}(?:\s+\#.*)?\z/;
219
return [] if $string =~ /^\[\](?:\s+\#.*)?\z/;
212
221
# Regular unquoted string
213
return $string unless $string =~ /^[>|]/;
222
if ( $string !~ /^[>|]/ ) {
224
$string =~ /^(?:-(?:\s|$)|[\@\%\`])/
226
$string =~ /:(?:\s|$)/
228
die \"YAML::Tiny found illegal characters in plain scalar: '$string'";
230
$string =~ s/\s+#.*\z//;
216
croak("YAML::Tiny failed to find multi-line scalar content") unless @$lines;
235
die \"YAML::Tiny failed to find multi-line scalar content" unless @$lines;
218
237
# Check the indent depth
219
238
$lines->[0] =~ /^(\s*)/;
220
239
$indent->[-1] = length("$1");
221
240
if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
222
croak("YAML::Tiny found bad indenting in line '$lines->[0]'");
241
die \"YAML::Tiny found bad indenting in line '$lines->[0]'";