<commit_before>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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 "string.h"

#include "array.h"
#include "gc/accounting/card_table-inl.h"
#include "intern_table.h"
#include "object-inl.h"
#include "runtime.h"
#include "sirt_ref.h"
#include "thread.h"
#include "utf.h"

namespace art {
namespace mirror {

const CharArray* String::GetCharArray() const {
  return GetFieldObject<const CharArray*>(ValueOffset(), false);
}

void String::ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
}

int32_t String::GetUtfLength() const {
  return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
}

int32_t String::FastIndexOf(int32_t ch, int32_t start) const {
  int32_t count = GetLength();
  if (start < 0) {
    start = 0;
  } else if (start > count) {
    start = count;
  }
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  const uint16_t* p = chars + start;
  const uint16_t* end = chars + count;
  while (p < end) {
    if (*p++ == ch) {
      return (p - 1) - chars;
    }
  }
  return -1;
}

void String::SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  DCHECK(new_array != NULL);
  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
}

// TODO: get global references for these
Class* String::java_lang_String_ = NULL;

void String::SetClass(Class* java_lang_String) {
  CHECK(java_lang_String_ == NULL);
  CHECK(java_lang_String != NULL);
  java_lang_String_ = java_lang_String;
}

void String::ResetClass() {
  CHECK(java_lang_String_ != NULL);
  java_lang_String_ = NULL;
}

String* String::Intern() {
  return Runtime::Current()->GetInternTable()->InternWeak(this);
}

int32_t String::GetHashCode() {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  if (result == 0) {
    ComputeHashCode();
  }
  result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
          << ToModifiedUtf8() << " " << result;
  return result;
}

int32_t String::GetLength() const {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
  DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
  return result;
}

uint16_t String::CharAt(int32_t index) const {
  // TODO: do we need this? Equals is the only caller, and could
  // bounds check itself.
  if (index < 0 || index >= count_) {
    Thread* self = Thread::Current();
    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    self->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
                             "length=%i; index=%i", count_, index);
    return 0;
  }
  return GetCharArray()->Get(index + GetOffset());
}

String* String::AllocFromUtf16(Thread* self,
                               int32_t utf16_length,
                               const uint16_t* utf16_data_in,
                               int32_t hash_code) {
  CHECK(utf16_data_in != NULL || utf16_length == 0);
  String* string = Alloc(self, GetJavaLangString(), utf16_length);
  if (string == NULL) {
    return NULL;
  }
  // TODO: use 16-bit wide memset variant
  CharArray* array = const_cast<CharArray*>(string->GetCharArray());
  if (array == NULL) {
    return NULL;
  }
  for (int i = 0; i < utf16_length; i++) {
    array->Set(i, utf16_data_in[i]);
  }
  if (hash_code != 0) {
    string->SetHashCode(hash_code);
  } else {
    string->ComputeHashCode();
  }
  return string;
}

  String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
  if (utf == NULL) {
    return NULL;
  }
  size_t char_count = CountModifiedUtf8Chars(utf);
  return AllocFromModifiedUtf8(self, char_count, utf);
}

String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
                                      const char* utf8_data_in) {
  String* string = Alloc(self, GetJavaLangString(), utf16_length);
  if (string == NULL) {
    return NULL;
  }
  uint16_t* utf16_data_out =
      const_cast<uint16_t*>(string->GetCharArray()->GetData());
  ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
  string->ComputeHashCode();
  return string;
}

String* String::Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length) {
  SirtRef<CharArray> array(self, CharArray::Alloc(self, utf16_length));
  if (array.get() == NULL) {
    return NULL;
  }
  return Alloc(self, java_lang_String, array.get());
}

String* String::Alloc(Thread* self, Class* java_lang_String, CharArray* array) {
  // Hold reference in case AllocObject causes GC.
  SirtRef<CharArray> array_ref(self, array);
  String* string = down_cast<String*>(java_lang_String->AllocObject(self));
  if (string == NULL) {
    return NULL;
  }
  string->SetArray(array);
  string->SetCount(array->GetLength());
  return string;
}

bool String::Equals(const String* that) const {
  if (this == that) {
    // Quick reference equality test
    return true;
  } else if (that == NULL) {
    // Null isn't an instanceof anything
    return false;
  } else if (this->GetLength() != that->GetLength()) {
    // Quick length inequality test
    return false;
  } else {
    // Note: don't short circuit on hash code as we're presumably here as the
    // hash code was already equal
    for (int32_t i = 0; i < that->GetLength(); ++i) {
      if (this->CharAt(i) != that->CharAt(i)) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
  if (this->GetLength() != that_length) {
    return false;
  } else {
    for (int32_t i = 0; i < that_length; ++i) {
      if (this->CharAt(i) != that_chars[that_offset + i]) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const char* modified_utf8) const {
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
    if (ch == '\0' || ch != CharAt(i)) {
      return false;
    }
  }
  return *modified_utf8 == '\0';
}

bool String::Equals(const StringPiece& modified_utf8) const {
  if (modified_utf8.size() != GetLength()) {
    return false;
  }
  const char* p = modified_utf8.data();
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&p);
    if (ch != CharAt(i)) {
      return false;
    }
  }
  return true;
}

// Create a modified UTF-8 encoded std::string from a java/lang/String object.
std::string String::ToModifiedUtf8() const {
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  size_t byte_count = GetUtfLength();
  std::string result(byte_count, static_cast<char>(0));
  ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
  return result;
}

#ifdef HAVE__MEMCMP16
// "count" is in 16-bit units.
extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
#define MemCmp16 __memcmp16
#else
static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
  for (size_t i = 0; i < count; i++) {
    if (s0[i] != s1[i]) {
      return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
    }
  }
  return 0;
}
#endif

int32_t String::CompareTo(String* rhs) const {
  // Quick test for comparison of a string with itself.
  const String* lhs = this;
  if (lhs == rhs) {
    return 0;
  }
  // TODO: is this still true?
  // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
  // because the interpreter converts the characters to 32-bit integers
  // *without* sign extension before it subtracts them (which makes some
  // sense since "char" is unsigned).  So what we get is the result of
  // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
  int lhsCount = lhs->GetLength();
  int rhsCount = rhs->GetLength();
  int countDiff = lhsCount - rhsCount;
  int minCount = (countDiff < 0) ? lhsCount : rhsCount;
  const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
  const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
  int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
  if (otherRes != 0) {
    return otherRes;
  }
  return countDiff;
}

}  // namespace mirror
}  // namespace art

<commit_msg>Use unsigned comparison in String::CharAt.<commit_after>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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 "string.h"

#include "array.h"
#include "gc/accounting/card_table-inl.h"
#include "intern_table.h"
#include "object-inl.h"
#include "runtime.h"
#include "sirt_ref.h"
#include "thread.h"
#include "utf.h"

namespace art {
namespace mirror {

const CharArray* String::GetCharArray() const {
  return GetFieldObject<const CharArray*>(ValueOffset(), false);
}

void String::ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
}

int32_t String::GetUtfLength() const {
  return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
}

int32_t String::FastIndexOf(int32_t ch, int32_t start) const {
  int32_t count = GetLength();
  if (start < 0) {
    start = 0;
  } else if (start > count) {
    start = count;
  }
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  const uint16_t* p = chars + start;
  const uint16_t* end = chars + count;
  while (p < end) {
    if (*p++ == ch) {
      return (p - 1) - chars;
    }
  }
  return -1;
}

void String::SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  DCHECK(new_array != NULL);
  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
}

// TODO: get global references for these
Class* String::java_lang_String_ = NULL;

void String::SetClass(Class* java_lang_String) {
  CHECK(java_lang_String_ == NULL);
  CHECK(java_lang_String != NULL);
  java_lang_String_ = java_lang_String;
}

void String::ResetClass() {
  CHECK(java_lang_String_ != NULL);
  java_lang_String_ = NULL;
}

String* String::Intern() {
  return Runtime::Current()->GetInternTable()->InternWeak(this);
}

int32_t String::GetHashCode() {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  if (result == 0) {
    ComputeHashCode();
  }
  result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
          << ToModifiedUtf8() << " " << result;
  return result;
}

int32_t String::GetLength() const {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
  DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
  return result;
}

uint16_t String::CharAt(int32_t index) const {
  // TODO: do we need this? Equals is the only caller, and could
  // bounds check itself.
  DCHECK_GE(count_, 0);  // ensures the unsigned comparison is safe.
  if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(count_))) {
    Thread* self = Thread::Current();
    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    self->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
                             "length=%i; index=%i", count_, index);
    return 0;
  }
  return GetCharArray()->Get(index + GetOffset());
}

String* String::AllocFromUtf16(Thread* self,
                               int32_t utf16_length,
                               const uint16_t* utf16_data_in,
                               int32_t hash_code) {
  CHECK(utf16_data_in != NULL || utf16_length == 0);
  String* string = Alloc(self, GetJavaLangString(), utf16_length);
  if (string == NULL) {
    return NULL;
  }
  // TODO: use 16-bit wide memset variant
  CharArray* array = const_cast<CharArray*>(string->GetCharArray());
  if (array == NULL) {
    return NULL;
  }
  for (int i = 0; i < utf16_length; i++) {
    array->Set(i, utf16_data_in[i]);
  }
  if (hash_code != 0) {
    string->SetHashCode(hash_code);
  } else {
    string->ComputeHashCode();
  }
  return string;
}

  String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
  if (utf == NULL) {
    return NULL;
  }
  size_t char_count = CountModifiedUtf8Chars(utf);
  return AllocFromModifiedUtf8(self, char_count, utf);
}

