<commit_before>//===-- sanitizer_linux.cc ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries and implements linux-specific functions from
// sanitizer_libc.h.
//===----------------------------------------------------------------------===//
#ifdef __linux__

#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"

#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

namespace __sanitizer {

// --------------- sanitizer_libc.h
void *internal_mmap(void *addr, uptr length, int prot, int flags,
                    int fd, u64 offset) {
#if __WORDSIZE == 64
  return (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset);
#else
  return (void *)syscall(__NR_mmap2, addr, length, prot, flags, fd, offset);
#endif
}

int internal_munmap(void *addr, uptr length) {
  return syscall(__NR_munmap, addr, length);
}

int internal_close(fd_t fd) {
  return syscall(__NR_close, fd);
}

fd_t internal_open(const char *filename, bool write) {
  return syscall(__NR_open, filename,
      write ? O_WRONLY | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
}

uptr internal_read(fd_t fd, void *buf, uptr count) {
  sptr res;
  HANDLE_EINTR(res, (sptr)syscall(__NR_read, fd, buf, count));
  return res;
}

uptr internal_write(fd_t fd, const void *buf, uptr count) {
  sptr res;
  HANDLE_EINTR(res, (sptr)syscall(__NR_write, fd, buf, count));
  return res;
}

uptr internal_filesize(fd_t fd) {
#if __WORDSIZE == 64
  struct stat st;
  if (syscall(__NR_fstat, fd, &st))
    return -1;
#else
  struct stat64 st;
  if (syscall(__NR_fstat64, fd, &st))
    return -1;
#endif
  return (uptr)st.st_size;
}

int internal_dup2(int oldfd, int newfd) {
  return syscall(__NR_dup2, oldfd, newfd);
}

uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
  return (uptr)syscall(__NR_readlink, path, buf, bufsize);
}

int internal_sched_yield() {
  return syscall(__NR_sched_yield);
}

// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
#if __WORDSIZE == 64
  struct stat st;
  if (syscall(__NR_stat, filename, &st))
    return false;
#else
  struct stat64 st;
  if (syscall(__NR_stat64, filename, &st))
    return false;
#endif
  // Sanity check: filename is a regular file.
  return S_ISREG(st.st_mode);
}

uptr GetTid() {
  return syscall(__NR_gettid);
}

void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
                                uptr *stack_bottom) {
  static const uptr kMaxThreadStackSize = 256 * (1 << 20);  // 256M
  CHECK(stack_top);
  CHECK(stack_bottom);
  if (at_initialization) {
    // This is the main thread. Libpthread may not be initialized yet.
    struct rlimit rl;
    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);

    // Find the mapping that contains a stack variable.
    MemoryMappingLayout proc_maps;
    uptr start, end, offset;
    uptr prev_end = 0;
    while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
      if ((uptr)&rl < end)
        break;
      prev_end = end;
    }
    CHECK((uptr)&rl >= start && (uptr)&rl < end);

    // Get stacksize from rlimit, but clip it so that it does not overlap
    // with other mappings.
    uptr stacksize = rl.rlim_cur;
    if (stacksize > end - prev_end)
      stacksize = end - prev_end;
    // When running with unlimited stack size, we still want to set some limit.
    // The unlimited stack size is caused by 'ulimit -s unlimited'.
    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
    if (stacksize > kMaxThreadStackSize)
      stacksize = kMaxThreadStackSize;
    *stack_top = end;
    *stack_bottom = end - stacksize;
    return;
  }
  pthread_attr_t attr;
  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
  uptr stacksize = 0;
  void *stackaddr = 0;
  pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
  pthread_attr_destroy(&attr);

  *stack_top = (uptr)stackaddr + stacksize;
  *stack_bottom = (uptr)stackaddr;
  CHECK(stacksize < kMaxThreadStackSize);  // Sanity check.
}

// Like getenv, but reads env directly from /proc and does not use libc.
// This function should be called first inside __asan_init.
const char *GetEnv(const char *name) {
  static char *environ;
  static uptr len;
  static bool inited;
  if (!inited) {
    inited = true;
    uptr environ_size;
    len = ReadFileToBuffer("/proc/self/environ",
                           &environ, &environ_size, 1 << 26);
  }
  if (!environ || len == 0) return 0;
  uptr namelen = internal_strlen(name);
  const char *p = environ;
  while (*p != '\0') {  // will happen at the \0\0 that terminates the buffer
    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
    const char* endp =
        (char*)internal_memchr(p, '\0', len - (p - environ));
    if (endp == 0)  // this entry isn't NUL terminated
      return 0;
    else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=')  // Match.
      return p + namelen + 1;  // point after =
    p = endp + 1;
  }
  return 0;  // Not found.
}

void ReExec() {
  static const int kMaxArgv = 100;
  InternalScopedBuffer<char*> argv(kMaxArgv + 1);
  static char *buff;
  uptr buff_size = 0;
  ReadFileToBuffer("/proc/self/cmdline", &buff, &buff_size, 1024 * 1024);
  argv[0] = buff;
  int argc, i;
  for (argc = 1, i = 1; ; i++) {
    if (buff[i] == 0) {
      if (buff[i+1] == 0) break;
      argv[argc] = &buff[i+1];
      CHECK_LE(argc, kMaxArgv);  // FIXME: make this more flexible.
      argc++;
    }
  }
  argv[argc] = 0;
  execv(argv[0], argv.data());
}

// ----------------- sanitizer_procmaps.h
MemoryMappingLayout::MemoryMappingLayout() {
  proc_self_maps_buff_len_ =
      ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
                       &proc_self_maps_buff_mmaped_size_, 1 << 26);
  CHECK_GT(proc_self_maps_buff_len_, 0);
  // internal_write(2, proc_self_maps_buff_, proc_self_maps_buff_len_);
  Reset();
}

MemoryMappingLayout::~MemoryMappingLayout() {
  UnmapOrDie(proc_self_maps_buff_, proc_self_maps_buff_mmaped_size_);
}

void MemoryMappingLayout::Reset() {
  current_ = proc_self_maps_buff_;
}

// Parse a hex value in str and update str.
static uptr ParseHex(char **str) {
  uptr x = 0;
  char *s;
  for (s = *str; ; s++) {
    char c = *s;
    uptr v = 0;
    if (c >= '0' && c <= '9')
      v = c - '0';
    else if (c >= 'a' && c <= 'f')
      v = c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      v = c - 'A' + 10;
    else
      break;
    x = x * 16 + v;
  }
  *str = s;
  return x;
}

static bool IsOnOf(char c, char c1, char c2) {
  return c == c1 || c == c2;
}

static bool IsDecimal(char c) {
  return c >= '0' && c <= '9';
}

bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
                               char filename[], uptr filename_size) {
  char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
  if (current_ >= last) return false;
  uptr dummy;
  if (!start) start = &dummy;
  if (!end) end = &dummy;
  if (!offset) offset = &dummy;
  char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
  if (next_line == 0)
    next_line = last;
  // Example: 08048000-08056000 r-xp 00000000 03:0c 64593   /foo/bar
  *start = ParseHex(&current_);
  CHECK_EQ(*current_++, '-');
  *end = ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  CHECK(IsOnOf(*current_++, '-', 'r'));
  CHECK(IsOnOf(*current_++, '-', 'w'));
  CHECK(IsOnOf(*current_++, '-', 'x'));
  CHECK(IsOnOf(*current_++, 's', 'p'));
  CHECK_EQ(*current_++, ' ');
  *offset = ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  ParseHex(&current_);
  CHECK_EQ(*current_++, ':');
  ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  while (IsDecimal(*current_))
    current_++;
  CHECK_EQ(*current_++, ' ');
  // Skip spaces.
  while (current_ < next_line && *current_ == ' ')
    current_++;
  // Fill in the filename.
  uptr i = 0;
  while (current_ < next_line) {
    if (filename && i < filename_size - 1)
      filename[i++] = *current_;
    current_++;
  }
  if (filename && i < filename_size)
    filename[i] = 0;
  current_ = next_line + 1;
  return true;
}

// Gets the object name and the offset by walking MemoryMappingLayout.
bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr, uptr *offset,
                                                 char filename[],
                                                 uptr filename_size) {
  return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
}

}  // namespace __sanitizer

#endif  // __linux__
<commit_msg>[asan] use #if defined __x86_64__ instead of #if __WORDSIZE == 64 in sanitizer_linux.cc<commit_after>//===-- sanitizer_linux.cc ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries and implements linux-specific functions from
// sanitizer_libc.h.
//===----------------------------------------------------------------------===//
#ifdef __linux__

#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"

#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

