<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/renderer_host/gtk_key_bindings_handler.h"

#include <gdk/gdkkeysyms.h>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/edit_command.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "testing/gtest/include/gtest/gtest.h"

class GtkKeyBindingsHandlerTest : public testing::Test {
 protected:
  struct EditCommand {
    const char* name;
    const char* value;
  };

  GtkKeyBindingsHandlerTest()
      : window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)),
        handler_(NULL) {
    FilePath gtkrc;
    PathService::Get(chrome::DIR_TEST_DATA, &gtkrc);
    gtkrc = gtkrc.AppendASCII("gtk_key_bindings_test_gtkrc");
    gtk_rc_parse(gtkrc.value().c_str());

    GtkWidget* fixed = gtk_fixed_new();
    handler_ = new GtkKeyBindingsHandler(fixed);
    gtk_container_add(GTK_CONTAINER(window_), fixed);
    gtk_widget_show(fixed);
    gtk_widget_show(window_);
  }
  ~GtkKeyBindingsHandlerTest() {
    gtk_widget_destroy(window_);
    delete handler_;
  }

  NativeWebKeyboardEvent NewNativeWebKeyboardEvent(guint keyval, guint state) {
    GdkKeymap* keymap =
        gdk_keymap_get_for_display(gtk_widget_get_display(window_));

    GdkKeymapKey *keys = NULL;
    gint n_keys = 0;
    if (gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) {
      GdkEventKey event;
      event.type = GDK_KEY_PRESS;
      event.window = NULL;
      event.send_event = 0;
      event.time = 0;
      event.state = state;
      event.keyval = keyval;
      event.length = 0;
      event.string = NULL;
      event.hardware_keycode = keys[0].keycode;
      event.group = keys[0].group;
      event.is_modifier = 0;
      g_free(keys);
      return NativeWebKeyboardEvent(&event);
    }
    return NativeWebKeyboardEvent();
  }

  void TestKeyBinding(const NativeWebKeyboardEvent& event,
                      const EditCommand expected_result[],
                      size_t size) {
    EditCommands result;
    ASSERT_TRUE(handler_->Match(event, &result));
    ASSERT_EQ(size, result.size());
    for (size_t i = 0; i < size; ++i) {
      ASSERT_STREQ(expected_result[i].name, result[i].name.c_str());
      ASSERT_STREQ(expected_result[i].value, result[i].value.c_str());
    }
  }

 protected:
  GtkWidget* window_;
  GtkKeyBindingsHandler* handler_;
};

TEST_F(GtkKeyBindingsHandlerTest, MoveCursor) {
  static const EditCommand kEditCommands[] = {
    // "move-cursor" (logical-positions, -2, 0)
    { "MoveBackward", "" },
    { "MoveBackward", "" },
    // "move-cursor" (logical-positions, 2, 0)
    { "MoveForward", "" },
    { "MoveForward", "" },
    // "move-cursor" (visual-positions, -1, 1)
    { "MoveLeftAndModifySelection", "" },
    // "move-cursor" (visual-positions, 1, 1)
    { "MoveRightAndModifySelection", "" },
    // "move-cursor" (words, -1, 0)
    { "MoveWordBackward", "" },
    // "move-cursor" (words, 1, 0)
    { "MoveWordForward", "" },
    // "move-cursor" (display-lines, -1, 0)
    { "MoveUp", "" },
    // "move-cursor" (display-lines, 1, 0)
    { "MoveDown", "" },
    // "move-cursor" (display-line-ends, -1, 0)
    { "MoveToBeginningOfLine", "" },
    // "move-cursor" (display-line-ends, 1, 0)
    { "MoveToEndOfLine", "" },
    // "move-cursor" (paragraph-ends, -1, 0)
    { "MoveToBeginningOfParagraph", "" },
    // "move-cursor" (paragraph-ends, 1, 0)
    { "MoveToEndOfParagraph", "" },
    // "move-cursor" (pages, -1, 0)
    { "MovePageUp", "" },
    // "move-cursor" (pages, 1, 0)
    { "MovePageDown", "" },
    // "move-cursor" (buffer-ends, -1, 0)
    { "MoveToBeginningOfDocument", "" },
    // "move-cursor" (buffer-ends, 1, 0)
    { "MoveToEndOfDocument", "" }
  };

  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_1, GDK_CONTROL_MASK),
                 kEditCommands, arraysize(kEditCommands));
}

TEST_F(GtkKeyBindingsHandlerTest, DeleteFromCursor) {
  static const EditCommand kEditCommands[] = {
    // "delete-from-cursor" (chars, -2)
    { "DeleteBackward", "" },
    { "DeleteBackward", "" },
    // "delete-from-cursor" (chars, 2)
    { "DeleteForward", "" },
    { "DeleteForward", "" },
    // "delete-from-cursor" (word-ends, -1)
    { "DeleteWordBackward", "" },
    // "delete-from-cursor" (word-ends, 1)
    { "DeleteWordForward", "" },
    // "delete-from-cursor" (words, -1)
    { "MoveWordBackward", "" },
    { "DeleteWordForward", "" },
    // "delete-from-cursor" (words, 1)
    { "MoveWordForward", "" },
    { "DeleteWordBackward", "" },
    // "delete-from-cursor" (display-lines, -1)
    { "MoveToBeginningOfLine", "" },
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (display-lines, 1)
    { "MoveToBeginningOfLine", "" },
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (display-line-ends, -1)
    { "DeleteToBeginningOfLine", "" },
    // "delete-from-cursor" (display-line-ends, 1)
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (paragraph-ends, -1)
    { "DeleteToBeginningOfParagraph", "" },
    // "delete-from-cursor" (paragraph-ends, 1)
    { "DeleteToEndOfParagraph", "" },
    // "delete-from-cursor" (paragraphs, -1)
    { "MoveToBeginningOfParagraph", "" },
    { "DeleteToEndOfParagraph", "" },
    // "delete-from-cursor" (paragraphs, 1)
    { "MoveToBeginningOfParagraph", "" },
    { "DeleteToEndOfParagraph", "" },
  };

  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_2, GDK_CONTROL_MASK),
                 kEditCommands, arraysize(kEditCommands));
}

TEST_F(GtkKeyBindingsHandlerTest, OtherActions) {
  static const EditCommand kBackspace[] = {
    { "DeleteBackward", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_3, GDK_CONTROL_MASK),
                 kBackspace, arraysize(kBackspace));

  static const EditCommand kCopyClipboard[] = {
    { "Copy", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_4, GDK_CONTROL_MASK),
                 kCopyClipboard, arraysize(kCopyClipboard));

  static const EditCommand kCutClipboard[] = {
    { "Cut", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_5, GDK_CONTROL_MASK),
                 kCutClipboard, arraysize(kCutClipboard));

  static const EditCommand kInsertAtCursor[] = {
    { "InsertText", "hello" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_6, GDK_CONTROL_MASK),
                 kInsertAtCursor, arraysize(kInsertAtCursor));

  static const EditCommand kPasteClipboard[] = {
    { "Paste", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_7, GDK_CONTROL_MASK),
                 kPasteClipboard, arraysize(kPasteClipboard));

  static const EditCommand kSelectAll[] = {
    { "Unselect", "" },
    { "SelectAll", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_8, GDK_CONTROL_MASK),
                 kSelectAll, arraysize(kSelectAll));

  static const EditCommand kSetAnchor[] = {
    { "SetMark", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_9, GDK_CONTROL_MASK),
                 kSetAnchor, arraysize(kSetAnchor));
}
<commit_msg>Mark the GtkKeyBindingsHandlerTest  tests as flaky since they don't work in a chroot.<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/renderer_host/gtk_key_bindings_handler.h"

#include <gdk/gdkkeysyms.h>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/edit_command.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "testing/gtest/include/gtest/gtest.h"

class GtkKeyBindingsHandlerTest : public testing::Test {
 protected:
  struct EditCommand {
    const char* name;
    const char* value;
  };

  GtkKeyBindingsHandlerTest()
      : window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)),
        handler_(NULL) {
    FilePath gtkrc;
    PathService::Get(chrome::DIR_TEST_DATA, &gtkrc);
    gtkrc = gtkrc.AppendASCII("gtk_key_bindings_test_gtkrc");
    gtk_rc_parse(gtkrc.value().c_str());

    GtkWidget* fixed = gtk_fixed_new();
    handler_ = new GtkKeyBindingsHandler(fixed);
    gtk_container_add(GTK_CONTAINER(window_), fixed);
    gtk_widget_show(fixed);
    gtk_widget_show(window_);
  }
  ~GtkKeyBindingsHandlerTest() {
    gtk_widget_destroy(window_);
    delete handler_;
  }

  NativeWebKeyboardEvent NewNativeWebKeyboardEvent(guint keyval, guint state) {
    GdkKeymap* keymap =
        gdk_keymap_get_for_display(gtk_widget_get_display(window_));

    GdkKeymapKey *keys = NULL;
    gint n_keys = 0;
    if (gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) {
      GdkEventKey event;
      event.type = GDK_KEY_PRESS;
      event.window = NULL;
      event.send_event = 0;
      event.time = 0;
      event.state = state;
      event.keyval = keyval;
      event.length = 0;
      event.string = NULL;
      event.hardware_keycode = keys[0].keycode;
      event.group = keys[0].group;
      event.is_modifier = 0;
      g_free(keys);
      return NativeWebKeyboardEvent(&event);
    }
    return NativeWebKeyboardEvent();
  }

  void TestKeyBinding(const NativeWebKeyboardEvent& event,
                      const EditCommand expected_result[],
                      size_t size) {
    EditCommands result;
    ASSERT_TRUE(handler_->Match(event, &result));
    ASSERT_EQ(size, result.size());
    for (size_t i = 0; i < size; ++i) {
      ASSERT_STREQ(expected_result[i].name, result[i].name.c_str());
      ASSERT_STREQ(expected_result[i].value, result[i].value.c_str());
    }
  }

 protected:
  GtkWidget* window_;
  GtkKeyBindingsHandler* handler_;
};

