<commit_before>#include "stdafx.h"
#include "CtrlrSlider.h"
#include "CtrlrProcessor.h"
#include "../CtrlrComponentTypeManager.h"
#include "CtrlrPanel/CtrlrPanelEditor.h"
#include "CtrlrModulator/CtrlrModulator.h"
#include "Lua/JuceClasses/LLookAndFeel.h"

CtrlrSlider::CtrlrSlider (CtrlrModulator &owner)
    :	CtrlrComponent(owner),
		lf(*this, componentTree),
		ctrlrSlider (*this)
{
	setColour (TooltipWindow::textColourId, Colours::red);
	addAndMakeVisible (&ctrlrSlider);

    ctrlrSlider.setRange (1, 127, 1);
    ctrlrSlider.setSliderStyle (Slider::RotaryVerticalDrag);
    ctrlrSlider.setTextBoxStyle (Slider::TextBoxBelow, false, 64, 12);
    ctrlrSlider.addListener (this);
	ctrlrSlider.setLookAndFeel (&lf);
	componentTree.addListener (this);

	setProperty (Ids::uiSliderStyle, "RotaryVerticalDrag");
	setProperty (Ids::uiSliderMin, 0);
	setProperty (Ids::uiSliderMax, 127);
	setProperty (Ids::uiSliderInterval, 1);
	setProperty (Ids::uiSliderDoubleClickEnabled, true);
	setProperty (Ids::uiSliderDoubleClickValue, 0);
	setProperty (Ids::uiSliderValuePosition, (int)Slider::TextBoxBelow);
	setProperty (Ids::uiSliderValueHeight, 12);
	setProperty (Ids::uiSliderValueWidth, 64);
	setProperty (Ids::uiSliderTrackCornerSize, 5);
	setProperty (Ids::uiSliderThumbCornerSize, 3);
	setProperty (Ids::uiSliderThumbWidth, 0);
	setProperty (Ids::uiSliderThumbHeight, 0);
	setProperty (Ids::uiSliderThumbFlatOnLeft, false);
	setProperty (Ids::uiSliderThumbFlatOnRight, false);
	setProperty (Ids::uiSliderThumbFlatOnTop, false);
	setProperty (Ids::uiSliderThumbFlatOnBottom, false);
	setProperty (Ids::uiSliderValueTextColour, "0xff000000");
	setProperty (Ids::uiSliderValueBgColour, "0xffffffff");
	setProperty (Ids::uiSliderRotaryOutlineColour, "0xff0000ff");
	setProperty (Ids::uiSliderRotaryFillColour, "0xff0000ff");
	setProperty (Ids::uiSliderThumbColour, "0xffff0000");
	setProperty (Ids::uiSliderValueHighlightColour, "0xff0000ff");
	setProperty (Ids::uiSliderValueOutlineColour, "0xffffffff");
	setProperty (Ids::uiSliderTrackColour, "0xff0f0f0f");
	setProperty (Ids::uiSliderIncDecButtonColour, "0xff0000ff");
	setProperty (Ids::uiSliderIncDecTextColour, "0xffffffff");
	setProperty (Ids::uiSliderValueFont, FONT2STR (Font(12)));
	setProperty (Ids::uiSliderValueTextJustification, "centred");
	setProperty (Ids::uiSliderVelocitySensitivity, 1.0);
	setProperty (Ids::uiSliderVelocityThreshold, 1);
	setProperty (Ids::uiSliderVelocityOffset, 0.0);
	setProperty (Ids::uiSliderVelocityMode, false);
	setProperty (Ids::uiSliderVelocityModeKeyTrigger, true);
	setProperty (Ids::uiSliderSpringMode, false);
	setProperty (Ids::uiSliderSpringValue, 0);
	setProperty (Ids::uiSliderMouseWheelInterval, 1);
	setProperty (Ids::uiSliderPopupBubble, false);

    setSize (64, 64);
}

CtrlrSlider::~CtrlrSlider()
{
	componentTree.removeListener (this);
}

void CtrlrSlider::resized()
{
	if (restoreStateInProgress)
		return;
	ctrlrSlider.setBounds (getUsableRect());
}

void CtrlrSlider::sliderValueChanged (Slider* sliderThatWasMoved)
{
    if (sliderThatWasMoved == &ctrlrSlider)
    {
		if ((bool)owner.getOwnerPanel().getEditor()->getProperty(Ids::uiPanelEditMode) == true)
			return;

		setComponentValue (ctrlrSlider.getValue(), true);
    }
}

void CtrlrSlider::mouseUp (const MouseEvent& e)
{
	if ((bool)getProperty(Ids::uiSliderSpringMode) == true)
	{
		ctrlrSlider.setValue ((double)getProperty(Ids::uiSliderSpringValue), sendNotificationSync);
	}
}

double CtrlrSlider::getComponentValue()
{
	return (ctrlrSlider.getValue());
}

int CtrlrSlider::getComponentMidiValue()
{
	return ((int)ctrlrSlider.getValue());
}

double CtrlrSlider::getComponentMaxValue()
{
	return (ctrlrSlider.getMaximum());
}

void CtrlrSlider::setComponentValue (const double newValue, const bool sendChangeMessage)
{
	ctrlrSlider.setValue (newValue, dontSendNotification);
	if (sendChangeMessage)
	{
		owner.getProcessor().setValueGeneric (CtrlrModulatorValue(newValue,CtrlrModulatorValue::changedByGUI));
	}
}

const Array<Font> CtrlrSlider::getFontList()
{
	Array <Font> ret;
	Font f = STR2FONT(getProperty(Ids::uiSliderValueFont));
	if (f.getTypefaceName() != Font::getDefaultSerifFontName()
		&& f.getTypefaceName() != Font::getDefaultSansSerifFontName()
		&& f.getTypefaceName() != Font::getDefaultMonospacedFontName()
		&& f.getTypefaceName() != "<Sans-Serif>")
	{
		ret.add (f);
	}
	return (ret);
}

void CtrlrSlider::valueTreePropertyChanged (ValueTree &treeWhosePropertyHasChanged, const Identifier &property)
{
	if (property == Ids::uiSliderStyle)
	{
		ctrlrSlider.setSliderStyle ((Slider::SliderStyle)CtrlrComponentTypeManager::sliderStringToStyle (getProperty (Ids::uiSliderStyle)));
	}
	else if (property == Ids::uiSliderRotaryFillColour)
	{
		ctrlrSlider.setColour (Slider::rotarySliderFillColourId, VAR2COLOUR(getProperty (Ids::uiSliderRotaryFillColour)) );
	}
	else if (property == Ids::uiSliderRotaryOutlineColour)
	{
		ctrlrSlider.setColour (Slider::rotarySliderOutlineColourId, VAR2COLOUR(getProperty (Ids::uiSliderRotaryOutlineColour)) );
	}
	else if (property == Ids::uiSliderValueTextColour)
	{
		ctrlrSlider.setColour (Slider::textBoxTextColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueTextColour)) );
	}

	else if (property == Ids::uiSliderValueBgColour)
	{
		ctrlrSlider.setColour (Slider::textBoxBackgroundColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueBgColour)) );
	}
	else if (property == Ids::uiSliderThumbColour)
	{
		ctrlrSlider.setColour (Slider::thumbColourId, VAR2COLOUR(getProperty (Ids::uiSliderThumbColour)) );
	}
	else if (property == Ids::uiSliderValueHighlightColour)
	{
		ctrlrSlider.setColour (Slider::textBoxHighlightColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueOutlineColour)) );
	}
	else if (property == Ids::uiSliderValueOutlineColour)
	{
		ctrlrSlider.setColour (Slider::textBoxOutlineColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueOutlineColour)) );
	}
	else if (property == Ids::uiSliderTrackColour)
	{
		ctrlrSlider.setColour (Slider::trackColourId, VAR2COLOUR(getProperty (Ids::uiSliderTrackColour)) );
	}
	else if (property == Ids::uiSliderInterval || property == Ids::uiSliderMax || property == Ids::uiSliderMin)
	{
		ctrlrSlider.setRange ( (double) getProperty (Ids::uiSliderMin), (double) getProperty (Ids::uiSliderMax), (double) getProperty (Ids::uiSliderInterval) );
		owner.setProperty (Ids::modulatorMax, ctrlrSlider.getMaximum());
		owner.setProperty (Ids::modulatorMin, ctrlrSlider.getMinimum());
	}
	else if (property == Ids::uiSliderValuePosition || property == Ids::uiSliderValueHeight || property == Ids::uiSliderValueWidth)
	{
		ctrlrSlider.setTextBoxStyle (
			(Slider::TextEntryBoxPosition)(int)getProperty (Ids::uiSliderValuePosition),
			false,
			getProperty (Ids::uiSliderValueWidth, 64),
			getProperty (Ids::uiSliderValueHeight, 12));
	}
	else if (property == Ids::uiSliderIncDecButtonColour
			|| property == Ids::uiSliderIncDecTextColour
			|| property == Ids::uiSliderValueFont
			|| property == Ids::uiSliderValueTextJustification)
	{
		ctrlrSlider.setLookAndFeel (nullptr);
		ctrlrSlider.setLookAndFeel (&lf);
	}
	else if (property == Ids::uiSliderVelocityMode
		|| property == Ids::uiSliderVelocityModeKeyTrigger
		|| property == Ids::uiSliderVelocitySensitivity
		|| property == Ids::uiSliderVelocityThreshold
		|| property == Ids::uiSliderVelocityOffset
		)
	{
		ctrlrSlider.setVelocityBasedMode((bool)getProperty(Ids::uiSliderVelocityMode));
		ctrlrSlider.setVelocityModeParameters ((double)getProperty(Ids::uiSliderVelocitySensitivity),
												(int)getProperty(Ids::uiSliderVelocityThreshold),
												(double)getProperty(Ids::uiSliderVelocityOffset),
												(bool)getProperty(Ids::uiSliderVelocityModeKeyTrigger));
	}
	else if (property == Ids::uiSliderSpringValue)
	{
		ctrlrSlider.setValue (getProperty(property), dontSendNotification);
	}

	else if (property == Ids::uiSliderDoubleClickValue
			|| property == Ids::uiSliderDoubleClickEnabled)
	{
		ctrlrSlider.setDoubleClickReturnValue ((bool)getProperty(Ids::uiSliderDoubleClickEnabled), getProperty(Ids::uiSliderDoubleClickValue));
	}
	else if (property == Ids::uiSliderSpringMode)
	{
		if ((bool)getProperty(property) == true)
		{
			ctrlrSlider.setValue (getProperty(Ids::uiSliderSpringValue), dontSendNotification);
		}
	}
	else if (property == Ids::uiSliderPopupBubble)
	{
		ctrlrSlider.setPopupDisplayEnabled ((bool)getProperty(property), (bool)getProperty(property), owner.getOwnerPanel().getEditor());
	}
	else
	{
		CtrlrComponent::valueTreePropertyChanged(treeWhosePropertyHasChanged, property);
	}

	if (restoreStateInProgress == false)
	{
		resized();
	}
}

const String CtrlrSlider::getComponentText()
{
	return (String(getComponentValue()));
}

void CtrlrSlider::customLookAndFeelChanged(LookAndFeelBase *customLookAndFeel)
{
    if (customLookAndFeel == nullptr)
        ctrlrSlider.setLookAndFeel (&lf);
    else
        ctrlrSlider.setLookAndFeel (customLookAndFeel);
}<commit_msg>Gracefully work when slider properties are not set up properly.<commit_after>#include "stdafx.h"
#include "CtrlrSlider.h"
#include "CtrlrProcessor.h"
#include "../CtrlrComponentTypeManager.h"
#include "CtrlrPanel/CtrlrPanelEditor.h"
#include "CtrlrModulator/CtrlrModulator.h"
#include "Lua/JuceClasses/LLookAndFeel.h"