String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
                                      const char* utf8_data_in) {
  String* string = Alloc(self, GetJavaLangString(), utf16_length);
  if (string == NULL) {
    return NULL;
  }
  uint16_t* utf16_data_out =
      const_cast<uint16_t*>(string->GetCharArray()->GetData());
  ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
  string->ComputeHashCode();
  return string;
}

String* String::Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length) {
  SirtRef<CharArray> array(self, CharArray::Alloc(self, utf16_length));
  if (array.get() == NULL) {
    return NULL;
  }
  return Alloc(self, java_lang_String, array.get());
}

String* String::Alloc(Thread* self, Class* java_lang_String, CharArray* array) {
  // Hold reference in case AllocObject causes GC.
  SirtRef<CharArray> array_ref(self, array);
  String* string = down_cast<String*>(java_lang_String->AllocObject(self));
  if (string == NULL) {
    return NULL;
  }
  string->SetArray(array);
  string->SetCount(array->GetLength());
  return string;
}

bool String::Equals(const String* that) const {
  if (this == that) {
    // Quick reference equality test
    return true;
  } else if (that == NULL) {
    // Null isn't an instanceof anything
    return false;
  } else if (this->GetLength() != that->GetLength()) {
    // Quick length inequality test
    return false;
  } else {
    // Note: don't short circuit on hash code as we're presumably here as the
    // hash code was already equal
    for (int32_t i = 0; i < that->GetLength(); ++i) {
      if (this->CharAt(i) != that->CharAt(i)) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
  if (this->GetLength() != that_length) {
    return false;
  } else {
    for (int32_t i = 0; i < that_length; ++i) {
      if (this->CharAt(i) != that_chars[that_offset + i]) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const char* modified_utf8) const {
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
    if (ch == '\0' || ch != CharAt(i)) {
      return false;
    }
  }
  return *modified_utf8 == '\0';
}

bool String::Equals(const StringPiece& modified_utf8) const {
  if (modified_utf8.size() != GetLength()) {
    return false;
  }
  const char* p = modified_utf8.data();
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&p);
    if (ch != CharAt(i)) {
      return false;
    }
  }
  return true;
}

// Create a modified UTF-8 encoded std::string from a java/lang/String object.
std::string String::ToModifiedUtf8() const {
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  size_t byte_count = GetUtfLength();
  std::string result(byte_count, static_cast<char>(0));
  ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
  return result;
}

#ifdef HAVE__MEMCMP16
// "count" is in 16-bit units.
extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
#define MemCmp16 __memcmp16
#else
static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
  for (size_t i = 0; i < count; i++) {
    if (s0[i] != s1[i]) {
      return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
    }
  }
  return 0;
}
#endif

int32_t String::CompareTo(String* rhs) const {
  // Quick test for comparison of a string with itself.
  const String* lhs = this;
  if (lhs == rhs) {
    return 0;
  }
  // TODO: is this still true?
  // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
  // because the interpreter converts the characters to 32-bit integers
  // *without* sign extension before it subtracts them (which makes some
  // sense since "char" is unsigned).  So what we get is the result of
  // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
  int lhsCount = lhs->GetLength();
  int rhsCount = rhs->GetLength();
  int countDiff = lhsCount - rhsCount;
  int minCount = (countDiff < 0) ? lhsCount : rhsCount;
  const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
  const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
  int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
  if (otherRes != 0) {
    return otherRes;
  }
  return countDiff;
}

}  // namespace mirror
}  // namespace art

<|endoftext|>


<commit_before>//
//  main.cpp
//  udpforwarder
//
//  Created by Shakthi Prasad G S on 23/10/16.
//  Copyright © 2016 self. All rights reserved.
//

#include <iostream>
#include <string>

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

/* udp-repeater
 *
 * example of use
 *
 *   udp-reflector -p 6180 -l localhost -a node1.net:2222 -b node2.net:2222
 *
 * This causes udp-reflector to listen on the local matchine (port 6180;
 * you can also bind a particular local IP address with the -l flag).
 * Whenever a UDP datagram is received from a, it is re-sent to destination b
 * (specified with the -b flag), and vice versa
 *
 * To test it, run udp-repeater with appropriate arguments, set up a sink
 * to receive the datagrams somewhere, like:
 *
 *   destination1% nc -l -u 6180
 *
 * then generate some UDP datagrams to the repeater, e.g.,
 *
 *   somewhere% echo hi | nc -4 -u repeater-host 6180
 *
 * you sould see the udp datagram repeated on destination1.
 *
 * NOTE: when using nc to generate traffic, if you omit the -4 flag
 *       and use a name (such as localhost) instead of an IPv4 address
 *       nc will use an IPv6 UDP datagram, which udp-repeater does not
 *       currently accept.
 *
 */

#define BUFSZ 2000
char buf[BUFSZ];
char *ip,*prog;
int port;

int verbose;

struct sockaddr_in dest;

void usage() {
    fprintf(stderr, "usage: %s [-v] [-l <bind-addr>] "
            "-p <bindport> -s <host>[:<port>] [-S sourceport] ...\n", prog);
    exit(-1);
}

class SocketAddress
{
    struct sockaddr_in socketAddress;

    sockaddr_in getAddress(std::string address)
    {
        std::string::size_type colonpos=address.find(':');
        if(colonpos == std::string::npos)
        {
            std::cerr <<"Unformated address"<<address<<" host:port format expected"<<std::endl;
            exit(-1);
        }

        std::string host= address.substr(0,colonpos);
        std::string port= address.substr(colonpos);

        sockaddr_in dest;

        dest.sin_family = AF_INET;
        dest.sin_port = htons(atoi(port.c_str()));
        struct hostent *h = gethostbyname(host.c_str());
        if (!h || !h->h_length) {
            fprintf(stderr, "could not resolve %s: %s\n", host.c_str(), hstrerror(h_errno));
            exit(-1);
        }

        memcpy(&dest.sin_addr, h->h_addr, h->h_length);
        if (dest.sin_addr.s_addr == INADDR_NONE) {
            fprintf(stderr, "invalid IP address for %s\n", host.c_str());
            exit(-1);
        }

        if (verbose) fprintf(stderr,"repeat-to %s (%s):%d\n", host.c_str(),
                             inet_ntoa(dest.sin_addr), atoi(port.c_str()));

        return dest;
    }

public:
    static int fd;

    SocketAddress()
    {}
    SocketAddress(std::string hostport)
    {
        initialized=true;
        socketAddress = getAddress(hostport);
    }

    SocketAddress(sockaddr_in addr)
    {
        initialized=true;
        socketAddress = addr;
    }

    bool operator==(const SocketAddress & bAddress) const
    {
        return socketAddress.sin_addr.s_addr  == bAddress.socketAddress.sin_addr.s_addr &&
        socketAddress.sin_port == bAddress.socketAddress.sin_port;

    }

    bool initialized = false;

    bool Send(void * buffer,size_t len)
    {

        ssize_t sc = sendto(fd, buffer, len, 0, (struct sockaddr*)&socketAddress, sizeof(&socketAddress));
        if (sc != len) {
            fprintf(stderr, "sendto %s: %s\n", inet_ntoa(socketAddress.sin_addr),
                    (sc==0)?strerror(errno):"partial write");
            exit(-1);
        }
       return true;
    }

    static const SocketAddress ReciveAny(void * buffer,size_t & len)
    {

        struct sockaddr_in cin;
        socklen_t cin_sz = sizeof(cin);

        size_t rc = recvfrom(fd,buf,BUFSZ,0,(struct sockaddr*)&cin,&cin_sz);
        len = rc;
        return SocketAddress(cin);

    }

};

int SocketAddress::fd;