// Does not work in a chroot. See bug 60363.
TEST_F(GtkKeyBindingsHandlerTest, FLAKY_MoveCursor) {
  static const EditCommand kEditCommands[] = {
    // "move-cursor" (logical-positions, -2, 0)
    { "MoveBackward", "" },
    { "MoveBackward", "" },
    // "move-cursor" (logical-positions, 2, 0)
    { "MoveForward", "" },
    { "MoveForward", "" },
    // "move-cursor" (visual-positions, -1, 1)
    { "MoveLeftAndModifySelection", "" },
    // "move-cursor" (visual-positions, 1, 1)
    { "MoveRightAndModifySelection", "" },
    // "move-cursor" (words, -1, 0)
    { "MoveWordBackward", "" },
    // "move-cursor" (words, 1, 0)
    { "MoveWordForward", "" },
    // "move-cursor" (display-lines, -1, 0)
    { "MoveUp", "" },
    // "move-cursor" (display-lines, 1, 0)
    { "MoveDown", "" },
    // "move-cursor" (display-line-ends, -1, 0)
    { "MoveToBeginningOfLine", "" },
    // "move-cursor" (display-line-ends, 1, 0)
    { "MoveToEndOfLine", "" },
    // "move-cursor" (paragraph-ends, -1, 0)
    { "MoveToBeginningOfParagraph", "" },
    // "move-cursor" (paragraph-ends, 1, 0)
    { "MoveToEndOfParagraph", "" },
    // "move-cursor" (pages, -1, 0)
    { "MovePageUp", "" },
    // "move-cursor" (pages, 1, 0)
    { "MovePageDown", "" },
    // "move-cursor" (buffer-ends, -1, 0)
    { "MoveToBeginningOfDocument", "" },
    // "move-cursor" (buffer-ends, 1, 0)
    { "MoveToEndOfDocument", "" }
  };

  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_1, GDK_CONTROL_MASK),
                 kEditCommands, arraysize(kEditCommands));
}

// Does not work in a chroot. See bug 60363.
TEST_F(GtkKeyBindingsHandlerTest, FLAKY_DeleteFromCursor) {
  static const EditCommand kEditCommands[] = {
    // "delete-from-cursor" (chars, -2)
    { "DeleteBackward", "" },
    { "DeleteBackward", "" },
    // "delete-from-cursor" (chars, 2)
    { "DeleteForward", "" },
    { "DeleteForward", "" },
    // "delete-from-cursor" (word-ends, -1)
    { "DeleteWordBackward", "" },
    // "delete-from-cursor" (word-ends, 1)
    { "DeleteWordForward", "" },
    // "delete-from-cursor" (words, -1)
    { "MoveWordBackward", "" },
    { "DeleteWordForward", "" },
    // "delete-from-cursor" (words, 1)
    { "MoveWordForward", "" },
    { "DeleteWordBackward", "" },
    // "delete-from-cursor" (display-lines, -1)
    { "MoveToBeginningOfLine", "" },
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (display-lines, 1)
    { "MoveToBeginningOfLine", "" },
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (display-line-ends, -1)
    { "DeleteToBeginningOfLine", "" },
    // "delete-from-cursor" (display-line-ends, 1)
    { "DeleteToEndOfLine", "" },
    // "delete-from-cursor" (paragraph-ends, -1)
    { "DeleteToBeginningOfParagraph", "" },
    // "delete-from-cursor" (paragraph-ends, 1)
    { "DeleteToEndOfParagraph", "" },
    // "delete-from-cursor" (paragraphs, -1)
    { "MoveToBeginningOfParagraph", "" },
    { "DeleteToEndOfParagraph", "" },
    // "delete-from-cursor" (paragraphs, 1)
    { "MoveToBeginningOfParagraph", "" },
    { "DeleteToEndOfParagraph", "" },
  };

  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_2, GDK_CONTROL_MASK),
                 kEditCommands, arraysize(kEditCommands));
}

// Does not work in a chroot. See bug 60363.
TEST_F(GtkKeyBindingsHandlerTest, FLAKY_OtherActions) {
  static const EditCommand kBackspace[] = {
    { "DeleteBackward", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_3, GDK_CONTROL_MASK),
                 kBackspace, arraysize(kBackspace));

  static const EditCommand kCopyClipboard[] = {
    { "Copy", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_4, GDK_CONTROL_MASK),
                 kCopyClipboard, arraysize(kCopyClipboard));

  static const EditCommand kCutClipboard[] = {
    { "Cut", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_5, GDK_CONTROL_MASK),
                 kCutClipboard, arraysize(kCutClipboard));

  static const EditCommand kInsertAtCursor[] = {
    { "InsertText", "hello" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_6, GDK_CONTROL_MASK),
                 kInsertAtCursor, arraysize(kInsertAtCursor));

  static const EditCommand kPasteClipboard[] = {
    { "Paste", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_7, GDK_CONTROL_MASK),
                 kPasteClipboard, arraysize(kPasteClipboard));

  static const EditCommand kSelectAll[] = {
    { "Unselect", "" },
    { "SelectAll", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_8, GDK_CONTROL_MASK),
                 kSelectAll, arraysize(kSelectAll));

  static const EditCommand kSetAnchor[] = {
    { "SetMark", "" }
  };
  TestKeyBinding(NewNativeWebKeyboardEvent(GDK_9, GDK_CONTROL_MASK),
                 kSetAnchor, arraysize(kSetAnchor));
}
<|endoftext|>