CtrlrSlider::CtrlrSlider (CtrlrModulator &owner)
    :	CtrlrComponent(owner),
		lf(*this, componentTree),
		ctrlrSlider (*this)
{
	setColour (TooltipWindow::textColourId, Colours::red);
	addAndMakeVisible (&ctrlrSlider);

    ctrlrSlider.setRange (1, 127, 1);
    ctrlrSlider.setSliderStyle (Slider::RotaryVerticalDrag);
    ctrlrSlider.setTextBoxStyle (Slider::TextBoxBelow, false, 64, 12);
    ctrlrSlider.addListener (this);
	ctrlrSlider.setLookAndFeel (&lf);
	componentTree.addListener (this);

	setProperty (Ids::uiSliderStyle, "RotaryVerticalDrag");
	setProperty (Ids::uiSliderMin, 0);
	setProperty (Ids::uiSliderMax, 127);
	setProperty (Ids::uiSliderInterval, 1);
	setProperty (Ids::uiSliderDoubleClickEnabled, true);
	setProperty (Ids::uiSliderDoubleClickValue, 0);
	setProperty (Ids::uiSliderValuePosition, (int)Slider::TextBoxBelow);
	setProperty (Ids::uiSliderValueHeight, 12);
	setProperty (Ids::uiSliderValueWidth, 64);
	setProperty (Ids::uiSliderTrackCornerSize, 5);
	setProperty (Ids::uiSliderThumbCornerSize, 3);
	setProperty (Ids::uiSliderThumbWidth, 0);
	setProperty (Ids::uiSliderThumbHeight, 0);
	setProperty (Ids::uiSliderThumbFlatOnLeft, false);
	setProperty (Ids::uiSliderThumbFlatOnRight, false);
	setProperty (Ids::uiSliderThumbFlatOnTop, false);
	setProperty (Ids::uiSliderThumbFlatOnBottom, false);
	setProperty (Ids::uiSliderValueTextColour, "0xff000000");
	setProperty (Ids::uiSliderValueBgColour, "0xffffffff");
	setProperty (Ids::uiSliderRotaryOutlineColour, "0xff0000ff");
	setProperty (Ids::uiSliderRotaryFillColour, "0xff0000ff");
	setProperty (Ids::uiSliderThumbColour, "0xffff0000");
	setProperty (Ids::uiSliderValueHighlightColour, "0xff0000ff");
	setProperty (Ids::uiSliderValueOutlineColour, "0xffffffff");
	setProperty (Ids::uiSliderTrackColour, "0xff0f0f0f");
	setProperty (Ids::uiSliderIncDecButtonColour, "0xff0000ff");
	setProperty (Ids::uiSliderIncDecTextColour, "0xffffffff");
	setProperty (Ids::uiSliderValueFont, FONT2STR (Font(12)));
	setProperty (Ids::uiSliderValueTextJustification, "centred");
	setProperty (Ids::uiSliderVelocitySensitivity, 1.0);
	setProperty (Ids::uiSliderVelocityThreshold, 1);
	setProperty (Ids::uiSliderVelocityOffset, 0.0);
	setProperty (Ids::uiSliderVelocityMode, false);
	setProperty (Ids::uiSliderVelocityModeKeyTrigger, true);
	setProperty (Ids::uiSliderSpringMode, false);
	setProperty (Ids::uiSliderSpringValue, 0);
	setProperty (Ids::uiSliderMouseWheelInterval, 1);
	setProperty (Ids::uiSliderPopupBubble, false);

    setSize (64, 64);
}

CtrlrSlider::~CtrlrSlider()
{
	componentTree.removeListener (this);
}

void CtrlrSlider::resized()
{
	if (restoreStateInProgress)
		return;
	ctrlrSlider.setBounds (getUsableRect());
}

void CtrlrSlider::sliderValueChanged (Slider* sliderThatWasMoved)
{
    if (sliderThatWasMoved == &ctrlrSlider)
    {
		if ((bool)owner.getOwnerPanel().getEditor()->getProperty(Ids::uiPanelEditMode) == true)
			return;

		setComponentValue (ctrlrSlider.getValue(), true);
    }
}

void CtrlrSlider::mouseUp (const MouseEvent& e)
{
	if ((bool)getProperty(Ids::uiSliderSpringMode) == true)
	{
		ctrlrSlider.setValue ((double)getProperty(Ids::uiSliderSpringValue), sendNotificationSync);
	}
}

double CtrlrSlider::getComponentValue()
{
	return (ctrlrSlider.getValue());
}

int CtrlrSlider::getComponentMidiValue()
{
	return ((int)ctrlrSlider.getValue());
}

double CtrlrSlider::getComponentMaxValue()
{
	return (ctrlrSlider.getMaximum());
}

void CtrlrSlider::setComponentValue (const double newValue, const bool sendChangeMessage)
{
	ctrlrSlider.setValue (newValue, dontSendNotification);
	if (sendChangeMessage)
	{
		owner.getProcessor().setValueGeneric (CtrlrModulatorValue(newValue,CtrlrModulatorValue::changedByGUI));
	}
}

const Array<Font> CtrlrSlider::getFontList()
{
	Array <Font> ret;
	Font f = STR2FONT(getProperty(Ids::uiSliderValueFont));
	if (f.getTypefaceName() != Font::getDefaultSerifFontName()
		&& f.getTypefaceName() != Font::getDefaultSansSerifFontName()
		&& f.getTypefaceName() != Font::getDefaultMonospacedFontName()
		&& f.getTypefaceName() != "<Sans-Serif>")
	{
		ret.add (f);
	}
	return (ret);
}

void CtrlrSlider::valueTreePropertyChanged (ValueTree &treeWhosePropertyHasChanged, const Identifier &property)
{
	if (property == Ids::uiSliderStyle)
	{
		ctrlrSlider.setSliderStyle ((Slider::SliderStyle)CtrlrComponentTypeManager::sliderStringToStyle (getProperty (Ids::uiSliderStyle)));
	}
	else if (property == Ids::uiSliderRotaryFillColour)
	{
		ctrlrSlider.setColour (Slider::rotarySliderFillColourId, VAR2COLOUR(getProperty (Ids::uiSliderRotaryFillColour)) );
	}
	else if (property == Ids::uiSliderRotaryOutlineColour)
	{
		ctrlrSlider.setColour (Slider::rotarySliderOutlineColourId, VAR2COLOUR(getProperty (Ids::uiSliderRotaryOutlineColour)) );
	}
	else if (property == Ids::uiSliderValueTextColour)
	{
		ctrlrSlider.setColour (Slider::textBoxTextColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueTextColour)) );
	}

	else if (property == Ids::uiSliderValueBgColour)
	{
		ctrlrSlider.setColour (Slider::textBoxBackgroundColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueBgColour)) );
	}
	else if (property == Ids::uiSliderThumbColour)
	{
		ctrlrSlider.setColour (Slider::thumbColourId, VAR2COLOUR(getProperty (Ids::uiSliderThumbColour)) );
	}
	else if (property == Ids::uiSliderValueHighlightColour)
	{
		ctrlrSlider.setColour (Slider::textBoxHighlightColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueOutlineColour)) );
	}
	else if (property == Ids::uiSliderValueOutlineColour)
	{
		ctrlrSlider.setColour (Slider::textBoxOutlineColourId, VAR2COLOUR(getProperty (Ids::uiSliderValueOutlineColour)) );
	}
	else if (property == Ids::uiSliderTrackColour)
	{
		ctrlrSlider.setColour (Slider::trackColourId, VAR2COLOUR(getProperty (Ids::uiSliderTrackColour)) );
	}
	else if (property == Ids::uiSliderInterval || property == Ids::uiSliderMax || property == Ids::uiSliderMin)
	{
		double max       = getProperty (Ids::uiSliderMax);
		const double min = getProperty (Ids::uiSliderMin);
		double interval  = getProperty (Ids::uiSliderInterval);
		if (interval == 0)
			interval = std::abs(max-min) + 1;
		// For JUCE MAX must be >= min
		if (max <= min) {
			// samething between 0.5 and 1 times the interval
			// to avoid rounding errors
			max = min + interval * 0.66;
		}
		ctrlrSlider.setRange ( min, max, interval  );
		owner.setProperty (Ids::modulatorMax, ctrlrSlider.getMaximum());
		owner.setProperty (Ids::modulatorMin, ctrlrSlider.getMinimum());
	}
	else if (property == Ids::uiSliderValuePosition || property == Ids::uiSliderValueHeight || property == Ids::uiSliderValueWidth)
	{
		ctrlrSlider.setTextBoxStyle (
			(Slider::TextEntryBoxPosition)(int)getProperty (Ids::uiSliderValuePosition),
			false,
			getProperty (Ids::uiSliderValueWidth, 64),
			getProperty (Ids::uiSliderValueHeight, 12));
	}
	else if (property == Ids::uiSliderIncDecButtonColour
			|| property == Ids::uiSliderIncDecTextColour
			|| property == Ids::uiSliderValueFont
			|| property == Ids::uiSliderValueTextJustification)
	{
		ctrlrSlider.setLookAndFeel (nullptr);
		ctrlrSlider.setLookAndFeel (&lf);
	}
	else if (property == Ids::uiSliderVelocityMode
		|| property == Ids::uiSliderVelocityModeKeyTrigger
		|| property == Ids::uiSliderVelocitySensitivity
		|| property == Ids::uiSliderVelocityThreshold
		|| property == Ids::uiSliderVelocityOffset
		)
	{
		ctrlrSlider.setVelocityBasedMode((bool)getProperty(Ids::uiSliderVelocityMode));
		ctrlrSlider.setVelocityModeParameters ((double)getProperty(Ids::uiSliderVelocitySensitivity),
												(int)getProperty(Ids::uiSliderVelocityThreshold),
												(double)getProperty(Ids::uiSliderVelocityOffset),
												(bool)getProperty(Ids::uiSliderVelocityModeKeyTrigger));
	}
	else if (property == Ids::uiSliderSpringValue)
	{
		ctrlrSlider.setValue (getProperty(property), dontSendNotification);
	}

	else if (property == Ids::uiSliderDoubleClickValue
			|| property == Ids::uiSliderDoubleClickEnabled)
	{
		ctrlrSlider.setDoubleClickReturnValue ((bool)getProperty(Ids::uiSliderDoubleClickEnabled), getProperty(Ids::uiSliderDoubleClickValue));
	}
	else if (property == Ids::uiSliderSpringMode)
	{
		if ((bool)getProperty(property) == true)
		{
			ctrlrSlider.setValue (getProperty(Ids::uiSliderSpringValue), dontSendNotification);
		}
	}
	else if (property == Ids::uiSliderPopupBubble)
	{
		ctrlrSlider.setPopupDisplayEnabled ((bool)getProperty(property), (bool)getProperty(property), owner.getOwnerPanel().getEditor());
	}
	else
	{
		CtrlrComponent::valueTreePropertyChanged(treeWhosePropertyHasChanged, property);
	}

	if (restoreStateInProgress == false)
	{
		resized();
	}
}

const String CtrlrSlider::getComponentText()
{
	return (String(getComponentValue()));
}

void CtrlrSlider::customLookAndFeelChanged(LookAndFeelBase *customLookAndFeel)
{
    if (customLookAndFeel == nullptr)
        ctrlrSlider.setLookAndFeel (&lf);
    else
        ctrlrSlider.setLookAndFeel (customLookAndFeel);
}
<|endoftext|>


<commit_before>/**
** Copyright (C) 2010 Aldebaran Robotics
*/

#include <gtest/gtest.h>
#include <vector>
#include <iostream>
#include <cmath>
#include <qi/transport/zeromq/zmqpublisher.hpp>
#include <qi/transport/zeromq/zmqsubscriber.hpp>
#include <qi/perf/sleep.hpp>
#include <boost/timer.hpp>

struct SubscribePerfHandler : qi::transport::SubscribeHandler {
  int fCount;
  int fExpectedMessages;
  boost::timer timer;

