<commit_before>#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "lodepng.h"

#define COMPILE_ERROR_EXIT_CODE (101)
#define LINK_ERROR_EXIT_CODE (102)
#define RENDER_ERROR_EXIT_CODE (103)

#define CHANNELS (4)
#define DELAY (2)

const float vertices[] = {
  -1.0f,  1.0f,
  -1.0f, -1.0f,
   1.0f, -1.0f,
   1.0f,  1.0f
};

const GLubyte indices[] = {
  0, 1, 2,
  2, 3, 0
};

const char* vertex_shader_wo_version =
"attribute vec2 vert2d;\n"
"void main(void) {\n"
"  gl_Position = vec4(vert2d, 0.0, 1.0);\n"
"}";

void errorCallback(int error, const char* description) {
  std::cerr << error << ": " << description << std::endl;
  exit(EXIT_FAILURE);
}

bool readFile(const std::string& fileName, std::string& contentsOut) {
  std::ifstream ifs(fileName.c_str());
  if(!ifs) {
    std::cerr << "File " << fileName << " not found" << std::endl;
    return false;
  }
  std::stringstream ss;
  ss << ifs.rdbuf();
  contentsOut = ss.str();
  return true;
}

void printProgramError(GLuint program) {
  GLint length = 0;
  glGetShaderiv(program, GL_INFO_LOG_LENGTH, &length);

  // The maxLength includes the NULL character

  std::vector<GLchar> errorLog((size_t) length, 0);

  glGetShaderInfoLog(program, length, &length, &errorLog[0]);
  if(length > 0) {
    std::string s(&errorLog[0]);
    std::cout << s << std::endl;
  }
}