namespace __sanitizer {

// --------------- sanitizer_libc.h
void *internal_mmap(void *addr, uptr length, int prot, int flags,
                    int fd, u64 offset) {
#if defined __x86_64__
  return (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset);
#else
  return (void *)syscall(__NR_mmap2, addr, length, prot, flags, fd, offset);
#endif
}

int internal_munmap(void *addr, uptr length) {
  return syscall(__NR_munmap, addr, length);
}

int internal_close(fd_t fd) {
  return syscall(__NR_close, fd);
}

fd_t internal_open(const char *filename, bool write) {
  return syscall(__NR_open, filename,
      write ? O_WRONLY | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
}

uptr internal_read(fd_t fd, void *buf, uptr count) {
  sptr res;
  HANDLE_EINTR(res, (sptr)syscall(__NR_read, fd, buf, count));
  return res;
}

uptr internal_write(fd_t fd, const void *buf, uptr count) {
  sptr res;
  HANDLE_EINTR(res, (sptr)syscall(__NR_write, fd, buf, count));
  return res;
}

uptr internal_filesize(fd_t fd) {
#if defined __x86_64__
  struct stat st;
  if (syscall(__NR_fstat, fd, &st))
    return -1;
#else
  struct stat64 st;
  if (syscall(__NR_fstat64, fd, &st))
    return -1;
#endif
  return (uptr)st.st_size;
}

int internal_dup2(int oldfd, int newfd) {
  return syscall(__NR_dup2, oldfd, newfd);
}

uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
  return (uptr)syscall(__NR_readlink, path, buf, bufsize);
}

int internal_sched_yield() {
  return syscall(__NR_sched_yield);
}

// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
#if defined __x86_64__
  struct stat st;
  if (syscall(__NR_stat, filename, &st))
    return false;
#else
  struct stat64 st;
  if (syscall(__NR_stat64, filename, &st))
    return false;
#endif
  // Sanity check: filename is a regular file.
  return S_ISREG(st.st_mode);
}

uptr GetTid() {
  return syscall(__NR_gettid);
}

void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
                                uptr *stack_bottom) {
  static const uptr kMaxThreadStackSize = 256 * (1 << 20);  // 256M
  CHECK(stack_top);
  CHECK(stack_bottom);
  if (at_initialization) {
    // This is the main thread. Libpthread may not be initialized yet.
    struct rlimit rl;
    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);

    // Find the mapping that contains a stack variable.
    MemoryMappingLayout proc_maps;
    uptr start, end, offset;
    uptr prev_end = 0;
    while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
      if ((uptr)&rl < end)
        break;
      prev_end = end;
    }
    CHECK((uptr)&rl >= start && (uptr)&rl < end);

    // Get stacksize from rlimit, but clip it so that it does not overlap
    // with other mappings.
    uptr stacksize = rl.rlim_cur;
    if (stacksize > end - prev_end)
      stacksize = end - prev_end;
    // When running with unlimited stack size, we still want to set some limit.
    // The unlimited stack size is caused by 'ulimit -s unlimited'.
    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
    if (stacksize > kMaxThreadStackSize)
      stacksize = kMaxThreadStackSize;
    *stack_top = end;
    *stack_bottom = end - stacksize;
    return;
  }
  pthread_attr_t attr;
  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
  uptr stacksize = 0;
  void *stackaddr = 0;
  pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
  pthread_attr_destroy(&attr);

  *stack_top = (uptr)stackaddr + stacksize;
  *stack_bottom = (uptr)stackaddr;
  CHECK(stacksize < kMaxThreadStackSize);  // Sanity check.
}

// Like getenv, but reads env directly from /proc and does not use libc.
// This function should be called first inside __asan_init.
const char *GetEnv(const char *name) {
  static char *environ;
  static uptr len;
  static bool inited;
  if (!inited) {
    inited = true;
    uptr environ_size;
    len = ReadFileToBuffer("/proc/self/environ",
                           &environ, &environ_size, 1 << 26);
  }
  if (!environ || len == 0) return 0;
  uptr namelen = internal_strlen(name);
  const char *p = environ;
  while (*p != '\0') {  // will happen at the \0\0 that terminates the buffer
    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
    const char* endp =
        (char*)internal_memchr(p, '\0', len - (p - environ));
    if (endp == 0)  // this entry isn't NUL terminated
      return 0;
    else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=')  // Match.
      return p + namelen + 1;  // point after =
    p = endp + 1;
  }
  return 0;  // Not found.
}

void ReExec() {
  static const int kMaxArgv = 100;
  InternalScopedBuffer<char*> argv(kMaxArgv + 1);
  static char *buff;
  uptr buff_size = 0;
  ReadFileToBuffer("/proc/self/cmdline", &buff, &buff_size, 1024 * 1024);
  argv[0] = buff;
  int argc, i;
  for (argc = 1, i = 1; ; i++) {
    if (buff[i] == 0) {
      if (buff[i+1] == 0) break;
      argv[argc] = &buff[i+1];
      CHECK_LE(argc, kMaxArgv);  // FIXME: make this more flexible.
      argc++;
    }
  }
  argv[argc] = 0;
  execv(argv[0], argv.data());
}

// ----------------- sanitizer_procmaps.h
MemoryMappingLayout::MemoryMappingLayout() {
  proc_self_maps_buff_len_ =
      ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
                       &proc_self_maps_buff_mmaped_size_, 1 << 26);
  CHECK_GT(proc_self_maps_buff_len_, 0);
  // internal_write(2, proc_self_maps_buff_, proc_self_maps_buff_len_);
  Reset();
}

MemoryMappingLayout::~MemoryMappingLayout() {
  UnmapOrDie(proc_self_maps_buff_, proc_self_maps_buff_mmaped_size_);
}

void MemoryMappingLayout::Reset() {
  current_ = proc_self_maps_buff_;
}

// Parse a hex value in str and update str.
static uptr ParseHex(char **str) {
  uptr x = 0;
  char *s;
  for (s = *str; ; s++) {
    char c = *s;
    uptr v = 0;
    if (c >= '0' && c <= '9')
      v = c - '0';
    else if (c >= 'a' && c <= 'f')
      v = c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      v = c - 'A' + 10;
    else
      break;
    x = x * 16 + v;
  }
  *str = s;
  return x;
}

static bool IsOnOf(char c, char c1, char c2) {
  return c == c1 || c == c2;
}

static bool IsDecimal(char c) {
  return c >= '0' && c <= '9';
}

bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
                               char filename[], uptr filename_size) {
  char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
  if (current_ >= last) return false;
  uptr dummy;
  if (!start) start = &dummy;
  if (!end) end = &dummy;
  if (!offset) offset = &dummy;
  char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
  if (next_line == 0)
    next_line = last;
  // Example: 08048000-08056000 r-xp 00000000 03:0c 64593   /foo/bar
  *start = ParseHex(&current_);
  CHECK_EQ(*current_++, '-');
  *end = ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  CHECK(IsOnOf(*current_++, '-', 'r'));
  CHECK(IsOnOf(*current_++, '-', 'w'));
  CHECK(IsOnOf(*current_++, '-', 'x'));
  CHECK(IsOnOf(*current_++, 's', 'p'));
  CHECK_EQ(*current_++, ' ');
  *offset = ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  ParseHex(&current_);
  CHECK_EQ(*current_++, ':');
  ParseHex(&current_);
  CHECK_EQ(*current_++, ' ');
  while (IsDecimal(*current_))
    current_++;
  CHECK_EQ(*current_++, ' ');
  // Skip spaces.
  while (current_ < next_line && *current_ == ' ')
    current_++;
  // Fill in the filename.
  uptr i = 0;
  while (current_ < next_line) {
    if (filename && i < filename_size - 1)
      filename[i++] = *current_;
    current_++;
  }
  if (filename && i < filename_size)
    filename[i] = 0;
  current_ = next_line + 1;
  return true;
}

// Gets the object name and the offset by walking MemoryMappingLayout.
bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr, uptr *offset,
                                                 char filename[],
                                                 uptr filename_size) {
  return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
}

}  // namespace __sanitizer

#endif  // __linux__
<|endoftext|>


<commit_before>#include "chimera/node/NodeParticleEmitter.hpp"
#include "chimera/core/Exception.hpp"
#include "chimera/node/NodeCamera.hpp"
#include "chimera/node/VisitorInterface.hpp"
#include <algorithm>

