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

#include "chrome/browser/gtk/sad_tab_gtk.h"

#include <string>

#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/lazy_instance.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"

namespace {

// The y offset from the center at which to paint the icon.
const int kSadTabOffset = -64;
// The spacing between the icon and the title.
const int kIconTitleSpacing = 20;
// The spacing between the title and the message.
const int kTitleMessageSpacing = 15;
const int kMessageLinkSpacing = 15;
const int kTabHorzMargin = 13;
const double kBackgroundColorTop[3] = {
  35.0 / 255.0, 48.0 / 255.0, 64.0 / 255.0 };
const double kBackgroundColorBottom[3] = {
  35.0 / 255.0, 48.0 / 255.0, 64.0 / 255.0 };

struct SadTabGtkConstants {
  SadTabGtkConstants()
      : sad_tab_bitmap(
            ResourceBundle::GetSharedInstance().GetPixbufNamed(IDR_SAD_TAB)),
        title(l10n_util::GetStringUTF8(IDS_SAD_TAB_TITLE)),
        message(l10n_util::GetStringUTF8(IDS_SAD_TAB_MESSAGE)),
        learn_more_url(l10n_util::GetStringUTF8(IDS_CRASH_REASON_URL)) {}

  const GdkPixbuf* sad_tab_bitmap;
  std::string title;
  std::string message;
  std::string learn_more_url;
};

base::LazyInstance<SadTabGtkConstants>
    g_sad_tab_constants(base::LINKER_INITIALIZED);

GtkWidget* MakeWhiteMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Center align and justify it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);

  // Set text to white.
  GdkColor white = gfx::kGdkWhite;
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &white);

  return label;
}

}  // namespace

SadTabGtk::SadTabGtk()
  : width_(0),
    height_(0) {
  // Use an event box to get the background painting correctly.
  event_box_.Own(gtk_event_box_new());
  gtk_widget_set_app_paintable(event_box_.get(), TRUE);
  g_signal_connect(event_box_.get(), "expose-event",
                   G_CALLBACK(OnBackgroundExposeThunk), this);
  // Listen to signal for resizing of widget.
  g_signal_connect(event_box_.get(), "size-allocate",
                   G_CALLBACK(OnSizeAllocateThunk), this);

  // Use an alignment to set the top and horizontal paddings. The padding will
  // be set later when we receive expose-event which gives us the width and
  // height of the widget.
  top_padding_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_container_add(GTK_CONTAINER(event_box_.get()), top_padding_);

  // Use a vertical box to contain icon, title, message and link.
  GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(top_padding_), vbox);

  const SadTabGtkConstants& sad_tab_constants = g_sad_tab_constants.Get();

  // Add center-aligned image.
  GtkWidget* image = gtk_image_new_from_pixbuf(
      const_cast<GdkPixbuf*>(sad_tab_constants.sad_tab_bitmap));
  gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5);
  gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, kIconTitleSpacing);

  // Add center-aligned title.
  GtkWidget* title = MakeWhiteMarkupLabel(
      "%s",
      sad_tab_constants.title);
  gtk_box_pack_start(GTK_BOX(vbox), title, FALSE, FALSE, kTitleMessageSpacing);

  // Add center-aligned message.
  message_ = MakeWhiteMarkupLabel("%s",
                                  sad_tab_constants.message);
  gtk_label_set_line_wrap(GTK_LABEL(message_), TRUE);
  gtk_box_pack_start(GTK_BOX(vbox), message_, FALSE, FALSE,
                     kMessageLinkSpacing);

  // Add the learn-more link and center-align it in an alignment.
  GtkWidget* link = gtk_chrome_link_button_new(
      l10n_util::GetStringUTF8(IDS_LEARN_MORE).c_str());
  g_signal_connect(link, "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(sad_tab_constants.learn_more_url.c_str()));
  GtkWidget* link_alignment = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
  gtk_container_add(GTK_CONTAINER(link_alignment), link);
  gtk_box_pack_start(GTK_BOX(vbox), link_alignment, FALSE, FALSE, 0);

  gtk_widget_show_all(event_box_.get());
}

SadTabGtk::~SadTabGtk() {
  event_box_.Destroy();
}

gboolean SadTabGtk::OnBackgroundExpose(
    GtkWidget* widget, GdkEventExpose* event) {
  // Clip to our damage rect.
  cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(event->window));
  cairo_rectangle(cr, event->area.x, event->area.y,
                  event->area.width, event->area.height);
  cairo_clip(cr);

  // Draw the gradient background.
  int half_width = width_ / 2;
  cairo_pattern_t* pattern = cairo_pattern_create_linear(
      half_width, 0,  half_width, height_);
  cairo_pattern_add_color_stop_rgb(
      pattern, 0.0,
      kBackgroundColorTop[0], kBackgroundColorTop[1], kBackgroundColorTop[2]);
  cairo_pattern_add_color_stop_rgb(
      pattern, 1.0,
      kBackgroundColorBottom[0], kBackgroundColorBottom[1],
      kBackgroundColorBottom[2]);
  cairo_set_source(cr, pattern);
  cairo_paint(cr);
  cairo_pattern_destroy(pattern);

  cairo_destroy(cr);

  return FALSE;  // Propagate expose event to children.
}

void SadTabGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
  // Only readjust top and horizontal paddings if height of widget has changed.
  if (allocation->height != 0 && allocation->height != height_) {
    height_ = allocation->height;
    const SadTabGtkConstants& sad_tab_constants = g_sad_tab_constants.Get();
    int icon_height = gdk_pixbuf_get_height(sad_tab_constants.sad_tab_bitmap);
    int icon_y = ((height_ - icon_height) / 2) + kSadTabOffset;
    gtk_alignment_set_padding(GTK_ALIGNMENT(top_padding_), std::max(icon_y, 0),
                              0, kTabHorzMargin, kTabHorzMargin);
  }

  // Only readjust width for message if width of widget has changed.
  if (allocation->width != 0 && allocation->width != width_) {
    width_ = allocation->width;
    // If necessary, set width for wrappable message.
    int message_width = width_ - (kTabHorzMargin * 2);
    if (message_width > -1)
      gtk_widget_set_size_request(message_, message_width, -1);
  }
}

// static
void SadTabGtk::OnLinkButtonClick(GtkWidget* button, const char* url) {
  BrowserList::GetLastActive()->OpenURL(GURL(url), GURL(), CURRENT_TAB,
                                        PageTransition::LINK);
}
<commit_msg>Linux: Make the sad tab link readable.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/sad_tab_gtk.h"

#include <string>

#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/lazy_instance.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"

namespace {

// The y offset from the center at which to paint the icon.
const int kSadTabOffset = -64;
// The spacing between the icon and the title.
const int kIconTitleSpacing = 20;
// The spacing between the title and the message.
const int kTitleMessageSpacing = 15;
const int kMessageLinkSpacing = 15;
const int kTabHorzMargin = 13;
const double kBackgroundColorTop[3] = {
  35.0 / 255.0, 48.0 / 255.0, 64.0 / 255.0 };
const double kBackgroundColorBottom[3] = {
  35.0 / 255.0, 48.0 / 255.0, 64.0 / 255.0 };

struct SadTabGtkConstants {
  SadTabGtkConstants()
      : sad_tab_bitmap(
            ResourceBundle::GetSharedInstance().GetPixbufNamed(IDR_SAD_TAB)),
        title(l10n_util::GetStringUTF8(IDS_SAD_TAB_TITLE)),
        message(l10n_util::GetStringUTF8(IDS_SAD_TAB_MESSAGE)),
        learn_more_url(l10n_util::GetStringUTF8(IDS_CRASH_REASON_URL)) {}

  const GdkPixbuf* sad_tab_bitmap;
  std::string title;
  std::string message;
  std::string learn_more_url;
};

base::LazyInstance<SadTabGtkConstants>
    g_sad_tab_constants(base::LINKER_INITIALIZED);

GtkWidget* MakeWhiteMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Center align and justify it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);

  // Set text to white.
  GdkColor white = gfx::kGdkWhite;
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &white);

  return label;
}

}  // namespace

SadTabGtk::SadTabGtk()
  : width_(0),
    height_(0) {
  // Use an event box to get the background painting correctly.
  event_box_.Own(gtk_event_box_new());
  gtk_widget_set_app_paintable(event_box_.get(), TRUE);
  g_signal_connect(event_box_.get(), "expose-event",
                   G_CALLBACK(OnBackgroundExposeThunk), this);
  // Listen to signal for resizing of widget.
  g_signal_connect(event_box_.get(), "size-allocate",
                   G_CALLBACK(OnSizeAllocateThunk), this);

  // Use an alignment to set the top and horizontal paddings. The padding will
  // be set later when we receive expose-event which gives us the width and
  // height of the widget.
  top_padding_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_container_add(GTK_CONTAINER(event_box_.get()), top_padding_);

  // Use a vertical box to contain icon, title, message and link.
  GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(top_padding_), vbox);

  const SadTabGtkConstants& sad_tab_constants = g_sad_tab_constants.Get();

  // Add center-aligned image.
  GtkWidget* image = gtk_image_new_from_pixbuf(
      const_cast<GdkPixbuf*>(sad_tab_constants.sad_tab_bitmap));
  gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5);
  gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, kIconTitleSpacing);

  // Add center-aligned title.
  GtkWidget* title = MakeWhiteMarkupLabel(
      "%s",
      sad_tab_constants.title);
  gtk_box_pack_start(GTK_BOX(vbox), title, FALSE, FALSE, kTitleMessageSpacing);

  // Add center-aligned message.
  message_ = MakeWhiteMarkupLabel("%s",
                                  sad_tab_constants.message);
  gtk_label_set_line_wrap(GTK_LABEL(message_), TRUE);
  gtk_box_pack_start(GTK_BOX(vbox), message_, FALSE, FALSE,
                     kMessageLinkSpacing);

  // Add the learn-more link and center-align it in an alignment.
  GtkWidget* link = gtk_chrome_link_button_new(
      l10n_util::GetStringUTF8(IDS_LEARN_MORE).c_str());
  gtk_chrome_link_button_set_normal_color(GTK_CHROME_LINK_BUTTON(link),
                                          &gfx::kGdkWhite);
  g_signal_connect(link, "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(sad_tab_constants.learn_more_url.c_str()));
  GtkWidget* link_alignment = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
  gtk_container_add(GTK_CONTAINER(link_alignment), link);
  gtk_box_pack_start(GTK_BOX(vbox), link_alignment, FALSE, FALSE, 0);

  gtk_widget_show_all(event_box_.get());
}

SadTabGtk::~SadTabGtk() {
  event_box_.Destroy();
}

gboolean SadTabGtk::OnBackgroundExpose(
    GtkWidget* widget, GdkEventExpose* event) {
  // Clip to our damage rect.
  cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(event->window));
  cairo_rectangle(cr, event->area.x, event->area.y,
                  event->area.width, event->area.height);
  cairo_clip(cr);

  // Draw the gradient background.
  int half_width = width_ / 2;
  cairo_pattern_t* pattern = cairo_pattern_create_linear(
      half_width, 0,  half_width, height_);
  cairo_pattern_add_color_stop_rgb(
      pattern, 0.0,
      kBackgroundColorTop[0], kBackgroundColorTop[1], kBackgroundColorTop[2]);
  cairo_pattern_add_color_stop_rgb(
      pattern, 1.0,
      kBackgroundColorBottom[0], kBackgroundColorBottom[1],
      kBackgroundColorBottom[2]);
  cairo_set_source(cr, pattern);
  cairo_paint(cr);
  cairo_pattern_destroy(pattern);

  cairo_destroy(cr);

  return FALSE;  // Propagate expose event to children.
}

void SadTabGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
  // Only readjust top and horizontal paddings if height of widget has changed.
  if (allocation->height != 0 && allocation->height != height_) {
    height_ = allocation->height;
    const SadTabGtkConstants& sad_tab_constants = g_sad_tab_constants.Get();
    int icon_height = gdk_pixbuf_get_height(sad_tab_constants.sad_tab_bitmap);
    int icon_y = ((height_ - icon_height) / 2) + kSadTabOffset;
    gtk_alignment_set_padding(GTK_ALIGNMENT(top_padding_), std::max(icon_y, 0),
                              0, kTabHorzMargin, kTabHorzMargin);
  }

  // Only readjust width for message if width of widget has changed.
  if (allocation->width != 0 && allocation->width != width_) {
    width_ = allocation->width;
    // If necessary, set width for wrappable message.
    int message_width = width_ - (kTabHorzMargin * 2);
    if (message_width > -1)
      gtk_widget_set_size_request(message_, message_width, -1);
  }
}

// static
void SadTabGtk::OnLinkButtonClick(GtkWidget* button, const char* url) {
  BrowserList::GetLastActive()->OpenURL(GURL(url), GURL(), CURRENT_TAB,
                                        PageTransition::LINK);
}
<|endoftext|>


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

#include "chrome/common/chrome_constants.h"

namespace chrome {
// The following should not be used for UI strings; they are meant
// for system strings only. UI changes should be made in the GRD.
const wchar_t kBrowserProcessExecutableName[] = L"chrome.exe";
#if defined(GOOGLE_CHROME_BUILD)
const wchar_t kBrowserAppName[] = L"Chrome";
const char    kStatsFilename[] = "ChromeStats";
#else
const wchar_t kBrowserAppName[] = L"Chromium";
const char    kStatsFilename[] = "ChromiumStats";
#endif
const wchar_t kExternalTabWindowClass[] = L"Chrome_ExternalTabContainer";
const wchar_t kMessageWindowClass[] = L"Chrome_MessageWindow";
const wchar_t kCrashReportLog[] = L"Reported Crashes.txt";
const wchar_t kTestingInterfaceDLL[] = L"testing_interface.dll";
const wchar_t kNotSignedInProfile[] = L"Default";
const wchar_t kNotSignedInID[] = L"not-signed-in";
const wchar_t kBrowserResourcesDll[] = L"chrome.dll";

// filenames
const wchar_t kArchivedHistoryFilename[] = L"Archived History";
const wchar_t kCacheDirname[] = L"Cache";
const wchar_t kChromePluginDataDirname[] = L"Plugin Data";
const wchar_t kCookieFilename[] = L"Cookies";
const wchar_t kHistoryFilename[] = L"History";
const wchar_t kLocalStateFilename[] = L"Local State";
const wchar_t kPreferencesFilename[] = L"Preferences";
const wchar_t kSafeBrowsingFilename[] = L"Safe Browsing";
const wchar_t kThumbnailsFilename[] = L"Thumbnails";
const wchar_t kUserDataDirname[] = L"User Data";
const wchar_t kWebDataFilename[] = L"Web Data";
const wchar_t kBookmarksFileName[] = L"Bookmarks";
const wchar_t kHistoryBookmarksFileName[] = L"Bookmarks From History";
const wchar_t kCustomDictionaryFileName[] = L"Custom Dictionary.txt";

// Note, this shouldn't go above 64.  See bug 535234.
const unsigned int kMaxRendererProcessCount = 20;
const int kStatsMaxThreads = 32;
const int kStatsMaxCounters = 300;

// We don't enable record mode in the released product because users could
// potentially be tricked into running a product in record mode without
// knowing it.  Enable in debug builds.  Playback mode is allowed always,
// because it is useful for testing and not hazardous by itself.
#ifndef NDEBUG
const bool kRecordModeEnabled = true;
#else
const bool kRecordModeEnabled = false;
#endif
}

<commit_msg>Rev stats file name to handle backwards incompatibility<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/chrome_constants.h"

namespace chrome {
// The following should not be used for UI strings; they are meant
// for system strings only. UI changes should be made in the GRD.
const wchar_t kBrowserProcessExecutableName[] = L"chrome.exe";
#if defined(GOOGLE_CHROME_BUILD)
const wchar_t kBrowserAppName[] = L"Chrome";
const char    kStatsFilename[] = "ChromeStats2";
#else
const wchar_t kBrowserAppName[] = L"Chromium";
const char    kStatsFilename[] = "ChromiumStats2";
#endif
const wchar_t kExternalTabWindowClass[] = L"Chrome_ExternalTabContainer";
const wchar_t kMessageWindowClass[] = L"Chrome_MessageWindow";
const wchar_t kCrashReportLog[] = L"Reported Crashes.txt";
const wchar_t kTestingInterfaceDLL[] = L"testing_interface.dll";
const wchar_t kNotSignedInProfile[] = L"Default";
const wchar_t kNotSignedInID[] = L"not-signed-in";
const wchar_t kBrowserResourcesDll[] = L"chrome.dll";

// filenames
const wchar_t kArchivedHistoryFilename[] = L"Archived History";
const wchar_t kCacheDirname[] = L"Cache";
const wchar_t kChromePluginDataDirname[] = L"Plugin Data";
const wchar_t kCookieFilename[] = L"Cookies";
const wchar_t kHistoryFilename[] = L"History";
const wchar_t kLocalStateFilename[] = L"Local State";
const wchar_t kPreferencesFilename[] = L"Preferences";
const wchar_t kSafeBrowsingFilename[] = L"Safe Browsing";
const wchar_t kThumbnailsFilename[] = L"Thumbnails";
const wchar_t kUserDataDirname[] = L"User Data";
const wchar_t kWebDataFilename[] = L"Web Data";
const wchar_t kBookmarksFileName[] = L"Bookmarks";
const wchar_t kHistoryBookmarksFileName[] = L"Bookmarks From History";
const wchar_t kCustomDictionaryFileName[] = L"Custom Dictionary.txt";

// Note, this shouldn't go above 64.  See bug 535234.
const unsigned int kMaxRendererProcessCount = 20;
const int kStatsMaxThreads = 32;
const int kStatsMaxCounters = 300;

// We don't enable record mode in the released product because users could
// potentially be tricked into running a product in record mode without
// knowing it.  Enable in debug builds.  Playback mode is allowed always,
// because it is useful for testing and not hazardous by itself.
#ifndef NDEBUG
const bool kRecordModeEnabled = true;
#else
const bool kRecordModeEnabled = false;
#endif
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <vector>
#include <osl/time.h>

#define LOK_USE_UNSTABLE_API

#include <LibreOfficeKit/LibreOfficeKitInit.h>
#include <LibreOfficeKit/LibreOfficeKit.hxx>

using namespace lok;

static int help()
{
    fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document]\n" );
    fprintf( stderr, "renders a selection of small tiles from the document, checksums them and times the process\n" );
    return 1;
}

static double getTimeNow()
{
    TimeValue aValue;
    osl_getSystemTime(&aValue);
    return (double)aValue.Seconds +
           (double)aValue.Nanosec / (1000*1000*1000);
}

int main( int argc, char* argv[] )
{
    struct TimeRecord {
        const char *mpName;
        double mfTime;

        TimeRecord() : mpName(NULL), mfTime(getTimeNow()) { }
        explicit TimeRecord(const char *pName) :
                       mpName(pName ), mfTime(getTimeNow()) { }
        explicit TimeRecord(const TimeRecord *pSrc) :
                       mpName(pSrc->mpName), mfTime(pSrc->mfTime) { }
    };
    std::vector< TimeRecord > aTimes;
    if( argc < 2 ||
        ( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) )
        return help();

    if ( argv[1][0] != '/' )
    {
        fprintf(stderr, "Absolute path required to libreoffice install\n");
        return 1;
    }

    aTimes.push_back(TimeRecord("initialization"));
    Office *pOffice = lok_cpp_init(argv[1]);
    aTimes.push_back(TimeRecord());

    if (argv[2] != NULL)
    {
        aTimes.push_back(TimeRecord("load document"));
        Document *pDocument(pOffice->documentLoad(argv[2]));
        aTimes.push_back(TimeRecord());

        aTimes.push_back(TimeRecord("getparts"));
        int nParts = pDocument->getParts();
        aTimes.push_back(TimeRecord());

        aTimes.push_back(TimeRecord("get size of parts"));
        for (int nPart = 0; nPart < nParts; nPart++)
        {
            char* pName = pDocument->getPartName(nPart);
            pDocument->setPart(nPart);
            long nWidth = 0, nHeight = 0;
            pDocument->getDocumentSize(&nWidth, &nHeight);
            fprintf (stderr, "  '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
            free (pName);
        }
        aTimes.push_back(TimeRecord());

        unsigned char pPixels[256*256*4];
        for (int nPart = 0; nPart < nParts; nPart++)
        {
            {
                char* pName = pDocument->getPartName(nPart);
                fprintf (stderr, "render '%s'\n", pName);
                free (pName);
            }
            pDocument->setPart(nPart);
            long nWidth = 0, nHeight = 0;
            pDocument->getDocumentSize(&nWidth, &nHeight);

            { // whole document
                aTimes.push_back(TimeRecord("render whole document"));
                int nRowStride = 256;
                pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                     0, 0, nWidth, nHeight); // not square
                aTimes.push_back(TimeRecord());
            }

            { // 1:1
                aTimes.push_back(TimeRecord("render sub-region at 1:1"));
                int nTiles = 0;
                int nSplit = nWidth / 4;
                for (int nX = 0; nX < 4; nX++)
                {
                    for (int nY = 0; nY < nHeight / nSplit; nY++)
                    {
                        int nRowStride = 256;
                        int nTilePosX = nX * nSplit;
                        int nTilePosY = nY * nSplit;
                        pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                             nTilePosX, nTilePosY, 256, 256);
                        nTiles++;
                        fprintf (stderr, "   rendered tile %d at %d, %d\n",
                                 nTiles, nTilePosX, nTilePosY);
                    }
                }
                aTimes.push_back(TimeRecord());
            }

            { // scaled
                aTimes.push_back(TimeRecord("render sub-regions at scale"));
                int nTiles = 0;
                int nSplit = nWidth / 4;
                for (int nX = 0; nX < 4; nX++)
                {
                    for (int nY = 0; nY < nHeight / nSplit; nY++)
                    {
                        int nRowStride = 256;
                        int nTilePosX = nX * nSplit;
                        int nTilePosY = nY * nSplit;
                        pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                             nTilePosX, nTilePosY, nSplit, nSplit);
                        nTiles++;
                        fprintf (stderr, "   rendered tile %d at %d, %d\n",
                                 nTiles, nTilePosX, nTilePosY);
                    }
                }
                aTimes.push_back(TimeRecord());
            }
        }

        aTimes.push_back(TimeRecord("destroy document"));
        delete pDocument;
        aTimes.push_back(TimeRecord());
    }

    delete pOffice;

    double nTotal = 0.0;
    fprintf (stderr, "profile run:\n");
    for (size_t i = 0; i < aTimes.size() - 1; i++)
    {
        double nDelta = aTimes[i+1].mfTime - aTimes[i].mfTime;
        fprintf (stderr, "  %s - %2.4f(ms)\n", aTimes[i].mpName, nDelta * 1000.0);
        if (aTimes[i+1].mpName == NULL)
            i++; // skip it.
        nTotal += nDelta;
    }
    fprintf (stderr, "Total: %2.4f(s)\n", nTotal);
    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>loplugin:unreffun<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <vector>