int go(int argc, char* argv[]) {

  glfwWindowHint(GLFW_RESIZABLE, 0);
#ifdef __APPLE__
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif

  GLFWwindow* window = glfwCreateWindow(640, 480, "Get image", NULL, NULL);

  if(!window) {
    return EXIT_FAILURE;
  }

  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
  glfwSwapInterval(1);

  bool persist = false;
  bool animate = false;
  bool exit_compile = false;
  bool exit_linking = false;
  std::string output("output.png");
  std::string vertex_shader;
  std::string fragment_shader;

  for(int i = 1; i < argc; i++) {
    std::string curr_arg = std::string(argv[i]);
    if(!curr_arg.compare(0, 2, "--")) {
      if(curr_arg == "--persist") {
        persist = true;
        continue;
      }
      else if(curr_arg == "--animate") {
        animate = true;
        continue;
      }
      else if(curr_arg == "--exit_compile") {
        exit_compile = true;
        continue;
      }
      else if(curr_arg == "--exit_linking") {
        exit_linking = true;
        continue;
      }
      else if(curr_arg == "--output") {
        output = argv[++i];
        continue;
      }
      else if(curr_arg == "--vertex") {
        vertex_shader = argv[++i];
        continue;
      }
      std::cerr << "Unknown argument " << curr_arg << std::endl;
      continue;
    }
    if (fragment_shader.length() == 0) {
      fragment_shader = curr_arg;
    } else {
      std::cerr << "Ignoring extra argument " << curr_arg << std::endl;
    }
  }

  if(fragment_shader.length() == 0) {
    std::cerr << "Requires fragment shader argument!" << std::endl;
    return EXIT_FAILURE;
  }

  GLuint program = glCreateProgram();
  int compileOk = 0;
  const char* temp;

  std::string fragContents;
  if(!readFile(fragment_shader, fragContents)) {
    return EXIT_FAILURE;
  }

  temp = fragContents.c_str();
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &temp, NULL);
  glCompileShader(fragmentShader);
  glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling fragment shader." << std::endl;
    printProgramError(program);
    return COMPILE_ERROR_EXIT_CODE;
  }
  std::cerr << "Fragment shader compiled successfully." << std::endl;
  if (exit_compile) {
    std::cout << "Exiting after fragment shader compilation." << std::endl;
    return EXIT_SUCCESS;
  }
  glAttachShader(program, fragmentShader);

  std::string vertexContents;
  if(vertex_shader.length() == 0) {
    // Use embedded vertex shader.
    std::stringstream ss;
    size_t i = fragContents.find('\n');
    if(i != std::string::npos && fragContents[0] == '#') {
      ss << fragContents.substr(0,i);
      ss << "\n";
    } else {
      std::cerr << "Warning: Could not find #version string of fragment shader." << std::endl;
    }
    ss << vertex_shader_wo_version;
    vertexContents = ss.str();
  } else {
    if(!readFile(vertex_shader, vertexContents)) {
      return EXIT_FAILURE;
    }
  }

  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  temp = vertexContents.c_str();
  glShaderSource(vertexShader, 1, &temp, NULL);
  glCompileShader(vertexShader);
  glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling vertex shader." << std::endl;
    printProgramError(program);
    return EXIT_FAILURE;
  }
  std::cerr << "Vertex shader compiled successfully." << std::endl;

  glAttachShader(program, vertexShader);

  std::cerr << "Linking program." << std::endl;
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error in linking program." << std::endl;
    printProgramError(program);
    return LINK_ERROR_EXIT_CODE;
  }
  std::cerr << "Program linked successfully." << std::endl;
  if (exit_linking) {
    std::cout << "Exiting after program linking." << std::endl;
    return EXIT_SUCCESS;
  }

  GLint posAttribLocationAttempt = glGetAttribLocation(program, "vert2d");
  if(posAttribLocationAttempt == -1) {
    std::cerr << "Error getting vert2d attribute location." << std::endl;
    return EXIT_FAILURE;
  }
  GLuint posAttribLocation = (GLuint) posAttribLocationAttempt;
  glEnableVertexAttribArray(posAttribLocation);

  glUseProgram(program);

  GLuint vertexBuffer;
  glGenBuffers(1, &vertexBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  GLuint indicesBuffer;
  glGenBuffers(1, &indicesBuffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

  GLint injectionSwitchLocation = glGetUniformLocation(program, "injectionSwitch");
  GLint timeLocation = glGetUniformLocation(program, "time");
  GLint mouseLocation = glGetUniformLocation(program, "mouse");
  GLint resolutionLocation = glGetUniformLocation(program, "resolution");

  if(injectionSwitchLocation != -1) {
    glUniform2f(injectionSwitchLocation, 0.0f, 1.0f);
  }
  if(mouseLocation != -1) {
    glUniform2f(mouseLocation, 0.0f, 0.0f);
  }
  if(timeLocation != -1) {
    glUniform1f(timeLocation, 0.0f);
  }

  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glVertexAttribPointer(posAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

  int numFrames = 0;
  bool saved = false;

  while(!glfwWindowShouldClose(window)) {
    int width;
    int height;
    glfwGetFramebufferSize(window, &width, &height);

    glViewport(0, 0, width, height);

    if(resolutionLocation != -1) {
      glUniform2f(resolutionLocation, width, height);
    }

    if(animate && timeLocation != -1 && numFrames > DELAY) {
      glUniform1f(timeLocation, numFrames / 10.0f);
    }

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
    glfwSwapBuffers(window);
    glfwPollEvents();
    ++numFrames;

    if(numFrames == DELAY && !saved) {
      saved = true;
      unsigned uwidth = (unsigned int) width;
      unsigned uheight = (unsigned int) height;
      std::vector<std::uint8_t> data(uwidth * uheight * CHANNELS);
      glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
      std::vector<std::uint8_t> flipped_data(uwidth * uheight * CHANNELS);
      for (unsigned int h = 0; h < uheight ; h++)
        for (unsigned int col = 0; col < uwidth * CHANNELS; col++)
          flipped_data[h * uwidth * CHANNELS + col] =
              data[(uheight - h - 1) * uwidth * CHANNELS + col];
      unsigned png_error = lodepng::encode(output, flipped_data, uwidth, uheight);
      if (png_error) {
        std::cerr << "Error producing PNG file: " << lodepng_error_text(png_error) << std::endl;
        return EXIT_FAILURE;
      }
      if (!persist) {
        return EXIT_SUCCESS;
      }
    }

  }
  return EXIT_SUCCESS;
}

int main(int argc, char* argv[]) {

  glfwSetErrorCallback(errorCallback);

  if(!glfwInit()) {
    exit(EXIT_FAILURE);
  }

  int res = go(argc, argv);

  glfwTerminate();
  return res;
}

<commit_msg>Added exit on key press for persist<commit_after>#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "lodepng.h"

#define COMPILE_ERROR_EXIT_CODE (101)
#define LINK_ERROR_EXIT_CODE (102)
#define RENDER_ERROR_EXIT_CODE (103)

#define CHANNELS (4)
#define DELAY (2)

const float vertices[] = {
  -1.0f,  1.0f,
  -1.0f, -1.0f,
   1.0f, -1.0f,
   1.0f,  1.0f
};

const GLubyte indices[] = {
  0, 1, 2,
  2, 3, 0
};

const char* vertex_shader_wo_version =
"attribute vec2 vert2d;\n"
"void main(void) {\n"
"  gl_Position = vec4(vert2d, 0.0, 1.0);\n"
"}";

void errorCallback(int error, const char* description) {
  std::cerr << error << ": " << description << std::endl;
  exit(EXIT_FAILURE);
}

bool readFile(const std::string& fileName, std::string& contentsOut) {
  std::ifstream ifs(fileName.c_str());
  if(!ifs) {
    std::cerr << "File " << fileName << " not found" << std::endl;
    return false;
  }
  std::stringstream ss;
  ss << ifs.rdbuf();
  contentsOut = ss.str();
  return true;
}

void printProgramError(GLuint program) {
  GLint length = 0;
  glGetShaderiv(program, GL_INFO_LOG_LENGTH, &length);

  // The maxLength includes the NULL character

  std::vector<GLchar> errorLog((size_t) length, 0);

  glGetShaderInfoLog(program, length, &length, &errorLog[0]);
  if(length > 0) {
    std::string s(&errorLog[0]);
    std::cout << s << std::endl;
  }
}

void persistKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
  exit(EXIT_SUCCESS);
}

int go(int argc, char* argv[]) {

  glfwWindowHint(GLFW_RESIZABLE, 0);
#ifdef __APPLE__
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif

  GLFWwindow* window = glfwCreateWindow(640, 480, "Get image", NULL, NULL);

  if(!window) {
    return EXIT_FAILURE;
  }

  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
  glfwSwapInterval(1);

  bool persist = false;
  bool animate = false;
  bool exit_compile = false;
  bool exit_linking = false;
  std::string output("output.png");
  std::string vertex_shader;
  std::string fragment_shader;

  for(int i = 1; i < argc; i++) {
    std::string curr_arg = std::string(argv[i]);
    if(!curr_arg.compare(0, 2, "--")) {
      if(curr_arg == "--persist") {
        persist = true;
        continue;
      }
      else if(curr_arg == "--animate") {
        animate = true;
        continue;
      }
      else if(curr_arg == "--exit_compile") {
        exit_compile = true;
        continue;
      }
      else if(curr_arg == "--exit_linking") {
        exit_linking = true;
        continue;
      }
      else if(curr_arg == "--output") {
        output = argv[++i];
        continue;
      }
      else if(curr_arg == "--vertex") {
        vertex_shader = argv[++i];
        continue;
      }
      std::cerr << "Unknown argument " << curr_arg << std::endl;
      continue;
    }
    if (fragment_shader.length() == 0) {
      fragment_shader = curr_arg;
    } else {
      std::cerr << "Ignoring extra argument " << curr_arg << std::endl;
    }
  }

  if(fragment_shader.length() == 0) {
    std::cerr << "Requires fragment shader argument!" << std::endl;
    return EXIT_FAILURE;
  }

  GLuint program = glCreateProgram();
  int compileOk = 0;
  const char* temp;

  std::string fragContents;
  if(!readFile(fragment_shader, fragContents)) {
    return EXIT_FAILURE;
  }

  temp = fragContents.c_str();
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &temp, NULL);
  glCompileShader(fragmentShader);
  glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling fragment shader." << std::endl;
    printProgramError(program);
    return COMPILE_ERROR_EXIT_CODE;
  }
  std::cerr << "Fragment shader compiled successfully." << std::endl;
  if (exit_compile) {
    std::cout << "Exiting after fragment shader compilation." << std::endl;
    return EXIT_SUCCESS;
  }
  glAttachShader(program, fragmentShader);

  std::string vertexContents;
  if(vertex_shader.length() == 0) {
    // Use embedded vertex shader.
    std::stringstream ss;
    size_t i = fragContents.find('\n');
    if(i != std::string::npos && fragContents[0] == '#') {
      ss << fragContents.substr(0,i);
      ss << "\n";
    } else {
      std::cerr << "Warning: Could not find #version string of fragment shader." << std::endl;
    }
    ss << vertex_shader_wo_version;
    vertexContents = ss.str();
  } else {
    if(!readFile(vertex_shader, vertexContents)) {
      return EXIT_FAILURE;
    }
  }

  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  temp = vertexContents.c_str();
  glShaderSource(vertexShader, 1, &temp, NULL);
  glCompileShader(vertexShader);
  glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling vertex shader." << std::endl;
    printProgramError(program);
    return EXIT_FAILURE;
  }
  std::cerr << "Vertex shader compiled successfully." << std::endl;

  glAttachShader(program, vertexShader);

  std::cerr << "Linking program." << std::endl;
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error in linking program." << std::endl;
    printProgramError(program);
    return LINK_ERROR_EXIT_CODE;
  }
  std::cerr << "Program linked successfully." << std::endl;
  if (exit_linking) {
    std::cout << "Exiting after program linking." << std::endl;
    return EXIT_SUCCESS;
  }

  GLint posAttribLocationAttempt = glGetAttribLocation(program, "vert2d");
  if(posAttribLocationAttempt == -1) {
    std::cerr << "Error getting vert2d attribute location." << std::endl;
    return EXIT_FAILURE;
  }
  GLuint posAttribLocation = (GLuint) posAttribLocationAttempt;
  glEnableVertexAttribArray(posAttribLocation);

  glUseProgram(program);

  GLuint vertexBuffer;
  glGenBuffers(1, &vertexBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  GLuint indicesBuffer;
  glGenBuffers(1, &indicesBuffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

  GLint injectionSwitchLocation = glGetUniformLocation(program, "injectionSwitch");
  GLint timeLocation = glGetUniformLocation(program, "time");
  GLint mouseLocation = glGetUniformLocation(program, "mouse");
  GLint resolutionLocation = glGetUniformLocation(program, "resolution");

  if(injectionSwitchLocation != -1) {
    glUniform2f(injectionSwitchLocation, 0.0f, 1.0f);
  }
  if(mouseLocation != -1) {
    glUniform2f(mouseLocation, 0.0f, 0.0f);
  }
  if(timeLocation != -1) {
    glUniform1f(timeLocation, 0.0f);
  }

  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glVertexAttribPointer(posAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

  int numFrames = 0;
  bool saved = false;

  while(!glfwWindowShouldClose(window)) {
    int width;
    int height;
    glfwGetFramebufferSize(window, &width, &height);

    glViewport(0, 0, width, height);

    if(resolutionLocation != -1) {
      glUniform2f(resolutionLocation, width, height);
    }

    if(animate && timeLocation != -1 && numFrames > DELAY) {
      glUniform1f(timeLocation, numFrames / 10.0f);
    }

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
    glfwSwapBuffers(window);
    glfwPollEvents();
    ++numFrames;

    if(numFrames == DELAY && !saved) {
      saved = true;
      unsigned uwidth = (unsigned int) width;
      unsigned uheight = (unsigned int) height;
      std::vector<std::uint8_t> data(uwidth * uheight * CHANNELS);
      glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
      std::vector<std::uint8_t> flipped_data(uwidth * uheight * CHANNELS);
      for (unsigned int h = 0; h < uheight ; h++)
        for (unsigned int col = 0; col < uwidth * CHANNELS; col++)
          flipped_data[h * uwidth * CHANNELS + col] =
              data[(uheight - h - 1) * uwidth * CHANNELS + col];
      unsigned png_error = lodepng::encode(output, flipped_data, uwidth, uheight);
      if (png_error) {
        std::cerr << "Error producing PNG file: " << lodepng_error_text(png_error) << std::endl;
        return EXIT_FAILURE;
      }
      if (persist) {
        printf("Press any key to close the window...\n");
        glfwSetKeyCallback(window, persistKeyCallback);
      }
      else {
        return EXIT_SUCCESS;
      }
    }

  }
  return EXIT_SUCCESS;
}

int main(int argc, char* argv[]) {

  glfwSetErrorCallback(errorCallback);

  if(!glfwInit()) {
    exit(EXIT_FAILURE);
  }

  int res = go(argc, argv);

  glfwTerminate();
  return res;
}

<|endoftext|>


<commit_before>// This test program mirrors whatever there is on PB0 onto PB2.
// An example circuit to excercise this test:

/*

         SW1          IC1             D1    R1
                     ____________
          /         |            |    |\ |
      +--/ ---------+ PB0    PB2 +----| >+--^v----+
      |             |            |    |/ |        |
      > R2          |____________|                |
      <                                          _+_
      |
     _+_

*/

#include "board.h"

#include <avr/interrupt.h>

using namespace test_int0;

ISR(PCINT0_vect, ISR_NAKED)
{
    Board::OutputPin::write(Board::InputPin::isSet());
    reti();
}

//ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
//ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));

int main(void)
{
    Board::init();
    sei();
    for (;;)
    { }
}<commit_msg>Some tweaks in interrupt test code.<commit_after>// This test program mirrors whatever there is on PB0 onto PB2.
// An example circuit to excercise this test:

/*

         SW1          IC1             D1    R1
                     ____________
          /         |            |    |\ |
      +--/ ---------+ PB0    PB2 +----| >+--^v----+
      |             |            |    |/ |        |
      > R2          |____________|                |
      <                                          _+_
      |
     _+_

*/

#include "board.h"

#include <avr/interrupt.h>

using namespace test_int0;

// copyInputToOutput1 and copyInputToOutput2 should generate identical code
// (like bit-for-bit identical).

static void copyInputToOutput1()
{
    Board::OutputPin::write(Board::InputPin::isSet());
}

static void copyInputToOutput2()
{
    bool const isSet = PINB & (1<<PORTB0);
    if (isSet)
        PORTB |= (1<<PORTB2);
    else
        PORTB &= ~(1<<PORTB2);
}

ISR(PCINT0_vect, ISR_NAKED)
{
    copyInputToOutput1();
    reti();
}

//ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
//ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));

int main(void)
{
    Board::init();
    copyInputToOutput1();
    sei();
    for (;;)
    { }
}<|endoftext|>


<commit_before>#include "src/s3_cmds/zgw_s3_command.h"

#include "src/zgw_utils.h"
#include "src/s3_cmds/zgw_s3_object.h"
#include "src/s3_cmds/zgw_s3_bucket.h"
#include "src/s3_cmds/zgw_s3_xml.h"

class ZgwTestCmd : public S3Cmd {
  virtual bool DoInitial() {
    http_response_xml_.clear();
    return true;
  }
  virtual void DoAndResponse(pink::HTTPResponse* resp) {

    resp->SetStatusCode(200);
    resp->SetContentLength(http_response_xml_.size());
  }
  virtual int DoResponseBody(char* buf, size_t max_size) {
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  };
};

class UnImplementCmd : public S3Cmd {
  virtual bool DoInitial() {
    return false;
  }
  virtual void DoAndResponse(pink::HTTPResponse* resp) {
    GenerateErrorXml(kNotImplemented);
    resp->SetStatusCode(501);
    resp->SetContentLength(http_response_xml_.size());
  }
  virtual int DoResponseBody(char* buf, size_t max_size) {
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  };
};

void InitCmdTable(S3CmdTable* cmd_table) {
  cmd_table->insert(std::make_pair(kListAllBuckets, new ListAllBucketsCmd()));
  cmd_table->insert(std::make_pair(kDeleteBucket, new DeleteBucketCmd()));
  cmd_table->insert(std::make_pair(kListObjects, new ListObjectsCmd()));
  cmd_table->insert(std::make_pair(kGetBucketLocation, new GetBucketLocationCmd()));
  cmd_table->insert(std::make_pair(kHeadBucket, new HeadBucketCmd()));
  cmd_table->insert(std::make_pair(kListMultiPartUpload, new ListMultiPartUploadCmd()));
  cmd_table->insert(std::make_pair(kPutBucket, new PutBucketCmd()));
  cmd_table->insert(std::make_pair(kDeleteObject, new DeleteObjectCmd()));
  cmd_table->insert(std::make_pair(kDeleteMultiObjects, new DeleteMultiObjectsCmd()));
  cmd_table->insert(std::make_pair(kGetObject, new GetObjectCmd()));
  cmd_table->insert(std::make_pair(kHeadObject, new HeadObjectCmd()));
  cmd_table->insert(std::make_pair(kPostObject, new PostObjectCmd()));
  cmd_table->insert(std::make_pair(kPutObject, new PutObjectCmd()));
  cmd_table->insert(std::make_pair(kPutObjectCopy, new PutObjectCopyCmd()));
  cmd_table->insert(std::make_pair(kInitMultipartUpload, new InitMultipartUploadCmd()));
  cmd_table->insert(std::make_pair(kUploadPart, new UploadPartCmd()));
  cmd_table->insert(std::make_pair(kUploadPartCopy, new UploadPartCopyCmd()));
  cmd_table->insert(std::make_pair(kUploadPartCopyPartial, new UploadPartCopyPartialCmd()));
  cmd_table->insert(std::make_pair(kCompleteMultiUpload, new CompleteMultiUploadCmd()));
  cmd_table->insert(std::make_pair(kAbortMultiUpload, new AbortMultiUploadCmd()));
  cmd_table->insert(std::make_pair(kListParts, new ListPartsCmd()));
  cmd_table->insert(std::make_pair(kUnImplement, new UnImplementCmd()));
  cmd_table->insert(std::make_pair(kZgwTest, new ZgwTestCmd()));
}

void DestroyCmdTable(S3CmdTable* cmd_table) {
  for (auto& cmd : *cmd_table) {
    delete cmd.second;
  }
}

bool S3Cmd::TryAuth() {
  switch(s3_auth_.TryAuth()) {
    case kAuthSuccess:
      http_ret_code_ = 200;
      break;
    case kAccessKeyInvalid:
      http_ret_code_ = 403;
      GenerateErrorXml(kInvalidAccessKeyId);
      return false;
      break;
    case kSignatureNotMatch:
      http_ret_code_ = 403;
      GenerateErrorXml(kSignatureDoesNotMatch);
      return false;
      break;
    case kMaybeAuthV2:
    default:
      http_ret_code_ = 400;
      GenerateErrorXml(kInvalidRequest, "Please use AWS4-HMAC-SHA256.");
      return false;
  }

  user_name_.assign(s3_auth_.user_name());

  return true;
}

void S3Cmd::Clear() {
  user_name_.clear();
  bucket_name_.clear();
  object_name_.clear();
  req_headers_.clear();
  query_params_.clear();
  store_ = nullptr;

  http_ret_code_ = 200;
  http_request_xml_.clear();
  http_response_xml_.clear();
}

void S3Cmd::GenerateErrorXml(S3ErrorType type, const std::string& message) {
  http_response_xml_.clear();
  S3XmlDoc doc("Error");
  switch(type) {
    case kInvalidRequest:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidRequest"));
      doc.AppendToRoot(doc.AllocateNode("Message", message));
      break;
    case kAccessDenied:
      doc.AppendToRoot(doc.AllocateNode("Code", "AccessDenied"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Access Denied"));
      break;
    case kInvalidRange:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidRange"));
      doc.AppendToRoot(doc.AllocateNode("ObjectName", message));
      break;
    case kInvalidArgument:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidArgument"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Copy Source must mention the "
                                        "source bucket and key: "
                                        "sourcebucket/sourcekey"));
      doc.AppendToRoot(doc.AllocateNode("ArgumentName", message));
      break;
    case kMethodNotAllowed:
      doc.AppendToRoot(doc.AllocateNode("Code", "MethodNotAllowed"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified method is not "
                                        "allowed against this resource."));
      break;
    case kInvalidPartOrder:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidPartOrder"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The list of parts was not in "
                                        "ascending order. The parts list must be "
                                        "specified in order by part number."));
      break;
    case kInvalidPart:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidPart"));
      doc.AppendToRoot(doc.AllocateNode("Message", "One or more of the specified "
                                        "parts could not be found. The part might "
                                        "not have been uploaded, or the specified "
                                        "entity tag might not have matched the "
                                        "part's entity tag."));
      break;
    case kMalformedXML:
      doc.AppendToRoot(doc.AllocateNode("Code", "MalformedXML"));
      doc.AppendToRoot(doc.AllocateNode("Message", "This happens when the user "
                                        "sends malformed xml (xml that doesn't "
                                                             "conform to the "
                                                             "published xsd) for "
                                        "the configuration. The error message is, "
                                        "\"The XML you provided was not well-formed "
                                        "or did not validate against our published "
                                        "schema.\""));
      break;
    case kNoSuchUpload:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchUpload"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified upload does not "
                                        "exist. The upload ID may be invalid, or "
                                        "the upload may have been aborted or "
                                        "completed."));
      doc.AppendToRoot(doc.AllocateNode("UploadId", message));
      break;
    case kBucketAlreadyExists:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketAlreadyExists"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The requested bucket name is "
                                        "not available. The bucket namespace is "
                                        "shared by all users of the system. Please "
                                        "select a different name and try again."));
      break;
    case kBucketAlreadyOwnedByYou:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketAlreadyOwnedByYou"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Your previous request to "
                                        "create the named bucket succeeded and you "
                                        "already own it."));
      break;
    case kInvalidAccessKeyId:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidAccessKeyId"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The access key Id you provided "
                                        "does not exist in our records."));
      break;
    case kNotImplemented:
      doc.AppendToRoot(doc.AllocateNode("Code", "NotImplemented"));
      doc.AppendToRoot(doc.AllocateNode("Message", "A header you provided implies "
                                        "functionality that is not implemented."));
      break;
    case kSignatureDoesNotMatch:
      doc.AppendToRoot(doc.AllocateNode("Code", "SignatureDoesNotMatch"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The request signature we "
                                        "calculated does not match the signature "
                                        "you provided. Check your key and signing "
                                        "method."));
      break;
    case kNoSuchBucket:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchBucket"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified bucket does not "
                                        "exist."));
      doc.AppendToRoot(doc.AllocateNode("BucketName", message));
      break;
    case kNoSuchKey:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchKey"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified key does not "
                                        "exist."));
      doc.AppendToRoot(doc.AllocateNode("Key", message));
      break;
    case kBucketNotEmpty:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketNotEmpty"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The bucket you tried to delete "
                                        "is not empty"));
      doc.AppendToRoot(doc.AllocateNode("BucketName", message));
      break;
    default:
      break;
  }
  doc.AppendToRoot("RequestId", request_id_);
  doc.AppendToRoot("HostId", hostname());
  doc.ToString(&http_response_xml_);
}
<commit_msg>use md5 as hostid<commit_after>#include "src/s3_cmds/zgw_s3_command.h"