  // conforms to ISubscriberHandler
  void subscribeHandler(const std::string& msg) {
    if (fCount == 0) {
      timer.restart();
    }
    fCount++;
    if (fCount != fExpectedMessages) {
      return;
    }
    // print results
    double elapsed = timer.elapsed();
    double msgPerSecond = 1.0 /(elapsed / fExpectedMessages);
    std::cout << "SUB: msg:" << fCount << " msg/s: " <<
      std::setprecision(12) << msgPerSecond << std::endl;
  }

  int getCount() {
    return fCount;
  }

  SubscribePerfHandler() : fCount(0) {}

  SubscribePerfHandler(int expectedMessages) :
    fCount(0),
    fExpectedMessages(expectedMessages) {}
};

TEST(TransportZMQPublisher , MillionPerSecond)
{
  int numMillions = 1;
  int numMessages = numMillions * 1000000;

  SubscribePerfHandler handler(numMessages);
  //qi::transport::ZMQPublisher publisher1("tcp://127.0.0.1:5556");
  qi::transport::ZMQPublisher publisher("tcp://127.0.0.1:5555");
  qi::transport::ZMQSubscriber subscriber("tcp://127.0.0.1:5555");

  subscriber.setSubscribeHandler(&handler);
  subscriber.subscribe();
  std::string msg = "Hello";
  sleep(1);
  for (int i=0; i < numMessages; i++) {
    publisher.publish(msg);
  }

  sleep(2);
  int result = handler.getCount();
  ASSERT_EQ( numMessages, result) << "Did not receive all messages";
}

TEST(TransportZMQPublisher , MultipleSubscribers)
{
  int numMessages = 100000;

  const int numSubscribers = 80;
  std::cout << "Using " << numSubscribers << " subscribers" << std::endl;
  std::vector<SubscribePerfHandler*>         handlers;
  std::vector< qi::transport::ZMQSubscriber*> subscribers;
  //boost::shared_ptr<zmq::context_t> subContext(new zmq::context_t(1));
  for (unsigned int i = 0; i < numSubscribers; ++i) {
    SubscribePerfHandler* hand = new SubscribePerfHandler(numMessages);
    qi::transport::ZMQSubscriber* sub = new qi::transport::ZMQSubscriber(/*subContext, */"tcp://127.0.0.1:5555");
    sub->setSubscribeHandler(hand);
    sub->subscribe();
    handlers.push_back(hand);
    subscribers.push_back(sub);
  }
  sleep(2);
  qi::transport::ZMQPublisher publisher("tcp://127.0.0.1:5555");

  sleep(1);
  std::string msg = "Hello";

  std::cout << "Publishing...";
  for (int i=0; i < numMessages; i++) {
    publisher.publish(msg);
  }
  std::cout << " Done." << std::endl;
  sleep(3);
  int result = 0;
  for(unsigned int i=0; i < numSubscribers; ++i) {
    result += handlers[i]->getCount();
  }
  ASSERT_EQ( numMessages * numSubscribers, result) << "Did not receive all messages";
}

<commit_msg>Added delete for subscribers vector<commit_after>/**
** Copyright (C) 2010 Aldebaran Robotics
*/

#include <gtest/gtest.h>
#include <vector>
#include <iostream>
#include <cmath>
#include <qi/transport/zeromq/zmqpublisher.hpp>
#include <qi/transport/zeromq/zmqsubscriber.hpp>
#include <qi/perf/sleep.hpp>
#include <boost/timer.hpp>

struct SubscribePerfHandler : qi::transport::SubscribeHandler {
  int fCount;
  int fExpectedMessages;
  boost::timer timer;

  // conforms to ISubscriberHandler
  void subscribeHandler(const std::string& msg) {
    if (fCount == 0) {
      timer.restart();
    }
    fCount++;
    if (fCount != fExpectedMessages) {
      return;
    }
    // print results
    double elapsed = timer.elapsed();
    double msgPerSecond = 1.0 /(elapsed / fExpectedMessages);
    std::cout << "SUB: msg:" << fCount << " msg/s: " <<
      std::setprecision(12) << msgPerSecond << std::endl;
  }

  int getCount() {
    return fCount;
  }

  SubscribePerfHandler() : fCount(0) {}

  SubscribePerfHandler(int expectedMessages) :
    fCount(0),
    fExpectedMessages(expectedMessages) {}
};

TEST(TransportZMQPublisher , MillionPerSecond)
{
  int numMillions = 1;
  int numMessages = numMillions * 1000000;

  SubscribePerfHandler handler(numMessages);
  //qi::transport::ZMQPublisher publisher1("tcp://127.0.0.1:5556");
  qi::transport::ZMQPublisher publisher("tcp://127.0.0.1:5555");
  qi::transport::ZMQSubscriber subscriber("tcp://127.0.0.1:5555");

  subscriber.setSubscribeHandler(&handler);
  subscriber.subscribe();
  std::string msg = "Hello";
  sleep(1);
  for (int i=0; i < numMessages; i++) {
    publisher.publish(msg);
  }

  sleep(2);
  int result = handler.getCount();
  ASSERT_EQ( numMessages, result) << "Did not receive all messages";
}

TEST(TransportZMQPublisher , MultipleSubscribers)
{
  int numMessages = 100000;

  const int numSubscribers = 80;
  std::cout << "Using " << numSubscribers << " subscribers" << std::endl;
  std::vector<SubscribePerfHandler*>         handlers;
  std::vector< qi::transport::ZMQSubscriber*> subscribers;
  //boost::shared_ptr<zmq::context_t> subContext(new zmq::context_t(1));
  for (unsigned int i = 0; i < numSubscribers; ++i) {
    SubscribePerfHandler* hand = new SubscribePerfHandler(numMessages);
    qi::transport::ZMQSubscriber* sub = new qi::transport::ZMQSubscriber(/*subContext, */"tcp://127.0.0.1:5555");
    sub->setSubscribeHandler(hand);
    sub->subscribe();
    handlers.push_back(hand);
    subscribers.push_back(sub);
  }
  sleep(2);
  qi::transport::ZMQPublisher publisher("tcp://127.0.0.1:5555");

  sleep(1);
  std::string msg = "Hello";

  std::cout << "Publishing...";
  for (int i=0; i < numMessages; i++) {
    publisher.publish(msg);
  }
  std::cout << " Done." << std::endl;
  sleep(3);
  int result = 0;
  for(unsigned int i=0; i < numSubscribers; ++i) {
    result += handlers[i]->getCount();
  }

  for(int i=0; i < numSubscribers; i++) {
    delete subscribers[i];
  }
  ASSERT_EQ( numMessages * numSubscribers, result) << "Did not receive all messages";

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006, 2007, 2008, Google 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 Google Inc. nor the names of its
 * contributors 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 "config.h"
#include "platform/fonts/harfbuzz/FontPlatformDataHarfBuzz.h"

#include "RuntimeEnabledFeatures.h"
#include "SkTypeface.h"
#include "platform/LayoutTestSupport.h"
#include "platform/NotImplemented.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/harfbuzz/HarfBuzzFace.h"

#include "public/platform/linux/WebFontInfo.h"
#include "public/platform/linux/WebFontRenderStyle.h"
#include "public/platform/linux/WebSandboxSupport.h"
#include "public/platform/Platform.h"
#include "wtf/text/WTFString.h"

namespace WebCore {

static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
static bool useSkiaAutoHint = true;
static bool useSkiaBitmaps = true;
static bool useSkiaAntiAlias = true;
static bool useSkiaSubpixelRendering = false;

void FontPlatformData::setHinting(SkPaint::Hinting hinting)
{
    skiaHinting = hinting;
}

void FontPlatformData::setAutoHint(bool useAutoHint)
{
    useSkiaAutoHint = useAutoHint;
}

void FontPlatformData::setUseBitmaps(bool useBitmaps)
{
    useSkiaBitmaps = useBitmaps;
}

void FontPlatformData::setAntiAlias(bool useAntiAlias)
{
    useSkiaAntiAlias = useAntiAlias;
}

void FontPlatformData::setSubpixelRendering(bool useSubpixelRendering)
{
    useSkiaSubpixelRendering = useSubpixelRendering;
}

FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
    : m_textSize(0)
    , m_syntheticBold(false)
    , m_syntheticItalic(false)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(true)
{
}

FontPlatformData::FontPlatformData()
    : m_textSize(0)
    , m_syntheticBold(false)
    , m_syntheticItalic(false)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(float textSize, bool syntheticBold, bool syntheticItalic)
    : m_textSize(textSize)
    , m_syntheticBold(syntheticBold)
    , m_syntheticItalic(syntheticItalic)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(const FontPlatformData& src)
    : m_typeface(src.m_typeface)
    , m_family(src.m_family)
    , m_textSize(src.m_textSize)
    , m_syntheticBold(src.m_syntheticBold)
    , m_syntheticItalic(src.m_syntheticItalic)
    , m_orientation(src.m_orientation)
    , m_style(src.m_style)
    , m_harfBuzzFace(nullptr)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family, float textSize, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, bool subpixelTextPosition)
    : m_typeface(tf)
    , m_family(family)
    , m_textSize(textSize)
    , m_syntheticBold(syntheticBold)
    , m_syntheticItalic(syntheticItalic)
    , m_orientation(orientation)
    , m_isHashTableDeletedValue(false)
{
    querySystemForRenderStyle(subpixelTextPosition);
}

FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    : m_typeface(src.m_typeface)
    , m_family(src.m_family)
    , m_textSize(textSize)
    , m_syntheticBold(src.m_syntheticBold)
    , m_syntheticItalic(src.m_syntheticItalic)
    , m_orientation(src.m_orientation)
    , m_harfBuzzFace(nullptr)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
    querySystemForRenderStyle(FontDescription::subpixelPositioning());
}

FontPlatformData::~FontPlatformData()
{
}

FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
{
    m_typeface = src.m_typeface;
    m_family = src.m_family;
    m_textSize = src.m_textSize;
    m_syntheticBold = src.m_syntheticBold;
    m_syntheticItalic = src.m_syntheticItalic;
    m_harfBuzzFace = nullptr;
    m_orientation = src.m_orientation;
    m_style = src.m_style;
#if OS(WIN)
    m_minSizeForAntiAlias = src.m_minSizeForAntiAlias;
#endif

    return *this;
}

#ifndef NDEBUG
String FontPlatformData::description() const
{
    return String();
}
#endif

void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext*) const
{
    paint->setAntiAlias(m_style.useAntiAlias);
    paint->setHinting(static_cast<SkPaint::Hinting>(m_style.hintStyle));
    paint->setEmbeddedBitmapText(m_style.useBitmaps);
    paint->setAutohinted(m_style.useAutoHint);
    if (m_style.useAntiAlias)
        paint->setLCDRenderText(m_style.useSubpixelRendering);

    // TestRunner specifically toggles the subpixel positioning flag.
    if (RuntimeEnabledFeatures::subpixelFontScalingEnabled() && !isRunningLayoutTest())
        paint->setSubpixelText(true);
    else
        paint->setSubpixelText(m_style.useSubpixelPositioning);

    const float ts = m_textSize >= 0 ? m_textSize : 12;
    paint->setTextSize(SkFloatToScalar(ts));
    paint->setTypeface(m_typeface.get());
    paint->setFakeBoldText(m_syntheticBold);
    paint->setTextSkewX(m_syntheticItalic ? -SK_Scalar1 / 4 : 0);
}

SkFontID FontPlatformData::uniqueID() const
{
    return m_typeface->uniqueID();
}

String FontPlatformData::fontFamilyName() const
{
    // FIXME(crbug.com/326582): come up with a proper way of handling SVG.
    if (!this->typeface())
        return "";
    SkTypeface::LocalizedStrings* fontFamilyIterator = this->typeface()->createFamilyNameIterator();
    SkTypeface::LocalizedString localizedString;
    while (fontFamilyIterator->next(&localizedString) && !localizedString.fString.size()) { }
    fontFamilyIterator->unref();
    return String(localizedString.fString.c_str());
}