#include <osl/time.h>

#define LOK_USE_UNSTABLE_API

#include <LibreOfficeKit/LibreOfficeKitInit.h>
#include <LibreOfficeKit/LibreOfficeKit.hxx>

using namespace lok;

static int help()
{
    fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document]\n" );
    fprintf( stderr, "renders a selection of small tiles from the document, checksums them and times the process\n" );
    return 1;
}

static double getTimeNow()
{
    TimeValue aValue;
    osl_getSystemTime(&aValue);
    return (double)aValue.Seconds +
           (double)aValue.Nanosec / (1000*1000*1000);
}

int main( int argc, char* argv[] )
{
    struct TimeRecord {
        const char *mpName;
        double mfTime;

        TimeRecord() : mpName(NULL), mfTime(getTimeNow()) { }
        explicit TimeRecord(const char *pName) :
                       mpName(pName ), mfTime(getTimeNow()) { }
    };
    std::vector< TimeRecord > aTimes;
    if( argc < 2 ||
        ( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) )
        return help();

    if ( argv[1][0] != '/' )
    {
        fprintf(stderr, "Absolute path required to libreoffice install\n");
        return 1;
    }

    aTimes.push_back(TimeRecord("initialization"));
    Office *pOffice = lok_cpp_init(argv[1]);
    aTimes.push_back(TimeRecord());

    if (argv[2] != NULL)
    {
        aTimes.push_back(TimeRecord("load document"));
        Document *pDocument(pOffice->documentLoad(argv[2]));
        aTimes.push_back(TimeRecord());

        aTimes.push_back(TimeRecord("getparts"));
        int nParts = pDocument->getParts();
        aTimes.push_back(TimeRecord());

        aTimes.push_back(TimeRecord("get size of parts"));
        for (int nPart = 0; nPart < nParts; nPart++)
        {
            char* pName = pDocument->getPartName(nPart);
            pDocument->setPart(nPart);
            long nWidth = 0, nHeight = 0;
            pDocument->getDocumentSize(&nWidth, &nHeight);
            fprintf (stderr, "  '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
            free (pName);
        }
        aTimes.push_back(TimeRecord());

        unsigned char pPixels[256*256*4];
        for (int nPart = 0; nPart < nParts; nPart++)
        {
            {
                char* pName = pDocument->getPartName(nPart);
                fprintf (stderr, "render '%s'\n", pName);
                free (pName);
            }
            pDocument->setPart(nPart);
            long nWidth = 0, nHeight = 0;
            pDocument->getDocumentSize(&nWidth, &nHeight);

            { // whole document
                aTimes.push_back(TimeRecord("render whole document"));
                int nRowStride = 256;
                pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                     0, 0, nWidth, nHeight); // not square
                aTimes.push_back(TimeRecord());
            }

            { // 1:1
                aTimes.push_back(TimeRecord("render sub-region at 1:1"));
                int nTiles = 0;
                int nSplit = nWidth / 4;
                for (int nX = 0; nX < 4; nX++)
                {
                    for (int nY = 0; nY < nHeight / nSplit; nY++)
                    {
                        int nRowStride = 256;
                        int nTilePosX = nX * nSplit;
                        int nTilePosY = nY * nSplit;
                        pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                             nTilePosX, nTilePosY, 256, 256);
                        nTiles++;
                        fprintf (stderr, "   rendered tile %d at %d, %d\n",
                                 nTiles, nTilePosX, nTilePosY);
                    }
                }
                aTimes.push_back(TimeRecord());
            }

            { // scaled
                aTimes.push_back(TimeRecord("render sub-regions at scale"));
                int nTiles = 0;
                int nSplit = nWidth / 4;
                for (int nX = 0; nX < 4; nX++)
                {
                    for (int nY = 0; nY < nHeight / nSplit; nY++)
                    {
                        int nRowStride = 256;
                        int nTilePosX = nX * nSplit;
                        int nTilePosY = nY * nSplit;
                        pDocument->paintTile(pPixels, 256, 256, &nRowStride,
                                             nTilePosX, nTilePosY, nSplit, nSplit);
                        nTiles++;
                        fprintf (stderr, "   rendered tile %d at %d, %d\n",
                                 nTiles, nTilePosX, nTilePosY);
                    }
                }
                aTimes.push_back(TimeRecord());
            }
        }

        aTimes.push_back(TimeRecord("destroy document"));
        delete pDocument;
        aTimes.push_back(TimeRecord());
    }

    delete pOffice;

    double nTotal = 0.0;
    fprintf (stderr, "profile run:\n");
    for (size_t i = 0; i < aTimes.size() - 1; i++)
    {
        double nDelta = aTimes[i+1].mfTime - aTimes[i].mfTime;
        fprintf (stderr, "  %s - %2.4f(ms)\n", aTimes[i].mpName, nDelta * 1000.0);
        if (aTimes[i+1].mpName == NULL)
            i++; // skip it.
        nTotal += nDelta;
    }
    fprintf (stderr, "Total: %2.4f(s)\n", nTotal);
    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pwre.hpp>

#if defined(__APPLE__) && defined(__MACH__)
	#include <OpenGL/gl.h>
#else
	#include <GL/gl.h>
#endif

int main() {
	Pwre::System::Init();

	Pwre::GLWindow wnd;
	wnd.Resize(600, 500);
	wnd.MakeCurrent();
	wnd.Retitle((const char *)glGetString(GL_VERSION));
	glClearColor(1, 1, 1, 1);
	wnd.AddStates(PWRE_STATE_VISIBLE);
	wnd.Move();

	while (Pwre::System::Step()) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glBegin(GL_TRIANGLES);

		glColor3f(1.0, 0.0, 0.0);
		glVertex3f(0.0, 1.0, 0.0);

		glColor3f(0.0, 1.0, 0.0);
		glVertex3f(-1.0, -1.0, 0.0);

		glColor3f(0.0, 0.0, 1.0);
		glVertex3f(1.0, -1.0, 0.0);

		glEnd();
		wnd.SwapBuffers();
	}
	return 0;
}
<commit_msg>Fixed<commit_after>#include <pwre.hpp>

#if defined(__APPLE__) && defined(__MACH__)
	#include <OpenGL/gl.h>
#else
	#include <GL/gl.h>
#endif

int main() {
	Pwre::System::Init();

	Pwre::GLWindow wnd;
	wnd.Resize(600, 500);
	wnd.MakeCurrent();
	wnd.Retitle((const char *)glGetString(GL_VERSION));
	glClearColor(1, 1, 1, 1);
	wnd.AddStates(PWRE_STATE_VISIBLE);
	wnd.Move();

	while (Pwre::System::Step()) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glBegin(GL_TRIANGLES);

		glColor3f(1.0, 0.0, 0.0);
		glVertex3f(0.0, 1.0, 0.0);

		glColor3f(0.0, 1.0, 0.0);
		glVertex3f(-1.0, -1.0, 0.0);

		glColor3f(0.0, 0.0, 1.0);
		glVertex3f(1.0, -1.0, 0.0);

		glEnd();
		wnd.SwapBuffers();
	}
	return 0;
}
<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2010 VoltDB Inc.
 *
 * VoltDB 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 3 of the License, or
 * (at your option) any later version.
 *
 * VoltDB 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "JNITopend.h"
#include <cassert>

#include "common/debuglog.h"
#include "storage/table.h"

namespace voltdb{

// Create an instance of this class on the stack to release all local
// references created during its lifetime.
class JNILocalFrameBarrier {
  private:
    JNIEnv * m_env;
    int32_t m_refs;
    int32_t m_result;

  public:
    JNILocalFrameBarrier(JNIEnv* env, int32_t numReferences) {
        m_env = env;
        m_refs = numReferences;
        m_result = m_env->PushLocalFrame(m_refs);
    }

    ~JNILocalFrameBarrier() {
        // pass jobject* to get pointer to previous frame?
        m_env->PopLocalFrame(NULL);
    }

    int32_t checkResult() {
        return m_result;
    }
};

JNITopend::JNITopend(JNIEnv *env, jobject caller) : m_jniEnv(env), m_javaExecutionEngine(caller) {
    // Cache the method id for better performance. It is valid until the JVM unloads the class:
    // http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp17074
    jclass jniClass = m_jniEnv->GetObjectClass(m_javaExecutionEngine);
    VOLT_TRACE("found class: %d", jniClass == NULL);

    m_nextDependencyMID = m_jniEnv->GetMethodID(jniClass, "nextDependencyAsBytes", "(I)[B");
    assert(m_nextDependencyMID != 0);

    m_crashVoltDBMID =
        m_jniEnv->GetStaticMethodID(
            jniClass,
            "crashVoltDB",
            "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I)V");
    assert(m_crashVoltDBMID != 0);

    if (m_nextDependencyMID == 0 ||
        m_crashVoltDBMID == 0)
    {
        throw std::exception();
    }
}

int JNITopend::loadNextDependency(int32_t dependencyId, voltdb::Pool *stringPool, Table* destination) {
    VOLT_DEBUG("iterating java dependency for id %d", dependencyId);

    JNILocalFrameBarrier jni_frame = JNILocalFrameBarrier(m_jniEnv, 10);
    if (jni_frame.checkResult() < 0) {
        VOLT_ERROR("Unable to load dependency: jni frame error.");
        throw std::exception();
    }

    jbyteArray jbuf = (jbyteArray)(m_jniEnv->CallObjectMethod(m_javaExecutionEngine,
                                                              m_nextDependencyMID,
                                                              dependencyId));

    if (!jbuf) {
        return 0;
    }

    jsize length = m_jniEnv->GetArrayLength(jbuf);
    if (length > 0) {
        jboolean is_copy;
        jbyte *bytes = m_jniEnv->GetByteArrayElements(jbuf, &is_copy);
        ReferenceSerializeInput serialize_in(bytes, length);
        destination->loadTuplesFrom(true, serialize_in, stringPool);
        if (is_copy == JNI_TRUE)
        {
            m_jniEnv->ReleaseByteArrayElements(jbuf, bytes, 0);
        }
        return 1;
    }
    else {
        return 0;
    }
}

void JNITopend::crashVoltDB(FatalException e) {
    //Enough references for the reason string, traces array, and traces strings
    JNILocalFrameBarrier jni_frame =
            JNILocalFrameBarrier(
                    m_jniEnv,
                    static_cast<int32_t>(e.m_traces.size()) + 4);
    if (jni_frame.checkResult() < 0) {
        VOLT_ERROR("Unable to load dependency: jni frame error.");
        throw std::exception();
    }
    jstring jReason = m_jniEnv->NewStringUTF(e.m_reason.c_str());
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    jstring jFilename = m_jniEnv->NewStringUTF(e.m_filename);
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    jobjectArray jTracesArray =
            m_jniEnv->NewObjectArray(
                    static_cast<jsize>(e.m_traces.size()),
                    m_jniEnv->FindClass("java/lang/String"),
                    NULL);
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    for (int ii = 0; ii < e.m_traces.size(); ii++) {
        jstring traceString = m_jniEnv->NewStringUTF(e.m_traces[ii].c_str());
        m_jniEnv->SetObjectArrayElement( jTracesArray, ii, traceString);
    }
    m_jniEnv->CallStaticVoidMethod(
            m_jniEnv->GetObjectClass(m_javaExecutionEngine),
            m_crashVoltDBMID,
            jReason,
            jTracesArray,
            jFilename,
            static_cast<int32_t>(e.m_lineno));
    throw std::exception();
}

JNITopend::~JNITopend() {
    m_jniEnv->DeleteGlobalRef(m_javaExecutionEngine);
}

}
<commit_msg>ENG-781, redux<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2010 VoltDB Inc.
 *
 * VoltDB 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 3 of the License, or
 * (at your option) any later version.
 *
 * VoltDB 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "JNITopend.h"
