<commit_before>
/* Interface for debugging- spawns a  prompt that will controll the main thread if it hits a specifies break point*/

#include <pthread.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "debug_simHandler.hpp"

using namespace std;

/*function prototypes*/
void *run_debugger(void * holder);
void parseline(string line);
int handle_command(string command);
void help();
void messageHandler(uint64_t* msg);
void debugSend(int command, string build);

/*to store the last input in the debugger*/
int lastInstruction = 0;
string lastBuild = "";

#define DEBUG 16
#define SIZE (sizeof(uint64_t))

static bool isPaused = false;
static void (*sendMessage)(int,int,uint64_t*);
static void (*pauseSimulation)(int);
static void (*unPauseSimulation)(void);

/*spawn the debbugging prompt as a separate thread to
  controll the main one*/
void (*initDebugger(void (*sendMsg)(int,int,uint64_t*),
		    void (*pauseSim)(int),
		    void (*unPauseSim)(void)))(uint64_t*){

  pthread_t tid;

  sendMessage = sendMsg;
  pauseSimulation = pauseSim;
  unPauseSimulation = unPauseSim;

  isPaused = true;
  pthread_create(&tid,NULL,run_debugger, NULL);

  return &messageHandler;
}

void messageHandler(uint64_t* msg){

  int sizeMsg;
  int command = (int)msg[2];
  switch(command){

  case BREAKFOUND:
    sizeMsg = 3*SIZE;
    uint64_t msgSend[sizeMsg/SIZE];
    msgSend[0] = sizeMsg;
    msgSend[1] = DEBUG;
    msgSend[2] = PAUSE;
    sendMessage(-1,sizeMsg,(uint64_t*)msgSend);
    pauseSimulation(0);
    cout << (char*)&msg[3];
    isPaused = true;
    break;
  case PRINTCONTENT:
    cout << (char*)&msg[3];
    isPaused = true;
    break;

  }
}

//continuously attend command line prompt for debugger
//when the system is not paused
void *run_debugger(void* holder){

  (void)holder;
  string inpt;

  while(true){
    if (isPaused){
      cout << ">";
      isPaused = false;
      getline(cin,inpt);
      //react to the input
      parseline(inpt);
    }
  }
  return NULL;
}

/*parses the command line and run the debugger*/
void parseline(string line){

  string build = "";
  int wordCount = 1;

  int command = NOTHING;

  /*empty input*/
  if (line == ""){
    //enterlast stored command
    debugSend(lastInstruction,lastBuild);
    return;
  }

  /*loop through input line*/
  for (unsigned int i = 0; i < line.length(); i++){

    /*parse line for words*/
    if (line[i]!=' '){
      build += line[i];

    } else {
      //exract the command
      if (wordCount == 1)
	command = handle_command(build);
    wordCount++;
    build = "";
    }
  }

  /*no whitespace at all-single word commands*/
  if (wordCount == 1){
    command = handle_command(build);

    if (command != BREAKPOINT && command!=DUMP){
      debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
      return;
    }
  }

  /*if not enough info - these  types must have a specification*/
  if ((command == BREAKPOINT||command == DUMP)&& wordCount == 1){
      cout << "Please specify- type help for options" << endl;
      return;
  }

  /*handle breakpoints and dumps*/
  if (wordCount == 2){
	if (command == BREAKPOINT||command == DUMP)
	  debugSend(command,build);
	else
	  debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
  }
}

int stringType2Int(string type){
  if (type == "factDer"){
    return FACTDER;
  } else if (type == "factCon"){
    return FACTCON;
  } else if (type == "factRet"){
    return FACTRET;
  } else if (type == "sense"){
    return SENSE;
  } else if (type == "action"){
    return ACTION;
  } else if (type == "block"){
    return BLOCK;
  } else {
    cout << "unknown type-- enter help for options" << endl;
    return -1;
  }
}

void debugSend(int command, string build){

  int node;
  string name;
  int size;
  int type;
  char* nameSpot;

  switch(command){

  case CONTINUE:
    size = 3*SIZE;
    uint64_t msgCont[size/SIZE];
    msgCont[0] = size;
    msgCont[1] = DEBUG;
    msgCont[2] = UNPAUSE;
    sendMessage(-1,size,(uint64_t*)msgCont);
    unPauseSimulation();
    break;

  case BREAKPOINT:
    if (build[0] == ':'||build[0] == '@'){
      cout << "Please Specify a Type" << endl;
      break;
    }
    type = stringType2Int(getType(build));
    if (type == -1)
      break;
    node = atoi(getNode(build).c_str());
    name = getName(build);
    size = 4*SIZE + (name.length() + 1)
      + (SIZE - (name.length() + 1)%SIZE);
    uint64_t msgBreak[size/SIZE];
    msgBreak[0] = size;
    msgBreak[1] = DEBUG;
    msgBreak[2] = BREAKPOINT;
    msgBreak[3] = type;
    nameSpot = (char*)&msgBreak[4];
    memcpy(nameSpot,name.c_str(),name.length()+1);
    sendMessage(node,size,(uint64_t*)msgBreak);
    break;

  case DUMP:
    node = atoi(build.c_str());
    size = 3*SIZE;
    uint64_t msgDump[size/SIZE];
    msgDump[0] = size;
    msgDump[1] = DEBUG;
    msgDump[2] = DUMP;
    sendMessage(node,size,(uint64_t*)msgDump);
    break;

  case NOTHING:
    break;
  }
}

/*recognizes and sets different modes for the debugger*/
int handle_command(string command){

  int retVal;

  if (command == "break"){
    retVal = BREAKPOINT;
  } else if (command == "help"||command == "h") {
    help();
    retVal = NOTHING;
  } else if (command == "run"|| command == "r") {
    retVal = CONTINUE;
  } else if (command == "dump"||command == "d") {
    retVal = DUMP;
  } else if (command == "continue"||command == "c"){
    retVal = CONTINUE;
  } else if (command == "quit"||command == "q"){
    exit(0);
  } else {
    cout << "unknown command: type 'help' for options " << endl;
    retVal = NOTHING;
  }
  return retVal;
}

/*prints the help screen*/
void help(){
  cout << endl;
  cout << "*******************************************************************" << endl;
  cout << endl;
  cout << "DEBUGGER HELP" << endl;
  cout << "\t-break <Specification>- set break point at specified place" << endl;
  cout << "\t\t-Specification Format:" << endl;
  cout << "\t\t  <type>:<name>@<block> OR" << endl;
  cout << "\t\t  <type>:<name>        OR" << endl;
  cout << "\t\t  <type>@<block>" << endl;
  cout << "\t\t    -type - [factRet|factDer|factCon|action|sense|block]" << endl;
  cout <<             "\t\t\t-a type MUST be specified" << endl;
  cout << "\t\t    -name - the name of certain type ex. the name of a fact" << endl;
  cout << "\t\t    -node - the number of the node" << endl;
  cout << "\t-dump or d <nodeID> <all> - dump the state of the system" << endl;
  cout << "\t-continue or c - continue execution" << endl;
  cout << "\t-run or r - start the program" << endl;
  cout << "\t-quit - exit debugger" << endl;
  cout << endl;
  cout << "\t-Press Enter to use last Input" << endl;
  cout << endl;
  cout << "*******************************************************************" << endl;
}

<commit_msg>fixed segfault bug<commit_after>
/* Interface for debugging- spawns a  prompt that will controll the main thread if it hits a specifies break point*/

#include <pthread.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "debug_simHandler.hpp"

using namespace std;

/*function prototypes*/
void *run_debugger(void * holder);
void parseline(string line);
int handle_command(string command);
void help();
void messageHandler(uint64_t* msg);
void debugSend(int command, string build);

/*to store the last input in the debugger*/
int lastInstruction = 0;
string lastBuild = "";

#define DEBUG 16
#define SIZE (sizeof(uint64_t))

static bool isPaused = false;
static void (*sendMessage)(int,int,uint64_t*);
static void (*pauseSimulation)(int);
static void (*unPauseSimulation)(void);

/*spawn the debbugging prompt as a separate thread to
  controll the main one*/