<commit_before>#include <iostream>
#include "../include/PreAllocString.h"
int main() {
   CREATE(str25, 25);
    printf("Size: %u\n", static_cast<unsigned int>(str25.SizeOf()));
    const char *cstr = "fester string";
    printf("String: %s\n", str25);
    str25 += 'c';
    str25.AddWhiteSpace();
    printf("String: %s\n", str25);
    str25 += "Blabla";
    printf("String: %s\n", str25);
    printf("Length: %u\n", static_cast<unsigned int>(str25.GetLength()));
    str25 += cstr;
    printf("String: %s\n", str25);
    printf("Length: %u\n", static_cast<unsigned int>(str25.GetLength()));

    CREATE(str0, 0);
    printf("Size: %u\n", static_cast<unsigned int>(str0.SizeOf()));
    printf("String: %s\n", str0);
    str0 += 'c';
    str0.AddWhiteSpace();
    printf("String: %s\n", str0);
    str0 += "Blabla";
    printf("String: %s\n", str0);
    printf("Length: %u\n", static_cast<unsigned int>(str0.GetLength()));
    str0 += cstr;
    printf("String: %s\n", str0);
    printf("Length: %u\n", static_cast<unsigned int>(str0.GetLength()));
    CREATE(str1, 1);
    printf("Size: %u\n", static_cast<unsigned int>(str1.SizeOf()));
    printf("String: %s\n", str1);
    str1 += 'c';
    str1.AddWhiteSpace();
    printf("String: %s\n", str1);
    str1 += "Blabla";
    printf("String: %s\n", str1);
    printf("Length: %u\n", static_cast<unsigned int>(str1.GetLength()));
    str1 += cstr;
    printf("String: %s\n", str1);
    printf("Length: %u\n", static_cast<unsigned int>(str1.GetLength()));
    return 0;

/*
    CREATE(test_string_5,5);
    CREATE(test_string_20,20);
    CREATE(test_string_100,100);
    int counter=1;

    printf("-->Test %d. Overflow:\n",counter++);
    */
/* Test overflow *//*

    test_string_5 = "abcdefghijk";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_5,\
            test_string_5.GetLength(),\
            test_string_5.SizeOf());
    printf("-->Test %d. char operators:\n",counter++);
    */
/* Test operator = for char *//*

    test_string_20 = 'a';
    test_string_20.AddWhiteSpace();
    */
/* Test operator += for char *//*

    test_string_20 += 'b';
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",
           (const char*)test_string_20,
           test_string_20.GetLength(),
           test_string_20.SizeOf());
    printf("-->Test %d. String operators:\n",counter++);
    */
/* Test operator = for char array*//*

    test_string_100 = "abcdef";
    test_string_100.AddWhiteSpace();
    */
/* Test operator += for char array*//*

    test_string_100 += "ghijklo";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",
           (const char*)test_string_100,
           test_string_100.GetLength(),
           test_string_100.SizeOf());
    printf("-->Test %d. Array operator\n\t\tarray[%d]\t=\tValue: %c\n\t\tarray[%d]\t=\tValue: %c\n",
           counter++,
           1,
           test_string_100[1],
           101,
           test_string_100[101]);
    test_string_100[1];
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_100,\
            test_string_100.GetLength(),\
            test_string_100.SizeOf());
    printf("-->Test %d. indirekt test of AddFormat and Empty:\n",counter++);
    test_string_100="abcdefghijklmnopqrstuvwxyz";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_100,\
            test_string_100.GetLength(),\
            test_string_100.SizeOf());

    //CREATE(test_string20_2,20);
    */
/*printf("-->Test %d. Copy Class:\n",counter++);
     *test_string20_2="zyxw";
     * fails-->> test_string_20=test_string20_2;
     *//*

    printf("--> Test ENDE \n");
}<commit_msg>fix comment problems in main<commit_after>#include <iostream>
#include "../include/PreAllocString.h"
int main() {
   CREATE(str25, 25);
    printf("Size: %u\n", static_cast<unsigned int>(str25.SizeOf()));
    const char *cstr = "fester string";
    printf("String: %s\n", str25);
    str25 += 'c';
    str25.AddWhiteSpace();
    printf("String: %s\n", str25);
    str25 += "Blabla";
    printf("String: %s\n", str25);
    printf("Length: %u\n", static_cast<unsigned int>(str25.GetLength()));
    str25 += cstr;
    printf("String: %s\n", str25);
    printf("Length: %u\n", static_cast<unsigned int>(str25.GetLength()));

    CREATE(str0, 0);
    printf("Size: %u\n", static_cast<unsigned int>(str0.SizeOf()));
    printf("String: %s\n", str0);
    str0 += 'c';
    str0.AddWhiteSpace();
    printf("String: %s\n", str0);
    str0 += "Blabla";
    printf("String: %s\n", str0);
    printf("Length: %u\n", static_cast<unsigned int>(str0.GetLength()));
    str0 += cstr;
    printf("String: %s\n", str0);
    printf("Length: %u\n", static_cast<unsigned int>(str0.GetLength()));
    CREATE(str1, 1);
    printf("Size: %u\n", static_cast<unsigned int>(str1.SizeOf()));
    printf("String: %s\n", str1);
    str1 += 'c';
    str1.AddWhiteSpace();
    printf("String: %s\n", str1);
    str1 += "Blabla";
    printf("String: %s\n", str1);
    printf("Length: %u\n", static_cast<unsigned int>(str1.GetLength()));
    str1 += cstr;
    printf("String: %s\n", str1);
    printf("Length: %u\n", static_cast<unsigned int>(str1.GetLength()));
    return 0;

/*
    CREATE(test_string_5,5);
    CREATE(test_string_20,20);
    CREATE(test_string_100,100);
    int counter=1;

    printf("-->Test %d. Overflow:\n",counter++);
    */
/* Test overflow *//*

    test_string_5 = "abcdefghijk";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_5,\
            test_string_5.GetLength(),\
            test_string_5.SizeOf());
    printf("-->Test %d. char operators:\n",counter++);
    */
/* Test operator = for char *//*

    test_string_20 = 'a';
    test_string_20.AddWhiteSpace();
    */
/* Test operator += for char *//*

    test_string_20 += 'b';
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",
           (const char*)test_string_20,
           test_string_20.GetLength(),
           test_string_20.SizeOf());
    printf("-->Test %d. String operators:\n",counter++);
    */
/* Test operator = for char array*//*

    test_string_100 = "abcdef";
    test_string_100.AddWhiteSpace();
    */
/* Test operator += for char array*//*

    test_string_100 += "ghijklo";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",
           (const char*)test_string_100,
           test_string_100.GetLength(),
           test_string_100.SizeOf());
    printf("-->Test %d. Array operator\n\t\tarray[%d]\t=\tValue: %c\n\t\tarray[%d]\t=\tValue: %c\n",
           counter++,
           1,
           test_string_100[1],
           101,
           test_string_100[101]);
    test_string_100[1];
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_100,\
            test_string_100.GetLength(),\
            test_string_100.SizeOf());
    printf("-->Test %d. indirekt test of AddFormat and Empty:\n",counter++);
    test_string_100="abcdefghijklmnopqrstuvwxyz";
    printf("\t\tInhalt: %s\t Länge: %d\t Maximum: %d\n",\
            (const char*)test_string_100,\
            test_string_100.GetLength(),\
            test_string_100.SizeOf());

    //CREATE(test_string20_2,20);
    */
/*printf("-->Test %d. Copy Class:\n",counter++);
     *test_string20_2="zyxw";
     * fails-->> test_string_20=test_string20_2;
     */

    printf("--> Test ENDE \n");
}
<|endoftext|>


<commit_before>int source();
void sink(...) {};

void arithAssignments(int source1, int clean1) {
  sink(clean1); // clean
  clean1 += source1;
  clean1 += 1;
  sink(clean1); // tainted

  clean1 = source1 = 1;
  sink(clean1); // clean
  source1 = clean1 = source();
  source1++;
  ++source1;
  source1 += 1;
  sink(source1); // tainted
  sink(++source1); // tainted
}

// --- globals ---

int increment(int x) {return x + 1;}
int zero(int x) {return 0;}

int global1 = 0;
int global2 = source();
int global3 = global2 + 1;
int global4 = increment(source());
int global5 = zero(source());
int global6, global7, global8, global9, global10;

void do_source()
{
	global6 = 0;
	global7 = source();
	global8 = global7 + 1;
	global9 = increment(source());
	global10 = zero(source());

	sink(global6);
	sink(global7); // tainted
	sink(global8); // tainted
	sink(global9); // tainted
	sink(global10);
}

void do_sink()
{
	sink(global1);
	sink(global2); // tainted [NOT DETECTED]
	sink(global3); // tainted [NOT DETECTED]
	sink(global4); // tainted [NOT DETECTED]
	sink(global5);
	sink(global6);
	sink(global7); // tainted [NOT DETECTED]
	sink(global8); // tainted [NOT DETECTED]
	sink(global9); // tainted [NOT DETECTED]
	sink(global10);
}

void global_test()
{
	do_source();
	do_sink();
}

// --- class fields ---

class MyClass {
public:
	MyClass() : a(0), b(source()) {
		c = source();
		d = 0;
	}

	void myMethod() {
		d = source();
	}

	int a, b, c, d;
};

void class_field_test() {
	MyClass mc1, mc2;

	mc1.myMethod();

	sink(mc1.a);
	sink(mc1.b); // tainted [NOT DETECTED with IR]
	sink(mc1.c); // tainted [NOT DETECTED with IR]
	sink(mc1.d); // tainted [NOT DETECTED with IR]
	sink(mc2.a);
	sink(mc2.b); // tainted [NOT DETECTED with IR]
	sink(mc2.c); // tainted [NOT DETECTED with IR]
	sink(mc2.d);
}

// --- arrays ---

void array_test(int i) {
	int arr1[10] = {0};
	int arr2[10] = {0};
	int arr3[10] = {0};

	arr1[5] = source();
	arr2[i] = source();
	arr3[5] = 0;

	sink(arr1[5]); // tainted
	sink(arr1[i]); // tainted [NOT DETECTED]
	sink(arr2[5]); // tainted [NOT DETECTED]
	sink(arr2[i]); // tainted [NOT DETECTED]
	sink(arr3[5]);
	sink(arr3[i]);
}

// --- pointers ---

void pointer_test() {
	int t1 = source();
	int t2 = 1;
	int t3 = 1;
	int *p1 = &t1;
	int *p2 = &t2;
	int *p3 = &t3;

	*p2 = source();

	sink(*p1); // tainted
	sink(*p2); // tainted [NOT DETECTED]
	sink(*p3);

	p3 = &t1;
	sink(*p3); // tainted

	*p3 = 0;
	sink(*p3); // [FALSE POSITIVE]
}

// --- return values ---

int select(int i, int a, int b) {
	if (i == 1) {
		return a;
	} else {
		return b;
	}
}

void fn_test(int i) {
	sink(select(i, 1, source())); // tainted
}

// --- strings ---

char *strcpy(char *destination, const char *source);
char *strcat(char *destination, const char *source);

namespace strings
{
	char *source(); // char* source

	void strings_test1() {
		char *tainted = source();
		char buffer[1024] = {0};

		sink(source()); // tainted
		sink(tainted); // tainted

		strcpy(buffer, "Hello, ");
		sink(buffer);
		strcat(buffer, tainted);
		sink(buffer); // tainted
	}
}

// --- pass by reference ---

namespace refs {
	void callee(int *p) {
		sink(*p); // tainted
	}

	void caller() {
		int x = source();
		callee(&x);
	}
}

void *memcpy(void *dest, void *src, int len);

void test_memcpy(int *source) {
	int x;
	memcpy(&x, source, sizeof(int));
	sink(x);
}

// --- std::swap ---

namespace std {
	template<class T> constexpr void swap(T& a, T& b);
}

void test_swap() {
	int x, y;

	x = source();
	y = 0;

	sink(x); // tainted
	sink(y); // clean

	std::swap(x, y);

	sink(x); // clean [FALSE POSITIVE]
	sink(y); // tainted
}

// --- lambdas ---

void test_lambdas()
{
	int t = source();
	int u = 0;
	int v = 0;
	int w = 0;

	auto a = [t, u]() -> int {
		sink(t); // tainted
		sink(u); // clean
		return t;
	};
	sink(a()); // tainted

	auto b = [&] {
		sink(t); // tainted
		sink(u); // clean
		v = source(); // (v is reference captured)
	};
	b();
	sink(v); // tainted [NOT DETECTED]

	auto c = [=] {
		sink(t); // tainted
		sink(u); // clean
	};
	c();

	auto d = [](int a, int b) {
		sink(a); // tainted
		sink(b); // clean
	};
	d(t, u);

	auto e = [](int &a, int &b, int &c) {
		sink(a); // tainted
		sink(b); // clean
		c = source();
	};
	e(t, u, w);
	sink(w); // tainted
}

// --- taint through return value ---

int id(int x)
{
	return x;
}

