## read a string until a '\x00' is encountered (-> null termination of strings in C!)
sub read_complete_string {
my ($self) = @_;
my $string = "";
## return empty string if we're already at the end of the buffer
if($self->index() >= $self->size()) {
return $string;
}
my $end_of_string = index($self->buffer(), "\x00", $self->index());
if(!($end_of_string)) {
## just read the rest of the buffer if there is no termination
$string = $self->read_buffer($self->size() - $self->index());
}
else {
$string = $self->read_buffer($end_of_string - $self->index());
## ignore the nullbyte '\x00'
$self->skip(1);
}
return $string;
}
####
## read the specified number of bytes from buffer, called by the other read_* functions
sub read_buffer {
my ($self , $user_length) = @_;
my $length = 1;
$length = $user_length if $user_length;
if(($self->index() + $length) > $self->size()) { print "$tag: WARNING: ##### read_buffer(): not enough data left, ignoring request to read $length bytes! #####\n"; return 0; }
my $val = substr($self->buffer(), $self->index(), $length);
$self->index($self->index() + $length);
print "$tag: DEBUG: read_buffer(): read raw data '$val' of length $length, now at $self->{_index} (" . $self->data_left() . " bytes of " . $self->size() . " left)\n";
return $val;
}
## skips the given number of bytes
sub skip {
my ($self, $user_length) = @_;
my $default_length;
my $length;
$default_length = 1;
$length = $default_length;
$length = $user_length if $user_length;
$self->index($self->index() + $length);
return $length;
}
####
struct client_t {
short ping;
int rate;
char name[32]; // NULL-terminated
byte clanTagPosition; // 0: prefix, 1: suffix
char clanTag[32]; // NULL-terminated
byte isBot;
};
####
sub read_short {
my ($self) = @_;
my $sys_short_length = $Config{shortsize};
my $short = unpack('S', $self->read_buffer($sys_short_length));
return $short;
}
# elsewhere in the code:
print "ping: " . $self->package_reader->read_short() . "\n";