void (*initDebugger(void (*sendMsg)(int,int,uint64_t*),
		    void (*pauseSim)(int),
		    void (*unPauseSim)(void)))(uint64_t*){

  pthread_t tid;

  sendMessage = sendMsg;
  pauseSimulation = pauseSim;
  unPauseSimulation = unPauseSim;

  isPaused = true;
  pthread_create(&tid,NULL,run_debugger, NULL);

  return messageHandler;
}

void messageHandler(uint64_t* msg){

  int sizeMsg;
  int command = (int)msg[2];
  if (command == BREAKPOINT){
    sizeMsg = 3*SIZE;
    uint64_t msgSend[sizeMsg/SIZE];
    msgSend[0] = sizeMsg;
    msgSend[1] = DEBUG;
    msgSend[2] = PAUSE;
    sendMessage(-1,sizeMsg,(uint64_t*)msgSend);
    pauseSimulation(0);
    cout << (char*)&msg[3];
    isPaused = true;
  } else if (command == PRINTCONTENT){
    cout << (char*)&msg[3];
    isPaused = true;
  }
}

//continuously attend command line prompt for debugger
//when the system is not paused
void *run_debugger(void* holder){

  (void)holder;
  string inpt;

  while(true){
    if (isPaused){
      cout << ">";
      isPaused = false;
      getline(cin,inpt);
      //react to the input
      parseline(inpt);
    }
  }
  return NULL;
}

/*parses the command line and run the debugger*/
void parseline(string line){

  string build = "";
  int wordCount = 1;

  int command = NOTHING;

  /*empty input*/
  if (line == ""){
    //enterlast stored command
    debugSend(lastInstruction,lastBuild);
    return;
  }

  /*loop through input line*/
  for (unsigned int i = 0; i < line.length(); i++){

    /*parse line for words*/
    if (line[i]!=' '){
      build += line[i];

    } else {
      //exract the command
      if (wordCount == 1)
	command = handle_command(build);
    wordCount++;
    build = "";
    }
  }

  /*no whitespace at all-single word commands*/
  if (wordCount == 1){
    command = handle_command(build);

    if (command != BREAKPOINT && command!=DUMP){
      debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
      return;
    }
  }

  /*if not enough info - these  types must have a specification*/
  if ((command == BREAKPOINT||command == DUMP)&& wordCount == 1){
      cout << "Please specify- type help for options" << endl;
      isPaused = true;
      return;
  }

  /*handle breakpoints and dumps*/
  if (wordCount == 2){
	if (command == BREAKPOINT||command == DUMP)
	  debugSend(command,build);
	else
	  debugSend(command,"");
      lastInstruction = command;
      lastBuild = build;
  }
}

int stringType2Int(string type){
  if (type == "factDer"){
    return FACTDER;
  } else if (type == "factCon"){
    return FACTCON;
  } else if (type == "factRet"){
    return FACTRET;
  } else if (type == "sense"){
    return SENSE;
  } else if (type == "action"){
    return ACTION;
  } else if (type == "block"){
    return BLOCK;
  } else {
    cout << "unknown type-- enter help for options" << endl;
    return -1;
  }
}

void debugSend(int command, string build){

  int node;
  string name;
  int size;
  int type;
  char* nameSpot;

  if(command == CONTINUE){
    size = 3*SIZE;
    uint64_t msgCont[size/SIZE];
    msgCont[0] = size;
    msgCont[1] = DEBUG;
    msgCont[2] = UNPAUSE;
    sendMessage(-1,size,(uint64_t*)msgCont);
    unPauseSimulation();

  } else if (command == BREAKPOINT) {
    if (build[0] == ':'||build[0] == '@'){
      cout << "Please Specify a Type" << endl;
      isPaused = true;
      return;
    }
    type = stringType2Int(getType(build));
    if (type == -1){
      isPaused = true;
      return;
    }
    node = atoi(getNode(build).c_str());
    name = getName(build);
    size = 4*SIZE + (name.length() + 1)
      + (SIZE - (name.length() + 1)%SIZE);
    uint64_t msgBreak[size/SIZE];
    msgBreak[0] = size;
    msgBreak[1] = DEBUG;
    msgBreak[2] = BREAKPOINT;
    msgBreak[3] = type;
    nameSpot = (char*)&msgBreak[4];
    memcpy(nameSpot,name.c_str(),name.length()+1);
    sendMessage(node,size,(uint64_t*)msgBreak);

  } else if (command == DUMP){
    node = atoi(build.c_str());
    size = 3*SIZE;
    uint64_t msgDump[size/SIZE];
    msgDump[0] = size;
    msgDump[1] = DEBUG;
    msgDump[2] = DUMP;
    sendMessage(node,size,(uint64_t*)msgDump);

  } else if (command == NOTHING){
    isPaused = true;
  }
  return;
}

/*recognizes and sets different modes for the debugger*/
int handle_command(string command){

  int retVal;

  if (command == "break"){
    retVal = BREAKPOINT;
  } else if (command == "help"||command == "h") {
    help();
    retVal = NOTHING;
  } else if (command == "run"|| command == "r") {
    retVal = CONTINUE;
  } else if (command == "dump"||command == "d") {
    retVal = DUMP;
  } else if (command == "continue"||command == "c"){
    retVal = CONTINUE;
  } else if (command == "quit"||command == "q"){
    exit(0);
  } else {
    cout << "unknown command: type 'help' for options " << endl;
    retVal = NOTHING;
  }
  return retVal;
}