void test_return()
{
	int x, y, z, t;

	t = source();
	x = 0;
	y = 0;
	z = 0;

	sink(t); // tainted
	sink(x);
	sink(y);
	sink(z);

	x = id(t);
	y = id(id(t));
	z = id(z);

	sink(t); // tainted
	sink(x); // tainted
	sink(y); // tainted
	sink(z);
}

// --- taint through parameters ---

void myAssign1(int &a, int &b)
{
	a = b;
}

void myAssign2(int &a, int b)
{
	a = b;
}

void myAssign3(int *a, int b)
{
	*a = b;
}

void myAssign4(int *a, int b)
{
	int c;

	c = b + 1;
	*a = c;
}

void myNotAssign(int &a, int &b)
{
	a = a + 1;
	b = b + 1;
}

void test_outparams()
{
	int t, a, b, c, d, e;

	t = source();
	a = 0;
	b = 0;
	c = 0;
	d = 0;
	e = 0;

	sink(t); // tainted
	sink(a);
	sink(b);
	sink(c);
	sink(d);
	sink(e);

	myAssign1(a, t);
	myAssign2(b, t);
	myAssign3(&c, t);
	myAssign4(&d, t);
	myNotAssign(e, t);

	sink(t); // tainted
	sink(a); // tainted
	sink(b); // tainted
	sink(c); // tainted [NOT DETECTED]
	sink(d); // tainted [NOT DETECTED]
	sink(e);
}

// --- strdup ---

typedef unsigned long size_t;
char *strdup(const char *s1);
char *strndup(const char *s1, size_t n);
wchar_t* wcsdup(const wchar_t* s1);

void test_strdup(char *source)
{
	char *a, *b, *c;

	a = strdup(source);
	b = strdup("hello, world");
	c = strndup(source, 100);
	sink(a); // tainted
	sink(b);
	sink(c); // tainted
}

void test_strndup(int source)
{
	char *a;

	a = strndup("hello, world", source);
	sink(a); // tainted
}

void test_wcsdup(wchar_t *source)
{
	wchar_t *a, *b;

	a = wcsdup(source);
	b = wcsdup(L"hello, world");
	sink(a); // tainted
	sink(b);
}

// --- qualifiers ---

class MyClass2 {
public:
	MyClass2(int value);
	void setMember(int value);
	int getMember();

	int member;
};

class MyClass3 {
public:
	MyClass3(const char *string);
	void setString(const char *string);
	const char *getString();

	const char *buffer;
};

void test_qualifiers()
{
	MyClass2 a(0), b(0), *c;
	MyClass3 d("");

	sink(a);
	sink(a.getMember());
	a.setMember(source());
	sink(a); // tainted
	sink(a.getMember()); // tainted

	sink(b);
	sink(b.getMember());
	b.member = source();
	sink(b); // tainted
	sink(b.member); // tainted
	sink(b.getMember());

	c = new MyClass2(0);

	sink(c);
	sink(c->getMember());
	c->setMember(source());
	sink(c); // tainted (deref)
	sink(c->getMember()); // tainted

	delete c;

	sink(d);
	sink(d.getString());
	d.setString(strings::source());
	sink(d); // tainted
	sink(d.getString()); // tainted
}

// --- non-standard swap ---

void swop(int &a, int &b)
{
	int c = a;
	a = b;
	b = c;
}

void test_swop() {
	int x, y;

	x = source();
	y = 0;

	sink(x); // tainted
	sink(y); // clean

	swop(x, y);

	sink(x); // clean [FALSE POSITIVE]
	sink(y); // tainted
}

// --- getdelim ---

struct FILE;

int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);

void test_getdelim(FILE* source1) {
	char* line = nullptr;
	size_t n;
	getdelim(&line, &n, '\n', source1);

	sink(line);
}

namespace std
{
	template <class T>
	T &&move(T &t) noexcept; // simplified signature
}

namespace IntWrapper
{
	struct Class
	{
		int data;

		Class() = default;

		Class(const Class &that) : data(that.data) {}

		Class &operator=(const Class &that)
		{
			auto tmp = that;
			swap(tmp);
			return *this;
		}

		Class& operator=(Class&& that) {
			swap(that);
			return *this;
		}

		void swap(Class &that) noexcept
		{
			using std::swap;
			swap(data, that.data);
		}
	};

	// For ADL
	void swap(Class &x, Class &y) {
		x.swap(y);
	}
} // namespace ImplementationDetails

// using std::swap;

void test_copy_assignment_operator() {
	IntWrapper::Class x;
	IntWrapper::Class y;
	x.data = source();

	sink(x.data); // tainted
	sink(y.data); // clean

	y = x;

	sink(y.data); // tainted [FALSE NEGATIVE in IR]
	sink(x.data); // tainted

	IntWrapper::Class z1, z2;
	z1.data = source();
	sink(z1.data); // tainted

	swap(z1, z2);

	sink(z2.data); // tainted
	sink(z1.data); // clean [FALSE POSITIVE]
}

void test_move_assignment_operator()
{
	IntWrapper::Class x;
	IntWrapper::Class y;
	x.data = source();

	sink(x.data); // tainted
	sink(y.data); // clean

	y = std::move(x);

	sink(y.data); // tainted [FALSE NEGATIVE in IR]
	sink(x.data); // tainted
}<commit_msg>Update cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp<commit_after>int source();
void sink(...) {};

void arithAssignments(int source1, int clean1) {
  sink(clean1); // clean
  clean1 += source1;
  clean1 += 1;
  sink(clean1); // tainted

  clean1 = source1 = 1;
  sink(clean1); // clean
  source1 = clean1 = source();
  source1++;
  ++source1;
  source1 += 1;
  sink(source1); // tainted
  sink(++source1); // tainted
}

// --- globals ---

int increment(int x) {return x + 1;}
int zero(int x) {return 0;}

int global1 = 0;
int global2 = source();
int global3 = global2 + 1;
int global4 = increment(source());
int global5 = zero(source());
int global6, global7, global8, global9, global10;

void do_source()
{
	global6 = 0;
	global7 = source();
	global8 = global7 + 1;
	global9 = increment(source());
	global10 = zero(source());

	sink(global6);
	sink(global7); // tainted
	sink(global8); // tainted
	sink(global9); // tainted
	sink(global10);
}

void do_sink()
{
	sink(global1);
	sink(global2); // tainted [NOT DETECTED]
	sink(global3); // tainted [NOT DETECTED]
	sink(global4); // tainted [NOT DETECTED]
	sink(global5);
	sink(global6);
	sink(global7); // tainted [NOT DETECTED]
	sink(global8); // tainted [NOT DETECTED]
	sink(global9); // tainted [NOT DETECTED]
	sink(global10);
}

void global_test()
{
	do_source();
	do_sink();
}

// --- class fields ---

class MyClass {
public:
	MyClass() : a(0), b(source()) {
		c = source();
		d = 0;
	}

	void myMethod() {
		d = source();
	}

	int a, b, c, d;
};

void class_field_test() {
	MyClass mc1, mc2;

	mc1.myMethod();

	sink(mc1.a);
	sink(mc1.b); // tainted [NOT DETECTED with IR]
	sink(mc1.c); // tainted [NOT DETECTED with IR]
	sink(mc1.d); // tainted [NOT DETECTED with IR]
	sink(mc2.a);
	sink(mc2.b); // tainted [NOT DETECTED with IR]
	sink(mc2.c); // tainted [NOT DETECTED with IR]
	sink(mc2.d);
}

// --- arrays ---

void array_test(int i) {
	int arr1[10] = {0};
	int arr2[10] = {0};
	int arr3[10] = {0};

	arr1[5] = source();
	arr2[i] = source();
	arr3[5] = 0;

	sink(arr1[5]); // tainted
	sink(arr1[i]); // tainted [NOT DETECTED]
	sink(arr2[5]); // tainted [NOT DETECTED]
	sink(arr2[i]); // tainted [NOT DETECTED]
	sink(arr3[5]);
	sink(arr3[i]);
}

// --- pointers ---

void pointer_test() {
	int t1 = source();
	int t2 = 1;
	int t3 = 1;
	int *p1 = &t1;
	int *p2 = &t2;
	int *p3 = &t3;

	*p2 = source();

	sink(*p1); // tainted
	sink(*p2); // tainted [NOT DETECTED]
	sink(*p3);

	p3 = &t1;
	sink(*p3); // tainted

	*p3 = 0;
	sink(*p3); // [FALSE POSITIVE]
}

// --- return values ---

int select(int i, int a, int b) {
	if (i == 1) {
		return a;
	} else {
		return b;
	}
}

void fn_test(int i) {
	sink(select(i, 1, source())); // tainted
}

// --- strings ---

char *strcpy(char *destination, const char *source);
char *strcat(char *destination, const char *source);

namespace strings
{
	char *source(); // char* source

	void strings_test1() {
		char *tainted = source();
		char buffer[1024] = {0};

		sink(source()); // tainted
		sink(tainted); // tainted

		strcpy(buffer, "Hello, ");
		sink(buffer);
		strcat(buffer, tainted);
		sink(buffer); // tainted
	}
}

// --- pass by reference ---

namespace refs {
	void callee(int *p) {
		sink(*p); // tainted
	}

	void caller() {
		int x = source();
		callee(&x);
	}
}

void *memcpy(void *dest, void *src, int len);

void test_memcpy(int *source) {
	int x;
	memcpy(&x, source, sizeof(int));
	sink(x);
}

// --- std::swap ---

namespace std {
	template<class T> constexpr void swap(T& a, T& b);
}

