Thread Nested Keys dynamisch zuweisen (5 answers)
Opened by rosti at 2013-05-27 22:12

rosti
 2013-06-22 08:36
#168541 #168541
User since
2011-03-19
3492 Artikel
BenutzerIn
[Homepage]
user image
Moin ;)

Hab diesen stacker() mal erweitert, so dass auf dem letzten Key im Array ein Value drangehängt wird, hier ist eine Anwendung:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use IO::String;
use bytes;

my $bio = IO::String->new; # binary IO
$bio->binmode();

my $h = {
        'nix' => '',
        'root' => {
                1 => {
                        '1.1' => 'val_1.1',
                        '1.2' => 'val_1.2',
                        '1.3' => {
                                '1.3.1' => 'val_1.3.1',
                                '1.3.2' => 'val_1.3.2',
                        },
                },
                2 => 'val_2',
                'Umlaute in UTF-8' => 'äöüß',
        },
        'nochn_root' => 'hat_nur_einen_Value',
};

##################### serialize ###########################################
while( my($k, $v) = each %{$h}){
        serializer($k,$v);
}

sub serializer{
        my $key  = shift;
        my $stub = shift;
        my @bis  = @_;
        if(ref $stub eq 'HASH'){
                push @bis, $key;
                while(my($stubk, $stubv) = each %{$stub}){
                        serializer($stubk, $stubv, @bis);
                }
        }
        else{
                if(scalar @bis){
                        # zum Angucken
                        # printf "%s => %s => %s\n", join(" => ", @bis), $key, $stub;
                        # Algorithmus:
                        # Anzahl der Keys als N
                        # dann das Array mit den Keys
                        # zuletzt der Value
                        my $xbis = scalar(@bis);
                        $bio->print(pack('N', $xbis + 1));
                        foreach my $k(@bis){
                                $bio->print(pack('N', length($k)).$k);
                        }
                        # der letzte key vor dem Value
                        $bio->print(pack('N', length($key)).$key);
                        $bio->print(pack('N', length($stub)).$stub);
                }
                else{
                        # zum Angucken
                        # printf "%s => %s\n", $key, $stub;
                        $bio->print(pack('N', 1));
                        $bio->print(pack('N', length($key)).$key);
                        $bio->print(pack('N', length($stub)).$stub);
                }
        }
}

#################### de-serialize #########################################
$bio->seek(0,0);

my $result = {};

# Die Schleife läuft über die Anzahl der Keys: 4 byte
while(my $buffer = fread(4)){
        my $xkeys = unpack('N', $buffer);
        my @prekeys = ();
        foreach my $i(1..$xkeys){
                my $buffer = fread(4);
                my $lenpk = unpack 'N', $buffer;
                my $pk = $lenpk ? fread($lenpk) : '';
                push @prekeys, $pk;
        }
        # jetzt den Wert auslesen
        my $vlen = unpack('N', fread(4));
        my $val = $vlen ? fread($vlen) : '';
        stacker(\@prekeys, $result, $val);
}

# Ergebnis ausgeben
print Dumper $h, $result;


# keys als Referenzen aufeinander stocken
# der letzte Key bekommt den Wert
sub stacker{
        my ($ref, $hash, $val) = @_;
        my $last = pop @$ref;
        for my $el (@$ref) {
                $hash = $hash->{$el} ||= {};
        }
        $hash->{$last} = $val;
}

# wrapper für read, buffer as return-value
sub fread{
        my $len = shift;
        read($bio, my $buffer, $len);
        return $buffer;
}

View full thread Nested Keys dynamisch zuweisen