#include <cassert>

#include "common/debuglog.h"
#include "storage/table.h"

namespace voltdb{

// Create an instance of this class on the stack to release all local
// references created during its lifetime.
class JNILocalFrameBarrier {
  private:
    JNIEnv * m_env;
    int32_t m_refs;
    int32_t m_result;

    jboolean m_isCopy;
    jbyteArray m_jbuf;
    jbyte* m_bytes;

  public:
    JNILocalFrameBarrier(JNIEnv* env, int32_t numReferences) {
        m_env = env;
        m_refs = numReferences;
        m_result = m_env->PushLocalFrame(m_refs);
        m_isCopy = JNI_FALSE;
    }

    void addDependencyRef(jboolean isCopy, jbyteArray jbuf, jbyte* bytes)
    {
        m_isCopy = isCopy;
        m_jbuf = jbuf;
        m_bytes = bytes;
    }

    ~JNILocalFrameBarrier() {
        if (m_isCopy == JNI_TRUE)
        {
            m_env->ReleaseByteArrayElements(m_jbuf, m_bytes, 0);
        }
        // pass jobject* to get pointer to previous frame?
        m_env->PopLocalFrame(NULL);
    }

    int32_t checkResult() {
        return m_result;
    }
};

JNITopend::JNITopend(JNIEnv *env, jobject caller) : m_jniEnv(env), m_javaExecutionEngine(caller) {
    // Cache the method id for better performance. It is valid until the JVM unloads the class:
    // http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp17074
    jclass jniClass = m_jniEnv->GetObjectClass(m_javaExecutionEngine);
    VOLT_TRACE("found class: %d", jniClass == NULL);

    m_nextDependencyMID = m_jniEnv->GetMethodID(jniClass, "nextDependencyAsBytes", "(I)[B");
    assert(m_nextDependencyMID != 0);

    m_crashVoltDBMID =
        m_jniEnv->GetStaticMethodID(
            jniClass,
            "crashVoltDB",
            "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I)V");
    assert(m_crashVoltDBMID != 0);

    if (m_nextDependencyMID == 0 ||
        m_crashVoltDBMID == 0)
    {
        throw std::exception();
    }
}

int JNITopend::loadNextDependency(int32_t dependencyId, voltdb::Pool *stringPool, Table* destination) {
    VOLT_DEBUG("iterating java dependency for id %d", dependencyId);

    JNILocalFrameBarrier jni_frame = JNILocalFrameBarrier(m_jniEnv, 10);
    if (jni_frame.checkResult() < 0) {
        VOLT_ERROR("Unable to load dependency: jni frame error.");
        throw std::exception();
    }

    jbyteArray jbuf = (jbyteArray)(m_jniEnv->CallObjectMethod(m_javaExecutionEngine,
                                                              m_nextDependencyMID,
                                                              dependencyId));

    if (!jbuf) {
        return 0;
    }

    jsize length = m_jniEnv->GetArrayLength(jbuf);
    if (length > 0) {
        jboolean is_copy;
        jbyte *bytes = m_jniEnv->GetByteArrayElements(jbuf, &is_copy);
        // Add the dependency buffer info to the stack object
        // so it'll get cleaned up if loadTuplesFrom throws
        jni_frame.addDependencyRef(is_copy, jbuf, bytes);
        ReferenceSerializeInput serialize_in(bytes, length);
        destination->loadTuplesFrom(true, serialize_in, stringPool);
        return 1;
    }
    else {
        return 0;
    }
}

void JNITopend::crashVoltDB(FatalException e) {
    //Enough references for the reason string, traces array, and traces strings
    JNILocalFrameBarrier jni_frame =
            JNILocalFrameBarrier(
                    m_jniEnv,
                    static_cast<int32_t>(e.m_traces.size()) + 4);
    if (jni_frame.checkResult() < 0) {
        VOLT_ERROR("Unable to load dependency: jni frame error.");
        throw std::exception();
    }
    jstring jReason = m_jniEnv->NewStringUTF(e.m_reason.c_str());
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    jstring jFilename = m_jniEnv->NewStringUTF(e.m_filename);
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    jobjectArray jTracesArray =
            m_jniEnv->NewObjectArray(
                    static_cast<jsize>(e.m_traces.size()),
                    m_jniEnv->FindClass("java/lang/String"),
                    NULL);
    if (m_jniEnv->ExceptionCheck()) {
        m_jniEnv->ExceptionDescribe();
        throw std::exception();
    }
    for (int ii = 0; ii < e.m_traces.size(); ii++) {
        jstring traceString = m_jniEnv->NewStringUTF(e.m_traces[ii].c_str());
        m_jniEnv->SetObjectArrayElement( jTracesArray, ii, traceString);
    }
    m_jniEnv->CallStaticVoidMethod(
            m_jniEnv->GetObjectClass(m_javaExecutionEngine),
            m_crashVoltDBMID,
            jReason,
            jTracesArray,
            jFilename,
            static_cast<int32_t>(e.m_lineno));
    throw std::exception();
}

JNITopend::~JNITopend() {
    m_jniEnv->DeleteGlobalRef(m_javaExecutionEngine);
}

}
<|endoftext|>


<commit_before>/* <src/HttpWorker.cpp>
 *
 * This file is part of the x0 web server project and is released under GPL-3.
 * http://www.xzero.io/
 *
 * (c) 2009-2013 Christian Parpart <trapni@gmail.com>
 */

#include <x0/http/HttpWorker.h>
#include <x0/http/HttpRequest.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpConnection.h>
#include <x0/ServerSocket.h>
#include <x0/DebugLogger.h>

#include <algorithm>
#include <cstdarg>
#include <ev++.h>
#include <signal.h>
#include <pthread.h>

// XXX one a connection has been passed to a worker, it is *bound* to it.

#if !defined(XZERO_NDEBUG)
//#	define TRACE(n, msg...) X0_DEBUG("worker", (n), msg)
#	define TRACE(n, msg...) log(Severity::debug ## n, msg)
#else
#	define TRACE(n, msg...) do {} while (0)
#endif