void test_swap() {
	int x, y;

	x = source();
	y = 0;

	sink(x); // tainted
	sink(y); // clean

	std::swap(x, y);

	sink(x); // clean [FALSE POSITIVE]
	sink(y); // tainted
}

// --- lambdas ---

void test_lambdas()
{
	int t = source();
	int u = 0;
	int v = 0;
	int w = 0;

	auto a = [t, u]() -> int {
		sink(t); // tainted
		sink(u); // clean
		return t;
	};
	sink(a()); // tainted

	auto b = [&] {
		sink(t); // tainted
		sink(u); // clean
		v = source(); // (v is reference captured)
	};
	b();
	sink(v); // tainted [NOT DETECTED]

	auto c = [=] {
		sink(t); // tainted
		sink(u); // clean
	};
	c();

	auto d = [](int a, int b) {
		sink(a); // tainted
		sink(b); // clean
	};
	d(t, u);

	auto e = [](int &a, int &b, int &c) {
		sink(a); // tainted
		sink(b); // clean
		c = source();
	};
	e(t, u, w);
	sink(w); // tainted
}

// --- taint through return value ---

int id(int x)
{
	return x;
}

void test_return()
{
	int x, y, z, t;

	t = source();
	x = 0;
	y = 0;
	z = 0;

	sink(t); // tainted
	sink(x);
	sink(y);
	sink(z);

	x = id(t);
	y = id(id(t));
	z = id(z);

	sink(t); // tainted
	sink(x); // tainted
	sink(y); // tainted
	sink(z);
}

// --- taint through parameters ---

void myAssign1(int &a, int &b)
{
	a = b;
}

void myAssign2(int &a, int b)
{
	a = b;
}

void myAssign3(int *a, int b)
{
	*a = b;
}

void myAssign4(int *a, int b)
{
	int c;

	c = b + 1;
	*a = c;
}

void myNotAssign(int &a, int &b)
{
	a = a + 1;
	b = b + 1;
}

void test_outparams()
{
	int t, a, b, c, d, e;

	t = source();
	a = 0;
	b = 0;
	c = 0;
	d = 0;
	e = 0;

	sink(t); // tainted
	sink(a);
	sink(b);
	sink(c);
	sink(d);
	sink(e);

	myAssign1(a, t);
	myAssign2(b, t);
	myAssign3(&c, t);
	myAssign4(&d, t);
	myNotAssign(e, t);

	sink(t); // tainted
	sink(a); // tainted
	sink(b); // tainted
	sink(c); // tainted [NOT DETECTED]
	sink(d); // tainted [NOT DETECTED]
	sink(e);
}

// --- strdup ---

typedef unsigned long size_t;
char *strdup(const char *s1);
char *strndup(const char *s1, size_t n);
wchar_t* wcsdup(const wchar_t* s1);

void test_strdup(char *source)
{
	char *a, *b, *c;

	a = strdup(source);
	b = strdup("hello, world");
	c = strndup(source, 100);
	sink(a); // tainted
	sink(b);
	sink(c); // tainted
}

void test_strndup(int source)
{
	char *a;

	a = strndup("hello, world", source);
	sink(a); // tainted
}

void test_wcsdup(wchar_t *source)
{
	wchar_t *a, *b;

	a = wcsdup(source);
	b = wcsdup(L"hello, world");
	sink(a); // tainted
	sink(b);
}

// --- qualifiers ---

class MyClass2 {
public:
	MyClass2(int value);
	void setMember(int value);
	int getMember();

	int member;
};

class MyClass3 {
public:
	MyClass3(const char *string);
	void setString(const char *string);
	const char *getString();

	const char *buffer;
};

void test_qualifiers()
{
	MyClass2 a(0), b(0), *c;
	MyClass3 d("");

	sink(a);
	sink(a.getMember());
	a.setMember(source());
	sink(a); // tainted
	sink(a.getMember()); // tainted

	sink(b);
	sink(b.getMember());
	b.member = source();
	sink(b); // tainted
	sink(b.member); // tainted
	sink(b.getMember());

	c = new MyClass2(0);

	sink(c);
	sink(c->getMember());
	c->setMember(source());
	sink(c); // tainted (deref)
	sink(c->getMember()); // tainted

	delete c;

	sink(d);
	sink(d.getString());
	d.setString(strings::source());
	sink(d); // tainted
	sink(d.getString()); // tainted
}

// --- non-standard swap ---

void swop(int &a, int &b)
{
	int c = a;
	a = b;
	b = c;
}

void test_swop() {
	int x, y;

	x = source();
	y = 0;

	sink(x); // tainted
	sink(y); // clean

	swop(x, y);

	sink(x); // clean [FALSE POSITIVE]
	sink(y); // tainted
}

// --- getdelim ---

struct FILE;

int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);

void test_getdelim(FILE* source1) {
	char* line = nullptr;
	size_t n;
	getdelim(&line, &n, '\n', source1);

	sink(line);
}

namespace std
{
	template <class T>
	T &&move(T &t) noexcept; // simplified signature
}

namespace IntWrapper
{
	struct Class
	{
		int data;

		Class() = default;

		Class(const Class &that) : data(that.data) {}

		Class &operator=(const Class &that)
		{
			auto tmp = that;
			swap(tmp);
			return *this;
		}

		Class& operator=(Class&& that) {
			swap(that);
			return *this;
		}

		void swap(Class &that) noexcept
		{
			using std::swap;
			swap(data, that.data);
		}
	};

	// For ADL
	void swap(Class &x, Class &y) {
		x.swap(y);
	}
} // namespace IntWrapper

// using std::swap;

void test_copy_assignment_operator() {
	IntWrapper::Class x;
	IntWrapper::Class y;
	x.data = source();

	sink(x.data); // tainted
	sink(y.data); // clean

	y = x;

	sink(y.data); // tainted [FALSE NEGATIVE in IR]
	sink(x.data); // tainted

	IntWrapper::Class z1, z2;
	z1.data = source();
	sink(z1.data); // tainted

	swap(z1, z2);

	sink(z2.data); // tainted
	sink(z1.data); // clean [FALSE POSITIVE]
}

void test_move_assignment_operator()
{
	IntWrapper::Class x;
	IntWrapper::Class y;
	x.data = source();

	sink(x.data); // tainted
	sink(y.data); // clean

	y = std::move(x);

	sink(y.data); // tainted [FALSE NEGATIVE in IR]
	sink(x.data); // tainted
}
<|endoftext|>


<commit_before>#ifndef EXPORTELEMENTVISITOR_HPP_DEFINED
#define EXPORTELEMENTVISITOR_HPP_DEFINED

#include "Callbacks.hpp"
#include "GeoCoordinate.hpp"
#include "entities/Element.hpp"
#include "entities/Node.hpp"
#include "entities/Area.hpp"
#include "entities/Way.hpp"
#include "entities/Relation.hpp"
#include "heightmap/ElevationProvider.hpp"
#include "mapcss/StyleProvider.hpp"

#include <string>
#include <vector>

/// Exports elements to external code using element callback.
struct ExportElementVisitor : public utymap::entities::ElementVisitor
{
    using Tags = std::vector<utymap::formats::Tag>;
    using Coordinates = std::vector<utymap::GeoCoordinate>;

    ExportElementVisitor(const utymap::QuadKey& quadKey,
                         utymap::index::StringTable& stringTable,
                         const utymap::mapcss::StyleProvider& styleProvider,
                         const utymap::heightmap::ElevationProvider& eleProvider,
                         OnElementLoaded* elementCallback) :
        quadKey_(quadKey), stringTable_(stringTable), styleProvider_(styleProvider),
        eleProvider_(eleProvider), elementCallback_(elementCallback)
    {
    }

    void visitNode(const utymap::entities::Node& node) override
    {
        visitElement(node, Coordinates{ node.coordinate });
    }

    void visitWay(const utymap::entities::Way& way) override
    {
        visitElement(way, way.coordinates);
    }

    void visitArea(const utymap::entities::Area& area) override
    {
        visitElement(area, area.coordinates);
    }

    void visitRelation(const utymap::entities::Relation& relation) override
    {
        // TODO not supported yet.
    }
private:

    void visitElement(const utymap::entities::Element& element, const Coordinates& coordinates)
    {
        // convert tags
        std::vector<const char*> ctags;
        tagStrings_.reserve(element.tags.size() * 2);
        ctags.reserve(element.tags.size() * 2);
        for (std::size_t i = 0; i < element.tags.size(); ++i) {
            const utymap::entities::Tag& tag = element.tags[i];
            tagStrings_.push_back(stringTable_.getString(tag.key));
            tagStrings_.push_back(stringTable_.getString(tag.value));
            ctags.push_back(tagStrings_[tagStrings_.size() - 2].c_str());
            ctags.push_back(tagStrings_[tagStrings_.size() - 1].c_str());
        }
        // convert geometry
        std::vector<double> vertices;
        vertices.reserve(coordinates.size() * 3);
        for (std::size_t i = 0; i < coordinates.size(); ++i) {
            const utymap::GeoCoordinate coordinate = coordinates[i];
            vertices.push_back(coordinate.longitude);
            vertices.push_back(coordinate.latitude);
            vertices.push_back(eleProvider_.getElevation(quadKey_, coordinate));
        }
        // convert style
        utymap::mapcss::Style style = styleProvider_.forElement(element, levelOfDetail_);
        std::vector<const char*> cstyles;
        auto declarations = style.declarations();
        styleStrings_.reserve(declarations.size() * 2);
        cstyles.reserve(declarations.size());
        for (const auto& declaration : declarations) {
            styleStrings_.push_back(stringTable_.getString(declaration->key()));
            styleStrings_.push_back(declaration->value());
            cstyles.push_back(styleStrings_[styleStrings_.size() - 2].c_str());
            cstyles.push_back(styleStrings_[styleStrings_.size() - 1].c_str());
        }

        elementCallback_(element.id,
            ctags.data(), static_cast<int>(ctags.size()),
            vertices.data(), static_cast<int>(vertices.size()),
            cstyles.data(), static_cast<int>(cstyles.size()));

        // NOTE clear vectors after raw array data is consumed by external code
        tagStrings_.clear();
        styleStrings_.clear();
    }

