<commit_before>/*!
 * ws: a node.js websocket client
 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
 * MIT Licensed
 */

#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <node_object_wrap.h>
#include <stdlib.h>
#include <strings.h>
#include <wchar.h>
#include <stdio.h>

using namespace v8;
using namespace node;

#define UNI_SUR_HIGH_START   (uint32_t) 0xD800
#define UNI_SUR_LOW_END    (uint32_t) 0xDFFF
#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD
#define UNI_MAX_LEGAL_UTF32  (uint32_t) 0x0010FFFF

static const uint8_t trailingBytesForUTF8[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};

static const uint32_t offsetsFromUTF8[6] = {
  0x00000000, 0x00003080, 0x000E2080,
  0x03C82080, 0xFA082080, 0x82082080
};

static int isLegalUTF8(const uint8_t *source, const int length)
{
  uint8_t a;
  const uint8_t *srcptr = source+length;
  switch (length) {
  default: return 0;
  /* Everything else falls through when "true"... */
  /* RFC3629 makes 5 & 6 bytes UTF-8 illegal
  case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */
  case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
    switch (*source) {
      /* no fall-through in this inner switch */
      case 0xE0: if (a < 0xA0) return 0; break;
      case 0xED: if (a > 0x9F) return 0; break;
      case 0xF0: if (a < 0x90) return 0; break;
      case 0xF4: if (a > 0x8F) return 0; break;
      default:   if (a < 0x80) return 0;
    }

  case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
  }
  if (*source > 0xF4) return 0;
  return 1;
}

int is_valid_utf8 (size_t len, char *value)
{
  /* is the string valid UTF-8? */
  for (int i = 0; i < len; i++) {
    uint32_t ch = 0;
    uint8_t  extrabytes = trailingBytesForUTF8[(uint8_t) value[i]];

    if (extrabytes + i >= len)
      return 0;

    if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0;

    switch (extrabytes) {
      case 5 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 4 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 3 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 2 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 1 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 0 : ch += (uint8_t) value[i];
    }

    ch -= offsetsFromUTF8[extrabytes];

    if (ch <= UNI_MAX_LEGAL_UTF32) {
      if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
        return 0;
    } else {
      return 0;
    }
  }

  return 1;
}

class Validation : public ObjectWrap
{
public:

  static void Initialize(v8::Handle<v8::Object> target)
  {
    HandleScope scope;
    Local<FunctionTemplate> t = FunctionTemplate::New(New);
    t->InstanceTemplate()->SetInternalFieldCount(1);
    NODE_SET_METHOD(t->GetFunction(), "isValidUTF8", Validation::IsValidUTF8);
    target->Set(String::NewSymbol("Validation"), t->GetFunction());
  }

protected:

  static Handle<Value> New(const Arguments& args)
  {
    HandleScope scope;
    Validation* validation = new Validation();
    validation->Wrap(args.This());
    return args.This();
  }

  static Handle<Value> IsValidUTF8(const Arguments& args)
  {
    HandleScope scope;
    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);
    return is_valid_utf8(buffer_length, buffer_data) == 1 ? scope.Close(True()) : scope.Close(False());
   }
};

extern "C" void init (Handle<Object> target)
{
  HandleScope scope;
  Validation::Initialize(target);
}
<commit_msg>removed unnecessary strings.h<commit_after>/*!
 * ws: a node.js websocket client
 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
 * MIT Licensed
 */

#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <node_object_wrap.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>

using namespace v8;
using namespace node;

#define UNI_SUR_HIGH_START   (uint32_t) 0xD800
#define UNI_SUR_LOW_END    (uint32_t) 0xDFFF
#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD
#define UNI_MAX_LEGAL_UTF32  (uint32_t) 0x0010FFFF

static const uint8_t trailingBytesForUTF8[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};

static const uint32_t offsetsFromUTF8[6] = {
  0x00000000, 0x00003080, 0x000E2080,
  0x03C82080, 0xFA082080, 0x82082080
};

static int isLegalUTF8(const uint8_t *source, const int length)
{
  uint8_t a;
  const uint8_t *srcptr = source+length;
  switch (length) {
  default: return 0;
  /* Everything else falls through when "true"... */
  /* RFC3629 makes 5 & 6 bytes UTF-8 illegal
  case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */
  case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
    switch (*source) {
      /* no fall-through in this inner switch */
      case 0xE0: if (a < 0xA0) return 0; break;
      case 0xED: if (a > 0x9F) return 0; break;
      case 0xF0: if (a < 0x90) return 0; break;
      case 0xF4: if (a > 0x8F) return 0; break;
      default:   if (a < 0x80) return 0;
    }

  case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
  }
  if (*source > 0xF4) return 0;
  return 1;
}

int is_valid_utf8 (size_t len, char *value)
{
  /* is the string valid UTF-8? */
  for (int i = 0; i < len; i++) {
    uint32_t ch = 0;
    uint8_t  extrabytes = trailingBytesForUTF8[(uint8_t) value[i]];

    if (extrabytes + i >= len)
      return 0;

    if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0;

    switch (extrabytes) {
      case 5 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 4 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 3 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 2 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 1 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 0 : ch += (uint8_t) value[i];
    }

    ch -= offsetsFromUTF8[extrabytes];

    if (ch <= UNI_MAX_LEGAL_UTF32) {
      if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
        return 0;
    } else {
      return 0;
    }
  }

  return 1;
}

class Validation : public ObjectWrap
{
public:

  static void Initialize(v8::Handle<v8::Object> target)
  {
    HandleScope scope;
    Local<FunctionTemplate> t = FunctionTemplate::New(New);
    t->InstanceTemplate()->SetInternalFieldCount(1);
    NODE_SET_METHOD(t->GetFunction(), "isValidUTF8", Validation::IsValidUTF8);
    target->Set(String::NewSymbol("Validation"), t->GetFunction());
  }

protected:

  static Handle<Value> New(const Arguments& args)
  {
    HandleScope scope;
    Validation* validation = new Validation();
    validation->Wrap(args.This());
    return args.This();
  }

  static Handle<Value> IsValidUTF8(const Arguments& args)
  {
    HandleScope scope;
    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);
    return is_valid_utf8(buffer_length, buffer_data) == 1 ? scope.Close(True()) : scope.Close(False());
   }
};

extern "C" void init (Handle<Object> target)
{
  HandleScope scope;
  Validation::Initialize(target);
}
<|endoftext|>


<commit_before>/*
 * RtpExtensionProcessor.cpp
 */
#include "rtp/RtpExtensionProcessor.h"
#include <map>
#include <string>
#include <vector>

#include "lib/Clock.h"

