deprecated/buildtools/buildsystemtools/lib/freezethaw/FreezeThaw.pm
author lorewang
Thu, 11 Nov 2010 11:26:32 +0800
changeset 677 44e49837144a
parent 655 3f65fd25dfd4
permissions -rw-r--r--
update release info
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
655
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     1
=head1 NAME
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     2
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     3
FreezeThaw - converting Perl structures to strings and back.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     5
=head1 SYNOPSIS
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     6
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     7
  use FreezeThaw qw(freeze thaw cmpStr safeFreeze cmpStrHard);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     8
  $string = freeze $data1, $data2, $data3;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     9
  ...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    10
  ($olddata1, $olddata2, $olddata3) = thaw $string;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    11
  if (cmpStr($olddata2,$data2) == 0) {print "OK!"}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    12
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    13
=head1 DESCRIPTION
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    14
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    15
Converts data to/from stringified form, appropriate for
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    16
saving-to/reading-from permanent storage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    17
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    18
Deals with objects, circular lists, repeated appearence of the same
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    19
refence. Does not deal with overloaded I<stringify> operator yet.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    20
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    21
=head1 EXPORT
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    22
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    23
=over 12
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    24
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    25
=item Default
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    26
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    27
None.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    28
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    29
=item Exportable
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    30
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    31
C<freeze thaw cmpStr cmpStrHard safeFreeze>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    32
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    33
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    34
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    35
=head1 User API
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    36
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    37
=over 12
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    38
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    39
=item C<cmpStr>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    40
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    41
analogue of C<cmp> for data. Takes two arguments and compares them as
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    42
separate entities.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    43
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    44
=item C<cmpStrHard>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    45
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    46
analogue of C<cmp> for data. Takes two arguments and compares them
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    47
considered as a group.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    48
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    49
=item C<freeze>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    50
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    51
returns a string that encupsulates its arguments (considered as a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    52
group). C<thaw>ing this string leads to a fatal error if arguments to
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    53
C<freeze> contained references to C<GLOB>s and C<CODE>s.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    54
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    55
=item C<safeFreeze>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    56
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    57
returns a string that encupsulates its arguments (considered as a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    58
group). The result is C<thaw>able in the same process. C<thaw>ing the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    59
result in a different process should result in a fatal error if
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    60
arguments to C<safeFreeze> contained references to C<GLOB>s and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    61
C<CODE>s.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    62
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    63
=item C<thaw>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    64
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    65
takes one string argument and returns an array. The elements of the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    66
array are "equivalent" to arguments of the C<freeze> command that
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    67
created the string. Can result in a fatal error (see above).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    68
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    69
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    70
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    71
=head1 Developer API
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    72
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    73
C<FreezeThaw> C<freeze>s and C<thaw>s data blessed in some package by
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    74
calling methods C<Freeze> and C<Thaw> in the package. The fallback
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    75
methods are provided by the C<FreezeThaw> itself. The fallback
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    76
C<Freeze> freezes the "content" of blessed object (from Perl point of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    77
view). The fallback C<Thaw> blesses the C<thaw>ed data back into the package.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    78
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    79
So the package needs to define its own methods only if the fallback
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    80
methods will fail (for example, for a lot of data the "content" of an
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    81
object is an address of some B<C> data). The methods are called like
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    82
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    83
  $newcooky = $obj->Freeze($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    84
  $obj = Package->Thaw($content,$cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    85
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    86
To save and restore the data the following method are applicable:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    87
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    88
  $cooky->FreezeScalar($data,$ignorePackage,$noduplicate);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    89
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    90
during Freeze()ing, and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    91
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    92
  $data = $cooky->ThawScalar;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    93
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    94
Two optional arguments $ignorePackage and $noduplicate regulate
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    95
whether the freezing should not call the methods even if $data is a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    96
reference to a blessed object, and whether the data should not be
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    97
marked as seen already even if it was seen before. The default methods
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    98
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    99
  sub UNIVERSAL::Freeze {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   100
    my ($obj, $cooky) = (shift, shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   101
    $cooky->FreezeScalar($obj,1,1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   102
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   103
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   104
  sub UNIVERSAL::Thaw {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   105
    my ($package, $cooky) = (shift, shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   106
    my $obj = $cooky->ThawScalar;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   107
    bless $obj, $package;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   108
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   109
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   110
call the C<FreezeScalar> method of the $cooky since the freezing
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   111
engine will see the data the second time during this call. Indeed, it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   112
is the freezing engine who calls UNIVERSAL::Freeze(), and it calls it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   113
because it needs to freeze $obj. The above call to
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   114
$cooky->FreezeScalar() handles the same data back to engine, but
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   115
because flags are different, the code does not cycle.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   116
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   117
Freezing and thawing $cooky also allows the following additional methods:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   118
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   119
  $cooky->isSafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   120
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   121
to find out whether the current freeze was initiated by C<freeze> or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   122
C<safeFreeze> command. Analogous method for thaw $cooky returns
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   123
whether the current thaw operation is considered safe (i.e., either
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   124
does not contain cached elsewhere data, or comes from the same
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   125
application). You can use
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   126
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   127
  $cooky->makeSafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   128
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   129
to prohibit cached data for the duration of the rest of freezing or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   130
thawing of current object.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   131
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   132
Two methods
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   133
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   134
  $value = $cooky->repeatedOK;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   135
  $cooky->noRepeated;		# Now repeated are prohibited
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   136
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   137
allow to find out/change the current setting for allowing repeated
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   138
references.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   139
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   140
If you want to flush the cache of saved objects you can use
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   141
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   142
  FreezeThaw->flushCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   143
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   144
this can invalidate some frozen string, so that thawing them will
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   145
result in fatal error.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   146
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   147
=head2 Instantiating
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   148
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   149
Sometimes, when an object from a package is recreated in presense of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   150
repeated references, it is not safe to recreate the internal structure
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   151
of an object in one step. In such a situation recreation of an object
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   152
is carried out in two steps: in the first the object is C<allocate>d,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   153
in the second it is C<instantiate>d.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   154
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   155
The restriction is that during the I<allocation> step you cannot use any
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   156
reference to any Perl object that can be referenced from any other
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   157
place. This restriction is applied since that object may not exist yet.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   158
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   159
Correspondingly, during I<instantiation> step the previosly I<allocated>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   160
object should be C<filled>, i.e., it can be changed in any way such
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   161
that the references to this object remain valid.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   162
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   163
The methods are called like this:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   164
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   165
  $pre_object_ref = Package->Allocate($pre_pre_object_ref);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   166
	# Returns reference
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   167
  Package->Instantiate($pre_object_ref,$cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   168
	# Converts into reference to blessed object
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   169
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   170
The reverse operations are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   171
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   172
  $object_ref->FreezeEmpty($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   173
  $object_ref->FreezeInstance($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   174
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   175
during these calls object can C<freezeScalar> some information (in a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   176
usual way) that will be used during C<Allocate> and C<Instantiate>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   177
calls (via C<thawScalar>). Note that the return value of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   178
C<FreezeEmpty> is cached during the phase of creation of uninialized
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   179
objects. This B<must> be used like this: the return value is the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   180
reference to the created object, so it is not destructed until other
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   181
objects are created, thus the frozen values of the different objects
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   182
will not share the same references. Example of bad result:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   183
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   184
  $o1->FreezeEmpty($cooky)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   185
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   186
freezes C<{}>, and C<$o2-E<gt>FreezeEmpty($cooky)> makes the same. Now
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   187
nobody guaranties that that these two copies of C<{}> are different,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   188
unless a reference to the first one is preserved during the call to
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   189
C<$o2-E<gt>FreezeEmpty($cooky)>. If C<$o1-E<gt>FreezeEmpty($cooky)>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   190
returns the value of C<{}> it uses, it will be preserved by the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   191
engine.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   192
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   193
The helper function C<FreezeThaw::copyContents> is provided for
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   194
simplification of instantiation. The syntax is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   195
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   196
  FreezeThaw::copyContents $to, $from;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   197
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   198
The function copies contents the object $from point to into what the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   199
object $to points to (including package for blessed references). Both
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   200
arguments should be references.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   201
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   202
The default methods are provided. They do the following:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   203
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   204
=over 12
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   205
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   206
=item C<FreezeEmpty>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   207
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   208
Freezes an I<empty> object of underlying type.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   209
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   210
=item C<FreezeInstance>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   211
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   212
Calls C<Freeze>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   213
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   214
=item C<Allocate>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   215
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   216
Thaws what was frozen by C<FreezeEmpty>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   217
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   218
=item C<Instantiate>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   219
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   220
Thaws what was frozen by C<FreezeInstance>, uses C<copyContents> to
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   221
transfer this to the $pre_object.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   222
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   223
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   224
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   225
=head1 BUGS and LIMITATIONS
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   226
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   227
A lot of objects are blessed in some obscure packages by XSUB
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   228
typemaps. It is not clear how to (automatically) prevent the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   229
C<UNIVERSAL> methods to be called for objects in these packages.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   230
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   231
The objects which can survive freeze()/thaw() cycle must also survive a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   232
change of a "member" to an equal member.  Say, after
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   233
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   234
  $a = [a => 3];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   235
  $a->{b} = \ $a->{a};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   236
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   237
$a satisfies
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   238
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   239
  $a->{b} == \ $a->{a}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   240
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   241
This property will be broken by freeze()/thaw(), but it is also broken by
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   242
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   243
  $a->{a} = delete $a->{a};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   244
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   245
=cut
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   246
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   247
require 5.002;			# defined ref stuff...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   248
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   249
# Different line noise chars:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   250
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   251
# $567|			next 567 chars form a scalar
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   252
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   253
# @34|			next 34 scalars form an array
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   254
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   255
# %34|			next 34 scalars form a hash
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   256
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   257
# ?			next scalar is a safe-stamp at beginning
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   258
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   259
# ?			next scalar is a stringified data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   260
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   261
# !  repeated array follows (after a scalar denoting array $#),
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   262
# (possibly?) followed by instantiation array. At beginning
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   263
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   264
# <45|			ordinal of element in repeated array
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   265
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   266
# *			stringified glob follows
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   267
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   268
# &			stringified coderef follows
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   269
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   270
# \\			stringified defererenced data follows
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   271
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   272
# /			stringified REx follows
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   273
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   274
# >			stringified package name follows, then frozen data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   275
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   276
# {			stringified package name follows, then allocation data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   277
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   278
# }			stringified package name follows, then instantiation data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   279
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   280
# _			frozen form of undef
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   281
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   282
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   283
package FreezeThaw;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   284
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   285
use Exporter;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   286
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   287
@ISA = qw(Exporter);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   288
$VERSION = '0.43';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   289
@EXPORT_OK = qw(freeze thaw cmpStr cmpStrHard safeFreeze);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   290
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   291
use strict;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   292
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   293
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   294
my $lock = (reverse time) ^ $$ ^ \&freezeString; # To distingush processes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   295
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   296
use vars qw( @multiple
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   297
	     %seen_packages
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   298
	     $seen_packages
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   299
	     %seen_packages
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   300
	     %count
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   301
	     %address
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   302
	     $string
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   303
	     $unsafe
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   304
	     $noCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   305
	     $cooky
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   306
	     $secondpass
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   307
	   ),			# Localized in freeze()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   308
	qw( $norepeated ),	# Localized in freezeScalar()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   309
	qw( $uninitOK ),	# Localized in thawScalar()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   310
	qw( @uninit ),		# Localized in thaw()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   311
	qw($safe);		# Localized in safeFreeze()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   312
my (%saved);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   313
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   314
my %Empty = ( ARRAY   => sub {[]}, HASH => sub {{}},
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   315
	      SCALAR  => sub {my $undef; \$undef},
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   316
	      REF     => sub {my $undef; \$undef},
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   317
	      CODE    => 1,		# 1 means atomic
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   318
	      GLOB    => 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   319
	      Regexp  => 0,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   320
	 );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   321
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   322
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   323
sub flushCache {$lock ^= rand; undef %saved;}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   324
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   325
sub getref ($) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   326
  my $ref = ref $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   327
  return $ref if not $ref or defined $Empty{$ref}; # Optimization _and_ Regexp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   328
  my $str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   329
  if (defined &overload::StrVal) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   330
    $str = overload::StrVal($_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   331
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   332
    $str = "$_[0]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   333
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   334
  $ref = $1 if $str =~ /=(\w+)/;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   335
  $ref;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   336
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   337
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   338
sub freezeString {$string .= "\$" . length($_[0]) . '|' . $_[0]}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   339
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   340
sub freezeNumber {$string .= $_[0] . '|'}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   341
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   342
sub freezeREx {$string .= '/' . length($_[0]) . '|' . $_[0]}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   343
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   344
sub thawString {	# Returns list: a string and offset of rest
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   345
  substr($string, $_[0]) =~ /^\$(\d+)\|/
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   346
    or confess "Wrong format of frozen string: " . substr($string, $_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   347
  length($string) - $_[0] > length($1) + 1 + $1
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   348
    or confess "Frozen string too short: `" .
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   349
      substr($string, $_[0]) . "', expect " . (length($1) + 2 + $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   350
  (substr($string, $_[0] + length($1) + 2, $1), $_[0] + length($1) + 2 + $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   351
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   352
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   353
sub thawNumber {	# Returns list: a number and offset of rest
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   354
  substr($string, $_[0]) =~ /^(\d+)\|/
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   355
    or confess "Wrong format of frozen string: " . substr($string, $_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   356
  ($1, $_[0] + length($1) + 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   357
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   358
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   359
sub _2rex ($);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   360
if (eval '"Regexp" eq ref qr/1/') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   361
  eval 'sub _2rex ($) {my $r = shift; qr/$r/} 1' or die;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   362
} else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   363
  eval 'sub _2rex ($) { shift } 1' or die;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   364
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   365
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   366
sub thawREx {	# Returns list: a REx and offset of rest
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   367
  substr($string, $_[0]) =~ m,^/(\d+)\|,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   368
    or confess "Wrong format of frozen REx: " . substr($string, $_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   369
  length($string) - $_[0] > length($1) + 1 + $1
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   370
    or confess "Frozen string too short: `" .
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   371
      substr($string, $_[0]) . "', expect " . (length($1) + 2 + $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   372
  (_2rex substr($string, $_[0] + length($1) + 2, $1),
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   373
   $_[0] + length($1) + 2 + $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   374
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   375
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   376
sub freezeArray {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   377
  $string .= '@' . @{$_[0]} . '|';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   378
  for (@{$_[0]}) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   379
    freezeScalar($_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   380
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   381
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   382
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   383
sub thawArray {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   384
  substr($string, $_[0]) =~ /^[\@%](\d+)\|/ # % To make it possible thaw hashes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   385
    or confess "Wrong format of frozen array: \n$_[0]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   386
  my $count = $1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   387
  my $off = $_[0] + 2 + length $count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   388
  my (@res, $res);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   389
  while ($count and length $string > $off) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   390
    ($res,$off) = thawScalar($off);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   391
    push(@res,$res);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   392
    --$count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   393
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   394
  confess "Wrong length of data in thawing Array: $count left" if $count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   395
  (\@res, $off);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   396
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   397
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   398
sub freezeHash {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   399
  my @arr = sort keys %{$_[0]};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   400
  $string .= '%' . (2*@arr) . '|';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   401
  for (@arr, @{$_[0]}{@arr}) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   402
    freezeScalar($_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   403
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   404
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   405
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   406
sub thawHash {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   407
  my ($arr, $rest) = &thawArray;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   408
  my %hash;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   409
  my $l = @$arr/2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   410
  foreach (0 .. $l - 1) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   411
    $hash{$arr->[$_]} = $arr->[$l + $_];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   412
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   413
  (\%hash,$rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   414
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   415
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   416
# Second optional argument: ignore the package
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   417
# Third optional one: do not check for duplicates on outer level
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   418
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   419
sub freezeScalar {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   420
  $string .= '_', return unless defined $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   421
  return &freezeString unless ref $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   422
  my $ref = ref $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   423
  my $str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   424
  if ($_[1] and $ref) {			# Similar to getref()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   425
    if (defined &overload::StrVal) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   426
      $str = overload::StrVal($_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   427
    } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   428
      $str = "$_[0]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   429
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   430
    $ref = $1 if $str =~ /=(\w+)/;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   431
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   432
    $str = "$_[0]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   433
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   434
  # Die if a) repeated prohibited, b) met, c) not explicitely requested to ingore.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   435
  confess "Repeated reference met when prohibited"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   436
    if $norepeated && !$_[2] && defined $count{$str};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   437
  if ($secondpass and !$_[2]) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   438
    $string .= "<$address{$str}|", return
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   439
      if defined $count{$str} and $count{$str} > 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   440
  } elsif (!$_[2]) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   441
    # $count{$str} is defined if we have seen it on this pass.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   442
    $address{$str} = @multiple, push(@multiple, $_[0])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   443
      if defined $count{$str} and not exists $address{$str};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   444
    # This is for debugging and shortening thrown-away output (also
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   445
    # internal data in arrays and hashes is not duplicated).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   446
    $string .= "<$address{$str}|", ++$count{$str}, return
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   447
      if defined $count{$str};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   448
    ++$count{$str};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   449
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   450
  return &freezeArray if $ref eq 'ARRAY';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   451
  return &freezeHash if $ref eq 'HASH';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   452
  return &freezeREx if $ref eq 'Regexp' and not defined ${$_[0]};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   453
  $string .= "*", return &freezeString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   454
    if $ref eq 'GLOB' and !$safe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   455
  $string .= "&", return &freezeString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   456
    if $ref eq 'CODE' and !$safe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   457
  $string .= '\\', return &freezeScalar( $ {shift()} )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   458
    if $ref eq 'REF' or $ref eq 'SCALAR';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   459
  if ($noCache and (($ref eq 'CODE') or $ref eq 'GLOB')) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   460
    confess "CODE and GLOB references prohibited now";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   461
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   462
  if ($safe and (($ref eq 'CODE') or $ref eq 'GLOB')) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   463
    $unsafe = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   464
    $saved{$str} = $_[0] unless defined $saved{$str};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   465
    $string .= "?";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   466
    return &freezeString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   467
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   468
  $string .= '>';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   469
  local $norepeated = $norepeated;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   470
  local $noCache = $noCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   471
  freezePackage(ref $_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   472
  $_[0]->Freeze($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   473
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   474
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   475
sub freezePackage {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   476
  my $packageid = $seen_packages{$_[0]};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   477
  if (defined $packageid) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   478
    $string .= ')';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   479
    &freezeNumber( $packageid );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   480
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   481
    $string .= '>';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   482
    &freezeNumber( $seen_packages );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   483
    &freezeScalar( $_[0] );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   484
    $seen_packages{ $_[0] } = $seen_packages++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   485
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   486
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   487
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   488
sub thawPackage {		# First argument: offset
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   489
  my $key = substr($string,$_[0],1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   490
  my ($get, $rest, $id);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   491
  ($id, $rest) = &thawNumber($_[0] + 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   492
  if ($key eq ')') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   493
    $get = $seen_packages{$id};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   494
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   495
    ($get, $rest) = &thawString($rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   496
    $seen_packages{$id} = $get;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   497
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   498
  ($get, $rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   499
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   500
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   501
# First argument: offset; Optional other: index in the @uninit array
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   502
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   503
sub thawScalar {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   504
  my $key = substr($string,$_[0],1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   505
  if ($key eq "\$") {&thawString}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   506
  elsif ($key eq '@') {&thawArray}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   507
  elsif ($key eq '%') {&thawHash}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   508
  elsif ($key eq '/') {&thawREx}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   509
  elsif ($key eq '\\') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   510
    my ($out,$rest) = &thawScalar( $_[0]+1 ) ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   511
    (\$out,$rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   512
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   513
  elsif ($key eq '_') { (undef, $_[0]+1) }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   514
  elsif ($key eq '&') {confess "Do not know how to thaw CODE"}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   515
  elsif ($key eq '*') {confess "Do not know how to thaw GLOB"}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   516
  elsif ($key eq '?') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   517
    my ($address,$rest) = &thawScalar( $_[0]+1 ) ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   518
    confess "The saved data accessed in unprotected thaw" unless $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   519
    confess "The saved data disappeared somewhere"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   520
      unless defined $saved{$address};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   521
    ($saved{$address},$rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   522
  } elsif ($key eq '<') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   523
    confess "Repeated data prohibited at this moment" unless $uninitOK;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   524
    my ($off,$end) = &thawNumber ($_[0]+1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   525
    ($uninit[$off],$end);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   526
  } elsif ($key eq '>' or $key eq '{' or $key eq '}') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   527
    my ($package,$rest) = &thawPackage( $_[0]+1 );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   528
    my $cooky = bless \$rest, 'FreezeThaw::TCooky';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   529
    local $uninitOK = $uninitOK;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   530
    local $unsafe = $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   531
    if ($key eq '{') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   532
      my $res = $package->Allocate($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   533
      ($res, $rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   534
    } elsif ($key eq '}') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   535
      warn "Here it is undef!" unless defined $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   536
      $package->Instantiate($uninit[$_[1]],$cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   537
      (undef, $rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   538
    } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   539
      ($package->Thaw($cooky),$rest);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   540
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   541
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   542
    confess "Do not know how to thaw data with code `$key'";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   543
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   544
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   545
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   546
sub freezeEmpty {		# Takes a type, freezes ref to empty object
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   547
  my $e = $Empty{ref $_[0]};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   548
  if (ref $e) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   549
    my $cache = &$e;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   550
    freezeScalar $cache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   551
    $cache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   552
  } elsif ($e) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   553
    my $cache = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   554
    freezeScalar($cache,1,1);	# Atomic
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   555
    $cache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   556
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   557
    $string .= "{";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   558
    freezePackage ref $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   559
    $_[0]->FreezeEmpty($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   560
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   561
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   562
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   563
sub freeze {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   564
  local @multiple;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   565
  local %seen_packages;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   566
  local $seen_packages = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   567
  local %seen_packages;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   568
#  local @seentypes;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   569
  local %count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   570
  local %address;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   571
  local $string = 'FrT;';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   572
  local $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   573
  local $noCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   574
  local $cooky = bless \$cooky, 'FreezeThaw::FCooky'; # Just something fake
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   575
  local $secondpass;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   576
  freezeScalar(\@_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   577
  if (@multiple) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   578
    # Now repeated structures are enumerated with order of *second* time
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   579
    # they appear in the what we freeze.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   580
    # What we want is to have them enumerated with respect to the first time
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   581
####    $string = '';		# Start again
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   582
####    @multiple = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   583
####    %address = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   584
####    for (keys %count) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   585
####      $count{$_} = undef if $count{$_} <= 1; # As at start
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   586
####      $count{$_} = 0 if $count{$_}; # As at start
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   587
####    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   588
####    $seen_packages = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   589
####    %seen_packages = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   590
####    freezeScalar(\@_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   591
    # Now repeated structures are enumerated with order of first time
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   592
    # they appear in the what we freeze
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   593
####    my $oldstring = substr $string, 4;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   594
    $string = 'FrT;!'; # Start again
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   595
    $seen_packages = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   596
    %seen_packages = ();	# XXXX We reshuffle parts of the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   597
                                # string, so the order of packages may
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   598
                                # be wrong...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   599
    freezeNumber($#multiple);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   600
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   601
      my @cache;		# Force different values for different
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   602
                                # empty objects.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   603
      foreach (@multiple) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   604
	push @cache, freezeEmpty $_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   605
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   606
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   607
#    for (keys %count) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   608
#      $count{$_} = undef
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   609
#	if !(defined $count{$_}) or $count{$_} <= 1; # As at start
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   610
#    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   611
    # $string .= '@' . @multiple . '|';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   612
    $secondpass = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   613
    for (@multiple) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   614
      freezeScalar($_,0,1,1), next if $Empty{ref $_};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   615
      $string .= "}";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   616
      freezePackage ref $_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   617
      $_->FreezeInstance($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   618
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   619
####    $string .= $oldstring;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   620
    freezeScalar(\@_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   621
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   622
  return "FrT;?\$" . length($lock) . "|" . $lock . substr $string, 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   623
    if $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   624
  $string;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   625
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   626
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   627
sub safeFreeze {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   628
  local $safe = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   629
  &freeze;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   630
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   631
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   632
sub copyContents {  # Given two references, copies contents of the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   633
                    # second one to the first one, provided they have
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   634
		    # the same basic type. The package is copied too.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   635
  my($first,$second) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   636
  my $ref = getref $second;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   637
  if ($ref eq 'SCALAR' or $ref eq 'REF') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   638
    $$first = $$second;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   639
  } elsif ($ref eq 'ARRAY') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   640
    @$first = @$second;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   641
  } elsif ($ref eq 'HASH') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   642
    %$first = %$second;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   643
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   644
    croak "Don't know how to copyContents of type `$ref'";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   645
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   646
  if (ref $second ne ref $first) { # Rebless
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   647
    # SvAMAGIC() is a property of a reference, not of a referent!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   648
    # Thus we cannot use $first here if $second was overloaded...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   649
    bless $_[0], ref $second;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   650
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   651
  $first;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   652
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   653
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   654
sub thaw {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   655
  confess "thaw requires one argument" unless @_ ==1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   656
  local $string = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   657
  local %seen_packages;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   658
  my $initoff = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   659
  #print STDERR "Thawing `$string'", substr ($string, 0, 4), "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   660
  if (substr($string, 0, 4) ne 'FrT;') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   661
    warn "Signature not present, continuing anyway" if $^W;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   662
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   663
    $initoff = 4;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   664
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   665
  local $unsafe = $initoff + (substr($string, $initoff, 1) eq "?" ? 1 : 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   666
  if ($unsafe != $initoff) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   667
    my $key;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   668
    ($key,$unsafe) = thawScalar($unsafe);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   669
    confess "The lock in frozen data does not match the key"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   670
      unless $key eq $lock;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   671
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   672
  local @multiple;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   673
  local $uninitOK = 1;		# The methods can change it.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   674
  my $repeated = substr($string,$unsafe,1) eq '!' ? 1 : 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   675
  my ($res, $off);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   676
  if ($repeated) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   677
    ($res, $off) = thawNumber($repeated + $unsafe);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   678
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   679
    ($res, $off) = thawScalar($repeated + $unsafe);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   680
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   681
  my $cooky = bless \$off, 'FreezeThaw::TCooky';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   682
  if ($repeated) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   683
    local @uninit;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   684
    my $lst = $res;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   685
    foreach (0..$lst) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   686
      ($res, $off) = thawScalar($off, $_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   687
      push(@uninit, $res);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   688
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   689
    my @init;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   690
    foreach (0..$lst) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   691
      ($res, $off) = thawScalar($off, $_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   692
      push(@init, $res);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   693
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   694
    #($init, $off)  = thawScalar($off);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   695
    #print "Instantiating...\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   696
    #my $ref;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   697
    for (0..$#uninit) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   698
      copyContents $uninit[$_], $init[$_] if ref $init[$_];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   699
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   700
    ($res, $off) = thawScalar($off);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   701
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   702
  croak "Extra elements in frozen structure: `" . substr($string,$off) . "'"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   703
    if $off != length $string;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   704
  return @$res;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   705
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   706
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   707
sub cmpStr {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   708
  confess "Compare requires two arguments" unless @_ == 2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   709
  freeze(shift) cmp freeze(shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   710
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   711
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   712
sub cmpStrHard {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   713
  confess "Compare requires two arguments" unless @_ == 2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   714
  local @multiple;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   715
#  local @seentypes;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   716
  local %count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   717
  local %address;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   718
  local $string = 'FrT;';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   719
  local $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   720
  local $noCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   721
  local $cooky = bless \$cooky, 'FreezeThaw::FCooky'; # Just something fake
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   722
  freezeScalar($_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   723
  my %cnt1 = %count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   724
  freezeScalar($_[1]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   725
  my %cnt2 = %count;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   726
  %count = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   727
  # Now all the caches are filled, delete the entries for guys which
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   728
  # are in one argument only.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   729
  my ($elt, $val);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   730
  while (($elt, $val) = each %cnt1) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   731
    $count{$elt}++ if $cnt2{$elt} > $cnt1{$elt};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   732
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   733
  $string = '';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   734
  freezeScalar($_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   735
  my $str1 = $string;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   736
  $string = '';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   737
  freezeScalar($_[1]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   738
  $str1 cmp $string;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   739
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   740
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   741
#   local $string = freeze(shift,shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   742
#   local $uninitOK = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   743
#   #print "$string\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   744
#   my $off = 7;			# Hardwired offset after @2|
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   745
#   if (substr($string,4,1) eq '!') {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   746
#     $off = 5;			# Hardwired offset after !
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   747
#     my ($uninit, $len);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   748
#     ($len,$off) = thawScalar $off;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   749
#     local @uninit;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   750
#     foreach (0..$len) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   751
#       ($uninit,$off) = thawScalar $off, $_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   752
#     }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   753
#     $off += 3;			# Hardwired offset after @2|
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   754
#   }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   755
#   croak "Unknown format of frozen array: " . substr($string,$off-3)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   756
#     unless substr($string,$off-3,1) eq '@';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   757
#   my ($first,$off2) = thawScalar $off;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   758
#   my $off3;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   759
#   ($first,$off3) = thawScalar $off2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   760
#   substr($string, $off, $off2-$off) cmp substr($string,$off2,$off3-$off2);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   761
# }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   762
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   763
sub FreezeThaw::FCooky::FreezeScalar {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   764
  shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   765
  &freezeScalar;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   766
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   767
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   768
sub FreezeThaw::FCooky::isSafe {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   769
  $safe || $noCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   770
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   771
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   772
sub FreezeThaw::FCooky::makeSafe {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   773
  $noCache = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   774
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   775
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   776
sub FreezeThaw::FCooky::repeatedOK {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   777
  !$norepeated;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   778
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   779
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   780
sub FreezeThaw::FCooky::noRepeated {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   781
  $norepeated = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   782
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   783
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   784
sub FreezeThaw::TCooky::repeatedOK {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   785
  $uninitOK;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   786
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   787
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   788
sub FreezeThaw::TCooky::noRepeated {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   789
  undef $uninitOK;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   790
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   791
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   792
sub FreezeThaw::TCooky::isSafe {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   793
  !$unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   794
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   795
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   796
sub FreezeThaw::TCooky::makeSafe {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   797
  undef $unsafe;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   798
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   799
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   800
sub FreezeThaw::TCooky::ThawScalar {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   801
  my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   802
  my ($res,$off) = &thawScalar($$self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   803
  $$self = $off;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   804
  $res;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   805
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   806
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   807
sub UNIVERSAL::Freeze {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   808
  my ($obj, $cooky) = (shift, shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   809
  $cooky->FreezeScalar($obj,1,1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   810
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   811
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   812
sub UNIVERSAL::Thaw {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   813
  my ($package, $cooky) = (shift, shift);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   814
  my $obj = $cooky->ThawScalar;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   815
  bless $obj, $package;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   816
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   817
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   818
sub UNIVERSAL::FreezeInstance {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   819
  my($obj,$cooky) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   820
  return if (ref $obj and ref $obj eq 'Regexp' and not defined $$obj); # Regexp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   821
  $obj->Freeze($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   822
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   823
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   824
sub UNIVERSAL::Instantiate {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   825
  my($package,$pre,$cooky) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   826
  return if $package eq 'Regexp';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   827
  my $obj = $package->Thaw($cooky);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   828
  # SvAMAGIC() is a property of a reference, not of a referent!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   829
  # Thus we cannot use $pre here if $obj was overloaded...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   830
  copyContents $_[1], $obj;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   831
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   832
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   833
sub UNIVERSAL::Allocate {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   834
  my($package,$cooky) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   835
  $cooky->ThawScalar;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   836
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   837
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   838
sub UNIVERSAL::FreezeEmpty {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   839
  my $obj = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   840
  my $type = getref $obj;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   841
  my $e = $Empty{$type};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   842
  if (ref $e) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   843
    my $ref = &$e;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   844
    freezeScalar $ref;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   845
    $ref;			# Put into cache.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   846
  } elsif ($e) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   847
    freezeScalar($obj,1,1);	# Atomic
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   848
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   849
  } elsif (defined $e and not defined $$obj) {	# Regexp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   850
    freezeREx($obj);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   851
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   852
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   853
    die "Do not know how to FreezeEmpty $type";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   854
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   855
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   856
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   857
1;