<commit_before>#include "codesyntaxhighlighter.h"
#include "languagedefinationxmlparser.h"

LanguageManager* LanguageManager::instance = NULL;

LanguageManager::LanguageManager()
{
}

LanguageManager::~LanguageManager()
{
    for (auto lang : languages)
        delete lang.second;
}

void LanguageManager::addLanguage(const std::string &name, char *content)
{
    LanguageDefinationXmlParser ldxp;
    Language *lan = ldxp.startParse(name.c_str(), content);
    lan->compileLanguage();
    languages[name] = lan;
//    lan->printDebugInfo();
}

Language* LanguageManager::getLanguage(const std::string &name)
{
    std::string realLan = name;
    if(name=="c")
        realLan = "cpp";
    else if(name=="html")
        realLan = "xml";
    else if(name=="js")
        realLan = "javascript";
    auto it = languages.find(realLan);
    if(it==languages.end())
        return NULL;
    return (*it).second;
}

LanguageManager* LanguageManager::getInstance()
{
    if(!instance)
        instance = new LanguageManager();
    return instance;
}

CodeSyntaxHighlighter::CodeSyntaxHighlighter()
{
    relevance = 0;
    top = NULL;
}

const std::string& CodeSyntaxHighlighter::highlight(const char *name, int len, const char *code, int codeLen)
{
    LanguageManager *lanManger = LanguageManager::getInstance();
    Language *targetLanguage = lanManger->getLanguage(std::string(name, len));
    if(!targetLanguage){
        result = escape(code, codeLen);
        return result;
    }
    return highlight(targetLanguage, code, codeLen);
}

const std::string& CodeSyntaxHighlighter::highlight(Language *lan, const char *code, int len)
{
    result.clear();
    modeBuffer.clear();
    while(!parentStack.empty())
        parentStack.pop();
    top = NULL;
    this->lan = lan;
    relevance = 0;
    int index = 0;
    while(true){
        FindResult fr;
        if(top){
            top->getTerminatorsRe().setLastIndex(index);
            fr = top->getTerminatorsRe().exec(code, len);
        } else {
            lan->getTerminatorsRe().setLastIndex(index);
            fr = lan->getTerminatorsRe().exec(code, len);
        }
        if(!fr.isValid())
            break;
        std::string match(code+fr.start, fr.end-fr.start);
        int count = processLexem(std::string(code+index, fr.start-index), &match);
        index = fr.start+count;
    }
    std::string left(code+index, len-index);
    processLexem(left);
    while(!parentStack.empty()){
        result.append("");
        parentStack.pop();
    }
//    printf("%s\n", result.c_str());
    return result;
}

int CodeSyntaxHighlighter::processLexem(const std::string &subCode, const std::string *matchCode)
{
//    printf("subCode: %s\n", subCode.c_str());
//    printf("matchCode: %s\n", matchCode->c_str());
//    return 0;
    modeBuffer += subCode;
    if(matchCode==NULL){
        result += processBuffer();
        return 0;
    }
    Contain* con = NULL;
    if(top){
        con = top->findMatchedContain(*matchCode);
        if(!con && top->isRefLanguageContains())
            con = lan->findMatchedContain(*matchCode);
    } else {
        con = lan->findMatchedContain(*matchCode);
    }
    if(con){
        result += processBuffer();
        processMatch(con, *matchCode);
        return con->isReturnBegin() ? 0 : matchCode->length();
    }

    Contain *endContain = findEndContain(top, *matchCode);
    if(endContain){
        if(!(endContain->isReturnEnd()||endContain->isExcludeEnd())){
            modeBuffer += *matchCode;
        }
        result += processBuffer();
        while(top!=endContain->getParent() && top){
            if(top->isShowClassName())
                result += "";
            if(!parentStack.empty()){
                top = parentStack.top();
                parentStack.pop();
            } else {
                top = NULL;
            }
        }
//        if(parentStack.empty())
//            top = NULL;
        if(endContain->isExcludeEnd()){
            result += escape(matchCode->c_str(), matchCode->length());
        }
        modeBuffer.clear();
        if(endContain->getStarts())
            processMatch(endContain->getStarts(), "");
        return endContain->isReturnEnd() ? 0 : matchCode->length();
    }
    modeBuffer += *matchCode;
    return matchCode->length()>0 ? matchCode->length() : 1;
}

std::string CodeSyntaxHighlighter::processBuffer()
{
    //language no sub language
    if(top)
        return top->isHaveSubLanguage() ? processSubLanguage(top) : processKeywords(top);
    else
        return processKeywords();
}

std::string CodeSyntaxHighlighter::processKeywords()
{
    std::string buffer = escape(modeBuffer.c_str(), modeBuffer.length());
    if(lan->getKeywords().empty())
        return buffer;
    std::string keywordResult;
    int lastIndex = 0;
    lan->getLexemsRe().setLastIndex(0);
    FindResult fr = lan->getLexemsRe().exec(buffer.c_str(), buffer.length());
    while(fr.isValid()){
        keywordResult.append(buffer.substr(lastIndex, fr.start-lastIndex));
        std::string keyword = buffer.substr(fr.start, fr.end-fr.start);
        int km = keywordMatch(keyword);
        if(km!=Keywords::NotFound){
            keywordResult.append("")
                    .append(keyword)
                    .append("");
        } else {
            keywordResult.append(keyword);
        }
        lastIndex = lan->getLexemsRe().getLastIndex();
        fr = lan->getLexemsRe().exec(buffer.c_str(), buffer.length());
    }
    return keywordResult + buffer.substr(lastIndex);
}

std::string CodeSyntaxHighlighter::processKeywords(Contain *contain)
{
    std::string buffer = escape(modeBuffer.c_str(), modeBuffer.length());
    if(contain->getKeywords().empty()&&!contain->isRefLanguageKeywords())
        return buffer;
    std::string keywordResult;
    int lastIndex = 0;
    contain->getLexemsRe().setLastIndex(0);
    FindResult fr = contain->getLexemsRe().exec(buffer.c_str(), buffer.length());
    while(fr.isValid()){
        keywordResult.append(buffer.substr(lastIndex, fr.start-lastIndex));
        std::string keyword = buffer.substr(fr.start, fr.end-fr.start);
        int km = keywordMatch(keyword, contain);
        if(km!=Keywords::NotFound){
            keywordResult.append("")
                    .append(keyword)
                    .append("");
        } else {
            keywordResult.append(keyword);
        }
        lastIndex = contain->getLexemsRe().getLastIndex();
        fr = contain->getLexemsRe().exec(buffer.c_str(), buffer.length());
    }
    return keywordResult + buffer.substr(lastIndex);
}

std::string CodeSyntaxHighlighter::processSubLanguage(Contain *top)
{
    CodeSyntaxHighlighter *subHighlighter = new CodeSyntaxHighlighter;
    LanguageManager *languageManager = LanguageManager::getInstance();
    Language* sub = languageManager->getLanguage(top->getSubLanguage());
    if(!sub)
        return escape(modeBuffer.c_str(), modeBuffer.length());
    std::string r = "getSubLanguage()+"\">";
    r += subHighlighter->highlight(sub, modeBuffer.c_str(), modeBuffer.length());
    r += "";
    delete subHighlighter;
    return r;
}

void CodeSyntaxHighlighter::processMatch(Contain *contain, const std::string &match)
{
    std::string markup;
    if(contain->isShowClassName())
        markup.append("getRealName()).append("\">");
    if(contain->isReturnBegin()){
        result += markup;
        modeBuffer.clear();
    } else if (contain->isExcludeBegin()){
        result += escape(match.c_str(), match.length()) + markup;
        modeBuffer.clear();
    } else {
        result += markup;
        modeBuffer = match;
    }
    //TODO: top = Object.create(mode, {parent: {value: top}});
//    parentStack.push(contain);
    if(top){
        contain->setParent(top);
        parentStack.push(top);
    }
    top = contain;
    relevance += contain->getRelevance();
}

int CodeSyntaxHighlighter::keywordMatch(const std::string &match, Contain *contain)
{
    std::string matchStr(match);
    if(!lan->isCaseSensitive()){//to lower case if not case sensitive
        for(unsigned int i=0;i<match.length(); i++){
            matchStr[i]=tolower(match[i]);
        }
    }
    return (contain&&!contain->isRefLanguageKeywords()) ? contain->matchKeyword(matchStr) : lan->matchKeyword(matchStr);
}

Contain* CodeSyntaxHighlighter::findEndContain(Contain *contain, const std::string &match)
{
    if(!contain)
        return NULL;
    if(!contain->getEnd().empty() && contain->getEndRe().test(match.c_str(), match.length())){
        return contain;
    }
    if(contain->isEndWithParent()){
        return findEndContain(contain->getParent(), match);
    }
    return NULL;
}

std::string CodeSyntaxHighlighter::escape(const char* src, int len)
{
    std::string result;
    if(len==0)
        return result;
    result.resize(len*2);
    result.resize(0);
    int index=0;
    for(int i=0; i<len; i++){
        if(src[i]=='&'){
            result.append(src+index, i-index);
            result.append("&");
            index = i+1;
        } else if(src[i]=='<'){
            result.append(src+index, i-index);
            result.append("<");
            index = i+1;
        } else if(src[i]=='>'){
            result.append(src+index, i-index);
            result.append(">");
            index = i+1;
        }
    }
    if(len>index)
        result.append(src+index, len-index);
    return result;
}
<commit_msg>using std::transform instead of loop<commit_after>#include "codesyntaxhighlighter.h"
#include "languagedefinationxmlparser.h"

LanguageManager* LanguageManager::instance = NULL;

LanguageManager::LanguageManager()
{
}

