Boolean _parseHostElement(
    const String& objectName,
    char*& p,
    String& host)
{
    // See if there is a host name (true if it begins with "//"):
    // Host is of the form <hostname>:<port> and begins with "//"
    // and ends with "/":

    if (p[0] != '/' || p[1] != '/')
    {
        return false;
    }

    p += 2;

    char* slash = strchr(p, '/');
    if (!slash)
    {
        throw MalformedObjectNameException(objectName);
    }

    String hostname = String(p, (Uint32)(slash - p));
    if (!CIMObjectPathRep::isValidHostname(hostname))
    {
        throw MalformedObjectNameException(objectName);
    }
    host = hostname;

    // Do not step past the '/'; it will be consumed by the namespace parser
    p = slash;

    return true;
}
void CIMObjectPath::set(const String& objectName)
{
    clear();

    //--------------------------------------------------------------------------
    // We will extract components from an object name. Here is an sample
    // object name:
    //
    //     //atp:9999/root/cimv25:TennisPlayer.first="Patrick",last="Rafter"
    //--------------------------------------------------------------------------

    // Convert to a C String first:

    CString pCString = objectName.getCString();
    char* p = const_cast<char*>((const char*) pCString);
    Boolean gotHost;
    Boolean gotNamespace;

    gotHost = _parseHostElement(objectName, p, _rep->_host);
    gotNamespace = _parseNamespaceElement(objectName, p, _rep->_nameSpace);

    if (gotHost && !gotNamespace)
    {
        throw MalformedObjectNameException(objectName);
    }

    // Extract the class name:

    char* dot = strchr(p, '.');

    if (!dot)
    {
        if (!CIMName::legal(p))
        {
            throw MalformedObjectNameException(objectName);
        }

        // ATTN: remove this later: a reference should only be able to hold
        // an instance name.

        _rep->_className = CIMName (p);
        return;
    }

    String className = String(p, (Uint32)(dot - p));
    if (!CIMName::legal(className))
    {
        throw MalformedObjectNameException(objectName);
    }
    _rep->_className = className;

    // Advance past dot:

    p = dot + 1;

    _parseKeyBindingPairs(objectName, p, _rep->_keyBindings);
}
void CIMObjectPath::setHost(const String& host)
{
    if ((host != String::EMPTY) && !CIMObjectPathRep::isValidHostname(host))
    {
        throw MalformedObjectNameException(host);
    }

    _rep->_host = host;
}
Exemple #4
0
Boolean _parseHostElement(
    const String& objectName,
    char*& p,
    String& host)
{
    // See if there is a host name (true if it begins with "//"):
    // Host is of the form <hostname>:<port> and begins with "//"
    // and ends with "/":

    if (p[0] != '/' || p[1] != '/')
    {
        return false;
    }

    p += 2;

    char* slash = strchr(p, '/');
    if (!slash)
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.MISSING_SLASH_AFTER_HOST",
            "$0, reason:\"missing slash after hostname\"",
            objectName);
        throw MalformedObjectNameException(mlParms);
    }

    String hostname = String(p, (Uint32)(slash - p));
    if (!CIMObjectPathRep::isValidHostname(hostname))
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.INVALID_HOSTNAME",
            "$0, reason:\"invalid hostname\"",
            objectName);
        throw MalformedObjectNameException(mlParms);
    }
    host = hostname;

    // Do not step past the '/'; it will be consumed by the namespace parser
    p = slash;

    return true;
}
Exemple #5
0
void CIMObjectPath::setHost(const String& host)
{
    if ((host != String::EMPTY) &&
        (host != System::getHostName()) &&
        !CIMObjectPathRep::isValidHostname(host))
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.INVALID_HOSTNAME",
            "$0, reason:\"invalid hostname\"",
            host);
        throw MalformedObjectNameException(mlParms);
    }
    _rep = _copyOnWriteCIMObjectPathRep(_rep);

    _rep->_host = host;
}
Exemple #6
0
Boolean _parseNamespaceElement(
    const String& objectName,
    char*& p,
    CIMNamespaceName& nameSpace)
{
    // If we don't find a valid namespace name followed by a ':', we
    // assume we're not looking at a namespace name.

    char* colon = strchr(p, ':');
    if (!colon)
    {
        return false;
    }

    // A ':' as part of a keybinding value should not be interpreted as
    // a namespace delimiter.  Since keybinding pairs follow the first '.'
    // in the object path string, the ':' delimiter only counts if it
    // appears before the '.'.

    char* dot = strchr(p, '.');
    if (dot && (dot < colon))
    {
        return false;
    }

    //----------------------------------------------------------------------
    // Validate the namespace path.  Namespaces must match the following
    // regular expression: "[A-Za-z_]+(/[A-Za-z_]+)*"
    //----------------------------------------------------------------------

    String namespaceName = String(p, (Uint32)(colon - p));
    if (!CIMNamespaceName::legal(namespaceName))
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.INVALID_NAMESPACE",
            "$0, reason:\"invalid namespace name\"",
            objectName);
        throw MalformedObjectNameException(mlParms);
    }
    nameSpace = namespaceName;

    p = colon+1;
    return true;
}
Exemple #7
0
void CIMObjectPath::set(
    const String& host,
    const CIMNamespaceName& nameSpace,
    const CIMName& className,
    const Array<CIMKeyBinding>& keyBindings)
{
    if ((host != String::EMPTY) && !CIMObjectPathRep::isValidHostname(host))
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.INVALID_HOSTNAME",
            "$0, reason:\"invalid hostname\"",
            host);

        throw MalformedObjectNameException(mlParms);
    }

    _rep = _copyOnWriteCIMObjectPathRep(_rep);

    _rep->_host.assign(host);
    _rep->_nameSpace = nameSpace;
    _rep->_className = className;
    _rep->_keyBindings = keyBindings;
    _Sort(_rep->_keyBindings);
}
Exemple #8
0
void CIMObjectPath::set(const String& objectName)
{
    // the clear automatically ensures
    // we have our own copy of the representation
    clear();

    //--------------------------------------------------------------------------
    // We will extract components from an object name. Here is an sample
    // object name:
    //
    //     //atp:9999/root/cimv25:TennisPlayer.first="Patrick",last="Rafter"
    //--------------------------------------------------------------------------

    // Convert to a C String first:

    CString pCString = objectName.getCString();
    char* p = const_cast<char*>((const char*) pCString);
    Boolean gotHost;
    Boolean gotNamespace;

    gotHost = _parseHostElement(objectName, p, _rep->_host);
    gotNamespace = _parseNamespaceElement(objectName, p, _rep->_nameSpace);

    if (gotHost && !gotNamespace)
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.MISSING_NAMESPACE",
            "$0, reason:\"host specified, missing namespace\"",
            objectName);
        throw MalformedObjectNameException(mlParms);
    }

    // Extract the class name:

    char* dot = strchr(p, '.');

    if (!dot)
    {
        if (!CIMName::legal(p))
        {
            MessageLoaderParms mlParms(
                "Common.CIMObjectPath.INVALID_CLASSNAME",
                "$0, reason:\"class name $1 not a legal CIM name\"",
                objectName,
                p);
            throw MalformedObjectNameException(mlParms);
        }

        // ATTN: remove this later: a reference should only be able to hold
        // an instance name.

        _rep->_className = CIMName (p);
        return;
    }

    String className = String(p, (Uint32)(dot - p));
    if (!CIMName::legal(className))
    {
        MessageLoaderParms mlParms(
            "Common.CIMObjectPath.INVALID_CLASSNAME",
            "$0, reason:\"class name $1 not a legal CIM name\"",
            objectName,
            className);
        throw MalformedObjectNameException(mlParms);
    }
    _rep->_className = className;

    // Advance past dot:

    p = dot + 1;

    _parseKeyBindingPairs(objectName, p, _rep->_keyBindings);
}
Exemple #9
0
/**
    ATTN-RK: The DMTF specification for the string form of an
    object path makes it impossible for a parser to distinguish
    between a key values of String type and Reference type.

    Given the ambiguity, this implementation takes a guess at the
    type of a quoted key value.  If the value can be parsed into
    a CIMObjectPath with at least one key binding, the type is
    set to REFERENCE.  Otherwise, the type is set to STRING.
    Note: This algorithm appears to be in line with what the Sun
    WBEM Services implementation does.

    To be totally correct, it would be necessary to retrieve the
    class definition and look up the types of the key properties
    to determine how to interpret the key values.  This is clearly
    too inefficient for internal transformations between
    CIMObjectPaths and String values.
*/
void _parseKeyBindingPairs(
    const String& objectName,
    char*& p,
    Array<CIMKeyBinding>& keyBindings)
{
    // Get the key-value pairs:

    while (*p)
    {
        // Get key part:

        char* equalsign = strchr(p, '=');
        if (!equalsign)
        {
            MessageLoaderParms mlParms(
                "Common.CIMObjectPath.INVALID_KEYVALUEPAIR",
                "$0, reason:\"invalid key-value pair, missing equal sign\"",
                objectName);
            throw MalformedObjectNameException(mlParms);
        }

        *equalsign = 0;

        if (!CIMName::legal(p))
        {
            MessageLoaderParms mlParms(
                "Common.CIMObjectPath.INVALID_KEYNAME",
                "$0, reason:\"invalid key-value pair, invalid key name:$1\"",
                objectName,
                p);
            throw MalformedObjectNameException(mlParms);
        }

        CIMName keyName (p);

        // Get the value part:

        String valueString;
        p = equalsign + 1;
        CIMKeyBinding::Type type;

        if (*p == '"')
        {
            // Could be CIMKeyBinding::STRING or CIMKeyBinding::REFERENCE

            p++;

            Buffer keyValueUTF8(128);

            while (*p && *p != '"')
            {
                if (*p == '\\')
                {
                    p++;

                    if ((*p != '\\') && (*p != '"'))
                    {
                        MessageLoaderParms mlParms(
                            "Common.CIMObjectPath.INVALID_KEYVALUE",
                            "$0, reason:\"invalid key-value pair, "
                                "malformed value\"",
                            objectName);
                        throw MalformedObjectNameException(mlParms);
                    }
                }

                keyValueUTF8.append(*p++);
            }

            if (*p++ != '"')
            {
                MessageLoaderParms mlParms(
                    "Common.CIMObjectPath.INVALID_KEYVALUEPAIR_MISSINGQUOTE",
                    "$0, reason:\"invalid key-value pair, "
                        "missing quote in key value\"",
                    objectName);
                throw MalformedObjectNameException(mlParms);
            }

            // Convert the UTF-8 value to a UTF-16 String

            valueString.assign(
                (const char*)keyValueUTF8.getData(),
                keyValueUTF8.size());

            /*
                Guess at the type of this quoted key value.  If the value
                can be parsed into a CIMObjectPath with at least one key
                binding, the type is assumed to be a REFERENCE.  Otherwise,
                the type is set to STRING.  (See method header for details.)
             */
            type = CIMKeyBinding::STRING;

            /* Performance shortcut will check for
               equal sign instead of doing the full
               CIMObjectPath creation and exception handling
            */
            if (strchr(keyValueUTF8.getData(), '='))
            {
                // found an equal sign, high probability for a reference
                try
                {
                    CIMObjectPath testForPath(valueString);
                    if (testForPath.getKeyBindings().size() > 0)
                    {
                        // We've found a reference value!
                        type = CIMKeyBinding::REFERENCE;
                    }
                }
                catch (const Exception &)
                {
                    // Not a reference value; leave type as STRING
                }
            }
        }
        else if (toupper(*p) == 'T' || toupper(*p) == 'F')
        {
            type = CIMKeyBinding::BOOLEAN;

            char* r = p;
            Uint32 n = 0;

            while (*r && *r != ',')
            {
                *r = toupper(*r);
                r++;
                n++;
            }

            if (!(((strncmp(p, "TRUE", n) == 0) && n == 4) ||
                  ((strncmp(p, "FALSE", n) == 0) && n == 5)))
            {
                MessageLoaderParms mlParms(
                    "Common.CIMObjectPath.INVALID_BOOLVALUE",
                    "$0, reason:\"invalid key-value pair, "
                        "value should be TRUE or FALSE\"",
                    objectName);
                throw MalformedObjectNameException(mlParms);
            }

            valueString.assign(p, n);

            p = p + n;
        }
        else
        {
            type = CIMKeyBinding::NUMERIC;

            char* r = p;
            Uint32 n = 0;

            while (*r && *r != ',')
            {
                r++;
                n++;
            }

            Boolean isComma = false;
            if (*r)
            {
                *r = '\0';
                isComma = true;
            }

            if (*p == '-')
            {
                Sint64 x;
                if (!StringConversion::stringToSignedInteger(p, x))
                {
                    MessageLoaderParms mlParms(
                        "Common.CIMObjectPath.INVALID_NEGATIVNUMBER_VALUE",
                        "$0, reason:\"invalid key-value pair, "
                            "invalid negative number value $1\"",
                        objectName,
                        p);
                    throw MalformedObjectNameException(mlParms);
                }
            }
            else
            {
                Uint64 x;
                if (!StringConversion::stringToUnsignedInteger(p, x))
                {
                    MessageLoaderParms mlParms(
                        "Common.CIMObjectPath.INVALID_NEGATIVNUMBER_VALUE",
                        "$0, reason:\"invalid key-value pair, "
                            "invalid number value $1\"",
                        objectName,
                        p);
                    throw MalformedObjectNameException(mlParms);
                }
            }

            valueString.assign(p, n);

            if (isComma)
            {
                *r = ',';
            }

            p = p + n;
        }

        keyBindings.append(CIMKeyBinding(keyName.getString (), valueString,
            type));

        if (*p)
        {
            if (*p++ != ',')
            {
                MessageLoaderParms mlParms(
                    "Common.CIMObjectPath.INVALID_KEYVALUEPAIR_MISSCOMMA",
                    "$0, reason:\"invalid key-value pair, "
                        "next key-value pair has to start with comma\"",
                    objectName);
                throw MalformedObjectNameException(mlParms);
            }
        }
    }

    _Sort(keyBindings);
}
Exemple #10
0
/**
    ATTN-RK: The DMTF specification for the string form of an
    object path makes it impossible for a parser to distinguish
    between a key values of String type and Reference type.

    Given the ambiguity, this implementation takes a guess at the
    type of a quoted key value.  If the value can be parsed into
    a CIMObjectPath with at least one key binding, the type is
    set to REFERENCE.  Otherwise, the type is set to STRING.
    Note: This algorithm appears to be in line with what the Sun
    WBEM Services implementation does.

    To be totally correct, it would be necessary to retrieve the
    class definition and look up the types of the key properties
    to determine how to interpret the key values.  This is clearly
    too inefficient for internal transformations between
    CIMObjectPaths and String values.
*/
void _parseKeyBindingPairs(
    const String& objectName,
    char*& p,
    Array<CIMKeyBinding>& keyBindings)
{
    // Get the key-value pairs:

    while (*p)
    {
        // Get key part:

        char* equalsign = strchr(p, '=');
        if (!equalsign)
        {
            throw MalformedObjectNameException(objectName);
        }

        *equalsign = 0;

        if (!CIMName::legal(p))
            throw MalformedObjectNameException(objectName);

        CIMName keyName (p);

        // Get the value part:

        String valueString;
        p = equalsign + 1;
        CIMKeyBinding::Type type;

        if (*p == '"')
        {
            // Could be CIMKeyBinding::STRING or CIMKeyBinding::REFERENCE

            p++;

            while (*p && *p != '"')
            {
                if (*p == '\\')
                {
                    *p++;

                    if ((*p != '\\') && (*p != '"'))
                    {
                        throw MalformedObjectNameException(objectName);
                    }
                }

                valueString.append(*p++);
            }

            if (*p++ != '"')
                throw MalformedObjectNameException(objectName);

            /*
                Guess at the type of this quoted key value.  If the value
                can be parsed into a CIMObjectPath with at least one key
                binding, the type is assumed to be a REFERENCE.  Otherwise,
                the type is set to STRING.  (See method header for details.)
             */
            type = CIMKeyBinding::STRING;

            try
            {
                CIMObjectPath testForPath(valueString);
                if (testForPath.getKeyBindings().size() > 0)
                {
                    // We've found a reference value!
                    type = CIMKeyBinding::REFERENCE;
                }
            }
            catch (const Exception &)
            {
                // Not a reference value; leave type as STRING
            }
        }
        else if (toupper(*p) == 'T' || toupper(*p) == 'F')
        {
            type = CIMKeyBinding::BOOLEAN;

            char* r = p;
            Uint32 n = 0;

            while (*r && *r != ',')
            {
                *r = toupper(*r);
                r++;
                n++;
            }

            if (!(((strncmp(p, "TRUE", n) == 0) && n == 4) ||
                  ((strncmp(p, "FALSE", n) == 0) && n == 5)))
                throw MalformedObjectNameException(objectName);

            valueString.assign(p, n);

            p = p + n;
        }
        else
        {
            type = CIMKeyBinding::NUMERIC;

            char* r = p;
            Uint32 n = 0;

            while (*r && *r != ',')
            {
                r++;
                n++;
            }

            Boolean isComma = false;
            if (*r)
            {
                *r = '\0';
                isComma = true;
            }

            Sint64 x;

            if (!XmlReader::stringToSignedInteger(p, x))
                throw MalformedObjectNameException(objectName);

            valueString.assign(p, n);

            if (isComma)
            {
                *r = ',';
            }

            p = p + n;
        }

        keyBindings.append(CIMKeyBinding(keyName.getString (), valueString,
            type));

        if (*p)
        {
            if (*p++ != ',')
            {
                throw MalformedObjectNameException(objectName);
            }
        }
    }

    _BubbleSort(keyBindings);
}