namespace Chimera {
NodeParticleEmitter::NodeParticleEmitter(Node* _parent, std::string _name, int _max)
    : Node(_parent, Kind::PARTICLE_SYSTEM, _name) {
    // MaxParticles = _max;
    LastUsedParticle = 0;
    material = new Material();
}

NodeParticleEmitter::~NodeParticleEmitter() {}

void NodeParticleEmitter::init() {

    pTransform->init(glm::vec3());

    material->init();

    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    g_particule_position_size_data = new GLfloat[MaxParticles * 4];
    g_particule_color_data = new GLubyte[MaxParticles * 4];

    // The VBO containing the 4 vertices of the particles.
    // Thanks to instancing, they will be shared by all particles.
    static const GLfloat g_vertex_buffer_data[] = {
        -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f,
    };

    glGenBuffers(1, &billboard_vertex_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    // The VBO containing the positions and sizes of the particles
    glGenBuffers(1, &particles_position_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);

    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

    // The VBO containing the colors of the particles
    glGenBuffers(1, &particles_color_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);

    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLubyte), NULL, GL_STREAM_DRAW);

    timer.start();
}

void NodeParticleEmitter::loadTexDiffuse(const std::string& _nome, const std::string& _arquivo) {
    material->addTexture(new TextureImg(SHADE_TEXTURE_DIFFUSE, _arquivo));
}

void NodeParticleEmitter::accept(VisitorInterface* v) { v->visit(this); }

void NodeParticleEmitter::SortParticles() { std::sort(&ParticlesContainer[0], &ParticlesContainer[MaxParticles]); }

int NodeParticleEmitter::recycleParticleLife(const glm::vec3& _camPosition) {

    double delta = timer.deltaTimeSecounds();

    // Generate 10 new particule each millisecond,
    // but limit this to 16 ms (60 fps), or if you have 1 long frame (1sec),
    // newparticles will be huge and the next frame even longer.
    int newparticles = (int)(delta * 10000.0);

    if (newparticles > (int)(0.016f * 10000.0))
        newparticles = (int)(0.016f * 10000.0);

    for (int i = 0; i < newparticles; i++) {

        int particleIndex = FindUnusedParticle();
        ParticlesContainer[particleIndex].reset();

        float spread = 1.5f;
        glm::vec3 maindir = glm::vec3(0.0f, 0.0f, 10.0f);

        ParticlesContainer[particleIndex].create(maindir, spread);
    }

    // Simulate all particles
    int ParticlesCount = 0;

    for (int i = 0; i < MaxParticles; i++) {

        Particle& p = ParticlesContainer[i]; // shortcut

        if (p.isDead() == false) {

            p.decrease(delta, ParticlesCount, g_particule_position_size_data, g_particule_color_data, _camPosition);
            ParticlesCount++;
        }
    }

    SortParticles();

    // printf("%d \n",ParticlesCount);

    return ParticlesCount;
}

void NodeParticleEmitter::render(Shader* _pShader) {
    //// We will need the camera's position in order to sort the particles
    //// w.r.t the camera's distance.
    //// There should be a getCameraPosition() function in common/controls.cpp,
    //// but this works too.
    // glm::vec3 CameraPosition(glm::inverse(_view)[3]);

    int ParticlesCount = recycleParticleLife(CameraPosition);

    // Update the buffers that OpenGL uses for rendering.
    // There are much more sophisticated means to stream data from the CPU to the GPU,
    // but this is outside the scope of this tutorial.
    // http://www.opengl.org/wiki/Buffer_Object_Streaming
    glBindVertexArray(VertexArrayID); // coloquei aqui porque acho que tenho que ligar antes

    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLfloat), NULL,
                 GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming
                                  // perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, ParticlesCount * sizeof(GLfloat) * 4, g_particule_position_size_data);

    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLubyte), NULL,
                 GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming
                                  // perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, ParticlesCount * sizeof(GLubyte) * 4, g_particule_color_data);

    // salva flags de bit
    glPushAttrib(GL_ENABLE_BIT);

    // preserva a cor original
    glPushAttrib(GL_CURRENT_BIT);

    // Enable depth test
    glEnable(GL_DEPTH_TEST);

    // Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Bind our texture
    material->apply(_pShader);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
    glVertexAttribPointer(0,        // attribute. No particular reason for 0, but must match the
                                    // layout in the shader.
                          3,        // size
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void*)0  // array buffer offset
    );

    // 2nd attribute buffer : positions of particles' centers
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
    glVertexAttribPointer(1,        // attribute. No particular reason for 1, but must match the
                                    // layout in the shader.
                          4,        // size : x + y + z + size => 4
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void*)0  // array buffer offset
    );

    // 3rd attribute buffer : particles' colors
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
    glVertexAttribPointer(2,                // attribute. No particular reason for 1, but must match the layout in the
                                            // shader.
                          4,                // size : r + g + b + a => 4
                          GL_UNSIGNED_BYTE, // type
                          GL_TRUE,          // normalized?    *** YES, this means that the unsigned char[4] will be
                                            // accessible with a vec4 (floats) in the ShadersManager ***
                          0,                // stride
                          (void*)0          // array buffer offset
    );

    // These functions are specific to glDrawArrays*Instanced*.
    // The first parameter is the attribute buffer we're talking about.
    // The second parameter is the "rate at which generic vertex attributes advance when
    // rendering multiple instances"
    // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml
    glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
    glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
    glVertexAttribDivisor(2, 1); // color : one per quad -> 1

    // Draw the particules !
    // This draws many times a small triangle_strip (which looks like a quad).
    // This is equivalent to :
    // for(i in ParticlesCount) : glDrawArrays(GL_TRIANGLE_STRIP, 0, 4),
    // but faster.
    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    // retorna paleta
    glPopAttrib();

    // retorna paleta
    glPopAttrib();
}

int NodeParticleEmitter::FindUnusedParticle() {

    for (int i = LastUsedParticle; i < MaxParticles; i++) {
        if (ParticlesContainer[i].isDead() == true) {
            LastUsedParticle = i;
            return i;
        }
    }

    for (int i = 0; i < LastUsedParticle; i++) {
        if (ParticlesContainer[i].isDead() == true) {
            LastUsedParticle = i;
            return i;
        }
    }

    return 0; // All particles are taken, override the first one
}
} // namespace Chimera
<commit_msg>todo adicionado<commit_after>#include "chimera/node/NodeParticleEmitter.hpp"
#include "chimera/core/Exception.hpp"
#include "chimera/node/NodeCamera.hpp"
#include "chimera/node/VisitorInterface.hpp"
#include <algorithm>

namespace Chimera {
NodeParticleEmitter::NodeParticleEmitter(Node* _parent, std::string _name, int _max) : Node(_parent, Kind::PARTICLE_SYSTEM, _name) {
    // MaxParticles = _max;
    LastUsedParticle = 0;
    material = new Material();
}

NodeParticleEmitter::~NodeParticleEmitter() {}

void NodeParticleEmitter::init() {

    pTransform->init(glm::vec3());

    material->init();

    // TODO: usar classes novas de buffers
    // VAO
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    g_particule_position_size_data = new GLfloat[MaxParticles * 4];
    g_particule_color_data = new GLubyte[MaxParticles * 4];

    // The VBO containing the 4 vertices of the particles.
    // Thanks to instancing, they will be shared by all particles.
    static const GLfloat g_vertex_buffer_data[] = {
        -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f,
    };

    // VBO square vertex
    glGenBuffers(1, &billboard_vertex_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    // The VBO containing the positions and sizes of the particles
    glGenBuffers(1, &particles_position_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);

    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

    // The VBO containing the colors of the particles
    glGenBuffers(1, &particles_color_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);

    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLubyte), NULL, GL_STREAM_DRAW);

    timer.start();
}

void NodeParticleEmitter::loadTexDiffuse(const std::string& _nome, const std::string& _arquivo) {
    material->addTexture(new TextureImg(SHADE_TEXTURE_DIFFUSE, _arquivo));
}

void NodeParticleEmitter::accept(VisitorInterface* v) { v->visit(this); }

void NodeParticleEmitter::SortParticles() { std::sort(&ParticlesContainer[0], &ParticlesContainer[MaxParticles]); }