#include "src/zgw_utils.h"
#include "src/s3_cmds/zgw_s3_object.h"
#include "src/s3_cmds/zgw_s3_bucket.h"
#include "src/s3_cmds/zgw_s3_xml.h"

class ZgwTestCmd : public S3Cmd {
  virtual bool DoInitial() {
    http_response_xml_.clear();
    return true;
  }
  virtual void DoAndResponse(pink::HTTPResponse* resp) {

    resp->SetStatusCode(200);
    resp->SetContentLength(http_response_xml_.size());
  }
  virtual int DoResponseBody(char* buf, size_t max_size) {
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  };
};

class UnImplementCmd : public S3Cmd {
  virtual bool DoInitial() {
    return false;
  }
  virtual void DoAndResponse(pink::HTTPResponse* resp) {
    GenerateErrorXml(kNotImplemented);
    resp->SetStatusCode(501);
    resp->SetContentLength(http_response_xml_.size());
  }
  virtual int DoResponseBody(char* buf, size_t max_size) {
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  };
};

void InitCmdTable(S3CmdTable* cmd_table) {
  cmd_table->insert(std::make_pair(kListAllBuckets, new ListAllBucketsCmd()));
  cmd_table->insert(std::make_pair(kDeleteBucket, new DeleteBucketCmd()));
  cmd_table->insert(std::make_pair(kListObjects, new ListObjectsCmd()));
  cmd_table->insert(std::make_pair(kGetBucketLocation, new GetBucketLocationCmd()));
  cmd_table->insert(std::make_pair(kHeadBucket, new HeadBucketCmd()));
  cmd_table->insert(std::make_pair(kListMultiPartUpload, new ListMultiPartUploadCmd()));
  cmd_table->insert(std::make_pair(kPutBucket, new PutBucketCmd()));
  cmd_table->insert(std::make_pair(kDeleteObject, new DeleteObjectCmd()));
  cmd_table->insert(std::make_pair(kDeleteMultiObjects, new DeleteMultiObjectsCmd()));
  cmd_table->insert(std::make_pair(kGetObject, new GetObjectCmd()));
  cmd_table->insert(std::make_pair(kHeadObject, new HeadObjectCmd()));
  cmd_table->insert(std::make_pair(kPostObject, new PostObjectCmd()));
  cmd_table->insert(std::make_pair(kPutObject, new PutObjectCmd()));
  cmd_table->insert(std::make_pair(kPutObjectCopy, new PutObjectCopyCmd()));
  cmd_table->insert(std::make_pair(kInitMultipartUpload, new InitMultipartUploadCmd()));
  cmd_table->insert(std::make_pair(kUploadPart, new UploadPartCmd()));
  cmd_table->insert(std::make_pair(kUploadPartCopy, new UploadPartCopyCmd()));
  cmd_table->insert(std::make_pair(kUploadPartCopyPartial, new UploadPartCopyPartialCmd()));
  cmd_table->insert(std::make_pair(kCompleteMultiUpload, new CompleteMultiUploadCmd()));
  cmd_table->insert(std::make_pair(kAbortMultiUpload, new AbortMultiUploadCmd()));
  cmd_table->insert(std::make_pair(kListParts, new ListPartsCmd()));
  cmd_table->insert(std::make_pair(kUnImplement, new UnImplementCmd()));
  cmd_table->insert(std::make_pair(kZgwTest, new ZgwTestCmd()));
}