namespace x0 {

/*!
 * Creates an HTTP worker instance.
 *
 * \param server   the worker parents server instance
 * \param loop     the event loop to be used within this worker
 * \param id       unique ID within the server instance
 * \param threaded whether or not to spawn a thread to actually run this worker
 */
HttpWorker::HttpWorker(HttpServer& server, struct ev_loop *loop, unsigned int id, bool threaded) :
	id_(id),
	state_(Inactive),
	server_(server),
	loop_(loop),
	startupTime_(ev_now(loop_)),
	now_(),
	connectionLoad_(0),
	requestCount_(0),
	connectionCount_(0),
	thread_(pthread_self()),
	queue_(),
	resumeLock_(),
	resumeCondition_(),
	performanceCounter_(),
	stopHandler_(),
	killHandler_(),
	connections_(nullptr),
	freeConnections_(nullptr),
	evLoopCheck_(loop_),
	evNewConnection_(loop_),
	evWakeup_(loop_),
	fileinfo(loop_, &server_.fileinfoConfig_)
{
	evLoopCheck_.set<HttpWorker, &HttpWorker::onLoopCheck>(this);
	evLoopCheck_.start();

	evNewConnection_.set<HttpWorker, &HttpWorker::onNewConnection>(this);
	evNewConnection_.start();

	evWakeup_.set<&HttpWorker::onWakeup>();
	evWakeup_.start();

	pthread_mutex_init(&resumeLock_, nullptr);
	pthread_cond_init(&resumeCondition_, nullptr);

	if (threaded) {
		pthread_create(&thread_, nullptr, &HttpWorker::_run, this);
	}

	setName("worker/%d", id_);

	TRACE(1, "spawned");
}

HttpWorker::~HttpWorker()
{
	TRACE(1, "destroying");

	clearCustomData();

	pthread_cond_destroy(&resumeCondition_);
	pthread_mutex_destroy(&resumeLock_);

	evLoopCheck_.stop();
	evNewConnection_.stop();
	evWakeup_.stop();

	freeCache();

	ev_loop_destroy(loop_);
}

void* HttpWorker::_run(void* p)
{
	reinterpret_cast<HttpWorker*>(p)->run();
	return nullptr;
}

void HttpWorker::run()
{
	state_ = Running;

	// XXX invoke onWorkerSpawned-hook here because we want to ensure this hook is
	// XXX being invoked from *within* the worker-thread.
	server_.onWorkerSpawn(this);

	TRACE(1, "enter loop");
	ev_loop(loop_, 0);

	while (connections_)
		_kill();

	server_.onWorkerUnspawn(this);

	state_ = Inactive;
}

/*!
 * Sets the thread/process name that's running this worker.
 */
void HttpWorker::setName(const char* fmt, ...)
{
	char buf[17]; // the name may be at most 16 bytes long.
	va_list va;

	va_start(va, fmt);
	vsnprintf(buf, sizeof(buf), fmt, va);
	va_end(va);

	pthread_setname_np(thread_, buf);
}

void HttpWorker::log(LogMessage&& msg)
{
	msg.addTag("worker/%u", id());

	server().log(std::forward<LogMessage>(msg));
}

/** enqueues/assigns/registers given client connection information to this worker.
 */
void HttpWorker::enqueue(std::pair<Socket*, ServerSocket*>&& client)
{
	queue_.enqueue(client);
	evNewConnection_.send();
}

/** callback to be invoked when new connection(s) have been assigned to this worker.
 */
void HttpWorker::onNewConnection(ev::async& /*w*/, int /*revents*/)
{
	std::pair<Socket*, ServerSocket*> client;

	while (queue_.dequeue(&client)) {
		spawnConnection(client.first, client.second);
	}
}

void HttpWorker::onWakeup(ev::async& w, int revents)
{
	// no-op - this callback is simply used to wake up the worker's event loop
}

void HttpWorker::spawnConnection(Socket* client, ServerSocket* listener)
{
	TRACE(1, "client connected; fd:%d", client->handle());

	++connectionLoad_;
	++connectionCount_;

	// XXX since socket has not been used so far, I might be able to defer its creation out of its socket descriptor
	// XXX so that I do not have to double-initialize libev's loop handles for this socket.
	client->setLoop(loop_);

	HttpConnection* c;
	if (likely(freeConnections_ != nullptr)) {
		c = freeConnections_;
		c->id_ = connectionCount_;
		freeConnections_ = c->next_;
	}
	else {
		c = new HttpConnection(this, connectionCount_/*id*/);
	}

	if (connections_)
		connections_->prev_ = c;

	c->next_ = connections_;
	connections_ = c;

	c->start(listener, client);
}

/** releases/unregisters given (and to-be-destroyed) connection from this worker.
 *
 * This decrements the connection-load counter by one.
 */
void HttpWorker::release(HttpConnection* c)
{
	//    /--<--\   /--<--\   /--<--\
	// NULL     item1     item2     item3     NULL
	//              \-->--/   \-->--/   \-->--/

	--connectionLoad_;

	// unlink from active-list
	HttpConnection* prev = c->prev_;
	HttpConnection* next = c->next_;

	if (prev)
		prev->next_ = next;

	if (next)
		next->prev_ = prev;

	if (c == connections_)
		connections_ = next;

	// link into free-list
	c->next_ = freeConnections_;
	c->prev_ = nullptr;					// not needed
	if (freeConnections_ && freeConnections_->prev_)
		freeConnections_->prev_ = c;	// not needed
	freeConnections_ = c;
}

/**
 * Clear some cached objects to free up memory.
 */
void HttpWorker::freeCache()
{
	size_t i = 0;
	while (freeConnections_) {
		auto next = freeConnections_->next_;
		delete freeConnections_;
		freeConnections_ = next;
		++i;
	}
	TRACE(1, "cleared %zu free-connections items", i);
}

void HttpWorker::handleRequest(HttpRequest *r)
{
	++requestCount_;
	performanceCounter_.touch(now_.value());

#if X0_HTTP_STRICT
	BufferRef expectHeader = r->requestHeader("Expect");
	bool contentRequired = r->method == "POST" || r->method == "PUT";

	if (contentRequired) {
		if (r->connection.contentLength() == -1 && !r->connection.isChunked()) {
			r>status = HttpStatus::LengthRequired;
			r->finish();
			return true;
		}
	} else {
		if (r->contentAvailable()) {
			r->status = HttpStatus::BadRequest; // FIXME do we have a better status code?
			r->finish();
			return true;
		}
	}

	if (expectHeader) {
		r->expectingContinue = equals(expectHeader, "100-continue");

		if (!r->expectingContinue || !r->supportsProtocol(1, 1)) {
			r->status = HttpStatus::ExpectationFailed;
			r->finish();
			return true;
		}
	}
#endif

	server_.onPreProcess(r);

	if (!server_.requestHandler(r))
		r->finish();
}

void HttpWorker::_stop()
{
	TRACE(1, "_stop");

	evLoopCheck_.stop();
	evNewConnection_.stop();
	evWakeup_.stop();

	for (auto handler: stopHandler_)
		handler();
}

void HttpWorker::onLoopCheck(ev::check& /*w*/, int /*revents*/)
{
	// update server time
	now_.update(ev_now(loop_));
}

void HttpWorker::setAffinity(int cpu)
{
	cpu_set_t set;

	CPU_ZERO(&set);
	CPU_SET(cpu, &set);

	TRACE(1, "setAffinity: %d", cpu);

	int rv = pthread_setaffinity_np(thread_, sizeof(set), &set);
	if (rv < 0) {
		log(Severity::error, "setting scheduler affinity on CPU %d failed for worker %u. %s",
			cpu, id_, strerror(errno));
	}
}

void HttpWorker::bind(ServerSocket* s)
{
	s->set<HttpWorker, &HttpWorker::spawnConnection>(this);
}

/** suspend the execution of the worker thread until resume() is invoked.
 *
 * \note has no effect on main worker
 * \see resume()
 */
void HttpWorker::suspend()
{
	TRACE(1, "suspend");

	if (id_ != 0)
		post<HttpWorker, &HttpWorker::_suspend>(this);
}

void HttpWorker::_suspend()
{
	TRACE(1, "_suspend");
	pthread_mutex_lock(&resumeLock_);
	state_ = Suspended;
	pthread_cond_wait(&resumeCondition_, &resumeLock_);
	state_ = Running;
	pthread_mutex_unlock(&resumeLock_);
}

/** resumes the previousely suspended worker thread.
 *
 * \note has no effect on main worker
 * \see suspend()
 */
void HttpWorker::resume()
{
	TRACE(1, "resume");
	if (id_ != 0)
		pthread_cond_signal(&resumeCondition_);
}

void HttpWorker::stop()
{
	TRACE(1, "stop: post -> _stop()");
	post<HttpWorker, &HttpWorker::_stop>(this);
}

void HttpWorker::join()
{
	if (thread_ != pthread_self()) {
		pthread_join(thread_, nullptr);
	}
}

/*! Actually aborts all active connections.
 *
 * \see HttpConnection::abort()
 */
void HttpWorker::kill()
{
	TRACE(1, "kill: post -> _kill()");
	post<HttpWorker, &HttpWorker::_kill>(this);
}

/*! Actually aborts all active connections.
 *
 * \note Must be invoked from within the worker's thread.
 *
 * \see HttpConnection::abort()
 */
void HttpWorker::_kill()
{
	TRACE(1, "_kill()");
	while (connections_) {
		std::list<HttpConnection*> copy;

		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			copy.push_back(c);

		for (auto c: copy)
			c->abort();

#ifndef XZERO_NDEBUG
		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			c->log(Severity::debug, "connection still open");
#endif
	}

	for (auto handler: killHandler_) {
		TRACE(1, "_kill: invoke kill handler");
		handler();
	}
}

std::list<std::function<void()>>::iterator HttpWorker::registerStopHandler(std::function<void()> callback)
{
	stopHandler_.push_front(callback);
	return stopHandler_.begin();
}

void HttpWorker::unregisterStopHandler(std::list<std::function<void()>>::iterator handle)
{
	stopHandler_.erase(handle);
}

std::list<std::function<void()>>::iterator HttpWorker::registerKillHandler(std::function<void()> callback)
{
	killHandler_.push_front(callback);
	return killHandler_.begin();
}

void HttpWorker::unregisterKillHandler(std::list<std::function<void()>>::iterator handle)
{
	killHandler_.erase(handle);
}

void HttpWorker::post_thunk3(int revents, void* arg)
{
	std::function<void()>* callback = static_cast<std::function<void()>*>(arg);
	(*callback)();
	delete callback;
}

} // namespace x0
<commit_msg>[http] fixes compile error with "Expect: 100-continue" support enabled.<commit_after>/* <src/HttpWorker.cpp>
 *
 * This file is part of the x0 web server project and is released under GPL-3.
 * http://www.xzero.io/
 *
 * (c) 2009-2013 Christian Parpart <trapni@gmail.com>
 */

#include <x0/http/HttpWorker.h>
#include <x0/http/HttpRequest.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpConnection.h>
#include <x0/ServerSocket.h>
#include <x0/DebugLogger.h>

#include <algorithm>
#include <cstdarg>
#include <ev++.h>
#include <signal.h>
#include <pthread.h>

// XXX one a connection has been passed to a worker, it is *bound* to it.

#if !defined(XZERO_NDEBUG)
//#	define TRACE(n, msg...) X0_DEBUG("worker", (n), msg)
#	define TRACE(n, msg...) log(Severity::debug ## n, msg)
#else
#	define TRACE(n, msg...) do {} while (0)
#endif

