ServerOptions::remapPrefixFromTo_t ServerOptions::remapFullPathPrefix()

in host/cxpslib/serveroptions.cpp [510:601]


ServerOptions::remapPrefixFromTo_t ServerOptions::remapFullPathPrefix() const
{
    std::string fromTo = getOption("remap_full_path_prefix", false, std::string());
    if (fromTo.empty()) {
        return remapPrefixFromTo_t(std::make_pair(std::string(), std::string()));
    }

    // have a remap setting
    std::string::size_type len(fromTo.size());

    char stopChar;

    // get <from prefix> start
    // skip over leading white space
    std::string::size_type fromStartIdx(0);
    while (fromStartIdx < len && std::isspace(fromTo[fromStartIdx])) {
        ++fromStartIdx;
    }

    // check if <from prefix> enclosed in double quotes
    if ('"' == fromTo[fromStartIdx]) {
        ++fromStartIdx;
        // skip over any leading white space after a double quote
        while (fromStartIdx < len && std::isspace(fromTo[fromStartIdx])) {
            ++fromStartIdx;
        }
        stopChar = '"';
    } else {
        stopChar = ' ';
    }

    // find <from prefix> end
    std::string::size_type fromEndIdx(fromStartIdx);
    while (fromEndIdx < len && (('"' == stopChar && '"' != fromTo[fromEndIdx]) || (' ' == stopChar && !std::isspace(fromTo[fromEndIdx])))) {
        if ('\\' == fromTo[fromEndIdx]) {
            fromTo[fromEndIdx] = '/'; // just to be safe convert backslash to slash
        }
        ++fromEndIdx;
    }

    // this is where to start looking for the <to prefix>
    std::string::size_type toStartIdx(fromEndIdx + 1);

    // if the <from prefix> was enclosed in double quotes trim
    // any trailing white space between <from prefix> and its
    // closing double quote
    if ('"' == stopChar && std::isspace(fromTo[fromEndIdx - 1])) {
        do {
            --fromEndIdx;
        } while (std::isspace(fromTo[fromEndIdx]));
        ++fromEndIdx;
    }

    // skip all white space between <from prefix> and <to prefix>
    while (toStartIdx < len && std::isspace(fromTo[toStartIdx])) {
        ++toStartIdx;
    }

    // check if <to prefix> enclosed in double quotes
    if ('"' == fromTo[toStartIdx]) {
        ++toStartIdx;
        // skip over any leading white space after a double quote
        while (toStartIdx < len && std::isspace(fromTo[toStartIdx])) {
            ++toStartIdx;
        }
        stopChar = '"';
    } else {
        stopChar = ' ';
    }

    // find <to prefix> end
    std::string::size_type toEndIdx(toStartIdx);
    while (toEndIdx < len && (('"' == stopChar && '"' != fromTo[toEndIdx]) || (' ' == stopChar && !std::isspace(fromTo[toEndIdx])))) {
        if ('\\' == fromTo[toEndIdx]) {
            fromTo[toEndIdx] = '/'; // just to be safe convert backslash to slash
        }
        ++toEndIdx;
    }

    // if the <to prefix> was enclosed in double quotes trim
    // any trailing white space between <to prefix> and its
    // closing double quote
    if ('"' == stopChar && std::isspace(fromTo[toEndIdx - 1])) {
        do {
            --toEndIdx;
        } while (std::isspace(fromTo[toEndIdx]));
        ++toEndIdx;
    }

    return remapPrefixFromTo_t(make_pair(std::string(fromTo.substr(fromStartIdx, fromEndIdx - fromStartIdx)),
                                         std::string(fromTo.substr(toStartIdx, toEndIdx - toStartIdx))));
}