void DestroyCmdTable(S3CmdTable* cmd_table) {
  for (auto& cmd : *cmd_table) {
    delete cmd.second;
  }
}

bool S3Cmd::TryAuth() {
  switch(s3_auth_.TryAuth()) {
    case kAuthSuccess:
      http_ret_code_ = 200;
      break;
    case kAccessKeyInvalid:
      http_ret_code_ = 403;
      GenerateErrorXml(kInvalidAccessKeyId);
      return false;
      break;
    case kSignatureNotMatch:
      http_ret_code_ = 403;
      GenerateErrorXml(kSignatureDoesNotMatch);
      return false;
      break;
    case kMaybeAuthV2:
    default:
      http_ret_code_ = 400;
      GenerateErrorXml(kInvalidRequest, "Please use AWS4-HMAC-SHA256.");
      return false;
  }

  user_name_.assign(s3_auth_.user_name());

  return true;
}

void S3Cmd::Clear() {
  user_name_.clear();
  bucket_name_.clear();
  object_name_.clear();
  req_headers_.clear();
  query_params_.clear();
  store_ = nullptr;

  http_ret_code_ = 200;
  http_request_xml_.clear();
  http_response_xml_.clear();
}

void S3Cmd::GenerateErrorXml(S3ErrorType type, const std::string& message) {
  http_response_xml_.clear();
  S3XmlDoc doc("Error");
  switch(type) {
    case kInvalidRequest:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidRequest"));
      doc.AppendToRoot(doc.AllocateNode("Message", message));
      break;
    case kAccessDenied:
      doc.AppendToRoot(doc.AllocateNode("Code", "AccessDenied"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Access Denied"));
      break;
    case kInvalidRange:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidRange"));
      doc.AppendToRoot(doc.AllocateNode("ObjectName", message));
      break;
    case kInvalidArgument:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidArgument"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Copy Source must mention the "
                                        "source bucket and key: "
                                        "sourcebucket/sourcekey"));
      doc.AppendToRoot(doc.AllocateNode("ArgumentName", message));
      break;
    case kMethodNotAllowed:
      doc.AppendToRoot(doc.AllocateNode("Code", "MethodNotAllowed"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified method is not "
                                        "allowed against this resource."));
      break;
    case kInvalidPartOrder:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidPartOrder"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The list of parts was not in "
                                        "ascending order. The parts list must be "
                                        "specified in order by part number."));
      break;
    case kInvalidPart:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidPart"));
      doc.AppendToRoot(doc.AllocateNode("Message", "One or more of the specified "
                                        "parts could not be found. The part might "
                                        "not have been uploaded, or the specified "
                                        "entity tag might not have matched the "
                                        "part's entity tag."));
      break;
    case kMalformedXML:
      doc.AppendToRoot(doc.AllocateNode("Code", "MalformedXML"));
      doc.AppendToRoot(doc.AllocateNode("Message", "This happens when the user "
                                        "sends malformed xml (xml that doesn't "
                                                             "conform to the "
                                                             "published xsd) for "
                                        "the configuration. The error message is, "
                                        "\"The XML you provided was not well-formed "
                                        "or did not validate against our published "
                                        "schema.\""));
      break;
    case kNoSuchUpload:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchUpload"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified upload does not "
                                        "exist. The upload ID may be invalid, or "
                                        "the upload may have been aborted or "
                                        "completed."));
      doc.AppendToRoot(doc.AllocateNode("UploadId", message));
      break;
    case kBucketAlreadyExists:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketAlreadyExists"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The requested bucket name is "
                                        "not available. The bucket namespace is "
                                        "shared by all users of the system. Please "
                                        "select a different name and try again."));
      break;
    case kBucketAlreadyOwnedByYou:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketAlreadyOwnedByYou"));
      doc.AppendToRoot(doc.AllocateNode("Message", "Your previous request to "
                                        "create the named bucket succeeded and you "
                                        "already own it."));
      break;
    case kInvalidAccessKeyId:
      doc.AppendToRoot(doc.AllocateNode("Code", "InvalidAccessKeyId"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The access key Id you provided "
                                        "does not exist in our records."));
      break;
    case kNotImplemented:
      doc.AppendToRoot(doc.AllocateNode("Code", "NotImplemented"));
      doc.AppendToRoot(doc.AllocateNode("Message", "A header you provided implies "
                                        "functionality that is not implemented."));
      break;
    case kSignatureDoesNotMatch:
      doc.AppendToRoot(doc.AllocateNode("Code", "SignatureDoesNotMatch"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The request signature we "
                                        "calculated does not match the signature "
                                        "you provided. Check your key and signing "
                                        "method."));
      break;
    case kNoSuchBucket:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchBucket"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified bucket does not "
                                        "exist."));
      doc.AppendToRoot(doc.AllocateNode("BucketName", message));
      break;
    case kNoSuchKey:
      doc.AppendToRoot(doc.AllocateNode("Code", "NoSuchKey"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The specified key does not "
                                        "exist."));
      doc.AppendToRoot(doc.AllocateNode("Key", message));
      break;
    case kBucketNotEmpty:
      doc.AppendToRoot(doc.AllocateNode("Code", "BucketNotEmpty"));
      doc.AppendToRoot(doc.AllocateNode("Message", "The bucket you tried to delete "
                                        "is not empty"));
      doc.AppendToRoot(doc.AllocateNode("BucketName", message));
      break;
    default:
      break;
  }
  doc.AppendToRoot("RequestId", request_id_);
  doc.AppendToRoot("HostId", md5(hostname()));
  doc.ToString(&http_response_xml_);
}
<|endoftext|>