bool FontPlatformData::operator==(const FontPlatformData& a) const
{
    // If either of the typeface pointers are null then we test for pointer
    // equality. Otherwise, we call SkTypeface::Equal on the valid pointers.
    bool typefacesEqual;
    if (!m_typeface || !a.m_typeface)
        typefacesEqual = m_typeface == a.m_typeface;
    else
        typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get());

    return typefacesEqual
        && m_textSize == a.m_textSize
        && m_syntheticBold == a.m_syntheticBold
        && m_syntheticItalic == a.m_syntheticItalic
        && m_orientation == a.m_orientation
        && m_style == a.m_style
        && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue;
}

bool FontPlatformData::isFixedPitch() const
{
    notImplemented();
    return false;
}

HarfBuzzFace* FontPlatformData::harfBuzzFace() const
{
    if (!m_harfBuzzFace)
        m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID());

    return m_harfBuzzFace.get();
}

void FontPlatformData::getRenderStyleForStrike(const char* font, int sizeAndStyle)
{
    blink::WebFontRenderStyle style;

#if OS(ANDROID)
    style.setDefaults();
#else
    if (!font || !*font)
        style.setDefaults(); // It's probably a webfont. Take the system defaults.
    else if (blink::Platform::current()->sandboxSupport())
        blink::Platform::current()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
    else
        blink::WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
#endif

    style.toFontRenderStyle(&m_style);
}

void FontPlatformData::querySystemForRenderStyle(bool useSkiaSubpixelPositioning)
{
    getRenderStyleForStrike(m_family.data(), (((int)m_textSize) << 2) | (m_typeface->style() & 3));

    // Fix FontRenderStyle::NoPreference to actual styles.
    if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
         m_style.useAntiAlias = useSkiaAntiAlias;

    if (!m_style.useHinting)
        m_style.hintStyle = SkPaint::kNo_Hinting;
    else if (m_style.useHinting == FontRenderStyle::NoPreference)
        m_style.hintStyle = skiaHinting;

    if (m_style.useBitmaps == FontRenderStyle::NoPreference)
        m_style.useBitmaps = useSkiaBitmaps;
    if (m_style.useAutoHint == FontRenderStyle::NoPreference)
        m_style.useAutoHint = useSkiaAutoHint;
    if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
        m_style.useAntiAlias = useSkiaAntiAlias;
    if (m_style.useSubpixelRendering == FontRenderStyle::NoPreference)
        m_style.useSubpixelRendering = useSkiaSubpixelRendering;

    // TestRunner specifically toggles the subpixel positioning flag.
    if (m_style.useSubpixelPositioning == FontRenderStyle::NoPreference
        || isRunningLayoutTest())
        m_style.useSubpixelPositioning = useSkiaSubpixelPositioning;
}

bool FontPlatformData::defaultUseSubpixelPositioning()
{
    return FontDescription::subpixelPositioning();
}

} // namespace WebCore
<commit_msg>Implement FontPlatformData::isFixedPitch for linux<commit_after>/*
 * Copyright (c) 2006, 2007, 2008, Google 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 Google Inc. nor the names of its
 * contributors 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 "config.h"
#include "platform/fonts/harfbuzz/FontPlatformDataHarfBuzz.h"

#include "RuntimeEnabledFeatures.h"
#include "SkTypeface.h"
#include "platform/LayoutTestSupport.h"
#include "platform/NotImplemented.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/harfbuzz/HarfBuzzFace.h"

#include "public/platform/linux/WebFontInfo.h"
#include "public/platform/linux/WebFontRenderStyle.h"
#include "public/platform/linux/WebSandboxSupport.h"
#include "public/platform/Platform.h"
#include "wtf/text/WTFString.h"

namespace WebCore {

static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
static bool useSkiaAutoHint = true;
static bool useSkiaBitmaps = true;
static bool useSkiaAntiAlias = true;
static bool useSkiaSubpixelRendering = false;

void FontPlatformData::setHinting(SkPaint::Hinting hinting)
{
    skiaHinting = hinting;
}

void FontPlatformData::setAutoHint(bool useAutoHint)
{
    useSkiaAutoHint = useAutoHint;
}

void FontPlatformData::setUseBitmaps(bool useBitmaps)
{
    useSkiaBitmaps = useBitmaps;
}

void FontPlatformData::setAntiAlias(bool useAntiAlias)
{
    useSkiaAntiAlias = useAntiAlias;
}

void FontPlatformData::setSubpixelRendering(bool useSubpixelRendering)
{
    useSkiaSubpixelRendering = useSubpixelRendering;
}

FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
    : m_textSize(0)
    , m_syntheticBold(false)
    , m_syntheticItalic(false)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(true)
{
}

FontPlatformData::FontPlatformData()
    : m_textSize(0)
    , m_syntheticBold(false)
    , m_syntheticItalic(false)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(float textSize, bool syntheticBold, bool syntheticItalic)
    : m_textSize(textSize)
    , m_syntheticBold(syntheticBold)
    , m_syntheticItalic(syntheticItalic)
    , m_orientation(Horizontal)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(const FontPlatformData& src)
    : m_typeface(src.m_typeface)
    , m_family(src.m_family)
    , m_textSize(src.m_textSize)
    , m_syntheticBold(src.m_syntheticBold)
    , m_syntheticItalic(src.m_syntheticItalic)
    , m_orientation(src.m_orientation)
    , m_style(src.m_style)
    , m_harfBuzzFace(nullptr)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
}

FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family, float textSize, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, bool subpixelTextPosition)
    : m_typeface(tf)
    , m_family(family)
    , m_textSize(textSize)
    , m_syntheticBold(syntheticBold)
    , m_syntheticItalic(syntheticItalic)
    , m_orientation(orientation)
    , m_isHashTableDeletedValue(false)
{
    querySystemForRenderStyle(subpixelTextPosition);
}

FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    : m_typeface(src.m_typeface)
    , m_family(src.m_family)
    , m_textSize(textSize)
    , m_syntheticBold(src.m_syntheticBold)
    , m_syntheticItalic(src.m_syntheticItalic)
    , m_orientation(src.m_orientation)
    , m_harfBuzzFace(nullptr)
    , m_isHashTableDeletedValue(false)
#if OS(WIN)
    , m_minSizeForAntiAlias(0)
#endif
{
    querySystemForRenderStyle(FontDescription::subpixelPositioning());
}

FontPlatformData::~FontPlatformData()
{
}

FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
{
    m_typeface = src.m_typeface;
    m_family = src.m_family;
    m_textSize = src.m_textSize;
    m_syntheticBold = src.m_syntheticBold;
    m_syntheticItalic = src.m_syntheticItalic;
    m_harfBuzzFace = nullptr;
    m_orientation = src.m_orientation;
    m_style = src.m_style;
#if OS(WIN)
    m_minSizeForAntiAlias = src.m_minSizeForAntiAlias;
#endif

    return *this;
}

#ifndef NDEBUG
String FontPlatformData::description() const
{
    return String();
}
#endif

void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext*) const
{
    paint->setAntiAlias(m_style.useAntiAlias);
    paint->setHinting(static_cast<SkPaint::Hinting>(m_style.hintStyle));
    paint->setEmbeddedBitmapText(m_style.useBitmaps);
    paint->setAutohinted(m_style.useAutoHint);
    if (m_style.useAntiAlias)
        paint->setLCDRenderText(m_style.useSubpixelRendering);

    // TestRunner specifically toggles the subpixel positioning flag.
    if (RuntimeEnabledFeatures::subpixelFontScalingEnabled() && !isRunningLayoutTest())
        paint->setSubpixelText(true);
    else
        paint->setSubpixelText(m_style.useSubpixelPositioning);

    const float ts = m_textSize >= 0 ? m_textSize : 12;
    paint->setTextSize(SkFloatToScalar(ts));
    paint->setTypeface(m_typeface.get());
    paint->setFakeBoldText(m_syntheticBold);
    paint->setTextSkewX(m_syntheticItalic ? -SK_Scalar1 / 4 : 0);
}

SkFontID FontPlatformData::uniqueID() const
{
    return m_typeface->uniqueID();
}

String FontPlatformData::fontFamilyName() const
{
    // FIXME(crbug.com/326582): come up with a proper way of handling SVG.
    if (!this->typeface())
        return "";
    SkTypeface::LocalizedStrings* fontFamilyIterator = this->typeface()->createFamilyNameIterator();
    SkTypeface::LocalizedString localizedString;
    while (fontFamilyIterator->next(&localizedString) && !localizedString.fString.size()) { }
    fontFamilyIterator->unref();
    return String(localizedString.fString.c_str());
}

bool FontPlatformData::operator==(const FontPlatformData& a) const
{
    // If either of the typeface pointers are null then we test for pointer
    // equality. Otherwise, we call SkTypeface::Equal on the valid pointers.
    bool typefacesEqual;
    if (!m_typeface || !a.m_typeface)
        typefacesEqual = m_typeface == a.m_typeface;
    else
        typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get());

    return typefacesEqual
        && m_textSize == a.m_textSize
        && m_syntheticBold == a.m_syntheticBold
        && m_syntheticItalic == a.m_syntheticItalic
        && m_orientation == a.m_orientation
        && m_style == a.m_style
        && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue;
}

bool FontPlatformData::isFixedPitch() const
{
    return typeface() && typeface()->isFixedPitch();
}

HarfBuzzFace* FontPlatformData::harfBuzzFace() const
{
    if (!m_harfBuzzFace)
        m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID());

    return m_harfBuzzFace.get();
}

void FontPlatformData::getRenderStyleForStrike(const char* font, int sizeAndStyle)
{
    blink::WebFontRenderStyle style;

#if OS(ANDROID)
    style.setDefaults();
#else
    if (!font || !*font)
        style.setDefaults(); // It's probably a webfont. Take the system defaults.
    else if (blink::Platform::current()->sandboxSupport())
        blink::Platform::current()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
    else
        blink::WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
#endif

    style.toFontRenderStyle(&m_style);
}

void FontPlatformData::querySystemForRenderStyle(bool useSkiaSubpixelPositioning)
{
    getRenderStyleForStrike(m_family.data(), (((int)m_textSize) << 2) | (m_typeface->style() & 3));

    // Fix FontRenderStyle::NoPreference to actual styles.
    if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
         m_style.useAntiAlias = useSkiaAntiAlias;

    if (!m_style.useHinting)
        m_style.hintStyle = SkPaint::kNo_Hinting;
    else if (m_style.useHinting == FontRenderStyle::NoPreference)
        m_style.hintStyle = skiaHinting;

    if (m_style.useBitmaps == FontRenderStyle::NoPreference)
        m_style.useBitmaps = useSkiaBitmaps;
    if (m_style.useAutoHint == FontRenderStyle::NoPreference)
        m_style.useAutoHint = useSkiaAutoHint;
    if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
        m_style.useAntiAlias = useSkiaAntiAlias;
    if (m_style.useSubpixelRendering == FontRenderStyle::NoPreference)
        m_style.useSubpixelRendering = useSkiaSubpixelRendering;

    // TestRunner specifically toggles the subpixel positioning flag.
    if (m_style.useSubpixelPositioning == FontRenderStyle::NoPreference
        || isRunningLayoutTest())
        m_style.useSubpixelPositioning = useSkiaSubpixelPositioning;
}

bool FontPlatformData::defaultUseSubpixelPositioning()
{
    return FontDescription::subpixelPositioning();
}

} // namespace WebCore
<|endoftext|>


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

/**
 * mapping to s3
 * directory:
 *   - empty object with the name of the dir, e.g. /testdir
 *   - metadata:
 *     - dir : 1
 *     - mode_t : int
 *     - gid : int
 *     - oid : int
 * file:
 *  - object with the path/name of the file, e.g. /testdir/testfile
 *  - metadata:
 *     - file: 1
 *     - mode_t : int
 *     - gid : int
 *     - oid : int
 */
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <sys/stat.h>
#include <map>
#include <sstream>

#define _FILE_OFFSET_BITS 64
#define FUSE_USE_VERSION  26
#include <fuse.h>
#include <libaws/aws.h>

using namespace aws;

static AWSConnectionFactory* theFactory;
static std::string theAccessKeyId;
static std::string theSecretAccessKey;
static std::string BUCKETNAME("msb");