LanguageManager::~LanguageManager()
{
    for (auto lang : languages)
        delete lang.second;
}

void LanguageManager::addLanguage(const std::string &name, char *content)
{
    LanguageDefinationXmlParser ldxp;
    Language *lan = ldxp.startParse(name.c_str(), content);
    lan->compileLanguage();
    languages[name] = lan;
//    lan->printDebugInfo();
}

Language* LanguageManager::getLanguage(const std::string &name)
{
    std::string realLan = name;
    if(name=="c")
        realLan = "cpp";
    else if(name=="html")
        realLan = "xml";
    else if(name=="js")
        realLan = "javascript";
    auto it = languages.find(realLan);
    if(it==languages.end())
        return NULL;
    return (*it).second;
}

LanguageManager* LanguageManager::getInstance()
{
    if(!instance)
        instance = new LanguageManager();
    return instance;
}

CodeSyntaxHighlighter::CodeSyntaxHighlighter()
{
    relevance = 0;
    top = NULL;
}

const std::string& CodeSyntaxHighlighter::highlight(const char *name, int len, const char *code, int codeLen)
{
    LanguageManager *lanManger = LanguageManager::getInstance();
    Language *targetLanguage = lanManger->getLanguage(std::string(name, len));
    if(!targetLanguage){
        result = escape(code, codeLen);
        return result;
    }
    return highlight(targetLanguage, code, codeLen);
}

const std::string& CodeSyntaxHighlighter::highlight(Language *lan, const char *code, int len)
{
    result.clear();
    modeBuffer.clear();
    while(!parentStack.empty())
        parentStack.pop();
    top = NULL;
    this->lan = lan;
    relevance = 0;
    int index = 0;
    while(true){
        FindResult fr;
        if(top){
            top->getTerminatorsRe().setLastIndex(index);
            fr = top->getTerminatorsRe().exec(code, len);
        } else {
            lan->getTerminatorsRe().setLastIndex(index);
            fr = lan->getTerminatorsRe().exec(code, len);
        }
        if(!fr.isValid())
            break;
        std::string match(code+fr.start, fr.end-fr.start);
        int count = processLexem(std::string(code+index, fr.start-index), &match);
        index = fr.start+count;
    }
    std::string left(code+index, len-index);
    processLexem(left);
    while(!parentStack.empty()){
        result.append("");
        parentStack.pop();
    }
//    printf("%s\n", result.c_str());
    return result;
}

int CodeSyntaxHighlighter::processLexem(const std::string &subCode, const std::string *matchCode)
{
//    printf("subCode: %s\n", subCode.c_str());
//    printf("matchCode: %s\n", matchCode->c_str());
//    return 0;
    modeBuffer += subCode;
    if(matchCode==NULL){
        result += processBuffer();
        return 0;
    }
    Contain* con = NULL;
    if(top){
        con = top->findMatchedContain(*matchCode);
        if(!con && top->isRefLanguageContains())
            con = lan->findMatchedContain(*matchCode);
    } else {
        con = lan->findMatchedContain(*matchCode);
    }
    if(con){
        result += processBuffer();
        processMatch(con, *matchCode);
        return con->isReturnBegin() ? 0 : matchCode->length();
    }

    Contain *endContain = findEndContain(top, *matchCode);
    if(endContain){
        if(!(endContain->isReturnEnd()||endContain->isExcludeEnd())){
            modeBuffer += *matchCode;
        }
        result += processBuffer();
        while(top!=endContain->getParent() && top){
            if(top->isShowClassName())
                result += "";
            if(!parentStack.empty()){
                top = parentStack.top();
                parentStack.pop();
            } else {
                top = NULL;
            }
        }
//        if(parentStack.empty())
//            top = NULL;
        if(endContain->isExcludeEnd()){
            result += escape(matchCode->c_str(), matchCode->length());
        }
        modeBuffer.clear();
        if(endContain->getStarts())
            processMatch(endContain->getStarts(), "");
        return endContain->isReturnEnd() ? 0 : matchCode->length();
    }
    modeBuffer += *matchCode;
    return matchCode->length()>0 ? matchCode->length() : 1;
}

std::string CodeSyntaxHighlighter::processBuffer()
{
    //language no sub language
    if(top)
        return top->isHaveSubLanguage() ? processSubLanguage(top) : processKeywords(top);
    else
        return processKeywords();
}

std::string CodeSyntaxHighlighter::processKeywords()
{
    std::string buffer = escape(modeBuffer.c_str(), modeBuffer.length());
    if(lan->getKeywords().empty())
        return buffer;
    std::string keywordResult;
    int lastIndex = 0;
    lan->getLexemsRe().setLastIndex(0);
    FindResult fr = lan->getLexemsRe().exec(buffer.c_str(), buffer.length());
    while(fr.isValid()){
        keywordResult.append(buffer.substr(lastIndex, fr.start-lastIndex));
        std::string keyword = buffer.substr(fr.start, fr.end-fr.start);
        int km = keywordMatch(keyword);
        if(km!=Keywords::NotFound){
            keywordResult.append("")
                    .append(keyword)
                    .append("");
        } else {
            keywordResult.append(keyword);
        }
        lastIndex = lan->getLexemsRe().getLastIndex();
        fr = lan->getLexemsRe().exec(buffer.c_str(), buffer.length());
    }
    return keywordResult + buffer.substr(lastIndex);
}

std::string CodeSyntaxHighlighter::processKeywords(Contain *contain)
{
    std::string buffer = escape(modeBuffer.c_str(), modeBuffer.length());
    if(contain->getKeywords().empty()&&!contain->isRefLanguageKeywords())
        return buffer;
    std::string keywordResult;
    int lastIndex = 0;
    contain->getLexemsRe().setLastIndex(0);
    FindResult fr = contain->getLexemsRe().exec(buffer.c_str(), buffer.length());
    while(fr.isValid()){
        keywordResult.append(buffer.substr(lastIndex, fr.start-lastIndex));
        std::string keyword = buffer.substr(fr.start, fr.end-fr.start);
        int km = keywordMatch(keyword, contain);
        if(km!=Keywords::NotFound){
            keywordResult.append("")
                    .append(keyword)
                    .append("");
        } else {
            keywordResult.append(keyword);
        }
        lastIndex = contain->getLexemsRe().getLastIndex();
        fr = contain->getLexemsRe().exec(buffer.c_str(), buffer.length());
    }
    return keywordResult + buffer.substr(lastIndex);
}

std::string CodeSyntaxHighlighter::processSubLanguage(Contain *top)
{
    CodeSyntaxHighlighter *subHighlighter = new CodeSyntaxHighlighter;
    LanguageManager *languageManager = LanguageManager::getInstance();
    Language* sub = languageManager->getLanguage(top->getSubLanguage());
    if(!sub)
        return escape(modeBuffer.c_str(), modeBuffer.length());
    std::string r = "getSubLanguage()+"\">";
    r += subHighlighter->highlight(sub, modeBuffer.c_str(), modeBuffer.length());
    r += "";
    delete subHighlighter;
    return r;
}

void CodeSyntaxHighlighter::processMatch(Contain *contain, const std::string &match)
{
    std::string markup;
    if(contain->isShowClassName())
        markup.append("getRealName()).append("\">");
    if(contain->isReturnBegin()){
        result += markup;
        modeBuffer.clear();
    } else if (contain->isExcludeBegin()){
        result += escape(match.c_str(), match.length()) + markup;
        modeBuffer.clear();
    } else {
        result += markup;
        modeBuffer = match;
    }
    //TODO: top = Object.create(mode, {parent: {value: top}});
//    parentStack.push(contain);
    if(top){
        contain->setParent(top);
        parentStack.push(top);
    }
    top = contain;
    relevance += contain->getRelevance();
}

int CodeSyntaxHighlighter::keywordMatch(const std::string &match, Contain *contain)
{
    std::string matchStr(match);
    if(!lan->isCaseSensitive()){//to lower case if not case sensitive
        std::transform(matchStr.begin(), matchStr.end(), matchStr.begin(), ::tolower);
    }
    return (contain&&!contain->isRefLanguageKeywords()) ? contain->matchKeyword(matchStr) : lan->matchKeyword(matchStr);
}

Contain* CodeSyntaxHighlighter::findEndContain(Contain *contain, const std::string &match)
{
    if(!contain)
        return NULL;
    if(!contain->getEnd().empty() && contain->getEndRe().test(match.c_str(), match.length())){
        return contain;
    }
    if(contain->isEndWithParent()){
        return findEndContain(contain->getParent(), match);
    }
    return NULL;
}

std::string CodeSyntaxHighlighter::escape(const char* src, int len)
{
    std::string result;
    if(len==0)
        return result;
    result.resize(len*2);
    result.resize(0);
    int index=0;
    for(int i=0; i<len; i++){
        if(src[i]=='&'){
            result.append(src+index, i-index);
            result.append("&");
            index = i+1;
        } else if(src[i]=='<'){
            result.append(src+index, i-index);
            result.append("<");
            index = i+1;
        } else if(src[i]=='>'){
            result.append(src+index, i-index);
            result.append(">");
            index = i+1;
        }
    }
    if(len>index)
        result.append(src+index, len-index);
    return result;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Embedded Framework 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 "client_handler.h"
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "atom.h"
#include <stdlib.h>
#include <gtk/gtk.h>

using namespace std;

ClientHandler::ClientHandler() :
    m_MainHwnd(NULL), m_BrowserHwnd(NULL) {
}

ClientHandler::~ClientHandler() {
}

bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
    CefProcessId source_process, CefRefPtr<CefProcessMessage> message) {
  string name = message->GetName().ToString();
  if (name == "showDevTools") {
    string devtools_url = browser->GetHost()->GetDevToolsURL(true);
    if (!devtools_url.empty())
      browser->GetMainFrame()->ExecuteJavaScript(
          "window.open('" + devtools_url + "');", "about:blank", 0);
  } else
    return false;

  return true;
}