namespace x0 {

/*!
 * Creates an HTTP worker instance.
 *
 * \param server   the worker parents server instance
 * \param loop     the event loop to be used within this worker
 * \param id       unique ID within the server instance
 * \param threaded whether or not to spawn a thread to actually run this worker
 */
HttpWorker::HttpWorker(HttpServer& server, struct ev_loop *loop, unsigned int id, bool threaded) :
	id_(id),
	state_(Inactive),
	server_(server),
	loop_(loop),
	startupTime_(ev_now(loop_)),
	now_(),
	connectionLoad_(0),
	requestCount_(0),
	connectionCount_(0),
	thread_(pthread_self()),
	queue_(),
	resumeLock_(),
	resumeCondition_(),
	performanceCounter_(),
	stopHandler_(),
	killHandler_(),
	connections_(nullptr),
	freeConnections_(nullptr),
	evLoopCheck_(loop_),
	evNewConnection_(loop_),
	evWakeup_(loop_),
	fileinfo(loop_, &server_.fileinfoConfig_)
{
	evLoopCheck_.set<HttpWorker, &HttpWorker::onLoopCheck>(this);
	evLoopCheck_.start();

	evNewConnection_.set<HttpWorker, &HttpWorker::onNewConnection>(this);
	evNewConnection_.start();

	evWakeup_.set<&HttpWorker::onWakeup>();
	evWakeup_.start();

	pthread_mutex_init(&resumeLock_, nullptr);
	pthread_cond_init(&resumeCondition_, nullptr);

	if (threaded) {
		pthread_create(&thread_, nullptr, &HttpWorker::_run, this);
	}

	setName("worker/%d", id_);

	TRACE(1, "spawned");
}

HttpWorker::~HttpWorker()
{
	TRACE(1, "destroying");

	clearCustomData();

	pthread_cond_destroy(&resumeCondition_);
	pthread_mutex_destroy(&resumeLock_);

	evLoopCheck_.stop();
	evNewConnection_.stop();
	evWakeup_.stop();

	freeCache();

	ev_loop_destroy(loop_);
}

void* HttpWorker::_run(void* p)
{
	reinterpret_cast<HttpWorker*>(p)->run();
	return nullptr;
}

void HttpWorker::run()
{
	state_ = Running;

	// XXX invoke onWorkerSpawned-hook here because we want to ensure this hook is
	// XXX being invoked from *within* the worker-thread.
	server_.onWorkerSpawn(this);

	TRACE(1, "enter loop");
	ev_loop(loop_, 0);

	while (connections_)
		_kill();

	server_.onWorkerUnspawn(this);

	state_ = Inactive;
}

/*!
 * Sets the thread/process name that's running this worker.
 */
void HttpWorker::setName(const char* fmt, ...)
{
	char buf[17]; // the name may be at most 16 bytes long.
	va_list va;

	va_start(va, fmt);
	vsnprintf(buf, sizeof(buf), fmt, va);
	va_end(va);

	pthread_setname_np(thread_, buf);
}

void HttpWorker::log(LogMessage&& msg)
{
	msg.addTag("worker/%u", id());

	server().log(std::forward<LogMessage>(msg));
}

/** enqueues/assigns/registers given client connection information to this worker.
 */
void HttpWorker::enqueue(std::pair<Socket*, ServerSocket*>&& client)
{
	queue_.enqueue(client);
	evNewConnection_.send();
}

/** callback to be invoked when new connection(s) have been assigned to this worker.
 */
void HttpWorker::onNewConnection(ev::async& /*w*/, int /*revents*/)
{
	std::pair<Socket*, ServerSocket*> client;

	while (queue_.dequeue(&client)) {
		spawnConnection(client.first, client.second);
	}
}

void HttpWorker::onWakeup(ev::async& w, int revents)
{
	// no-op - this callback is simply used to wake up the worker's event loop
}

void HttpWorker::spawnConnection(Socket* client, ServerSocket* listener)
{
	TRACE(1, "client connected; fd:%d", client->handle());

	++connectionLoad_;
	++connectionCount_;

	// XXX since socket has not been used so far, I might be able to defer its creation out of its socket descriptor
	// XXX so that I do not have to double-initialize libev's loop handles for this socket.
	client->setLoop(loop_);

	HttpConnection* c;
	if (likely(freeConnections_ != nullptr)) {
		c = freeConnections_;
		c->id_ = connectionCount_;
		freeConnections_ = c->next_;
	}
	else {
		c = new HttpConnection(this, connectionCount_/*id*/);
	}

	if (connections_)
		connections_->prev_ = c;

	c->next_ = connections_;
	connections_ = c;

	c->start(listener, client);
}

/** releases/unregisters given (and to-be-destroyed) connection from this worker.
 *
 * This decrements the connection-load counter by one.
 */
void HttpWorker::release(HttpConnection* c)
{
	//    /--<--\   /--<--\   /--<--\
	// NULL     item1     item2     item3     NULL
	//              \-->--/   \-->--/   \-->--/

	--connectionLoad_;

	// unlink from active-list
	HttpConnection* prev = c->prev_;
	HttpConnection* next = c->next_;

	if (prev)
		prev->next_ = next;

	if (next)
		next->prev_ = prev;

	if (c == connections_)
		connections_ = next;

	// link into free-list
	c->next_ = freeConnections_;
	c->prev_ = nullptr;					// not needed
	if (freeConnections_ && freeConnections_->prev_)
		freeConnections_->prev_ = c;	// not needed
	freeConnections_ = c;
}

/**
 * Clear some cached objects to free up memory.
 */
void HttpWorker::freeCache()
{
	size_t i = 0;
	while (freeConnections_) {
		auto next = freeConnections_->next_;
		delete freeConnections_;
		freeConnections_ = next;
		++i;
	}
	TRACE(1, "cleared %zu free-connections items", i);
}

void HttpWorker::handleRequest(HttpRequest *r)
{
	++requestCount_;
	performanceCounter_.touch(now_.value());

	BufferRef expectHeader = r->requestHeader("Expect");
	bool contentRequired = r->method == "POST" || r->method == "PUT";

	if (contentRequired) {
		if (r->connection.contentLength() == -1 && !r->connection.isChunked()) {
			r->status = HttpStatus::LengthRequired;
			r->finish();
			return;
		}
	} else {
		if (r->contentAvailable()) {
			r->status = HttpStatus::BadRequest; // FIXME do we have a better status code?
			r->finish();
			return;
		}
	}

	if (expectHeader) {
		r->expectingContinue = equals(expectHeader, "100-continue");

		if (!r->expectingContinue || !r->supportsProtocol(1, 1)) {
			r->status = HttpStatus::ExpectationFailed;
			r->finish();
			return;
		}
	}

	server_.onPreProcess(r);

	if (!server_.requestHandler(r))
		r->finish();
}

void HttpWorker::_stop()
{
	TRACE(1, "_stop");

	evLoopCheck_.stop();
	evNewConnection_.stop();
	evWakeup_.stop();

	for (auto handler: stopHandler_)
		handler();
}

void HttpWorker::onLoopCheck(ev::check& /*w*/, int /*revents*/)
{
	// update server time
	now_.update(ev_now(loop_));
}

void HttpWorker::setAffinity(int cpu)
{
	cpu_set_t set;

	CPU_ZERO(&set);
	CPU_SET(cpu, &set);

	TRACE(1, "setAffinity: %d", cpu);

	int rv = pthread_setaffinity_np(thread_, sizeof(set), &set);
	if (rv < 0) {
		log(Severity::error, "setting scheduler affinity on CPU %d failed for worker %u. %s",
			cpu, id_, strerror(errno));
	}
}

void HttpWorker::bind(ServerSocket* s)
{
	s->set<HttpWorker, &HttpWorker::spawnConnection>(this);
}

/** suspend the execution of the worker thread until resume() is invoked.
 *
 * \note has no effect on main worker
 * \see resume()
 */
void HttpWorker::suspend()
{
	TRACE(1, "suspend");

	if (id_ != 0)
		post<HttpWorker, &HttpWorker::_suspend>(this);
}

void HttpWorker::_suspend()
{
	TRACE(1, "_suspend");
	pthread_mutex_lock(&resumeLock_);
	state_ = Suspended;
	pthread_cond_wait(&resumeCondition_, &resumeLock_);
	state_ = Running;
	pthread_mutex_unlock(&resumeLock_);
}

/** resumes the previousely suspended worker thread.
 *
 * \note has no effect on main worker
 * \see suspend()
 */
void HttpWorker::resume()
{
	TRACE(1, "resume");
	if (id_ != 0)
		pthread_cond_signal(&resumeCondition_);
}

void HttpWorker::stop()
{
	TRACE(1, "stop: post -> _stop()");
	post<HttpWorker, &HttpWorker::_stop>(this);
}

void HttpWorker::join()
{
	if (thread_ != pthread_self()) {
		pthread_join(thread_, nullptr);
	}
}

/*! Actually aborts all active connections.
 *
 * \see HttpConnection::abort()
 */
void HttpWorker::kill()
{
	TRACE(1, "kill: post -> _kill()");
	post<HttpWorker, &HttpWorker::_kill>(this);
}

/*! Actually aborts all active connections.
 *
 * \note Must be invoked from within the worker's thread.
 *
 * \see HttpConnection::abort()
 */
void HttpWorker::_kill()
{
	TRACE(1, "_kill()");
	while (connections_) {
		std::list<HttpConnection*> copy;

		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			copy.push_back(c);

		for (auto c: copy)
			c->abort();

#ifndef XZERO_NDEBUG
		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			c->log(Severity::debug, "connection still open");
#endif
	}

	for (auto handler: killHandler_) {
		TRACE(1, "_kill: invoke kill handler");
		handler();
	}
}

std::list<std::function<void()>>::iterator HttpWorker::registerStopHandler(std::function<void()> callback)
{
	stopHandler_.push_front(callback);
	return stopHandler_.begin();
}

void HttpWorker::unregisterStopHandler(std::list<std::function<void()>>::iterator handle)
{
	stopHandler_.erase(handle);
}

std::list<std::function<void()>>::iterator HttpWorker::registerKillHandler(std::function<void()> callback)
{
	killHandler_.push_front(callback);
	return killHandler_.begin();
}

void HttpWorker::unregisterKillHandler(std::list<std::function<void()>>::iterator handle)
{
	killHandler_.erase(handle);
}

void HttpWorker::post_thunk3(int revents, void* arg)
{
	std::function<void()>* callback = static_cast<std::function<void()>*>(arg);
	(*callback)();
	delete callback;
}

} // namespace x0
<|endoftext|>


<commit_before>/* <x0/FilterSource.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 * http://www.xzero.ws/
 *
 * (c) 2009-2010 Christian Parpart <trapni@gentoo.org>
 */

#include <x0/io/FilterSource.h>
#include <x0/io/BufferSink.h>
#include <x0/io/Filter.h>
#include <x0/Defines.h>
#include <memory>

namespace x0 {

ssize_t FilterSource::sendto(Sink& sink)
{
	if (buffer_.empty()) {
		BufferSink input;
		source_->sendto(input);
		buffer_ = filter_(input.buffer());
		pos_ = 0;
	}

	ssize_t result = sink.write(buffer_.data() + pos_, buffer_.size() - pos_);

	if (result > 0) {
		pos_ += result;
	}

	return result;
}

} // namespace x0
<commit_msg>[io] FilterSource: sendto() fixed.<commit_after>/* <x0/FilterSource.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 * http://www.xzero.ws/
 *
 * (c) 2009-2010 Christian Parpart <trapni@gentoo.org>
 */

#include <x0/io/FilterSource.h>
#include <x0/io/BufferSink.h>
#include <x0/io/Filter.h>
#include <x0/Defines.h>
#include <memory>

namespace x0 {

ssize_t FilterSource::sendto(Sink& sink)
{
	if (buffer_.empty()) {
		BufferSink input;
		ssize_t rv = source_->sendto(input);
		if (rv < 0 || (rv == 0 && !force_))
			return rv;
		buffer_ = filter_(input.buffer());
	}

	ssize_t result = sink.write(buffer_.data() + pos_, buffer_.size() - pos_);

	if (result > 0) {
		pos_ += result;
		if (pos_ == buffer_.size()) {
			pos_ = 0;
			buffer_.clear();
		}
	}

	return result;
}

} // namespace x0
<|endoftext|>


<commit_before>#include <curl/curl.h>        	// cURL to make HTTP requests
#include <iostream>             // std::cout, std::cin
#include <sstream>		          // stringstreams, converting ints to numbers
#include <string>             	// std::string, std::to_string;
#include <time.h>          	    // Timestamps

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::to_string;        	  // for converting an int into a string.

/*
    This is a POST request which is hard coded to one project - project 929
    Future POST programs will let you upload to any project, by using a class to do
    most of the work for us.
*/

// Basic upload a test. Uploads a number, a string and a timestamp
void upload_to_rsense(string title, int num, string letters, time_t timestamp)
{
    string upload;     		// DATA for the project. This will be the entire uploaded string.

    //  URL for the project. Change "929" for a different project.
    string url = "http://rsense-dev.cs.uml.edu/api/v1/projects/929/jsonDataUpload";

    /*
        Part of the stuff needed to upload. "3550" is the field ID for a number on rSENSE, so make
        sure to change that if you change the project ID in the URL.
        You may also need to change the following to your own project:
        contribution_key = the key to your iSENSE project
        contributor_name = you can leave this or change it to something relevant to your project
        for the data part, the field ID comes first and should be changed for your project's fields
    */
    string data = "\",\"contribution_key\":\"123\",\"contributor_name\":\"cURL\",\"data\":{\"4274\":[";

    // This part combines everything entered above into one string that can be uploaded to rSENSE.
    upload += string("{\"title\":\"") + title + data;                   // JSON/Title/Data string

    // Add the number and the bracket/comma to the upload string.
    upload += to_string(num) + string("],");

    // Add the letters that were entered (+ the field ID / JSON stuff)
    upload += string("\"4275\":[\"") + letters + string("\"],");

    // Add the timestamp field ID, timestamp, and JSON stuff.
    upload += string( "\"4276\":[\"") + to_string(timestamp) + string( "\"]}}");

    // Debugging:
    cout << "The string is: " << upload << endl;

    // CURL object and response code.
    CURL *curl;
    CURLcode res;

    // In windows, this will init the winsock stuff
    res = curl_global_init(CURL_GLOBAL_DEFAULT);

    // Set the headers to JSON
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: application/json");
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");

    // get a curl handle
    curl = curl_easy_init();
    if(curl)
    {
        // Set the URL that we will be using for our POST.
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

        // POST data. Upload will be the char array with all the data.
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, upload.c_str());

        // JSON Headers
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Verbose debug output - turn this on if you are having problems. It will spit out a ton of information.
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        cout << "\nrSENSE says: \n\n";

        // Perform the request, res will get the return code
        res = curl_easy_perform(curl);

        // For cURL return codes, see the following page:
        // http://curl.haxx.se/libcurl/c/libcurl-errors.html
        cout << "\n\ncURL return code was: " << res << endl;

        // Check for errors
        if(res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
        }

        curl_easy_cleanup(curl);                // always cleanup
    }

    curl_global_cleanup();
}

int main ()
{
    string title;
    string letters;
    time_t timestamp;
    int num = 0;

    // Get user input.
    cout << "Please enter a title for the dataset: ";       // Gets the title
    getline(cin, title);

    cout << "Please enter a bunch of letters: ";            // Gets a bunch of letters
    getline(cin, letters);

    cout << "Please enter a number: ";                      // Gets a number to upload to iSENSE
    cin >> num;

    // Get timestamp (unix)
    timestamp = time(NULL);

    // Let the user know we're uploading. (Maybe add an option to confirm here in the future.)
    cout << "\nUploading " << " to rSENSE.\n\n";
    cout << "The title you entered: " << title << endl;
    cout << "Letters you entered: " << letters << endl;
    cout << "Number you entered: " << num << endl;
    cout << "Timestamp: " << timestamp << endl << endl;

    // Right here I call a function to upload to rSENSE-dev.
    // I just pass it the title of the dataset and the number that the user entered.
    upload_to_rsense(title, num, letters, timestamp);

    return 0;
}
<commit_msg>quick fix to the comments<commit_after>#include <curl/curl.h>        	    // cURL to make HTTP requests
#include <iostream>                 // std::cout, std::cin
#include <sstream>                  // stringstreams, converting ints to numbers
#include <string>             	    // std::string, std::to_string;
#include <time.h>          	        // Timestamps

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::to_string;        	      // for converting an int into a string.