/**
 * accessor and release functions for S3 Connection objects
 */
static S3ConnectionPtr getConnection() {
  return theFactory->createS3Connection(theAccessKeyId, theSecretAccessKey);
}

static void releaseConnection(const S3ConnectionPtr& aConnection) {
}

/**
 * macro that should be used to exit a function
 * it releases the connection object used in the function and returns with the given return code
 */
#define S3FS_EXIT(code) \
  releaseConnection(lCon); \
  return code;

/**
 * macros that should be used for try-catch combinations
 */
#define S3FS_TRY try {

#ifndef NDEBUG
#  define S3FS_CATCH(kind) \
    } catch (kind ## Exception & s3Exception) { \
      std::cerr << s3Exception.getErrorMessage() << std::endl; \
      S3FS_EXIT(-ENOENT); \
    } catch (AWSConnectionException & conException) { \
      std::cerr << conException.what() << std::endl; \
      S3FS_EXIT(-ECONNREFUSED); \
    }
#else
#  define S3FS_CATCH(kind) \
    } catch (kind ## Exception & s3Exception) { \
      std::cerr << s3Exception.what() << std::endl; \
      S3FS_EXIT(-ENOENT); \
    } catch (AWSConnectionException & conException) { \
      std::cerr << conException.what() << std::endl; \
      S3FS_EXIT(-ECONNREFUSED); \
    }
#endif

// shorcuts
typedef std::map<std::string, std::string> map_t;
typedef std::pair<std::string, std::string> pair_t;

/**
 * helper functions
 */
static mode_t
to_int(const std::string s)
{
  return (mode_t) atoi(s.c_str());
}

static std::string
to_string(int i)
{
  std::stringstream s;
  s << i;
  return s.str();
}

static void
fill_stat(map_t& aMap, struct stat* stbuf, long long aContentLength)
{
  stbuf->st_mode |= to_int(aMap["mode"]);
  stbuf->st_gid  |= to_int(aMap["gid"]);
  stbuf->st_uid  |= to_int(aMap["uid"]);

  if (aMap.count("dir") != 0) {
    stbuf->st_mode |= S_IFDIR;
  } else if (aMap.count("file") != 0) {
    stbuf->st_mode |= S_IFREG;
    stbuf->st_size = 5;
  }
  // TODO date
}

/**
 * operation functions
 */
static int
s3_getattr(const char *path, struct stat *stbuf)
{
#ifndef NDEBUG
  std::cerr << "getattr path: " << path << std::endl;
#endif

  // we always immediately exit if the root dir is requested.
  if (strcmp(path, "/") == 0) { /* The root directory of our file system. */
    stbuf->st_mode = S_IFDIR | 0777;
    stbuf->st_nlink = 3;
    return 0;
  }

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY
    memset(stbuf, 0, sizeof(struct stat));

    // check if we have that path
    HeadResponsePtr lRes;
    lRes = lCon->head(BUCKETNAME, path);
    map_t lMap = lRes->getMetaData();
#ifndef NDEBUG
    std::cerr << "  requested metadata for " << path << std::endl;
    for (map_t::iterator lIter = lMap.begin(); lIter != lMap.end(); ++lIter) {
      std::cerr << "    got " << (*lIter).first << " : " << (*lIter).second << std::endl;
    }
    std::cerr << "    content-length: " << lRes->getContentLength() << std::endl;
#endif

    // set the meta data in the stat struct
    fill_stat(lMap, stbuf, lRes->getContentLength());

    S3FS_EXIT(0);
  S3FS_CATCH(Head)
}

static int
s3_mkdir(const char *path, mode_t mode)
{
#ifndef NDEBUG
  std::cerr << "mkdir: " << path << std::endl;
  std::cerr << "  mode: " << mode << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY
    map_t lDirMap;
    lDirMap.insert(pair_t("dir", "1"));
    lDirMap.insert(pair_t("gid", to_string(getgid())));
    lDirMap.insert(pair_t("uid", to_string(getuid())));
    lDirMap.insert(pair_t("mode", to_string(mode)));
    PutResponsePtr lRes = lCon->put(BUCKETNAME, path, 0, "text/plain", 0, &lDirMap);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
  S3FS_EXIT(-ENOENT);
}

static int
s3_rmdir(const char *path)
{
#ifndef NDEBUG
  std::cerr << "rmdir: " << path << std::endl;
#endif
  S3ConnectionPtr lCon = getConnection();

  try {
    HeadResponsePtr lRes;
    lRes = lCon->head(BUCKETNAME, path);
    map_t lMap = lRes->getMetaData();
    if (lMap.count("dir") == 0) {
#ifndef NDEBUG
      std::cerr << " not a directory" << std::endl;
#endif
      S3FS_EXIT(-ENOTTY);
    }
  } catch (HeadException &e) {
    if (e.getErrorCode() == aws::S3Exception::NoSuchKey) {
#ifndef NDEBUG
      std::cerr << " no such key" << std::endl;
#endif
      S3FS_EXIT(-ENOENT);
    }
#ifndef NDEBU
    std::cerr << " something unexpected happened: " << e.getErrorMessage() << std::endl;
#endif
    S3FS_EXIT(-ENOENT);
  }

  S3FS_TRY
    DeleteResponsePtr lRes = lCon->del(BUCKETNAME, path);
  S3FS_CATCH(Put)
  S3FS_EXIT(0);
}

static int
s3_readdir(const char *path,
           void *buf,
           fuse_fill_dir_t filler,
           off_t offset,
           struct fuse_file_info *fi)
{
#ifndef NDEBUG
  std::cerr << "readdir: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();

  filler(buf, ".", NULL, 0);
  filler(buf, "..", NULL, 0);

  // TODO handle full buffer by remembering the marker

  std::string lPath(path);
  if (lPath.at(lPath.length()-1) != '/')
    lPath += "/";

  ListBucketResponsePtr lRes;
  S3FS_TRY
    std::string lMarker;
    do {
      lRes = lCon->listBucket(BUCKETNAME, lPath, lMarker, "/", -1);
      lRes->open();
      ListBucketResponse::Object o;
      while (lRes->next(o)) {
        struct stat lStat;
        memset(&lStat, 0, sizeof(struct stat));

#ifndef NDEBUG
        std::cerr << "  result: " << o.KeyValue << std::endl;
#endif
        std::string lTmp = o.KeyValue.replace(0, lPath.length(), "");
        filler(buf, lTmp.c_str(), &lStat, 0);
        lMarker = o.KeyValue;
      }
      lRes->close();
    } while (lRes->isTruncated());

    S3FS_EXIT(0);
  S3FS_CATCH(ListBucket);

  S3FS_EXIT(-ENOENT);
}

static int
s3_create(const char *path, mode_t mode, struct fuse_file_info *fs)
{
#ifndef NDEBUG
  std::cerr << "create: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY
    map_t lDirMap;
    lDirMap.insert(pair_t("file", "1"));
    lDirMap.insert(pair_t("gid", to_string(getgid())));
    lDirMap.insert(pair_t("uid", to_string(getuid())));
    lDirMap.insert(pair_t("mode", to_string(mode)));
    PutResponsePtr lRes = lCon->put(BUCKETNAME, path, 0, "text/plain", 0, &lDirMap);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
  S3FS_EXIT(-ENOENT);
}

// open, write, release
// always use a temporary file

static int
s3_read(const char *path,
        char *buf,
        size_t size,
        off_t offset,
        struct fuse_file_info *fi)
{
#ifndef NDEBUG
  std::cerr << "read: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  memcpy(buf, "test\n", 5); /* Provide the content. */
  return 5;
#if 0
  GetResponsePtr lRes;
  S3FS_TRY
    lRes = lCon->get(BUCKETNAME, path);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
#endif
}

#if 0
static int
s3_release(const char *path, struct fuse_file_info *fi)
{
  fprintf(stderr, "release path: '%s'\n", path);

  S3ConnectionPtr lCon = getConnection();
  S3FS_EXIT(0);
}

static int
s3_opendir(const char *path, struct fuse_file_info *fi)
{
  fprintf(stderr, "opendir: '%s'\n", path);

  S3ConnectionPtr lCon = getConnection();
  S3FS_EXIT(0);
}
#endif

static struct fuse_operations s3_filesystem_operations;

int
main(int argc, char **argv)
{
  // set callback functions
  s3_filesystem_operations.getattr    = s3_getattr;
  s3_filesystem_operations.mkdir      = s3_mkdir;
  s3_filesystem_operations.rmdir      = s3_rmdir;
  s3_filesystem_operations.readdir    = s3_readdir;
  s3_filesystem_operations.create     = s3_create;
  // can't be supported because s3 doesn't allow to change meta data without putting the object again
  s3_filesystem_operations.read       = s3_read;

  // initialization
  theFactory = AWSConnectionFactory::getInstance();

  theAccessKeyId = getenv("AWS_ACCESS_KEY");
  theSecretAccessKey = getenv("AWS_SECRET_ACCESS_KEY");

  if (theAccessKeyId.length() == 0) {
    std::cerr << "Please specify the AWS_ACCESS_KEY environment variable" << std::endl;
    return 1;
  }
  if (theSecretAccessKey.length() == 0) {
    std::cerr << "Please specify the AWS_SECRET_ACCESS_KEY environment variable" << std::endl;
    return 2;
  }

  // let's get started
  return fuse_main(argc, argv, &s3_filesystem_operations, NULL);
}
<commit_msg>fix s3fs for linux<commit_after>/*
 * Copyright 2008 28msec, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * mapping to s3
 * directory:
 *   - empty object with the name of the dir, e.g. /testdir
 *   - metadata:
 *     - dir : 1
 *     - mode_t : int
 *     - gid : int
 *     - oid : int
 * file:
 *  - object with the path/name of the file, e.g. /testdir/testfile
 *  - metadata:
 *     - file: 1
 *     - mode_t : int
 *     - gid : int
 *     - oid : int
 */
#define _FILE_OFFSET_BITS 64
#define FUSE_USE_VERSION  26
#include <fuse.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <sys/stat.h>
#include <map>
#include <sstream>

#include <libaws/aws.h>

using namespace aws;

static AWSConnectionFactory* theFactory;
static std::string theAccessKeyId;
static std::string theSecretAccessKey;
static std::string BUCKETNAME("msb");

/**
 * accessor and release functions for S3 Connection objects
 */
static S3ConnectionPtr getConnection() {
  return theFactory->createS3Connection(theAccessKeyId, theSecretAccessKey);
}

static void releaseConnection(const S3ConnectionPtr& aConnection) {
}

/**
 * macro that should be used to exit a function
 * it releases the connection object used in the function and returns with the given return code
 */
#define S3FS_EXIT(code) \
  releaseConnection(lCon); \
  return code;

/**
 * macros that should be used for try-catch combinations
 */
#define S3FS_TRY try {

#ifndef NDEBUG
#  define S3FS_CATCH(kind) \
    } catch (kind ## Exception & s3Exception) { \
      std::cerr << s3Exception.getErrorMessage() << std::endl; \
      S3FS_EXIT(-ENOENT); \
    } catch (AWSConnectionException & conException) { \
      std::cerr << conException.what() << std::endl; \
      S3FS_EXIT(-ECONNREFUSED); \
    }
#else
#  define S3FS_CATCH(kind) \
    } catch (kind ## Exception & s3Exception) { \
      std::cerr << s3Exception.what() << std::endl; \
      S3FS_EXIT(-ENOENT); \
    } catch (AWSConnectionException & conException) { \
      std::cerr << conException.what() << std::endl; \
      S3FS_EXIT(-ECONNREFUSED); \
    }
#endif

// shorcuts
typedef std::map<std::string, std::string> map_t;
typedef std::pair<std::string, std::string> pair_t;

/**
 * helper functions
 */
static mode_t
to_int(const std::string s)
{
  return (mode_t) atoi(s.c_str());
}

static std::string
to_string(int i)
{
  std::stringstream s;
  s << i;
  return s.str();
}