void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  AutoLock lock_scope(this);
  if (!m_Browser.get()) {
    // We need to keep the main child window, but not popup windows
    m_Browser = browser;
    m_BrowserId = browser->GetIdentifier();
  }
}

bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier()) {
    // Since the main window contains the browser window, we need to close
    // the parent window instead of the browser window.
    CloseMainWindow();

    // Return true here so that we can skip closing the browser window
    // in this pass. (It will be destroyed due to the call to close
    // the parent above.)
    return true;
  }

  // A popup browser window is not contained in another window, so we can let
  // these windows close by themselves.
  return false;
}

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  // Free the browser pointer so that the browser can be destroyed
  if (m_BrowserId == browser->GetIdentifier())
    m_Browser = NULL;
}

void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame) {
  REQUIRE_UI_THREAD();

}

void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, int httpStatusCode) {
  REQUIRE_UI_THREAD();

}

bool ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& failedUrl,
    CefString& errorText) {
  REQUIRE_UI_THREAD();

  if (errorCode == ERR_CACHE_MISS) {
    // Usually caused by navigating to a page with POST data via back or
    // forward buttons.
    errorText = "<title>Expired Form Data</title>"
        "
Expired Form Data
"
        "
Your form request has expired. "
        "Click reload to re-submit the form data.
"
        "";
  } else {
    // All other messages.
    stringstream ss;
    ss << "<title>Load Failed</title>"
        "
Load Failed
"
        "
Load of URL " << string(failedUrl) << " failed with error code "
        << static_cast<int>(errorCode) << ".
"
            "";
    errorText = ss.str();
  }

  return false;
}

void ClientHandler::OnNavStateChange(CefRefPtr<CefBrowser> browser,
    bool canGoBack, bool canGoForward) {
  //Intentionally left blank
}

bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
    const CefString& message, const CefString& source, int line) {
  REQUIRE_UI_THREAD();
  cout << string(message) << endl;
  return false;
}

void ClientHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, CefRefPtr<CefDOMNode> node) {
  REQUIRE_UI_THREAD();
}

void ClientHandler::SetWindow(GtkWidget* widget) {
  window = widget;
}

void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_MainHwnd = hwnd;
}

// ClientHandler::ClientLifeSpanHandler implementation
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
    const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo,
    const CefString& url, CefRefPtr<CefClient>& client,
    CefBrowserSettings& settings) {
  REQUIRE_UI_THREAD();

  return false;
}

void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, const CefString& url) {
  //Intentionally left blank
}

void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
    const CefString& title) {
  REQUIRE_UI_THREAD();

  string titleStr(title);

  size_t inHomeDir;
  string home = getenv("HOME");
  inHomeDir = titleStr.find(home);
  if (inHomeDir == 0) {
    titleStr = titleStr.substr(home.length());
    titleStr.insert(0, "~");
  }

  size_t lastSlash;
  lastSlash = titleStr.rfind("/");

  string formatted;
  if (lastSlash != string::npos && lastSlash + 1 < titleStr.length()) {
    formatted.append(titleStr, lastSlash + 1, titleStr.length() - lastSlash);
    formatted.append(" (");
    formatted.append(titleStr, 0, lastSlash);
    formatted.append(")");
  } else
    formatted.append(titleStr);
  formatted.append(" - atom");

  GtkWidget* window = gtk_widget_get_ancestor(
      GTK_WIDGET(browser->GetHost()->GetWindowHandle()), GTK_TYPE_WINDOW);
  gtk_window_set_title(GTK_WINDOW(window), formatted.c_str());
}

void ClientHandler::SendNotification(NotificationType type) {
  // TODO(port): Implement this method.
}

void ClientHandler::CloseMainWindow() {
  // TODO(port): Close main window.
}
<commit_msg>Remove cache miss error text<commit_after>// Copyright (c) 2011 The Chromium Embedded Framework 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 "client_handler.h"
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "atom.h"
#include <stdlib.h>
#include <gtk/gtk.h>

using namespace std;

ClientHandler::ClientHandler() :
    m_MainHwnd(NULL), m_BrowserHwnd(NULL) {
}

ClientHandler::~ClientHandler() {
}

bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
    CefProcessId source_process, CefRefPtr<CefProcessMessage> message) {
  string name = message->GetName().ToString();
  if (name == "showDevTools") {
    string devtools_url = browser->GetHost()->GetDevToolsURL(true);
    if (!devtools_url.empty())
      browser->GetMainFrame()->ExecuteJavaScript(
          "window.open('" + devtools_url + "');", "about:blank", 0);
  } else
    return false;

  return true;
}

void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  AutoLock lock_scope(this);
  if (!m_Browser.get()) {
    // We need to keep the main child window, but not popup windows
    m_Browser = browser;
    m_BrowserId = browser->GetIdentifier();
  }
}

bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier()) {
    // Since the main window contains the browser window, we need to close
    // the parent window instead of the browser window.
    CloseMainWindow();

    // Return true here so that we can skip closing the browser window
    // in this pass. (It will be destroyed due to the call to close
    // the parent above.)
    return true;
  }

  // A popup browser window is not contained in another window, so we can let
  // these windows close by themselves.
  return false;
}

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  // Free the browser pointer so that the browser can be destroyed
  if (m_BrowserId == browser->GetIdentifier())
    m_Browser = NULL;
}

void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame) {
  REQUIRE_UI_THREAD();

}

void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, int httpStatusCode) {
  REQUIRE_UI_THREAD();

}

bool ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& failedUrl,
    CefString& errorText) {
  REQUIRE_UI_THREAD();

  // All other messages.
  stringstream ss;
  ss << "<title>Load Failed</title>"
      "
Load Failed
"
      "
Load of URL " << string(failedUrl) << " failed with error code "
      << static_cast<int>(errorCode) << ".
"
          "";
  errorText = ss.str();

  return false;
}

void ClientHandler::OnNavStateChange(CefRefPtr<CefBrowser> browser,
    bool canGoBack, bool canGoForward) {
  //Intentionally left blank
}

bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
    const CefString& message, const CefString& source, int line) {
  REQUIRE_UI_THREAD();
  cout << string(message) << endl;
  return false;
}

void ClientHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, CefRefPtr<CefDOMNode> node) {
  REQUIRE_UI_THREAD();
}

void ClientHandler::SetWindow(GtkWidget* widget) {
  window = widget;
}

void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_MainHwnd = hwnd;
}

// ClientHandler::ClientLifeSpanHandler implementation
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
    const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo,
    const CefString& url, CefRefPtr<CefClient>& client,
    CefBrowserSettings& settings) {
  REQUIRE_UI_THREAD();

  return false;
}

void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame, const CefString& url) {
  //Intentionally left blank
}

void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
    const CefString& title) {
  REQUIRE_UI_THREAD();

  string titleStr(title);

  size_t inHomeDir;
  string home = getenv("HOME");
  inHomeDir = titleStr.find(home);
  if (inHomeDir == 0) {
    titleStr = titleStr.substr(home.length());
    titleStr.insert(0, "~");
  }

  size_t lastSlash;
  lastSlash = titleStr.rfind("/");

  string formatted;
  if (lastSlash != string::npos && lastSlash + 1 < titleStr.length()) {
    formatted.append(titleStr, lastSlash + 1, titleStr.length() - lastSlash);
    formatted.append(" (");
    formatted.append(titleStr, 0, lastSlash);
    formatted.append(")");
  } else
    formatted.append(titleStr);
  formatted.append(" - atom");

  GtkWidget* window = gtk_widget_get_ancestor(
      GTK_WIDGET(browser->GetHost()->GetWindowHandle()), GTK_TYPE_WINDOW);
  gtk_window_set_title(GTK_WINDOW(window), formatted.c_str());
}

void ClientHandler::SendNotification(NotificationType type) {
  // TODO(port): Implement this method.
}

void ClientHandler::CloseMainWindow() {
  // TODO(port): Close main window.
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2010 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 "net/base/x509_cert_types.h"

#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include <Security/SecAsn1Coder.h>

#include "base/logging.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/utf_string_conversions.h"

namespace net {

static const CSSM_OID* kOIDs[] = {
    &CSSMOID_CommonName,
    &CSSMOID_LocalityName,
    &CSSMOID_StateProvinceName,
    &CSSMOID_CountryName,
    &CSSMOID_StreetAddress,
    &CSSMOID_OrganizationName,
    &CSSMOID_OrganizationalUnitName,
    &CSSMOID_DNQualifier      // This should be "DC" but is undoubtedly wrong.
};                            // TODO(avi): Find the right OID.

// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.)
static std::string DataToString(CSSM_DATA data);

// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8.
static std::string Latin1DataToUTF8String(CSSM_DATA data);

// Converts big-endian UTF-16 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
static bool UTF16BigEndianToUTF8(char16* chars, size_t length,
                                 std::string* out_string);

// Converts big-endian UTF-32 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
static bool UTF32BigEndianToUTF8(char32* chars, size_t length,
                                 std::string* out_string);

// Adds a type+value pair to the appropriate vector from a C array.
// The array is keyed by the matching OIDs from kOIDS[].
  static void AddTypeValuePair(const CSSM_OID type,
                               const std::string& value,
                               std::vector<std::string>* values[]);

// Stores the first string of the vector, if any, to *single_value.
static void SetSingle(const std::vector<std::string> &values,
                      std::string* single_value);

void CertPrincipal::Parse(const CSSM_X509_NAME* name) {
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &(this->street_addresses),
      &(this->organization_names),
      &(this->organization_unit_names),
      &(this->domain_components)
  };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) {
    CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn];
    for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) {
      CSSM_X509_TYPE_VALUE_PAIR pair_struct =
          rdn_struct.AttributeTypeAndValue[pair];
      AddTypeValuePair(pair_struct.type,
                       DataToString(pair_struct.value),
                       values);
    }
  }

  SetSingle(common_names, &this->common_name);
  SetSingle(locality_names, &this->locality_name);
  SetSingle(state_names, &this->state_or_province_name);
  SetSingle(country_names, &this->country_name);
}