/*prints the help screen*/
void help(){
  cout << endl;
  cout << "*******************************************************************" << endl;
  cout << endl;
  cout << "DEBUGGER HELP" << endl;
  cout << "\t-break <Specification>- set break point at specified place" << endl;
  cout << "\t\t-Specification Format:" << endl;
  cout << "\t\t  <type>:<name>@<block> OR" << endl;
  cout << "\t\t  <type>:<name>        OR" << endl;
  cout << "\t\t  <type>@<block>" << endl;
  cout << "\t\t    -type - [factRet|factDer|factCon|action|sense|block]" << endl;
  cout <<             "\t\t\t-a type MUST be specified" << endl;
  cout << "\t\t    -name - the name of certain type ex. the name of a fact" << endl;
  cout << "\t\t    -node - the number of the node" << endl;
  cout << "\t-dump or d <nodeID> <all> - dump the state of the system" << endl;
  cout << "\t-continue or c - continue execution" << endl;
  cout << "\t-run or r - start the program" << endl;
  cout << "\t-quit - exit debugger" << endl;
  cout << endl;
  cout << "\t-Press Enter to use last Input" << endl;
  cout << endl;
  cout << "*******************************************************************" << endl;
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

THIS_CLASS::THIS_CLASS(DocumentImpl *ownerDoc)
    : PARENT_CLASS(ownerDoc)
{
    this->ownerDocument = ownerDoc;
    this->firstChild = null;
};

// This only makes a shallow copy, cloneChildren must also be called for a
// deep clone
THIS_CLASS::THIS_CLASS(const THIS_CLASS &other)
    : PARENT_CLASS(other)
{
    this->ownerDocument = other.ownerDocument;

    // Need to break the association w/ original kids
    this->firstChild = null;
};

void THIS_CLASS::cloneChildren(const NodeImpl &other) {
  //    for (NodeImpl *mykid = other.getFirstChild();
    for (NodeImpl *mykid = ((NodeImpl&)other).getFirstChild();
         mykid != null;
         mykid = mykid->getNextSibling()) {
        this->appendChild(mykid->cloneNode(true));
    }
}

DocumentImpl * THIS_CLASS::getOwnerDocument() {
    return ownerDocument;
}

// unlike getOwnerDocument this is not overriden by DocumentImpl to return null
DocumentImpl * THIS_CLASS::getDocument() {
    return ownerDocument;
}

void THIS_CLASS::setOwnerDocument(DocumentImpl *doc) {
    ownerDocument = doc;
    for (NodeImpl *child = firstChild;
         child != null; child = child->getNextSibling()) {
        child->setOwnerDocument(doc);
    }
}

NodeListImpl *THIS_CLASS::getChildNodes() {
    return this;
};

NodeImpl * THIS_CLASS::getFirstChild() {
    return firstChild;
};

NodeImpl * THIS_CLASS::getLastChild()
{
    return lastChild();
};

ChildNode * THIS_CLASS::lastChild()
{
    // last child is stored as the previous sibling of first child
    return firstChild != null ? firstChild->previousSibling : null;
};

void THIS_CLASS::lastChild(ChildNode *node) {
        // store lastChild as previous sibling of first child
        if (firstChild != null) {
            firstChild->previousSibling = node;
        }
    }

unsigned int THIS_CLASS::getLength() {
    unsigned int count = 0;
    ChildNode *node = firstChild;
    while(node != null)
    {
        ++count;
        node = node->nextSibling;
    }
    return count;
};

bool THIS_CLASS::hasChildNodes()
{
    return firstChild!=null;
};

NodeImpl *THIS_CLASS::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {
    if (isReadOnly())
        throw DOM_DOMException(
        DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);

    if (newChild->getOwnerDocument() != ownerDocument)
        throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null);

    // Convert to internal type, to avoid repeated casting
    ChildNode * newInternal= (ChildNode *)newChild;

    // Prevent cycles in the tree
    bool treeSafe=true;
    for(NodeImpl *a=this->getParentNode();
        treeSafe && a!=null;
        a=a->getParentNode())
        treeSafe=(newInternal!=a);
    if(!treeSafe)
        throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);

    // refChild must in fact be a child of this node (or null)
    if (refChild!=null && refChild->getParentNode() != this)
        throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR,null);

    if (newInternal->isDocumentFragmentImpl())
    {
        // SLOW BUT SAFE: We could insert the whole subtree without
        // juggling so many next/previous pointers. (Wipe out the
        // parent's child-list, patch the parent pointers, set the
        // ends of the list.) But we know some subclasses have special-
        // case behavior they add to insertBefore(), so we don't risk it.
        // This approch also takes fewer bytecodes.

        // NOTE: If one of the children is not a legal child of this
        // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children
        // have been transferred. (Alternative behaviors would be to
        // reparent up to the first failure point or reparent all those
        // which are acceptable to the target node, neither of which is
        // as robust. PR-DOM-0818 isn't entirely clear on which it
        // recommends?????

        // No need to check kids for right-document; if they weren't,
        // they wouldn't be kids of that DocFrag.
        for(NodeImpl *kid=newInternal->getFirstChild(); // Prescan
        kid!=null;
        kid=kid->getNextSibling())
        {
            if (!DocumentImpl::isKidOK(this, kid))
              throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
        }
        while(newInternal->hasChildNodes())     // Move
            insertBefore(newInternal->getFirstChild(),refChild);
    }

    else if (!DocumentImpl::isKidOK(this, newInternal))
        throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);

    else
    {
        NodeImpl *oldparent=newInternal->getParentNode();
        if(oldparent!=null) {
            oldparent->removeChild(newInternal);
        }

        // Convert to internal type, to avoid repeated casting
        ChildNode *refInternal = (ChildNode *)refChild;

        // Attach up
        newInternal->ownerNode = this;
        newInternal->isOwned(true);

        // Attach before and after
        // Note: firstChild.previousSibling == lastChild!!
        if (firstChild == null) {
            // this our first and only child
            firstChild = newInternal;
            newInternal->isFirstChild(true);
            newInternal->previousSibling = newInternal;
        } else {
            if (refInternal == null) {
                // this is an append
                ChildNode *lastChild = firstChild->previousSibling;
                lastChild->nextSibling = newInternal;
                newInternal->previousSibling = lastChild;
                firstChild->previousSibling = newInternal;
            } else {
                // this is an insert
                if (refChild == firstChild) {
                    // at the head of the list
                    firstChild->isFirstChild(false);
                    newInternal->nextSibling = firstChild;
                    newInternal->previousSibling = firstChild->previousSibling;
                    firstChild->previousSibling = newInternal;
                    firstChild = newInternal;
                    newInternal->isFirstChild(true);
                } else {
                    // somewhere in the middle
                    ChildNode *prev = refInternal->previousSibling;
                    newInternal->nextSibling = refInternal;
                    prev->nextSibling = newInternal;
                    refInternal->previousSibling = newInternal;
                    newInternal->previousSibling = prev;
                }
            }
        }
    }

    changed();

    if (this->getOwnerDocument() != null) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if ( ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForInsertedNode(newInternal);
                }
            }
        }
    }

    return newInternal;
};

NodeImpl *THIS_CLASS::item(unsigned int index) {
    ChildNode *node = firstChild;
    for(unsigned int i=0; i<index && node!=null; ++i)
        node = node->nextSibling;
    return node;
};

NodeImpl *THIS_CLASS::removeChild(NodeImpl *oldChild)
{
    if (isReadOnly())
        throw DOM_DOMException(
        DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);

    if (oldChild != null && oldChild->getParentNode() != this)
        throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);

    //fix other ranges for change before deleting the node
    if (this->getOwnerDocument() !=  null  ) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if (ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != null)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }

    ChildNode * oldInternal = (ChildNode *) oldChild;

    // Patch linked list around oldChild
    // Note: lastChild == firstChild->previousSibling
    if (oldInternal == firstChild) {
        // removing first child
        oldInternal->isFirstChild(false);
        firstChild = oldInternal->nextSibling;
        if (firstChild != null) {
            firstChild->isFirstChild(true);
            firstChild->previousSibling = oldInternal->previousSibling;
        }
    } else {
        ChildNode *prev = oldInternal->previousSibling;
        ChildNode *next = oldInternal->nextSibling;
        prev->nextSibling = next;
        if (next == null) {
            // removing last child
            firstChild->previousSibling = prev;
        } else {
            // removing some other child in the middle
            next->previousSibling = prev;
        }
    }

    // Remove oldInternal's references to tree
    oldInternal->ownerNode = ownerDocument;
    oldInternal->isOwned(false);
    oldInternal->nextSibling = null;
    oldInternal->previousSibling = null;

    changed();

    return oldInternal;
};

NodeImpl *THIS_CLASS::replaceChild(NodeImpl *newChild, NodeImpl *oldChild)
{
    insertBefore(newChild, oldChild);
    // changed() already done.
    return removeChild(oldChild);
};

void THIS_CLASS::setReadOnly(bool readOnl, bool deep)
{
    NodeImpl::setReadOnly(readOnl, deep);

    if (deep)
        // Recursively set kids
        for (ChildNode *mykid = firstChild;
             mykid != null;
             mykid = mykid->nextSibling)
            if(! (mykid->isEntityReference()))
                mykid->setReadOnly(readOnl,true);
};

//Introduced in DOM Level 2

void THIS_CLASS::normalize()
{
    ChildNode *kid, *next;
    for (kid = firstChild; kid != null; kid = next)
    {
        next = kid->nextSibling;

        // If kid and next are both Text nodes (but _not_ CDATASection,
        // which is a subclass of Text), they can be merged.
        if (next != null &&
            kid->isTextImpl()   && !(kid->isCDATASectionImpl())  &&
            next->isTextImpl()  && !(next->isCDATASectionImpl()) )
        {
            ((TextImpl *) kid)->appendData(((TextImpl *) next)->getData());
            removeChild(next);
            if (next->nodeRefCount == 0)
                deleteIf(next);
            next = kid; // Don't advance; there might be another.
        }

        // Otherwise it might be an Element, which is handled recursively
        else
            if (kid->isElementImpl())
                kid->normalize();
    };

    // changed() will have occurred when the removeChild() was done,
    // so does not have to be reissued.
};

<commit_msg>Access violations and stack overflows in insertBefore<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

THIS_CLASS::THIS_CLASS(DocumentImpl *ownerDoc)
    : PARENT_CLASS(ownerDoc)
{
    this->ownerDocument = ownerDoc;
    this->firstChild = null;
};

// This only makes a shallow copy, cloneChildren must also be called for a
// deep clone
THIS_CLASS::THIS_CLASS(const THIS_CLASS &other)
    : PARENT_CLASS(other)
{
    this->ownerDocument = other.ownerDocument;

    // Need to break the association w/ original kids
    this->firstChild = null;
};

void THIS_CLASS::cloneChildren(const NodeImpl &other) {
  //    for (NodeImpl *mykid = other.getFirstChild();
    for (NodeImpl *mykid = ((NodeImpl&)other).getFirstChild();
         mykid != null;
         mykid = mykid->getNextSibling()) {
        this->appendChild(mykid->cloneNode(true));
    }
}

DocumentImpl * THIS_CLASS::getOwnerDocument() {
    return ownerDocument;
}