namespace erizo {
DEFINE_LOGGER(RtpExtensionProcessor, "rtp.RtpExtensionProcessor");

RtpExtensionProcessor::RtpExtensionProcessor(const std::vector<erizo::ExtMap> ext_mappings) :
    ext_mappings_{ext_mappings}, video_orientation_{kVideoRotation_0} {
  translationMap_["urn:ietf:params:rtp-hdrext:ssrc-audio-level"] = SSRC_AUDIO_LEVEL;
  translationMap_["http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"] = ABS_SEND_TIME;
  translationMap_["urn:ietf:params:rtp-hdrext:toffset"] = TOFFSET;
  translationMap_["urn:3gpp:video-orientation"] = VIDEO_ORIENTATION;
  translationMap_["http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"] = TRANSPORT_CC;
  translationMap_["http://www.webrtc.org/experiments/rtp-hdrext/playout-delay"]= PLAYBACK_TIME;
  translationMap_["urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"]= RTP_ID;
  ext_map_video_.fill(UNKNOWN);
  ext_map_audio_.fill(UNKNOWN);
}

RtpExtensionProcessor::~RtpExtensionProcessor() {
}

void RtpExtensionProcessor::setSdpInfo(std::shared_ptr<SdpInfo> theInfo) {
  // We build the Extension Map
  for (unsigned int i = 0; i < theInfo->extMapVector.size(); i++) {
    const ExtMap& theMap = theInfo->extMapVector[i];
    std::map<std::string, uint8_t>::iterator it;
    switch (theMap.mediaType) {
      case VIDEO_TYPE:
        if (isValidExtension(theMap.uri)) {
          ELOG_DEBUG("Adding RTP Extension for video %s, value %u", theMap.uri.c_str(), theMap.value);
          ext_map_video_[theMap.value] = RTPExtensions((*translationMap_.find(theMap.uri)).second);
        } else {
          ELOG_WARN("Unsupported extension %s", theMap.uri.c_str());
        }
        break;
      case AUDIO_TYPE:
        if (isValidExtension(theMap.uri)) {
          ELOG_DEBUG("Adding RTP Extension for Audio %s, value %u", theMap.uri.c_str(), theMap.value);
          ext_map_audio_[theMap.value] = RTPExtensions((*translationMap_.find(theMap.uri)).second);
        } else {
          ELOG_WARN("Unsupported extension %s", theMap.uri.c_str());
        }
        break;
      default:
        ELOG_WARN("Unknown type of extMap, ignoring");
        break;
    }
  }
}

bool RtpExtensionProcessor::isValidExtension(std::string uri) {
  auto value = std::find_if(ext_mappings_.begin(), ext_mappings_.end(), [uri](const ExtMap &extension) {
    return uri == extension.uri;
  });
  return value != ext_mappings_.end() && translationMap_.find(uri) != translationMap_.end();
}

uint32_t RtpExtensionProcessor::processRtpExtensions(std::shared_ptr<DataPacket> p) {
  const RtpHeader* head = reinterpret_cast<const RtpHeader*>(p->data);
  uint32_t len = p->length;
  std::array<RTPExtensions, 15> extMap;
  if (head->getExtension()) {
    switch (p->type) {
      case VIDEO_PACKET:
        extMap = ext_map_video_;
        break;
      case AUDIO_PACKET:
        extMap = ext_map_audio_;
        break;
      default:
        ELOG_WARN("Won't process RTP extensions for unknown type packets");
        return 0;
        break;
    }
    uint16_t totalExtLength = head->getExtLength();
    if (head->getExtId() == 0xBEDE) {
      char* extBuffer = (char*)&head->extensions;  // NOLINT
      uint8_t extByte = 0;
      uint16_t currentPlace = 1;
      uint8_t extId = 0;
      uint8_t extLength = 0;
      while (currentPlace < (totalExtLength*4)) {
        extByte = (uint8_t)(*extBuffer);
        extId = extByte >> 4;
        extLength = extByte & 0x0F;
        if (extId != 0 && extMap[extId] != 0) {
          switch (extId) {
            case ABS_SEND_TIME:
              processAbsSendTime(extBuffer);
              break;
            case VIDEO_ORIENTATION:
              processVideoOrientation(extBuffer);
              break;
            default:
              break;
          }
        }
        extBuffer = extBuffer + extLength + 2;
        currentPlace = currentPlace + extLength + 2;
      }
    }
  }
  return len;
}

VideoRotation RtpExtensionProcessor::getVideoRotation() {
  return video_orientation_;
}

uint32_t RtpExtensionProcessor::processVideoOrientation(char* buf) {
  VideoOrientation* head = reinterpret_cast<VideoOrientation*>(buf);
  video_orientation_ = head->getVideoOrientation();
  return 0;
}

uint32_t RtpExtensionProcessor::processAbsSendTime(char* buf) {
  duration now = clock::now().time_since_epoch();
  AbsSendTimeExtension* head = reinterpret_cast<AbsSendTimeExtension*>(buf);
  auto now_sec = std::chrono::duration_cast<std::chrono::seconds>(now);
  auto now_usec = std::chrono::duration_cast<std::chrono::microseconds>(now);

  uint32_t now_usec_only = now_usec.count() - now_sec.count()*1e+6;

  uint8_t seconds = now_sec.count() & 0x3F;
  uint32_t absecs = now_usec_only * ((1LL << 18) - 1) * 1e-6;

  absecs = (seconds << 18) + absecs;
  head->setAbsSendTime(absecs);
  return 0;
}

uint32_t RtpExtensionProcessor::stripExtension(char* buf, int len) {
  // TODO(pedro)
  return len;
}
}  // namespace erizo
<commit_msg>Fix the way we detect abs send time to update it (#1486)<commit_after>/*
 * RtpExtensionProcessor.cpp
 */
#include "rtp/RtpExtensionProcessor.h"
#include <map>
#include <string>
#include <vector>

#include "lib/Clock.h"

namespace erizo {
DEFINE_LOGGER(RtpExtensionProcessor, "rtp.RtpExtensionProcessor");

RtpExtensionProcessor::RtpExtensionProcessor(const std::vector<erizo::ExtMap> ext_mappings) :
    ext_mappings_{ext_mappings}, video_orientation_{kVideoRotation_0} {
  translationMap_["urn:ietf:params:rtp-hdrext:ssrc-audio-level"] = SSRC_AUDIO_LEVEL;
  translationMap_["http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"] = ABS_SEND_TIME;
  translationMap_["urn:ietf:params:rtp-hdrext:toffset"] = TOFFSET;
  translationMap_["urn:3gpp:video-orientation"] = VIDEO_ORIENTATION;
  translationMap_["http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"] = TRANSPORT_CC;
  translationMap_["http://www.webrtc.org/experiments/rtp-hdrext/playout-delay"]= PLAYBACK_TIME;
  translationMap_["urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"]= RTP_ID;
  ext_map_video_.fill(UNKNOWN);
  ext_map_audio_.fill(UNKNOWN);
}

RtpExtensionProcessor::~RtpExtensionProcessor() {
}

void RtpExtensionProcessor::setSdpInfo(std::shared_ptr<SdpInfo> theInfo) {
  // We build the Extension Map
  for (unsigned int i = 0; i < theInfo->extMapVector.size(); i++) {
    const ExtMap& theMap = theInfo->extMapVector[i];
    std::map<std::string, uint8_t>::iterator it;
    switch (theMap.mediaType) {
      case VIDEO_TYPE:
        if (isValidExtension(theMap.uri)) {
          ELOG_DEBUG("Adding RTP Extension for video %s, value %u", theMap.uri.c_str(), theMap.value);
          ext_map_video_[theMap.value] = RTPExtensions((*translationMap_.find(theMap.uri)).second);
        } else {
          ELOG_WARN("Unsupported extension %s", theMap.uri.c_str());
        }
        break;
      case AUDIO_TYPE:
        if (isValidExtension(theMap.uri)) {
          ELOG_DEBUG("Adding RTP Extension for Audio %s, value %u", theMap.uri.c_str(), theMap.value);
          ext_map_audio_[theMap.value] = RTPExtensions((*translationMap_.find(theMap.uri)).second);
        } else {
          ELOG_WARN("Unsupported extension %s", theMap.uri.c_str());
        }
        break;
      default:
        ELOG_WARN("Unknown type of extMap, ignoring");
        break;
    }
  }
}

bool RtpExtensionProcessor::isValidExtension(std::string uri) {
  auto value = std::find_if(ext_mappings_.begin(), ext_mappings_.end(), [uri](const ExtMap &extension) {
    return uri == extension.uri;
  });
  return value != ext_mappings_.end() && translationMap_.find(uri) != translationMap_.end();
}

uint32_t RtpExtensionProcessor::processRtpExtensions(std::shared_ptr<DataPacket> p) {
  const RtpHeader* head = reinterpret_cast<const RtpHeader*>(p->data);
  uint32_t len = p->length;
  std::array<RTPExtensions, 15> extMap;
  if (head->getExtension()) {
    switch (p->type) {
      case VIDEO_PACKET:
        extMap = ext_map_video_;
        break;
      case AUDIO_PACKET:
        extMap = ext_map_audio_;
        break;
      default:
        ELOG_WARN("Won't process RTP extensions for unknown type packets");
        return 0;
        break;
    }
    uint16_t totalExtLength = head->getExtLength();
    if (head->getExtId() == 0xBEDE) {
      char* extBuffer = (char*)&head->extensions;  // NOLINT
      uint8_t extByte = 0;
      uint16_t currentPlace = 1;
      uint8_t extId = 0;
      uint8_t extLength = 0;
      while (currentPlace < (totalExtLength*4)) {
        extByte = (uint8_t)(*extBuffer);
        extId = extByte >> 4;
        extLength = extByte & 0x0F;
        if (extId != 0 && extMap[extId] != 0) {
          switch (extMap[extId]) {
            case ABS_SEND_TIME:
              processAbsSendTime(extBuffer);
              break;
            case VIDEO_ORIENTATION:
              processVideoOrientation(extBuffer);
              break;
            default:
              break;
          }
        }
        extBuffer = extBuffer + extLength + 2;
        currentPlace = currentPlace + extLength + 2;
      }
    }
  }
  return len;
}

VideoRotation RtpExtensionProcessor::getVideoRotation() {
  return video_orientation_;
}

uint32_t RtpExtensionProcessor::processVideoOrientation(char* buf) {
  VideoOrientation* head = reinterpret_cast<VideoOrientation*>(buf);
  video_orientation_ = head->getVideoOrientation();
  return 0;
}

uint32_t RtpExtensionProcessor::processAbsSendTime(char* buf) {
  duration now = clock::now().time_since_epoch();
  AbsSendTimeExtension* head = reinterpret_cast<AbsSendTimeExtension*>(buf);
  auto now_sec = std::chrono::duration_cast<std::chrono::seconds>(now);
  auto now_usec = std::chrono::duration_cast<std::chrono::microseconds>(now);

  uint32_t now_usec_only = now_usec.count() - now_sec.count()*1e+6;

  uint8_t seconds = now_sec.count() & 0x3F;
  uint32_t absecs = now_usec_only * ((1LL << 18) - 1) * 1e-6;

  absecs = (seconds << 18) + absecs;
  head->setAbsSendTime(absecs);
  return 0;
}

uint32_t RtpExtensionProcessor::stripExtension(char* buf, int len) {
  // TODO(pedro)
  return len;
}
}  // namespace erizo
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: admininvokationimpl.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-25 16:00:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source 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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX
#define EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

class Window;
//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= OAdminDialogInvokation
    //=====================================================================
    /** outsourced from AdminDialogInvokationPage, 'cause this class here, in opposite to
        the page, needs exception handlng to be enabled.
    */
    class OAdminDialogInvokation
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        m_xORB;
        ::rtl::OUString m_sPreferredName;
        Window*         m_pMessageParent;

    public:
        OAdminDialogInvokation(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            const ::rtl::OUString& _rPreferredName,
            Window* _pMessageParent
        );

        sal_Bool invokeAdministration( sal_Bool _bFixedType );
    };