    const utymap::QuadKey& quadKey_;
    utymap::index::StringTable& stringTable_;
    const utymap::mapcss::StyleProvider& styleProvider_;
    const utymap::heightmap::ElevationProvider& eleProvider_;
    int levelOfDetail_;
    OnElementLoaded* elementCallback_;
    std::vector<std::string> tagStrings_;   // holds temporary tag strings
    std::vector<std::string> styleStrings_; // holds temporary style strings
};

#endif // EXPORTELEMENTVISITOR_HPP_DEFINED
<commit_msg>core: fix issue in element exporting<commit_after>#ifndef EXPORTELEMENTVISITOR_HPP_DEFINED
#define EXPORTELEMENTVISITOR_HPP_DEFINED

#include "Callbacks.hpp"
#include "GeoCoordinate.hpp"
#include "entities/Element.hpp"
#include "entities/Node.hpp"
#include "entities/Area.hpp"
#include "entities/Way.hpp"
#include "entities/Relation.hpp"
#include "heightmap/ElevationProvider.hpp"
#include "mapcss/StyleProvider.hpp"

#include <string>
#include <vector>

/// Exports elements to external code using element callback.
struct ExportElementVisitor : public utymap::entities::ElementVisitor
{
    using Tags = std::vector<utymap::formats::Tag>;
    using Coordinates = std::vector<utymap::GeoCoordinate>;

    ExportElementVisitor(const utymap::QuadKey& quadKey,
                         utymap::index::StringTable& stringTable,
                         const utymap::mapcss::StyleProvider& styleProvider,
                         const utymap::heightmap::ElevationProvider& eleProvider,
                         OnElementLoaded* elementCallback) :
        quadKey_(quadKey), stringTable_(stringTable), styleProvider_(styleProvider),
        eleProvider_(eleProvider), elementCallback_(elementCallback)
    {
    }

    void visitNode(const utymap::entities::Node& node) override
    {
        visitElement(node, Coordinates{ node.coordinate });
    }

    void visitWay(const utymap::entities::Way& way) override
    {
        visitElement(way, way.coordinates);
    }

    void visitArea(const utymap::entities::Area& area) override
    {
        visitElement(area, area.coordinates);
    }

    void visitRelation(const utymap::entities::Relation& relation) override
    {
        // TODO not supported yet.
    }
private:

    void visitElement(const utymap::entities::Element& element, const Coordinates& coordinates)
    {
        // convert tags
        std::vector<const char*> ctags;
        tagStrings_.reserve(element.tags.size() * 2);
        ctags.reserve(element.tags.size() * 2);
        for (std::size_t i = 0; i < element.tags.size(); ++i) {
            const utymap::entities::Tag& tag = element.tags[i];
            tagStrings_.push_back(stringTable_.getString(tag.key));
            tagStrings_.push_back(stringTable_.getString(tag.value));
            ctags.push_back(tagStrings_[tagStrings_.size() - 2].c_str());
            ctags.push_back(tagStrings_[tagStrings_.size() - 1].c_str());
        }
        // convert geometry
        std::vector<double> vertices;
        vertices.reserve(coordinates.size() * 3);
        for (std::size_t i = 0; i < coordinates.size(); ++i) {
            const utymap::GeoCoordinate coordinate = coordinates[i];
            vertices.push_back(coordinate.longitude);
            vertices.push_back(coordinate.latitude);
            vertices.push_back(eleProvider_.getElevation(quadKey_, coordinate));
        }
        // convert style
        utymap::mapcss::Style style = styleProvider_.forElement(element, quadKey_.levelOfDetail);
        std::vector<const char*> cstyles;
        auto declarations = style.declarations();
        styleStrings_.reserve(declarations.size() * 2);
        cstyles.reserve(declarations.size());
        for (const auto& declaration : declarations) {
            styleStrings_.push_back(stringTable_.getString(declaration->key()));
            styleStrings_.push_back(declaration->value());
            cstyles.push_back(styleStrings_[styleStrings_.size() - 2].c_str());
            cstyles.push_back(styleStrings_[styleStrings_.size() - 1].c_str());
        }

        elementCallback_(element.id,
            ctags.data(), static_cast<int>(ctags.size()),
            vertices.data(), static_cast<int>(vertices.size()),
            cstyles.data(), static_cast<int>(cstyles.size()));

        // NOTE clear vectors after raw array data is consumed by external code
        tagStrings_.clear();
        styleStrings_.clear();
    }

    const utymap::QuadKey& quadKey_;
    utymap::index::StringTable& stringTable_;
    const utymap::mapcss::StyleProvider& styleProvider_;
    const utymap::heightmap::ElevationProvider& eleProvider_;
    OnElementLoaded* elementCallback_;
    std::vector<std::string> tagStrings_;   // holds temporary tag strings
    std::vector<std::string> styleStrings_; // holds temporary style strings
};

#endif // EXPORTELEMENTVISITOR_HPP_DEFINED
<|endoftext|>


<commit_before>#include "lsys/LSystemParser.hpp"

#include "lsys/StringTurtle.hpp"
#include <boost/test/unit_test.hpp>

using namespace utymap::lsys;
using namespace utymap::tests;

namespace {
    const double ProbabilityPrecision = 0.01;
    const std::string SimpleGrammar = "generations: 3\n"
                                      "angle: 45\n"
                                      "scale: 0.1\n"
                                      "axiom: D F ab G G F K\n"
                                      "F(1) -> F G\n"
                                      "G(0.8) -> F\n"
                                      "G(0.2) -> G G G G ab\n"
                                      "ab -> G G F ab";

    std::shared_ptr<MoveForwardRule> move() { return std::make_shared<MoveForwardRule>(); }
    std::shared_ptr<JumpForwardRule> jump() { return std::make_shared<JumpForwardRule>(); }
    std::shared_ptr<WordRule> A() { return std::make_shared<WordRule>("ab"); }
}

BOOST_AUTO_TEST_SUITE(Lsys_LSystemParser)

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasGenerations)
{
    BOOST_CHECK_EQUAL(LSystemParser().parse(SimpleGrammar).generations, 3);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasAngle)
{
    BOOST_CHECK_CLOSE(LSystemParser().parse(SimpleGrammar).angle, 45, ProbabilityPrecision);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasScale)
{
    BOOST_CHECK_CLOSE(LSystemParser().parse(SimpleGrammar).scale, 0.1, ProbabilityPrecision);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasExpectedAmountOfAxiomRules)
{
    BOOST_CHECK_EQUAL(LSystemParser().parse(SimpleGrammar).axiom.size(), 7);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasExpectedAmountOfProductions)
{
    auto lsystem = LSystemParser().parse(SimpleGrammar);

    BOOST_CHECK_EQUAL(lsystem.productions.size(), 3);

    BOOST_CHECK_EQUAL(lsystem.productions[move()].size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[move()].at(0).first, 1, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[move()].at(0).second.size(), 2);

    BOOST_CHECK_EQUAL(lsystem.productions[jump()].size(), 2);
    BOOST_CHECK_CLOSE(lsystem.productions[jump()].at(0).first, 0.8, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[jump()].at(0).second.size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[jump()].at(1).first, 0.2, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[jump()].at(1).second.size(), 5);

    BOOST_CHECK_EQUAL(lsystem.productions[A()].size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[A()].at(0).first, 1, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[A()].at(0).second.size(), 4);
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithComment_WhenParse_ThenSkipsCommentLine)
{
    const std::string grammar = "generations: 3\n"
                                "#angle:35\n"
                                "angle: 45\n"
                                "#angle:55\n"
                                "scale: 1.2\n"
                                "axiom: A\n"
                                "A -> G G";

    BOOST_CHECK_EQUAL(LSystemParser().parse(grammar).angle, 45);
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithProbabilities_WhenParse_ThenStringTurtleBuildsProperPath)
{
    StringTurtle turtle;
    const std::string grammar = "generations: 2\n"
                                "angle: 45\n"
                                "scale: 1.2\n"
                                "axiom: A G\n"
                                "G(0) -> G\n"
                                "G(1) -> F F\n"
                                "F -> G\n"
                                "A -> G G";

    turtle.run(LSystemParser().parse(grammar));

    BOOST_CHECK_EQUAL(turtle.path, "FFFFGG");
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithWords_WhenParse_ThenStringTurtleBuildsProperPath)
{
    StringTurtle turtle;
    const std::string grammar = "generations: 1\n"
                                "angle: 45\n"
                                "scale: 1.2\n"
                                "axiom: root F G leaf\n"
                                "root(0) -> G\n"
                                "root(1) -> F trunk\n"
                                "G -> F\n"
                                "leaf -> trunk G leaf";

    turtle.run(LSystemParser().parse(grammar));

    BOOST_CHECK_EQUAL(turtle.path, "FtrunkFFtrunkGleaf");
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>core: add unit test for lsystem parser<commit_after>#include "lsys/LSystemParser.hpp"

#include "lsys/StringTurtle.hpp"
#include <boost/test/unit_test.hpp>

#include "config.hpp"
#include <fstream>

using namespace utymap::lsys;
using namespace utymap::tests;

namespace {
    const double ProbabilityPrecision = 0.01;
    const std::string SimpleGrammar = "generations: 3\n"
                                      "angle: 45\n"
                                      "scale: 0.1\n"
                                      "axiom: D F ab G G F K\n"
                                      "F(1) -> F G\n"
                                      "G(0.8) -> F\n"
                                      "G(0.2) -> G G G G ab\n"
                                      "ab -> G G F ab";

    std::shared_ptr<MoveForwardRule> move() { return std::make_shared<MoveForwardRule>(); }
    std::shared_ptr<JumpForwardRule> jump() { return std::make_shared<JumpForwardRule>(); }
    std::shared_ptr<WordRule> A() { return std::make_shared<WordRule>("ab"); }
}

BOOST_AUTO_TEST_SUITE(Lsys_LSystemParser)

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasGenerations)
{
    BOOST_CHECK_EQUAL(LSystemParser().parse(SimpleGrammar).generations, 3);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasAngle)
{
    BOOST_CHECK_CLOSE(LSystemParser().parse(SimpleGrammar).angle, 45, ProbabilityPrecision);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasScale)
{
    BOOST_CHECK_CLOSE(LSystemParser().parse(SimpleGrammar).scale, 0.1, ProbabilityPrecision);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasExpectedAmountOfAxiomRules)
{
    BOOST_CHECK_EQUAL(LSystemParser().parse(SimpleGrammar).axiom.size(), 7);
}