// unlike getOwnerDocument this is not overriden by DocumentImpl to return null
DocumentImpl * THIS_CLASS::getDocument() {
    return ownerDocument;
}

void THIS_CLASS::setOwnerDocument(DocumentImpl *doc) {
    ownerDocument = doc;
    for (NodeImpl *child = firstChild;
         child != null; child = child->getNextSibling()) {
        child->setOwnerDocument(doc);
    }
}

NodeListImpl *THIS_CLASS::getChildNodes() {
    return this;
};

NodeImpl * THIS_CLASS::getFirstChild() {
    return firstChild;
};

NodeImpl * THIS_CLASS::getLastChild()
{
    return lastChild();
};

ChildNode * THIS_CLASS::lastChild()
{
    // last child is stored as the previous sibling of first child
    return firstChild != null ? firstChild->previousSibling : null;
};

void THIS_CLASS::lastChild(ChildNode *node) {
        // store lastChild as previous sibling of first child
        if (firstChild != null) {
            firstChild->previousSibling = node;
        }
    }

unsigned int THIS_CLASS::getLength() {
    unsigned int count = 0;
    ChildNode *node = firstChild;
    while(node != null)
    {
        ++count;
        node = node->nextSibling;
    }
    return count;
};

bool THIS_CLASS::hasChildNodes()
{
    return firstChild!=null;
};

NodeImpl *THIS_CLASS::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {
    if (isReadOnly())
        throw DOM_DOMException(
        DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);

    if (newChild->getOwnerDocument() != ownerDocument)
        throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null);

    // Convert to internal type, to avoid repeated casting
    ChildNode * newInternal= (ChildNode *)newChild;

    // Prevent cycles in the tree
    // newChild cannot be ancestor of this Node, and actually cannot be this Node
    bool treeSafe=true;
    for(NodeImpl *a=this;
        treeSafe && a!=null;
        a=a->getParentNode())
        treeSafe=(newInternal!=a);
    if(!treeSafe)
        throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);

    // refChild must in fact be a child of this node (or null)
    if (refChild!=null && refChild->getParentNode() != this)
        throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR,null);

    // refChild cannot be same as newChild
    if(refChild==newInternal)
        throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);

    if (newInternal->isDocumentFragmentImpl())
    {
        // SLOW BUT SAFE: We could insert the whole subtree without
        // juggling so many next/previous pointers. (Wipe out the
        // parent's child-list, patch the parent pointers, set the
        // ends of the list.) But we know some subclasses have special-
        // case behavior they add to insertBefore(), so we don't risk it.
        // This approch also takes fewer bytecodes.

        // NOTE: If one of the children is not a legal child of this
        // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children
        // have been transferred. (Alternative behaviors would be to
        // reparent up to the first failure point or reparent all those
        // which are acceptable to the target node, neither of which is
        // as robust. PR-DOM-0818 isn't entirely clear on which it
        // recommends?????

        // No need to check kids for right-document; if they weren't,
        // they wouldn't be kids of that DocFrag.
        for(NodeImpl *kid=newInternal->getFirstChild(); // Prescan
        kid!=null;
        kid=kid->getNextSibling())
        {
            if (!DocumentImpl::isKidOK(this, kid))
              throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
        }
        while(newInternal->hasChildNodes())     // Move
            insertBefore(newInternal->getFirstChild(),refChild);
    }

    else if (!DocumentImpl::isKidOK(this, newInternal))
        throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);

    else
    {
        NodeImpl *oldparent=newInternal->getParentNode();
        if(oldparent!=null) {
            oldparent->removeChild(newInternal);
        }

        // Convert to internal type, to avoid repeated casting
        ChildNode *refInternal = (ChildNode *)refChild;

        // Attach up
        newInternal->ownerNode = this;
        newInternal->isOwned(true);

        // Attach before and after
        // Note: firstChild.previousSibling == lastChild!!
        if (firstChild == null) {
            // this our first and only child
            firstChild = newInternal;
            newInternal->isFirstChild(true);
            newInternal->previousSibling = newInternal;
        } else {
            if (refInternal == null) {
                // this is an append
                ChildNode *lastChild = firstChild->previousSibling;
                lastChild->nextSibling = newInternal;
                newInternal->previousSibling = lastChild;
                firstChild->previousSibling = newInternal;
            } else {
                // this is an insert
                if (refChild == firstChild) {
                    // at the head of the list
                    firstChild->isFirstChild(false);
                    newInternal->nextSibling = firstChild;
                    newInternal->previousSibling = firstChild->previousSibling;
                    firstChild->previousSibling = newInternal;
                    firstChild = newInternal;
                    newInternal->isFirstChild(true);
                } else {
                    // somewhere in the middle
                    ChildNode *prev = refInternal->previousSibling;
                    newInternal->nextSibling = refInternal;
                    prev->nextSibling = newInternal;
                    refInternal->previousSibling = newInternal;
                    newInternal->previousSibling = prev;
                }
            }
        }
    }

    changed();

    if (this->getOwnerDocument() != null) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if ( ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForInsertedNode(newInternal);
                }
            }
        }
    }

    return newInternal;
};

NodeImpl *THIS_CLASS::item(unsigned int index) {
    ChildNode *node = firstChild;
    for(unsigned int i=0; i<index && node!=null; ++i)
        node = node->nextSibling;
    return node;
};

NodeImpl *THIS_CLASS::removeChild(NodeImpl *oldChild)
{
    if (isReadOnly())
        throw DOM_DOMException(
        DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);

    if (oldChild != null && oldChild->getParentNode() != this)
        throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);

    //fix other ranges for change before deleting the node
    if (this->getOwnerDocument() !=  null  ) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if (ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != null)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }

    ChildNode * oldInternal = (ChildNode *) oldChild;

    // Patch linked list around oldChild
    // Note: lastChild == firstChild->previousSibling
    if (oldInternal == firstChild) {
        // removing first child
        oldInternal->isFirstChild(false);
        firstChild = oldInternal->nextSibling;
        if (firstChild != null) {
            firstChild->isFirstChild(true);
            firstChild->previousSibling = oldInternal->previousSibling;
        }
    } else {
        ChildNode *prev = oldInternal->previousSibling;
        ChildNode *next = oldInternal->nextSibling;
        prev->nextSibling = next;
        if (next == null) {
            // removing last child
            firstChild->previousSibling = prev;
        } else {
            // removing some other child in the middle
            next->previousSibling = prev;
        }
    }

    // Remove oldInternal's references to tree
    oldInternal->ownerNode = ownerDocument;
    oldInternal->isOwned(false);
    oldInternal->nextSibling = null;
    oldInternal->previousSibling = null;

    changed();

    return oldInternal;
};

NodeImpl *THIS_CLASS::replaceChild(NodeImpl *newChild, NodeImpl *oldChild)
{
    insertBefore(newChild, oldChild);
    // changed() already done.
    return removeChild(oldChild);
};

void THIS_CLASS::setReadOnly(bool readOnl, bool deep)
{
    NodeImpl::setReadOnly(readOnl, deep);

    if (deep)
        // Recursively set kids
        for (ChildNode *mykid = firstChild;
             mykid != null;
             mykid = mykid->nextSibling)
            if(! (mykid->isEntityReference()))
                mykid->setReadOnly(readOnl,true);
};

//Introduced in DOM Level 2

void THIS_CLASS::normalize()
{
    ChildNode *kid, *next;
    for (kid = firstChild; kid != null; kid = next)
    {
        next = kid->nextSibling;

        // If kid and next are both Text nodes (but _not_ CDATASection,
        // which is a subclass of Text), they can be merged.
        if (next != null &&
            kid->isTextImpl()   && !(kid->isCDATASectionImpl())  &&
            next->isTextImpl()  && !(next->isCDATASectionImpl()) )
        {
            ((TextImpl *) kid)->appendData(((TextImpl *) next)->getData());
            removeChild(next);
            if (next->nodeRefCount == 0)
                deleteIf(next);
            next = kid; // Don't advance; there might be another.
        }

        // Otherwise it might be an Element, which is handled recursively
        else
            if (kid->isElementImpl())
                kid->normalize();
    };

    // changed() will have occurred when the removeChild() was done,
    // so does not have to be reissued.
};

<|endoftext|>


<commit_before>// 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/proxy/proxy_bypass_rules.h"

#include "base/logging.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "net/base/net_util.h"