int main(int argc, const char** argv) {

    const char* n_argv[] = { "udpforaward", "-vp", "7000", "-s","localhost:7001"};
    argv = n_argv;
    argc=7;

     prog = strdup(argv[0]);
    char  opt;

    bool aset=false,bset=false;
    SocketAddress sa;
    SocketAddress sb;

    while ( (opt = getopt(argc, (char* * const )argv, "v+l:p:a:b:")) != -1) {
        switch (opt) {
                case 'v': verbose++; break;
                case 'l': ip = strdup(optarg); break;
                case 'p': port = atoi(optarg); break;
                case 'a': sa = SocketAddress(optarg);aset=true; break;
                case 'b': sb = SocketAddress(optarg);bset=true; break;
            default: usage(); break;
        }
    }

    if (!port) usage();

    in_addr_t listen_addr;
    if (ip) {
        if ( (listen_addr = inet_addr(ip)) == INADDR_NONE) {
            fprintf(stderr,"invalid listener IP address: %s\n", ip);
            exit(-1);
        }
    } else {
        listen_addr = htonl(INADDR_ANY);
        ip = strdup("all-local-addresses");
    }
    if (verbose) fprintf(stderr, "local address: %s:%d\n", ip, port);

    /**********************************************************
     * create two IPv4/UDP sockets, for listener and repeater
     *********************************************************/
    SocketAddress::fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (SocketAddress::fd == -1 ) { fprintf(stderr,"socket error\n"); exit(-1); }

    /**********************************************************
     * internet socket address structure: our address and port
     *********************************************************/
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = listen_addr;
    sin.sin_port = htons(port);

    /**********************************************************
     * bind socket to address and port we'd like to receive on
     *********************************************************/
    if (bind(SocketAddress::fd, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
        fprintf(stderr, "listen bind to %s:%d failed: %s\n", ip, port, strerror(errno));
        exit(-1);
    }

    while (true)  {

        /**********************************************************
         * uses recvfrom to get data along with client address/port
         *********************************************************/

        size_t len;
        SocketAddress recivedAddress = SocketAddress::ReciveAny(buf, len);

        if(sa.initialized && sb.initialized)
        {
            if(recivedAddress == sa)
            {
                sb.Send(buf, len);
            }

            else if(recivedAddress == sb)
            {
                sa.Send(buf, len);
            }
            else
            {
                printf("Discarding ");
            }
        }else if(sa.initialized && ! sb.initialized)
        {

            if(!(recivedAddress==sa))
            {
                sb= recivedAddress;

            }else
            {
                printf("Discarding  ");
            }

        }else if (!sa.initialized && ! sb.initialized)
        {

            sa = recivedAddress;

        }

    }

}<commit_msg>Connection establishment<commit_after>//
//  main.cpp
//  udpforwarder
//
//  Created by Shakthi Prasad G S on 23/10/16.
//  Copyright © 2016 self. All rights reserved.
//

#include <iostream>
#include <string>

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <poll.h>

/* udp-repeater
 *
 * example of use
 *
 *   udp-reflector -p 6180 -l localhost -a node1.net:2222 -b node2.net:2222
 *
 * This causes udp-reflector to listen on the local matchine (port 6180;
 * you can also bind a particular local IP address with the -l flag).
 * Whenever a UDP datagram is received from a, it is re-sent to destination b
 * (specified with the -b flag), and vice versa
 *
 * To test it, run udp-repeater with appropriate arguments, set up a sink
 * to receive the datagrams somewhere, like:
 *
 *   destination1% nc -l -u 6180
 *
 * then generate some UDP datagrams to the repeater, e.g.,
 *
 *   somewhere% echo hi | nc -4 -u repeater-host 6180
 *
 * you sould see the udp datagram repeated on destination1.
 *
 * NOTE: when using nc to generate traffic, if you omit the -4 flag
 *       and use a name (such as localhost) instead of an IPv4 address
 *       nc will use an IPv6 UDP datagram, which udp-repeater does not
 *       currently accept.
 *
 */

#define BUFSZ 2000
char buf[BUFSZ];
char *ip,*prog;
int port;

int verbose;

struct sockaddr_in dest;

void usage() {
    fprintf(stderr, "usage: %s [-v] [-l <bind-addr>] "
            "-p <bindport> -s <host>[:<port>] [-S sourceport] ...\n", prog);
    exit(-1);
}

class SocketAddress
{
    struct sockaddr_in socketAddress;

    sockaddr_in getAddress(std::string address)
    {
        std::string::size_type colonpos=address.find(':');
        if(colonpos == std::string::npos)
        {
            std::cerr <<"Unformated address"<<address<<" host:port format expected"<<std::endl;
            exit(-1);
        }

        std::string host= address.substr(0,colonpos);
        std::string port= address.substr(colonpos+1);

        sockaddr_in dest;

        dest.sin_family = AF_INET;
        dest.sin_port = htons(atoi(port.c_str()));
        struct hostent *h = gethostbyname(host.c_str());
        if (!h || !h->h_length) {
            fprintf(stderr, "could not resolve %s: %s\n", host.c_str(), hstrerror(h_errno));
            exit(-1);
        }

        memcpy(&dest.sin_addr, h->h_addr, h->h_length);
        if (dest.sin_addr.s_addr == INADDR_NONE) {
            fprintf(stderr, "invalid IP address for %s\n", host.c_str());
            exit(-1);
        }

        if (verbose) fprintf(stderr,"repeat-to %s (%s):%d\n", host.c_str(),
                             inet_ntoa(dest.sin_addr), atoi(port.c_str()));

        return dest;
    }

public:
    static int fd;

    SocketAddress()
    {}
    SocketAddress(std::string hostport)
    {
        initialized=true;
        socketAddress = getAddress(hostport);
    }

    SocketAddress(sockaddr_in addr)
    {
        initialized=true;
        socketAddress = addr;
    }

    bool operator==(const SocketAddress & bAddress) const
    {
        return socketAddress.sin_addr.s_addr  == bAddress.socketAddress.sin_addr.s_addr &&
        socketAddress.sin_port == bAddress.socketAddress.sin_port;

    }

    bool initialized = false;

    const std::string  to_string()
    {
        std::string address =inet_ntoa(socketAddress.sin_addr);
        address+=":";

        address+=std::to_string(ntohs(socketAddress.sin_port) );

        return address;

    }
    bool Send(void * buffer,size_t len)
    {

        ssize_t sc = sendto(fd, buffer, len, 0, (struct sockaddr*)&socketAddress, sizeof(&socketAddress));
        if (sc != len) {
            fprintf(stderr, "sendto %s: %s\n", inet_ntoa(socketAddress.sin_addr),
                    (sc==0)?strerror(errno):"partial write");
            exit(-1);
        }

        if(verbose>0)
            fprintf(stderr, "send %zu bytes to %s\n", len,to_string().c_str());

       return true;
    }

    static const SocketAddress ReciveAny(void * buffer,size_t & len)
    {

        struct sockaddr_in cin;
        socklen_t cin_sz = sizeof(cin);

        size_t rc = recvfrom(fd,buf,BUFSZ,0,(struct sockaddr*)&cin,&cin_sz);
        len = rc;
        SocketAddress sa(cin);

        if(verbose>0)
            fprintf(stderr, "recieved %zu bytes from %s\n", rc,sa.to_string().c_str());

        return sa;

    }

};

int SocketAddress::fd;

int main(int argc, const char** argv) {

    if(argc<2)
    {

        const char* n_argv[] = { "udpforaward", "-vp", "6008", "-l","127.0.0.1","-a",
            "127.0.0.1:60001","-B","127.0.0.1:7001"};

        const char* m_argv[] = { "udpforaward", "-vp", "7001", "-l","127.0.0.1","-1","-b","127.0.0.1:50001"};

    argv = n_argv;
#if CLIENT
    argv = m_argv;
#endif
    argc=9;

    }

     prog = strdup(argv[0]);
    char  opt;

    SocketAddress sa;
    SocketAddress sb;

    bool connecta=false,connectb=false;

    bool revieveb=false,recievea=false;

    while ( (opt = getopt(argc, (char* * const )argv, "v+l:p:a:b:A:B:12")) != -1) {
        switch (opt) {
                case 'v': verbose++; break;
                case 'l': ip = strdup(optarg); break;
                case 'p': port = atoi(optarg); break;
                case 'a': sa = SocketAddress(optarg); break;
                case 'b': sb = SocketAddress(optarg); break;

                case 'A': sa = SocketAddress(optarg); connecta=true;break;
                case 'B': sb = SocketAddress(optarg); connectb=true;break;
                case '1':  recievea=true;break;
                case '2':  revieveb=true;break;

            default: usage(); break;
        }
    }

    if (!port) usage();

    in_addr_t listen_addr;
    if (ip) {
        if ( (listen_addr = inet_addr(ip)) == INADDR_NONE) {
            fprintf(stderr,"invalid listener IP address: %s\n", ip);
            exit(-1);
        }
    } else {
        listen_addr = htonl(INADDR_ANY);
        ip = strdup("all-local-addresses");
    }
    if (verbose) fprintf(stderr, "local address: %s:%d\n", ip, port);

    /**********************************************************
     * create two IPv4/UDP sockets, for listener and repeater
     *********************************************************/
    SocketAddress::fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (SocketAddress::fd == -1 ) { fprintf(stderr,"socket error\n"); exit(-1); }

    /**********************************************************
     * internet socket address structure: our address and port
     *********************************************************/
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = listen_addr;
    sin.sin_port = htons(port);

    /**********************************************************
     * bind socket to address and port we'd like to receive on
     *********************************************************/
    if (bind(SocketAddress::fd, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
        fprintf(stderr, "listen bind to %s:%d failed: %s\n", ip, port, strerror(errno));
        exit(-1);
    }

    while (true)  {

        /**********************************************************
         * uses recvfrom to get data along with client address/port
         *********************************************************/
        int random= rand();

        if(sa.initialized && connecta)
        {
            std::string testConnection="testConnection"+std::to_string(random);
            if(verbose>0)
                fprintf(stderr, "testConnection  to %s\n", sa.to_string().c_str());

            sa.Send((void*)testConnection.c_str(), testConnection.length());

        }

        if (sb.initialized && connectb)
        {
            std::string testConnection="testConnection"+std::to_string(random);

            if(verbose>0)
                fprintf(stderr, "testConnection  to %s\n", sb.to_string().c_str());
            sb.Send((void*)testConnection.c_str(), testConnection.length());

        }

        if(connectb||connecta)
        {
            struct pollfd pfdfd;
            int ret;

            pfdfd.fd = SocketAddress::fd; // your socket handler
            pfdfd.events = POLLIN;
            ret = poll(&pfdfd, 1, 1000); // 1 second for timeout

            if(ret == 0 || ret ==-1)
                continue;
        }

        size_t len;
        SocketAddress recivedAddress = SocketAddress::ReciveAny(buf, len);

        if(sa.initialized && sb.initialized)
        {
            if(recivedAddress == sa )
            {
                if(!recievea && !connecta)
                sb.Send(buf, len);
            }

            else if(recivedAddress == sb)
            {
                if(!revieveb && !connectb)

                sa.Send(buf, len);
            }
            else
            {
                printf("Discarding ");
            }
        }else if(sa.initialized && ! sb.initialized)
        {

            if(!(recivedAddress==sa))
            {
                sb= recivedAddress;

                if(!revieveb)
                    sa.Send(buf, len);

            }else
            {
                printf("Discarding  ");
            }

        }else if(!sa.initialized &&  sb.initialized){

            if(!(recivedAddress==sb))
            {
                sa= recivedAddress;

                if(!recievea)
                    sb.Send(buf, len);

            }else
            {
                printf("Discarding  ");
            }

        }

        else if (!sa.initialized && ! sb.initialized)
        {

            sa = recivedAddress;

        }

        if(recivedAddress == sa && connecta )
        {
            std::string testConnection=std::string(buf,len);
            if(testConnection=="testConnection")
            {
                connecta =false;
                fprintf(stderr, "connection scuccedded  to %s\n", sa.to_string().c_str());

            }

        }

        if (recivedAddress == sb && connectb)
        {
            std::string testConnection1="testConnection"+std::to_string(random);

            std::string testConnection=std::string(buf,len);
            if(testConnection==testConnection1)
            {
                fprintf(stderr, "connection scuccedded  to %s\n", sb.to_string().c_str());
                connectb =false;
            }

        }

        if(recivedAddress == sa && recievea )
        {
            std::string testConnection=std::string(buf,len);
            if(testConnection.find("testConnection")==std::string::npos)
                exit(-1);
            else
                recivedAddress.Send((void*)testConnection.c_str(), testConnection.length());

        }

        if (recivedAddress == sb && revieveb )
        {
            std::string testConnection=std::string(buf,len);
            if(testConnection.find("testConnection")==std::string::npos)
                exit(-1);
            else
                recivedAddress.Send((void*)testConnection.c_str(), testConnection.length());

        }

    }

}<|endoftext|>


<commit_before>#ifndef SILICIUM_COROUTINE_HPP
#define SILICIUM_COROUTINE_HPP

#include <silicium/exchange.hpp>
#include <silicium/observable/observer.hpp>
#include <silicium/config.hpp>
#include <silicium/observable/yield_context.hpp>
#include <boost/coroutine/all.hpp>

namespace Si
{
	namespace detail
	{
		struct coroutine_yield_context : basic_yield_context
		{
#if BOOST_VERSION >= 105500
			typedef boost::coroutines::coroutine<observable<nothing> *>::push_type consumer_type;
#else
			typedef boost::coroutines::coroutine<observable<nothing> *()>::caller_type consumer_type;
#endif

			explicit coroutine_yield_context(consumer_type &consumer)
				: consumer(&consumer)
			{
			}

			virtual void get_one(observable<nothing> &target) SILICIUM_OVERRIDE
			{
				(*consumer)(&target);
			}

		private:

			consumer_type *consumer;
		};
	}

	template <class Element>
	struct coroutine_observable : observer<nothing>
	{
		typedef Element element_type;

		coroutine_observable()
			: receiver_(nullptr)
			, has_finished(false)
		{
		}

		coroutine_observable(coroutine_observable &&other)
			: coro_(std::move(other.coro_))
			, action(std::move(other.action))
			, receiver_(nullptr)
			, has_finished(false)
		{
		}

		template <class Action>
		explicit coroutine_observable(Action &&action)
			: coro_()
			, action(std::forward<Action>(action))
			, receiver_(nullptr)
			, has_finished(false)
		{
		}

		coroutine_observable &operator = (coroutine_observable &&other)
		{
			coro_ = std::move(other.coro_);
			action = std::move(other.action);
			receiver_ = std::move(other.receiver_);
			has_finished = other.has_finished;
			return *this;
		}

		void async_get_one(Si::observer<element_type> &receiver)
		{
			receiver_ = &receiver;
			next();
		}

	private:

		typedef Si::observable<nothing> *command_type;
		typedef
#if BOOST_VERSION >= 105500
			typename boost::coroutines::coroutine<command_type>::pull_type
#else
			boost::coroutines::coroutine<command_type ()>
#endif
		coroutine_type;
		typedef std::shared_ptr<coroutine_type> coroutine_holder;

		coroutine_holder coro_;
		std::function<Element (yield_context)> action;
		Si::observer<Element> *receiver_;
		bool has_finished;

		coroutine_type &coro()
		{
			return *coro_;
		}

		virtual void got_element(nothing) SILICIUM_OVERRIDE
		{
			next();
		}

		virtual void ended() SILICIUM_OVERRIDE
		{
			next();
		}

		void next()
		{
			auto keep_coro_alive = coro_;
			if (has_finished)
			{
				return Si::exchange(receiver_, nullptr)->ended();
			}
			if (action)
			{
				auto bound_action = Si::exchange(action, decltype(action)());
				coro_ =
					std::make_shared<coroutine_type>
						([bound_action, this](
#if BOOST_VERSION >= 105500
							typename boost::coroutines::coroutine<command_type>::push_type
#else
							typename coroutine_type::caller_type
#endif
							&push)
						{
							detail::coroutine_yield_context yield_impl(push);
							yield_context yield(yield_impl); //TODO: save this indirection
							auto result = bound_action(yield);
							assert(!has_finished);
							has_finished = true;
							Si::exchange(receiver_, nullptr)->got_element(std::move(result));
						});
			}
			else if (coro())
			{
				coro()();
			}
			if (!receiver_)
			{
				return;
			}
			if (coro())
			{
				command_type command = coro().get();
				command->async_get_one(*this);
			}
			else
			{
				Si::exchange(receiver_, nullptr)->ended();
			}
		}

		SILICIUM_DELETED_FUNCTION(coroutine_observable(coroutine_observable const &))
		SILICIUM_DELETED_FUNCTION(coroutine_observable &operator = (coroutine_observable const &))
	};

	template <class Action, class Element = decltype(std::declval<Action>()(std::declval<yield_context>()))>
	auto make_coroutine(Action &&action)
#if !SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE
		-> coroutine_observable<Element>
#endif
	{
		return coroutine_observable<Element>(std::forward<Action>(action));
	}
}

#endif
<commit_msg>coroutine_observable inherits from observer privately<commit_after>#ifndef SILICIUM_COROUTINE_HPP
#define SILICIUM_COROUTINE_HPP

#include <silicium/exchange.hpp>
#include <silicium/observable/observer.hpp>
#include <silicium/config.hpp>
#include <silicium/observable/yield_context.hpp>
#include <boost/coroutine/all.hpp>

namespace Si
{
	namespace detail
	{
		struct coroutine_yield_context : basic_yield_context
		{
#if BOOST_VERSION >= 105500
			typedef boost::coroutines::coroutine<observable<nothing> *>::push_type consumer_type;
#else
			typedef boost::coroutines::coroutine<observable<nothing> *()>::caller_type consumer_type;
#endif

			explicit coroutine_yield_context(consumer_type &consumer)
				: consumer(&consumer)
			{
			}

			virtual void get_one(observable<nothing> &target) SILICIUM_OVERRIDE
			{
				(*consumer)(&target);
			}

		private:

			consumer_type *consumer;
		};
	}

	template <class Element>
	struct coroutine_observable : private observer<nothing>
	{
		typedef Element element_type;

		coroutine_observable()
			: receiver_(nullptr)
			, has_finished(false)
		{
		}

		coroutine_observable(coroutine_observable &&other)
			: coro_(std::move(other.coro_))
			, action(std::move(other.action))
			, receiver_(nullptr)
			, has_finished(false)
		{
		}

		template <class Action>
		explicit coroutine_observable(Action &&action)
			: coro_()
			, action(std::forward<Action>(action))
			, receiver_(nullptr)
			, has_finished(false)
		{
		}

		coroutine_observable &operator = (coroutine_observable &&other)
		{
			coro_ = std::move(other.coro_);
			action = std::move(other.action);
			receiver_ = std::move(other.receiver_);
			has_finished = other.has_finished;
			return *this;
		}

		void async_get_one(Si::observer<element_type> &receiver)
		{
			receiver_ = &receiver;
			next();
		}

	private:

		typedef Si::observable<nothing> *command_type;
		typedef
#if BOOST_VERSION >= 105500
			typename boost::coroutines::coroutine<command_type>::pull_type
#else
			boost::coroutines::coroutine<command_type ()>
#endif
		coroutine_type;
		typedef std::shared_ptr<coroutine_type> coroutine_holder;

		coroutine_holder coro_;
		std::function<Element (yield_context)> action;
		Si::observer<Element> *receiver_;
		bool has_finished;

		coroutine_type &coro()
		{
			return *coro_;
		}

		virtual void got_element(nothing) SILICIUM_OVERRIDE
		{
			next();
		}

		virtual void ended() SILICIUM_OVERRIDE
		{
			next();
		}

		void next()
		{
			auto keep_coro_alive = coro_;
			if (has_finished)
			{
				return Si::exchange(receiver_, nullptr)->ended();
			}
			if (action)
			{
				auto bound_action = Si::exchange(action, decltype(action)());
				coro_ =
					std::make_shared<coroutine_type>
						([bound_action, this](
#if BOOST_VERSION >= 105500
							typename boost::coroutines::coroutine<command_type>::push_type
#else
							typename coroutine_type::caller_type
#endif
							&push)
						{
							detail::coroutine_yield_context yield_impl(push);
							yield_context yield(yield_impl); //TODO: save this indirection
							auto result = bound_action(yield);
							assert(!has_finished);
							has_finished = true;
							Si::exchange(receiver_, nullptr)->got_element(std::move(result));
						});
			}
			else if (coro())
			{
				coro()();
			}
			if (!receiver_)
			{
				return;
			}
			if (coro())
			{
				command_type command = coro().get();
				command->async_get_one(*this);
			}
			else
			{
				Si::exchange(receiver_, nullptr)->ended();
			}
		}

		SILICIUM_DELETED_FUNCTION(coroutine_observable(coroutine_observable const &))
		SILICIUM_DELETED_FUNCTION(coroutine_observable &operator = (coroutine_observable const &))
	};

	template <class Action, class Element = decltype(std::declval<Action>()(std::declval<yield_context>()))>
	auto make_coroutine(Action &&action)
#if !SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE
		-> coroutine_observable<Element>
#endif
	{
		return coroutine_observable<Element>(std::forward<Action>(action));
	}
}

#endif
<|endoftext|>


<commit_before>#include <ros/ros.h>
// TODO Include mavlink to/from message types

#define NAME_AS_STRING(macro) #macro
#define VALUE_AS_STRING(macro) NAME_AS_STRING(macro)

#define DRONE_COMM_CLASS drone_comm

class DRONE_COMM_CLASS
{
	// TODO Implement service uploadWaypoints()

	// TODO Implement service monitorFlight()

};

int main(int argc, char** argv)
{
	ros::init(argc, argv, VALUE_AS_STRING(DRONE_COMM_CLASS));
  DRONE_COMM_CLASS dc;
  ros::spin();
  return 0;
}
<commit_msg>Basic setup<commit_after>#include <ros/ros.h>
// TODO Include mavlink to/from message types

#define NAME_AS_STRING(macro) #macro
#define VALUE_AS_STRING(macro) NAME_AS_STRING(macro)

#define DRONE_COMM_CLASS drone_comm

class DRONE_COMM_CLASS
{
public:
	DRONE_COMM_CLASS(ros::NodeHandle);
	~DRONE_COMM_CLASS();

private:
	ros::NodeHandle nh;

	// TODO Implement service uploadWaypoints()

	// TODO Implement service monitorFlight()

};

DRONE_COMM_CLASS::DRONE_COMM_CLASS(ros::NodeHandle n)
{
	nh = n;
}

DRONE_COMM_CLASS::~DRONE_COMM_CLASS()
{}

int main(int argc, char** argv)
{
	ros::init(argc, argv, VALUE_AS_STRING(DRONE_COMM_CLASS));
	ros::NodeHandle nh;
	DRONE_COMM_CLASS dc(nh);
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>/**
   @file   PlotStack.cc

   Source file of PlotStack, including the functions used for creating the histograms.

   @author Daniel Abercrombie <dabercro@mit.edu>
*/

#include <fstream>
#include <algorithm>
#include <sqlite3.h>

#include "TFile.h"
#include "TLegend.h"
#include "TProfile.h"

#include "PlotStack.h"

ClassImp(PlotStack)

//--------------------------------------------------------------------

/**
   The default constructor for PlotStack.
   It changes the value of PlotBase::fMakeRatio to be true by default.
 */

PlotStack::PlotStack()
{
  fMakeRatio = true;
}

//--------------------------------------------------------------------
PlotStack::~PlotStack()
{ }

//--------------------------------------------------------------------
std::vector<HistHolder*>
PlotStack::MergeHistograms(FileType type, std::vector<TH1D*> hists) {

  DisplayFunc(__func__);

  std::vector<HistHolder*> HistHolders;

  auto *fileInfo = GetFileInfo(type);
  TString previousEntry = "";
  TH1D *tempMCHist = NULL;
  HistHolder *tempHistHolder = NULL;

  for (UInt_t iHist = 0; iHist != hists.size(); ++iHist) {

    Message(eDebug, "About to process Histogram %i out of %i", iHist, hists.size());
    Message(eDebug, "Entry is \"%s\". Previous entry is \"%s\"",
            (*fileInfo)[iHist]->fEntry.Data(), previousEntry.Data());

    if ((*fileInfo)[iHist]->fEntry != previousEntry) {

      Message(eDebug, "Creating a new histogram");

      previousEntry = (*fileInfo)[iHist]->fEntry;
      TString tempName;
      tempName.Format("StackedHist_%d",iHist);
      tempMCHist = (TH1D*) hists[iHist]->Clone(tempName);
      tempHistHolder = new HistHolder(tempMCHist, (*fileInfo)[iHist]->fEntry,
                                      (*fileInfo)[iHist]->fColorStyle,
                                      (*fileInfo)[iHist]->fTreeName,
                                      (fForceTop == (*fileInfo)[iHist]->fEntry),
                                      (type == kSignal));
      HistHolders.push_back(tempHistHolder);

    } else {

      tempMCHist->Add(hists[iHist]);
      Message(eDebug, "Added to previous histogram.");

    }

    Message(eDebug, "Number of unique entries so far: %i", HistHolders.size());

  }

  return HistHolders;
}

//--------------------------------------------------------------------
void
PlotStack::MakeCanvas(TString FileBase, Int_t NumXBins, Double_t *XBins,
                      TString XLabel, TString YLabel, Bool_t logY)
{
  DisplayFunc(__func__);
  Message(eInfo, "Making File :   %s", FileBase.Data());
  Message(eInfo, "Plotting    :   %s", fDefaultExpr.Data());
  Message(eInfo, "Labeled     :   %s", XLabel.Data());
  Message(eInfo, "With cut    :   %s", fDefaultCut.GetTitle());

  if (YLabel == "") {
    if (fEventsPer == 0)
      YLabel = "Events/Bin";
    else if (fEventsPer >= 10)
      YLabel.Form("Events/%.0f", fEventsPer);
    else if (fEventsPer < 0.1)
      YLabel.Form("Events/%.3f", fEventsPer);
    else if (fEventsPer < 1.0)
      YLabel.Form("Events/%.2f", fEventsPer);
    else
      YLabel.Form("Events/%.1f", fEventsPer);
  }

  SetLumiLabel(float(fLuminosity/1000.0));
  ResetLegend();

  fRatioLines.clear();

  std::vector<TFile*> TemplateFiles;
  TFile *templateFile = NULL;

  Message(eDebug, "Number of Templates: %i", fTemplateEntries.size());

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp) {
    Message(eDebug, "Getting template: %i", iTemp);
    templateFile = TFile::Open(fTemplateFiles[iTemp]);
    TemplateFiles.push_back(templateFile);
  }

  SetIncludeErrorBars(true);
  std::vector<TH1D*> DataHists = GetHistList(NumXBins, XBins, kData);
  Message(eDebug, "Number of Data Histograms: %i", DataHists.size());
  SetIncludeErrorBars(false);
  std::vector<TH1D*> MCHists = GetHistList(NumXBins, XBins, kBackground);
  Message(eDebug, "Number of MC Histograms: %i", MCHists.size());
  std::vector<TH1D*> SignalHists;
  if (fSignalFileInfo.size() != 0)
    SignalHists = GetHistList(NumXBins, XBins, kSignal);
  Message(eDebug, "Number of Signal Histograms: %i", SignalHists.size());

  SetLegendFill(true);
  TH1D *DataHist = (TH1D*) DataHists[0]->Clone("DataHist");
  Message(eDebug, "Final Data Histogram created at %p", DataHist);
  DataHist->Reset("M");

  for (UInt_t iHist = 0; iHist < DataHists.size(); iHist++)
    DataHist->Add(DataHists[iHist]);

  Message(eInfo, "Number of data events: %i, integral: %f", (Int_t) DataHist->GetEntries(), DataHist->Integral("width")/fEventsPer);

  std::vector<HistHolder*> HistHolders = MergeHistograms(kBackground, MCHists);

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp) {

    for (UInt_t iHist = 0; iHist != HistHolders.size(); ++iHist) {

      if (fTemplateEntries[iTemp] == HistHolders[iHist]->fEntry) {

        Message(eInfo, "Replacing histogram %s with a template",
                fTemplateEntries[iTemp].Data());

        TH1D *templateHist = (TH1D*) TemplateFiles[iTemp]->Get(fTemplateHists[iTemp]);
        TH1D *toFormat = (TH1D*) templateHist->Rebin(NumXBins, "", XBins);
        toFormat->SetFillStyle(HistHolders[iHist]->fHist->GetFillStyle());
        toFormat->SetFillColor(HistHolders[iHist]->fHist->GetFillColor());
        toFormat->SetMarkerSize(HistHolders[iHist]->fHist->GetMarkerSize());
        HistHolders[iHist]->fHist = toFormat;

      }
    }
  }

  std::vector<HistHolder*> SignalHolders = MergeHistograms(kSignal, SignalHists);

  if (fDumpRootName != "") {

    Message(eInfo, "Dumping histograms into %s", fDumpRootName.Data());

    TH1D* tempHist;
    TFile* dumpFile = new TFile(fDumpRootName,"RECREATE");

    // Background Histograms

    for (UInt_t iHist = 0; iHist != HistHolders.size(); ++iHist) {

      tempHist = (TH1D*) HistHolders[iHist]->fHist->Clone();

      Message(eInfo, "%s  :  %f", HistHolders[iHist]->fEntry.Data(),
              tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);

      dumpFile->WriteTObject(tempHist, TString::Format("%s-%s",
                                                       fDefaultExpr.Data(),
                                                       HistHolders[iHist]->fTree.Data()
                                                       )
                             );
    }

    // Signal Histograms

    for (auto iHist = SignalHolders.begin(); iHist != SignalHolders.end(); ++iHist) {

      tempHist = (TH1D*) (*iHist)->fHist->Clone();

      Message(eInfo, "%s  :  %f", (*iHist)->fTree.Data(),
              tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);

      dumpFile->WriteTObject(tempHist, TString::Format("%s-%s",
                                                       fDefaultExpr.Data(),
                                                       (*iHist)->fTree.Data()
                                                       )
                             );

    }

    // Data Histogram

    tempHist = (TH1D*) DataHist->Clone();
    Message(eInfo, "Data     :  %f", tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);
    dumpFile->WriteTObject(tempHist, TString::Format("%s-data", fDefaultExpr.Data()));
    dumpFile->Close();

  }

  if (fSortBackground) {
    std::sort(HistHolders.begin(), HistHolders.end(), SortHistHolders);
    Message(eInfo, "Backgrounds sorted");
  }

  Message(eDebug, "Number of unique histograms: %i", HistHolders.size());

  std::vector<TH1D*> AllHists;
  for (UInt_t iLarger = 0; iLarger != HistHolders.size(); ++iLarger) {

    Message(eDebug, "Stacking up histogram: %i", iLarger);
    Message(eInfo, "Entry %s has total integral %f",
            HistHolders[iLarger]->fEntry.Data(),
            HistHolders[iLarger]->fHist->Integral("width")/fEventsPer);

    for (UInt_t iSmaller = iLarger + 1; iSmaller != HistHolders.size(); ++iSmaller) {
      Message(eDebug, "Adding %i to %i", iSmaller, iLarger);
      HistHolders[iLarger]->fHist->Add(HistHolders[iSmaller]->fHist);
    }

    Message(eDebug, "Histogram %i has integral %f", iLarger, HistHolders[iLarger]->fHist->Integral());

    if (HistHolders[iLarger]->fHist->Integral() > 0 || iLarger == 0) {

      if (iLarger != 0)
        SetZeroError(HistHolders[iLarger]->fHist);
      AllHists.push_back(HistHolders[iLarger]->fHist);

      if ((HistHolders[iLarger]->fHist->Integral() > fMinLegendFrac * HistHolders[0]->fHist->Integral()) ||  // If more than the fraction set
          (iLarger == HistHolders.size() - 1))                                                               // or the last histogram
        AddLegendEntry(HistHolders[iLarger]->fEntry, 1, fStackLineWidth, 1);                                 // Add legend properly
      else if ((HistHolders[iLarger]->fHist->Integral() > fIgnoreInLinear * HistHolders[0]->fHist->Integral()) ||
               logY) {                                                                                // Otherwise if not ignored
        if (HistHolders[iLarger + 1]->fHist->Integral() > 0) {                                               // Check if the next histogram contribute
          if (fOthersColor != 0)
            HistHolders[iLarger]->fHist->SetFillColor(fOthersColor);
          AddLegendEntry("Others", 1, fStackLineWidth, 1);                                                   // If so, make others legend
        }
        else                                                                                // If not,
          AddLegendEntry(HistHolders[iLarger]->fEntry, HistHolders[iLarger]->fColor, 1, 1);                  // Make normal legend entry
        break;                                                                                // Stop adding histograms
      } else {
        AllHists.pop_back();
        break;
      }
    }

    Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());

  }

  Message(eInfo, "Total background contribution: %f", HistHolders[0]->fHist->Integral("width")/fEventsPer);

  AddLegendEntry("Data", 1);
  SetDataIndex(int(AllHists.size()));
  AllHists.push_back(DataHist);

  if (fSortSignal) {
    std::sort(SignalHolders.begin(), SignalHolders.end(), SortHistHolders);
    Message(eInfo, "Signals sorted");
  }

  for (UInt_t iHist = 0; iHist != SignalHolders.size(); ++iHist) {

    if (fAddSignal) {                            // Do some clever things if we're adding signal to backgrounds

      if (fMakeRatio)                            // All possible signals show up on the ratio pad
        AddRatioLine(int(AllHists.size()));
      if (AllHists.size() > 1)
        SignalHolders[iHist]->fHist->Add(AllHists[0]);    // Add the background to the signals

    }

    AllHists.push_back(SignalHolders[iHist]->fHist);
    AddLegendEntry(SignalHolders[iHist]->fEntry, 1, 2, SignalHolders[iHist]->fColor);
    Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());
  }

  TString tempName;
  tempName.Form("Hist_%d", fPlotCounter);
  fPlotCounter++;
  TH1D* post_fit = new TH1D(tempName, tempName, NumXBins, XBins);

  if (fPostFitFile != "") {

    const char* signal_name = fSignalFileInfo.size() == 0 ? "" : fSignalFileInfo[0]->fTreeName.Data();

    sqlite3 *conn;
    if(sqlite3_open(fPostFitFile.Data(), &conn) != SQLITE_OK) {
      Message(eError, "Can't open database in %s", fPostFitFile.Data());
      sqlite3_close(conn);
      exit(50);
    }

    for (int i_bin = 1; i_bin <= NumXBins; i_bin++) {
      sqlite3_stmt *fetch_stmt;
      sqlite3_prepare_v2(conn, R"SQL(
SELECT yield FROM postfit_yields
WHERE region = ? AND bin = ? AND signal = ?
)SQL", -1, &fetch_stmt, NULL);

      sqlite3_bind_text(fetch_stmt, 1, fRegion.Data(), -1, NULL);
      sqlite3_bind_int(fetch_stmt, 2, i_bin);
      sqlite3_bind_text(fetch_stmt, 3, signal_name, -1, NULL);

      int rc = sqlite3_step(fetch_stmt);

      post_fit->SetBinContent(i_bin, sqlite3_column_double(fetch_stmt, 0));

      sqlite3_finalize(fetch_stmt);
    }

    sqlite3_close(conn);

    post_fit->SetLineWidth(2);
    post_fit->SetLineColor(2);

    if (fMakeRatio)
      AddRatioLine(int(AllHists.size()));
    AllHists.push_back(post_fit);
    AddLegendEntry("Post Fit", 2);

  }

  Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());

  if (fMakeRatio)
    AddRatioLine(fDataIndex);

  SetRatioIndex(0);

  BaseCanvas(AddOutDir(FileBase), AllHists, XLabel, YLabel, logY);

  for (UInt_t iHist = 0; iHist != AllHists.size(); ++iHist)
    delete AllHists[iHist];
  for (UInt_t iHist = 0; iHist != MCHists.size(); ++iHist)
    delete MCHists[iHist];
  for (UInt_t iHist = 0; iHist != DataHists.size(); ++iHist)
    delete DataHists[iHist];

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp)
    TemplateFiles[iTemp]->Close();

  CloseFiles();
}