/*
    This is a POST request which is hard coded to one project - project 929
    Future POST programs will let you upload to any project, by using a class to do
    most of the work for us.
*/

// Basic upload a test. Uploads a number, a string and a timestamp
void upload_to_rsense(string title, int num, string letters, time_t timestamp)
{
    string upload;     		// DATA for the project. This will be the entire uploaded string.

    //  URL for the project. Change "929" for a different project.
    string url = "http://rsense-dev.cs.uml.edu/api/v1/projects/929/jsonDataUpload";

    /*
        Part of the stuff needed to upload. "3550" is the field ID for a number on rSENSE, so make
        sure to change that if you change the project ID in the URL.
        You may also need to change the following to your own project:
        contribution_key = the key to your iSENSE project
        contributor_name = you can leave this or change it to something relevant to your project
        for the data part, the field ID comes first and should be changed for your project's fields
    */
    string data = "\",\"contribution_key\":\"123\",\"contributor_name\":\"cURL\",\"data\":{\"4274\":[";

    // This part combines everything entered above into one string that can be uploaded to rSENSE.
    upload += string("{\"title\":\"") + title + data;                   // JSON/Title/Data string

    // Add the number and the bracket/comma to the upload string.
    upload += to_string(num) + string("],");

    // Add the letters that were entered (+ the field ID / JSON stuff)
    upload += string("\"4275\":[\"") + letters + string("\"],");

    // Add the timestamp field ID, timestamp, and JSON stuff.
    upload += string( "\"4276\":[\"") + to_string(timestamp) + string( "\"]}}");

    // Debugging:
    cout << "The string is: " << upload << endl;

    // CURL object and response code.
    CURL *curl;
    CURLcode res;

    // In windows, this will init the winsock stuff
    res = curl_global_init(CURL_GLOBAL_DEFAULT);

    // Set the headers to JSON
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: application/json");
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");

    // get a curl handle
    curl = curl_easy_init();
    if(curl)
    {
        // Set the URL that we will be using for our POST.
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

        // POST data. Upload will be the char array with all the data.
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, upload.c_str());

        // JSON Headers
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Verbose debug output - turn this on if you are having problems.
        // It will spit out a ton of information.
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        cout << "\nrSENSE says: \n\n";

        // Perform the request, res will get the return code
        res = curl_easy_perform(curl);

        // For cURL return codes, see the following page:
        // http://curl.haxx.se/libcurl/c/libcurl-errors.html
        cout << "\n\ncURL return code was: " << res << endl;

        // Check for errors
        if(res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
        }

        curl_easy_cleanup(curl);                // always cleanup
    }

    curl_global_cleanup();
}

int main ()
{
    string title;
    string letters;
    time_t timestamp;
    int num = 0;

    // Get user input.
    cout << "Please enter a title for the dataset: ";       // Gets the title
    getline(cin, title);

    cout << "Please enter a bunch of letters: ";            // Gets a bunch of letters
    getline(cin, letters);

    cout << "Please enter a number: ";                      // Gets a number to upload to iSENSE
    cin >> num;

    // Get timestamp (unix)
    timestamp = time(NULL);

    // Let the user know we're uploading. (Maybe add an option to confirm here in the future.)
    cout << "\nUploading " << " to rSENSE.\n\n";
    cout << "The title you entered: " << title << endl;
    cout << "Letters you entered: " << letters << endl;
    cout << "Number you entered: " << num << endl;
    cout << "Timestamp: " << timestamp << endl << endl;

    // Right here I call a function to upload to rSENSE-dev.
    // I just pass it the title of the dataset and the number that the user entered.
    upload_to_rsense(title, num, letters, timestamp);

    return 0;
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CommonIO.cpp
 * @author Gav Wood
 * @date 2014
 */

#include "CommonIO.h"
#include <iostream>
#include <cstdlib>
#include <fstream>
#include "Exceptions.h"
#ifndef _WIN32
#include <termios.h>
#endif
using namespace std;
using namespace dev;

string dev::memDump(bytes const& _bytes, unsigned _width, bool _html)
{
	stringstream ret;
	if (_html)
		ret << "
";
	for (unsigned i = 0; i < _bytes.size(); i += _width)
	{
		ret << hex << setw(4) << setfill('0') << i << " ";
		for (unsigned j = i; j < i + _width; ++j)
			if (j < _bytes.size())
				if (_bytes[j] >= 32 && _bytes[j] < 127)
					if ((char)_bytes[j] == '<' && _html)
						ret << "<";
					else if ((char)_bytes[j] == '&' && _html)
						ret << "&";
					else
						ret << (char)_bytes[j];
				else
					ret << '?';
			else
				ret << ' ';
		ret << " ";
		for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
			ret << setfill('0') << setw(2) << hex << (unsigned)_bytes[j] << " ";
		ret << "\n";
	}
	if (_html)
		ret << "
";
	return ret.str();
}

// Don't forget to delete[] later.
bytesRef dev::contentsNew(std::string const& _file, bytesRef _dest)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return bytesRef();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return bytesRef();
	if (!_dest.empty() && _dest.size() != (unsigned)length)
		return bytesRef();
	is.seekg (0, is.beg);
	bytesRef ret = _dest.empty() ? bytesRef(new byte[length], length) : _dest;
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

bytes dev::contents(std::string const& _file)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return bytes();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return bytes();
	is.seekg (0, is.beg);
	bytes ret(length);
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

string dev::contentsString(std::string const& _file)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return string();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return string();
	is.seekg (0, is.beg);
	string ret;
	ret.resize(length);
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

void dev::writeFile(std::string const& _file, bytesConstRef _data)
{
	ofstream(_file, ios::trunc|ios::binary).write((char const*)_data.data(), _data.size());
}

std::string dev::getPassword(std::string const& _prompt)
{
#if WIN32
	cout << _prompt << flush;
	std::string ret;
	std::getline(cin, ret);
	return ret;
#else
	struct termios oflags;
	struct termios nflags;
	char password[128];

	// disable echo in the terminal
	tcgetattr(fileno(stdin), &oflags);
	nflags = oflags;
	nflags.c_lflag &= ~ECHO;
	nflags.c_lflag |= ECHONL;

	if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));

	printf("%s", _prompt.c_str());
	if (!fgets(password, sizeof(password), stdin))
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets"));
	password[strlen(password) - 1] = 0;

	// restore terminal
	if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));
	}

	return password;
#endif
}
<commit_msg>Bump password size to 256 chars<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CommonIO.cpp
 * @author Gav Wood
 * @date 2014
 */

#include "CommonIO.h"
#include <iostream>
#include <cstdlib>
#include <fstream>
#include "Exceptions.h"
#ifndef _WIN32
#include <termios.h>
#endif
using namespace std;
using namespace dev;

string dev::memDump(bytes const& _bytes, unsigned _width, bool _html)
{
	stringstream ret;
	if (_html)
		ret << "
";
	for (unsigned i = 0; i < _bytes.size(); i += _width)
	{
		ret << hex << setw(4) << setfill('0') << i << " ";
		for (unsigned j = i; j < i + _width; ++j)
			if (j < _bytes.size())
				if (_bytes[j] >= 32 && _bytes[j] < 127)
					if ((char)_bytes[j] == '<' && _html)
						ret << "<";
					else if ((char)_bytes[j] == '&' && _html)
						ret << "&";
					else
						ret << (char)_bytes[j];
				else
					ret << '?';
			else
				ret << ' ';
		ret << " ";
		for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
			ret << setfill('0') << setw(2) << hex << (unsigned)_bytes[j] << " ";
		ret << "\n";
	}
	if (_html)
		ret << "
";
	return ret.str();
}

// Don't forget to delete[] later.
bytesRef dev::contentsNew(std::string const& _file, bytesRef _dest)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return bytesRef();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return bytesRef();
	if (!_dest.empty() && _dest.size() != (unsigned)length)
		return bytesRef();
	is.seekg (0, is.beg);
	bytesRef ret = _dest.empty() ? bytesRef(new byte[length], length) : _dest;
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

bytes dev::contents(std::string const& _file)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return bytes();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return bytes();
	is.seekg (0, is.beg);
	bytes ret(length);
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

string dev::contentsString(std::string const& _file)
{
	std::ifstream is(_file, std::ifstream::binary);
	if (!is)
		return string();
	// get length of file:
	is.seekg (0, is.end);
	streamoff length = is.tellg();
	if (length == 0) // return early, MSVC does not like reading 0 bytes
		return string();
	is.seekg (0, is.beg);
	string ret;
	ret.resize(length);
	is.read((char*)ret.data(), length);
	is.close();
	return ret;
}

void dev::writeFile(std::string const& _file, bytesConstRef _data)
{
	ofstream(_file, ios::trunc|ios::binary).write((char const*)_data.data(), _data.size());
}

std::string dev::getPassword(std::string const& _prompt)
{
#if WIN32
	cout << _prompt << flush;
	std::string ret;
	std::getline(cin, ret);
	return ret;
#else
	struct termios oflags;
	struct termios nflags;
	char password[256];

	// disable echo in the terminal
	tcgetattr(fileno(stdin), &oflags);
	nflags = oflags;
	nflags.c_lflag &= ~ECHO;
	nflags.c_lflag |= ECHONL;

	if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));

	printf("%s", _prompt.c_str());
	if (!fgets(password, sizeof(password), stdin))
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets"));
	password[strlen(password) - 1] = 0;

	// restore terminal
	if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0)
		BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));

	return password;
#endif
}
<|endoftext|>


<commit_before><commit_msg>[booking] review fixes for booking filters<commit_after><|endoftext|>


<commit_before>// -*- mode: C++; c-file-style: "gnu" -*-
// kaddrbook.cpp
// Author: Stefan Taferner <taferner@kde.org>
// This code is under GPL

#include <config.h>

#include "kaddrbook.h"

#ifdef KDEPIM_NEW_DISTRLISTS
#include "distributionlist.h"
#else
#include <kabc/distributionlist.h>
#endif

#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdeversion.h>
#include <kabc/resource.h>
#include <kabc/stdaddressbook.h>
#include <kabc/vcardconverter.h>
#include <kresources/selectdialog.h>
#include <dcopref.h>
#include <dcopclient.h>

#include <qeventloop.h>
#include <qregexp.h>

#include <unistd.h>

//-----------------------------------------------------------------------------
void KAddrBookExternal::openEmail( const QString &email, const QString &addr, QWidget *) {
  //QString email = KMMessage::getEmailAddr(addr);
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
  KABC::Addressee::List addresseeList = addressBook->findByEmail(email);
  if ( kapp->dcopClient()->isApplicationRegistered( "kaddressbook" ) ){
    //make sure kaddressbook is loaded, otherwise showContactEditor
    //won't work as desired, see bug #87233
    DCOPRef call ( "kaddressbook", "kaddressbook" );
    call.send( "newInstance()" );
  }
  else
    kapp->startServiceByDesktopName( "kaddressbook" );

  DCOPRef call( "kaddressbook", "KAddressBookIface" );
  if( !addresseeList.isEmpty() ) {
    call.send( "showContactEditor(QString)", addresseeList.first().uid() );
  }
  else {
    call.send( "addEmail(QString)", addr );
  }
}