//.........................................................................
}   // namespace abp
//.........................................................................

#endif // EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX

<commit_msg>INTEGRATION: CWS insight01 (1.2.182); FILE MERGED 2004/04/16 12:07:05 oj 1.2.182.1: correct alignment and default<commit_after>/*************************************************************************
 *
 *  $RCSfile: admininvokationimpl.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 17:35:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source 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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX
#define EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

class Window;
//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= OAdminDialogInvokation
    //=====================================================================
    /** outsourced from AdminDialogInvokationPage, 'cause this class here, in opposite to
        the page, needs exception handlng to be enabled.
    */
    class OAdminDialogInvokation
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        m_xORB;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xDataSource;
        Window*         m_pMessageParent;

    public:
        OAdminDialogInvokation(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > _xDataSource,
            Window* _pMessageParent
        );

        sal_Bool invokeAdministration( sal_Bool _bFixedType );
    };

//.........................................................................
}   // namespace abp
//.........................................................................

#endif // EXTENSIONS_ABP_ADMININVOKATIONIMPL_HXX

<|endoftext|>


<commit_before>//===- Pass.cpp - LLVM Pass Infrastructure Implementation -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVM Pass infrastructure.  It is primarily
// responsible with ensuring that passes are executed and batched together
// optimally.
//
//===----------------------------------------------------------------------===//

#include "llvm/PassManager.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TypeInfo.h"
#include <algorithm>
#include <set>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Pass Implementation
//

// Force out-of-line virtual method.
Pass::~Pass() {
  delete Resolver;
}

// Force out-of-line virtual method.
ModulePass::~ModulePass() { }

bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
  return Resolver->getAnalysisToUpdate(AnalysisID, true) != 0;
}

// dumpPassStructure - Implement the -debug-passes=Structure option
void Pass::dumpPassStructure(unsigned Offset) {
  cerr << std::string(Offset*2, ' ') << getPassName() << "\n";
}

// getPassName - Use C++ RTTI to get a SOMEWHAT intelligible name for the pass.
//
const char *Pass::getPassName() const {
  if (const PassInfo *PI = getPassInfo())
    return PI->getPassName();
  return typeid(*this).name();
}

// print - Print out the internal state of the pass.  This is called by Analyze
// to print out the contents of an analysis.  Otherwise it is not necessary to
// implement this method.
//
void Pass::print(std::ostream &O,const Module*) const {
  O << "Pass::print not implemented for pass: '" << getPassName() << "'!\n";
}

// dump - call print(cerr);
void Pass::dump() const {
  print(*cerr.stream(), 0);
}

//===----------------------------------------------------------------------===//
// ImmutablePass Implementation
//
// Force out-of-line virtual method.
ImmutablePass::~ImmutablePass() { }

//===----------------------------------------------------------------------===//
// FunctionPass Implementation
//

// run - On a module, we run this pass by initializing, runOnFunction'ing once
// for every function in the module, then by finalizing.
//
bool FunctionPass::runOnModule(Module &M) {
  bool Changed = doInitialization(M);

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration())      // Passes are not run on external functions!
    Changed |= runOnFunction(*I);

  return Changed | doFinalization(M);
}

// run - On a function, we simply initialize, run the function, then finalize.
//
bool FunctionPass::run(Function &F) {
  if (F.isDeclaration()) return false;// Passes are not run on external functions!

  bool Changed = doInitialization(*F.getParent());
  Changed |= runOnFunction(F);
  return Changed | doFinalization(*F.getParent());
}

//===----------------------------------------------------------------------===//
// BasicBlockPass Implementation
//

// To run this pass on a function, we simply call runOnBasicBlock once for each
// function.
//
bool BasicBlockPass::runOnFunction(Function &F) {
  bool Changed = doInitialization(F);
  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
    Changed |= runOnBasicBlock(*I);
  return Changed | doFinalization(F);
}

// To run directly on the basic block, we initialize, runOnBasicBlock, then
// finalize.
//
bool BasicBlockPass::runPass(BasicBlock &BB) {
  Function &F = *BB.getParent();
  Module &M = *F.getParent();
  bool Changed = doInitialization(M);
  Changed |= doInitialization(F);
  Changed |= runOnBasicBlock(BB);
  Changed |= doFinalization(F);
  Changed |= doFinalization(M);
  return Changed;
}

//===----------------------------------------------------------------------===//
// Pass Registration mechanism
//
namespace {
class PassRegistrar {
  /// PassInfoMap - Keep track of the passinfo object for each registered llvm
  /// pass.
  std::map<intptr_t, PassInfo*> PassInfoMap;

  /// AnalysisGroupInfo - Keep track of information for each analysis group.
  struct AnalysisGroupInfo {
    const PassInfo *DefaultImpl;
    std::set<const PassInfo *> Implementations;
    AnalysisGroupInfo() : DefaultImpl(0) {}
  };

  /// AnalysisGroupInfoMap - Information for each analysis group.
  std::map<const PassInfo *, AnalysisGroupInfo> AnalysisGroupInfoMap;

public:

  const PassInfo *GetPassInfo(intptr_t TI) const {
    std::map<intptr_t, PassInfo*>::const_iterator I = PassInfoMap.find(TI);
    return I != PassInfoMap.end() ? I->second : 0;
  }

  void RegisterPass(PassInfo &PI) {
    bool Inserted =
      PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
    assert(Inserted && "Pass registered multiple times!");
  }

  void UnregisterPass(PassInfo &PI) {
    std::map<intptr_t, PassInfo*>::iterator I =
      PassInfoMap.find(PI.getTypeInfo());
    assert(I != PassInfoMap.end() && "Pass registered but not in map!");

    // Remove pass from the map.
    PassInfoMap.erase(I);
  }

  void EnumerateWith(PassRegistrationListener *L) {
    for (std::map<intptr_t, PassInfo*>::const_iterator I = PassInfoMap.begin(),
         E = PassInfoMap.end(); I != E; ++I)
      L->passEnumerate(I->second);
  }

  /// Analysis Group Mechanisms.
  void RegisterAnalysisGroup(PassInfo *InterfaceInfo,
                             const PassInfo *ImplementationInfo,
                             bool isDefault) {
    AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
    assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
           "Cannot add a pass to the same analysis group more than once!");
    AGI.Implementations.insert(ImplementationInfo);
    if (isDefault) {
      assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 &&
             "Default implementation for analysis group already specified!");
      assert(ImplementationInfo->getNormalCtor() &&
           "Cannot specify pass as default if it does not have a default ctor");
      AGI.DefaultImpl = ImplementationInfo;
      InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
    }
  }
};
}

static std::vector<PassRegistrationListener*> *Listeners = 0;

// FIXME: This should use ManagedStatic to manage the pass registrar.
// Unfortunately, we can't do this, because passes are registered with static
// ctors, and having llvm_shutdown clear this map prevents successful
// ressurection after llvm_shutdown is run.
static PassRegistrar *getPassRegistrar() {
  static PassRegistrar *PassRegistrarObj = 0;
  if (!PassRegistrarObj)
    PassRegistrarObj = new PassRegistrar();
  return PassRegistrarObj;
}

// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass...
const PassInfo *Pass::getPassInfo() const {
  return lookupPassInfo(PassID);
}

const PassInfo *Pass::lookupPassInfo(intptr_t TI) {
  return getPassRegistrar()->GetPassInfo(TI);
}