<commit_before>#include "kmmainwin.h"
#include "kmmainwidget.h"
#include "kstatusbar.h"
#include "kmkernel.h"
#include "kmsender.h"
#include "kmbroadcaststatus.h"
#include "kmglobal.h"
#include "kapplication.h"
#include <klocale.h>
#include <kedittoolbar.h>
#include <kconfig.h>
#include <kmessagebox.h>

#include "kmmainwin.moc"

KMMainWin::KMMainWin(QWidget *)
	: KMTopLevelWidget("kmail-mainwindow")
{
  mKMMainWidget = new KMMainWidget( this, "KMMainWidget", actionCollection() );
  mKMMainWidget->resize( 450, 600 );
  setCentralWidget(mKMMainWidget);
  setupStatusBar();

#if KDE_IS_VERSION( 3, 1, 90 )
  createStandardStatusBarAction();
  setStandardToolBarMenuEnabled(true);
#endif

  KStdAction::configureToolbars(this, SLOT(slotEditToolbars()),
				actionCollection());

  KStdAction::keyBindings(mKMMainWidget, SLOT(slotEditKeys()),
                          actionCollection());

#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction = KStdAction::showToolbar(this,
					   SLOT(slotToggleToolBar()),
					   actionCollection());
  mStatusbarAction = KStdAction::showStatusbar(this,
					       SLOT(slotToggleStatusBar()),
					       actionCollection());
#endif

  KStdAction::quit( this, SLOT(slotQuit()), actionCollection());
  createGUI( "kmmainwin.rc", false );
#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction->setChecked(!toolBar()->isHidden());
  mStatusbarAction->setChecked(!statusBar()->isHidden());
#endif

  conserveMemory();
  applyMainWindowSettings(KMKernel::config(), "Main Window");
  connect(kmkernel->msgSender(), SIGNAL(statusMsg(const QString&)),
	  this, SLOT(statusMsg(const QString&)));
  connect(kmkernel, SIGNAL(configChanged()),
    this, SLOT(slotConfigChanged()));
  connect(mKMMainWidget->messageView(), SIGNAL(statusMsg(const QString&)),
	  this, SLOT(htmlStatusMsg(const QString&)));
  connect(mKMMainWidget, SIGNAL(captionChangeRequest(const QString&)),
	  SLOT(setCaption(const QString&)) );
}

KMMainWin::~KMMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Main Window");
  KMKernel::config()->sync();
}

void KMMainWin::statusMsg(const QString& aText)
{
  mLastStatusMsg = aText;
  displayStatusMsg(aText);
}

void KMMainWin::htmlStatusMsg(const QString& aText)
{
  if (aText.isEmpty()) displayStatusMsg(mLastStatusMsg);
  else displayStatusMsg(aText);
}

void KMMainWin::displayStatusMsg(const QString& aText)
{
  if ( !statusBar() || !littleProgress) return;
  QString text = " " + aText + " ";
  int statusWidth = statusBar()->width() - littleProgress->width()
    - fontMetrics().maxWidth();

  while (!text.isEmpty() && fontMetrics().width( text ) >= statusWidth)
    text.truncate( text.length() - 1);

  // ### FIXME: We should disable richtext/HTML (to avoid possible denial of service attacks),
  // but this code would double the size of the satus bar if the user hovers
  // over an <foo@bar.com>-style email address :-(
//  text.replace("&", "&");
//  text.replace("<", "<");
//  text.replace(">", ">");

  statusBar()->changeItem(text, mMessageStatusId);
}

void KMMainWin::slotToggleToolBar()
{
#if !KDE_IS_VERSION( 3, 1, 90 )
  if(toolBar("mainToolBar")->isVisible())
    toolBar("mainToolBar")->hide();
  else
    toolBar("mainToolBar")->show();
#endif
}

void KMMainWin::slotToggleStatusBar()
{
#if !KDE_IS_VERSION( 3, 1, 90 )
  if (statusBar()->isVisible())
    statusBar()->hide();
  else
    statusBar()->show();
#endif
}

void KMMainWin::slotEditToolbars()
{
  saveMainWindowSettings(KMKernel::config(), "MainWindow");
  KEditToolbar dlg(actionCollection(), "kmmainwin.rc");

  connect( &dlg, SIGNAL(newToolbarConfig()),
	   SLOT(slotUpdateToolbars()) );

  dlg.exec();
}

void KMMainWin::slotUpdateToolbars()
{
  createGUI("kmmainwin.rc");
  applyMainWindowSettings(KMKernel::config(), "MainWindow");
#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction->setChecked(!toolBar()->isHidden());
#endif
}

void KMMainWin::setupStatusBar()
{
  mMessageStatusId = 1;
  littleProgress = mainKMWidget()->progressDialog();

  statusBar()->addWidget( littleProgress, 0 , true );
  statusBar()->insertItem(i18n(" Initializing..."), 1, 1 );
  statusBar()->setItemAlignment( 1, AlignLeft | AlignVCenter );
  littleProgress->show();
}

/** Read configuration options after widgets are created. */
void KMMainWin::readConfig(void)
{
}

/** Write configuration options. */
void KMMainWin::writeConfig(void)
{
  mKMMainWidget->writeConfig();
}

void KMMainWin::slotQuit()
{
    close();
}

void KMMainWin::slotConfigChanged()
{
  readConfig();
}

//-----------------------------------------------------------------------------
bool KMMainWin::queryClose() {
  if (kmkernel->shuttingDown() || kapp->sessionSaving())
    return true;

  int      ret = 0;
  QString  str = i18n("Expire old messages from all folders? "
		      "Expired messages are permanently deleted.");
  KConfig *config = KMKernel::config();

  // Make sure this is the last window.
  KMainWindow   *kmWin = 0;
  int           num = 0;

  kmkernel->setCanExpire(false);
  for (kmWin = KMainWindow::memberList->first(); kmWin;
       kmWin = KMainWindow::memberList->next()) {
    if (kmWin->isA("KMMainWin")) {
      num++;
    }
  }
  // If this isn't the last open window, don't do anything.
  if (num > 1) {
    return true;
  }

  KConfigGroupSaver saver(config, "General");
  if (config->readNumEntry("when-to-expire", 0) != expireAtExit) {
    return true;
  }

  if (config->readBoolEntry("warn-before-expire", true)) {
    ret = KMessageBox::warningYesNo(KMainWindow::memberList->first(),
			 str, i18n("Expire Old Messages?"), i18n("Expire"), i18n("Don't Expire"));
    if (ret == KMessageBox::Continue) {
      kmkernel->setCanExpire(true);
    }
  }

  return true;
}
<commit_msg>Fix bug #70411 (menu and toolbar of additional KMail main window miss almost everything in Kontact).<commit_after>#include "kmmainwin.h"
#include "kmmainwidget.h"
#include "kstatusbar.h"
#include "kmkernel.h"
#include "kmsender.h"
#include "kmbroadcaststatus.h"
#include "kmglobal.h"
#include "kapplication.h"
#include <klocale.h>
#include <kedittoolbar.h>
#include <kconfig.h>
#include <kmessagebox.h>

#include "kmmainwin.moc"

KMMainWin::KMMainWin(QWidget *)
	: KMTopLevelWidget("kmail-mainwindow")
{
  mKMMainWidget = new KMMainWidget( this, "KMMainWidget", actionCollection() );
  mKMMainWidget->resize( 450, 600 );
  setCentralWidget(mKMMainWidget);
  setupStatusBar();
  if (kmkernel->xmlGuiInstance())
    setInstance( kmkernel->xmlGuiInstance() );

#if KDE_IS_VERSION( 3, 1, 90 )
  createStandardStatusBarAction();
  setStandardToolBarMenuEnabled(true);
#endif

  KStdAction::configureToolbars(this, SLOT(slotEditToolbars()),
				actionCollection());

  KStdAction::keyBindings(mKMMainWidget, SLOT(slotEditKeys()),
                          actionCollection());

#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction = KStdAction::showToolbar(this,
					   SLOT(slotToggleToolBar()),
					   actionCollection());
  mStatusbarAction = KStdAction::showStatusbar(this,
					       SLOT(slotToggleStatusBar()),
					       actionCollection());
#endif

  KStdAction::quit( this, SLOT(slotQuit()), actionCollection());
  createGUI( "kmmainwin.rc", false );
#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction->setChecked(!toolBar()->isHidden());
  mStatusbarAction->setChecked(!statusBar()->isHidden());
#endif

  conserveMemory();
  applyMainWindowSettings(KMKernel::config(), "Main Window");
  connect(kmkernel->msgSender(), SIGNAL(statusMsg(const QString&)),
	  this, SLOT(statusMsg(const QString&)));
  connect(kmkernel, SIGNAL(configChanged()),
    this, SLOT(slotConfigChanged()));
  connect(mKMMainWidget->messageView(), SIGNAL(statusMsg(const QString&)),
	  this, SLOT(htmlStatusMsg(const QString&)));
  connect(mKMMainWidget, SIGNAL(captionChangeRequest(const QString&)),
	  SLOT(setCaption(const QString&)) );
}