int NodeParticleEmitter::recycleParticleLife(const glm::vec3& _camPosition) {

    double delta = timer.deltaTimeSecounds();

    // Generate 10 new particule each millisecond,
    // but limit this to 16 ms (60 fps), or if you have 1 long frame (1sec),
    // newparticles will be huge and the next frame even longer.
    int newparticles = (int)(delta * 10000.0);

    if (newparticles > (int)(0.016f * 10000.0))
        newparticles = (int)(0.016f * 10000.0);

    for (int i = 0; i < newparticles; i++) {

        int particleIndex = FindUnusedParticle();
        ParticlesContainer[particleIndex].reset();

        float spread = 1.5f;
        glm::vec3 maindir = glm::vec3(0.0f, 0.0f, 10.0f);

        ParticlesContainer[particleIndex].create(maindir, spread);
    }

    // Simulate all particles
    int ParticlesCount = 0;

    for (int i = 0; i < MaxParticles; i++) {

        Particle& p = ParticlesContainer[i]; // shortcut

        if (p.isDead() == false) {

            p.decrease(delta, ParticlesCount, g_particule_position_size_data, g_particule_color_data, _camPosition);
            ParticlesCount++;
        }
    }

    SortParticles();

    // printf("%d \n",ParticlesCount);

    return ParticlesCount;
}

void NodeParticleEmitter::render(Shader* _pShader) {
    //// We will need the camera's position in order to sort the particles
    //// w.r.t the camera's distance.
    //// There should be a getCameraPosition() function in common/controls.cpp,
    //// but this works too.
    // glm::vec3 CameraPosition(glm::inverse(_view)[3]);

    int ParticlesCount = recycleParticleLife(CameraPosition);

    // Update the buffers that OpenGL uses for rendering.
    // There are much more sophisticated means to stream data from the CPU to the GPU,
    // but this is outside the scope of this tutorial.
    // http://www.opengl.org/wiki/Buffer_Object_Streaming
    glBindVertexArray(VertexArrayID); // coloquei aqui porque acho que tenho que ligar antes

    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLfloat), NULL,
                 GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming
                                  // perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, ParticlesCount * sizeof(GLfloat) * 4, g_particule_position_size_data);

    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
    glBufferData(GL_ARRAY_BUFFER, MaxParticles * 4 * sizeof(GLubyte), NULL,
                 GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming
                                  // perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, ParticlesCount * sizeof(GLubyte) * 4, g_particule_color_data);

    // salva flags de bit
    glPushAttrib(GL_ENABLE_BIT);

    // preserva a cor original
    glPushAttrib(GL_CURRENT_BIT);

    // Enable depth test
    glEnable(GL_DEPTH_TEST);

    // Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Bind our texture
    material->apply(_pShader);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
    glVertexAttribPointer(0,        // attribute. No particular reason for 0, but must match the
                                    // layout in the shader.
                          3,        // size
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void*)0  // array buffer offset
    );

    // 2nd attribute buffer : positions of particles' centers
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
    glVertexAttribPointer(1,        // attribute. No particular reason for 1, but must match the
                                    // layout in the shader.
                          4,        // size : x + y + z + size => 4
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void*)0  // array buffer offset
    );

    // 3rd attribute buffer : particles' colors
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
    glVertexAttribPointer(2,                // attribute. No particular reason for 1, but must match the layout in the
                                            // shader.
                          4,                // size : r + g + b + a => 4
                          GL_UNSIGNED_BYTE, // type
                          GL_TRUE,          // normalized?    *** YES, this means that the unsigned char[4] will be
                                            // accessible with a vec4 (floats) in the ShadersManager ***
                          0,                // stride
                          (void*)0          // array buffer offset
    );

    // These functions are specific to glDrawArrays*Instanced*.
    // The first parameter is the attribute buffer we're talking about.
    // The second parameter is the "rate at which generic vertex attributes advance when
    // rendering multiple instances"
    // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml
    glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
    glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
    glVertexAttribDivisor(2, 1); // color : one per quad -> 1

    // Draw the particules !
    // This draws many times a small triangle_strip (which looks like a quad).
    // This is equivalent to :
    // for(i in ParticlesCount) : glDrawArrays(GL_TRIANGLE_STRIP, 0, 4),
    // but faster.
    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    // retorna paleta
    glPopAttrib();

    // retorna paleta
    glPopAttrib();
}

int NodeParticleEmitter::FindUnusedParticle() {

    for (int i = LastUsedParticle; i < MaxParticles; i++) {
        if (ParticlesContainer[i].isDead() == true) {
            LastUsedParticle = i;
            return i;
        }
    }

    for (int i = 0; i < LastUsedParticle; i++) {
        if (ParticlesContainer[i].isDead() == true) {
            LastUsedParticle = i;
            return i;
        }
    }

    return 0; // All particles are taken, override the first one
}
} // namespace Chimera
<|endoftext|>


<commit_before>#include<bits/stdc++.h>
using namespace std;

#define endl "\n"

long long a[100001];
int n;

int findmax() {
	if(n==1)
		return 1;
	int j = 0;
	int mx = 1;
	for(int i=0;i<n-1;) {
		j = i+1;
		while((j<n) && (a[j-1]+1==a[j])) {
			j++;
		}
		if((j-i) > mx) {
			mx = j-i;
		}
		i = j;
	}
	return mx;
}

int main() {
	ios::sync_with_stdio(false);
	int m;
	long long k,l;
	cin >> n >> m;
	for(int i=0;i<n;i++)
		cin >> a[i];
	cout << findmax() << endl;
	while(m--) {
		cin >> k >> l;
		a[k-1]=l;
		/*for(int i=0;i<n;i++)
			cout << a[i] << " ";
		cout << endl;*/
		cout << findmax() << endl;
	}
	return 0;
}<commit_msg>Removed SUBSGM from Codechef<commit_after><|endoftext|>


<commit_before>/**
 * Copyright 2013 Truphone
 */
#include "TapCommand.h"

#include <bb/cascades/Application>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/TouchEvent>
#include <bb/cascades/VisualNode>

#include "Utils.h"
#include "Connection.h"

using truphone::test::cascades::Utils;
using bb::cascades::Application;
using bb::cascades::VisualNode;
using bb::cascades::TouchEvent;
using bb::cascades::TouchType;

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString TapCommand::CMD_NAME = "tap";

    TapCommand::TapCommand(Connection * const socket,
                           QObject * parent)
        : Command(parent),
          client(socket)
    {
    }

    TapCommand::~TapCommand()
    {
    }

    bool TapCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if ((not arguments->isEmpty()) and (arguments->size() >= 2))
        {
            const QString typeName = arguments->first();
            arguments->removeFirst();
            QObject * const obj = Utils::findObject(arguments->first());
            arguments->removeFirst();
            if (obj)
            {
                TouchType::Type type = TouchType::Move;
                if (typeName == "up")
                {
                    type = TouchType::Up;
                }
                else if (typeName == "down")
                {
                    type = TouchType::Down;
                }
                else if (typeName == "move")
                {
                    type = TouchType::Move;
                }
                else if (typeName == "cancel")
                {
                    type = TouchType::Cancel;
                }
                else
                {
                    QString data(typeName);
                    data += " is not a known event type for touch events, " \
                            "assuming 'move'\r\n";
                    this->client->write(data.trimmed().toUtf8());
                }
                VisualNode * const visual_node = qobject_cast<VisualNode*>(obj);
                if (visual_node)
                {
                    TouchEvent * const te = new TouchEvent(type,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           visual_node);
                    const bool invoked = QMetaObject::invokeMethod(
                                obj,
                                "touch",
                                Q_ARG(bb::cascades::TouchEvent*, te));
                    if (invoked)
                    {
                        bb::cascades::Application::processEvents();
                        ret = true;
                    }
                    else
                    {
                        this->client->write("ERROR: Failed to invoke function\r\n");
                    }
                }
                else
                {
                    this->client->write("ERROR: The object in question isn't a visual element\r\n");
                }
            }
            else
            {
                this->client->write("ERROR: Unknown object\r\n");
            }
        }
        else
        {
            this->client->write("ERROR: Not enough arguments, " \
                                "touch <up/down/move/cancel> <object>\r\n");
        }
        return ret;
    }
    void TapCommand::showHelp()
    {
        this->client->write("> tap <up/down/move/cancel> <object>\r\n");
        this->client->write("Simulate a touch event on a UI object and " \
                            "trigger the onTouched method.\r\n");
        this->client->write("You can specify the type of touch as up/down/move/cancel " \
                            "which will be\r\n");
        this->client->write(" accessibleto the event handler\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<commit_msg>Event loop flush prior to tap.<commit_after>/**
 * Copyright 2013 Truphone
 */
#include "TapCommand.h"

#include <bb/cascades/Application>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/TouchEvent>
#include <bb/cascades/VisualNode>

#include "Utils.h"
#include "Connection.h"

using truphone::test::cascades::Utils;
using bb::cascades::Application;
using bb::cascades::VisualNode;
using bb::cascades::TouchEvent;
using bb::cascades::TouchType;

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString TapCommand::CMD_NAME = "tap";

    TapCommand::TapCommand(Connection * const socket,
                           QObject * parent)
        : Command(parent),
          client(socket)
    {
    }

    TapCommand::~TapCommand()
    {
    }

    bool TapCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if ((not arguments->isEmpty()) and (arguments->size() >= 2))
        {
            const QString typeName = arguments->first();
            arguments->removeFirst();
            QObject * const obj = Utils::findObject(arguments->first());
            arguments->removeFirst();
            if (obj)
            {
                TouchType::Type type = TouchType::Move;
                if (typeName == "up")
                {
                    type = TouchType::Up;
                }
                else if (typeName == "down")
                {
                    type = TouchType::Down;
                }
                else if (typeName == "move")
                {
                    type = TouchType::Move;
                }
                else if (typeName == "cancel")
                {
                    type = TouchType::Cancel;
                }
                else
                {
                    QString data(typeName);
                    data += " is not a known event type for touch events, " \
                            "assuming 'move'\r\n";
                    this->client->write(data.trimmed().toUtf8());
                }
                VisualNode * const visual_node = qobject_cast<VisualNode*>(obj);
                if (visual_node)
                {
                    TouchEvent * const te = new TouchEvent(type,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           0.0,
                                                           visual_node);
                    bb::cascades::Application::processEvents();
                    const bool invoked = QMetaObject::invokeMethod(
                                obj,
                                "touch",
                                Q_ARG(bb::cascades::TouchEvent*, te));
                    if (invoked)
                    {
                        bb::cascades::Application::processEvents();
                        ret = true;
                    }
                    else
                    {
                        this->client->write("ERROR: Failed to invoke function\r\n");
                    }
                }
                else
                {
                    this->client->write("ERROR: The object in question isn't a visual element\r\n");
                }
            }
            else
            {
                this->client->write("ERROR: Unknown object\r\n");
            }
        }
        else
        {
            this->client->write("ERROR: Not enough arguments, " \
                                "touch <up/down/move/cancel> <object>\r\n");
        }
        return ret;
    }
    void TapCommand::showHelp()
    {
        this->client->write("> tap <up/down/move/cancel> <object>\r\n");
        this->client->write("Simulate a touch event on a UI object and " \
                            "trigger the onTouched method.\r\n");
        this->client->write("You can specify the type of touch as up/down/move/cancel " \
                            "which will be\r\n");
        this->client->write(" accessibleto the event handler\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<|endoftext|>


<commit_before>#include "Core.h"

void coreInit()
{
    cli();

    //init adc peripheral
    setUpADC();

    //init uart
    uart.init();

    sei();
}<commit_msg>remove init<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

// Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/
//
#include "SkGradientShader.h"
static void test_grad(SkCanvas* canvas) {
    SkPoint pts[] = {
        { 478.544067f, -84.2041016f },
        { 602.455933f, 625.204102f },
    };
    SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED };
    SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f };
    SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::kClamp_TileMode);
    SkPaint p;
    p.setShader(s)->unref();
    canvas->drawPaint(p);
}