// The following structs and templates work with Apple's very arcane and under-
// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1
// decoder:
// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html

// These are used to parse the contents of a raw
// BER DistinguishedName structure.

struct KeyValuePair {
  CSSM_OID key;
  int value_type;
  CSSM_DATA value;

  enum {
    kTypeOther = 0,
    kTypePrintableString,
    kTypeIA5String,
    kTypeT61String,
    kTypeUTF8String,
    kTypeBMPString,
    kTypeUniversalString,
  };
};

static const SecAsn1Template kStringValueTemplate[] = {
  { SEC_ASN1_CHOICE, offsetof(KeyValuePair, value_type), },
  { SEC_ASN1_PRINTABLE_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypePrintableString },
  { SEC_ASN1_IA5_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeIA5String },
  { SEC_ASN1_T61_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeT61String },
  { SEC_ASN1_UTF8_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUTF8String },
  { SEC_ASN1_BMP_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeBMPString },
  { SEC_ASN1_UNIVERSAL_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUniversalString },
  { 0, }
};

static const SecAsn1Template kKeyValuePairTemplate[] = {
  { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(KeyValuePair) },
  { SEC_ASN1_OBJECT_ID, offsetof(KeyValuePair, key), },
  { SEC_ASN1_INLINE, 0, &kStringValueTemplate, },
  { 0, }
};

struct KeyValuePairs {
  KeyValuePair* pairs;
};

static const SecAsn1Template kKeyValuePairSetTemplate[] = {
  { SEC_ASN1_SET_OF, offsetof(KeyValuePairs,pairs),
      kKeyValuePairTemplate, sizeof(KeyValuePairs) }
};

struct X509Name {
  KeyValuePairs** pairs_list;
};

static const SecAsn1Template kNameTemplate[] = {
  { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name,pairs_list),
      kKeyValuePairSetTemplate, sizeof(X509Name) }
};

bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data,
                                           size_t length) {
  DCHECK(ber_name_data);

  // First parse the BER |name_data| into the above structs.
  SecAsn1CoderRef coder = NULL;
  SecAsn1CoderCreate(&coder);
  DCHECK(coder);
  X509Name* name = NULL;
  OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate,
                               &name);
  if (err) {
    LOG(ERROR) << "SecAsn1Decode returned " << err << "; name=" << name;
    SecAsn1CoderRelease(coder);
    return false;
  }

  // Now scan the structs and add the values to my string vectors.
  // I don't store multiple common/locality/state/country names, so use
  // temporary vectors for those.
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;
  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &this->street_addresses,
      &this->organization_names,
      &this->organization_unit_names,
      &this->domain_components
  };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (int rdn=0; name[rdn].pairs_list; ++rdn) {
    KeyValuePair *pair;
    for (int pair_index = 0;
         NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs);
         ++pair_index) {
      switch (pair->value_type) {
        case KeyValuePair::kTypeIA5String:          // ASCII (that means 7-bit!)
        case KeyValuePair::kTypePrintableString:    // a subset of ASCII
        case KeyValuePair::kTypeUTF8String:         // UTF-8
          AddTypeValuePair(pair->key, DataToString(pair->value), values);
          break;
        case KeyValuePair::kTypeT61String:          // T61, pretend it's Latin-1
          AddTypeValuePair(pair->key,
                           Latin1DataToUTF8String(pair->value),
                           values);
          break;
        case KeyValuePair::kTypeBMPString: {        // UTF-16, big-endian
          std::string value;
          UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data),
                               pair->value.Length / sizeof(char16),
                               &value);
          AddTypeValuePair(pair->key, value, values);
          break;
        }
        case KeyValuePair::kTypeUniversalString: {  // UTF-32, big-endian
          std::string value;
          UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data),
                               pair->value.Length / sizeof(char32),
                               &value);
          AddTypeValuePair(pair->key, value, values);
          break;
        }
        default:
          DCHECK_EQ(pair->value_type, KeyValuePair::kTypeOther);
          // We don't know what data type this is, but we'll store it as a blob.
          // Displaying the string may not work, but at least it can be compared
          // byte-for-byte by a Matches() call.
          AddTypeValuePair(pair->key, DataToString(pair->value), values);
          break;
      }
    }
  }

  SetSingle(common_names, &this->common_name);
  SetSingle(locality_names, &this->locality_name);
  SetSingle(state_names, &this->state_or_province_name);
  SetSingle(country_names, &this->country_name);

  // Releasing |coder| frees all the memory pointed to via |name|.
  SecAsn1CoderRelease(coder);
  return true;
}

// SUBROUTINES:

static std::string DataToString(CSSM_DATA data) {
  return std::string(
      reinterpret_cast<std::string::value_type*>(data.Data),
      data.Length);
}

static std::string Latin1DataToUTF8String(CSSM_DATA data) {
  string16 utf16;
  if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1,
                       base::OnStringConversionError::FAIL, &utf16))
    return "";
  return UTF16ToUTF8(utf16);
}

bool UTF16BigEndianToUTF8(char16* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; i++)
    chars[i] = EndianU16_BtoN(chars[i]);
  return UTF16ToUTF8(chars, length, out_string);
}

bool UTF32BigEndianToUTF8(char32* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; i++)
    chars[i] = EndianS32_BtoN(chars[i]);
#if defined(WCHAR_T_IS_UTF32)
  return WideToUTF8(reinterpret_cast<const wchar_t*>(chars),
                    length, out_string);
#else
#error This code doesn't handle 16-bit wchar_t.
#endif
}

  static void AddTypeValuePair(const CSSM_OID type,
                               const std::string& value,
                               std::vector<std::string>* values[]) {
  for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
    if (CSSMOIDEqual(&type, kOIDs[oid])) {
      values[oid]->push_back(value);
      break;
    }
  }
}

static void SetSingle(const std::vector<std::string> &values,
                      std::string* single_value) {
  // We don't expect to have more than one CN, L, S, and C.
  LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values";
  if (values.size() > 0)
    *single_value = values[0];
}

}  // namespace net
<commit_msg>Whitespace change to trigger the bots.<commit_after>// Copyright (c) 2010 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 "net/base/x509_cert_types.h"

#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include <Security/SecAsn1Coder.h>

#include "base/logging.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/utf_string_conversions.h"

namespace net {

static const CSSM_OID* kOIDs[] = {
    &CSSMOID_CommonName,
    &CSSMOID_LocalityName,
    &CSSMOID_StateProvinceName,
    &CSSMOID_CountryName,
    &CSSMOID_StreetAddress,
    &CSSMOID_OrganizationName,
    &CSSMOID_OrganizationalUnitName,
    &CSSMOID_DNQualifier      // This should be "DC" but is undoubtedly wrong.
};                            // TODO(avi): Find the right OID.

// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.)
static std::string DataToString(CSSM_DATA data);

// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8.
static std::string Latin1DataToUTF8String(CSSM_DATA data);

// Converts big-endian UTF-16 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
static bool UTF16BigEndianToUTF8(char16* chars, size_t length,
                                 std::string* out_string);

// Converts big-endian UTF-32 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
static bool UTF32BigEndianToUTF8(char32* chars, size_t length,
                                 std::string* out_string);

// Adds a type+value pair to the appropriate vector from a C array.
// The array is keyed by the matching OIDs from kOIDS[].
  static void AddTypeValuePair(const CSSM_OID type,
                               const std::string& value,
                               std::vector<std::string>* values[]);

// Stores the first string of the vector, if any, to *single_value.
static void SetSingle(const std::vector<std::string> &values,
                      std::string* single_value);

void CertPrincipal::Parse(const CSSM_X509_NAME* name) {
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &(this->street_addresses),
      &(this->organization_names),
      &(this->organization_unit_names),
      &(this->domain_components)
  };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) {
    CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn];
    for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) {
      CSSM_X509_TYPE_VALUE_PAIR pair_struct =
          rdn_struct.AttributeTypeAndValue[pair];
      AddTypeValuePair(pair_struct.type,
                       DataToString(pair_struct.value),
                       values);
    }
  }

  SetSingle(common_names, &this->common_name);
  SetSingle(locality_names, &this->locality_name);
  SetSingle(state_names, &this->state_or_province_name);
  SetSingle(country_names, &this->country_name);
}

// The following structs and templates work with Apple's very arcane and under-
// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1
// decoder:
// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html

// These are used to parse the contents of a raw
// BER DistinguishedName structure.

struct KeyValuePair {
  CSSM_OID key;
  int value_type;
  CSSM_DATA value;

  enum {
    kTypeOther = 0,
    kTypePrintableString,
    kTypeIA5String,
    kTypeT61String,
    kTypeUTF8String,
    kTypeBMPString,
    kTypeUniversalString,
  };
};