namespace net {

namespace {

class HostnamePatternRule : public ProxyBypassRules::Rule {
 public:
  HostnamePatternRule(const std::string& optional_scheme,
                      const std::string& hostname_pattern,
                      int optional_port)
      : optional_scheme_(StringToLowerASCII(optional_scheme)),
        hostname_pattern_(StringToLowerASCII(hostname_pattern)),
        optional_port_(optional_port) {
  }

  virtual bool Matches(const GURL& url) const {
    if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_)
      return false;  // Didn't match port expectation.

    if (!optional_scheme_.empty() && url.scheme() != optional_scheme_)
      return false;  // Didn't match scheme expectation.

    // Note it is necessary to lower-case the host, since GURL uses capital
    // letters for percent-escaped characters.
    return MatchPatternASCII(StringToLowerASCII(url.host()),
                             hostname_pattern_);
  }

  virtual std::string ToString() const {
    std::string str;
    if (!optional_scheme_.empty())
      StringAppendF(&str, "%s://", optional_scheme_.c_str());
    str += hostname_pattern_;
    if (optional_port_ != -1)
      StringAppendF(&str, ":%d", optional_port_);
    return str;
  }

 private:
  const std::string optional_scheme_;
  const std::string hostname_pattern_;
  const int optional_port_;
};

class BypassLocalRule : public ProxyBypassRules::Rule {
 public:
  virtual bool Matches(const GURL& url) const {
    const std::string& host = url.host();
    if (host == "127.0.0.1" || host == "[::1]")
      return true;
    return host.find('.') == std::string::npos;
  }

  virtual std::string ToString() const {
    return "<local>";
  }
};

// Returns true if the given string represents an IP address.
bool IsIPAddress(const std::string& domain) {
  // From GURL::HostIsIPAddress()
  url_canon::RawCanonOutputT<char, 128> ignored_output;
  url_canon::CanonHostInfo host_info;
  url_parse::Component domain_comp(0, domain.size());
  url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
                                   &ignored_output, &host_info);
  return host_info.IsIPAddress();
}

}  // namespace

ProxyBypassRules::~ProxyBypassRules() {
}

bool ProxyBypassRules::Matches(const GURL& url) const {
  for (RuleList::const_iterator it = rules_.begin(); it != rules_.end(); ++it) {
    if ((*it)->Matches(url))
      return true;
  }
  return false;
}

bool ProxyBypassRules::Equals(const ProxyBypassRules& other) const {
  if (rules_.size() != other.rules().size())
    return false;

  for (size_t i = 0; i < rules_.size(); ++i) {
    if (!rules_[i]->Equals(*other.rules()[i]))
      return false;
  }
  return true;
}

void ProxyBypassRules::ParseFromString(const std::string& raw) {
  ParseFromStringInternal(raw, false);
}

void ProxyBypassRules::ParseFromStringUsingSuffixMatching(
    const std::string& raw) {
  ParseFromStringInternal(raw, true);
}

bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme,
                                          const std::string& hostname_pattern,
                                          int optional_port) {
  if (hostname_pattern.empty())
    return false;

  rules_.push_back(new HostnamePatternRule(optional_scheme,
                                           hostname_pattern,
                                           optional_port));
  return true;
}

void ProxyBypassRules::AddRuleToBypassLocal() {
  rules_.push_back(new BypassLocalRule);
}

bool ProxyBypassRules::AddRuleFromString(const std::string& raw) {
  return AddRuleFromStringInternalWithLogging(raw, false);
}

void ProxyBypassRules::Clear() {
  rules_.clear();
}

void ProxyBypassRules::ParseFromStringInternal(
    const std::string& raw,
    bool use_hostname_suffix_matching) {
  Clear();

  StringTokenizer entries(raw, ",;");
  while (entries.GetNext()) {
    AddRuleFromStringInternalWithLogging(entries.token(),
                                         use_hostname_suffix_matching);
  }
}

bool ProxyBypassRules::AddRuleFromStringInternal(
    const std::string& raw_untrimmed,
    bool use_hostname_suffix_matching) {
  std::string raw;
  TrimWhitespaceASCII(raw_untrimmed, TRIM_ALL, &raw);

  // This is the special syntax used by WinInet's bypass list -- we allow it
  // on all platforms and interpret it the same way.
  if (LowerCaseEqualsASCII(raw, "<local>")) {
    AddRuleToBypassLocal();
    return true;
  }

  // Extract any scheme-restriction.
  std::string::size_type scheme_pos = raw.find("://");
  std::string scheme;
  if (scheme_pos != std::string::npos) {
    scheme = raw.substr(0, scheme_pos);
    raw = raw.substr(scheme_pos + 3);
    if (scheme.empty())
      return false;
  }

  if (raw.empty())
    return false;

  // If there is a forward slash in the input, it is probably a CIDR style
  // mask.
  if (raw.find('/') != std::string::npos) {
    LOG(WARNING) << "TODO: support CIDR-style proxy bypass entries "
                    "(http://crbug.com/9835)";
    return false;
  }

  // Check if we have an <ip-address>[:port] input. We need to treat this
  // separately since the IP literal may not be in a canonical form.
  std::string host;
  int port;
  if (ParseHostAndPort(raw, &host, &port)) {
    if (IsIPAddress(host)) {
      // Canonicalize the IP literal before adding it as a string pattern.
      GURL tmp_url("http://" + host);
      return AddRuleForHostname(scheme, tmp_url.host(), port);
    }
  }

  // Otherwise assume we have <hostname-pattern>[:port].
  std::string::size_type pos_colon = raw.rfind(':');
  host = raw;
  port = -1;
  if (pos_colon != std::string::npos) {
    if (!StringToInt(raw.substr(pos_colon + 1), &port) ||
        (port < 0 || port > 0xFFFF)) {
      return false;  // Port was invalid.
    }
    raw = raw.substr(0, pos_colon);
  }

  // Special-case hostnames that begin with a period.
  // For example, we remap ".google.com" --> "*.google.com".
  if (StartsWithASCII(raw, ".", false))
    raw = "*" + raw;

  // If suffix matching was asked for, make sure the pattern starts with a
  // wildcard.
  if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false))
    raw = "*" + raw;

  return AddRuleForHostname(scheme, raw, port);
}

bool ProxyBypassRules::AddRuleFromStringInternalWithLogging(
    const std::string& raw,
    bool use_hostname_suffix_matching) {
  bool ok = AddRuleFromStringInternal(raw, use_hostname_suffix_matching);
  LOG_IF(WARNING, !ok) << "Unable to parse proxy bypass rule: " << raw;
  return ok;
}

}  // namespace net
<commit_msg>Remove LOG(WARNING)s for when fails to parse proxy bypass rules. This can pollute the log since it gets hit often (each time poll for checks).<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/proxy/proxy_bypass_rules.h"

#include "base/logging.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "net/base/net_util.h"

namespace net {

namespace {

class HostnamePatternRule : public ProxyBypassRules::Rule {
 public:
  HostnamePatternRule(const std::string& optional_scheme,
                      const std::string& hostname_pattern,
                      int optional_port)
      : optional_scheme_(StringToLowerASCII(optional_scheme)),
        hostname_pattern_(StringToLowerASCII(hostname_pattern)),
        optional_port_(optional_port) {
  }

  virtual bool Matches(const GURL& url) const {
    if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_)
      return false;  // Didn't match port expectation.

    if (!optional_scheme_.empty() && url.scheme() != optional_scheme_)
      return false;  // Didn't match scheme expectation.

    // Note it is necessary to lower-case the host, since GURL uses capital
    // letters for percent-escaped characters.
    return MatchPatternASCII(StringToLowerASCII(url.host()),
                             hostname_pattern_);
  }

  virtual std::string ToString() const {
    std::string str;
    if (!optional_scheme_.empty())
      StringAppendF(&str, "%s://", optional_scheme_.c_str());
    str += hostname_pattern_;
    if (optional_port_ != -1)
      StringAppendF(&str, ":%d", optional_port_);
    return str;
  }

 private:
  const std::string optional_scheme_;
  const std::string hostname_pattern_;
  const int optional_port_;
};

class BypassLocalRule : public ProxyBypassRules::Rule {
 public:
  virtual bool Matches(const GURL& url) const {
    const std::string& host = url.host();
    if (host == "127.0.0.1" || host == "[::1]")
      return true;
    return host.find('.') == std::string::npos;
  }