KMMainWin::~KMMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Main Window");
  KMKernel::config()->sync();
}

void KMMainWin::statusMsg(const QString& aText)
{
  mLastStatusMsg = aText;
  displayStatusMsg(aText);
}

void KMMainWin::htmlStatusMsg(const QString& aText)
{
  if (aText.isEmpty()) displayStatusMsg(mLastStatusMsg);
  else displayStatusMsg(aText);
}

void KMMainWin::displayStatusMsg(const QString& aText)
{
  if ( !statusBar() || !littleProgress) return;
  QString text = " " + aText + " ";
  int statusWidth = statusBar()->width() - littleProgress->width()
    - fontMetrics().maxWidth();

  while (!text.isEmpty() && fontMetrics().width( text ) >= statusWidth)
    text.truncate( text.length() - 1);

  // ### FIXME: We should disable richtext/HTML (to avoid possible denial of service attacks),
  // but this code would double the size of the satus bar if the user hovers
  // over an <foo@bar.com>-style email address :-(
//  text.replace("&", "&");
//  text.replace("<", "<");
//  text.replace(">", ">");

  statusBar()->changeItem(text, mMessageStatusId);
}

void KMMainWin::slotToggleToolBar()
{
#if !KDE_IS_VERSION( 3, 1, 90 )
  if(toolBar("mainToolBar")->isVisible())
    toolBar("mainToolBar")->hide();
  else
    toolBar("mainToolBar")->show();
#endif
}

void KMMainWin::slotToggleStatusBar()
{
#if !KDE_IS_VERSION( 3, 1, 90 )
  if (statusBar()->isVisible())
    statusBar()->hide();
  else
    statusBar()->show();
#endif
}

void KMMainWin::slotEditToolbars()
{
  saveMainWindowSettings(KMKernel::config(), "MainWindow");
  KEditToolbar dlg(actionCollection(), "kmmainwin.rc");

  connect( &dlg, SIGNAL(newToolbarConfig()),
	   SLOT(slotUpdateToolbars()) );

  dlg.exec();
}

void KMMainWin::slotUpdateToolbars()
{
  createGUI("kmmainwin.rc");
  applyMainWindowSettings(KMKernel::config(), "MainWindow");
#if !KDE_IS_VERSION( 3, 1, 90 )
  mToolbarAction->setChecked(!toolBar()->isHidden());
#endif
}

void KMMainWin::setupStatusBar()
{
  mMessageStatusId = 1;
  littleProgress = mainKMWidget()->progressDialog();

  statusBar()->addWidget( littleProgress, 0 , true );
  statusBar()->insertItem(i18n(" Initializing..."), 1, 1 );
  statusBar()->setItemAlignment( 1, AlignLeft | AlignVCenter );
  littleProgress->show();
}

/** Read configuration options after widgets are created. */
void KMMainWin::readConfig(void)
{
}

/** Write configuration options. */
void KMMainWin::writeConfig(void)
{
  mKMMainWidget->writeConfig();
}

void KMMainWin::slotQuit()
{
    close();
}

void KMMainWin::slotConfigChanged()
{
  readConfig();
}

//-----------------------------------------------------------------------------
bool KMMainWin::queryClose() {
  if (kmkernel->shuttingDown() || kapp->sessionSaving())
    return true;

  int      ret = 0;
  QString  str = i18n("Expire old messages from all folders? "
		      "Expired messages are permanently deleted.");
  KConfig *config = KMKernel::config();

  // Make sure this is the last window.
  KMainWindow   *kmWin = 0;
  int           num = 0;

  kmkernel->setCanExpire(false);
  for (kmWin = KMainWindow::memberList->first(); kmWin;
       kmWin = KMainWindow::memberList->next()) {
    if (kmWin->isA("KMMainWin")) {
      num++;
    }
  }
  // If this isn't the last open window, don't do anything.
  if (num > 1) {
    return true;
  }

  KConfigGroupSaver saver(config, "General");
  if (config->readNumEntry("when-to-expire", 0) != expireAtExit) {
    return true;
  }

  if (config->readBoolEntry("warn-before-expire", true)) {
    ret = KMessageBox::warningYesNo(KMainWindow::memberList->first(),
			 str, i18n("Expire Old Messages?"), i18n("Expire"), i18n("Don't Expire"));
    if (ret == KMessageBox::Continue) {
      kmkernel->setCanExpire(true);
    }
  }

  return true;
}
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "v8-profiler.h"
#include "nan.h"

using namespace v8;

Local<Value> TranslateAllocationProfile(AllocationProfile::Node* node) {
  Local<Object> js_node = Nan::New<Object>();
  js_node->Set(Nan::New<String>("name").ToLocalChecked(),
    node->name);
  js_node->Set(Nan::New<String>("scriptName").ToLocalChecked(),
    node->script_name);
  js_node->Set(Nan::New<String>("lineNumber").ToLocalChecked(),
    Nan::New<Integer>(node->line_number));
  Local<Array> children = Nan::New<Array>(node->children.size());
  for (size_t i = 0; i < node->children.size(); i++) {
    children->Set(i, TranslateAllocationProfile(node->children[i]));
  }
  js_node->Set(Nan::New<String>("children").ToLocalChecked(),
    children);
  Local<Array> allocations = Nan::New<Array>(node->allocations.size());
  for (size_t i = 0; i < node->allocations.size(); i++) {
    AllocationProfile::Allocation alloc = node->allocations[i];
    Local<Object> js_alloc = Nan::New<Object>();
    js_alloc->Set(Nan::New<String>("size").ToLocalChecked(),
      Nan::New<Number>(alloc.size));
    js_alloc->Set(Nan::New<String>("count").ToLocalChecked(),
      Nan::New<Number>(alloc.count));
    allocations->Set(i, js_alloc);
  }
  js_node->Set(Nan::New<String>("allocations").ToLocalChecked(),
    allocations);
  return js_node;
}

NAN_METHOD(StartSamplingHeapProfiler) {
  if (info.Length() == 2) {
    if (!info[0]->IsUint32()) {
      return Nan::ThrowTypeError("First argument type must be uint32.");
    }
    if (!info[1]->IsNumber()) {
      return Nan::ThrowTypeError("First argument type must be Integer.");
    }
    uint64_t sample_interval = info[0].As<Integer>()->Uint32Value();
    int stack_depth = info[1].As<Integer>()->IntegerValue();
    info.GetIsolate()->GetHeapProfiler()->
      StartSamplingHeapProfiler(sample_interval, stack_depth);
  } else {
    info.GetIsolate()->GetHeapProfiler()->StartSamplingHeapProfiler();
  }
}

NAN_METHOD(StopSamplingHeapProfiler) {
  info.GetIsolate()->GetHeapProfiler()->StopSamplingHeapProfiler();
}

NAN_METHOD(GetAllocationProfile) {
  AllocationProfile profile = info.GetIsolate()->GetHeapProfiler()->GetAllocationProfile();
  AllocationProfile::Node* root = profile.GetRootNode();
  info.GetReturnValue().Set(TranslateAllocationProfile(root));
}

NAN_MODULE_INIT(InitAll) {
  Nan::Set(target, Nan::New("startSamplingHeapProfiler").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(StartSamplingHeapProfiler)).ToLocalChecked());
  Nan::Set(target, Nan::New("stopSamplingHeapProfiler").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(StopSamplingHeapProfiler)).ToLocalChecked());
  Nan::Set(target, Nan::New("getAllocationProfile").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(GetAllocationProfile)).ToLocalChecked());
}

NODE_MODULE(sampling_heap_profiler, InitAll);
<commit_msg>Update profile collection to match new api<commit_after>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "v8-profiler.h"
#include "nan.h"

using namespace v8;

Local<Value> TranslateAllocationProfile(AllocationProfile::Node* node) {
  Local<Object> js_node = Nan::New<Object>();
  js_node->Set(Nan::New<String>("name").ToLocalChecked(),
    node->name);
  js_node->Set(Nan::New<String>("scriptName").ToLocalChecked(),
    node->script_name);
  js_node->Set(Nan::New<String>("lineNumber").ToLocalChecked(),
    Nan::New<Integer>(node->line_number));
  Local<Array> children = Nan::New<Array>(node->children.size());
  for (size_t i = 0; i < node->children.size(); i++) {
    children->Set(i, TranslateAllocationProfile(node->children[i]));
  }
  js_node->Set(Nan::New<String>("children").ToLocalChecked(),
    children);
  Local<Array> allocations = Nan::New<Array>(node->allocations.size());
  for (size_t i = 0; i < node->allocations.size(); i++) {
    AllocationProfile::Allocation alloc = node->allocations[i];
    Local<Object> js_alloc = Nan::New<Object>();
    js_alloc->Set(Nan::New<String>("size").ToLocalChecked(),
      Nan::New<Number>(alloc.size));
    js_alloc->Set(Nan::New<String>("count").ToLocalChecked(),
      Nan::New<Number>(alloc.count));
    allocations->Set(i, js_alloc);
  }
  js_node->Set(Nan::New<String>("allocations").ToLocalChecked(),
    allocations);
  return js_node;
}