static SkCanvas* MakeCanvas(const SkIRect& bounds) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
    bm.allocPixels();
    bm.eraseColor(SK_ColorTRANSPARENT);

    SkCanvas* canvas = new SkCanvas(bm);
    canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
    return canvas;
}

#ifdef SK_DEBUG
static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) {
    *bm = canvas->getDevice()->accessBitmap(false);
}
#endif

static void compare_canvas(const SkCanvas* a, const SkCanvas* b) {
#ifdef SK_DEBUG
    SkBitmap bma, bmb;
    GetBitmap(a, &bma);
    GetBitmap(b, &bmb);

    SkASSERT(bma.width() == bmb.width());
    SkASSERT(bma.height() == bmb.height());

    bma.lockPixels();
    bmb.lockPixels();
    for (int y = 0; y < bma.height(); ++y) {
        const SkPMColor* rowa = bma.getAddr32(0, y);
        const SkPMColor* rowb = bmb.getAddr32(0, y);
        SkASSERT(!memcmp(rowa, rowb, bma.width() << 2));

        for (int x = 1; x < bma.width() - 1; ++x) {
            SkASSERT(0xFF000000 == rowa[x]);
            SkASSERT(0xFF000000 == rowb[x]);
        }
    }
#endif
}

static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPath path;
    path.addRect(r);
    canvas->drawPath(path, p);
}

static void test_maskFromPath(const SkPath& path) {
    SkIRect bounds;
    path.getBounds().roundOut(&bounds);

    SkPaint paint;
    paint.setAntiAlias(true);

    SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds));
    path_canvas->drawPath(path, paint);

    SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds));
    drawRectAsPath(rect_canvas, path.getBounds(), paint);

    compare_canvas(path_canvas, rect_canvas);
}

static void test_mask() {
    for (int i = 1; i <= 20; ++i) {
        const SkScalar dx = SK_Scalar1 / i;
        const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2));
        for (int n = 2; n < 20; ++n) {
            SkPath path;
            path.setFillType(SkPath::kEvenOdd_FillType);
            SkRect r = constr;
            while (r.fRight < SkIntToScalar(4)) {
                path.addRect(r);
                r.offset(dx, 0);
            }
            test_maskFromPath(path);
        }
    }
}

namespace skiagm {

/** Draw a 2px border around the target, then red behind the target;
    set the clip to match the target, then draw >> the target in blue.
*/

static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
    SkPaint borderPaint;
    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
    borderPaint.setAntiAlias(true);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
    backgroundPaint.setAntiAlias(true);
    SkPaint foregroundPaint;
    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
    foregroundPaint.setAntiAlias(true);

    canvas->save();
    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
    canvas->drawRect(target, borderPaint);
    target.inset(SkIntToScalar(2), SkIntToScalar(2));
    canvas->drawRect(target, backgroundPaint);
    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
    canvas->drawRect(target, foregroundPaint);
    canvas->restore();
}

static void draw_square (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_column (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_bar (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_rect_tests (SkCanvas* canvas) {
    draw_square(canvas, 10, 10);
    draw_column(canvas, 30, 10);
    draw_bar(canvas, 10, 30);
}

/**
   Test a set of clipping problems discovered while writing blitAntiRect,
   and test all the code paths through the clipping blitters.
   Each region should show as a blue center surrounded by a 2px green
   border, with no red.
*/

class AAClipGM : public GM {
public:
    AAClipGM() {

    }

protected:
    virtual SkString onShortName() {
        return SkString("aaclip");
    }

    virtual SkISize onISize() {
        return make_isize(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) {
        if (false) {
            test_grad(canvas); return;
        }
        if (false) { // avoid bit rot, suppress warning
            test_mask();
        }

        // Initial pixel-boundary-aligned draw
        draw_rect_tests(canvas);

        // Repeat 4x with .2, .4, .6, .8 px offsets
        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);
    }

    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }

private:
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new AAClipGM; }
static GMRegistry reg(MyFactory);

}
<commit_msg>add (disabled) test for big dashing<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

#include "SkDashPathEffect.h"
static void test_giant_dash(SkCanvas* canvas) {
    SkPaint paint;
    const SkScalar intervals[] = { SK_Scalar1, SK_Scalar1 };

    paint.setStrokeWidth(2);
    paint.setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();

    SkScalar big = 500 * 1000;

    canvas->drawLine(10, 10, big, 10, paint);
    canvas->drawLine(-big, 20, 500, 20, paint);
    canvas->drawLine(-big, 30, big, 30, paint);

    const SkScalar intervals2[] = { 20, 5, 10, 5 };
    paint.setPathEffect(new SkDashPathEffect(intervals2, 4, 17))->unref();

    canvas->translate(0, 40);
    SkScalar x = -500;
    SkScalar width = 3173;
    for (int i = 0; i < 40; ++i) {
        if (i > 10)
        canvas->drawLine(x, 0, x + width, 0, paint);
        x += 1;
        canvas->translate(0, 4);
    }
}

// Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/
//
#include "SkGradientShader.h"
static void test_grad(SkCanvas* canvas) {
    SkPoint pts[] = {
        { 478.544067f, -84.2041016f },
        { 602.455933f, 625.204102f },
    };
    SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED };
    SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f };
    SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::kClamp_TileMode);
    SkPaint p;
    p.setShader(s)->unref();
    canvas->drawPaint(p);
}

static SkCanvas* MakeCanvas(const SkIRect& bounds) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
    bm.allocPixels();
    bm.eraseColor(SK_ColorTRANSPARENT);

    SkCanvas* canvas = new SkCanvas(bm);
    canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
    return canvas;
}

#ifdef SK_DEBUG
static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) {
    *bm = canvas->getDevice()->accessBitmap(false);
}
#endif