static void
fill_stat(map_t& aMap, struct stat* stbuf, long long aContentLength)
{
  stbuf->st_mode |= to_int(aMap["mode"]);
  stbuf->st_gid  |= to_int(aMap["gid"]);
  stbuf->st_uid  |= to_int(aMap["uid"]);

  if (aMap.count("dir") != 0) {
    stbuf->st_mode |= S_IFDIR;
    stbuf->st_nlink = 1;
  } else if (aMap.count("file") != 0) {
    stbuf->st_mode |= S_IFREG;
    stbuf->st_nlink = 1;
    stbuf->st_size = 5;
  }
  // TODO date
}

/**
 * operation functions
 */
static int
s3_getattr(const char *path, struct stat *stbuf)
{
#ifndef NDEBUG
  std::cerr << "getattr path: " << path << std::endl;
#endif

  memset(stbuf, 0, sizeof(struct stat));

  // we always immediately exit if the root dir is requested.
  if (strcmp(path, "/") == 0) { /* The root directory of our file system. */
    stbuf->st_mode = S_IFDIR | 0755;
    stbuf->st_nlink = 2;
#ifndef NDEBUG
    std::cerr << "  requested getattr for /" << std::endl;
#endif
    return 0;
  }

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY

    // check if we have that path
    HeadResponsePtr lRes;
    lRes = lCon->head(BUCKETNAME, path);
    map_t lMap = lRes->getMetaData();
#ifndef NDEBUG
    std::cerr << "  requested metadata for " << path << std::endl;
    for (map_t::iterator lIter = lMap.begin(); lIter != lMap.end(); ++lIter) {
      std::cerr << "    got " << (*lIter).first << " : " << (*lIter).second << std::endl;
    }
    std::cerr << "    content-length: " << lRes->getContentLength() << std::endl;
#endif

    // set the meta data in the stat struct
    fill_stat(lMap, stbuf, lRes->getContentLength());

    S3FS_EXIT(0);
  S3FS_CATCH(Head)
}

static int
s3_mkdir(const char *path, mode_t mode)
{
#ifndef NDEBUG
  std::cerr << "mkdir: " << path << std::endl;
  std::cerr << "  mode: " << mode << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY
    map_t lDirMap;
    lDirMap.insert(pair_t("dir", "1"));
    lDirMap.insert(pair_t("gid", to_string(getgid())));
    lDirMap.insert(pair_t("uid", to_string(getuid())));
    lDirMap.insert(pair_t("mode", to_string(mode)));
    PutResponsePtr lRes = lCon->put(BUCKETNAME, path, 0, "text/plain", 0, &lDirMap);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
  S3FS_EXIT(-ENOENT);
}

static int
s3_rmdir(const char *path)
{
#ifndef NDEBUG
  std::cerr << "rmdir: " << path << std::endl;
#endif
  S3ConnectionPtr lCon = getConnection();

  try {
    HeadResponsePtr lRes;
    lRes = lCon->head(BUCKETNAME, path);
    map_t lMap = lRes->getMetaData();
    if (lMap.count("dir") == 0) {
#ifndef NDEBUG
      std::cerr << " not a directory" << std::endl;
#endif
      S3FS_EXIT(-ENOTTY);
    }
  } catch (HeadException &e) {
    if (e.getErrorCode() == aws::S3Exception::NoSuchKey) {
#ifndef NDEBUG
      std::cerr << " no such key" << std::endl;
#endif
      S3FS_EXIT(-ENOENT);
    }
#ifndef NDEBU
    std::cerr << " something unexpected happened: " << e.getErrorMessage() << std::endl;
#endif
    S3FS_EXIT(-ENOENT);
  }

  S3FS_TRY
    DeleteResponsePtr lRes = lCon->del(BUCKETNAME, path);
  S3FS_CATCH(Put)
  S3FS_EXIT(0);
}

static int
s3_readdir(const char *path,
           void *buf,
           fuse_fill_dir_t filler,
           off_t offset,
           struct fuse_file_info *fi)
{
#ifndef NDEBUG
  std::cerr << "readdir: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();

  filler(buf, ".", NULL, 0);
  filler(buf, "..", NULL, 0);

  // TODO handle full buffer by remembering the marker

  std::string lPath(path);
  if (lPath.at(lPath.length()-1) != '/')
    lPath += "/";

  ListBucketResponsePtr lRes;
  S3FS_TRY
    std::string lMarker;
    do {
      lRes = lCon->listBucket(BUCKETNAME, lPath, lMarker, "/", -1);
      lRes->open();
      ListBucketResponse::Object o;
      while (lRes->next(o)) {
        struct stat lStat;
        memset(&lStat, 0, sizeof(struct stat));

#ifndef NDEBUG
        std::cerr << "  result: " << o.KeyValue << std::endl;
#endif
        std::string lTmp = o.KeyValue.replace(0, lPath.length(), "");
        filler(buf, lTmp.c_str(), NULL, 0);
        lMarker = o.KeyValue;
      }
      lRes->close();
    } while (lRes->isTruncated());

    S3FS_EXIT(0);
  S3FS_CATCH(ListBucket);

  S3FS_EXIT(-ENOENT);
}

static int
s3_create(const char *path, mode_t mode, struct fuse_file_info *fs)
{
#ifndef NDEBUG
  std::cerr << "create: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  S3FS_TRY
    map_t lDirMap;
    lDirMap.insert(pair_t("file", "1"));
    lDirMap.insert(pair_t("gid", to_string(getgid())));
    lDirMap.insert(pair_t("uid", to_string(getuid())));
    lDirMap.insert(pair_t("mode", to_string(mode)));
    PutResponsePtr lRes = lCon->put(BUCKETNAME, path, 0, "text/plain", 0, &lDirMap);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
  S3FS_EXIT(-ENOENT);
}

// open, write, release
// always use a temporary file

static int
s3_read(const char *path,
        char *buf,
        size_t size,
        off_t offset,
        struct fuse_file_info *fi)
{
#ifndef NDEBUG
  std::cerr << "read: " << path << std::endl;
#endif

  S3ConnectionPtr lCon = getConnection();
  memcpy(buf, "test\n", 5); /* Provide the content. */
  return 5;
#if 0
  GetResponsePtr lRes;
  S3FS_TRY
    lRes = lCon->get(BUCKETNAME, path);
    S3FS_EXIT(0);
  S3FS_CATCH(Put)
#endif
}

#if 0
static int
s3_release(const char *path, struct fuse_file_info *fi)
{
  fprintf(stderr, "release path: '%s'\n", path);

  S3ConnectionPtr lCon = getConnection();
  S3FS_EXIT(0);
}

static int
s3_opendir(const char *path, struct fuse_file_info *fi)
{
  fprintf(stderr, "opendir: '%s'\n", path);

  S3ConnectionPtr lCon = getConnection();
  S3FS_EXIT(0);
}
#endif

static struct fuse_operations s3_filesystem_operations;

int
main(int argc, char **argv)
{
  // set callback functions
  s3_filesystem_operations.getattr    = s3_getattr;
  s3_filesystem_operations.mkdir      = s3_mkdir;
  s3_filesystem_operations.rmdir      = s3_rmdir;
  s3_filesystem_operations.readdir    = s3_readdir;
  s3_filesystem_operations.create     = s3_create;
  // can't be supported because s3 doesn't allow to change meta data without putting the object again
  s3_filesystem_operations.read       = s3_read;

  // initialization
  theFactory = AWSConnectionFactory::getInstance();

  theAccessKeyId = getenv("AWS_ACCESS_KEY");
  theSecretAccessKey = getenv("AWS_SECRET_ACCESS_KEY");

  if (theAccessKeyId.length() == 0) {
    std::cerr << "Please specify the AWS_ACCESS_KEY environment variable" << std::endl;
    return 1;
  }
  if (theSecretAccessKey.length() == 0) {
    std::cerr << "Please specify the AWS_SECRET_ACCESS_KEY environment variable" << std::endl;
    return 2;
  }

  // let's get started
  return fuse_main(argc, argv, &s3_filesystem_operations, NULL);
}
<|endoftext|>


<commit_before>
// (c) COPYRIGHT URI/MIT 1995-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for the class TestStructure. See TestByte.cc
//
// jhrg 1/12/95

// $Log: TestSequence.cc,v $
// Revision 1.14  1996/08/13 20:50:47  jimg
// Changed definition of the read member function.
//
// Revision 1.13  1996/05/31 23:30:28  jimg
// Updated copyright notice.
//
// Revision 1.12  1996/05/29 22:08:50  jimg
// Made changes necessary to support CEs that return the value of a function
// instead of the value of a variable. This was done so that it would be
// possible to translate Sequences into Arrays without first reading the
// entire sequence over the network.
//
// Revision 1.11  1996/05/22 18:05:27  jimg
// Merged files from the old netio directory into the dap directory.
// Removed the errmsg library from the software.
//
// Revision 1.10  1996/04/05 00:21:58  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.9  1995/12/09  01:07:23  jimg
// Added changes so that relational operators will work properly for all the
// datatypes (including Sequences). The relational ops are evaluated in
// DDS::eval_constraint() after being parsed by DDS::parse_constraint().
//
// Revision 1.8  1995/12/06  19:55:26  jimg
// Changes read() member function from three arguments to two.
//
// Revision 1.7  1995/08/26  00:31:58  jimg
// Removed code enclosed in #ifdef NEVER #endif.
//
// Revision 1.6  1995/07/09  21:29:18  jimg
// Added copyright notice.
//
// Revision 1.5  1995/05/10  17:35:31  jimg
// Removed the header file `Test.h' from the Test*.cc implementation files.
//
// Revision 1.4  1995/03/04  14:38:08  jimg
// Modified these so that they fit with the changes in the DAP classes.
//
// Revision 1.3  1995/02/10  02:33:46  jimg
// Modified Test<class>.h and .cc so that they used to new definitions of
// read_val().
// Modified the classes read() so that they are more in line with the
// class library's intended use in a real subclass set.
//
// Revision 1.2  1995/01/19  21:59:00  jimg
// Added read_val from dummy_read.cc to the sample set of sub-class
// implementations.
// Changed the declaration of readVal in BaseType so that it names the
// mfunc read_val (to be consistant with the other mfunc names).
// Removed the unnecessary duplicate declaration of the abstract virtual
// mfuncs read and (now) read_val from the classes Byte, ... Grid. The
// declaration in BaseType is sufficient along with the decl and definition
// in the *.cc,h files which contain the subclasses for Byte, ..., Grid.
//
// Revision 1.1  1995/01/19  20:20:51  jimg
// Created as an example of subclassing the class hierarchy rooted at
// BaseType.
//

#ifdef _GNUG_
#pragma implementation
#endif

#include "TestSequence.h"

Sequence *
NewSequence(const String &n)
{
    return new TestSequence(n);
}

BaseType *
TestSequence::ptr_duplicate()
{
    return new TestSequence(*this);
}

TestSequence::TestSequence(const String &n) : Sequence(n)
{
}

TestSequence::~TestSequence()
{
}

bool
TestSequence::read(const String &, int &)
{
    if (read_p())
	return true;

    set_read_p(true);

    return true;
}

unsigned int
TestSequence::length()
{
    return 0;
}
<commit_msg>Changed return type of length member function.<commit_after>
// (c) COPYRIGHT URI/MIT 1995-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for the class TestStructure. See TestByte.cc
//
// jhrg 1/12/95