NAN_METHOD(StartSamplingHeapProfiler) {
  if (info.Length() == 2) {
    if (!info[0]->IsUint32()) {
      return Nan::ThrowTypeError("First argument type must be uint32.");
    }
    if (!info[1]->IsNumber()) {
      return Nan::ThrowTypeError("First argument type must be Integer.");
    }
    uint64_t sample_interval = info[0].As<Integer>()->Uint32Value();
    int stack_depth = info[1].As<Integer>()->IntegerValue();
    info.GetIsolate()->GetHeapProfiler()->
      StartSamplingHeapProfiler(sample_interval, stack_depth);
  } else {
    info.GetIsolate()->GetHeapProfiler()->StartSamplingHeapProfiler();
  }
}

NAN_METHOD(StopSamplingHeapProfiler) {
  info.GetIsolate()->GetHeapProfiler()->StopSamplingHeapProfiler();
}

NAN_METHOD(GetAllocationProfile) {
  AllocationProfile* profile = info.GetIsolate()->GetHeapProfiler()->GetAllocationProfile();
  AllocationProfile::Node* root = profile->GetRootNode();
  info.GetReturnValue().Set(TranslateAllocationProfile(root));
  free(profile);
}

NAN_MODULE_INIT(InitAll) {
  Nan::Set(target, Nan::New("startSamplingHeapProfiler").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(StartSamplingHeapProfiler)).ToLocalChecked());
  Nan::Set(target, Nan::New("stopSamplingHeapProfiler").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(StopSamplingHeapProfiler)).ToLocalChecked());
  Nan::Set(target, Nan::New("getAllocationProfile").ToLocalChecked(),
    Nan::GetFunction(Nan::New<FunctionTemplate>(GetAllocationProfile)).ToLocalChecked());
}

NODE_MODULE(sampling_heap_profiler, InitAll);
<|endoftext|>