  virtual std::string ToString() const {
    return "<local>";
  }
};

// Returns true if the given string represents an IP address.
bool IsIPAddress(const std::string& domain) {
  // From GURL::HostIsIPAddress()
  url_canon::RawCanonOutputT<char, 128> ignored_output;
  url_canon::CanonHostInfo host_info;
  url_parse::Component domain_comp(0, domain.size());
  url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
                                   &ignored_output, &host_info);
  return host_info.IsIPAddress();
}

}  // namespace

ProxyBypassRules::~ProxyBypassRules() {
}

bool ProxyBypassRules::Matches(const GURL& url) const {
  for (RuleList::const_iterator it = rules_.begin(); it != rules_.end(); ++it) {
    if ((*it)->Matches(url))
      return true;
  }
  return false;
}

bool ProxyBypassRules::Equals(const ProxyBypassRules& other) const {
  if (rules_.size() != other.rules().size())
    return false;

  for (size_t i = 0; i < rules_.size(); ++i) {
    if (!rules_[i]->Equals(*other.rules()[i]))
      return false;
  }
  return true;
}

void ProxyBypassRules::ParseFromString(const std::string& raw) {
  ParseFromStringInternal(raw, false);
}

void ProxyBypassRules::ParseFromStringUsingSuffixMatching(
    const std::string& raw) {
  ParseFromStringInternal(raw, true);
}

bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme,
                                          const std::string& hostname_pattern,
                                          int optional_port) {
  if (hostname_pattern.empty())
    return false;

  rules_.push_back(new HostnamePatternRule(optional_scheme,
                                           hostname_pattern,
                                           optional_port));
  return true;
}

void ProxyBypassRules::AddRuleToBypassLocal() {
  rules_.push_back(new BypassLocalRule);
}

bool ProxyBypassRules::AddRuleFromString(const std::string& raw) {
  return AddRuleFromStringInternalWithLogging(raw, false);
}

void ProxyBypassRules::Clear() {
  rules_.clear();
}

void ProxyBypassRules::ParseFromStringInternal(
    const std::string& raw,
    bool use_hostname_suffix_matching) {
  Clear();

  StringTokenizer entries(raw, ",;");
  while (entries.GetNext()) {
    AddRuleFromStringInternalWithLogging(entries.token(),
                                         use_hostname_suffix_matching);
  }
}

bool ProxyBypassRules::AddRuleFromStringInternal(
    const std::string& raw_untrimmed,
    bool use_hostname_suffix_matching) {
  std::string raw;
  TrimWhitespaceASCII(raw_untrimmed, TRIM_ALL, &raw);

  // This is the special syntax used by WinInet's bypass list -- we allow it
  // on all platforms and interpret it the same way.
  if (LowerCaseEqualsASCII(raw, "<local>")) {
    AddRuleToBypassLocal();
    return true;
  }

  // Extract any scheme-restriction.
  std::string::size_type scheme_pos = raw.find("://");
  std::string scheme;
  if (scheme_pos != std::string::npos) {
    scheme = raw.substr(0, scheme_pos);
    raw = raw.substr(scheme_pos + 3);
    if (scheme.empty())
      return false;
  }

  if (raw.empty())
    return false;

  // If there is a forward slash in the input, it is probably a CIDR style
  // mask.
  if (raw.find('/') != std::string::npos) {
    // TODO(eroman): support CIDR-style proxy bypass entries
    // (http://crbug.com/9835)
    return false;
  }

  // Check if we have an <ip-address>[:port] input. We need to treat this
  // separately since the IP literal may not be in a canonical form.
  std::string host;
  int port;
  if (ParseHostAndPort(raw, &host, &port)) {
    if (IsIPAddress(host)) {
      // Canonicalize the IP literal before adding it as a string pattern.
      GURL tmp_url("http://" + host);
      return AddRuleForHostname(scheme, tmp_url.host(), port);
    }
  }

  // Otherwise assume we have <hostname-pattern>[:port].
  std::string::size_type pos_colon = raw.rfind(':');
  host = raw;
  port = -1;
  if (pos_colon != std::string::npos) {
    if (!StringToInt(raw.substr(pos_colon + 1), &port) ||
        (port < 0 || port > 0xFFFF)) {
      return false;  // Port was invalid.
    }
    raw = raw.substr(0, pos_colon);
  }

  // Special-case hostnames that begin with a period.
  // For example, we remap ".google.com" --> "*.google.com".
  if (StartsWithASCII(raw, ".", false))
    raw = "*" + raw;

  // If suffix matching was asked for, make sure the pattern starts with a
  // wildcard.
  if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false))
    raw = "*" + raw;

  return AddRuleForHostname(scheme, raw, port);
}

bool ProxyBypassRules::AddRuleFromStringInternalWithLogging(
    const std::string& raw,
    bool use_hostname_suffix_matching) {
  return AddRuleFromStringInternal(raw, use_hostname_suffix_matching);
}

}  // namespace net
<|endoftext|>


<commit_before>#ifndef PARSER_H
#define PARSER_H
#include <vector>

//namespace definition
namespace CVRP {
  struct Node;
  struct Instance;
  class Parser;
}

//node definition
struct CVRP::Node{
   int demand;
   int x;
   int y;
};

//instance definition
struct CVRP::Instance{
   int number_of_trucks;
   int number_of_nodes;
   int capacity;
   std::vector<Node> nodes;
   std::vector<std::vector<double>> distance_matrix;
};

//parser definition
class CVRP::Parser{
    public:
      Parser();
      ~Parser();
      Instance build_problem();
      double calc_distance(Node node1, Node node2);
      void print_nodes(Instance problem_instance);
      void print_matrix(Instance problem_instance);
};

#endif
<commit_msg>Parser | Adicao de atributo de marcacao no nó<commit_after>#ifndef PARSER_H
#define PARSER_H
#include <vector>

//namespace definition
namespace CVRP {
  class Parser;
  struct Instance;
  struct Node;
}

//node definition
struct CVRP::Node{
   int demand;
   int x;
   int y;
   bool marked = false;
};

//instance definition
struct CVRP::Instance{
   int number_of_trucks;
   int number_of_nodes;
   int capacity;
   std::vector<Node> nodes;
   std::vector<std::vector<double>> distance_matrix;
};

//parser definition
class CVRP::Parser{
    public:
      Parser();
      ~Parser();
      Instance build_problem();
      double calc_distance(Node node1, Node node2);
      void print_nodes(Instance problem_instance);
      void print_matrix(Instance problem_instance);
};

#endif
<|endoftext|>


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

#include "llvmjit_internal.h"

#include "realm/logging.h"

#include <iostream>

// xcode's clang isn't defining these?
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS

#include <cstdint>

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/PassManager.h"

namespace Realm {

  extern Logger log_llvmjit;  // defined in llvmjit_module.cc

  namespace LLVMJit {

    ////////////////////////////////////////////////////////////////////////
    //
    // class LLVMJitInternal

    LLVMJitInternal::LLVMJitInternal(void)
    {
      context = new llvm::LLVMContext;

      // generative native target
      {
	llvm::InitializeNativeTarget();

	std::string triple = llvm::sys::getDefaultTargetTriple();
	log_llvmjit.debug() << "default target triple = " << triple;

	std::string err;
	const llvm::Target *target = llvm::TargetRegistry::lookupTarget(triple, err);
	if(!target) {
	  log_llvmjit.fatal() << "target not found: triple='" << triple << "'";
	  assert(0);
	}

	// TODO - allow configuration options to steer these
	llvm::Reloc::Model reloc_model = llvm::Reloc::Default;
	llvm::CodeModel::Model code_model = llvm::CodeModel::Large;
	llvm::CodeGenOpt::Level opt_level = llvm::CodeGenOpt::Aggressive;

	llvm::TargetOptions options;
	options.NoFramePointerElim = true;

	llvm::TargetMachine *host_cpu_machine = target->createTargetMachine(triple, "",
									    0/*HostHasAVX()*/ ? "+avx" : "",
									    options,
									    reloc_model,
									    code_model,
									    opt_level);
	assert(host_cpu_machine != 0);

	// you have to have a module to build an execution engine, so create
	//  a dummy one
	{
	  llvm::Module *m = new llvm::Module("eebuilder", *context);
	  m->setTargetTriple(triple);
	  llvm::EngineBuilder eb(m);

	  std::string err;

	  eb
	    .setErrorStr(&err)
	    .setEngineKind(llvm::EngineKind::JIT)
	    .setAllocateGVsWithCode(false)
	    .setUseMCJIT(true);

	  host_exec_engine = eb.create(host_cpu_machine);

	  if(!host_exec_engine) {
	    log_llvmjit.fatal() << "failed to create execution engine: " << err;
	    assert(0);
	  }
	}
      }

      nvptx_machine = 0;
    }