// $Log: TestSequence.cc,v $
// Revision 1.15  1997/07/15 21:54:57  jimg
// Changed return type of length member function.
//
// Revision 1.14  1996/08/13 20:50:47  jimg
// Changed definition of the read member function.
//
// Revision 1.13  1996/05/31 23:30:28  jimg
// Updated copyright notice.
//
// Revision 1.12  1996/05/29 22:08:50  jimg
// Made changes necessary to support CEs that return the value of a function
// instead of the value of a variable. This was done so that it would be
// possible to translate Sequences into Arrays without first reading the
// entire sequence over the network.
//
// Revision 1.11  1996/05/22 18:05:27  jimg
// Merged files from the old netio directory into the dap directory.
// Removed the errmsg library from the software.
//
// Revision 1.10  1996/04/05 00:21:58  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.9  1995/12/09  01:07:23  jimg
// Added changes so that relational operators will work properly for all the
// datatypes (including Sequences). The relational ops are evaluated in
// DDS::eval_constraint() after being parsed by DDS::parse_constraint().
//
// Revision 1.8  1995/12/06  19:55:26  jimg
// Changes read() member function from three arguments to two.
//
// Revision 1.7  1995/08/26  00:31:58  jimg
// Removed code enclosed in #ifdef NEVER #endif.
//
// Revision 1.6  1995/07/09  21:29:18  jimg
// Added copyright notice.
//
// Revision 1.5  1995/05/10  17:35:31  jimg
// Removed the header file `Test.h' from the Test*.cc implementation files.
//
// Revision 1.4  1995/03/04  14:38:08  jimg
// Modified these so that they fit with the changes in the DAP classes.
//
// Revision 1.3  1995/02/10  02:33:46  jimg
// Modified Test<class>.h and .cc so that they used to new definitions of
// read_val().
// Modified the classes read() so that they are more in line with the
// class library's intended use in a real subclass set.
//
// Revision 1.2  1995/01/19  21:59:00  jimg
// Added read_val from dummy_read.cc to the sample set of sub-class
// implementations.
// Changed the declaration of readVal in BaseType so that it names the
// mfunc read_val (to be consistant with the other mfunc names).
// Removed the unnecessary duplicate declaration of the abstract virtual
// mfuncs read and (now) read_val from the classes Byte, ... Grid. The
// declaration in BaseType is sufficient along with the decl and definition
// in the *.cc,h files which contain the subclasses for Byte, ..., Grid.
//
// Revision 1.1  1995/01/19  20:20:51  jimg
// Created as an example of subclassing the class hierarchy rooted at
// BaseType.
//

#ifdef _GNUG_
#pragma implementation
#endif

#include "TestSequence.h"

Sequence *
NewSequence(const String &n)
{
    return new TestSequence(n);
}

BaseType *
TestSequence::ptr_duplicate()
{
    return new TestSequence(*this);
}

TestSequence::TestSequence(const String &n) : Sequence(n)
{
}

TestSequence::~TestSequence()
{
}

bool
TestSequence::read(const String &, int &)
{
    if (read_p())
	return true;

    set_read_p(true);

    return true;
}

int
TestSequence::length()
{
    return 0;
}
<|endoftext|>


<commit_before>// PNM Reader -- Written by Eric Sokolowsky
// Reads Ascii and Binary files in the PPM, PGM, and PBM formats.

#include <osg/Image>
#include <osg/Notify>
#include <osg/Endian>

#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/fstream>

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

#include <sstream>

using namespace osg;