//--------------------------------------------------------------------
void
PlotStack::MakeCanvas(TString FileBase, Int_t NumXBins, Double_t MinX, Double_t MaxX,
                      TString XLabel, TString YLabel, Bool_t logY)
{
  bool reset_per = (fEventsPer == 0);
  if (reset_per)
    SetEventsPer((MaxX - MinX)/NumXBins);

  Double_t XBins[NumXBins+1];
  ConvertToArray(NumXBins, MinX, MaxX, XBins);
  MakeCanvas(FileBase, NumXBins, XBins, XLabel, YLabel, logY);

  if (reset_per)
    SetEventsPer(0);
}

//--------------------------------------------------------------------
PlotStack*
PlotStack::Copy()
{
  PlotStack *newPlotter = new PlotStack();
  *newPlotter = *this;
  return newPlotter;
}
<commit_msg>Fix the data name<commit_after>/**
   @file   PlotStack.cc

   Source file of PlotStack, including the functions used for creating the histograms.

   @author Daniel Abercrombie <dabercro@mit.edu>
*/

#include <fstream>
#include <algorithm>
#include <sqlite3.h>

#include "TFile.h"
#include "TLegend.h"
#include "TProfile.h"

#include "PlotStack.h"

ClassImp(PlotStack)

//--------------------------------------------------------------------

