| /* |
| * Copyright (c) 2020, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "lib/url/url.hpp" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "core/common/code_utils.hpp" |
| |
| namespace ot { |
| namespace Url { |
| |
| otError Url::Init(char *aUrl) |
| { |
| otError error = OT_ERROR_NONE; |
| char *url = aUrl; |
| |
| mEnd = aUrl + strlen(aUrl); |
| mProtocol = aUrl; |
| |
| url = strstr(aUrl, "://"); |
| VerifyOrExit(url != nullptr, error = OT_ERROR_PARSE); |
| *url = '\0'; |
| url += sizeof("://") - 1; |
| mPath = url; |
| |
| url = strstr(url, "?"); |
| |
| if (url != nullptr) |
| { |
| mQuery = ++url; |
| |
| for (char *cur = strtok(url, "&"); cur != nullptr; cur = strtok(nullptr, "&")) |
| { |
| cur[-1] = '\0'; |
| } |
| } |
| else |
| { |
| mQuery = mEnd; |
| } |
| |
| exit: |
| return error; |
| } |
| |
| const char *Url::GetValue(const char *aName, const char *aLastValue) const |
| { |
| const char *rval = nullptr; |
| const size_t len = strlen(aName); |
| const char *start; |
| |
| if (aLastValue == nullptr) |
| { |
| start = mQuery; |
| } |
| else |
| { |
| VerifyOrExit(aLastValue > mQuery && aLastValue < mEnd); |
| start = aLastValue + strlen(aLastValue) + 1; |
| } |
| |
| while (start < mEnd) |
| { |
| const char *last = nullptr; |
| |
| if (!strncmp(aName, start, len)) |
| { |
| if (start[len] == '=') |
| { |
| ExitNow(rval = &start[len + 1]); |
| } |
| else if (start[len] == '\0') |
| { |
| ExitNow(rval = &start[len]); |
| } |
| } |
| last = start; |
| start = last + strlen(last) + 1; |
| } |
| |
| exit: |
| return rval; |
| } |
| |
| otError Url::ParseUint32(const char *aName, uint32_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| const char *str; |
| long long value; |
| |
| VerifyOrExit((str = GetValue(aName)) != nullptr, error = OT_ERROR_NOT_FOUND); |
| |
| value = strtoll(str, nullptr, 0); |
| VerifyOrExit(0 <= value && value <= UINT32_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<uint32_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| otError Url::ParseUint16(const char *aName, uint16_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| uint32_t value; |
| |
| SuccessOrExit(error = ParseUint32(aName, value)); |
| VerifyOrExit(value <= UINT16_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<uint16_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| otError Url::ParseUint8(const char *aName, uint8_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| uint32_t value; |
| |
| SuccessOrExit(error = ParseUint32(aName, value)); |
| VerifyOrExit(value <= UINT8_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<uint8_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| otError Url::ParseInt32(const char *aName, int32_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| const char *str; |
| long long value; |
| |
| VerifyOrExit((str = GetValue(aName)) != nullptr, error = OT_ERROR_NOT_FOUND); |
| |
| value = strtoll(str, nullptr, 0); |
| VerifyOrExit(INT32_MIN <= value && value <= INT32_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<int32_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| otError Url::ParseInt16(const char *aName, int16_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| int32_t value; |
| |
| SuccessOrExit(error = ParseInt32(aName, value)); |
| VerifyOrExit(INT16_MIN <= value && value <= INT16_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<int16_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| otError Url::ParseInt8(const char *aName, int8_t &aValue) const |
| { |
| otError error = OT_ERROR_NONE; |
| int32_t value; |
| |
| SuccessOrExit(error = ParseInt32(aName, value)); |
| VerifyOrExit(INT8_MIN <= value && value <= INT8_MAX, error = OT_ERROR_INVALID_ARGS); |
| aValue = static_cast<int8_t>(value); |
| |
| exit: |
| return error; |
| } |
| |
| } // namespace Url |
| } // namespace ot |