static void compare_canvas(const SkCanvas* a, const SkCanvas* b) {
#ifdef SK_DEBUG
    SkBitmap bma, bmb;
    GetBitmap(a, &bma);
    GetBitmap(b, &bmb);

    SkASSERT(bma.width() == bmb.width());
    SkASSERT(bma.height() == bmb.height());

    bma.lockPixels();
    bmb.lockPixels();
    for (int y = 0; y < bma.height(); ++y) {
        const SkPMColor* rowa = bma.getAddr32(0, y);
        const SkPMColor* rowb = bmb.getAddr32(0, y);
        SkASSERT(!memcmp(rowa, rowb, bma.width() << 2));

        for (int x = 1; x < bma.width() - 1; ++x) {
            SkASSERT(0xFF000000 == rowa[x]);
            SkASSERT(0xFF000000 == rowb[x]);
        }
    }
#endif
}

static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPath path;
    path.addRect(r);
    canvas->drawPath(path, p);
}

static void test_maskFromPath(const SkPath& path) {
    SkIRect bounds;
    path.getBounds().roundOut(&bounds);

    SkPaint paint;
    paint.setAntiAlias(true);

    SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds));
    path_canvas->drawPath(path, paint);

    SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds));
    drawRectAsPath(rect_canvas, path.getBounds(), paint);

    compare_canvas(path_canvas, rect_canvas);
}

static void test_mask() {
    for (int i = 1; i <= 20; ++i) {
        const SkScalar dx = SK_Scalar1 / i;
        const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2));
        for (int n = 2; n < 20; ++n) {
            SkPath path;
            path.setFillType(SkPath::kEvenOdd_FillType);
            SkRect r = constr;
            while (r.fRight < SkIntToScalar(4)) {
                path.addRect(r);
                r.offset(dx, 0);
            }
            test_maskFromPath(path);
        }
    }
}

namespace skiagm {

/** Draw a 2px border around the target, then red behind the target;
    set the clip to match the target, then draw >> the target in blue.
*/

static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
    SkPaint borderPaint;
    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
    borderPaint.setAntiAlias(true);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
    backgroundPaint.setAntiAlias(true);
    SkPaint foregroundPaint;
    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
    foregroundPaint.setAntiAlias(true);

    canvas->save();
    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
    canvas->drawRect(target, borderPaint);
    target.inset(SkIntToScalar(2), SkIntToScalar(2));
    canvas->drawRect(target, backgroundPaint);
    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
    canvas->drawRect(target, foregroundPaint);
    canvas->restore();
}

static void draw_square (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_column (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_bar (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_rect_tests (SkCanvas* canvas) {
    draw_square(canvas, 10, 10);
    draw_column(canvas, 30, 10);
    draw_bar(canvas, 10, 30);
}

/**
   Test a set of clipping problems discovered while writing blitAntiRect,
   and test all the code paths through the clipping blitters.
   Each region should show as a blue center surrounded by a 2px green
   border, with no red.
*/

class AAClipGM : public GM {
public:
    AAClipGM() {

    }

protected:
    virtual SkString onShortName() {
        return SkString("aaclip");
    }

    virtual SkISize onISize() {
        return make_isize(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (false) {
            test_giant_dash(canvas); return;
        }
        if (false) {
            test_grad(canvas); return;
        }
        if (false) { // avoid bit rot, suppress warning
            test_mask();
        }

        // Initial pixel-boundary-aligned draw
        draw_rect_tests(canvas);

        // Repeat 4x with .2, .4, .6, .8 px offsets
        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);
    }

    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }

private:
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new AAClipGM; }
static GMRegistry reg(MyFactory);

}
<|endoftext|>


<commit_before>/*
// Copyright (c) 2018 Intel Corporation
//
// 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.
*/
#pragma once
#include <ipmid/api.h>

#include <string>

namespace ipmi
{

static constexpr uint8_t maxIpmiChannels = 16;
static constexpr uint8_t currentChNum = 0xE;

/**
 * @enum IPMI return codes specific to channel (refer spec se 22.22 response
 * data)
 */
enum ipmi_channel_return_codes
{
    IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL = 0x82,
    IPMI_CC_ACCESS_MODE_NOT_SUPPORTED_FOR_CHANEL = 0x83
};

/**
 * @enum Channel Protocol Type (refer spec sec 6.4)
 */
enum class EChannelProtocolType : uint8_t
{
    na = 0x00,
    ipmbV10 = 0x01,
    icmbV11 = 0x02,
    reserved = 0x03,
    ipmiSmbus = 0x04,
    kcs = 0x05,
    smic = 0x06,
    bt10 = 0x07,
    bt15 = 0x08,
    tMode = 0x09,
    oem = 0x1C,
};

/**
 * @enum Channel Medium Type (refer spec sec 6.5)
 */
enum class EChannelMediumType : uint8_t
{
    reserved = 0x00,
    ipmb = 0x01,
    icmbV10 = 0x02,
    icmbV09 = 0x03,
    lan8032 = 0x04,
    serial = 0x05,
    otherLan = 0x06,
    pciSmbus = 0x07,
    smbusV11 = 0x08,
    smbusV20 = 0x09,
    usbV1x = 0x0A,
    usbV2x = 0x0B,
    systemInterface = 0x0C,
    oem = 0x60,
    unknown = 0x82,
};

/**
 * @enum Channel Session Type (refer spec sec 22.24 -
 * response data byte 5)
 */
enum class EChannelSessSupported : uint8_t
{
    none = 0,
    single = 1,
    multi = 2,
    any = 3,
};

/**
 * @enum Channel Access Mode (refer spec sec 6.6)
 */
enum class EChannelAccessMode : uint8_t
{
    disabled = 0,
    preboot = 1,
    alwaysAvail = 2,
    shared = 3,
};

/**
 * @enum Authentication Types (refer spec sec 13.6 - IPMI
 * Session Header)
 */
enum class EAuthType : uint8_t
{
    none = (1 << 0x0),
    md2 = (1 << 0x1),
    md5 = (1 << 0x2),
    reserved = (1 << 0x3),
    straightPasswd = (1 << 0x4),
    oem = (1 << 0x5),
};

/**
 * @enum Access mode for channel access set/get (refer spec
 * sec 22.22 - request byte 2[7:6])
 */
typedef enum
{
    doNotSet = 0x00,
    nvData = 0x01,
    activeData = 0x02,
    reserved = 0x03,
} EChannelActionType;

/**
 * @enum Access set flag to determine changes that has to be updated
 * in channel access data configuration.
 */
enum AccessSetFlag
{
    setAccessMode = (1 << 0),
    setUserAuthEnabled = (1 << 1),
    setMsgAuthEnabled = (1 << 2),
    setAlertingEnabled = (1 << 3),
    setPrivLimit = (1 << 4),
};

/** @struct ChannelAccess
 *
 *  Structure to store channel access related information, defined in IPMI
 * specification and used in Get / Set channel access (refer spec sec 22.22
 * & 22.23)
 */
struct ChannelAccess
{
    uint8_t accessMode;
    bool userAuthDisabled;
    bool perMsgAuthDisabled;
    bool alertingDisabled;
    uint8_t privLimit;
};

/** @struct ChannelInfo
 *
 *  Structure to store data about channel information, which identifies each
 *  channel type and information as defined in IPMI specification. (refer spec
 * sec 22.22 & 22.23)
 */
struct ChannelInfo
{
    uint8_t mediumType;
    uint8_t protocolType;
    uint8_t sessionSupported;
    bool isIpmi; // Is session IPMI
    // This is used in Get LAN Configuration parameter.
    // This holds the supported AuthTypes for a given channel.
    uint8_t authTypeSupported;
};

/** @brief determines valid channel
 *
 *  @param[in] chNum- channel number
 *
 *  @return true if valid, false otherwise
 */
bool isValidChannel(const uint8_t chNum);

/** @brief determines whether channel device exist
 *
 *  @param[in] chNum - channel number
 *
 *  @return true if valid, false otherwise
 */
bool doesDeviceExist(const uint8_t chNum);

/** @brief determines whether privilege limit is valid
 *
 *  @param[in] privLimit - Privilege limit
 *
 *  @return true if valid, false otherwise
 */
bool isValidPrivLimit(const uint8_t privLimit);

/** @brief determines whether access mode  is valid
 *
 *  @param[in] accessMode - Access mode
 *
 *  @return true if valid, false otherwise
 */
bool isValidAccessMode(const uint8_t accessMode);

/** @brief determines valid authentication type based on channel number
 *
 *  @param[in] chNum - channel number
 *  @param[in] authType - authentication type
 *
 *  @return true if valid, false otherwise
 */
bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);

/** @brief determines supported session type of a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return EChannelSessSupported - supported session type
 */
EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);