void RegisterPassBase::registerPass() {
  getPassRegistrar()->RegisterPass(PIObj);

  // Notify any listeners.
  if (Listeners)
    for (std::vector<PassRegistrationListener*>::iterator
           I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
      (*I)->passRegistered(&PIObj);
}

void RegisterPassBase::unregisterPass() {
  getPassRegistrar()->UnregisterPass(PIObj);
}

//===----------------------------------------------------------------------===//
//                  Analysis Group Implementation Code
//===----------------------------------------------------------------------===//

// RegisterAGBase implementation
//
RegisterAGBase::RegisterAGBase(intptr_t InterfaceID,
                               intptr_t PassID, bool isDefault)
  : RegisterPassBase(InterfaceID),
    ImplementationInfo(0), isDefaultImplementation(isDefault) {

  InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(InterfaceID));
  if (InterfaceInfo == 0) {
    // First reference to Interface, register it now.
    registerPass();
    InterfaceInfo = &PIObj;
  }
  assert(PIObj.isAnalysisGroup() &&
         "Trying to join an analysis group that is a normal pass!");

  if (PassID) {
    ImplementationInfo = Pass::lookupPassInfo(PassID);
    assert(ImplementationInfo &&
           "Must register pass before adding to AnalysisGroup!");

    // Make sure we keep track of the fact that the implementation implements
    // the interface.
    PassInfo *IIPI = const_cast<PassInfo*>(ImplementationInfo);
    IIPI->addInterfaceImplemented(InterfaceInfo);

    getPassRegistrar()->RegisterAnalysisGroup(InterfaceInfo, IIPI, isDefault);
  }
}

void RegisterAGBase::setGroupName(const char *Name) {
  assert(InterfaceInfo->getPassName()[0] == 0 && "Interface Name already set!");
  InterfaceInfo->setPassName(Name);
}

//===----------------------------------------------------------------------===//
// PassRegistrationListener implementation
//

// PassRegistrationListener ctor - Add the current object to the list of
// PassRegistrationListeners...
PassRegistrationListener::PassRegistrationListener() {
  if (!Listeners) Listeners = new std::vector<PassRegistrationListener*>();
  Listeners->push_back(this);
}

// dtor - Remove object from list of listeners...
PassRegistrationListener::~PassRegistrationListener() {
  std::vector<PassRegistrationListener*>::iterator I =
    std::find(Listeners->begin(), Listeners->end(), this);
  assert(Listeners && I != Listeners->end() &&
         "PassRegistrationListener not registered!");
  Listeners->erase(I);

  if (Listeners->empty()) {
    delete Listeners;
    Listeners = 0;
  }
}

// enumeratePasses - Iterate over the registered passes, calling the
// passEnumerate callback on each PassInfo object.
//
void PassRegistrationListener::enumeratePasses() {
  getPassRegistrar()->EnumerateWith(this);
}

//===----------------------------------------------------------------------===//
//   AnalysisUsage Class Implementation
//

namespace {
  struct GetCFGOnlyPasses : public PassRegistrationListener {
    std::vector<AnalysisID> &CFGOnlyList;
    GetCFGOnlyPasses(std::vector<AnalysisID> &L) : CFGOnlyList(L) {}

    void passEnumerate(const PassInfo *P) {
      if (P->isCFGOnlyPass())
        CFGOnlyList.push_back(P);
    }
  };
}

// setPreservesCFG - This function should be called to by the pass, iff they do
// not:
//
//  1. Add or remove basic blocks from the function
//  2. Modify terminator instructions in any way.
//
// This function annotates the AnalysisUsage info object to say that analyses
// that only depend on the CFG are preserved by this pass.
//
void AnalysisUsage::setPreservesCFG() {
  // Since this transformation doesn't modify the CFG, it preserves all analyses
  // that only depend on the CFG (like dominators, loop info, etc...)
  GetCFGOnlyPasses(Preserved).enumeratePasses();
}

<commit_msg>Reduce reliance on rtti info<commit_after>//===- Pass.cpp - LLVM Pass Infrastructure Implementation -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVM Pass infrastructure.  It is primarily
// responsible with ensuring that passes are executed and batched together
// optimally.
//
//===----------------------------------------------------------------------===//

#include "llvm/PassManager.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ManagedStatic.h"
#include <algorithm>
#include <set>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Pass Implementation
//

// Force out-of-line virtual method.
Pass::~Pass() {
  delete Resolver;
}

// Force out-of-line virtual method.
ModulePass::~ModulePass() { }

bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
  return Resolver->getAnalysisToUpdate(AnalysisID, true) != 0;
}

// dumpPassStructure - Implement the -debug-passes=Structure option
void Pass::dumpPassStructure(unsigned Offset) {
  cerr << std::string(Offset*2, ' ') << getPassName() << "\n";
}

// getPassName - Use C++ RTTI to get a SOMEWHAT intelligible name for the pass.
//
const char *Pass::getPassName() const {
  if (const PassInfo *PI = getPassInfo())
    return PI->getPassName();
  return "Unnamed pass: implement Pass::getPassName()";
}

// print - Print out the internal state of the pass.  This is called by Analyze
// to print out the contents of an analysis.  Otherwise it is not necessary to
// implement this method.
//
void Pass::print(std::ostream &O,const Module*) const {
  O << "Pass::print not implemented for pass: '" << getPassName() << "'!\n";
}

// dump - call print(cerr);
void Pass::dump() const {
  print(*cerr.stream(), 0);
}

//===----------------------------------------------------------------------===//
// ImmutablePass Implementation
//
// Force out-of-line virtual method.
ImmutablePass::~ImmutablePass() { }

//===----------------------------------------------------------------------===//
// FunctionPass Implementation
//

// run - On a module, we run this pass by initializing, runOnFunction'ing once
// for every function in the module, then by finalizing.
//
bool FunctionPass::runOnModule(Module &M) {
  bool Changed = doInitialization(M);

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration())      // Passes are not run on external functions!
    Changed |= runOnFunction(*I);

  return Changed | doFinalization(M);
}

// run - On a function, we simply initialize, run the function, then finalize.
//
bool FunctionPass::run(Function &F) {
  if (F.isDeclaration()) return false;// Passes are not run on external functions!

  bool Changed = doInitialization(*F.getParent());
  Changed |= runOnFunction(F);
  return Changed | doFinalization(*F.getParent());
}

//===----------------------------------------------------------------------===//
// BasicBlockPass Implementation
//

// To run this pass on a function, we simply call runOnBasicBlock once for each
// function.
//
bool BasicBlockPass::runOnFunction(Function &F) {
  bool Changed = doInitialization(F);
  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
    Changed |= runOnBasicBlock(*I);
  return Changed | doFinalization(F);
}

// To run directly on the basic block, we initialize, runOnBasicBlock, then
// finalize.
//
bool BasicBlockPass::runPass(BasicBlock &BB) {
  Function &F = *BB.getParent();
  Module &M = *F.getParent();
  bool Changed = doInitialization(M);
  Changed |= doInitialization(F);
  Changed |= runOnBasicBlock(BB);
  Changed |= doFinalization(F);
  Changed |= doFinalization(M);
  return Changed;
}

//===----------------------------------------------------------------------===//
// Pass Registration mechanism
//
namespace {
class PassRegistrar {
  /// PassInfoMap - Keep track of the passinfo object for each registered llvm
  /// pass.
  std::map<intptr_t, PassInfo*> PassInfoMap;

  /// AnalysisGroupInfo - Keep track of information for each analysis group.
  struct AnalysisGroupInfo {
    const PassInfo *DefaultImpl;
    std::set<const PassInfo *> Implementations;
    AnalysisGroupInfo() : DefaultImpl(0) {}
  };

  /// AnalysisGroupInfoMap - Information for each analysis group.
  std::map<const PassInfo *, AnalysisGroupInfo> AnalysisGroupInfoMap;

public:

  const PassInfo *GetPassInfo(intptr_t TI) const {
    std::map<intptr_t, PassInfo*>::const_iterator I = PassInfoMap.find(TI);
    return I != PassInfoMap.end() ? I->second : 0;
  }

  void RegisterPass(PassInfo &PI) {
    bool Inserted =
      PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
    assert(Inserted && "Pass registered multiple times!");
  }

  void UnregisterPass(PassInfo &PI) {
    std::map<intptr_t, PassInfo*>::iterator I =
      PassInfoMap.find(PI.getTypeInfo());
    assert(I != PassInfoMap.end() && "Pass registered but not in map!");

    // Remove pass from the map.
    PassInfoMap.erase(I);
  }

  void EnumerateWith(PassRegistrationListener *L) {
    for (std::map<intptr_t, PassInfo*>::const_iterator I = PassInfoMap.begin(),
         E = PassInfoMap.end(); I != E; ++I)
      L->passEnumerate(I->second);
  }