/**
   The default constructor for PlotStack.
   It changes the value of PlotBase::fMakeRatio to be true by default.
 */

PlotStack::PlotStack()
{
  fMakeRatio = true;
}

//--------------------------------------------------------------------
PlotStack::~PlotStack()
{ }

//--------------------------------------------------------------------
std::vector<HistHolder*>
PlotStack::MergeHistograms(FileType type, std::vector<TH1D*> hists) {

  DisplayFunc(__func__);

  std::vector<HistHolder*> HistHolders;

  auto *fileInfo = GetFileInfo(type);
  TString previousEntry = "";
  TH1D *tempMCHist = NULL;
  HistHolder *tempHistHolder = NULL;

  for (UInt_t iHist = 0; iHist != hists.size(); ++iHist) {

    Message(eDebug, "About to process Histogram %i out of %i", iHist, hists.size());
    Message(eDebug, "Entry is \"%s\". Previous entry is \"%s\"",
            (*fileInfo)[iHist]->fEntry.Data(), previousEntry.Data());

    if ((*fileInfo)[iHist]->fEntry != previousEntry) {

      Message(eDebug, "Creating a new histogram");

      previousEntry = (*fileInfo)[iHist]->fEntry;
      TString tempName;
      tempName.Format("StackedHist_%d",iHist);
      tempMCHist = (TH1D*) hists[iHist]->Clone(tempName);
      tempHistHolder = new HistHolder(tempMCHist, (*fileInfo)[iHist]->fEntry,
                                      (*fileInfo)[iHist]->fColorStyle,
                                      (*fileInfo)[iHist]->fTreeName,
                                      (fForceTop == (*fileInfo)[iHist]->fEntry),
                                      (type == kSignal));
      HistHolders.push_back(tempHistHolder);

    } else {

      tempMCHist->Add(hists[iHist]);
      Message(eDebug, "Added to previous histogram.");

    }

    Message(eDebug, "Number of unique entries so far: %i", HistHolders.size());

  }

  return HistHolders;
}