static const SecAsn1Template kStringValueTemplate[] = {
  { SEC_ASN1_CHOICE, offsetof(KeyValuePair, value_type), },
  { SEC_ASN1_PRINTABLE_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypePrintableString },
  { SEC_ASN1_IA5_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeIA5String },
  { SEC_ASN1_T61_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeT61String },
  { SEC_ASN1_UTF8_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUTF8String },
  { SEC_ASN1_BMP_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeBMPString },
  { SEC_ASN1_UNIVERSAL_STRING,
    offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUniversalString },
  { 0, }
};

static const SecAsn1Template kKeyValuePairTemplate[] = {
  { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(KeyValuePair) },
  { SEC_ASN1_OBJECT_ID, offsetof(KeyValuePair, key), },
  { SEC_ASN1_INLINE, 0, &kStringValueTemplate, },
  { 0, }
};

struct KeyValuePairs {
  KeyValuePair* pairs;
};

static const SecAsn1Template kKeyValuePairSetTemplate[] = {
  { SEC_ASN1_SET_OF, offsetof(KeyValuePairs,pairs),
      kKeyValuePairTemplate, sizeof(KeyValuePairs) }
};

struct X509Name {
  KeyValuePairs** pairs_list;
};

static const SecAsn1Template kNameTemplate[] = {
  { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name,pairs_list),
      kKeyValuePairSetTemplate, sizeof(X509Name) }
};

bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data,
                                           size_t length) {
  DCHECK(ber_name_data);

  // First parse the BER |name_data| into the above structs.
  SecAsn1CoderRef coder = NULL;
  SecAsn1CoderCreate(&coder);
  DCHECK(coder);
  X509Name* name = NULL;
  OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate,
                               &name);
  if (err) {
    LOG(ERROR) << "SecAsn1Decode returned " << err << "; name=" << name;
    SecAsn1CoderRelease(coder);
    return false;
  }

  // Now scan the structs and add the values to my string vectors.
  // I don't store multiple common/locality/state/country names, so use
  // temporary vectors for those.
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;
  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &this->street_addresses,
      &this->organization_names,
      &this->organization_unit_names,
      &this->domain_components
  };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (int rdn=0; name[rdn].pairs_list; ++rdn) {
    KeyValuePair *pair;
    for (int pair_index = 0;
         NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs);
         ++pair_index) {
      switch (pair->value_type) {
        case KeyValuePair::kTypeIA5String:          // ASCII (that means 7-bit!)
        case KeyValuePair::kTypePrintableString:    // a subset of ASCII
        case KeyValuePair::kTypeUTF8String:         // UTF-8
          AddTypeValuePair(pair->key, DataToString(pair->value), values);
          break;
        case KeyValuePair::kTypeT61String:          // T61, pretend it's Latin-1
          AddTypeValuePair(pair->key,
                           Latin1DataToUTF8String(pair->value),
                           values);
          break;
        case KeyValuePair::kTypeBMPString: {        // UTF-16, big-endian
          std::string value;
          UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data),
                               pair->value.Length / sizeof(char16),
                               &value);
          AddTypeValuePair(pair->key, value, values);
          break;
        }
        case KeyValuePair::kTypeUniversalString: {  // UTF-32, big-endian
          std::string value;
          UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data),
                               pair->value.Length / sizeof(char32),
                               &value);
          AddTypeValuePair(pair->key, value, values);
          break;
        }
        default:
          DCHECK_EQ(pair->value_type, KeyValuePair::kTypeOther);
          // We don't know what data type this is, but we'll store it as a blob.
          // Displaying the string may not work, but at least it can be compared
          // byte-for-byte by a Matches() call.
          AddTypeValuePair(pair->key, DataToString(pair->value), values);
          break;
      }
    }
  }

  SetSingle(common_names, &this->common_name);
  SetSingle(locality_names, &this->locality_name);
  SetSingle(state_names, &this->state_or_province_name);
  SetSingle(country_names, &this->country_name);

  // Releasing |coder| frees all the memory pointed to via |name|.
  SecAsn1CoderRelease(coder);
  return true;
}

// SUBROUTINES:

static std::string DataToString(CSSM_DATA data) {
  return std::string(
      reinterpret_cast<std::string::value_type*>(data.Data),
      data.Length);
}

static std::string Latin1DataToUTF8String(CSSM_DATA data) {
  string16 utf16;
  if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1,
                       base::OnStringConversionError::FAIL, &utf16))
    return "";
  return UTF16ToUTF8(utf16);
}

bool UTF16BigEndianToUTF8(char16* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; i++)
    chars[i] = EndianU16_BtoN(chars[i]);
  return UTF16ToUTF8(chars, length, out_string);
}

bool UTF32BigEndianToUTF8(char32* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; i++)
    chars[i] = EndianS32_BtoN(chars[i]);
#if defined(WCHAR_T_IS_UTF32)
  return WideToUTF8(reinterpret_cast<const wchar_t*>(chars),
                    length, out_string);
#else
#error This code doesn't handle 16-bit wchar_t.
#endif
}

  static void AddTypeValuePair(const CSSM_OID type,
                               const std::string& value,
                               std::vector<std::string>* values[]) {
  for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
    if (CSSMOIDEqual(&type, kOIDs[oid])) {
      values[oid]->push_back(value);
      break;
    }
  }
}

static void SetSingle(const std::vector<std::string> &values,
                      std::string* single_value) {
  // We don't expect to have more than one CN, L, S, and C.
  LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values";
  if (values.size() > 0)
    *single_value = values[0];
}

}  // namespace net
<|endoftext|>


<commit_before>#include "Automate.h"

using namespace std;

static const int MAX = 200;
/*
Automate::Automate()
{
    //ctor
    struct analyseSymbole test(new SymboleSimple(VAR));
    tableauAnalyseStatique.push_back(test);
}*/

Automate::Automate(AnalyseurLexical *aL)
{
    aLexical = aL;
    nouveauIdentifiant = true;
}

void Automate::analyseStatique()
{
    vector<Declaration*> declarations = programme.getDeclarations();
    vector<Instruction*> instructions = programme.getInstructions();

    for (auto itDeclaration = declarations.begin() ; itDeclaration != declarations.end(); ++itDeclaration)
    {
        switch((*itDeclaration)->getContenu()->getType())
        {
            case LC:
                {
                    vector<Identifiant *> constantes = ((DecConstante*)(*itDeclaration))->getConstantes();
                    for (auto itConstantes = constantes.begin(); itConstantes != constantes.end(); ++itConstantes)
                    {
                        //cout << "constante: " << (*itConstantes)->afficherType() << endl;
                        if (tableauAnalyseStatique.find((*itConstantes)->valeur()) != tableauAnalyseStatique.end())
                        {
                            cout << "ERROR: The Constant " << (*itConstantes)->valeur() << " has already been declared" << endl;
                        }
                        else
                        {
                            tableauAnalyseStatique.insert(make_pair((*itConstantes)->valeur(),analyseSymbole(*itConstantes, true)));
                            tableauAnalyseStatique.at((*itConstantes)->valeur()).affecte = true;
                        }
                    }
                }
                break;

            case LV:
                {
                    vector<Identifiant *> variables = ((DecVariable*)(*itDeclaration))->getVariables();
                    for (auto itVariables = variables.begin(); itVariables != variables.end(); ++itVariables)
                    {
                        //cout << "variable: " << (*itVariables)->afficherType() << endl;
                        if (tableauAnalyseStatique.find((*itVariables)->valeur()) != tableauAnalyseStatique.end()) {
                            cout << "ERROR: The Variable " << (*itVariables)->valeur() << " has already been declared" << endl;
                        } else {
                            tableauAnalyseStatique.insert(make_pair((*itVariables)->valeur(),analyseSymbole(*itVariables, false)));
                        }
                        // variables cannot be directly initalized;
                    }
                }
                break;
            // should never be the case when no fault in grammar
            default:
                cout << "Something went wrong, declaration was a :" <<  (*itDeclaration)->getContenu()->afficherType() << endl;
        }
    }
/*    for (auto it = tableauAnalyseStatique.begin(); it != tableauAnalyseStatique.end(); it++)
      {
          cout << it->first << endl;
      }*/

    for (auto it = instructions.begin() ; it != instructions.end(); ++it)
    {
        switch((*it)->getInstType())
        {
            case AFF:
                {
                    InstructionAffectation * instrAff = (InstructionAffectation*) *it;
                    Identifiant* id = instrAff->getIdentifiant();
                    checkIdent(id, false);
                    Expression* expr = instrAff->getExpression();
                    checkExpression(expr);
                }
                break;
            case LEC:
                {
                    InstructionLecture * instrLec = (InstructionLecture*) *it;
                    Identifiant* id = instrLec->getIdentifiant();
                    checkIdent(id, false);
                }
                break;
            case ECR:
                {
                    InstructionEcriture * instrEcr = (InstructionEcriture*) *it;
                    Expression* expr = instrEcr->getExpression();
                    checkExpression(expr);
                }
                break;
        }
    }

    for (auto itIdentifiers = tableauAnalyseStatique.begin(); itIdentifiers != tableauAnalyseStatique.end(); ++itIdentifiers)
    {
        if (itIdentifiers->second.utilise == false)
        {
            cout << "ERROR: The identifier " << itIdentifiers->first << " is never used!" << endl;
        }
    }
}

Programme Automate::getProgramme() {
    return this->programme;
}

bool Automate::reduction(int nbEtat, Symbole *s)
{
    for (int i = 0; i < nbEtat ; i++){
        etats.pop();
    }

    //symboles.push(s);

    etats.top()->transition(*this, s);
    return false;

}

bool Automate::decalage(Symbole *s, Etat *etat){

    etats.push(etat);
    symboles.push(s);

    return false;
}