    LLVMJitInternal::~LLVMJitInternal(void)
    {
      delete host_exec_engine;
      delete context;
    }

    void *LLVMJitInternal::llvmir_to_fnptr(const ByteArray& ir,
					   const std::string& entry_symbol)
    {
      // do we even know how to jit?
      if(!host_exec_engine)
	return 0;

      llvm::SMDiagnostic sm;
      llvm::MemoryBuffer *mb = llvm::MemoryBuffer::getMemBuffer((const char *)ir.base());
      llvm::Module *m = llvm::ParseIR(mb, sm, *context);
      if(!m) {
	std::string errstr;
	llvm::raw_string_ostream s(errstr);
	sm.print(entry_symbol.c_str(), s);
	log_llvmjit.fatal() << "LLVM IR PARSE ERROR:\n" << s.str();
	assert(0);
      }
      m->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64");

      host_exec_engine->addModule(m);

      llvm::Function* func = host_exec_engine->FindFunctionNamed(entry_symbol.c_str());
      if(!func) {
	log_llvmjit.fatal() << "entry symbol not found: " << entry_symbol;
	assert(0);
      }

      void *fnptr = host_exec_engine->getPointerToFunction(func);
      assert(fnptr != 0);

      return fnptr;
    }

  }; // namespace LLVMJit

}; // namespace Realm
<commit_msg>llvmjit: make sure we find the entry symbol in the current LLVM blob<commit_after>/* Copyright 2016 Stanford University, NVIDIA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "llvmjit_internal.h"

#include "realm/logging.h"

#include <iostream>

// xcode's clang isn't defining these?
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS

#include <cstdint>

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/PassManager.h"

namespace Realm {

  extern Logger log_llvmjit;  // defined in llvmjit_module.cc

  namespace LLVMJit {

    ////////////////////////////////////////////////////////////////////////
    //
    // class LLVMJitInternal

    LLVMJitInternal::LLVMJitInternal(void)
    {
      context = new llvm::LLVMContext;

      // generative native target
      {
	llvm::InitializeNativeTarget();

	std::string triple = llvm::sys::getDefaultTargetTriple();
	log_llvmjit.debug() << "default target triple = " << triple;

	std::string err;
	const llvm::Target *target = llvm::TargetRegistry::lookupTarget(triple, err);
	if(!target) {
	  log_llvmjit.fatal() << "target not found: triple='" << triple << "'";
	  assert(0);
	}

	// TODO - allow configuration options to steer these
	llvm::Reloc::Model reloc_model = llvm::Reloc::Default;
	llvm::CodeModel::Model code_model = llvm::CodeModel::Large;
	llvm::CodeGenOpt::Level opt_level = llvm::CodeGenOpt::Aggressive;

	llvm::TargetOptions options;
	options.NoFramePointerElim = true;

	llvm::TargetMachine *host_cpu_machine = target->createTargetMachine(triple, "",
									    0/*HostHasAVX()*/ ? "+avx" : "",
									    options,
									    reloc_model,
									    code_model,
									    opt_level);
	assert(host_cpu_machine != 0);

	// you have to have a module to build an execution engine, so create
	//  a dummy one
	{
	  llvm::Module *m = new llvm::Module("eebuilder", *context);
	  m->setTargetTriple(triple);
	  m->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64");
	  llvm::EngineBuilder eb(m);

	  std::string err;

	  eb
	    .setErrorStr(&err)
	    .setEngineKind(llvm::EngineKind::JIT)
	    .setAllocateGVsWithCode(false)
	    .setUseMCJIT(true);

	  host_exec_engine = eb.create(host_cpu_machine);

	  if(!host_exec_engine) {
	    log_llvmjit.fatal() << "failed to create execution engine: " << err;
	    assert(0);
	  }
	}
      }

      nvptx_machine = 0;
    }

    LLVMJitInternal::~LLVMJitInternal(void)
    {
      delete host_exec_engine;
      delete context;
    }

    void *LLVMJitInternal::llvmir_to_fnptr(const ByteArray& ir,
					   const std::string& entry_symbol)
    {
      // do we even know how to jit?
      if(!host_exec_engine)
	return 0;

      llvm::SMDiagnostic sm;
      llvm::MemoryBuffer *mb = llvm::MemoryBuffer::getMemBuffer((const char *)ir.base());
      llvm::Module *m = llvm::ParseIR(mb, sm, *context);
      if(!m) {
	std::string errstr;
	llvm::raw_string_ostream s(errstr);
	sm.print(entry_symbol.c_str(), s);
	log_llvmjit.fatal() << "LLVM IR PARSE ERROR:\n" << s.str();
	assert(0);
      }

      // get the entry function from the module before we add it to the exec engine - that way
      //  we're sure to get the one we want
      llvm::Function *func = m->getFunction(entry_symbol.c_str());
      if(!func) {
	log_llvmjit.fatal() << "entry symbol not found: " << entry_symbol;
	assert(0);
      }

      host_exec_engine->addModule(m);

      void *fnptr = host_exec_engine->getPointerToFunction(func);
      assert(fnptr != 0);

      return fnptr;
    }

  }; // namespace LLVMJit

}; // namespace Realm
<|endoftext|>


<commit_before>#ifndef DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH
#define DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH

// local includes
#include "vector.hh"

namespace Dune
{

namespace Functionals
{

namespace Assembler
{

namespace Local
{

namespace Codim0
{

template< class LocalOperatorImp >
class Matrix
{
public:

  typedef LocalOperatorImp
    LocalOperatorType;

  typedef Matrix< LocalOperatorType >
    ThisType;

  typedef typename LocalOperatorType::RangeFieldType
    RangeFieldType;

  template< class InducingDiscreteFunctionType >
  class LocalVectorAssembler
  {
  private:
    typedef typename LocalOperatorType::template LocalFunctional< InducingDiscreteFunctionType >::Type
      InducingFunctionalType;

  public:
    typedef Dune::Functionals::Assembler::Local::Codim0::Vector< InducingFunctionalType >
      Type;
  };

  //! constructor
  Matrix( const LocalOperatorType& localOperator )
    : localOperator_( localOperator )
  {
  }

private:
  //! copy constructor
  Matrix( const ThisType& other )
    : localOperator_( other.localOperator() )
  {
  }

public:
  const LocalOperatorType& localOperator() const
  {
    return localOperator_;
  }

  template< class InducingDiscreteFunctionType >
  typename LocalVectorAssembler< InducingDiscreteFunctionType >::Type localVectorAssembler( const InducingDiscreteFunctionType& inducingDiscreteFunction ) const
  {
    typedef typename LocalVectorAssembler< InducingDiscreteFunctionType >::Type
      LocalVectorAssemblerType;

    return LocalVectorAssemblerType( localOperator_.localFunctional( inducingDiscreteFunction ) );
  }

  template< class AnsatzSpaceType,
            class TestSpaceType,
            class EntityType,
            class MatrixType,
            class LocalMatrixType >
  void assembleLocal( const AnsatzSpaceType& ansatzSpace,
                      const TestSpaceType& testSpace,
                      const EntityType& entity,
                      MatrixType& matrix,
                      LocalMatrixType& tmpLocalMatrix ) const
  {
    // write local operator application to tmpLocalMatrix
    localOperator_.applyLocal( ansatzSpace.baseFunctionSet().local( entity ), testSpace.baseFunctionSet().local( entity ), tmpLocalMatrix );

    // write local matrix to global
    addToMatrix( ansatzSpace, testSpace, entity, tmpLocalMatrix, matrix );
  }

private:

  //! assignment operator
  ThisType& operator=( const ThisType& );