//--------------------------------------------------------------------
void
PlotStack::MakeCanvas(TString FileBase, Int_t NumXBins, Double_t *XBins,
                      TString XLabel, TString YLabel, Bool_t logY)
{
  DisplayFunc(__func__);
  Message(eInfo, "Making File :   %s", FileBase.Data());
  Message(eInfo, "Plotting    :   %s", fDefaultExpr.Data());
  Message(eInfo, "Labeled     :   %s", XLabel.Data());
  Message(eInfo, "With cut    :   %s", fDefaultCut.GetTitle());

  if (YLabel == "") {
    if (fEventsPer == 0)
      YLabel = "Events/Bin";
    else if (fEventsPer >= 10)
      YLabel.Form("Events/%.0f", fEventsPer);
    else if (fEventsPer < 0.1)
      YLabel.Form("Events/%.3f", fEventsPer);
    else if (fEventsPer < 1.0)
      YLabel.Form("Events/%.2f", fEventsPer);
    else
      YLabel.Form("Events/%.1f", fEventsPer);
  }

  SetLumiLabel(float(fLuminosity/1000.0));
  ResetLegend();

  fRatioLines.clear();

  std::vector<TFile*> TemplateFiles;
  TFile *templateFile = NULL;

  Message(eDebug, "Number of Templates: %i", fTemplateEntries.size());

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp) {
    Message(eDebug, "Getting template: %i", iTemp);
    templateFile = TFile::Open(fTemplateFiles[iTemp]);
    TemplateFiles.push_back(templateFile);
  }

  SetIncludeErrorBars(true);
  std::vector<TH1D*> DataHists = GetHistList(NumXBins, XBins, kData);
  Message(eDebug, "Number of Data Histograms: %i", DataHists.size());
  SetIncludeErrorBars(false);
  std::vector<TH1D*> MCHists = GetHistList(NumXBins, XBins, kBackground);
  Message(eDebug, "Number of MC Histograms: %i", MCHists.size());
  std::vector<TH1D*> SignalHists;
  if (fSignalFileInfo.size() != 0)
    SignalHists = GetHistList(NumXBins, XBins, kSignal);
  Message(eDebug, "Number of Signal Histograms: %i", SignalHists.size());

  SetLegendFill(true);
  TH1D *DataHist = (TH1D*) DataHists[0]->Clone("DataHist");
  Message(eDebug, "Final Data Histogram created at %p", DataHist);
  DataHist->Reset("M");

  for (UInt_t iHist = 0; iHist < DataHists.size(); iHist++)
    DataHist->Add(DataHists[iHist]);

  Message(eInfo, "Number of data events: %i, integral: %f", (Int_t) DataHist->GetEntries(), DataHist->Integral("width")/fEventsPer);

  std::vector<HistHolder*> HistHolders = MergeHistograms(kBackground, MCHists);

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp) {

    for (UInt_t iHist = 0; iHist != HistHolders.size(); ++iHist) {

      if (fTemplateEntries[iTemp] == HistHolders[iHist]->fEntry) {

        Message(eInfo, "Replacing histogram %s with a template",
                fTemplateEntries[iTemp].Data());

        TH1D *templateHist = (TH1D*) TemplateFiles[iTemp]->Get(fTemplateHists[iTemp]);
        TH1D *toFormat = (TH1D*) templateHist->Rebin(NumXBins, "", XBins);
        toFormat->SetFillStyle(HistHolders[iHist]->fHist->GetFillStyle());
        toFormat->SetFillColor(HistHolders[iHist]->fHist->GetFillColor());
        toFormat->SetMarkerSize(HistHolders[iHist]->fHist->GetMarkerSize());
        HistHolders[iHist]->fHist = toFormat;

      }
    }
  }

  std::vector<HistHolder*> SignalHolders = MergeHistograms(kSignal, SignalHists);

  if (fDumpRootName != "") {

    Message(eInfo, "Dumping histograms into %s", fDumpRootName.Data());

    TH1D* tempHist;
    TFile* dumpFile = new TFile(fDumpRootName,"RECREATE");

    // Background Histograms

    for (UInt_t iHist = 0; iHist != HistHolders.size(); ++iHist) {

      tempHist = (TH1D*) HistHolders[iHist]->fHist->Clone();

      Message(eInfo, "%s  :  %f", HistHolders[iHist]->fEntry.Data(),
              tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);

      dumpFile->WriteTObject(tempHist, TString::Format("%s-%s",
                                                       fDefaultExpr.Data(),
                                                       HistHolders[iHist]->fTree.Data()
                                                       )
                             );
    }

    // Signal Histograms

    for (auto iHist = SignalHolders.begin(); iHist != SignalHolders.end(); ++iHist) {

      tempHist = (TH1D*) (*iHist)->fHist->Clone();

      Message(eInfo, "%s  :  %f", (*iHist)->fTree.Data(),
              tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);

      dumpFile->WriteTObject(tempHist, TString::Format("%s-%s",
                                                       fDefaultExpr.Data(),
                                                       (*iHist)->fTree.Data()
                                                       )
                             );

    }

    // Data Histogram

    tempHist = (TH1D*) DataHist->Clone();
    Message(eInfo, "Data     :  %f", tempHist->Integral(0, NumXBins + 1, "width")/fEventsPer);
    dumpFile->WriteTObject(tempHist, TString::Format("%s-data_obs", fDefaultExpr.Data()));
    dumpFile->Close();

  }

  if (fSortBackground) {
    std::sort(HistHolders.begin(), HistHolders.end(), SortHistHolders);
    Message(eInfo, "Backgrounds sorted");
  }

  Message(eDebug, "Number of unique histograms: %i", HistHolders.size());

  std::vector<TH1D*> AllHists;
  for (UInt_t iLarger = 0; iLarger != HistHolders.size(); ++iLarger) {

    Message(eDebug, "Stacking up histogram: %i", iLarger);
    Message(eInfo, "Entry %s has total integral %f",
            HistHolders[iLarger]->fEntry.Data(),
            HistHolders[iLarger]->fHist->Integral("width")/fEventsPer);

    for (UInt_t iSmaller = iLarger + 1; iSmaller != HistHolders.size(); ++iSmaller) {
      Message(eDebug, "Adding %i to %i", iSmaller, iLarger);
      HistHolders[iLarger]->fHist->Add(HistHolders[iSmaller]->fHist);
    }

    Message(eDebug, "Histogram %i has integral %f", iLarger, HistHolders[iLarger]->fHist->Integral());

    if (HistHolders[iLarger]->fHist->Integral() > 0 || iLarger == 0) {

      if (iLarger != 0)
        SetZeroError(HistHolders[iLarger]->fHist);
      AllHists.push_back(HistHolders[iLarger]->fHist);

      if ((HistHolders[iLarger]->fHist->Integral() > fMinLegendFrac * HistHolders[0]->fHist->Integral()) ||  // If more than the fraction set
          (iLarger == HistHolders.size() - 1))                                                               // or the last histogram
        AddLegendEntry(HistHolders[iLarger]->fEntry, 1, fStackLineWidth, 1);                                 // Add legend properly
      else if ((HistHolders[iLarger]->fHist->Integral() > fIgnoreInLinear * HistHolders[0]->fHist->Integral()) ||
               logY) {                                                                                // Otherwise if not ignored
        if (HistHolders[iLarger + 1]->fHist->Integral() > 0) {                                               // Check if the next histogram contribute
          if (fOthersColor != 0)
            HistHolders[iLarger]->fHist->SetFillColor(fOthersColor);
          AddLegendEntry("Others", 1, fStackLineWidth, 1);                                                   // If so, make others legend
        }
        else                                                                                // If not,
          AddLegendEntry(HistHolders[iLarger]->fEntry, HistHolders[iLarger]->fColor, 1, 1);                  // Make normal legend entry
        break;                                                                                // Stop adding histograms
      } else {
        AllHists.pop_back();
        break;
      }
    }

    Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());

  }

  Message(eInfo, "Total background contribution: %f", HistHolders[0]->fHist->Integral("width")/fEventsPer);

  AddLegendEntry("Data", 1);
  SetDataIndex(int(AllHists.size()));
  AllHists.push_back(DataHist);

  if (fSortSignal) {
    std::sort(SignalHolders.begin(), SignalHolders.end(), SortHistHolders);
    Message(eInfo, "Signals sorted");
  }

  for (UInt_t iHist = 0; iHist != SignalHolders.size(); ++iHist) {

    if (fAddSignal) {                            // Do some clever things if we're adding signal to backgrounds

      if (fMakeRatio)                            // All possible signals show up on the ratio pad
        AddRatioLine(int(AllHists.size()));
      if (AllHists.size() > 1)
        SignalHolders[iHist]->fHist->Add(AllHists[0]);    // Add the background to the signals

    }

    AllHists.push_back(SignalHolders[iHist]->fHist);
    AddLegendEntry(SignalHolders[iHist]->fEntry, 1, 2, SignalHolders[iHist]->fColor);
    Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());
  }

  TString tempName;
  tempName.Form("Hist_%d", fPlotCounter);
  fPlotCounter++;
  TH1D* post_fit = new TH1D(tempName, tempName, NumXBins, XBins);

  if (fPostFitFile != "") {

    const char* signal_name = fSignalFileInfo.size() == 0 ? "" : fSignalFileInfo[0]->fTreeName.Data();

    sqlite3 *conn;
    if(sqlite3_open(fPostFitFile.Data(), &conn) != SQLITE_OK) {
      Message(eError, "Can't open database in %s", fPostFitFile.Data());
      sqlite3_close(conn);
      exit(50);
    }

    for (int i_bin = 1; i_bin <= NumXBins; i_bin++) {
      sqlite3_stmt *fetch_stmt;
      sqlite3_prepare_v2(conn, R"SQL(
SELECT yield FROM postfit_yields
WHERE region = ? AND bin = ? AND signal = ?
)SQL", -1, &fetch_stmt, NULL);

      sqlite3_bind_text(fetch_stmt, 1, fRegion.Data(), -1, NULL);
      sqlite3_bind_int(fetch_stmt, 2, i_bin);
      sqlite3_bind_text(fetch_stmt, 3, signal_name, -1, NULL);

      int rc = sqlite3_step(fetch_stmt);

      post_fit->SetBinContent(i_bin, sqlite3_column_double(fetch_stmt, 0));

      sqlite3_finalize(fetch_stmt);
    }

    sqlite3_close(conn);

    post_fit->SetLineWidth(2);
    post_fit->SetLineColor(2);

    if (fMakeRatio)
      AddRatioLine(int(AllHists.size()));
    AllHists.push_back(post_fit);
    AddLegendEntry("Post Fit", 2);

  }

  Message(eDebug, "There are now %i total histograms to plot.", AllHists.size());

  if (fMakeRatio)
    AddRatioLine(fDataIndex);

  SetRatioIndex(0);

  BaseCanvas(AddOutDir(FileBase), AllHists, XLabel, YLabel, logY);

  for (UInt_t iHist = 0; iHist != AllHists.size(); ++iHist)
    delete AllHists[iHist];
  for (UInt_t iHist = 0; iHist != MCHists.size(); ++iHist)
    delete MCHists[iHist];
  for (UInt_t iHist = 0; iHist != DataHists.size(); ++iHist)
    delete DataHists[iHist];

  for (UInt_t iTemp = 0; iTemp != fTemplateEntries.size(); ++iTemp)
    TemplateFiles[iTemp]->Close();

  CloseFiles();
}

