Files
cdesktop/cde/lib/tt/lib/mp/mp_arg.C
2018-04-28 12:30:20 -06:00

404 lines
8.1 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $XConsortium: mp_arg.C /main/3 1995/10/23 10:18:54 rswiston $
/*
*
* @(#)mp_arg.C 1.19 93/09/07
*
* Tool Talk Message Passer (MP) - mp_arg.C
*
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
*
* Implementation of the _Tt_arg & _Tt_arg_list classes representing
* arguments to a method or a procedure.
*/
#include "mp/mp_global.h"
#include "mp/mp_arg.h"
#include <stdlib.h>
#include <string.h>
#include "util/tt_enumname.h"
#include "util/tt_iostream.h"
#include "util/tt_xdr_utils.h"
#include "util/tt_global_env.h"
/*
* Construct a _Tt_arg with everything zeroed out
*/
_Tt_arg::
_Tt_arg()
{
constructor_common();
}
/*
* Copy constructor for _Tt_args.
*/
_Tt_arg::
_Tt_arg(const _Tt_arg &a)
{
_mode = a._mode;
_type = a._type;
_name = a._name;
_data_type = a._data_type;
_data_int = a._data_int;
_data_string = a._data_string;
}
/*
* Copy the _Tt_arg pointed to by a _Tt_arg_ptr.
*/
_Tt_arg::
_Tt_arg(const _Tt_arg_ptr &p)
{
_mode = p->_mode;
_type = p->_type;
_name = p->_name;
_data_type = p->_data_type;
_data_int = p->_data_int;
_data_string = p->_data_string;
}
_Tt_arg::
_Tt_arg(const _Tt_string &t)
{
constructor_common();
_type = t;
}
/*
* Constructs a _Tt_arg where the mode and type are known.
* No valid data is yet known.
*
*/
_Tt_arg::
_Tt_arg(Tt_mode m, _Tt_string &t)
{
constructor_common();
_mode = m;
_type = t;
}
_Tt_arg::
_Tt_arg(const char *t)
{
_Tt_string ts(t);
constructor_common();
_type = ts;
}
/*
* Constructs a _Tt_arg where the mode and type are known.
* No valid data is yet known.
*
*/
_Tt_arg::
_Tt_arg(Tt_mode m, const char *t)
{
_Tt_string ts(t);
constructor_common();
_mode = m;
_type = ts;
}
/*
* Destroys any memory associated with _Tt_arg
*/
_Tt_arg::
~_Tt_arg()
{
}
/*
* Sets the data associated with this arg as an integer
*/
Tt_status _Tt_arg::
set_data_int(int i)
{
_data_type = INT;
_data_int = i;
return TT_OK;
}
/*
* Sets the data associated with this arg as a byte string
*/
Tt_status _Tt_arg::
set_data_string(const _Tt_string &s)
{
_data_type = STRING;
_data_string = s;
return TT_OK;
}
/*
* Obtain the data for this arg as an int.
* Return TT_ERR_NUM if the value is a string.
*/
Tt_status _Tt_arg::
data_int(int &i) const
{
if (_data_type != INT) return TT_ERR_NUM;
i = _data_int;
return TT_OK;
}
/*
* Obtain the data for this arg as a string.
* Return TT_ERR_POINTER if the value is an int.
*/
Tt_status _Tt_arg::
data_string(_Tt_string &s) const
{
if (_data_type != STRING) return TT_ERR_POINTER;
s = _data_string;
return TT_OK;
}
/*
* Prints out a _Tt_arg. Mainly used for debugging purposes only.
*/
void _Tt_arg::
print(const _Tt_ostream &os) const
{
os << _tt_enumname(_mode) << " " << _type << ": ";
if (_name.len() > 0) {
os << "<" << _name << ">\n";
} else if (_data_type==INT) {
os << _data_int << "\n";
} else {
_data_string.print(os, _Tt_string_user_width, 1);
os << "\n";
}
}
/*
* XDR encodes and decodes a _Tt_arg object. Returns 1 if successful and
* 0 otherwise.
*/
bool_t _Tt_arg::
xdr(XDR *xdrs)
{
if (! xdr_int(xdrs, (int *)&_mode)) {
return(0);
}
if (! _type.xdr(xdrs)) {
return(0);
}
if (_tt_global->xdr_version() < TT_PUSH_ROTATE_XDR_VERSION) {
//
// Earlier versions of the XDR protocol included an
// a never-used _Tt_string called _matched_type.
//
_Tt_string _matched_type;
if (! _matched_type.xdr(xdrs)) {
return(0);
}
}
if (! _name.xdr(xdrs)) {
return(0);
}
if (! xdr_int(xdrs, (int *)&_data_type)) {
return(0);
}
if (_data_type==INT) {
if (! xdr_int(xdrs, &_data_int)) {
return(0);
}
} else {
if (! _data_string.xdr(xdrs)) {
return(0);
}
}
return(1);
}
/*
* update_value is used when merging a reply with the original message.
* The value cells of this arg are updated with the value cells in the
* given arg.
*/
Tt_status _Tt_arg::
update_value(const _Tt_arg &x)
{
_data_type = x._data_type;
_data_int = x._data_int;
_data_string = x._data_string;
return TT_OK;
}
/*
* Wrapper whose only purpose is to invoke the xdr method on the given
* pointer.
*/
bool_t
tt_xdr_arg(XDR *xdrs, _Tt_arg_ptr *ptr)
{
return((*ptr)->xdr(xdrs));
}
/*
* XDR encodes and decodes a list of _Tt_arg objects. p is assumed to
* point to the list on which to append/get the objects.
*/
bool_t
tt_xdr_arg_list(XDR *xdrs, _Tt_arg_list_ptr *p)
{
return((*p).xdr(xdrs));
}
void
_tt_arg_print(const _Tt_ostream &os, const _Tt_object *obj)
{
((_Tt_arg *)obj)->print(os);
}
/*
* Common initialization code for _Tt_arg constructors.
*/
void _Tt_arg::
constructor_common()
{
_mode = TT_MODE_UNDEFINED;
_type = (char *)0;
_name = (char *)0;
_data_type = UNSET;
_data_int = 0;
_data_string = (char *)0;
}
/*
* Returns non-zero score if \'this\', which must be a pattern arg, matches
* the given arg, which must be a message arg. Matching is
* less restrictive than equality, since the following exceptions
* apply:
* 1\) If the pattern type is ALL, it matches any type in the message.
* 2\) If the message type is ALL, it matches any type in the pattern.
* \[Somehow, the pattern type should get into the message, but
* I don\'t know how yet.\]
* 3\) If the pattern value is not set, it matches any value in the
* message.
* Although this method is only used in the server, it is too hard
* to figure out how to get messages and patterns un-XDRed in
* the server with args as a _Tt_s_arg instead of _Tt_arg.
*/
int _Tt_arg::
match_score(const _Tt_arg &msg_arg, int &used_wildcard) const
{
// Comparing args works because XDR is defined as always
// padding with zeroes.
int score = 1; // wildcard match scores only 1
used_wildcard = 0;
// match modes
if (_mode == msg_arg.mode()) {
score++;
} else if (_mode != TT_MODE_UNDEFINED) {
return 0;
}
// match types
if (_type == msg_arg.type()) {
// check equality first, in case both are "ALL"
score++;
} else if (_type == "ALL") {
used_wildcard = 1; // pattern ALL matches everything
} else if (msg_arg.type() == "ALL") {
used_wildcard = 1; // message ALL matches everything
} else {
return 0; // types mismatched
}
// match values
switch (_data_type) {
case INT:
case STRING:
default:
if (msg_arg.data_type() != _data_type) {
return 0;
}
switch (_data_type) {
case INT:
if (msg_arg.data_int() != _data_int) {
return 0;
}
break;
case STRING:
if (msg_arg.data_string() != _data_string) {
return 0;
}
break;
default:
return 0;
}
score++;
break;
case UNSET:
if (msg_arg.data_type() != _data_type) {
used_wildcard = 1;
}
break;
}
// everything matches
return score;
}
//
// Returns 1 if the typed values are equal, else 0. Ignores mode and
// vtype. Used by _Tt_pat_context::deleteValue().
//
int _Tt_arg::
operator==(const _Tt_arg &arg) const
{
if (_data_type != arg.data_type()) {
return 0;
}
switch (_data_type) {
case INT:
if (_data_int != arg.data_int()) {
return 0;
}
break;
case STRING:
if (_data_string != arg.data_string()) {
return 0;
}
}
return 1;
}