/** @brief determines number of active sessions on a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return numer of active sessions
 */
int getChannelActiveSessions(const uint8_t chNum);

/** @brief determines maximum transfer size for a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return maximum bytes that can be transferred on this channel
 */
size_t getChannelMaxTransferSize(uint8_t chNum);

/** @brief initializes channel management
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t ipmiChannelInit();

/** @brief provides channel info details
 *
 *  @param[in] chNum - channel number
 *  @param[out] chInfo - channel info details
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);

/** @brief provides channel access data
 *
 *  @param[in] chNum - channel number
 *  @param[out] chAccessData -channel access data
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAccessData(const uint8_t chNum,
                                ChannelAccess& chAccessData);

/** @brief provides function to convert current channel number (0xE)
 *
 *  @param[in] chNum - channel number as requested in commands.
 *
 *  @return same channel number or proper channel number for current channel
 * number (0xE).
 */
uint8_t convertCurrentChannelNum(const uint8_t chNum);

/** @brief to set channel access data
 *
 *  @param[in] chNum - channel number
 *  @param[in] chAccessData - channel access data
 *  @param[in] setFlag - flag to indicate updatable fields
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t setChannelAccessData(const uint8_t chNum,
                                const ChannelAccess& chAccessData,
                                const uint8_t setFlag);

/** @brief to get channel access data persistent data
 *
 *  @param[in] chNum - channel number
 *  @param[out] chAccessData - channel access data
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAccessPersistData(const uint8_t chNum,
                                       ChannelAccess& chAccessData);

/** @brief to set channel access data persistent data
 *
 *  @param[in] chNum - channel number
 *  @param[in] chAccessData - channel access data
 *  @param[in] setFlag - flag to indicate updatable fields
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t setChannelAccessPersistData(const uint8_t chNum,
                                       const ChannelAccess& chAccessData,
                                       const uint8_t setFlag);

/** @brief provides supported authentication type for the channel
 *
 *  @param[in] chNum - channel number
 *  @param[out] authTypeSupported - supported authentication type
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAuthTypeSupported(const uint8_t chNum,
                                       uint8_t& authTypeSupported);

/** @brief provides enabled authentication type for the channel
 *
 *  @param[in] chNum - channel number
 *  @param[in] priv - privilege
 *  @param[out] authType - enabled authentication type
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
                                     EAuthType& authType);

/** @brief Retrieves the LAN channel name from the IPMI channel number
 *
 *  @param[in] chNum - IPMI channel number
 *
 *  @return the LAN channel name (i.e. eth0)
 */
std::string getChannelName(const uint8_t chNum);

} // namespace ipmi
<commit_msg>Add convert current channel number function<commit_after>/*
// Copyright (c) 2018 Intel Corporation
//
// 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.
*/
#pragma once
#include <ipmid/api.h>

#include <ipmid/api.hpp>
#include <ipmid/message.hpp>
#include <string>

namespace ipmi
{

static constexpr uint8_t maxIpmiChannels = 16;
static constexpr uint8_t currentChNum = 0xE;

/**
 * @enum IPMI return codes specific to channel (refer spec se 22.22 response
 * data)
 */
enum ipmi_channel_return_codes
{
    IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL = 0x82,
    IPMI_CC_ACCESS_MODE_NOT_SUPPORTED_FOR_CHANEL = 0x83
};

/**
 * @enum Channel Protocol Type (refer spec sec 6.4)
 */
enum class EChannelProtocolType : uint8_t
{
    na = 0x00,
    ipmbV10 = 0x01,
    icmbV11 = 0x02,
    reserved = 0x03,
    ipmiSmbus = 0x04,
    kcs = 0x05,
    smic = 0x06,
    bt10 = 0x07,
    bt15 = 0x08,
    tMode = 0x09,
    oem = 0x1C,
};

/**
 * @enum Channel Medium Type (refer spec sec 6.5)
 */
enum class EChannelMediumType : uint8_t
{
    reserved = 0x00,
    ipmb = 0x01,
    icmbV10 = 0x02,
    icmbV09 = 0x03,
    lan8032 = 0x04,
    serial = 0x05,
    otherLan = 0x06,
    pciSmbus = 0x07,
    smbusV11 = 0x08,
    smbusV20 = 0x09,
    usbV1x = 0x0A,
    usbV2x = 0x0B,
    systemInterface = 0x0C,
    oem = 0x60,
    unknown = 0x82,
};

/**
 * @enum Channel Session Type (refer spec sec 22.24 -
 * response data byte 5)
 */
enum class EChannelSessSupported : uint8_t
{
    none = 0,
    single = 1,
    multi = 2,
    any = 3,
};

/**
 * @enum Channel Access Mode (refer spec sec 6.6)
 */
enum class EChannelAccessMode : uint8_t
{
    disabled = 0,
    preboot = 1,
    alwaysAvail = 2,
    shared = 3,
};

/**
 * @enum Authentication Types (refer spec sec 13.6 - IPMI
 * Session Header)
 */
enum class EAuthType : uint8_t
{
    none = (1 << 0x0),
    md2 = (1 << 0x1),
    md5 = (1 << 0x2),
    reserved = (1 << 0x3),
    straightPasswd = (1 << 0x4),
    oem = (1 << 0x5),
};

/**
 * @enum Access mode for channel access set/get (refer spec
 * sec 22.22 - request byte 2[7:6])
 */
typedef enum
{
    doNotSet = 0x00,
    nvData = 0x01,
    activeData = 0x02,
    reserved = 0x03,
} EChannelActionType;

/**
 * @enum Access set flag to determine changes that has to be updated
 * in channel access data configuration.
 */
enum AccessSetFlag
{
    setAccessMode = (1 << 0),
    setUserAuthEnabled = (1 << 1),
    setMsgAuthEnabled = (1 << 2),
    setAlertingEnabled = (1 << 3),
    setPrivLimit = (1 << 4),
};

/** @struct ChannelAccess
 *
 *  Structure to store channel access related information, defined in IPMI
 * specification and used in Get / Set channel access (refer spec sec 22.22
 * & 22.23)
 */
struct ChannelAccess
{
    uint8_t accessMode;
    bool userAuthDisabled;
    bool perMsgAuthDisabled;
    bool alertingDisabled;
    uint8_t privLimit;
};

/** @struct ChannelInfo
 *
 *  Structure to store data about channel information, which identifies each
 *  channel type and information as defined in IPMI specification. (refer spec
 * sec 22.22 & 22.23)
 */
struct ChannelInfo
{
    uint8_t mediumType;
    uint8_t protocolType;
    uint8_t sessionSupported;
    bool isIpmi; // Is session IPMI
    // This is used in Get LAN Configuration parameter.
    // This holds the supported AuthTypes for a given channel.
    uint8_t authTypeSupported;
};

/** @brief determines valid channel
 *
 *  @param[in] chNum- channel number
 *
 *  @return true if valid, false otherwise
 */
bool isValidChannel(const uint8_t chNum);

/** @brief determines whether channel device exist
 *
 *  @param[in] chNum - channel number
 *
 *  @return true if valid, false otherwise
 */
bool doesDeviceExist(const uint8_t chNum);

/** @brief determines whether privilege limit is valid
 *
 *  @param[in] privLimit - Privilege limit
 *
 *  @return true if valid, false otherwise
 */
bool isValidPrivLimit(const uint8_t privLimit);

/** @brief determines whether access mode  is valid
 *
 *  @param[in] accessMode - Access mode
 *
 *  @return true if valid, false otherwise
 */
bool isValidAccessMode(const uint8_t accessMode);

/** @brief determines valid authentication type based on channel number
 *
 *  @param[in] chNum - channel number
 *  @param[in] authType - authentication type
 *
 *  @return true if valid, false otherwise
 */
bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);

/** @brief determines supported session type of a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return EChannelSessSupported - supported session type
 */
EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);

/** @brief determines number of active sessions on a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return numer of active sessions
 */
int getChannelActiveSessions(const uint8_t chNum);

/** @brief determines maximum transfer size for a channel
 *
 *  @param[in] chNum - channel number
 *
 *  @return maximum bytes that can be transferred on this channel
 */
size_t getChannelMaxTransferSize(uint8_t chNum);