//--------------------------------------------------------------------
void
PlotStack::MakeCanvas(TString FileBase, Int_t NumXBins, Double_t MinX, Double_t MaxX,
                      TString XLabel, TString YLabel, Bool_t logY)
{
  bool reset_per = (fEventsPer == 0);
  if (reset_per)
    SetEventsPer((MaxX - MinX)/NumXBins);

  Double_t XBins[NumXBins+1];
  ConvertToArray(NumXBins, MinX, MaxX, XBins);
  MakeCanvas(FileBase, NumXBins, XBins, XLabel, YLabel, logY);

  if (reset_per)
    SetEventsPer(0);
}

//--------------------------------------------------------------------
PlotStack*
PlotStack::Copy()
{
  PlotStack *newPlotter = new PlotStack();
  *newPlotter = *this;
  return newPlotter;
}
<|endoftext|>


<commit_before><commit_msg>Add deltagen hash command<commit_after><|endoftext|>


<commit_before>#include "prepencryptcommand.h"
#include "encryptemailcontroller.h"
#include "kleo-assuan.h"

#include <KLocale>

using namespace Kleo;
using namespace boost;

class PrepEncryptCommand::Private : public QObject {
    Q_OBJECT
private:
    friend class ::Kleo::PrepEncryptCommand;
    PrepEncryptCommand * const q;
public:
    explicit Private( PrepEncryptCommand * qq )
        : q( qq ), controller() {}

private:
    void checkForErrors() const;

public Q_SLOTS:
    void slotRecipientsResolved();
    void slotError( int, const QString & );

private:
    shared_ptr<EncryptEMailController> controller;
};