<commit_before>/*****************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "materialinstance.h"
#include "material.h"

#include <QtCore/QVariant>
#include <QtGui/QVector2D>
#include <QtGui/QColor>

#include "mathutils.h"
#include "engine.h"
#include "texture.h"
#include "glheaders.h"
#include "camera.h"
#include "frustrum.h"

REGISTER_OBJECTTYPE( GluonGraphics, MaterialInstance )

using namespace GluonGraphics;

class MaterialInstance::MaterialInstancePrivate
{
    public:
        MaterialInstancePrivate()
            : activeCamera( 0 )
            , bound( false )
            , customViewProjMatrices( false )
        {
            activeCamera = Engine::instance()->activeCamera();
        }

        void setActiveCamera( Camera* camera )
        {
            activeCamera = camera;
        }

        Material* material;

        QHash<QString, int> uniformLocations;
        QHash<QString, int> attributeLocations;

        QHash<QString, QVariant> uniformValues;

        QHash<uint, Texture*> textures;

        Camera* activeCamera;

        bool bound;
        bool customViewProjMatrices;
};

MaterialInstance::MaterialInstance( QObject* parent )
    : GluonObject( parent ),
      d( new MaterialInstancePrivate )
{
    connect( Engine::instance(), SIGNAL( activeCameraChanging( Camera* ) ), this, SLOT( setActiveCamera( Camera* ) ) );
}

MaterialInstance::~MaterialInstance()
{
    delete d;
}

bool
MaterialInstance::bind()
{
    if( !d->material )
    {
        debug("Trying to bind a MaterialInstance without a material. This will most likely cause problems!");
        return false;
    }

    int program = d->material->glProgram();
    if( !program )
        return false;

    glUseProgram( program );
    d->bound = true;

    if(!d->customViewProjMatrices)
    {
        setGLUniform( QString( "viewMatrix" ), d->activeCamera->viewMatrix() );
        setGLUniform( QString( "projectionMatrix" ), d->activeCamera->frustrum()->projectionMatrix() );
    }

    QList<QByteArray> properties = dynamicPropertyNames();
    foreach( const QByteArray& prop, properties )
    {
        setGLUniform( prop, property( prop ) );
    }

    return true;
}

void
MaterialInstance::release()
{
    glUseProgram( 0 );
    glEnable( GL_BLEND );
    d->bound = false;
}

Material*
MaterialInstance::material()
{
    return d->material;
}

void
MaterialInstance::setMaterial( Material* material )
{
    d->material = material;
}

int MaterialInstance::attributeLocation( const QString& attrib )
{
    if( d->attributeLocations.contains( attrib ) )
        return d->attributeLocations.value( attrib );

    int loc = glGetAttribLocation( d->material->glProgram(), attrib.toUtf8().constData() );
    if( loc != -1 )
    {
        d->attributeLocations.insert( attrib, loc );
    }

    return loc;
}

int MaterialInstance::uniformLocation( const QString& name )
{
    if( d->uniformLocations.contains( name ) )
        return d->uniformLocations.value( name );

    int loc = glGetUniformLocation( d->material->glProgram(), name.toUtf8().constData() );
    if( loc != -1 )
    {
        d->uniformLocations.insert( name, loc );
    }

    return loc;
}

void
MaterialInstance::setPropertiesFromMaterial()
{
    QHash<QString, QVariant> uniforms = d->material->uniformList();
    for( QHash<QString, QVariant>::iterator pitr = uniforms.begin(); pitr != uniforms.end(); ++pitr )
    {
        setProperty( pitr.key().toUtf8(), pitr.value() );
    }
}

void MaterialInstance::setUseCustomViewProjMatrices(bool useCustom)
{
    d->customViewProjMatrices = useCustom;
}

void
MaterialInstance::setGLUniform( const QString& name, const QVariant& value )
{
    switch( value.type() )
    {
        case QVariant::UInt:
        case QVariant::Int:
            if(name.contains("texture"))
            {
                bindTexture(name, value.toInt());
            }
            else
            {
                glUniform1i( uniformLocation( name ), value.toInt() );
            }
            break;
        case QVariant::Double:
            glUniform1f( uniformLocation( name ), value.toDouble() );
            break;
        case QVariant::Color:
        {
            QColor color = value.value<QColor>();
            glUniform4f( uniformLocation( name ), color.red() / 255.f, color.green() / 255.f, color.blue() / 255.f, color.alpha() / 255.f );
            break;
        }
        case QVariant::Vector2D:
        {
            QVector2D vector = value.value<QVector2D>();
            glUniform2f( uniformLocation( name ), vector.x(), vector.y() );
            break;
        }
        case QVariant::Vector3D:
        {
            QVector3D vector = value.value<QVector3D>();
            glUniform3f( uniformLocation( name ), vector.x(), vector.y(), vector.z() );
            break;
        }
        case QVariant::Vector4D:
        {
            QVector4D vector = value.value<QVector4D>();
            glUniform4f( uniformLocation( name ), vector.x(), vector.y(), vector.z(), vector.w() );
            break;
        }
        case QVariant::String:
        {
            if( name.contains( "texture" ) )
            {
                GluonGraphics::Texture* texture = GluonGraphics::Engine::instance()->texture( value.toString() );
                bindTexture( name, texture );
            }
            break;
        }
        case QVariant::Matrix4x4:
        {
            QMatrix4x4 mat = value.value<QMatrix4x4>();
            float glMatrix[16];
            MathUtils::qmatrixToGLMatrix( mat, glMatrix );
            glUniformMatrix4fv( uniformLocation( name ), 1, false, glMatrix );
            break;
        }
        default:
        {
            GluonCore::GluonObject* obj = GluonCore::GluonObjectFactory::instance()->wrappedObject( value );
            if( obj && name.contains( "texture" ) )
            {
                QVariant val = obj->property("texture");
                if( val.isValid() )
                {
                    if( GluonGraphics::Texture* texture = val.value<GluonGraphics::Texture*>() )
                    {
                        bindTexture( name, texture );
                    }
                    else
                    {
                        debug( QString("The object contained in the texture property on object %1 was not valid").arg( obj->fullyQualifiedName() ) );
                    }
                }
                else
                {
                    debug( QString("Texture was not a valid property on %1").arg( obj->fullyQualifiedName() ) );
                }
            }
            break;
        }
    }
}

void
MaterialInstance::bindTexture( const QString& name, Texture* tex )
{
    if( !tex )
        return;

    bindTexture(name, tex->glTexture());
}

void MaterialInstance::bindTexture( const QString& name, int tex )
{
    QString uniName = name;
    int id = uniName.remove( "texture" ).toInt();

    glActiveTexture( GL_TEXTURE0 + id );
    glBindTexture( GL_TEXTURE_2D, tex );
    glUniform1i( uniformLocation( name ), id );
}

#include "materialinstance.moc"
<commit_msg>qRegisterMetatype for GluonEngine::Texture* in MaterialInstance<commit_after>/*****************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "materialinstance.h"
#include "material.h"

#include <QtCore/QVariant>
#include <QtGui/QVector2D>
#include <QtGui/QColor>

#include "mathutils.h"
#include "engine.h"
#include "texture.h"
#include "glheaders.h"
#include "camera.h"
#include "frustrum.h"

REGISTER_OBJECTTYPE( GluonGraphics, MaterialInstance )

using namespace GluonGraphics;

class MaterialInstance::MaterialInstancePrivate
{
    public:
        MaterialInstancePrivate()
            : activeCamera( 0 )
            , bound( false )
            , customViewProjMatrices( false )
        {
            activeCamera = Engine::instance()->activeCamera();
        }

        void setActiveCamera( Camera* camera )
        {
            activeCamera = camera;
        }

        Material* material;

        QHash<QString, int> uniformLocations;
        QHash<QString, int> attributeLocations;

        QHash<QString, QVariant> uniformValues;

        QHash<uint, Texture*> textures;

        Camera* activeCamera;

        bool bound;
        bool customViewProjMatrices;
};

MaterialInstance::MaterialInstance( QObject* parent )
    : GluonObject( parent ),
      d( new MaterialInstancePrivate )
{
    qRegisterMetaType<GluonGraphics::Texture*>("GluonGraphics::Texture*");
    connect( Engine::instance(), SIGNAL( activeCameraChanging( Camera* ) ), this, SLOT( setActiveCamera( Camera* ) ) );
}

MaterialInstance::~MaterialInstance()
{
    delete d;
}

bool
MaterialInstance::bind()
{
    if( !d->material )
    {
        debug("Trying to bind a MaterialInstance without a material. This will most likely cause problems!");
        return false;
    }

    int program = d->material->glProgram();
    if( !program )
        return false;

    glUseProgram( program );
    d->bound = true;

    if(!d->customViewProjMatrices)
    {
        setGLUniform( QString( "viewMatrix" ), d->activeCamera->viewMatrix() );
        setGLUniform( QString( "projectionMatrix" ), d->activeCamera->frustrum()->projectionMatrix() );
    }

    QList<QByteArray> properties = dynamicPropertyNames();
    foreach( const QByteArray& prop, properties )
    {
        setGLUniform( prop, property( prop ) );
    }

    return true;
}

void
MaterialInstance::release()
{
    glUseProgram( 0 );
    glEnable( GL_BLEND );
    d->bound = false;
}

Material*
MaterialInstance::material()
{
    return d->material;
}

void
MaterialInstance::setMaterial( Material* material )
{
    d->material = material;
}

int MaterialInstance::attributeLocation( const QString& attrib )
{
    if( d->attributeLocations.contains( attrib ) )
        return d->attributeLocations.value( attrib );

    int loc = glGetAttribLocation( d->material->glProgram(), attrib.toUtf8().constData() );
    if( loc != -1 )
    {
        d->attributeLocations.insert( attrib, loc );
    }

    return loc;
}

int MaterialInstance::uniformLocation( const QString& name )
{
    if( d->uniformLocations.contains( name ) )
        return d->uniformLocations.value( name );

    int loc = glGetUniformLocation( d->material->glProgram(), name.toUtf8().constData() );
    if( loc != -1 )
    {
        d->uniformLocations.insert( name, loc );
    }

    return loc;
}

void
MaterialInstance::setPropertiesFromMaterial()
{
    QHash<QString, QVariant> uniforms = d->material->uniformList();
    for( QHash<QString, QVariant>::iterator pitr = uniforms.begin(); pitr != uniforms.end(); ++pitr )
    {
        setProperty( pitr.key().toUtf8(), pitr.value() );
    }
}

void MaterialInstance::setUseCustomViewProjMatrices(bool useCustom)
{
    d->customViewProjMatrices = useCustom;
}

void
MaterialInstance::setGLUniform( const QString& name, const QVariant& value )
{
    switch( value.type() )
    {
        case QVariant::UInt:
        case QVariant::Int:
            if(name.contains("texture"))
            {
                bindTexture(name, value.toInt());
            }
            else
            {
                glUniform1i( uniformLocation( name ), value.toInt() );
            }
            break;
        case QVariant::Double:
            glUniform1f( uniformLocation( name ), value.toDouble() );
            break;
        case QVariant::Color:
        {
            QColor color = value.value<QColor>();
            glUniform4f( uniformLocation( name ), color.red() / 255.f, color.green() / 255.f, color.blue() / 255.f, color.alpha() / 255.f );
            break;
        }
        case QVariant::Vector2D:
        {
            QVector2D vector = value.value<QVector2D>();
            glUniform2f( uniformLocation( name ), vector.x(), vector.y() );
            break;
        }
        case QVariant::Vector3D:
        {
            QVector3D vector = value.value<QVector3D>();
            glUniform3f( uniformLocation( name ), vector.x(), vector.y(), vector.z() );
            break;
        }
        case QVariant::Vector4D:
        {
            QVector4D vector = value.value<QVector4D>();
            glUniform4f( uniformLocation( name ), vector.x(), vector.y(), vector.z(), vector.w() );
            break;
        }
        case QVariant::String:
        {
            if( name.contains( "texture" ) )
            {
                GluonGraphics::Texture* texture = GluonGraphics::Engine::instance()->texture( value.toString() );
                bindTexture( name, texture );
            }
            break;
        }
        case QVariant::Matrix4x4:
        {
            QMatrix4x4 mat = value.value<QMatrix4x4>();
            float glMatrix[16];
            MathUtils::qmatrixToGLMatrix( mat, glMatrix );
            glUniformMatrix4fv( uniformLocation( name ), 1, false, glMatrix );
            break;
        }
        default:
        {
            GluonCore::GluonObject* obj = GluonCore::GluonObjectFactory::instance()->wrappedObject( value );
            if( obj && name.contains( "texture" ) )
            {
                QVariant val = obj->property("texture");
                if( val.isValid() )
                {
                    if( GluonGraphics::Texture* texture = val.value<GluonGraphics::Texture*>() )
                    {
                        bindTexture( name, texture );
                    }
                    else
                    {
                        debug( QString("The object contained in the texture property on object %1 was not valid").arg( obj->fullyQualifiedName() ) );
                    }
                }
                else
                {
                    debug( QString("Texture was not a valid property on %1").arg( obj->fullyQualifiedName() ) );
                }
            }
            break;
        }
    }
}

void
MaterialInstance::bindTexture( const QString& name, Texture* tex )
{
    if( !tex )
        return;

    bindTexture(name, tex->glTexture());
}

void MaterialInstance::bindTexture( const QString& name, int tex )
{
    QString uniName = name;
    int id = uniName.remove( "texture" ).toInt();

    glActiveTexture( GL_TEXTURE0 + id );
    glBindTexture( GL_TEXTURE_2D, tex );
    glUniform1i( uniformLocation( name ), id );
}

#include "materialinstance.moc"
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if(!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
    /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
   /// For all but the first task,
   /// the input path must be changed if
   /// the output path argument -o was given, because the input
   /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }
  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    createScopeTaskAndAddToTaskList();
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    if (nevents > 0) {
      fUnpacker.setParams(fOptions.getInputFile(), nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams(fOptions.getInputFile());
    }
    unpackFile();
  }
  else if( inputFileType == JPetOptions::kZip){
    INFO( std::string("Unzipping file before unpacking") );
    unzipFile();
  }
  return true;
}

void JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
  }
  fTasks.push_front(module);
}

void JPetTaskExecutor::unpackFile()
{
  if (fOptions.getInputFileType() == JPetOptions::kHld) {
    fUnpacker.exec();
  } else {
    WARNING("Input file is not hld and unpacker was supposed to be called!");
  }
}

void JPetTaskExecutor::unzipFile()
{
  if( (fOptions.getInputFileType() == JPetOptions::kZip) ) {
    std::cout<<"This should unzip"<<std::endl;
  }
  else {
    WARNING("Input file is not zip and cannot be unzipped");
  }
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<commit_msg>Added error message when undefined file type is found<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include <stdlib.h>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if(!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
    /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
   /// For all but the first task,
   /// the input path must be changed if
   /// the output path argument -o was given, because the input
   /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }

  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    createScopeTaskAndAddToTaskList();
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    if (nevents > 0) {
      fUnpacker.setParams(fOptions.getInputFile(), nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams(fOptions.getInputFile());
    }
    unpackFile();
  }
  else if( inputFileType == JPetOptions::kZip){
    INFO( std::string("Unzipping file before unpacking") );
    unzipFile();

  }

  if(fOptions.getInputFileType() == JPetOptions::kUndefinedFileType)
    ERROR( Form("Unknown file type provided for file: %s", fOptions.getInputFile()) );

  return true;
}

void JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
  }
  fTasks.push_front(module);
}

void JPetTaskExecutor::unpackFile()
{
  if (fOptions.getInputFileType() == JPetOptions::kHld) {
    fUnpacker.exec();
  } else {
    WARNING("Input file is not hld and unpacker was supposed to be called!");
  }
}

void JPetTaskExecutor::unzipFile()
{

  if( (fOptions.getInputFileType() == JPetOptions::kZip) ) {
    system(Form("gzip -d %s", fOptions.getInputFile() ) );

  }
  else {
    WARNING("Input file is not zip and cannot be unzipped");
  }
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<|endoftext|>