Import Geant4 10.5.0 source tree
This commit is contained in:
@@ -1,272 +1,271 @@
|
||||
// Copyright FreeHEP, 2005.
|
||||
|
||||
#include "cheprep/config.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "HEPREP/HepRepConstants.h"
|
||||
|
||||
#include "cheprep/DefaultHepRepAttValue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace HEPREP;
|
||||
|
||||
/**
|
||||
* @author Mark Donszelmann
|
||||
* @version $Id: DefaultHepRepAttValue.cc 68043 2013-03-13 14:27:49Z gcosmo $
|
||||
*/
|
||||
namespace cheprep {
|
||||
|
||||
std::string DefaultHepRepAttValue::labelStrings[LABELSTRINGS_LEN];
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, string aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_STRING)
|
||||
, stringValue(aValue)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, int64 aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_LONG)
|
||||
, longValue(aValue)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, int aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_INT)
|
||||
, longValue(aValue)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, double aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_DOUBLE)
|
||||
, longValue(0)
|
||||
, doubleValue(aValue)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, bool aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_BOOLEAN)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(aValue)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, vector<double> aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_COLOR)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, colorValue(aValue)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::~DefaultHepRepAttValue() {
|
||||
}
|
||||
|
||||
void DefaultHepRepAttValue::init() {
|
||||
labelStrings[0] = "NAME";
|
||||
labelStrings[1] = "DESC";
|
||||
labelStrings[2] = "VALUE";
|
||||
labelStrings[3] = "EXTRA";
|
||||
}
|
||||
|
||||
HepRepAttValue* DefaultHepRepAttValue::copy() {
|
||||
// Coverity issues warnings here. It looks to me (JA) that "return" is
|
||||
// missing on severeal lines.
|
||||
switch(type) {
|
||||
// case HepRepConstants::TYPE_COLOR: new DefaultHepRepAttValue(name, colorValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_STRING: new DefaultHepRepAttValue(name, stringValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_LONG: new DefaultHepRepAttValue(name, longValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_INT: new DefaultHepRepAttValue(name, (int)longValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_DOUBLE: new DefaultHepRepAttValue(name, doubleValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_BOOLEAN: new DefaultHepRepAttValue(name, booleanValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_COLOR: return new DefaultHepRepAttValue(name, colorValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_STRING: return new DefaultHepRepAttValue(name, stringValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_LONG: return new DefaultHepRepAttValue(name, longValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_INT: return new DefaultHepRepAttValue(name, (int)longValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_DOUBLE: return new DefaultHepRepAttValue(name, doubleValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_BOOLEAN: return new DefaultHepRepAttValue(name, booleanValue, showLabelValue);
|
||||
default: return new DefaultHepRepAttValue(name, "Unknown type stored in HepRepAttDef", showLabelValue);
|
||||
}
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getLowerCaseName() {
|
||||
string s = name;
|
||||
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
|
||||
return s;
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getTypeName() {
|
||||
switch(type) {
|
||||
case HepRepConstants::TYPE_COLOR: return("Color");
|
||||
case HepRepConstants::TYPE_STRING: return("String");
|
||||
case HepRepConstants::TYPE_LONG: return("long");
|
||||
case HepRepConstants::TYPE_INT: return("int");
|
||||
case HepRepConstants::TYPE_DOUBLE: return("double");
|
||||
case HepRepConstants::TYPE_BOOLEAN: return("boolean");
|
||||
default: return "Unknown type stored in HepRepAttDef";
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::showLabel() {
|
||||
return showLabelValue;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getString() {
|
||||
if (type != HepRepConstants::TYPE_STRING) cerr << "Trying to access AttValue '" << getName() << "' as 'string'" << endl;
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getLowerCaseString() {
|
||||
if (type != HepRepConstants::TYPE_STRING) cerr << "Trying to access AttValue '" << getName() << "' as 'string'" << endl;
|
||||
string s = stringValue;
|
||||
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
|
||||
return s;
|
||||
}
|
||||
|
||||
int64 DefaultHepRepAttValue::getLong() {
|
||||
if (type != HepRepConstants::TYPE_LONG) cerr << "Trying to access AttValue '" << getName() << "' as 'long'" << endl;
|
||||
return longValue;
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::getInteger() {
|
||||
if (type != HepRepConstants::TYPE_INT) cerr << "Trying to access AttValue '" << getName() << "' as 'int'" << endl;
|
||||
return (int64)longValue;
|
||||
}
|
||||
|
||||
double DefaultHepRepAttValue::getDouble() {
|
||||
if (type != HepRepConstants::TYPE_DOUBLE) cerr << "Trying to access AttValue '" << getName() << "' as 'double'" << endl;
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
bool DefaultHepRepAttValue::getBoolean() {
|
||||
if (type != HepRepConstants::TYPE_BOOLEAN) cerr << "Trying to access AttValue '" << getName() << "' as 'boolean'" << endl;
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
vector<double> DefaultHepRepAttValue::getColor() {
|
||||
if (type != HepRepConstants::TYPE_COLOR) cerr << "Trying to access AttValue '" << getName() << "' as 'color'" << endl;
|
||||
return colorValue;
|
||||
}
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::getAsString() {
|
||||
switch(type) {
|
||||
case HepRepConstants::TYPE_COLOR: return getAsString(getColor());
|
||||
case HepRepConstants::TYPE_STRING: return getString();
|
||||
case HepRepConstants::TYPE_LONG: return getAsString(getLong());
|
||||
case HepRepConstants::TYPE_INT: return getAsString(getInteger());
|
||||
case HepRepConstants::TYPE_DOUBLE: return getAsString(getDouble());
|
||||
case HepRepConstants::TYPE_BOOLEAN: return getAsString(getBoolean());
|
||||
default: return "Unknown typecode";
|
||||
}
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(vector<double> c) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%4.2f, %4.2f, %4.2f, %4.2f",
|
||||
c[0],
|
||||
c[1],
|
||||
c[2],
|
||||
(c.size() > 3) ? c[3] : 1.0);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(int i) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%d", i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(int64 i) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, CHEPREP_INT64_FORMAT, i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// NOTE: keep at %g rather than %lg for backward compatibility
|
||||
string DefaultHepRepAttValue::getAsString(double d) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%g", d);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::toShowLabel() {
|
||||
return toShowLabel(showLabel());
|
||||
}
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::toShowLabel(int showLabel) {
|
||||
string label = "";
|
||||
bool first = true;
|
||||
if (showLabel == HepRepConstants::SHOW_NONE) {
|
||||
label = "NONE";
|
||||
} else {
|
||||
for (int i=0; i<16; i++) {
|
||||
if (((showLabel >> i) & 0x0001) == 0x0001) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
label.append(", ");
|
||||
}
|
||||
if (i < LABELSTRINGS_LEN) {
|
||||
label.append(labelStrings[i]);
|
||||
} else {
|
||||
char hex[20];
|
||||
sprintf(hex, "%0x", 1 << i);
|
||||
label.append(hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
} // cheprep
|
||||
// Copyright FreeHEP, 2005.
|
||||
|
||||
#include "cheprep/config.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "HEPREP/HepRepConstants.h"
|
||||
|
||||
#include "cheprep/DefaultHepRepAttValue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace HEPREP;
|
||||
|
||||
/**
|
||||
* @author Mark Donszelmann
|
||||
*/
|
||||
namespace cheprep {
|
||||
|
||||
std::string DefaultHepRepAttValue::labelStrings[LABELSTRINGS_LEN];
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, string aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_STRING)
|
||||
, stringValue(aValue)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, int64 aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_LONG)
|
||||
, longValue(aValue)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, int aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_INT)
|
||||
, longValue(aValue)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, double aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_DOUBLE)
|
||||
, longValue(0)
|
||||
, doubleValue(aValue)
|
||||
, booleanValue(false)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, bool aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_BOOLEAN)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(aValue)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::DefaultHepRepAttValue(string aName, vector<double> aValue, int aShowLabel)
|
||||
: name(aName)
|
||||
, type(HepRepConstants::TYPE_COLOR)
|
||||
, longValue(0)
|
||||
, doubleValue(0.)
|
||||
, booleanValue(false)
|
||||
, colorValue(aValue)
|
||||
, showLabelValue(aShowLabel)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
DefaultHepRepAttValue::~DefaultHepRepAttValue() {
|
||||
}
|
||||
|
||||
void DefaultHepRepAttValue::init() {
|
||||
labelStrings[0] = "NAME";
|
||||
labelStrings[1] = "DESC";
|
||||
labelStrings[2] = "VALUE";
|
||||
labelStrings[3] = "EXTRA";
|
||||
}
|
||||
|
||||
HepRepAttValue* DefaultHepRepAttValue::copy() {
|
||||
// Coverity issues warnings here. It looks to me (JA) that "return" is
|
||||
// missing on severeal lines.
|
||||
switch(type) {
|
||||
// case HepRepConstants::TYPE_COLOR: new DefaultHepRepAttValue(name, colorValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_STRING: new DefaultHepRepAttValue(name, stringValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_LONG: new DefaultHepRepAttValue(name, longValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_INT: new DefaultHepRepAttValue(name, (int)longValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_DOUBLE: new DefaultHepRepAttValue(name, doubleValue, showLabelValue);
|
||||
// case HepRepConstants::TYPE_BOOLEAN: new DefaultHepRepAttValue(name, booleanValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_COLOR: return new DefaultHepRepAttValue(name, colorValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_STRING: return new DefaultHepRepAttValue(name, stringValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_LONG: return new DefaultHepRepAttValue(name, longValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_INT: return new DefaultHepRepAttValue(name, (int)longValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_DOUBLE: return new DefaultHepRepAttValue(name, doubleValue, showLabelValue);
|
||||
case HepRepConstants::TYPE_BOOLEAN: return new DefaultHepRepAttValue(name, booleanValue, showLabelValue);
|
||||
default: return new DefaultHepRepAttValue(name, "Unknown type stored in HepRepAttDef", showLabelValue);
|
||||
}
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getLowerCaseName() {
|
||||
string s = name;
|
||||
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
|
||||
return s;
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getTypeName() {
|
||||
switch(type) {
|
||||
case HepRepConstants::TYPE_COLOR: return("Color");
|
||||
case HepRepConstants::TYPE_STRING: return("String");
|
||||
case HepRepConstants::TYPE_LONG: return("long");
|
||||
case HepRepConstants::TYPE_INT: return("int");
|
||||
case HepRepConstants::TYPE_DOUBLE: return("double");
|
||||
case HepRepConstants::TYPE_BOOLEAN: return("boolean");
|
||||
default: return "Unknown type stored in HepRepAttDef";
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::showLabel() {
|
||||
return showLabelValue;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getString() {
|
||||
if (type != HepRepConstants::TYPE_STRING) cerr << "Trying to access AttValue '" << getName() << "' as 'string'" << endl;
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getLowerCaseString() {
|
||||
if (type != HepRepConstants::TYPE_STRING) cerr << "Trying to access AttValue '" << getName() << "' as 'string'" << endl;
|
||||
string s = stringValue;
|
||||
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
|
||||
return s;
|
||||
}
|
||||
|
||||
int64 DefaultHepRepAttValue::getLong() {
|
||||
if (type != HepRepConstants::TYPE_LONG) cerr << "Trying to access AttValue '" << getName() << "' as 'long'" << endl;
|
||||
return longValue;
|
||||
}
|
||||
|
||||
int DefaultHepRepAttValue::getInteger() {
|
||||
if (type != HepRepConstants::TYPE_INT) cerr << "Trying to access AttValue '" << getName() << "' as 'int'" << endl;
|
||||
return (int64)longValue;
|
||||
}
|
||||
|
||||
double DefaultHepRepAttValue::getDouble() {
|
||||
if (type != HepRepConstants::TYPE_DOUBLE) cerr << "Trying to access AttValue '" << getName() << "' as 'double'" << endl;
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
bool DefaultHepRepAttValue::getBoolean() {
|
||||
if (type != HepRepConstants::TYPE_BOOLEAN) cerr << "Trying to access AttValue '" << getName() << "' as 'boolean'" << endl;
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
vector<double> DefaultHepRepAttValue::getColor() {
|
||||
if (type != HepRepConstants::TYPE_COLOR) cerr << "Trying to access AttValue '" << getName() << "' as 'color'" << endl;
|
||||
return colorValue;
|
||||
}
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::getAsString() {
|
||||
switch(type) {
|
||||
case HepRepConstants::TYPE_COLOR: return getAsString(getColor());
|
||||
case HepRepConstants::TYPE_STRING: return getString();
|
||||
case HepRepConstants::TYPE_LONG: return getAsString(getLong());
|
||||
case HepRepConstants::TYPE_INT: return getAsString(getInteger());
|
||||
case HepRepConstants::TYPE_DOUBLE: return getAsString(getDouble());
|
||||
case HepRepConstants::TYPE_BOOLEAN: return getAsString(getBoolean());
|
||||
default: return "Unknown typecode";
|
||||
}
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(vector<double> c) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%4.2f, %4.2f, %4.2f, %4.2f",
|
||||
c[0],
|
||||
c[1],
|
||||
c[2],
|
||||
(c.size() > 3) ? c[3] : 1.0);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(int i) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%d", i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(int64 i) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, CHEPREP_INT64_FORMAT, i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// NOTE: keep at %g rather than %lg for backward compatibility
|
||||
string DefaultHepRepAttValue::getAsString(double d) {
|
||||
char buffer[40];
|
||||
sprintf(buffer, "%g", d);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string DefaultHepRepAttValue::getAsString(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::toShowLabel() {
|
||||
return toShowLabel(showLabel());
|
||||
}
|
||||
|
||||
|
||||
string DefaultHepRepAttValue::toShowLabel(int showLabel) {
|
||||
string label = "";
|
||||
bool first = true;
|
||||
if (showLabel == HepRepConstants::SHOW_NONE) {
|
||||
label = "NONE";
|
||||
} else {
|
||||
for (int i=0; i<16; i++) {
|
||||
if (((showLabel >> i) & 0x0001) == 0x0001) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
label.append(", ");
|
||||
}
|
||||
if (i < LABELSTRINGS_LEN) {
|
||||
label.append(labelStrings[i]);
|
||||
} else {
|
||||
char hex[20];
|
||||
sprintf(hex, "%0x", 1 << i);
|
||||
label.append(hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
} // cheprep
|
||||
|
||||
Reference in New Issue
Block a user