BEGIN {
$VERSION
=
'2.05'
;
}
sub
test {
my
(
$f
,
$encoding
)=
@_
;
if
(
ref
(
$f
)) {
return
$f
->getline()=~/^pst0/;
}
else
{
my
$fh
= open_backend(
$f
,
"r"
);
my
$test
=
$fh
&& test(
$fh
,
$encoding
);
close_backend(
$fh
);
return
$test
;
}
}
sub
open_backend {
Treex::PML::IO::open_backend(
@_
[0,1]);
}
sub
read
{
my
(
$fd
,
$fs
)=
@_
;
binmode
(
$fd
);
my
$restore
= fd_retrieve(
$fd
);
my
$api_version
=
$restore
->[6];
unless
(
$Treex::PML::COMPATIBLE_API_VERSION
{
$api_version
}) {
$api_version
=
'0.001'
unless
defined
$api_version
;
warn
"Warning: the binary file "
.
$fs
->filename.
" is a dump of structures created by possibly incompatible Treex::PML API version $api_version (the current Treex::PML API version is $Treex::PML::API_VERSION)\n"
;
}
if
(
ref
(
$restore
->[0]) eq
'FSFormat'
and not
defined
(
$Fslib::VERSION
)) {
upgrade_from_fslib(
$restore
);
}
$fs
->changeTail(@{
$restore
->[2]});
$fs
->[13]=
$restore
->[3];
my
$appData
=
delete
$fs
->[13]->{
'StorableBackend:savedAppData'
};
if
(
$appData
) {
$fs
->changeAppData(
$_
,
$appData
->{
$_
})
foreach
keys
(
%$appData
);
}
$fs
->changePatterns(@{
$restore
->[4]});
$fs
->changeHint(
$restore
->[5]);
my
$schema
=
$fs
->metaData(
'schema'
);
if
(
ref
(
$schema
) and !
$schema
->{-api_version}) {
$schema
->convert_from_hash();
$schema
->post_process();
}
$fs
->changeFS(
$restore
->[0]);
$fs
->changeTrees(@{
$restore
->[1]});
$fs
->FS->renew_specials();
}
sub
write
{
my
(
$fd
,
$fs
)=
@_
;
binmode
(
$fd
);
my
$metaData
= { %{
$fs
->[13]} };
my
$ref
=
$fs
->appData(
'ref'
);
$metaData
->{
'StorableBackend:savedAppData'
}||={};
foreach
my
$savedAppData
(
$metaData
->{
'StorableBackend:savedAppData'
}) {
$savedAppData
->{
'id-hash'
} =
$fs
->appData(
'id-hash'
);
$savedAppData
->{
'ref'
} = {
map
{
my
$val
=
$ref
->{
$_
};
UNIVERSAL::DOES::does(
$val
,
'Treex::PML::Instance'
) ? (
$_
=>
$val
) : ()
}
keys
%$ref
}
if
ref
$ref
;
}
nstore_fd([
$fs
->FS,
$fs
->treeList,
[
$fs
->tail],
$metaData
,
[
$fs
->patterns],
$fs
->hint,
$Treex::PML::API_VERSION
],
$fd
);
}
sub
upgrade_from_fslib {
my
@next
=
@_
;
my
%seen
;
$seen
{refaddr(
$_
)}=1
for
@next
;
while
(
@next
) {
my
$object
=
shift
@next
;
my
$ref
=
ref
(
$object
);
next
unless
$ref
;
my
$is
= blessed(
$object
);
if
(
defined
$is
) {
if
(
$is
=~ /^Treex/) {
}
elsif
(
$is
eq
'FSNode'
) {
bless
$object
,
'Treex::PML::Node'
;
}
elsif
(
$is
eq
'Fslib::Type'
) {
bless
$object
,
'Treex::PML::Backend::Storable::CopmpatType'
;
}
elsif
(
$is
=~ /^Fslib::(.*)$/) {
bless
$object
,
qq{Treex::PML::$1}
;
}
elsif
(
$is
=~ /^PMLSchema(::.*)?$/) {
bless
$object
,
qq{Treex::PML::Schema$1}
;
}
elsif
(
$is
eq
'FSFile'
) {
bless
$object
,
'Treex::PML::Document'
;
}
elsif
(
$is
eq
'FSFormat'
) {
bless
$object
,
'Treex::PML::FSFormat'
;
}
elsif
(
$is
eq
'PMLInstance'
) {
bless
$object
,
'Treex::PML::Instance'
;
}
$ref
= reftype(
$object
);
}
for
((
$ref
eq
'HASH'
) ?
values
(
%$object
)
: (
$ref
eq
'ARRAY'
) ?
@$object
: (
$ref
eq
'SCALAR'
) ?
$$object
: ()) {
my
$key
= refaddr(
$_
) ||
next
;
push
@next
,
$_
unless
(
$seen
{
$key
}++);
}
}
}
sub
schema {
my
(
$self
)=
@_
;
return
$self
->[0];
}
sub
type_decl {
my
(
$self
)=
@_
;
return
$self
->[1];
}
sub
AUTOLOAD {
my
$self
=
shift
;
croak
"$self is not an object"
unless
ref
(
$self
);
my
$name
=
$AUTOLOAD
;
$name
=~ s/.*://;
return
$self
->[1]->
$name
(
@_
);
}
1;
Hide Show 31 lines of Pod