  /// Analysis Group Mechanisms.
  void RegisterAnalysisGroup(PassInfo *InterfaceInfo,
                             const PassInfo *ImplementationInfo,
                             bool isDefault) {
    AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
    assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
           "Cannot add a pass to the same analysis group more than once!");
    AGI.Implementations.insert(ImplementationInfo);
    if (isDefault) {
      assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 &&
             "Default implementation for analysis group already specified!");
      assert(ImplementationInfo->getNormalCtor() &&
           "Cannot specify pass as default if it does not have a default ctor");
      AGI.DefaultImpl = ImplementationInfo;
      InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
    }
  }
};
}

static std::vector<PassRegistrationListener*> *Listeners = 0;

// FIXME: This should use ManagedStatic to manage the pass registrar.
// Unfortunately, we can't do this, because passes are registered with static
// ctors, and having llvm_shutdown clear this map prevents successful
// ressurection after llvm_shutdown is run.
static PassRegistrar *getPassRegistrar() {
  static PassRegistrar *PassRegistrarObj = 0;
  if (!PassRegistrarObj)
    PassRegistrarObj = new PassRegistrar();
  return PassRegistrarObj;
}

// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass...
const PassInfo *Pass::getPassInfo() const {
  return lookupPassInfo(PassID);
}

const PassInfo *Pass::lookupPassInfo(intptr_t TI) {
  return getPassRegistrar()->GetPassInfo(TI);
}

void RegisterPassBase::registerPass() {
  getPassRegistrar()->RegisterPass(PIObj);

  // Notify any listeners.
  if (Listeners)
    for (std::vector<PassRegistrationListener*>::iterator
           I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
      (*I)->passRegistered(&PIObj);
}

void RegisterPassBase::unregisterPass() {
  getPassRegistrar()->UnregisterPass(PIObj);
}

//===----------------------------------------------------------------------===//
//                  Analysis Group Implementation Code
//===----------------------------------------------------------------------===//

// RegisterAGBase implementation
//
RegisterAGBase::RegisterAGBase(intptr_t InterfaceID,
                               intptr_t PassID, bool isDefault)
  : RegisterPassBase(InterfaceID),
    ImplementationInfo(0), isDefaultImplementation(isDefault) {

  InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(InterfaceID));
  if (InterfaceInfo == 0) {
    // First reference to Interface, register it now.
    registerPass();
    InterfaceInfo = &PIObj;
  }
  assert(PIObj.isAnalysisGroup() &&
         "Trying to join an analysis group that is a normal pass!");

  if (PassID) {
    ImplementationInfo = Pass::lookupPassInfo(PassID);
    assert(ImplementationInfo &&
           "Must register pass before adding to AnalysisGroup!");

    // Make sure we keep track of the fact that the implementation implements
    // the interface.
    PassInfo *IIPI = const_cast<PassInfo*>(ImplementationInfo);
    IIPI->addInterfaceImplemented(InterfaceInfo);

    getPassRegistrar()->RegisterAnalysisGroup(InterfaceInfo, IIPI, isDefault);
  }
}

void RegisterAGBase::setGroupName(const char *Name) {
  assert(InterfaceInfo->getPassName()[0] == 0 && "Interface Name already set!");
  InterfaceInfo->setPassName(Name);
}

//===----------------------------------------------------------------------===//
// PassRegistrationListener implementation
//

// PassRegistrationListener ctor - Add the current object to the list of
// PassRegistrationListeners...
PassRegistrationListener::PassRegistrationListener() {
  if (!Listeners) Listeners = new std::vector<PassRegistrationListener*>();
  Listeners->push_back(this);
}

// dtor - Remove object from list of listeners...
PassRegistrationListener::~PassRegistrationListener() {
  std::vector<PassRegistrationListener*>::iterator I =
    std::find(Listeners->begin(), Listeners->end(), this);
  assert(Listeners && I != Listeners->end() &&
         "PassRegistrationListener not registered!");
  Listeners->erase(I);

  if (Listeners->empty()) {
    delete Listeners;
    Listeners = 0;
  }
}

// enumeratePasses - Iterate over the registered passes, calling the
// passEnumerate callback on each PassInfo object.
//
void PassRegistrationListener::enumeratePasses() {
  getPassRegistrar()->EnumerateWith(this);
}

//===----------------------------------------------------------------------===//
//   AnalysisUsage Class Implementation
//

namespace {
  struct GetCFGOnlyPasses : public PassRegistrationListener {
    std::vector<AnalysisID> &CFGOnlyList;
    GetCFGOnlyPasses(std::vector<AnalysisID> &L) : CFGOnlyList(L) {}

    void passEnumerate(const PassInfo *P) {
      if (P->isCFGOnlyPass())
        CFGOnlyList.push_back(P);
    }
  };
}

// setPreservesCFG - This function should be called to by the pass, iff they do
// not:
//
//  1. Add or remove basic blocks from the function
//  2. Modify terminator instructions in any way.
//
// This function annotates the AnalysisUsage info object to say that analyses
// that only depend on the CFG are preserved by this pass.
//
void AnalysisUsage::setPreservesCFG() {
  // Since this transformation doesn't modify the CFG, it preserves all analyses
  // that only depend on the CFG (like dominators, loop info, etc...)
  GetCFGOnlyPasses(Preserved).enumeratePasses();
}

<|endoftext|>


<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Stock.hxx"
#include "stock/MapStock.hxx"
#include "stock/Class.hxx"
#include "stock/Item.hxx"
#include "system/Error.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "event/SocketEvent.hxx"
#include "event/TimerEvent.hxx"
#include "event/Duration.hxx"
#include "spawn/Interface.hxx"
#include "spawn/Prepared.hxx"
#include "spawn/ChildOptions.hxx"
#include "AllocatorPtr.hxx"
#include "pool/tpool.hxx"
#include "io/Logger.hxx"

#include <assert.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>

struct DelegateArgs {
    const char *executable_path;

    const ChildOptions &options;

    DelegateArgs(const char *_executable_path,
                 const ChildOptions &_options)
        :executable_path(_executable_path), options(_options) {}

    const char *GetStockKey(struct pool &pool) const {
        const char *key = executable_path;

        char options_buffer[16384];
        *options.MakeId(options_buffer) = 0;
        if (*options_buffer != 0)
            key = p_strcat(&pool, key, "|", options_buffer, nullptr);

        return key;
    }
};

class DelegateProcess final : public StockItem {
    const LLogger logger;

    UniqueSocketDescriptor fd;

    SocketEvent event;
    TimerEvent idle_timeout_event;

public:
    explicit DelegateProcess(CreateStockItem c, UniqueSocketDescriptor &&_fd)
        :StockItem(c),
         logger(c.GetStockName()),
         fd(std::move(_fd)),
         event(c.stock.GetEventLoop(), fd.Get(), SocketEvent::READ,
               BIND_THIS_METHOD(SocketEventCallback)),
         idle_timeout_event(c.stock.GetEventLoop(),
                    BIND_THIS_METHOD(OnIdleTimeout))
    {
    }

    ~DelegateProcess() override {
        if (fd.IsDefined())
            event.Delete();
    }

    SocketDescriptor GetSocket() const noexcept {
        return fd;
    }

    /* virtual methods from class StockItem */
    bool Borrow() noexcept override {
        event.Delete();
        idle_timeout_event.Cancel();
        return true;
    }

    bool Release() noexcept override {
        event.Add();
        idle_timeout_event.Add(EventDuration<60>::value);
        return true;
    }

private:
    void SocketEventCallback(unsigned events);
    void OnIdleTimeout() noexcept;
};

class DelegateStock final : StockClass {
    SpawnService &spawn_service;
    StockMap stock;

public:
    explicit DelegateStock(EventLoop &event_loop, SpawnService &_spawn_service)
        :spawn_service(_spawn_service),
         stock(event_loop, *this, 0, 16) {}

    StockMap &GetStock() {
        return stock;
    }

private:
    /* virtual methods from class StockClass */
    void Create(CreateStockItem c, void *info, struct pool &caller_pool,
                CancellablePointer &cancel_ptr) override;
};

/*
 * libevent callback
 *
 */

inline void
DelegateProcess::SocketEventCallback(unsigned)
{
    char buffer;
    ssize_t nbytes = recv(fd.Get(), &buffer, sizeof(buffer), MSG_DONTWAIT);
    if (nbytes < 0)
        logger(2, "error on idle delegate process: ", strerror(errno));
    else if (nbytes > 0)
        logger(2, "unexpected data from idle delegate process");

    InvokeIdleDisconnect();
}

inline void
DelegateProcess::OnIdleTimeout() noexcept
{
    InvokeIdleDisconnect();
}

/*
 * stock class
 *
 */