PrepEncryptCommand::PrepEncryptCommand()
    : AssuanCommandMixin<PrepEncryptCommand>(), d( new Private( this ) )
{

}

PrepEncryptCommand::~PrepEncryptCommand() {}

void PrepEncryptCommand::Private::checkForErrors() const {

    if ( q->numBulkInputDevices() || q->numBulkOutputDevices() || q->numBulkMessageDevices() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "INPUT/OUTPUT/MESSAGE may only be given after PREP_ENCRYPT" ) );

    if ( q->numFiles() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "PREP_ENCRYPT is an email mode command, connection seems to be in filemanager mode" ) );

    if ( !q->senders().empty() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "SENDER may not be given prior to PREP_ENCRYPT" ) );

    if ( q->recipients().empty() )
        throw assuan_exception( makeError( GPG_ERR_MISSING_VALUE ),
                                i18n( "No recipients given" ) );

}

int PrepEncryptCommand::doStart() {

    removeMemento( EncryptEMailController::mementoName() );

    d->checkForErrors();

    d->controller.reset( new EncryptEMailController );

    d->controller->setCommand( shared_from_this() );

    if ( hasOption( "protocol" ) )
        // --protocol is optional for PREP_ENCRYPT
        d->controller->setProtocol( checkProtocol( EMail ) );

    QObject::connect( d->controller.get(), SIGNAL(recipientsResolved()), d.get(), SLOT(slotRecipientsResolved()) );
    QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)) );

    d->controller->startResolveRecipients( recipients() );

    return 0;
}

void PrepEncryptCommand::Private::slotRecipientsResolved() {
    if ( const int err = q->sendStatus( "PROTOCOL", controller->protocolAsString() ) )
        q->done( err, i18n( "Failed to send PROTOCOL status" ) );
    q->registerMemento( EncryptEMailController::mementoName(),
                        make_typed_memento( controller ) );
    q->done();
}

void PrepEncryptCommand::Private::slotError( int err, const QString & details ) {
    q->done( err, details );
}

void PrepEncryptCommand::doCanceled() {
    d->controller->cancel();
}

#include "prepencryptcommand.moc"
<commit_msg>./add_license_blurb.sh<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    uiserver/prepencryptcommand.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "prepencryptcommand.h"
#include "encryptemailcontroller.h"
#include "kleo-assuan.h"

#include <KLocale>

using namespace Kleo;
using namespace boost;

class PrepEncryptCommand::Private : public QObject {
    Q_OBJECT
private:
    friend class ::Kleo::PrepEncryptCommand;
    PrepEncryptCommand * const q;
public:
    explicit Private( PrepEncryptCommand * qq )
        : q( qq ), controller() {}

private:
    void checkForErrors() const;

public Q_SLOTS:
    void slotRecipientsResolved();
    void slotError( int, const QString & );

private:
    shared_ptr<EncryptEMailController> controller;
};

PrepEncryptCommand::PrepEncryptCommand()
    : AssuanCommandMixin<PrepEncryptCommand>(), d( new Private( this ) )
{

}

PrepEncryptCommand::~PrepEncryptCommand() {}

void PrepEncryptCommand::Private::checkForErrors() const {

    if ( q->numBulkInputDevices() || q->numBulkOutputDevices() || q->numBulkMessageDevices() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "INPUT/OUTPUT/MESSAGE may only be given after PREP_ENCRYPT" ) );

    if ( q->numFiles() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "PREP_ENCRYPT is an email mode command, connection seems to be in filemanager mode" ) );

    if ( !q->senders().empty() )
        throw assuan_exception( makeError( GPG_ERR_CONFLICT ),
                                i18n( "SENDER may not be given prior to PREP_ENCRYPT" ) );

    if ( q->recipients().empty() )
        throw assuan_exception( makeError( GPG_ERR_MISSING_VALUE ),
                                i18n( "No recipients given" ) );

}

int PrepEncryptCommand::doStart() {

    removeMemento( EncryptEMailController::mementoName() );

    d->checkForErrors();

    d->controller.reset( new EncryptEMailController );

    d->controller->setCommand( shared_from_this() );

    if ( hasOption( "protocol" ) )
        // --protocol is optional for PREP_ENCRYPT
        d->controller->setProtocol( checkProtocol( EMail ) );

    QObject::connect( d->controller.get(), SIGNAL(recipientsResolved()), d.get(), SLOT(slotRecipientsResolved()) );
    QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)) );

    d->controller->startResolveRecipients( recipients() );

    return 0;
}

void PrepEncryptCommand::Private::slotRecipientsResolved() {
    if ( const int err = q->sendStatus( "PROTOCOL", controller->protocolAsString() ) )
        q->done( err, i18n( "Failed to send PROTOCOL status" ) );
    q->registerMemento( EncryptEMailController::mementoName(),
                        make_typed_memento( controller ) );
    q->done();
}

void PrepEncryptCommand::Private::slotError( int err, const QString & details ) {
    q->done( err, details );
}

void PrepEncryptCommand::doCanceled() {
    d->controller->cancel();
}

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