BOOST_AUTO_TEST_CASE(GivenSimpleGrammar_WhenParse_ThenHasExpectedAmountOfProductions)
{
    auto lsystem = LSystemParser().parse(SimpleGrammar);

    BOOST_CHECK_EQUAL(lsystem.productions.size(), 3);

    BOOST_CHECK_EQUAL(lsystem.productions[move()].size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[move()].at(0).first, 1, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[move()].at(0).second.size(), 2);

    BOOST_CHECK_EQUAL(lsystem.productions[jump()].size(), 2);
    BOOST_CHECK_CLOSE(lsystem.productions[jump()].at(0).first, 0.8, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[jump()].at(0).second.size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[jump()].at(1).first, 0.2, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[jump()].at(1).second.size(), 5);

    BOOST_CHECK_EQUAL(lsystem.productions[A()].size(), 1);
    BOOST_CHECK_CLOSE(lsystem.productions[A()].at(0).first, 1, ProbabilityPrecision);
    BOOST_CHECK_EQUAL(lsystem.productions[A()].at(0).second.size(), 4);
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithComment_WhenParse_ThenSkipsCommentLine)
{
    const std::string grammar = "generations: 3\n"
                                "#angle:35\n"
                                "angle: 45\n"
                                "#angle:55\n"
                                "scale: 1.2\n"
                                "axiom: A\n"
                                "A -> G G";

    BOOST_CHECK_EQUAL(LSystemParser().parse(grammar).angle, 45);
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithProbabilities_WhenParse_ThenStringTurtleBuildsProperPath)
{
    StringTurtle turtle;
    const std::string grammar = "generations: 2\n"
                                "angle: 45\n"
                                "scale: 1.2\n"
                                "axiom: A G\n"
                                "G(0) -> G\n"
                                "G(1) -> F F\n"
                                "F -> G\n"
                                "A -> G G";

    turtle.run(LSystemParser().parse(grammar));

    BOOST_CHECK_EQUAL(turtle.path, "FFFFGG");
}

BOOST_AUTO_TEST_CASE(GivenGrammarWithWords_WhenParse_ThenStringTurtleBuildsProperPath)
{
    StringTurtle turtle;
    const std::string grammar = "generations: 1\n"
                                "angle: 45\n"
                                "scale: 1.2\n"
                                "axiom: root F G leaf\n"
                                "root(0) -> G\n"
                                "root(1) -> F trunk\n"
                                "G -> F\n"
                                "leaf -> trunk G leaf";

    turtle.run(LSystemParser().parse(grammar));

    BOOST_CHECK_EQUAL(turtle.path, "FtrunkFFtrunkGleaf");
}

BOOST_AUTO_TEST_CASE(GivenGrammarInFile_WhenParse_ThenGrammarIsParsed)
{
    StringTurtle turtle;
    std::ifstream file(TEST_MAPCSS_PATH "tree.lsys");

    turtle.run(LSystemParser().parse(file));

    BOOST_CHECK_EQUAL(turtle.path, "cylindersphere");
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before><commit_msg>removed variable re-declaration.<commit_after><|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/CurvesPrimitive.h"
#include "IECore/Exception.h"
#include "IECore/SimpleTypedData.h"

#include "IECoreArnold/ToArnoldCurvesConverter.h"

using namespace IECoreArnold;
using namespace IECore;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( ToArnoldCurvesConverter );

ToArnoldCurvesConverter::ConverterDescription<ToArnoldCurvesConverter> ToArnoldCurvesConverter::g_description;

ToArnoldCurvesConverter::ToArnoldCurvesConverter( IECore::CurvesPrimitivePtr toConvert )
	:	ToArnoldShapeConverter( "Converts IECore::CurvesPrimitives to arnold curves nodes", IECore::CurvesPrimitive::staticTypeId() )
{
	srcParameter()->setValue( toConvert );
}

ToArnoldCurvesConverter::~ToArnoldCurvesConverter()
{
}

AtNode *ToArnoldCurvesConverter::doConversion( IECore::ConstObjectPtr from, IECore::ConstCompoundObjectPtr operands ) const
{
	const CurvesPrimitive *curves = static_cast<const CurvesPrimitive *>( from.get() );
	const V3fVectorData *p = curves->variableData<V3fVectorData>( "P", PrimitiveVariable::Vertex );
	if( !p )
	{
		throw Exception( "CurvesPrimitive does not have \"P\" primitive variable of interpolation type Vertex." );
	}

	// make the result curves and add points

	AtNode *result = AiNode( "curves" );

	const std::vector<int> verticesPerCurve = curves->verticesPerCurve()->readable();
	AiNodeSetArray(
		result,
		"num_points",
		AiArrayConvert( verticesPerCurve.size(), 1, AI_TYPE_INT, (void *)&( verticesPerCurve[0] ) )
	);

	convertP( p, result, "points" );

	// set basis

	if( curves->basis() == CubicBasisf::bezier() )
	{
		AiNodeSetStr( result, "basis", "bezier" );

	}
	else if( curves->basis() == CubicBasisf::bSpline() )
	{
		AiNodeSetStr( result, "basis", "b-spline" );
	}
	else if( curves->basis() == CubicBasisf::catmullRom() )
	{
		AiNodeSetStr( result, "basis", "catmull-rom" );
	}
	else
	{
		// just accept the default
	}

	// add radius

	convertRadius( curves, result );

	// add arbitrary user parameters

	const char *ignore[] = { "P", "width", "radius", 0 };
	convertPrimitiveVariables( curves, result, ignore );

	return result;
}
<commit_msg>IECoreArnold now supports linear curves<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/CurvesPrimitive.h"
#include "IECore/Exception.h"
#include "IECore/SimpleTypedData.h"

#include "IECoreArnold/ToArnoldCurvesConverter.h"

using namespace IECoreArnold;
using namespace IECore;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( ToArnoldCurvesConverter );

ToArnoldCurvesConverter::ConverterDescription<ToArnoldCurvesConverter> ToArnoldCurvesConverter::g_description;

ToArnoldCurvesConverter::ToArnoldCurvesConverter( IECore::CurvesPrimitivePtr toConvert )
	:	ToArnoldShapeConverter( "Converts IECore::CurvesPrimitives to arnold curves nodes", IECore::CurvesPrimitive::staticTypeId() )
{
	srcParameter()->setValue( toConvert );
}

ToArnoldCurvesConverter::~ToArnoldCurvesConverter()
{
}

AtNode *ToArnoldCurvesConverter::doConversion( IECore::ConstObjectPtr from, IECore::ConstCompoundObjectPtr operands ) const
{
	const CurvesPrimitive *curves = static_cast<const CurvesPrimitive *>( from.get() );
	const V3fVectorData *p = curves->variableData<V3fVectorData>( "P", PrimitiveVariable::Vertex );
	if( !p )
	{
		throw Exception( "CurvesPrimitive does not have \"P\" primitive variable of interpolation type Vertex." );
	}

	// make the result curves and add points

	AtNode *result = AiNode( "curves" );

	const std::vector<int> verticesPerCurve = curves->verticesPerCurve()->readable();
	AiNodeSetArray(
		result,
		"num_points",
		AiArrayConvert( verticesPerCurve.size(), 1, AI_TYPE_INT, (void *)&( verticesPerCurve[0] ) )
	);

	convertP( p, result, "points" );

	// set basis

	if( curves->basis() == CubicBasisf::bezier() )
	{
		AiNodeSetStr( result, "basis", "bezier" );
	}
	else if( curves->basis() == CubicBasisf::bSpline() )
	{
		AiNodeSetStr( result, "basis", "b-spline" );
	}
	else if( curves->basis() == CubicBasisf::catmullRom() )
	{
		AiNodeSetStr( result, "basis", "catmull-rom" );
	}
	else if( curves->basis() == CubicBasisf::linear() )
	{
		AiNodeSetStr( result, "basis", "linear" );
	}
	else
	{
		// just accept the default
	}

	// add radius

	convertRadius( curves, result );

	// add arbitrary user parameters

	const char *ignore[] = { "P", "width", "radius", 0 };
	convertPrimitiveVariables( curves, result, ignore );

	return result;
}
<|endoftext|>


<commit_before>// Please read Bounce2.h for information about the liscence and authors

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Bounce2.h"

#define DEBOUNCED_STATE 0
#define UNSTABLE_STATE  1
#define STATE_CHANGED   3

Bounce::Bounce()
    : previous_millis(0)
    , interval_millis(10)
    , state(0)
    , pin(0)
{}

void Bounce::attach(int pin) {
    this->pin = pin;
    state = 0;
    if (digitalRead(pin)) {
        state = _BV(DEBOUNCED_STATE) | _BV(UNSTABLE_STATE);
    }
#ifdef BOUNCE_LOCK_OUT
    previous_millis = 0;
#else
    previous_millis = millis();
#endif
}

void Bounce::attach(int pin, int mode){
  pinMode(pin, mode);

  this->attach(pin);
}

void Bounce::interval(uint16_t interval_millis)
{
    this->interval_millis = interval_millis;
}

bool Bounce::update()
{
#ifdef BOUNCE_LOCK_OUT
    state &= ~_BV(STATE_CHANGED);
    // Ignore everything if we are locked out
    if (millis() - previous_millis >= interval_millis) {
        bool currentState = digitalRead(pin);
        if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
            previous_millis = millis();
            state ^= _BV(DEBOUNCED_STATE);
            state |= _BV(STATE_CHANGED);
        }
    }
    return state & _BV(STATE_CHANGED);

#elif defined BOUNCE_WITH_PROMPT_DETECTION
    // Read the state of the switch port into a temporary variable.
    bool readState = digitalRead(pin);

    // Clear Changed State Flag - will be reset if we confirm a button state change.
    state &= ~_BV(STATE_CHANGED);

    if ( readState != (bool)(state & _BV(DEBOUNCED_STATE))) {
      // We have seen a change from the current button state.

      if ( millis() - previous_millis >= interval_millis ) {
	// We have passed the time threshold, so a new change of state is allowed.
	// set the STATE_CHANGED flag and the new DEBOUNCED_STATE.
	// This will be prompt as long as there has been greater than interval_misllis ms since last change of input.
	// Otherwise debounced state will not change again until bouncing is stable for the timeout period.
	state ^= _BV(DEBOUNCED_STATE);
	state |= _BV(STATE_CHANGED);
      }
    }

    // If the readState is different from previous readState, reset the debounce timer - as input is still unstable
    // and we want to prevent new button state changes until the previous one has remained stable for the timeout.
    if ( readState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
	// Update Unstable Bit to macth readState
        state ^= _BV(UNSTABLE_STATE);
        previous_millis = millis();
    }
    // return just the sate changed bit
    return state & _BV(STATE_CHANGED);
#else
    // Read the state of the switch in a temporary variable.
    bool currentState = digitalRead(pin);
    state &= ~_BV(STATE_CHANGED);

    // If the reading is different from last reading, reset the debounce counter
    if ( currentState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
        previous_millis = millis();
        state ^= _BV(UNSTABLE_STATE);
    } else
        if ( millis() - previous_millis >= interval_millis ) {
            // We have passed the threshold time, so the input is now stable
            // If it is different from last state, set the STATE_CHANGED flag
            if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
                previous_millis = millis();
                state ^= _BV(DEBOUNCED_STATE);
                state |= _BV(STATE_CHANGED);
            }
        }

    return state & _BV(STATE_CHANGED);