  template< class AnsatzSpaceType,
            class TestSpaceType,
            class EntityType,
            class LocalMatrixType,
            class MatrixType >
  void addToMatrix( const AnsatzSpaceType& ansatzSpace,
                    const TestSpaceType& testSpace,
                    const EntityType& entity,
                    const LocalMatrixType& localMatrix,
                    MatrixType& matrix ) const
  {
    for( unsigned int i = 0; i < ansatzSpace.baseFunctionSet().local( entity ).size(); ++i )
    {
      for( unsigned int j = 0; j < testSpace.baseFunctionSet().local( entity ).size(); ++j )
      {
        const unsigned int globalI = ansatzSpace.map().toGlobal( entity, i );
        const unsigned int globalJ = testSpace.map().toGlobal( entity, j );

        matrix[globalI][globalJ] += localMatrix[i][j];
      }
    }
  } // end method addToMatrix

  const LocalOperatorType& localOperator_;

}; // end class Matrix

} // end namespace Codim0

} // end namespace Local

} // end namespace Assembler

} // end namespace Functionals

} // end namespace Dune

#endif // DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH
<commit_msg>some beautyfication<commit_after>#ifndef DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH
#define DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH

// local includes
#include "vector.hh"

namespace Dune
{

namespace Functionals
{

namespace Assembler
{

namespace Local
{

namespace Codim0
{

template< class LocalOperatorImp >
class Matrix
{
public:

  typedef LocalOperatorImp
    LocalOperatorType;

  typedef Matrix< LocalOperatorType >
    ThisType;

  typedef typename LocalOperatorType::RangeFieldType
    RangeFieldType;

  template< class InducingDiscreteFunctionType >
  class LocalVectorAssembler
  {
  private:
    typedef typename LocalOperatorType::template LocalFunctional< InducingDiscreteFunctionType >::Type
      InducingFunctionalType;

  public:
    typedef Dune::Functionals::Assembler::Local::Codim0::Vector< InducingFunctionalType >
      Type;
  };

  //! constructor
  Matrix( const LocalOperatorType& localOperator )
    : localOperator_( localOperator )
  {
  }

private:
  //! copy constructor
  Matrix( const ThisType& other )
    : localOperator_( other.localOperator() )
  {
  }

public:
  const LocalOperatorType& localOperator() const
  {
    return localOperator_;
  }

  template< class InducingDiscreteFunctionType >
  typename LocalVectorAssembler< InducingDiscreteFunctionType >::Type
    localVectorAssembler( const InducingDiscreteFunctionType& inducingDiscreteFunction ) const
  {
    typedef typename LocalVectorAssembler< InducingDiscreteFunctionType >::Type
      LocalVectorAssemblerType;

    return LocalVectorAssemblerType( localOperator_.localFunctional( inducingDiscreteFunction ) );
  }

  template< class AnsatzSpaceType,
            class TestSpaceType,
            class EntityType,
            class MatrixType,
            class LocalMatrixType >
  void assembleLocal( const AnsatzSpaceType& ansatzSpace,
                      const TestSpaceType& testSpace,
                      const EntityType& entity,
                      MatrixType& matrix,
                      LocalMatrixType& tmpLocalMatrix ) const
  {
    // write local operator application to tmpLocalMatrix
    localOperator_.applyLocal(  ansatzSpace.baseFunctionSet().local( entity ),
                                testSpace.baseFunctionSet().local( entity ),
                                tmpLocalMatrix );

    // write local matrix to global
    addToMatrix( ansatzSpace, testSpace, entity, tmpLocalMatrix, matrix );
  }

private:

  //! assignment operator
  ThisType& operator=( const ThisType& );

  template< class AnsatzSpaceType,
            class TestSpaceType,
            class EntityType,
            class LocalMatrixType,
            class MatrixType >
  void addToMatrix( const AnsatzSpaceType& ansatzSpace,
                    const TestSpaceType& testSpace,
                    const EntityType& entity,
                    const LocalMatrixType& localMatrix,
                    MatrixType& matrix ) const
  {
    for( unsigned int i = 0; i < ansatzSpace.baseFunctionSet().local( entity ).size(); ++i )
    {
      for( unsigned int j = 0; j < testSpace.baseFunctionSet().local( entity ).size(); ++j )
      {
        const unsigned int globalI = ansatzSpace.map().toGlobal( entity, i );
        const unsigned int globalJ = testSpace.map().toGlobal( entity, j );

        matrix[globalI][globalJ] += localMatrix[i][j];
      }
    }
  } // end method addToMatrix

  const LocalOperatorType& localOperator_;

}; // end class Matrix

} // end namespace Codim0

} // end namespace Local

} // end namespace Assembler

} // end namespace Functionals

} // end namespace Dune

#endif // DUNE_FUNCTIONALS_ASSEMLBER_LOCAL_CODIM0_MATRIX_HH
<|endoftext|>


<commit_before>/*************************************************************************
> File Name: Interface.cpp
> Project Name: Hearthstone++
> Author: Young-Joong Kim
> Purpose: Interface for Hearthstone Game Agent
> Created Time: 2017/10/04
> Copyright (c) 2017, Young-Joong Kim
*************************************************************************/
#include <Agents/Interface.h>

namespace Hearthstonepp
{
	InteractBuffer::InteractBuffer(int capacity)
	{
		this->capacity = capacity; // size of the buffer
		this->head = 0;
		this->tail = 0;
		this->usage = 0; // size of the data in the buffer
		this->readable = false; // whether the buffer has data
		this->buffer = new BYTE[capacity]; // buffer, circular queue
	}

	int InteractBuffer::ReadBuffer(BYTE *data, int maxSize)
	{
		std::unique_lock<std::mutex> lock(mtx);
		cv.wait(lock, [this]() { return readable; }); // wait until the buffer can be read

		int read = 0;
		for (int i = 0; (i < usage) && maxSize; ++i) // read data from buffer
		{
			data[i] = buffer[head];

			head = (head + 1) % capacity;
			maxSize -= 1;
			read += 1;
		}

		usage -= read; // calculate remaining capacity to read

		readable = false;
		cv.notify_one(); // inform buffer is writable

		return read;
	}

	int InteractBuffer::WriteBuffer(BYTE *data, int size)
	{
		std::unique_lock<std::mutex> lock(mtx);
		cv.wait(lock, [this]() { return !readable; }); // wait until the buffer can be write

		for (int i = 0; (i < size) && (usage < capacity); ++i) // write data to buffer
		{
			buffer[tail] = data[i];

			tail = (tail + 1) % capacity;
			usage += 1;
		}

		readable = true;
		cv.notify_one(); // inform buffer is readable

		return usage;
	}
}<commit_msg>Update Interface - InteractBuffer ctor initialize with list<commit_after>/*************************************************************************
> File Name: Interface.cpp
> Project Name: Hearthstone++
> Author: Young-Joong Kim
> Purpose: Interface for Hearthstone Game Agent
> Created Time: 2017/10/04
> Copyright (c) 2017, Young-Joong Kim
*************************************************************************/
#include <Agents/Interface.h>

namespace Hearthstonepp
{
	InteractBuffer::InteractBuffer(int capacity)
		: capacity(capacity), head(0), tail(0), usage(0), readable(false)
	{
		buffer = new BYTE[capacity]; // buffer, circular queue
	}

	int InteractBuffer::ReadBuffer(BYTE *data, int maxSize)
	{
		std::unique_lock<std::mutex> lock(mtx);
		cv.wait(lock, [this]() { return readable; }); // wait until the buffer can be read

		int read = 0;
		for (int i = 0; (i < usage) && maxSize; ++i) // read data from buffer
		{
			data[i] = buffer[head];

			head = (head + 1) % capacity;
			maxSize -= 1;
			read += 1;
		}

		usage -= read; // calculate remaining capacity to read

		readable = false;
		cv.notify_one(); // inform buffer is writable

		return read;
	}

	int InteractBuffer::WriteBuffer(BYTE *data, int size)
	{
		std::unique_lock<std::mutex> lock(mtx);
		cv.wait(lock, [this]() { return !readable; }); // wait until the buffer can be write

		for (int i = 0; (i < size) && (usage < capacity); ++i) // write data to buffer
		{
			buffer[tail] = data[i];

			tail = (tail + 1) % capacity;
			usage += 1;
		}

		readable = true;
		cv.notify_one(); // inform buffer is readable

		return usage;
	}
}<|endoftext|>