bool Automate::analyse(){

    etats.push(new Etat0);

    int i =0;
    Symbole * next;
    bool accepte;
    do{
        //etats.top()->print();

        next = aLexical->next();

        //cout << next->afficherType() << endl;

        //if the next symbol is an id, we have to make sure it has not been created before

        if(next->getType() == ID)
        {
            Identifiant * id  = (Identifiant*) next;
            if(identifiants.find(id->valeur()) != identifiants.end())
            {

                //TODO delete next?

                //use existing id if it exists
                next = identifiants[id->valeur()];
                //reset id role (could have been used as T or F before)
                next->setType(ID);
                nouveauIdentifiant = false;

            }else{
                //insert new id

                identifiants.insert(make_pair(id->valeur(),id));
                nouveauIdentifiant = true;
            }

        }
        try
        {
            accepte = etats.top()->transition(*this, next);
        }catch(std::logic_error ex)
        {
            throw ex;
        }

     }while(!accepte);

}

AnalyseurLexical * Automate::getAnalyseurLexical()
{
    return aLexical;
}

Symbole *Automate::getDernierSymbole()
{
    Symbole *s = symboles.top();
    symboles.pop();
    return s;

}

void Automate::pushEtat(Etat *etat)
{
    etats.push(etat);
}

void Automate::consommer()
{
    aLexical->shift();
}
void Automate::popSymbole()
{
    symboles.pop();
}

Automate::~Automate()
{
    //dtor
}

void Automate::ajouter(Instruction* instr)
{
    programme.ajouter(instr);
}

void Automate::ajouter(Declaration* dec)
{
    programme.ajouter(dec);
}

void Automate::executer()
{
    programme.executer();
}

void Automate::checkIdent(Identifiant * id, bool isExpression)
{
    if (id->getExprType() != IDENT)
    {
        cout << "ERROR: Expression type of identifier to use is " << id->afficherExprType() << endl;
    }
    else
    {
        // should never be the case when no fault in grammar
// not sure yet if we need this
/*        if (id->getType() != ID)
        {
            cout << "ERROR: Symbol type of identifier to use is " << id->afficherType() << endl;
        }*/
        if (tableauAnalyseStatique.find(id->valeur()) == tableauAnalyseStatique.end())
        {
            cout << "ERROR: Identifier " << id->valeur() << "has not been declared" << endl;
        }
        else
        {
            if (!isExpression && tableauAnalyseStatique.at(id->valeur()).isConstante)
            {
                cout << "ERROR: Constante " << id->valeur() << " used in variable context" << endl;
            }
            else if (isExpression && !(id->isInitialized()))
            {
                cout << "ERROR: Variable " << id->valeur() << " has not been initialised" << endl;
            }
            else
            {
                tableauAnalyseStatique.at(id->valeur()).utilise = true;
            }
        }
    }
}

void Automate::checkExpression(Expression * expr)
{
    if (expr->getExprType() == IDENT)
    {
        checkIdent((Identifiant*) expr, true);
    }
    else if (expr->getExprType() == PAR)
    {
        checkExpression(((ExprPar*)expr)->getExpression());
    }
    else if (expr->getExprType() == BIN)
    {
        checkExpression(((ExprBinaire*)expr)->getGauche());
        checkExpression(((ExprBinaire*)expr)->getDroite());
    }
}

bool Automate::doubleDeclaration(string nomIdentifiant)
{
     if(identifiants.find(nomIdentifiant) != identifiants.end())
     {
         return true;
     }
     return false;
}
<commit_msg>last commit boys<commit_after>#include "Automate.h"

using namespace std;

static const int MAX = 200;
/*
Automate::Automate()
{
    //ctor
    struct analyseSymbole test(new SymboleSimple(VAR));
    tableauAnalyseStatique.push_back(test);
}*/

Automate::Automate(AnalyseurLexical *aL)
{
    aLexical = aL;
    nouveauIdentifiant = true;
}

void Automate::analyseStatique()
{
    vector<Declaration*> declarations = programme.getDeclarations();
    vector<Instruction*> instructions = programme.getInstructions();

    for (auto itDeclaration = declarations.begin() ; itDeclaration != declarations.end(); ++itDeclaration)
    {
        switch((*itDeclaration)->getContenu()->getType())
        {
            case LC:
                {
                    vector<Identifiant *> constantes = ((DecConstante*)(*itDeclaration))->getConstantes();
                    for (auto itConstantes = constantes.begin(); itConstantes != constantes.end(); ++itConstantes)
                    {
                        //cout << "constante: " << (*itConstantes)->afficherType() << endl;
                        if (tableauAnalyseStatique.find((*itConstantes)->valeur()) != tableauAnalyseStatique.end())
                        {
                            cout << "ERROR: The Constant " << (*itConstantes)->valeur() << " has already been declared" << endl;
                        }
                        else
                        {
                            tableauAnalyseStatique.insert(make_pair((*itConstantes)->valeur(),analyseSymbole(*itConstantes, true)));
                            tableauAnalyseStatique.at((*itConstantes)->valeur()).affecte = true;
                        }
                    }
                }
                break;

            case LV:
                {
                    vector<Identifiant *> variables = ((DecVariable*)(*itDeclaration))->getVariables();
                    for (auto itVariables = variables.begin(); itVariables != variables.end(); ++itVariables)
                    {
                        //cout << "variable: " << (*itVariables)->afficherType() << endl;
                        if (tableauAnalyseStatique.find((*itVariables)->valeur()) != tableauAnalyseStatique.end()) {
                            cout << "ERROR: The Variable " << (*itVariables)->valeur() << " has already been declared" << endl;
                        } else {
                            tableauAnalyseStatique.insert(make_pair((*itVariables)->valeur(),analyseSymbole(*itVariables, false)));
                        }
                        // variables cannot be directly initalized;
                    }
                }
                break;
            // should never be the case when no fault in grammar
            default:
                cout << "Something went wrong, declaration was a :" <<  (*itDeclaration)->getContenu()->afficherType() << endl;
        }
    }
/*    for (auto it = tableauAnalyseStatique.begin(); it != tableauAnalyseStatique.end(); it++)
      {
          cout << it->first << endl;
      }*/

    for (auto it = instructions.begin() ; it != instructions.end(); ++it)
    {
        switch((*it)->getInstType())
        {
            case AFF:
                {
                    InstructionAffectation * instrAff = (InstructionAffectation*) *it;
                    Identifiant* id = instrAff->getIdentifiant();
                    checkIdent(id, false);
                    Expression* expr = instrAff->getExpression();
                    checkExpression(expr);
                }
                break;
            case LEC:
                {
                    InstructionLecture * instrLec = (InstructionLecture*) *it;
                    Identifiant* id = instrLec->getIdentifiant();
                    checkIdent(id, false);
                }
                break;
            case ECR:
                {
                    InstructionEcriture * instrEcr = (InstructionEcriture*) *it;
                    Expression* expr = instrEcr->getExpression();
                    checkExpression(expr);
                }
                break;
        }
    }

    for (auto itIdentifiers = tableauAnalyseStatique.begin(); itIdentifiers != tableauAnalyseStatique.end(); ++itIdentifiers)
    {
        if (itIdentifiers->second.utilise == false)
        {
            cout << "ERROR: The identifier " << itIdentifiers->first << " is never used!" << endl;
        }
    }
}

Programme Automate::getProgramme() {
    return this->programme;
}

bool Automate::reduction(int nbEtat, Symbole *s)
{
    for (int i = 0; i < nbEtat ; i++){
        etats.pop();
    }

    //symboles.push(s);

    etats.top()->transition(*this, s);
    return false;

}

bool Automate::decalage(Symbole *s, Etat *etat){

    etats.push(etat);
    symboles.push(s);

    return false;
}

bool Automate::analyse(){

    etats.push(new Etat0);

    int i =0;
    Symbole * next;
    bool accepte;
    do{
        //etats.top()->print();

        next = aLexical->next();

        //cout << next->afficherType() << endl;

        //if the next symbol is an id, we have to make sure it has not been created before

        if(next->getType() == ID)
        {
            Identifiant * id  = (Identifiant*) next;
            if(identifiants.find(id->valeur()) != identifiants.end())
            {

                //TODO delete next?

                //use existing id if it exists
                next = identifiants[id->valeur()];
                //reset id role (could have been used as T or F before)
                next->setType(ID);
                nouveauIdentifiant = false;

            }else{
                //insert new id

                identifiants.insert(make_pair(id->valeur(),id));
                nouveauIdentifiant = true;
            }

        }
        try
        {
            accepte = etats.top()->transition(*this, next);
        }catch(std::logic_error ex)
        {
            throw ex;
        }

     }while(!accepte);

}

AnalyseurLexical * Automate::getAnalyseurLexical()
{
    return aLexical;
}

Symbole *Automate::getDernierSymbole()
{
    Symbole *s = symboles.top();
    symboles.pop();
    return s;

}

void Automate::pushEtat(Etat *etat)
{
    etats.push(etat);
}

void Automate::consommer()
{
    aLexical->shift();
}
void Automate::popSymbole()
{
    symboles.pop();
}

Automate::~Automate()
{
    //dtor
}

void Automate::ajouter(Instruction* instr)
{
    programme.ajouter(instr);
}

void Automate::ajouter(Declaration* dec)
{
    programme.ajouter(dec);
}

void Automate::executer()
{
    programme.executer();
}