void
DelegateStock::Create(CreateStockItem c,
                      void *_info,
                      gcc_unused struct pool &caller_pool,
                      gcc_unused CancellablePointer &cancel_ptr)
{
    auto &info = *(DelegateArgs *)_info;

    PreparedChildProcess p;
    p.Append(info.executable_path);

    info.options.CopyTo(p, true, nullptr);

    UniqueSocketDescriptor server_fd, client_fd;
    if (!UniqueSocketDescriptor::CreateSocketPair(AF_LOCAL, SOCK_STREAM, 0,
                                                  server_fd, client_fd))
        throw MakeErrno("socketpair() failed");

    p.SetStdin(std::move(server_fd));

    spawn_service.SpawnChildProcess(info.executable_path,
                                    std::move(p), nullptr);

    auto *process = new DelegateProcess(c, std::move(client_fd));
    process->InvokeCreateSuccess();
}

/*
 * interface
 *
 */

StockMap *
delegate_stock_new(EventLoop &event_loop, SpawnService &spawn_service)
{
    auto *stock = new DelegateStock(event_loop, spawn_service);
    return &stock->GetStock();
}

void
delegate_stock_free(StockMap *_stock)
{
    auto *stock = (DelegateStock *)&_stock->GetClass();
    delete stock;
}

StockItem *
delegate_stock_get(StockMap *delegate_stock,
                   const char *helper,
                   const ChildOptions &options)
{
    const AutoRewindPool auto_rewind(*tpool);
    DelegateArgs args(helper, options);
    return delegate_stock->GetNow(*tpool, args.GetStockKey(*tpool), &args);
}

SocketDescriptor
delegate_stock_item_get(StockItem &item) noexcept
{
    auto *process = (DelegateProcess *)&item;

    return process->GetSocket();
}
<commit_msg>delegate/stock: migrate to class NewSocketEvent<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Stock.hxx"
#include "stock/MapStock.hxx"
#include "stock/Class.hxx"
#include "stock/Item.hxx"
#include "system/Error.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "event/NewSocketEvent.hxx"
#include "event/TimerEvent.hxx"
#include "event/Duration.hxx"
#include "spawn/Interface.hxx"
#include "spawn/Prepared.hxx"
#include "spawn/ChildOptions.hxx"
#include "AllocatorPtr.hxx"
#include "pool/tpool.hxx"
#include "io/Logger.hxx"

#include <assert.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>

struct DelegateArgs {
    const char *executable_path;

    const ChildOptions &options;

    DelegateArgs(const char *_executable_path,
                 const ChildOptions &_options)
        :executable_path(_executable_path), options(_options) {}

    const char *GetStockKey(struct pool &pool) const {
        const char *key = executable_path;

        char options_buffer[16384];
        *options.MakeId(options_buffer) = 0;
        if (*options_buffer != 0)
            key = p_strcat(&pool, key, "|", options_buffer, nullptr);

        return key;
    }
};

class DelegateProcess final : public StockItem {
    const LLogger logger;

    UniqueSocketDescriptor fd;

    NewSocketEvent event;
    TimerEvent idle_timeout_event;

public:
    explicit DelegateProcess(CreateStockItem c, UniqueSocketDescriptor &&_fd)
        :StockItem(c),
         logger(c.GetStockName()),
         fd(std::move(_fd)),
         event(c.stock.GetEventLoop(),
               BIND_THIS_METHOD(SocketEventCallback), fd),
         idle_timeout_event(c.stock.GetEventLoop(),
                    BIND_THIS_METHOD(OnIdleTimeout))
    {
    }

    SocketDescriptor GetSocket() const noexcept {
        return fd;
    }

    /* virtual methods from class StockItem */
    bool Borrow() noexcept override {
        event.Cancel();
        idle_timeout_event.Cancel();
        return true;
    }

    bool Release() noexcept override {
        event.ScheduleRead();
        idle_timeout_event.Add(EventDuration<60>::value);
        return true;
    }

private:
    void SocketEventCallback(unsigned events);
    void OnIdleTimeout() noexcept;
};

class DelegateStock final : StockClass {
    SpawnService &spawn_service;
    StockMap stock;

public:
    explicit DelegateStock(EventLoop &event_loop, SpawnService &_spawn_service)
        :spawn_service(_spawn_service),
         stock(event_loop, *this, 0, 16) {}

    StockMap &GetStock() {
        return stock;
    }

private:
    /* virtual methods from class StockClass */
    void Create(CreateStockItem c, void *info, struct pool &caller_pool,
                CancellablePointer &cancel_ptr) override;
};

/*
 * libevent callback
 *
 */

inline void
DelegateProcess::SocketEventCallback(unsigned)
{
    char buffer;
    ssize_t nbytes = recv(fd.Get(), &buffer, sizeof(buffer), MSG_DONTWAIT);
    if (nbytes < 0)
        logger(2, "error on idle delegate process: ", strerror(errno));
    else if (nbytes > 0)
        logger(2, "unexpected data from idle delegate process");

    InvokeIdleDisconnect();
}

inline void
DelegateProcess::OnIdleTimeout() noexcept
{
    InvokeIdleDisconnect();
}

/*
 * stock class
 *
 */

void
DelegateStock::Create(CreateStockItem c,
                      void *_info,
                      gcc_unused struct pool &caller_pool,
                      gcc_unused CancellablePointer &cancel_ptr)
{
    auto &info = *(DelegateArgs *)_info;

    PreparedChildProcess p;
    p.Append(info.executable_path);

    info.options.CopyTo(p, true, nullptr);

    UniqueSocketDescriptor server_fd, client_fd;
    if (!UniqueSocketDescriptor::CreateSocketPair(AF_LOCAL, SOCK_STREAM, 0,
                                                  server_fd, client_fd))
        throw MakeErrno("socketpair() failed");

    p.SetStdin(std::move(server_fd));

    spawn_service.SpawnChildProcess(info.executable_path,
                                    std::move(p), nullptr);

    auto *process = new DelegateProcess(c, std::move(client_fd));
    process->InvokeCreateSuccess();
}

/*
 * interface
 *
 */

StockMap *
delegate_stock_new(EventLoop &event_loop, SpawnService &spawn_service)
{
    auto *stock = new DelegateStock(event_loop, spawn_service);
    return &stock->GetStock();
}

void
delegate_stock_free(StockMap *_stock)
{
    auto *stock = (DelegateStock *)&_stock->GetClass();
    delete stock;
}

StockItem *
delegate_stock_get(StockMap *delegate_stock,
                   const char *helper,
                   const ChildOptions &options)
{
    const AutoRewindPool auto_rewind(*tpool);
    DelegateArgs args(helper, options);
    return delegate_stock->GetNow(*tpool, args.GetStockKey(*tpool), &args);
}

SocketDescriptor
delegate_stock_item_get(StockItem &item) noexcept
{
    auto *process = (DelegateProcess *)&item;

    return process->GetSocket();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/options2/manage_profile_handler2.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/value_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/gaia_info_update_service.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_info_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/ui/webui/web_ui_util.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_ui.h"
#include "grit/generated_resources.h"

namespace options2 {

ManageProfileHandler::ManageProfileHandler() {
}

ManageProfileHandler::~ManageProfileHandler() {
}

void ManageProfileHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  static OptionsStringResource resources[] = {
    { "manageProfilesNameLabel", IDS_PROFILES_MANAGE_NAME_LABEL },
    { "manageProfilesDuplicateNameError",
        IDS_PROFILES_MANAGE_DUPLICATE_NAME_ERROR },
    { "manageProfilesIconLabel", IDS_PROFILES_MANAGE_ICON_LABEL },
    { "deleteProfileTitle", IDS_PROFILES_DELETE_TITLE },
    { "deleteProfileOK", IDS_PROFILES_DELETE_OK_BUTTON_LABEL },
    { "deleteProfileMessage", IDS_PROFILES_DELETE_MESSAGE },
  };

  RegisterStrings(localized_strings, resources, arraysize(resources));
  RegisterTitle(localized_strings, "manageProfile",
                IDS_PROFILES_MANAGE_TITLE);
}

void ManageProfileHandler::InitializeHandler() {
  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
                 content::NotificationService::AllSources());
}

void ManageProfileHandler::InitializePage() {
  SendProfileNames();
}

void ManageProfileHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback("setProfileNameAndIcon",
      base::Bind(&ManageProfileHandler::SetProfileNameAndIcon,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("deleteProfile",
      base::Bind(&ManageProfileHandler::DeleteProfile,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("requestDefaultProfileIcons",
      base::Bind(&ManageProfileHandler::RequestDefaultProfileIcons,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("requestProfileInfo",
      base::Bind(&ManageProfileHandler::RequestProfileInfo,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("profileIconSelectionChanged",
      base::Bind(&ManageProfileHandler::ProfileIconSelectionChanged,
                 base::Unretained(this)));
}

void ManageProfileHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED) {
    SendProfileNames();
    SendProfileIcons();
  } else {
    OptionsPageUIHandler::Observe(type, source, details);
  }
}

void ManageProfileHandler::RequestDefaultProfileIcons(const ListValue* args) {
  SendProfileIcons();
}

void ManageProfileHandler::SendProfileIcons() {
  ListValue image_url_list;

  // First add the GAIA picture if it's available.
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  Profile* profile = Profile::FromWebUI(web_ui());
  size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
  if (profile_index != std::string::npos) {
    const gfx::Image* icon =
        cache.GetGAIAPictureOfProfileAtIndex(profile_index);
    if (icon) {
      gfx::Image icon2 = profiles::GetAvatarIconForWebUI(*icon, true);
      gaia_picture_url_ = web_ui_util::GetImageDataUrl(icon2);
      image_url_list.Append(Value::CreateStringValue(gaia_picture_url_));
    }
  }

  // Next add the default avatar icons.
  for (size_t i = 0; i < ProfileInfoCache::GetDefaultAvatarIconCount(); i++) {
    std::string url = ProfileInfoCache::GetDefaultAvatarIconUrl(i);
    image_url_list.Append(Value::CreateStringValue(url));
  }

  web_ui()->CallJavascriptFunction(
      "ManageProfileOverlay.receiveDefaultProfileIcons",
      image_url_list);
}

void ManageProfileHandler::SendProfileNames() {
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  DictionaryValue profile_name_dict;
  for (size_t i = 0, e = cache.GetNumberOfProfiles(); i < e; ++i)
    profile_name_dict.SetBoolean(UTF16ToUTF8(cache.GetNameOfProfileAtIndex(i)),
                                 true);

  web_ui()->CallJavascriptFunction("ManageProfileOverlay.receiveProfileNames",
                                   profile_name_dict);
}

void ManageProfileHandler::SetProfileNameAndIcon(const ListValue* args) {
  DCHECK(args);

  Value* file_path_value;
  FilePath profile_file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &profile_file_path))
    return;

  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  size_t profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
  if (profile_index == std::string::npos)
    return;

  string16 new_profile_name;
  if (!args->GetString(1, &new_profile_name))
    return;

  if (new_profile_name == cache.GetGAIANameOfProfileAtIndex(profile_index)) {
    // Set the profile to use the GAIA name as the profile name. Note, this
    // is a little weird if the user typed their GAIA name manually but
    // it's not a big deal.
    cache.SetIsUsingGAIANameOfProfileAtIndex(profile_index, true);
    // Using the GAIA name as the profile name can invalidate the profile index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;
  } else {
    cache.SetNameOfProfileAtIndex(profile_index, new_profile_name);
    // Changing the profile name can invalidate the profile index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;

    cache.SetIsUsingGAIANameOfProfileAtIndex(profile_index, false);
    // Unsetting the GAIA name as the profile name can invalidate the profile
    // index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;
  }

  std::string icon_url;
  if (!args->GetString(2, &icon_url))
    return;

  // Metrics logging variable.
  bool previously_using_gaia_icon =
      cache.IsUsingGAIANameOfProfileAtIndex(profile_index);

  size_t new_icon_index;
  if (icon_url == gaia_picture_url_) {
    cache.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index, true);
    if (!previously_using_gaia_icon) {
      // Only log if they changed to the GAIA photo.
      // Selection of GAIA photo as avatar is logged as part of the function
      // below.
      ProfileMetrics::LogProfileSwitchGaia(ProfileMetrics::GAIA_OPT_IN);
    }
  } else if (cache.IsDefaultAvatarIconUrl(icon_url, &new_icon_index)) {
    ProfileMetrics::LogProfileAvatarSelection(new_icon_index);
    cache.SetAvatarIconOfProfileAtIndex(profile_index, new_icon_index);
    cache.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index, false);
  }

  ProfileMetrics::LogProfileUpdate(profile_file_path);
}

void ManageProfileHandler::DeleteProfile(const ListValue* args) {
  DCHECK(args);
  // This handler could have been called in managed mode, for example because
  // the user fiddled with the web inspector. Silently return in this case.
  if (!ProfileManager::IsMultipleProfilesEnabled())
    return;

  ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::PROFILE_DELETED);

  Value* file_path_value;
  FilePath profile_file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &profile_file_path))
    return;

  g_browser_process->profile_manager()->ScheduleProfileForDeletion(
      profile_file_path);
}

void ManageProfileHandler::RequestProfileInfo(const ListValue* args) {
  DCHECK(args);

  Value* index_value;
  double index_double;
  if (!args->Get(0, &index_value) || !index_value->GetAsDouble(&index_double))
    return;

  int index = static_cast<int>(index_double);
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  int profile_count = cache.GetNumberOfProfiles();
  if (index < 0 && index >= profile_count)
    return;

  FilePath profile_path = cache.GetPathOfProfileAtIndex(index);
  FilePath current_profile_path = Profile::FromWebUI(web_ui())->GetPath();
  bool is_current_profile =
      profile_path == Profile::FromWebUI(web_ui())->GetPath();

  DictionaryValue profile_value;
  profile_value.SetString("name", cache.GetNameOfProfileAtIndex(index));
  profile_value.Set("filePath", base::CreateFilePathValue(profile_path));
  profile_value.SetBoolean("isCurrentProfile", is_current_profile);

  bool is_gaia_picture =
      cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
      cache.GetGAIAPictureOfProfileAtIndex(index);
  if (is_gaia_picture) {
    gfx::Image icon = profiles::GetAvatarIconForWebUI(
        cache.GetAvatarIconOfProfileAtIndex(index), true);
    profile_value.SetString("iconURL", web_ui_util::GetImageDataUrl(icon));
  } else {
    size_t icon_index = cache.GetAvatarIconIndexOfProfileAtIndex(index);
    profile_value.SetString("iconURL",
                             cache.GetDefaultAvatarIconUrl(icon_index));
  }

  web_ui()->CallJavascriptFunction("ManageProfileOverlay.setProfileInfo",
                                   profile_value);

  // Ensure that we have the most up to date GAIA picture.
  if (is_current_profile) {
    GAIAInfoUpdateService* service =
        Profile::FromWebUI(web_ui())->GetGAIAInfoUpdateService();
    if (service)
      service->Update();
  }
}

void ManageProfileHandler::ProfileIconSelectionChanged(
    const base::ListValue* args) {
  DCHECK(args);

  Value* file_path_value;
  FilePath file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &file_path)) {
    return;
  }

  // Currently this only supports editing the current profile's info.
  if (file_path != Profile::FromWebUI(web_ui())->GetPath())
    return;

  std::string icon_url;
  if (!args->GetString(1, &icon_url))
    return;

  if (icon_url != gaia_picture_url_)
    return;

  // If the selection is the GAIA picture then also show the GAIA name in the
  // text field.
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  size_t i = cache.GetIndexOfProfileWithPath(file_path);
  if (i == std::string::npos)
    return;
  string16 gaia_name = cache.GetGAIANameOfProfileAtIndex(i);
  if (gaia_name.empty())
    return;

  StringValue gaia_name_value(gaia_name);
  web_ui()->CallJavascriptFunction("ManageProfileOverlay.setProfileName",
                                   gaia_name_value);
}

}  // namespace options2
<commit_msg>Making the personal options handler for the new uber settings page set profile avatar/name in profile prefs instead of profile info cache. This is simply adding code to the options2 handler that I put in the original options handler. The original bag is crbug.com/87658.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/options2/manage_profile_handler2.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/value_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/gaia_info_update_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_info_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/ui/webui/web_ui_util.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_ui.h"
#include "grit/generated_resources.h"

namespace options2 {

ManageProfileHandler::ManageProfileHandler() {
}

ManageProfileHandler::~ManageProfileHandler() {
}

void ManageProfileHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  static OptionsStringResource resources[] = {
    { "manageProfilesNameLabel", IDS_PROFILES_MANAGE_NAME_LABEL },
    { "manageProfilesDuplicateNameError",
        IDS_PROFILES_MANAGE_DUPLICATE_NAME_ERROR },
    { "manageProfilesIconLabel", IDS_PROFILES_MANAGE_ICON_LABEL },
    { "deleteProfileTitle", IDS_PROFILES_DELETE_TITLE },
    { "deleteProfileOK", IDS_PROFILES_DELETE_OK_BUTTON_LABEL },
    { "deleteProfileMessage", IDS_PROFILES_DELETE_MESSAGE },
  };

  RegisterStrings(localized_strings, resources, arraysize(resources));
  RegisterTitle(localized_strings, "manageProfile",
                IDS_PROFILES_MANAGE_TITLE);
}