template <class T>
    unsigned char* read_bitmap_ascii(std::istream& fin, int width, int height)
{
    T* data = new T[width*height];

    T* dst = data;
    T* end = data + width*height;
    T value = 0;
    unsigned long num;

    while(dst < end)
    {
        // read in characters looking for '0's and '1's, these
        // values map to 255 and 0. Any other characters
        // are silently ignored.
        fin >> num;
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        if (num == 1)
        {
            value = 0;
            break;
        }
        else if (num == 0)
        {
            value = 255;
            break;
        }

        // place value in the image
        *(dst++) = value;
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_grayscale_ascii(std::istream& fin, int width, int height)
{
    T* data = new T[width*height];

    T* dst = data;
    T* end = data + width*height;
    T value = 0;
    unsigned long num;

    while(dst < end)
    {
        fin >> num;
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        // place value in the image
        *(dst++) = value;
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_color_ascii(std::istream& fin, int width, int height)
{
    T* data = new T[3*width*height];

    T* dst = data;
    T* end = data + 3*width*height;
    T value = 0;
    unsigned long num;

    while(dst < end)
    {
        fin >> num;
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        // place value in the image
        *(dst++) = value;
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_bitmap_binary(std::istream& fin, int width, int height)
{
    T* data = new T[width*height];

    for(int y = 0; y < height; y++)
    {
        T* dst = data + (y+0)*width;
        T* end = data + (y+1)*width;

        while(dst < end)
        {
            unsigned char b = (unsigned char) fin.get();
            if (!fin.good())
            {
                delete [] data;
                return NULL;
            }

            for(int i = 7; i >= 0 && dst < end; i--)
            {
                // 1 means black, 0 means white
                T data_value = (b & (1<<i)) ? 0 : 255;
                *(dst++) = data_value;
            }
        }
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_grayscale_binary(std::istream& fin, int width, int height)
{
    unsigned char* data = new unsigned char[sizeof(T)*width*height];

    fin.read((char*)data, sizeof(T)*width*height);
    if (!fin.good())
    {
        delete [] data;
        return NULL;
    }

    // if the machine is little endian swap the bytes around
    if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian)
    {
        for(int i = 0; i < width*height; i++)
        {
            unsigned char* bs = (unsigned char*)(&data[i]);
            std::swap(bs[0], bs[1]);
        }
    }

    return data;
}

template <class T>
    unsigned char* read_color_binary(std::istream& fin, int width, int height)
{
    unsigned char* data = new unsigned char[sizeof(T)*3*width*height];

    fin.read((char*)data, sizeof(T)*3*width*height);
    if (!fin.good())
    {
        delete [] data;
        return NULL;
    }

    // if the machine is little endian swap the bytes around
    if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian)
    {
        for(int i = 0; i < 3*width*height; i++)
        {
            unsigned char* bs = (unsigned char*)(&data[i]);
            std::swap(bs[0], bs[1]);
        }
    }

    return reinterpret_cast<unsigned char*>(data);
}

class ReaderWriterPNM : public osgDB::ReaderWriter
{
    public:
        ReaderWriterPNM()
        {
            supportsExtension("pnm","PNM Image format");
            supportsExtension("ppm","PNM Image format");
            supportsExtension("pgm","PNM Image format");
            supportsExtension("pbm","PNM Image format");
        }

        virtual const char* className() const { return "PNM Image Reader/Writer"; }

        virtual ReadResult readImage(std::istream& fin, const osgDB::ReaderWriter::Options* options=NULL) const
        {
            int ppmtype = 0;    /* P1, P2, etc. */
            int width = 0;
            int height = 0;
            int max_value = 0;

            // Read header items.
            std::string line;
            int row;
            for (row = 1; row <= 3; row++)
            {
                getline(fin, line);
                if (!fin.good())
                    return ReadResult::ERROR_IN_READING_FILE;

                const char *cp = line.c_str();
                while (*cp && isspace(*cp))
                    cp++;
                if (! *cp || *cp == '#')
                {
                    // Skip comment lines.
                    row--;
                }
                else if (row == 1)
                {
                    // Get the image type.
                    if (line[0] == 'p' || line[0] == 'P')
                    {
                        ppmtype = line[1] - '0';
                    }
                }
                else if (row == 2)
                {
                    std::istringstream istr(line);

                    istr >> width;
                    istr >> height;

                    // pbm files don't have row 3
                    if (ppmtype == 1 || ppmtype == 4)
                    {
                        max_value = 1;
                        break;
                    }
                }
                else if (row == 3)
                {
                    // Get the maximum value
                    std::istringstream istr(line);
                    istr >> max_value;
                }
            }

            // Check for valid values.
            if (width <= 0 || height <= 0 ||
                max_value <= 0 || max_value > 65535 ||
                ppmtype < 1 || ppmtype > 6)
            {
                return ReadResult::ERROR_IN_READING_FILE;
            }

            int pixelFormat = 0;
            int dataType = 0;
            unsigned char* data = NULL;

            if (max_value > 255)
            {
                OSG_NOTICE<<"OpenSceneGraph PPM reader: width="<<width<<" height="<<height<<std::endl;
                dataType = GL_UNSIGNED_SHORT;
                switch(ppmtype)
                {
                    case 1:    // bitmap ascii
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_ascii<unsigned short>(fin, width, height);
                        break;
                    case 2:    // grayscale ascii
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_ascii<unsigned short>(fin, width, height);
                        break;
                    case 3:    // color ascii
                        pixelFormat = GL_RGB;
                        data = read_color_ascii<unsigned short>(fin, width, height);
                        break;
                    case 4:    // bitmap binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_binary<unsigned short>(fin, width, height);
                        break;
                    case 5:    // grayscale binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_binary<unsigned short>(fin, width, height);
                        break;
                    case 6:    // color binary
                        pixelFormat = GL_RGB;
                        data = read_color_binary<unsigned short>(fin, width, height);
                        break;
                }
            }
            else
            {
                dataType = GL_UNSIGNED_BYTE;
                switch(ppmtype)
                {
                    case 1:    // bitmap ascii
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_ascii<unsigned char>(fin, width, height);
                        break;
                    case 2:    // grayscale ascii
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_ascii<unsigned char>(fin, width, height);
                        break;
                    case 3:    // color ascii
                        pixelFormat = GL_RGB;
                        data = read_color_ascii<unsigned char>(fin, width, height);
                        break;
                    case 4:    // bitmap binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_binary<unsigned char>(fin, width, height);
                        break;
                    case 5:    // grayscale binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_binary<unsigned char>(fin, width, height);
                        break;
                    case 6:    // color binary
                        pixelFormat = GL_RGB;
                        data = read_color_binary<unsigned char>(fin, width, height);
                        break;
                }
            }

            if (data == NULL)
            {
                return ReadResult::FILE_NOT_HANDLED;
            }

            osg::Image* pOsgImage = new osg::Image();

            pOsgImage->setImage(width, height, 1,
                pixelFormat,
                pixelFormat,
                dataType,
                data,
                osg::Image::USE_NEW_DELETE);

            if (options && options->getOptionString().find("flip")!=std::string::npos)
            {
                pOsgImage->flipVertical();
            }

            return pOsgImage;
        }

        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            std::ifstream fin(fileName.c_str());
            if (!fin.good())
                return ReadResult::ERROR_IN_READING_FILE;

            ReadResult rr = readImage(fin, options);
            fin.close();
            if (rr.validImage()) rr.getImage()->setFileName(file);
            return rr;
        }

        virtual WriteResult writeImage(const osg::Image& image,std::ostream& fout,const osgDB::ReaderWriter::Options* options) const
        {
            bool ascii = (options && options->getOptionString().find("ascii")!=std::string::npos);

            if (ascii)
            {
                // ascii ppm format.
                fout<<"P3"<<std::endl;
                fout<<image.s()<<" "<<image.t()<<std::endl;
                fout<<"255"<<std::endl;
                for(int row = image.t()-1; row >= 0; --row)
                {
                    const unsigned char* ptr = image.data(0,row);
                    for(int col = 0; col < image.s(); ++col)
                    {
                        fout<<static_cast<int>(*(ptr++));
                        fout<<" "<<static_cast<int>(*(ptr++));
                        fout<<" "<<static_cast<int>(*(ptr++))<<"  ";
                    }
                    fout<<std::endl;
                }
            }
            else
            {
                // binary ppm format
                fout<<"P6"<<std::endl;
                fout<<image.s()<<" "<<image.t()<<std::endl;
                fout<<"255"<<std::endl;
                for(int row = image.t()-1; row >= 0; --row)
                {
                    const unsigned char* ptr = image.data(0,row);
                    for(int col = 0; col < image.s(); ++col)
                    {
                        fout.put(*(ptr++));
                        fout.put(*(ptr++));
                        fout.put(*(ptr++));
                    }
                }
            }
            return WriteResult::FILE_SAVED;
        }

        virtual WriteResult writeImage(const osg::Image& image,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
        {
            // Only ppm format output supported
            std::string ext = osgDB::getFileExtension(fileName);
            if ( !osgDB::equalCaseInsensitive(ext, "ppm") ) return WriteResult::FILE_NOT_HANDLED;

            // only support rgb images right now.
            if (image.getPixelFormat()!=GL_RGB || image.getDataType()!=GL_UNSIGNED_BYTE) return WriteResult("Error image pixel format not supported by pnm writer.");

            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
            if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;

            return writeImage(image,fout,options);
        }

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(pnm, ReaderWriterPNM)
<commit_msg>From Eric Sokolowsky, "Attached is an updated PNM plugin for inclusion in both the trunk and for release version 2.8.5. The attached file fixes numerous bugs in reading 8-bit and 16-bit images, including loading the images upside-down. This file also incorporates trunk patch r12220 which updated the plugin for reading and writing images through streams instead of C-style FILE I/O."<commit_after>// PNM Reader -- Written by Eric Sokolowsky
// Reads Ascii and Binary files in the PPM, PGM, and PBM formats.

#include <osg/Image>
#include <osg/Notify>
#include <osg/Endian>

#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/fstream>

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

#include <sstream>

using namespace osg;

template <class T>
    unsigned char* read_bitmap_ascii(std::istream& fin, int width, int height)
{
    T* data = new T[width*height];

    {
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        {
        }
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
{
    T* data = new T[width*height];

    {
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        // place value in the image
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
{
    T* data = new T[3*width*height];

    {
        if (!fin.good())
        {
            delete [] data;
            return NULL;
        }

        // place value in the image
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_bitmap_binary(std::istream& fin, int width, int height)
{
    T* data = new T[width*height];

    {
        T* dst = data + (y+0)*width;
        T* end = data + (y+1)*width;

        while(dst < end)
        {
            unsigned char b = (unsigned char) fin.get();
            if (!fin.good())
            {
                delete [] data;
                return NULL;
            }

            for(int i = 7; i >= 0 && dst < end; i--)
            {
                // 1 means black, 0 means white
                T data_value = (b & (1<<i)) ? 0 : 255;
                *(dst++) = data_value;
            }
        }
    }

    return reinterpret_cast<unsigned char*>(data);
}

template <class T>
    unsigned char* read_grayscale_binary(std::istream& fin, int width, int height)
{

    {
    }

    // if the machine is little endian swap the bytes around
    if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian)
    {
        {
            std::swap(bs[0], bs[1]);
        }
    }

}

template <class T>
    unsigned char* read_color_binary(std::istream& fin, int width, int height)
{

    {
    }

    // if the machine is little endian swap the bytes around
    if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian)
    {
        {
            std::swap(bs[0], bs[1]);
        }
    }

    return reinterpret_cast<unsigned char*>(data);
}

class ReaderWriterPNM : public osgDB::ReaderWriter
{
    public:
        ReaderWriterPNM()
        {
            supportsExtension("pnm","PNM Image format");
            supportsExtension("ppm","PNM Image format");
            supportsExtension("pgm","PNM Image format");
            supportsExtension("pbm","PNM Image format");
        }

        virtual const char* className() const { return "PNM Image Reader/Writer"; }

        virtual ReadResult readImage(std::istream& fin, const osgDB::ReaderWriter::Options* options=NULL) const
        {
            int ppmtype = 0;    /* P1, P2, etc. */
            int width = 0;
            int height = 0;
            int max_value = 0;

            // Read header items.
            std::string line;
            int row;
            for (row = 1; row <= 3; row++)
            {
                getline(fin, line);
                if (!fin.good())
                    return ReadResult::ERROR_IN_READING_FILE;

                const char *cp = line.c_str();
                while (*cp && isspace(*cp))
                    cp++;
                if (! *cp || *cp == '#')
                {
                    // Skip comment lines.
                    row--;
                }
                else if (row == 1)
                {
                    // Get the image type.
                    if (line[0] == 'p' || line[0] == 'P')
                    {
                        ppmtype = line[1] - '0';
                    }
                }
                else if (row == 2)
                {
                    std::istringstream istr(line);

                    istr >> width;
                    istr >> height;

                    // pbm files don't have row 3
                    if (ppmtype == 1 || ppmtype == 4)
                    {
                        max_value = 1;
                        break;
                    }
                }
                else if (row == 3)
                {
                    // Get the maximum value
                    std::istringstream istr(line);
                    istr >> max_value;
                }
            }

            // Check for valid values.
            if (width <= 0 || height <= 0 ||
                max_value <= 0 || max_value > 65535 ||
                ppmtype < 1 || ppmtype > 6)
            {
                return ReadResult::ERROR_IN_READING_FILE;
            }

            int pixelFormat = 0;
            int dataType = 0;
            unsigned char* data = NULL;

            if (max_value > 255)
            {
                dataType = GL_UNSIGNED_SHORT;
                switch(ppmtype)
                {
                    case 2:    // grayscale ascii
                        pixelFormat = GL_LUMINANCE;
                        break;
                    case 3:    // color ascii
                        pixelFormat = GL_RGB;
                        break;
                    case 5:    // grayscale binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_binary<unsigned short>(fin, width, height);
                        break;
                    case 6:    // color binary
                        pixelFormat = GL_RGB;
                        data = read_color_binary<unsigned short>(fin, width, height);
                        break;
                }
            }
            else
            {
                dataType = GL_UNSIGNED_BYTE;
                switch(ppmtype)
                {
                    case 1:    // bitmap ascii
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_ascii<unsigned char>(fin, width, height);
                        break;
                    case 2:    // grayscale ascii
                        pixelFormat = GL_LUMINANCE;
                        break;
                    case 3:    // color ascii
                        pixelFormat = GL_RGB;
                        break;
                    case 4:    // bitmap binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_bitmap_binary<unsigned char>(fin, width, height);
                        break;
                    case 5:    // grayscale binary
                        pixelFormat = GL_LUMINANCE;
                        data = read_grayscale_binary<unsigned char>(fin, width, height);
                        break;
                    case 6:    // color binary
                        pixelFormat = GL_RGB;
                        data = read_color_binary<unsigned char>(fin, width, height);
                        break;
                }
            }

            if (data == NULL)
            {
                return ReadResult::FILE_NOT_HANDLED;
            }

            osg::Image* pOsgImage = new osg::Image();

            pOsgImage->setImage(width, height, 1,
                pixelFormat,
                pixelFormat,
                dataType,
                data,
                osg::Image::USE_NEW_DELETE);

            if (options && options->getOptionString().find("flip")!=std::string::npos)
            {
                pOsgImage->flipVertical();
            }

            return pOsgImage;
        }

        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            std::ifstream fin(fileName.c_str());
            if (!fin.good())
                return ReadResult::ERROR_IN_READING_FILE;

            ReadResult rr = readImage(fin, options);
            fin.close();
            if (rr.validImage()) rr.getImage()->setFileName(file);
            return rr;
        }

        virtual WriteResult writeImage(const osg::Image& image,std::ostream& fout,const osgDB::ReaderWriter::Options* options) const
        {
            bool ascii = (options && options->getOptionString().find("ascii")!=std::string::npos);

            if (ascii)
            {
                // ascii ppm format.
                fout<<"P3"<<std::endl;
                fout<<image.s()<<" "<<image.t()<<std::endl;
                fout<<"255"<<std::endl;
                for(int row = image.t()-1; row >= 0; --row)
                {
                    const unsigned char* ptr = image.data(0,row);
                    for(int col = 0; col < image.s(); ++col)
                    {
                        fout<<static_cast<int>(*(ptr++));
                        fout<<" "<<static_cast<int>(*(ptr++));
                        fout<<" "<<static_cast<int>(*(ptr++))<<"  ";
                    }
                    fout<<std::endl;
                }
            }
            else
            {
                // binary ppm format
                fout<<"P6"<<std::endl;
                fout<<image.s()<<" "<<image.t()<<std::endl;
                fout<<"255"<<std::endl;
                for(int row = image.t()-1; row >= 0; --row)
                {
                    const unsigned char* ptr = image.data(0,row);
                    for(int col = 0; col < image.s(); ++col)
                    {
                        fout.put(*(ptr++));
                        fout.put(*(ptr++));
                        fout.put(*(ptr++));
                    }
                }
            }
            return WriteResult::FILE_SAVED;
        }

        virtual WriteResult writeImage(const osg::Image& image,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
        {
            // Only ppm format output supported
            std::string ext = osgDB::getFileExtension(fileName);
            if ( !osgDB::equalCaseInsensitive(ext, "ppm") ) return WriteResult::FILE_NOT_HANDLED;

            // only support rgb images right now.
            if (image.getPixelFormat()!=GL_RGB || image.getDataType()!=GL_UNSIGNED_BYTE) return WriteResult("Error image pixel format not supported by pnm writer.");

            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
            if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;

            return writeImage(image,fout,options);
        }

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(pnm, ReaderWriterPNM)
<|endoftext|>


<commit_before>#include "Hotkeys.h"

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"
#include "resource.h"

DLGPROC Hotkeys::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        break;

    case CBN_SELCHANGE:
        break;
    }

    return FALSE;
}

DLGPROC Hotkeys::Notification(NMHDR *nHdr) {
    return FALSE;
}

void Hotkeys::Initialize() {

}

void Hotkeys::LoadSettings() {
    Settings *settings = Settings::Instance();

    /* Make highlighted items span the entire row in the list view */
    _ctxt->AddWindowExStyle(LST_KEYS, LVS_EX_FULLROWSELECT);

    RECT dims = _ctxt->GetWindowDimensions(LST_KEYS);
    int width = dims.right - dims.left;

    _ctxt->AddListColumn(LST_KEYS, 0, L"Hotkeys", (int) (width * .485));
    _ctxt->AddListColumn(LST_KEYS, 0, L"Action", (int) (width * .445));
}

void Hotkeys::SaveSettings() {
    if (_hWnd == NULL) {
        return;
    }

    CLOG(L"Saving: Hotkeys");
    Settings *settings = Settings::Instance();
}

<commit_msg>Include common controls<commit_after>#include "Hotkeys.h"

#include <CommCtrl.h>

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"
#include "resource.h"

DLGPROC Hotkeys::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        break;

    case CBN_SELCHANGE:
        break;
    }

    return FALSE;
}

DLGPROC Hotkeys::Notification(NMHDR *nHdr) {
    return FALSE;
}

void Hotkeys::Initialize() {

}

void Hotkeys::LoadSettings() {
    Settings *settings = Settings::Instance();

    /* Make highlighted items span the entire row in the list view */
    _ctxt->AddWindowExStyle(LST_KEYS, LVS_EX_FULLROWSELECT);

    RECT dims = _ctxt->GetWindowDimensions(LST_KEYS);
    int width = dims.right - dims.left;

    _ctxt->AddListColumn(LST_KEYS, 0, L"Hotkeys", (int) (width * .485));
    _ctxt->AddListColumn(LST_KEYS, 0, L"Action", (int) (width * .445));
}

void Hotkeys::SaveSettings() {
    if (_hWnd == NULL) {
        return;
    }

    CLOG(L"Saving: Hotkeys");
    Settings *settings = Settings::Instance();
}

<|endoftext|>


<commit_before>#include "Hotkeys.h"

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"
#include "resource.h"

DLGPROC Hotkeys::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        break;

    case CBN_SELCHANGE:
    }

    return FALSE;
}

DLGPROC Hotkeys::Notification(NMHDR *nHdr) {
    return FALSE;
}

void Hotkeys::LoadSettings() {
    Settings *settings = Settings::Instance();
}

void Hotkeys::SaveSettings() {
    if (_hWnd == NULL) {
        return;
    }

    CLOG(L"Saving: Hotkeys");
    Settings *settings = Settings::Instance();

}

<commit_msg>It might be helpful if this actually compiled<commit_after>#include "Hotkeys.h"

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"
#include "resource.h"

DLGPROC Hotkeys::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        break;

    case CBN_SELCHANGE:
        break;
    }

    return FALSE;
}

DLGPROC Hotkeys::Notification(NMHDR *nHdr) {
    return FALSE;
}

void Hotkeys::LoadSettings() {
    Settings *settings = Settings::Instance();
}

void Hotkeys::SaveSettings() {
    if (_hWnd == NULL) {
        return;
    }

    CLOG(L"Saving: Hotkeys");
    Settings *settings = Settings::Instance();
}

<|endoftext|>