/** @brief initializes channel management
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t ipmiChannelInit();

/** @brief provides channel info details
 *
 *  @param[in] chNum - channel number
 *  @param[out] chInfo - channel info details
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);

/** @brief provides channel access data
 *
 *  @param[in] chNum - channel number
 *  @param[out] chAccessData -channel access data
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAccessData(const uint8_t chNum,
                                ChannelAccess& chAccessData);

/** @brief provides function to convert current channel number (0xE)
 *
 *  @param[in] chNum - channel number as requested in commands.
 *  @param[in] ipmi::context - ipmi context ptr, which has more details
 *
 *  @return same channel number or proper channel number for current channel
 * number (0xE).
 */
inline uint8_t convertCurrentChannelNum(const uint8_t chNum,
                                        ipmi::Context::ptr ctx)
{
    if (chNum == currentChNum)
    {
        return ctx->channel;
    }
    return chNum;
}

/** @brief provides function to convert current channel number (0xE)
 *
 *  @param[in] chNum - channel number as requested in commands.
 *
 *  @return same channel number or proper channel number for current channel
 * number (0xE).
 */
uint8_t convertCurrentChannelNum(const uint8_t chNum);

/** @brief to set channel access data
 *
 *  @param[in] chNum - channel number
 *  @param[in] chAccessData - channel access data
 *  @param[in] setFlag - flag to indicate updatable fields
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t setChannelAccessData(const uint8_t chNum,
                                const ChannelAccess& chAccessData,
                                const uint8_t setFlag);

/** @brief to get channel access data persistent data
 *
 *  @param[in] chNum - channel number
 *  @param[out] chAccessData - channel access data
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAccessPersistData(const uint8_t chNum,
                                       ChannelAccess& chAccessData);

/** @brief to set channel access data persistent data
 *
 *  @param[in] chNum - channel number
 *  @param[in] chAccessData - channel access data
 *  @param[in] setFlag - flag to indicate updatable fields
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t setChannelAccessPersistData(const uint8_t chNum,
                                       const ChannelAccess& chAccessData,
                                       const uint8_t setFlag);

/** @brief provides supported authentication type for the channel
 *
 *  @param[in] chNum - channel number
 *  @param[out] authTypeSupported - supported authentication type
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelAuthTypeSupported(const uint8_t chNum,
                                       uint8_t& authTypeSupported);

/** @brief provides enabled authentication type for the channel
 *
 *  @param[in] chNum - channel number
 *  @param[in] priv - privilege
 *  @param[out] authType - enabled authentication type
 *
 *  @return IPMI_CC_OK for success, others for failure.
 */
ipmi_ret_t getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
                                     EAuthType& authType);

/** @brief Retrieves the LAN channel name from the IPMI channel number
 *
 *  @param[in] chNum - IPMI channel number
 *
 *  @return the LAN channel name (i.e. eth0)
 */
std::string getChannelName(const uint8_t chNum);

} // namespace ipmi
<|endoftext|>


<commit_before>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is [Open Source Virtual Machine.].
 *
 * The Initial Developer of the Original Code is
 * Adobe System Incorporated.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Adobe AS3 Team
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "avmplus.h"

namespace avmplus
{
    using namespace MMgc;

    QCache::QCache(uint32_t _max, MMgc::GC* _gc) :
        m_gc(_gc),
        m_head(NULL),
        m_count(0),
        m_max(0)
    {
        MathUtils::RandomFastInit(&m_rand);
        resize(_max);
    }

    QCache::~QCache()
    {
        flush();
    }

    void QCache::flush()
    {
        QCachedItem* gen = first();
        while (gen)
        {
            QCachedItem* n = next(gen);
            gen->next = NULL;
            gen = n;
        }
        m_head = NULL;
        m_count = 0;
    }

    void QCache::resize(uint32_t _max)
    {
        flush();
        // 0 -> unlimited
        m_max = !_max ? 0xffffffff : _max;
    }

    QCachedItem* QCache::add(QCachedItem* gen)
    {
        AvmAssert(gen && !next(gen));

        QCachedItem* evicted = NULL;

        // if no space, evict oldest
        if (m_count >= m_max)
        {
            AvmAssert(m_count == m_max);
            uint32_t which = MathUtils::Random(count(), &m_rand);
            QCachedItem* evicted_prev = NULL;
            for (QCachedItem* td = first(); td; td = next(td))
            {
                if (!which--)
                {
                    evicted = td;
                    break;
                }
                evicted_prev = td;
            }
            if (evicted_prev)
            {
                evicted = evicted_prev->next;
                AvmAssert(evicted != NULL && evicted != gen);
                WB(m_gc, evicted_prev, &evicted_prev->next, evicted->next);
            }
            else
            {
                evicted = m_head;
                AvmAssert(evicted != NULL && evicted != gen);
                WB(m_gc, this, &m_head, evicted->next);
            }
            evicted->next = NULL;   // never need a WB to write NULL
            --m_count;
            #ifdef QCACHE_DEBUG
            validate();
            #endif
        }

        // add at head
        WB(m_gc, gen, &gen->next, m_head);
        WB(m_gc, this, &m_head, gen);
        ++m_count;

        #ifdef QCACHE_DEBUG
        validate();
        #endif

        AvmAssert(evicted ? evicted->next == NULL : true);
        return evicted;
    }

    #ifdef QCACHE_DEBUG
    void QCache::validate() const
    {
        if (!m_head)
        {
            AvmAssert(m_count == 0);
            return;
        }
        uint32_t c = 0;
        QCachedItem* prev = NULL;
        for (QCachedItem* td = first(); td; td = next(td))
        {
            AvmAssert(prev ? prev->next == td : true);
            ++c;
            prev = td;
            if (c > m_max)
            {
                // oops, probably a cycle, busted code
                AvmAssert(0);
            }
        }
        AvmAssert(c == m_count);
    }
    #endif
}

<commit_msg>Fix 525562  - Double var assign in QCache.cpp (r=stejohns)<commit_after>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is [Open Source Virtual Machine.].
 *
 * The Initial Developer of the Original Code is
 * Adobe System Incorporated.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Adobe AS3 Team
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "avmplus.h"

namespace avmplus
{
    using namespace MMgc;

    QCache::QCache(uint32_t _max, MMgc::GC* _gc) :
        m_gc(_gc),
        m_head(NULL),
        m_count(0),
        m_max(0)
    {
        MathUtils::RandomFastInit(&m_rand);
        resize(_max);
    }

    QCache::~QCache()
    {
        flush();
    }

    void QCache::flush()
    {
        QCachedItem* gen = first();
        while (gen)
        {
            QCachedItem* n = next(gen);
            gen->next = NULL;
            gen = n;
        }
        m_head = NULL;
        m_count = 0;
    }

    void QCache::resize(uint32_t _max)
    {
        flush();
        // 0 -> unlimited
        m_max = !_max ? 0xffffffff : _max;
    }

    QCachedItem* QCache::add(QCachedItem* gen)
    {
        AvmAssert(gen && !next(gen));

        QCachedItem* evicted = NULL;

        // if no space, evict oldest
        if (m_count >= m_max)
        {
            AvmAssert(m_count == m_max);
            uint32_t which = MathUtils::Random(count(), &m_rand);
            QCachedItem* evicted_prev = NULL;
            for (QCachedItem* td = first(); td; td = next(td))
            {
                if (!which--)
                    break;
                evicted_prev = td;
            }
            if (evicted_prev)
            {
                evicted = evicted_prev->next;
                AvmAssert(evicted != NULL && evicted != gen);
                WB(m_gc, evicted_prev, &evicted_prev->next, evicted->next);
            }
            else
            {
                evicted = m_head;
                AvmAssert(evicted != NULL && evicted != gen);
                WB(m_gc, this, &m_head, evicted->next);
            }
            evicted->next = NULL;   // never need a WB to write NULL
            --m_count;
            #ifdef QCACHE_DEBUG
            validate();
            #endif
        }

        // add at head
        WB(m_gc, gen, &gen->next, m_head);
        WB(m_gc, this, &m_head, gen);
        ++m_count;

        #ifdef QCACHE_DEBUG
        validate();
        #endif

        AvmAssert(evicted ? evicted->next == NULL : true);
        return evicted;
    }

    #ifdef QCACHE_DEBUG
    void QCache::validate() const
    {
        if (!m_head)
        {
            AvmAssert(m_count == 0);
            return;
        }
        uint32_t c = 0;
        QCachedItem* prev = NULL;
        for (QCachedItem* td = first(); td; td = next(td))
        {
            AvmAssert(prev ? prev->next == td : true);
            ++c;
            prev = td;
            if (c > m_max)
            {
                // oops, probably a cycle, busted code
                AvmAssert(0);
            }
        }
        AvmAssert(c == m_count);
    }
    #endif
}

<|endoftext|>