//-----------------------------------------------------------------------------
void KAddrBookExternal::addEmail( const QString& addr, QWidget *parent) {
  QString email;
  QString name;

  KABC::Addressee::parseEmailAddress( addr, name, email );

  KABC::AddressBook *ab = KABC::StdAddressBook::self( true );

  // force a reload of the address book file so that changes that were made
  // by other programs are loaded
  ab->asyncLoad();

  KABC::Addressee::List addressees = ab->findByEmail( email );

  if ( addressees.isEmpty() ) {
    KABC::Addressee a;
    a.setNameFromString( name );
    a.insertEmail( email, true );

    if ( !KAddrBookExternal::addAddressee( a ) ) {
      KMessageBox::error( parent, i18n("Cannot save to addressbook.") );
    } else {
      QString text = i18n("<qt>The email address %1 was added to your "
                          "addressbook; you can add more information to this "
                          "entry by opening the addressbook.</qt>").arg( addr );
      KMessageBox::information( parent, text, QString::null, "addedtokabc" );
    }
  } else {
    QString text = i18n("<qt>The email address %1 is already in your "
                        "addressbook.</qt>").arg( addr );
    KMessageBox::information( parent, text, QString::null,
                              "alreadyInAddressBook" );
  }
}

void KAddrBookExternal::openAddressBook(QWidget *) {
  kapp->startServiceByDesktopName( "kaddressbook" );
}

void KAddrBookExternal::addNewAddressee( QWidget* )
{
  kapp->startServiceByDesktopName("kaddressbook");
  DCOPRef call("kaddressbook", "KAddressBookIface");
  call.send("newContact()");
}

bool KAddrBookExternal::addVCard( const KABC::Addressee& addressee, QWidget *parent )
{
  KABC::AddressBook *ab = KABC::StdAddressBook::self( true );
  bool inserted = false;

  KABC::Addressee::List addressees =
      ab->findByEmail( addressee.preferredEmail() );

  if ( addressees.isEmpty() ) {
    if ( !KAddrBookExternal::addAddressee( addressee ) ) {
      KMessageBox::error( parent, i18n("Cannot save to addressbook.") );
      inserted = false;
    } else {
      QString text = i18n("The VCard was added to your addressbook; "
                          "you can add more information to this "
                          "entry by opening the addressbook.");
      KMessageBox::information( parent, text, QString::null, "addedtokabc" );
      inserted = true;
    }
  } else {
    QString text = i18n("The VCard's primary email address is already in "
                        "your addressbook; however, you may save the VCard "
                        "into a file and import it into the addressbook "
                        "manually.");
    KMessageBox::information( parent, text );
    inserted = true;
  }

  return inserted;
}

bool KAddrBookExternal::addAddressee( const KABC::Addressee& addr )
{
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );

#if KDE_IS_VERSION(3,4,89)
  // This ugly hack will be removed in 4.0
  while ( !addressBook->loadingHasFinished() ) {
    QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );

    // use sleep here to reduce cpu usage
    usleep( 100 );
  }
#endif

  // Select a resource
  QPtrList<KABC::Resource> kabcResources = addressBook->resources();

  QPtrList<KRES::Resource> kresResources;
  QPtrListIterator<KABC::Resource> resIt( kabcResources );
  KABC::Resource *kabcResource;
  while ( ( kabcResource = resIt.current() ) != 0 ) {
    ++resIt;
    if ( !kabcResource->readOnly() ) {
      KRES::Resource *res = static_cast<KRES::Resource*>( kabcResource );
      if ( res )
        kresResources.append( res );
    }
  }

  kabcResource = static_cast<KABC::Resource*>( KRES::SelectDialog::getResource( kresResources, 0 ) );

  KABC::Ticket *ticket = addressBook->requestSaveTicket( kabcResource );
  bool saved = false;
  if ( ticket ) {
    KABC::Addressee addressee( addr );
    addressee.setResource( kabcResource );
    addressBook->insertAddressee( addressee );
    saved = addressBook->save( ticket );
    if ( !saved )
      addressBook->releaseSaveTicket( ticket );
  }

  addressBook->emitAddressBookChanged();

  return saved;
}

QString KAddrBookExternal::expandDistributionList( const QString& listName )
{
  if ( listName.isEmpty() )
    return QString::null;

  const QString lowerListName = listName.lower();
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
#ifdef KDEPIM_NEW_DISTRLISTS
  KPIM::DistributionList distrList = KPIM::DistributionList::findByName( addressBook, lowerListName, false );
  if ( !distrList.isEmpty() ) {
    return distrList.emails( addressBook ).join( ", " );
  }
#else
  KABC::DistributionListManager manager( addressBook );
  manager.load();
  const QStringList listNames = manager.listNames();

  for ( QStringList::ConstIterator it = listNames.begin();
        it != listNames.end(); ++it) {
    if ( (*it).lower() == lowerListName ) {
      const QStringList addressList = manager.list( *it )->emails();
      return addressList.join( ", " );
    }
  }
#endif
  return QString::null;
}
<commit_msg>Add hack which hopefully stops the loose of contacts when adding them via KMail.<commit_after>// -*- mode: C++; c-file-style: "gnu" -*-
// kaddrbook.cpp
// Author: Stefan Taferner <taferner@kde.org>
// This code is under GPL

#include <config.h>

#include "kaddrbook.h"

#ifdef KDEPIM_NEW_DISTRLISTS
#include "distributionlist.h"
#else
#include <kabc/distributionlist.h>
#endif

#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdeversion.h>
#include <kabc/resource.h>
#include <kabc/stdaddressbook.h>
#include <kabc/vcardconverter.h>
#include <kresources/selectdialog.h>
#include <dcopref.h>
#include <dcopclient.h>

#include <qeventloop.h>
#include <qregexp.h>

#include <unistd.h>

//-----------------------------------------------------------------------------
void KAddrBookExternal::openEmail( const QString &email, const QString &addr, QWidget *) {
  //QString email = KMMessage::getEmailAddr(addr);
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
  KABC::Addressee::List addresseeList = addressBook->findByEmail(email);
  if ( kapp->dcopClient()->isApplicationRegistered( "kaddressbook" ) ){
    //make sure kaddressbook is loaded, otherwise showContactEditor
    //won't work as desired, see bug #87233
    DCOPRef call ( "kaddressbook", "kaddressbook" );
    call.send( "newInstance()" );
  }
  else
    kapp->startServiceByDesktopName( "kaddressbook" );

  DCOPRef call( "kaddressbook", "KAddressBookIface" );
  if( !addresseeList.isEmpty() ) {
    call.send( "showContactEditor(QString)", addresseeList.first().uid() );
  }
  else {
    call.send( "addEmail(QString)", addr );
  }
}

//-----------------------------------------------------------------------------
void KAddrBookExternal::addEmail( const QString& addr, QWidget *parent) {
  QString email;
  QString name;

  KABC::Addressee::parseEmailAddress( addr, name, email );

  KABC::AddressBook *ab = KABC::StdAddressBook::self( true );

  // force a reload of the address book file so that changes that were made
  // by other programs are loaded
  ab->asyncLoad();

  // if we have to reload the address book then we should also wait until
  // it's completely reloaded
#if KDE_IS_VERSION(3,4,89)
  // This ugly hack will be removed in 4.0
  while ( !ab->loadingHasFinished() ) {
    QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );

    // use sleep here to reduce cpu usage
    usleep( 100 );
  }
#endif

  KABC::Addressee::List addressees = ab->findByEmail( email );

  if ( addressees.isEmpty() ) {
    KABC::Addressee a;
    a.setNameFromString( name );
    a.insertEmail( email, true );

    if ( !KAddrBookExternal::addAddressee( a ) ) {
      KMessageBox::error( parent, i18n("Cannot save to addressbook.") );
    } else {
      QString text = i18n("<qt>The email address %1 was added to your "
                          "addressbook; you can add more information to this "
                          "entry by opening the addressbook.</qt>").arg( addr );
      KMessageBox::information( parent, text, QString::null, "addedtokabc" );
    }
  } else {
    QString text = i18n("<qt>The email address %1 is already in your "
                        "addressbook.</qt>").arg( addr );
    KMessageBox::information( parent, text, QString::null,
                              "alreadyInAddressBook" );
  }
}

void KAddrBookExternal::openAddressBook(QWidget *) {
  kapp->startServiceByDesktopName( "kaddressbook" );
}

void KAddrBookExternal::addNewAddressee( QWidget* )
{
  kapp->startServiceByDesktopName("kaddressbook");
  DCOPRef call("kaddressbook", "KAddressBookIface");
  call.send("newContact()");
}

bool KAddrBookExternal::addVCard( const KABC::Addressee& addressee, QWidget *parent )
{
  KABC::AddressBook *ab = KABC::StdAddressBook::self( true );
  bool inserted = false;

  KABC::Addressee::List addressees =
      ab->findByEmail( addressee.preferredEmail() );

  if ( addressees.isEmpty() ) {
    if ( !KAddrBookExternal::addAddressee( addressee ) ) {
      KMessageBox::error( parent, i18n("Cannot save to addressbook.") );
      inserted = false;
    } else {
      QString text = i18n("The VCard was added to your addressbook; "
                          "you can add more information to this "
                          "entry by opening the addressbook.");
      KMessageBox::information( parent, text, QString::null, "addedtokabc" );
      inserted = true;
    }
  } else {
    QString text = i18n("The VCard's primary email address is already in "
                        "your addressbook; however, you may save the VCard "
                        "into a file and import it into the addressbook "
                        "manually.");
    KMessageBox::information( parent, text );
    inserted = true;
  }

  return inserted;
}

bool KAddrBookExternal::addAddressee( const KABC::Addressee& addr )
{
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );

#if KDE_IS_VERSION(3,4,89)
  // This ugly hack will be removed in 4.0
  while ( !addressBook->loadingHasFinished() ) {
    QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );

    // use sleep here to reduce cpu usage
    usleep( 100 );
  }
#endif

  // Select a resource
  QPtrList<KABC::Resource> kabcResources = addressBook->resources();

  QPtrList<KRES::Resource> kresResources;
  QPtrListIterator<KABC::Resource> resIt( kabcResources );
  KABC::Resource *kabcResource;
  while ( ( kabcResource = resIt.current() ) != 0 ) {
    ++resIt;
    if ( !kabcResource->readOnly() ) {
      KRES::Resource *res = static_cast<KRES::Resource*>( kabcResource );
      if ( res )
        kresResources.append( res );
    }
  }

  kabcResource = static_cast<KABC::Resource*>( KRES::SelectDialog::getResource( kresResources, 0 ) );

  KABC::Ticket *ticket = addressBook->requestSaveTicket( kabcResource );
  bool saved = false;
  if ( ticket ) {
    KABC::Addressee addressee( addr );
    addressee.setResource( kabcResource );
    addressBook->insertAddressee( addressee );
    saved = addressBook->save( ticket );
    if ( !saved )
      addressBook->releaseSaveTicket( ticket );
  }

  addressBook->emitAddressBookChanged();

  return saved;
}

QString KAddrBookExternal::expandDistributionList( const QString& listName )
{
  if ( listName.isEmpty() )
    return QString::null;

  const QString lowerListName = listName.lower();
  KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
#ifdef KDEPIM_NEW_DISTRLISTS
  KPIM::DistributionList distrList = KPIM::DistributionList::findByName( addressBook, lowerListName, false );
  if ( !distrList.isEmpty() ) {
    return distrList.emails( addressBook ).join( ", " );
  }
#else
  KABC::DistributionListManager manager( addressBook );
  manager.load();
  const QStringList listNames = manager.listNames();

  for ( QStringList::ConstIterator it = listNames.begin();
        it != listNames.end(); ++it) {
    if ( (*it).lower() == lowerListName ) {
      const QStringList addressList = manager.list( *it )->emails();
      return addressList.join( ", " );
    }
  }
#endif
  return QString::null;
}
<|endoftext|>