#endif
}

bool Bounce::read()
{
    return state & _BV(DEBOUNCED_STATE);
}

bool Bounce::rose()
{
    return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}

bool Bounce::fell()
{
    return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}
<commit_msg>Blue Pill port<commit_after>// Please read Bounce2.h for information about the liscence and authors

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Bounce2.h"

#define DEBOUNCED_STATE 0
#define UNSTABLE_STATE  1
#define STATE_CHANGED   3

Bounce::Bounce()
    : previous_millis(0)
    , interval_millis(10)
    , state(0)
    , pin(0)
{}

void Bounce::attach(int pin) {
    this->pin = pin;
    state = 0;
    if (digitalRead(pin)) {
        state = _BV(DEBOUNCED_STATE) | _BV(UNSTABLE_STATE);
    }
#ifdef BOUNCE_LOCK_OUT
    previous_millis = 0;
#else
    previous_millis = millis();
#endif
}

void Bounce::attach(int pin, int mode){
#if defined(ARDUINO_STM_NUCLEO_F103RB) || defined(ARDUINO_GENERIC_STM32F103C)
    pinMode(pin, (WiringPinMode)mode);
#else
    pinMode(pin, mode);
#endif
  this->attach(pin);
}

void Bounce::interval(uint16_t interval_millis)
{
    this->interval_millis = interval_millis;
}

bool Bounce::update()
{
#ifdef BOUNCE_LOCK_OUT
    state &= ~_BV(STATE_CHANGED);
    // Ignore everything if we are locked out
    if (millis() - previous_millis >= interval_millis) {
        bool currentState = digitalRead(pin);
        if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
            previous_millis = millis();
            state ^= _BV(DEBOUNCED_STATE);
            state |= _BV(STATE_CHANGED);
        }
    }
    return state & _BV(STATE_CHANGED);

#elif defined BOUNCE_WITH_PROMPT_DETECTION
    // Read the state of the switch port into a temporary variable.
    bool readState = digitalRead(pin);

    // Clear Changed State Flag - will be reset if we confirm a button state change.
    state &= ~_BV(STATE_CHANGED);

    if ( readState != (bool)(state & _BV(DEBOUNCED_STATE))) {
      // We have seen a change from the current button state.

      if ( millis() - previous_millis >= interval_millis ) {
	// We have passed the time threshold, so a new change of state is allowed.
	// set the STATE_CHANGED flag and the new DEBOUNCED_STATE.
	// This will be prompt as long as there has been greater than interval_misllis ms since last change of input.
	// Otherwise debounced state will not change again until bouncing is stable for the timeout period.
	state ^= _BV(DEBOUNCED_STATE);
	state |= _BV(STATE_CHANGED);
      }
    }

    // If the readState is different from previous readState, reset the debounce timer - as input is still unstable
    // and we want to prevent new button state changes until the previous one has remained stable for the timeout.
    if ( readState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
	// Update Unstable Bit to macth readState
        state ^= _BV(UNSTABLE_STATE);
        previous_millis = millis();
    }
    // return just the sate changed bit
    return state & _BV(STATE_CHANGED);
#else
    // Read the state of the switch in a temporary variable.
    bool currentState = digitalRead(pin);
    state &= ~_BV(STATE_CHANGED);

    // If the reading is different from last reading, reset the debounce counter
    if ( currentState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
        previous_millis = millis();
        state ^= _BV(UNSTABLE_STATE);
    } else
        if ( millis() - previous_millis >= interval_millis ) {
            // We have passed the threshold time, so the input is now stable
            // If it is different from last state, set the STATE_CHANGED flag
            if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
                previous_millis = millis();
                state ^= _BV(DEBOUNCED_STATE);
                state |= _BV(STATE_CHANGED);
            }
        }

    return state & _BV(STATE_CHANGED);
#endif
}

bool Bounce::read()
{
    return state & _BV(DEBOUNCED_STATE);
}

bool Bounce::rose()
{
    return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}

bool Bounce::fell()
{
    return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}
<|endoftext|>


<commit_before>/*
 * D3D11VertexBufferArray.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "D3D11VertexBufferArray.h"
#include "D3D11VertexBuffer.h"
#include "../../CheckedCast.h"

namespace LLGL
{

D3D11VertexBufferArray::D3D11VertexBufferArray(unsigned int numBuffers, Buffer* const * bufferArray) :
    D3D11BufferArray( BufferType::Vertex, numBuffers, bufferArray )
{
    /* Store the pointer of each ID3D11Buffer inside the array */
    for (strides_.reserve(numBuffers), offsets_.reserve(numBuffers); numBuffers > 0; --numBuffers)
    {
        auto vertexBufferD3D = LLGL_CAST(D3D11VertexBuffer*, (*bufferArray));
        strides_.push_back(vertexBufferD3D->GetStride());
        offsets_.push_back(0);//vertexBufferD3D->GetOffset());
        ++bufferArray;
    }
}

} // /namespace LLGL

// ================================================================================
<commit_msg>Simplified D3D11VertexBufferArray constructor.<commit_after>/*
 * D3D11VertexBufferArray.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "D3D11VertexBufferArray.h"
#include "D3D11VertexBuffer.h"
#include "../../CheckedCast.h"
#include "../../../Core/Helper.h"

namespace LLGL
{

D3D11VertexBufferArray::D3D11VertexBufferArray(unsigned int numBuffers, Buffer* const * bufferArray) :
    D3D11BufferArray( BufferType::Vertex, numBuffers, bufferArray )
{
    /* Store the pointer of each ID3D11Buffer inside the array */
    strides_.reserve(numBuffers);
    offsets_.reserve(numBuffers);

    while (auto next = NextArrayResource<D3D11VertexBuffer>(numBuffers, bufferArray))
    {
        strides_.push_back(next->GetStride());
        offsets_.push_back(0);//next->GetOffset());
    }
}

} // /namespace LLGL

// ================================================================================
<|endoftext|>