static string GetExpandedShaderCode(const wchar* path, GrowableList<wstring>& filePaths)
{
    for(uint64 i = 0; i < filePaths.Count(); ++i)
        if(filePaths[i] == path)
            return string();

    filePaths.Add(path);

    string fileContents = ReadFileAsString(path);

    // Look for includes
    size_t lineStart = 0;
    while(true)
    {
        size_t lineEnd = fileContents.find('\n', lineStart);
        size_t lineLength = 0;
        if(lineEnd == string::npos)
            lineLength = string::npos;
        else
            lineLength = lineEnd - lineStart;

        string line = fileContents.substr(lineStart, lineLength);
        if(line.find("#include") == 0)
        {
            wstring fullIncludePath;
            size_t startQuote = line.find('\"');
            if(startQuote != -1)
            {
                size_t endQuote = line.find('\"', startQuote + 1);
                string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
                fullIncludePath = AnsiToWString(includePath.c_str());
            }
            else
            {
                startQuote = line.find('<');
                if(startQuote == -1)
                    throw Exception(L"Malformed include statement: \"" + AnsiToWString(line.c_str()) + L"\" in file " + path);
                size_t endQuote = line.find('>', startQuote + 1);
                string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
                fullIncludePath = SampleFrameworkDir() + L"Shaders\\" + AnsiToWString(includePath.c_str());
            }

            if(FileExists(fullIncludePath.c_str()) == false)
                throw Exception(L"Couldn't find #included file \"" + fullIncludePath + L"\" in file " + path);

            string includeCode = GetExpandedShaderCode(fullIncludePath.c_str(), filePaths);
            fileContents.insert(lineEnd + 1, includeCode);
            lineEnd += includeCode.length();
        }

        if(lineEnd == string::npos)
            break;

        lineStart = lineEnd + 1;
    }

    return fileContents;
}
Beispiel #2
0
static string GetExpandedShaderCode(const wchar* path, vector<wstring>& filePaths)
{
    for(uint64 i = 0; i < filePaths.size(); ++i)
        if(filePaths[i] == path)
            throw Exception(L"File \"" + wstring(path) + L" is recursively included");

    filePaths.push_back(path);

    string fileContents = ReadFileAsString(path);
    wstring fileDirectory = GetDirectoryFromFilePath(path);

    // Look for includes
    size_t lineStart = 0;
    size_t lineEnd = std::string::npos;
    while(true)
    {
        size_t lineEnd = fileContents.find('\n', lineStart);
        size_t lineLength = 0;
        if(lineEnd == string::npos)
            lineLength = string::npos;
        else
            lineLength = lineEnd - lineStart;

        string line = fileContents.substr(lineStart, lineLength);
        if(line.find("#include") == 0)
        {
            size_t startQuote = line.find('\"');
            size_t endQuote = line.find('\"', startQuote + 1);
            string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
            wstring fullIncludePath = fileDirectory + AnsiToWString(includePath.c_str());
            if(FileExists(fullIncludePath.c_str()) == false)
                throw Exception(L"Couldn't find #included file \"" + fullIncludePath + L"\"");

            string includeCode = GetExpandedShaderCode(fullIncludePath.c_str(), filePaths);
            fileContents.insert(lineEnd + 1, includeCode);
            lineEnd += includeCode.length();
        }

        if(lineEnd == string::npos)
            break;

        lineStart = lineEnd + 1;
    }

    return fileContents;
}
// Extract HTTP headers via temporary file with -D switch.
// HTTP status code is extracted from curl output (-w switches).
// Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop.
bool HttpClient::RunHttpRequest()
{
  ScopedRemoveFile headers_deleter(GetTmpFileName());
  ScopedRemoveFile body_deleter;
  ScopedRemoveFile received_file_deleter;

  string cmd = "curl -s -w '%{http_code}' -X " + m_httpMethod + " -D '" + headers_deleter.m_fileName + "' ";

  for (auto const & header : m_headers)
  {
    cmd += "-H '" + header.first + ": " + header.second + "' ";
  }

  if (!m_cookies.empty())
    cmd += "-b '" + m_cookies + "' ";

  if (!m_bodyData.empty())
  {
    body_deleter.m_fileName = GetTmpFileName();
    // POST body through tmp file to avoid breaking command line.
    if (!WriteToFile(body_deleter.m_fileName, m_bodyData))
      return false;

    // TODO(AlexZ): Correctly clean up this internal var to avoid client confusion.
    m_inputFile = body_deleter.m_fileName;
  }
  // Content-Length is added automatically by curl.
  if (!m_inputFile.empty())
    cmd += "--data-binary '@" + m_inputFile + "' ";

  // Use temporary file to receive data from server.
  // If user has specified file name to save data, it is not temporary and is not deleted automatically.
  string rfile = m_outputFile;
  if (rfile.empty())
  {
    rfile = GetTmpFileName();
    received_file_deleter.m_fileName = rfile;
  }

  cmd += "-o " + rfile + strings::to_string(" ") + "'" + m_urlRequested + "'";

  LOG(LDEBUG, ("Executing", cmd));

  try
  {
    m_errorCode = stoi(RunCurl(cmd));
  }
  catch (RootException const & ex)
  {
    LOG(LERROR, (ex.Msg()));
    return false;
  }

  m_headers.clear();
  Headers const headers = ParseHeaders(ReadFileAsString(headers_deleter.m_fileName));
  string serverCookies;
  string headerKey;
  for (auto const & header : headers)
  {
    if (header.first == "Set-Cookie")
    {
      serverCookies += header.second + ", ";
    }
    else
    {
      if (header.first == "Location")
        m_urlReceived = header.second;

      if (m_loadHeaders)
      {
        headerKey = header.first;
        strings::AsciiToLower(headerKey);
        m_headers.emplace(headerKey, header.second);
      }
    }
  }
  m_headers.emplace("Set-Cookie", NormalizeServerCookies(move(serverCookies)));

  if (m_urlReceived.empty())
  {
    m_urlReceived = m_urlRequested;
    // Load body contents in final request only (skip redirects).
    // Sometimes server can reply with empty body, and it's ok.
    if (m_outputFile.empty())
      m_serverResponse = ReadFileAsString(rfile);
  }
  else
  {
    // Handle HTTP redirect.
    // TODO(AlexZ): Should we check HTTP redirect code here?
    LOG(LDEBUG, ("HTTP redirect", m_errorCode, "to", m_urlReceived));

    HttpClient redirect(m_urlReceived);
    redirect.SetCookies(CombinedCookies());

    if (!redirect.RunHttpRequest())
    {
      m_errorCode = -1;
      return false;
    }

    m_errorCode = redirect.ErrorCode();
    m_urlReceived = redirect.UrlReceived();
    m_headers = move(redirect.m_headers);
    m_serverResponse = move(redirect.m_serverResponse);
  }

  return true;
}