xref: /openbsd-src/gnu/usr.bin/perl/os2/OS2/OS2-PrfDB/PrfDB.pm (revision b39c515898423c8d899e35282f4b395f7cad3298)
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