void Automate::checkIdent(Identifiant * id, bool isExpression)
{
    if (id->getExprType() != IDENT)
    {
        cout << "ERROR: Expression type of identifier to use is " << id->afficherExprType() << endl;
    }
    else
    {
        // should never be the case when no fault in grammar
// not sure yet if we need this
/*        if (id->getType() != ID)
        {
            cout << "ERROR: Symbol type of identifier to use is " << id->afficherType() << endl;
        }*/
        if (tableauAnalyseStatique.find(id->valeur()) == tableauAnalyseStatique.end())
        {
            cout << "ERROR: Identifier " << id->valeur() << "has not been declared" << endl;
        }
        else
        {
            if (!isExpression && tableauAnalyseStatique.at(id->valeur()).isConstante)
            {
                cout << "ERROR: Constante " << id->valeur() << " used in variable context" << endl;
            }
            else if (isExpression && !(tableauAnalyseStatique.at(id->valeur()).affecte))
            {
                cout << "ERROR: Variable " << id->valeur() << " has not been initialised" << endl;
                tableauAnalyseStatique.at(id->valeur()).utilise = true;
            }
            else
            {
                tableauAnalyseStatique.at(id->valeur()).utilise = true;
            }
        }
    }
}

void Automate::checkExpression(Expression * expr)
{
    if (expr->getExprType() == IDENT)
    {
        checkIdent((Identifiant*) expr, true);
    }
    else if (expr->getExprType() == PAR)
    {
        checkExpression(((ExprPar*)expr)->getExpression());
    }
    else if (expr->getExprType() == BIN)
    {
        checkExpression(((ExprBinaire*)expr)->getGauche());
        checkExpression(((ExprBinaire*)expr)->getDroite());
    }
}

bool Automate::doubleDeclaration(string nomIdentifiant)
{
     if(identifiants.find(nomIdentifiant) != identifiants.end())
     {
         return true;
     }
     return false;
}
<|endoftext|>


<commit_before>/*
 * Category.cpp
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "log4cpp/Portability.hh"

#ifdef LOG4CPP_HAVE_UNISTD_H
#    include <unistd.h>
#endif

#include "log4cpp/OstringStream.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/HierarchyMaintainer.hh"
#include "log4cpp/NDC.hh"

namespace log4cpp {

    Category& Category::getRoot() {
        return getInstance("");
    }

    void Category::setRootPriority(Priority::Value priority) {
        getRoot().setPriority(priority);
    }

    Priority::Value Category::getRootPriority() throw() {
        return getRoot().getPriority();
    }

    Category& Category::getInstance(const std::string& name) {
        return HierarchyMaintainer::getDefaultMaintainer().getInstance(name);
    }

    Category* Category::exists(const std::string& name) {
        return HierarchyMaintainer::getDefaultMaintainer().getExistingInstance(name);
    }

    std::set<Category*>* Category::getCurrentCategories() {
        return HierarchyMaintainer::getDefaultMaintainer().
            getCurrentCategories();
    }

    void Category::shutdown() {
        HierarchyMaintainer::getDefaultMaintainer().shutdown();
    }

    Category::Category(const std::string& name, Category* parent, Priority::Value priority) :
        _name(name),
        _parent(parent),
        _priority(priority),
        _isAdditive(true) {
    }

    Category::~Category() {
        removeAllAppenders();
    }

    const std::string& Category::getName() const throw() {
        return _name;
    }

    Priority::Value Category::getPriority() const throw() {
        return _priority;
    }

    void Category::setPriority(Priority::Value priority) {
        if ((priority != Priority::NOTSET) || (getParent() != NULL)) {
            _priority = priority;
        } else {
            /* caller tried to set NOTSET priority to root Category.
               Bad caller!
               Will ignore for now.
            */
        }
    }

    Priority::Value Category::getChainedPriority() const throw() {
        // REQUIRE(rootCategory->getPriority() != Priority::NOTSET)

        const Category* c = this;
        while(c->getPriority() == Priority::NOTSET) {
            c = c->getParent();
        }

        return c->getPriority();
    }

    void Category::addAppender(Appender* appender) {
        if (appender) {
            AppenderSet::iterator i = _appender.find(appender);
            if (_appender.end() == i) {
                // not found
                _appender.insert(appender);
                _ownsAppender[appender] = true;
            }
        }
    }

    void Category::addAppender(Appender& appender) {
        AppenderSet::iterator i = _appender.find(&appender);
        if (_appender.end() == i) {
            _appender.insert(&appender);
            _ownsAppender[&appender] = false;
        }
    }

    Appender* Category::getAppender() const {
        AppenderSet::const_iterator i = _appender.begin();
        return (_appender.end() == i) ? NULL : *i;
    }

    Appender* Category::getAppender(const std::string& name) const {
        AppenderSet::const_iterator i = _appender.begin();
        if (_appender.end() != i) {
            // found
            return((*i)->getAppender(name));
        }
		else {
			return(NULL);
		}
    }

    void Category::removeAllAppenders() {
        AppenderSet::iterator i2, i = _appender.begin();
        while (i != _appender.end()) {
            // found
            OwnsAppenderMap::iterator i3;
            if (ownsAppender(*i, i3)) {
                _ownsAppender.erase(i3);
                delete (*i);
            }

            i2 = i++;
            _appender.erase(i2);
        }
    }

    void Category::removeAppender(Appender* appender) {
        AppenderSet::iterator i = _appender.find(appender);
        if (_appender.end() != i) {
            OwnsAppenderMap::iterator i2;
            if (ownsAppender(*i, i2)) {
                _ownsAppender.erase(i2);
                delete (*i);
            }
            _appender.erase(i);
        } else {
            // appender not found
        }
    }

    bool Category::ownsAppender(Appender* appender) const throw() {
        bool found = false;

        if (NULL != appender) {
            OwnsAppenderMap::const_iterator i = _ownsAppender.find(appender);
            found = (_ownsAppender.end() != i);
        }

        return found;
    }

    bool Category::ownsAppender(Appender* appender,
                                Category::OwnsAppenderMap::iterator& i2) throw() {
        bool found = false;

        if (NULL != appender) {
            OwnsAppenderMap::iterator i = _ownsAppender.find(appender);
            if (_ownsAppender.end() != i) {
                found = true;
                i2 = i;
            }
        }

        return found;
    }

    void Category::callAppenders(const LoggingEvent& event) throw() {
        if (!_appender.empty()) {
            for(AppenderSet::const_iterator i = _appender.begin(); i != _appender.end(); i++) {
                (*i)->doAppend(event);
            }
        }

        if (getAdditivity() && (getParent() != NULL)) {
            getParent()->callAppenders(event);
        }
    }

    void Category::setAdditivity(bool additivity) {
        _isAdditive = additivity;
    }

    bool Category::getAdditivity() const throw() {
        return _isAdditive;
    }

    Category* Category::getParent() throw() {
        return _parent;
    }

    const Category* Category::getParent() const throw() {
        return _parent;
    }

    void Category::_logUnconditionally(Priority::Value priority,
                                       const char* format,
                                       va_list arguments) throw() {
        OstringStream messageBuffer;

        messageBuffer.vform(format, arguments);
        _logUnconditionally2(priority, messageBuffer.str());
    }

    void Category::_logUnconditionally2(Priority::Value priority,
                                        const std::string& message) throw() {
        LoggingEvent event(getName(), message, NDC::get(), priority);
        callAppenders(event);
    }

    bool Category::isPriorityEnabled(Priority::Value priority) const throw() {
        return(getChainedPriority() >= priority);
    }

    void Category::log(Priority::Value priority,
                       const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(priority)) {
            va_list va;
            va_start(va, stringFormat);
            _logUnconditionally(priority, stringFormat, va);
            va_end(va);
        }
    }

    void Category::log(Priority::Value priority,
                       const std::string& message) throw() {
        if (isPriorityEnabled(priority))
            _logUnconditionally2(priority, message);
    }

    void Category::logva(Priority::Value priority,
                         const char* stringFormat,
                         va_list va) throw() {
        if (isPriorityEnabled(priority)) {
            _logUnconditionally(priority, stringFormat, va);
        }
    }

    void Category::debug(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::DEBUG)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::DEBUG, stringFormat, va);
            va_end(va);
        }
    }

    void Category::debug(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::DEBUG))
            _logUnconditionally2(Priority::DEBUG, message);
    }

    void Category::info(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::INFO)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::INFO, stringFormat, va);
            va_end(va);
        }
    }

    void Category::info(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::INFO))
            _logUnconditionally2(Priority::INFO, message);
    }

    void Category::notice(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::NOTICE)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::NOTICE, stringFormat, va);
            va_end(va);
        }
    }

    void Category::notice(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::NOTICE))
            _logUnconditionally2(Priority::NOTICE, message);
    }

    void Category::warn(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::WARN)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::WARN, stringFormat, va);
            va_end(va);
        }
    }

    void Category::warn(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::WARN))
            _logUnconditionally2(Priority::WARN, message);
    }

    void Category::error(const char* stringFormat, ...) throw() {
               if (isPriorityEnabled(Priority::ERROR)) {
            va_list va;
            va_start(va,stringFormat);
                       _logUnconditionally(Priority::ERROR, stringFormat, va);
            va_end(va);
        }
    }

    void Category::error(const std::string& message) throw() {
               if (isPriorityEnabled(Priority::ERROR))
            _logUnconditionally2(Priority::ERROR, message);
    }

    void Category::crit(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::CRIT)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::CRIT, stringFormat, va);
            va_end(va);
        }
    }

    void Category::crit(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::CRIT))
            _logUnconditionally2(Priority::CRIT, message);
    }

    void Category::alert(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::ALERT)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::ALERT, stringFormat, va);
            va_end(va);
        }
    }

    void Category::alert(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::ALERT))
            _logUnconditionally2(Priority::ALERT, message);
    }

    void Category::emerg(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::EMERG)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::EMERG, stringFormat, va);
            va_end(va);
        }
    }

    void Category::emerg(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::EMERG))
            _logUnconditionally2(Priority::EMERG, message);
    }

    void Category::fatal(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::FATAL)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::FATAL, stringFormat, va);
            va_end(va);
        }
    }

    void Category::fatal(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::FATAL))
            _logUnconditionally2(Priority::FATAL, message);
    }

    CategoryStream Category::getStream(Priority::Value priority) {
        return CategoryStream(*this, isPriorityEnabled(priority) ?
                              priority : Priority::NOTSET);
    }

    CategoryStream Category::operator<<(Priority::Value priority) {
        return getStream(priority);
    }
}