void ManageProfileHandler::InitializeHandler() {
  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
                 content::NotificationService::AllSources());
}

void ManageProfileHandler::InitializePage() {
  SendProfileNames();
}

void ManageProfileHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback("setProfileNameAndIcon",
      base::Bind(&ManageProfileHandler::SetProfileNameAndIcon,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("deleteProfile",
      base::Bind(&ManageProfileHandler::DeleteProfile,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("requestDefaultProfileIcons",
      base::Bind(&ManageProfileHandler::RequestDefaultProfileIcons,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("requestProfileInfo",
      base::Bind(&ManageProfileHandler::RequestProfileInfo,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("profileIconSelectionChanged",
      base::Bind(&ManageProfileHandler::ProfileIconSelectionChanged,
                 base::Unretained(this)));
}

void ManageProfileHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED) {
    SendProfileNames();
    SendProfileIcons();
  } else {
    OptionsPageUIHandler::Observe(type, source, details);
  }
}

void ManageProfileHandler::RequestDefaultProfileIcons(const ListValue* args) {
  SendProfileIcons();
}

void ManageProfileHandler::SendProfileIcons() {
  ListValue image_url_list;

  // First add the GAIA picture if it's available.
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  Profile* profile = Profile::FromWebUI(web_ui());
  size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
  if (profile_index != std::string::npos) {
    const gfx::Image* icon =
        cache.GetGAIAPictureOfProfileAtIndex(profile_index);
    if (icon) {
      gfx::Image icon2 = profiles::GetAvatarIconForWebUI(*icon, true);
      gaia_picture_url_ = web_ui_util::GetImageDataUrl(icon2);
      image_url_list.Append(Value::CreateStringValue(gaia_picture_url_));
    }
  }

  // Next add the default avatar icons.
  for (size_t i = 0; i < ProfileInfoCache::GetDefaultAvatarIconCount(); i++) {
    std::string url = ProfileInfoCache::GetDefaultAvatarIconUrl(i);
    image_url_list.Append(Value::CreateStringValue(url));
  }

  web_ui()->CallJavascriptFunction(
      "ManageProfileOverlay.receiveDefaultProfileIcons",
      image_url_list);
}

void ManageProfileHandler::SendProfileNames() {
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  DictionaryValue profile_name_dict;
  for (size_t i = 0, e = cache.GetNumberOfProfiles(); i < e; ++i)
    profile_name_dict.SetBoolean(UTF16ToUTF8(cache.GetNameOfProfileAtIndex(i)),
                                 true);

  web_ui()->CallJavascriptFunction("ManageProfileOverlay.receiveProfileNames",
                                   profile_name_dict);
}

void ManageProfileHandler::SetProfileNameAndIcon(const ListValue* args) {
  DCHECK(args);

  Value* file_path_value;
  FilePath profile_file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &profile_file_path))
    return;

  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  size_t profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
  if (profile_index == std::string::npos)
    return;

  Profile* profile =
      g_browser_process->profile_manager()->GetProfile(profile_file_path);
  if (!profile)
    return;

  string16 new_profile_name;
  if (!args->GetString(1, &new_profile_name))
    return;

  if (new_profile_name == cache.GetGAIANameOfProfileAtIndex(profile_index)) {
    // Set the profile to use the GAIA name as the profile name. Note, this
    // is a little weird if the user typed their GAIA name manually but
    // it's not a big deal.
    cache.SetIsUsingGAIANameOfProfileAtIndex(profile_index, true);
    // Using the GAIA name as the profile name can invalidate the profile index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;
  } else {
    PrefService* pref_service = profile->GetPrefs();
    // Updating the profile preference will cause the cache to be updated for
    // this preference.
    pref_service->SetString(prefs::kProfileName, UTF16ToUTF8(new_profile_name));

    // Changing the profile name can invalidate the profile index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;

    cache.SetIsUsingGAIANameOfProfileAtIndex(profile_index, false);
    // Unsetting the GAIA name as the profile name can invalidate the profile
    // index.
    profile_index = cache.GetIndexOfProfileWithPath(profile_file_path);
    if (profile_index == std::string::npos)
      return;
  }

  std::string icon_url;
  if (!args->GetString(2, &icon_url))
    return;

  // Metrics logging variable.
  bool previously_using_gaia_icon =
      cache.IsUsingGAIANameOfProfileAtIndex(profile_index);

  size_t new_icon_index;
  if (icon_url == gaia_picture_url_) {
    cache.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index, true);
    if (!previously_using_gaia_icon) {
      // Only log if they changed to the GAIA photo.
      // Selection of GAIA photo as avatar is logged as part of the function
      // below.
      ProfileMetrics::LogProfileSwitchGaia(ProfileMetrics::GAIA_OPT_IN);
    }
  } else if (cache.IsDefaultAvatarIconUrl(icon_url, &new_icon_index)) {
    ProfileMetrics::LogProfileAvatarSelection(new_icon_index);
    PrefService* pref_service = profile->GetPrefs();
    // Updating the profile preference will cause the cache to be updated for
    // this preference.
    pref_service->SetInteger(prefs::kProfileAvatarIndex, new_icon_index);
    cache.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index, false);
  }

  ProfileMetrics::LogProfileUpdate(profile_file_path);
}

void ManageProfileHandler::DeleteProfile(const ListValue* args) {
  DCHECK(args);
  // This handler could have been called in managed mode, for example because
  // the user fiddled with the web inspector. Silently return in this case.
  if (!ProfileManager::IsMultipleProfilesEnabled())
    return;

  ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::PROFILE_DELETED);

  Value* file_path_value;
  FilePath profile_file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &profile_file_path))
    return;

  g_browser_process->profile_manager()->ScheduleProfileForDeletion(
      profile_file_path);
}

void ManageProfileHandler::RequestProfileInfo(const ListValue* args) {
  DCHECK(args);

  Value* index_value;
  double index_double;
  if (!args->Get(0, &index_value) || !index_value->GetAsDouble(&index_double))
    return;

  int index = static_cast<int>(index_double);
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  int profile_count = cache.GetNumberOfProfiles();
  if (index < 0 && index >= profile_count)
    return;

  FilePath profile_path = cache.GetPathOfProfileAtIndex(index);
  FilePath current_profile_path = Profile::FromWebUI(web_ui())->GetPath();
  bool is_current_profile =
      profile_path == Profile::FromWebUI(web_ui())->GetPath();

  DictionaryValue profile_value;
  profile_value.SetString("name", cache.GetNameOfProfileAtIndex(index));
  profile_value.Set("filePath", base::CreateFilePathValue(profile_path));
  profile_value.SetBoolean("isCurrentProfile", is_current_profile);

  bool is_gaia_picture =
      cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
      cache.GetGAIAPictureOfProfileAtIndex(index);
  if (is_gaia_picture) {
    gfx::Image icon = profiles::GetAvatarIconForWebUI(
        cache.GetAvatarIconOfProfileAtIndex(index), true);
    profile_value.SetString("iconURL", web_ui_util::GetImageDataUrl(icon));
  } else {
    size_t icon_index = cache.GetAvatarIconIndexOfProfileAtIndex(index);
    profile_value.SetString("iconURL",
                             cache.GetDefaultAvatarIconUrl(icon_index));
  }

  web_ui()->CallJavascriptFunction("ManageProfileOverlay.setProfileInfo",
                                   profile_value);

  // Ensure that we have the most up to date GAIA picture.
  if (is_current_profile) {
    GAIAInfoUpdateService* service =
        Profile::FromWebUI(web_ui())->GetGAIAInfoUpdateService();
    if (service)
      service->Update();
  }
}

void ManageProfileHandler::ProfileIconSelectionChanged(
    const base::ListValue* args) {
  DCHECK(args);

  Value* file_path_value;
  FilePath file_path;
  if (!args->Get(0, &file_path_value) ||
      !base::GetValueAsFilePath(*file_path_value, &file_path)) {
    return;
  }

  // Currently this only supports editing the current profile's info.
  if (file_path != Profile::FromWebUI(web_ui())->GetPath())
    return;

  std::string icon_url;
  if (!args->GetString(1, &icon_url))
    return;

  if (icon_url != gaia_picture_url_)
    return;

  // If the selection is the GAIA picture then also show the GAIA name in the
  // text field.
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  size_t i = cache.GetIndexOfProfileWithPath(file_path);
  if (i == std::string::npos)
    return;
  string16 gaia_name = cache.GetGAIANameOfProfileAtIndex(i);
  if (gaia_name.empty())
    return;

  StringValue gaia_name_value(gaia_name);
  web_ui()->CallJavascriptFunction("ManageProfileOverlay.setProfileName",
                                   gaia_name_value);
}

}  // namespace options2
<|endoftext|>