1*b39c5158Smillertpackage OS2::PrfDB; 2*b39c5158Smillert 3*b39c5158Smillertuse strict; 4*b39c5158Smillert 5*b39c5158Smillertrequire Exporter; 6*b39c5158Smillertuse XSLoader; 7*b39c5158Smillertuse Tie::Hash; 8*b39c5158Smillert 9*b39c5158Smillertour $debug; 10*b39c5158Smillertour @ISA = qw(Exporter Tie::Hash); 11*b39c5158Smillert# Items to export into callers namespace by default. Note: do not export 12*b39c5158Smillert# names by default without a very good reason. Use EXPORT_OK instead. 13*b39c5158Smillert# Do not simply export all your public functions/methods/constants. 14*b39c5158Smillertour @EXPORT = qw( 15*b39c5158Smillert AnyIni UserIni SystemIni 16*b39c5158Smillert ); 17*b39c5158Smillertour $VERSION = '0.04'; 18*b39c5158Smillert 19*b39c5158SmillertXSLoader::load 'OS2::PrfDB', $VERSION; 20*b39c5158Smillert 21*b39c5158Smillert# Preloaded methods go here. 22*b39c5158Smillert 23*b39c5158Smillertsub AnyIni { 24*b39c5158Smillert new_from_int OS2::PrfDB::Hini OS2::Prf::System(0), 25*b39c5158Smillert 'Anyone of two "systemish" databases', 1; 26*b39c5158Smillert} 27*b39c5158Smillert 28*b39c5158Smillertsub UserIni { 29*b39c5158Smillert new_from_int OS2::PrfDB::Hini OS2::Prf::System(1), 'User settings database', 1; 30*b39c5158Smillert} 31*b39c5158Smillert 32*b39c5158Smillertsub SystemIni { 33*b39c5158Smillert new_from_int OS2::PrfDB::Hini OS2::Prf::System(2),'System settings database',1; 34*b39c5158Smillert} 35*b39c5158Smillert 36*b39c5158Smillert# Internal structure 0 => HINI, 1 => array of entries, 2 => iterator. 37*b39c5158Smillert 38*b39c5158Smillertsub TIEHASH { 39*b39c5158Smillert die "Usage: tie %arr, OS2::PrfDB, filename\n" unless @_ == 2; 40*b39c5158Smillert my ($obj, $file) = @_; 41*b39c5158Smillert my $hini = ref $file eq 'OS2::PrfDB::Hini' ? $file 42*b39c5158Smillert : new OS2::PrfDB::Hini $file; 43*b39c5158Smillert die "Error opening profile database `$file': $!" unless $hini; 44*b39c5158Smillert # print "tiehash `@_', hini $hini\n" if $debug; 45*b39c5158Smillert bless [$hini, undef, undef]; 46*b39c5158Smillert} 47*b39c5158Smillert 48*b39c5158Smillertsub STORE { 49*b39c5158Smillert my ($self, $key, $val) = @_; 50*b39c5158Smillert die unless @_ == 3; 51*b39c5158Smillert die unless ref $val eq 'HASH'; 52*b39c5158Smillert my %sub; 53*b39c5158Smillert tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key; 54*b39c5158Smillert %sub = %$val; 55*b39c5158Smillert} 56*b39c5158Smillert 57*b39c5158Smillertsub FETCH { 58*b39c5158Smillert my ($self, $key) = @_; 59*b39c5158Smillert die unless @_ == 2; 60*b39c5158Smillert my %sub; 61*b39c5158Smillert tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key; 62*b39c5158Smillert \%sub; 63*b39c5158Smillert} 64*b39c5158Smillert 65*b39c5158Smillertsub DELETE { 66*b39c5158Smillert my ($self, $key) = @_; 67*b39c5158Smillert die unless @_ == 2; 68*b39c5158Smillert my %sub; 69*b39c5158Smillert tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key; 70*b39c5158Smillert %sub = (); 71*b39c5158Smillert} 72*b39c5158Smillert 73*b39c5158Smillert# CLEAR ???? - deletion of the whole 74*b39c5158Smillert 75*b39c5158Smillertsub EXISTS { 76*b39c5158Smillert my ($self, $key) = @_; 77*b39c5158Smillert die unless @_ == 2; 78*b39c5158Smillert return OS2::Prf::GetLength($self->[0]->[0], $key, undef) >= 0; 79*b39c5158Smillert} 80*b39c5158Smillert 81*b39c5158Smillertsub FIRSTKEY { 82*b39c5158Smillert my $self = shift; 83*b39c5158Smillert my $keys = OS2::Prf::Get($self->[0]->[0], undef, undef); 84*b39c5158Smillert return undef unless defined $keys; 85*b39c5158Smillert chop($keys); 86*b39c5158Smillert $self->[1] = [split /\0/, $keys]; 87*b39c5158Smillert # print "firstkey1 $self, `$self->[3]->[0], $self->[3]->[1]'\n" if $debug; 88*b39c5158Smillert $self->[2] = 0; 89*b39c5158Smillert return $self->[1]->[0]; 90*b39c5158Smillert # OS2::Prf::Get($self->[0]->[0], $self->[2], $self->[3]->[0])); 91*b39c5158Smillert} 92*b39c5158Smillert 93*b39c5158Smillertsub NEXTKEY { 94*b39c5158Smillert # print "nextkey `@_'\n" if $debug; 95*b39c5158Smillert my $self = shift; 96*b39c5158Smillert return undef unless $self->[2]++ < $#{$self->[1]}; 97*b39c5158Smillert my $key = $self->[1]->[$self->[2]]; 98*b39c5158Smillert return $key; #, OS2::Prf::Get($self->[0]->[0], $self->[2], $key)); 99*b39c5158Smillert} 100*b39c5158Smillert 101*b39c5158Smillertpackage OS2::PrfDB::Hini; 102*b39c5158Smillert 103*b39c5158Smillertsub new { 104*b39c5158Smillert die "Usage: new OS2::PrfDB::Hini filename\n" unless @_ == 2; 105*b39c5158Smillert shift; 106*b39c5158Smillert my $file = shift; 107*b39c5158Smillert my $hini = OS2::Prf::Open($file); 108*b39c5158Smillert die "Error opening profile database `$file': $!" unless $hini; 109*b39c5158Smillert bless [$hini, $file]; 110*b39c5158Smillert} 111*b39c5158Smillert 112*b39c5158Smillert# Takes HINI and file name: 113*b39c5158Smillert 114*b39c5158Smillertsub new_from_int { shift; bless [@_] } 115*b39c5158Smillert 116*b39c5158Smillert# Internal structure 0 => HINI, 1 => filename, 2 => do-not-close. 117*b39c5158Smillert 118*b39c5158Smillertsub DESTROY { 119*b39c5158Smillert my $self = shift; 120*b39c5158Smillert my $hini = $self->[0]; 121*b39c5158Smillert unless ($self->[2]) { 122*b39c5158Smillert OS2::Prf::Close($hini) or die "Error closing profile `$self->[1]': $!"; 123*b39c5158Smillert } 124*b39c5158Smillert} 125*b39c5158Smillert 126*b39c5158Smillertpackage OS2::PrfDB::Sub; 127*b39c5158Smillertuse Tie::Hash; 128*b39c5158Smillert 129*b39c5158Smillertour $debug; 130*b39c5158Smillertour @ISA = qw{Tie::Hash}; 131*b39c5158Smillert 132*b39c5158Smillert# Internal structure 0 => HINI, 1 => array of entries, 2 => iterator, 133*b39c5158Smillert# 3 => appname. 134*b39c5158Smillert 135*b39c5158Smillertsub TIEHASH { 136*b39c5158Smillert die "Usage: tie %arr, OS2::PrfDB::Sub, filename, appname\n" unless @_ == 3; 137*b39c5158Smillert my ($obj, $file, $app) = @_; 138*b39c5158Smillert my $hini = ref $file eq 'OS2::PrfDB::Hini' ? $file 139*b39c5158Smillert : new OS2::PrfDB::Hini $file; 140*b39c5158Smillert die "Error opening profile database `$file': $!" unless $hini; 141*b39c5158Smillert # print "tiehash `@_', hini $hini\n" if $debug; 142*b39c5158Smillert bless [$hini, undef, undef, $app]; 143*b39c5158Smillert} 144*b39c5158Smillert 145*b39c5158Smillertsub STORE { 146*b39c5158Smillert my ($self, $key, $val) = @_; 147*b39c5158Smillert die unless @_ == 3; 148*b39c5158Smillert OS2::Prf::Set($self->[0]->[0], $self->[3], $key, $val); 149*b39c5158Smillert} 150*b39c5158Smillert 151*b39c5158Smillertsub FETCH { 152*b39c5158Smillert my ($self, $key) = @_; 153*b39c5158Smillert die unless @_ == 2; 154*b39c5158Smillert OS2::Prf::Get($self->[0]->[0], $self->[3], $key); 155*b39c5158Smillert} 156*b39c5158Smillert 157*b39c5158Smillertsub DELETE { 158*b39c5158Smillert my ($self, $key) = @_; 159*b39c5158Smillert die unless @_ == 2; 160*b39c5158Smillert OS2::Prf::Set($self->[0]->[0], $self->[3], $key, undef); 161*b39c5158Smillert} 162*b39c5158Smillert 163*b39c5158Smillert# CLEAR ???? - deletion of the whole 164*b39c5158Smillert 165*b39c5158Smillertsub EXISTS { 166*b39c5158Smillert my ($self, $key) = @_; 167*b39c5158Smillert die unless @_ == 2; 168*b39c5158Smillert return OS2::Prf::GetLength($self->[0]->[0], $self->[3], $key) >= 0; 169*b39c5158Smillert} 170*b39c5158Smillert 171*b39c5158Smillertsub FIRSTKEY { 172*b39c5158Smillert my $self = shift; 173*b39c5158Smillert my $keys = OS2::Prf::Get($self->[0]->[0], $self->[3], undef); 174*b39c5158Smillert return undef unless defined $keys; 175*b39c5158Smillert chop($keys); 176*b39c5158Smillert $self->[1] = [split /\0/, $keys]; 177*b39c5158Smillert # print "firstkey1 $self, `$self->[3]->[0], $self->[3]->[1]'\n" if $debug; 178*b39c5158Smillert $self->[2] = 0; 179*b39c5158Smillert return $self->[1]->[0]; 180*b39c5158Smillert # OS2::Prf::Get($self->[0]->[0], $self->[2], $self->[3]->[0])); 181*b39c5158Smillert} 182*b39c5158Smillert 183*b39c5158Smillertsub NEXTKEY { 184*b39c5158Smillert # print "nextkey `@_'\n" if $debug; 185*b39c5158Smillert my $self = shift; 186*b39c5158Smillert return undef unless $self->[2]++ < $#{$self->[1]}; 187*b39c5158Smillert my $key = $self->[1]->[$self->[2]]; 188*b39c5158Smillert return $key; #, OS2::Prf::Get($self->[0]->[0], $self->[2], $key)); 189*b39c5158Smillert} 190*b39c5158Smillert 191*b39c5158Smillert# Autoload methods go after =cut, and are processed by the autosplit program. 192*b39c5158Smillert 193*b39c5158Smillert1; 194*b39c5158Smillert__END__ 195*b39c5158Smillert# Below is the stub of documentation for your module. You better edit it! 196*b39c5158Smillert 197*b39c5158Smillert=head1 NAME 198*b39c5158Smillert 199*b39c5158SmillertOS2::PrfDB - Perl extension for access to OS/2 setting database. 200*b39c5158Smillert 201*b39c5158Smillert=head1 SYNOPSIS 202*b39c5158Smillert 203*b39c5158Smillert use OS2::PrfDB; 204*b39c5158Smillert tie %settings, OS2::PrfDB, 'my.ini'; 205*b39c5158Smillert tie %subsettings, OS2::PrfDB::Sub, 'my.ini', 'mykey'; 206*b39c5158Smillert 207*b39c5158Smillert print "$settings{firstkey}{subkey}\n"; 208*b39c5158Smillert print "$subsettings{subkey}\n"; 209*b39c5158Smillert 210*b39c5158Smillert tie %system, OS2::PrfDB, SystemIni; 211*b39c5158Smillert $system{myapp}{mykey} = "myvalue"; 212*b39c5158Smillert 213*b39c5158Smillert 214*b39c5158Smillert=head1 DESCRIPTION 215*b39c5158Smillert 216*b39c5158SmillertThe extension provides both high-level and low-level access to .ini 217*b39c5158Smillertfiles. 218*b39c5158Smillert 219*b39c5158Smillert=head2 High level access 220*b39c5158Smillert 221*b39c5158SmillertHigh-level access is the tie-hash access via two packages: 222*b39c5158SmillertC<OS2::PrfDB> and C<OS2::PrfDB::Sub>. First one supports one argument, 223*b39c5158Smillertthe name of the file to open, the second one the name of the file to 224*b39c5158Smillertopen and so called I<Application name>, or the primary key of the 225*b39c5158Smillertdatabase. 226*b39c5158Smillert 227*b39c5158Smillert tie %settings, OS2::PrfDB, 'my.ini'; 228*b39c5158Smillert tie %subsettings, OS2::PrfDB::Sub, 'my.ini', 'mykey'; 229*b39c5158Smillert 230*b39c5158SmillertOne may substitute a handle for already opened ini-file instead of the 231*b39c5158Smillertfile name (obtained via low-level access functions). In particular, 3 232*b39c5158Smillertfunctions SystemIni(), UserIni(), and AnyIni() provide handles to the 233*b39c5158Smillert"systemish" databases. AniIni will read from both, and write into User 234*b39c5158Smillertdatabase. 235*b39c5158Smillert 236*b39c5158Smillert=head2 Low-level access 237*b39c5158Smillert 238*b39c5158SmillertLow-level access functions reside in the package C<OS2::Prf>. They are 239*b39c5158Smillert 240*b39c5158Smillert=over 14 241*b39c5158Smillert 242*b39c5158Smillert=item C<Open(file)> 243*b39c5158Smillert 244*b39c5158SmillertOpens the database, returns an I<integer handle>. 245*b39c5158Smillert 246*b39c5158Smillert=item C<Close(hndl)> 247*b39c5158Smillert 248*b39c5158SmillertCloses the database given an I<integer handle>. 249*b39c5158Smillert 250*b39c5158Smillert=item C<Get(hndl, appname, key)> 251*b39c5158Smillert 252*b39c5158SmillertRetrieves data from the database given 2-part-key C<appname> C<key>. 253*b39c5158SmillertIf C<key> is C<undef>, return the "\0" delimited list of C<key>s, 254*b39c5158Smillertterminated by \0. If C<appname> is C<undef>, returns the list of 255*b39c5158Smillertpossible C<appname>s in the same form. 256*b39c5158Smillert 257*b39c5158Smillert=item C<GetLength(hndl, appname, key)> 258*b39c5158Smillert 259*b39c5158SmillertSame as above, but returns the length of the value. 260*b39c5158Smillert 261*b39c5158Smillert=item C<Set(hndl, appname, key, value [ , length ])> 262*b39c5158Smillert 263*b39c5158SmillertSets the value. If the C<value> is not defined, removes the C<key>. If 264*b39c5158Smillertthe C<key> is not defined, removes the C<appname>. 265*b39c5158Smillert 266*b39c5158Smillert=item C<System(val)> 267*b39c5158Smillert 268*b39c5158SmillertReturn an I<integer handle> associated with the system database. If 269*b39c5158SmillertC<val> is 1, it is I<User> database, if 2, I<System> database, if 270*b39c5158Smillert0, handle for "both" of them: the handle works for read from any one, 271*b39c5158Smillertand for write into I<User> one. 272*b39c5158Smillert 273*b39c5158Smillert=item C<Profiles()> 274*b39c5158Smillert 275*b39c5158Smillertreturns a reference to a list of two strings, giving names of the 276*b39c5158SmillertI<User> and I<System> databases. 277*b39c5158Smillert 278*b39c5158Smillert=item C<SetUser(file)> 279*b39c5158Smillert 280*b39c5158SmillertB<(Not tested.)> Sets the profile name of the I<User> database. The 281*b39c5158Smillertapplication should have a message queue to use this function! 282*b39c5158Smillert 283*b39c5158Smillert=back 284*b39c5158Smillert 285*b39c5158Smillert=head2 Integer handles 286*b39c5158Smillert 287*b39c5158SmillertTo convert a name or an integer handle into an object acceptable as 288*b39c5158Smillertargument to tie() interface, one may use the following functions from 289*b39c5158Smillertthe package C<OS2::Prf::Hini>: 290*b39c5158Smillert 291*b39c5158Smillert=over 14 292*b39c5158Smillert 293*b39c5158Smillert=item C<new(package, file)> 294*b39c5158Smillert 295*b39c5158Smillert=item C<new_from_int(package, int_hndl [ , filename ])> 296*b39c5158Smillert 297*b39c5158Smillert=back 298*b39c5158Smillert 299*b39c5158Smillert=head2 Exports 300*b39c5158Smillert 301*b39c5158SmillertSystemIni(), UserIni(), and AnyIni(). 302*b39c5158Smillert 303*b39c5158Smillert=head1 AUTHOR 304*b39c5158Smillert 305*b39c5158SmillertIlya Zakharevich, ilya@math.ohio-state.edu 306*b39c5158Smillert 307*b39c5158Smillert=head1 SEE ALSO 308*b39c5158Smillert 309*b39c5158Smillertperl(1). 310*b39c5158Smillert 311*b39c5158Smillert=cut 312*b39c5158Smillert 313