<commit_msg>fix ownsAppender() methods.<commit_after>/*
 * Category.cpp
 *
 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2000, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "log4cpp/Portability.hh"

#ifdef LOG4CPP_HAVE_UNISTD_H
#    include <unistd.h>
#endif

#include "log4cpp/OstringStream.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/HierarchyMaintainer.hh"
#include "log4cpp/NDC.hh"

namespace log4cpp {

    Category& Category::getRoot() {
        return getInstance("");
    }

    void Category::setRootPriority(Priority::Value priority) {
        getRoot().setPriority(priority);
    }

    Priority::Value Category::getRootPriority() throw() {
        return getRoot().getPriority();
    }

    Category& Category::getInstance(const std::string& name) {
        return HierarchyMaintainer::getDefaultMaintainer().getInstance(name);
    }

    Category* Category::exists(const std::string& name) {
        return HierarchyMaintainer::getDefaultMaintainer().getExistingInstance(name);
    }

    std::set<Category*>* Category::getCurrentCategories() {
        return HierarchyMaintainer::getDefaultMaintainer().
            getCurrentCategories();
    }

    void Category::shutdown() {
        HierarchyMaintainer::getDefaultMaintainer().shutdown();
    }

    Category::Category(const std::string& name, Category* parent, Priority::Value priority) :
        _name(name),
        _parent(parent),
        _priority(priority),
        _isAdditive(true) {
    }

    Category::~Category() {
        removeAllAppenders();
    }

    const std::string& Category::getName() const throw() {
        return _name;
    }

    Priority::Value Category::getPriority() const throw() {
        return _priority;
    }

    void Category::setPriority(Priority::Value priority) {
        if ((priority != Priority::NOTSET) || (getParent() != NULL)) {
            _priority = priority;
        } else {
            /* caller tried to set NOTSET priority to root Category.
               Bad caller!
               Will ignore for now.
            */
        }
    }

    Priority::Value Category::getChainedPriority() const throw() {
        // REQUIRE(rootCategory->getPriority() != Priority::NOTSET)

        const Category* c = this;
        while(c->getPriority() == Priority::NOTSET) {
            c = c->getParent();
        }

        return c->getPriority();
    }

    void Category::addAppender(Appender* appender) {
        if (appender) {
            AppenderSet::iterator i = _appender.find(appender);
            if (_appender.end() == i) {
                // not found
                _appender.insert(appender);
                _ownsAppender[appender] = true;
            }
        }
    }

    void Category::addAppender(Appender& appender) {
        AppenderSet::iterator i = _appender.find(&appender);
        if (_appender.end() == i) {
            _appender.insert(&appender);
            _ownsAppender[&appender] = false;
        }
    }

    Appender* Category::getAppender() const {
        AppenderSet::const_iterator i = _appender.begin();
        return (_appender.end() == i) ? NULL : *i;
    }

    Appender* Category::getAppender(const std::string& name) const {
        AppenderSet::const_iterator i = _appender.begin();
        if (_appender.end() != i) {
            // found
            return((*i)->getAppender(name));
        }
		else {
			return(NULL);
		}
    }

    void Category::removeAllAppenders() {
        AppenderSet::iterator i2, i = _appender.begin();
        while (i != _appender.end()) {
            // found
            OwnsAppenderMap::iterator i3;
            if (ownsAppender(*i, i3)) {
                _ownsAppender.erase(i3);
                delete (*i);
            }

            i2 = i++;
            _appender.erase(i2);
        }
    }

    void Category::removeAppender(Appender* appender) {
        AppenderSet::iterator i = _appender.find(appender);
        if (_appender.end() != i) {
            OwnsAppenderMap::iterator i2;
            if (ownsAppender(*i, i2)) {
                _ownsAppender.erase(i2);
                delete (*i);
            }
            _appender.erase(i);
        } else {
            // appender not found
        }
    }

    bool Category::ownsAppender(Appender* appender) const throw() {
        bool owned = false;

        if (NULL != appender) {
            OwnsAppenderMap::const_iterator i = _ownsAppender.find(appender);
            if (_ownsAppender.end() != i) {
                owned = (*i).second;
            }
        }

        return owned;
    }

    bool Category::ownsAppender(Appender* appender,
                                Category::OwnsAppenderMap::iterator& i2) throw() {
        bool owned = false;

        if (NULL != appender) {
            OwnsAppenderMap::iterator i = _ownsAppender.find(appender);
            if (_ownsAppender.end() != i) {
                owned = (*i).second;
                if (owned) {
                    i2 = i;
                }
            }
        }

        return owned;
    }

    void Category::callAppenders(const LoggingEvent& event) throw() {
        if (!_appender.empty()) {
            for(AppenderSet::const_iterator i = _appender.begin(); i != _appender.end(); i++) {
                (*i)->doAppend(event);
            }
        }

        if (getAdditivity() && (getParent() != NULL)) {
            getParent()->callAppenders(event);
        }
    }

    void Category::setAdditivity(bool additivity) {
        _isAdditive = additivity;
    }

    bool Category::getAdditivity() const throw() {
        return _isAdditive;
    }

    Category* Category::getParent() throw() {
        return _parent;
    }

    const Category* Category::getParent() const throw() {
        return _parent;
    }

    void Category::_logUnconditionally(Priority::Value priority,
                                       const char* format,
                                       va_list arguments) throw() {
        OstringStream messageBuffer;

        messageBuffer.vform(format, arguments);
        _logUnconditionally2(priority, messageBuffer.str());
    }

    void Category::_logUnconditionally2(Priority::Value priority,
                                        const std::string& message) throw() {
        LoggingEvent event(getName(), message, NDC::get(), priority);
        callAppenders(event);
    }

    bool Category::isPriorityEnabled(Priority::Value priority) const throw() {
        return(getChainedPriority() >= priority);
    }

    void Category::log(Priority::Value priority,
                       const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(priority)) {
            va_list va;
            va_start(va, stringFormat);
            _logUnconditionally(priority, stringFormat, va);
            va_end(va);
        }
    }

    void Category::log(Priority::Value priority,
                       const std::string& message) throw() {
        if (isPriorityEnabled(priority))
            _logUnconditionally2(priority, message);
    }

    void Category::logva(Priority::Value priority,
                         const char* stringFormat,
                         va_list va) throw() {
        if (isPriorityEnabled(priority)) {
            _logUnconditionally(priority, stringFormat, va);
        }
    }

    void Category::debug(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::DEBUG)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::DEBUG, stringFormat, va);
            va_end(va);
        }
    }

    void Category::debug(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::DEBUG))
            _logUnconditionally2(Priority::DEBUG, message);
    }

    void Category::info(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::INFO)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::INFO, stringFormat, va);
            va_end(va);
        }
    }

    void Category::info(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::INFO))
            _logUnconditionally2(Priority::INFO, message);
    }

    void Category::notice(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::NOTICE)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::NOTICE, stringFormat, va);
            va_end(va);
        }
    }

    void Category::notice(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::NOTICE))
            _logUnconditionally2(Priority::NOTICE, message);
    }

    void Category::warn(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::WARN)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::WARN, stringFormat, va);
            va_end(va);
        }
    }

    void Category::warn(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::WARN))
            _logUnconditionally2(Priority::WARN, message);
    }

    void Category::error(const char* stringFormat, ...) throw() {
               if (isPriorityEnabled(Priority::ERROR)) {
            va_list va;
            va_start(va,stringFormat);
                       _logUnconditionally(Priority::ERROR, stringFormat, va);
            va_end(va);
        }
    }

    void Category::error(const std::string& message) throw() {
               if (isPriorityEnabled(Priority::ERROR))
            _logUnconditionally2(Priority::ERROR, message);
    }

    void Category::crit(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::CRIT)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::CRIT, stringFormat, va);
            va_end(va);
        }
    }

    void Category::crit(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::CRIT))
            _logUnconditionally2(Priority::CRIT, message);
    }

    void Category::alert(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::ALERT)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::ALERT, stringFormat, va);
            va_end(va);
        }
    }

    void Category::alert(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::ALERT))
            _logUnconditionally2(Priority::ALERT, message);
    }

    void Category::emerg(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::EMERG)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::EMERG, stringFormat, va);
            va_end(va);
        }
    }

    void Category::emerg(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::EMERG))
            _logUnconditionally2(Priority::EMERG, message);
    }

    void Category::fatal(const char* stringFormat, ...) throw() {
        if (isPriorityEnabled(Priority::FATAL)) {
            va_list va;
            va_start(va,stringFormat);
            _logUnconditionally(Priority::FATAL, stringFormat, va);
            va_end(va);
        }
    }

    void Category::fatal(const std::string& message) throw() {
        if (isPriorityEnabled(Priority::FATAL))
            _logUnconditionally2(Priority::FATAL, message);
    }

    CategoryStream Category::getStream(Priority::Value priority) {
        return CategoryStream(*this, isPriorityEnabled(priority) ?
                              priority : Priority::NOTSET);
    }

    CategoryStream Category::operator<<(Priority::Value priority) {
        return getStream(priority);
    }
}

<|endoftext|>