<commit_before>// Scintilla source code edit control
/** @file LexMatlab.cxx
 ** Lexer for Matlab.
 ** Written by Jos Fonseca
 **
 ** Changes by Christoph Dalitz 2003/12/04:
 **   - added support for Octave
 **   - Strings can now be included both in single or double quotes
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static bool IsMatlabCommentChar(int c) {
	return (c == '%') ;
}

static bool IsOctaveCommentChar(int c) {
	return (c == '%' || c == '#') ;
}

static bool IsMatlabComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsMatlabCommentChar(styler[pos]) ;
}

static bool IsOctaveComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsOctaveCommentChar(styler[pos]) ;
}

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static void ColouriseMatlabOctaveDoc(
            unsigned int startPos, int length, int initStyle,
            WordList *keywordlists[], Accessor &styler,
            bool (*IsCommentChar)(int)) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool transpose = false;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.state == SCE_MATLAB_OPERATOR) {
			if (sc.chPrev == '.') {
				if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				} else {
					sc.SetState(SCE_MATLAB_DEFAULT);
				}
			} else {
				sc.SetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_KEYWORD) {
			if (!isalnum(sc.ch) && sc.ch != '_') {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else {
					sc.ChangeState(SCE_MATLAB_IDENTIFIER);
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				}
			}
		} else if (sc.state == SCE_MATLAB_NUMBER) {
			if (!isdigit(sc.ch) && sc.ch != '.'
			        && !(sc.ch == 'e' || sc.ch == 'E')
			        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = true;
			}
		} else if (sc.state == SCE_MATLAB_STRING) {
			if (sc.ch == '\'' && sc.chPrev != '\\') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
			if (sc.ch == '"' && sc.chPrev != '\\') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = false;
			}
		}

		if (sc.state == SCE_MATLAB_DEFAULT) {
			if (IsCommentChar(sc.ch)) {
				sc.SetState(SCE_MATLAB_COMMENT);
			} else if (sc.ch == '!') {
				sc.SetState(SCE_MATLAB_COMMAND);
			} else if (sc.ch == '\'') {
				if (transpose) {
					sc.SetState(SCE_MATLAB_OPERATOR);
				} else {
					sc.SetState(SCE_MATLAB_STRING);
				}
			} else if (sc.ch == '"') {
              sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
				sc.SetState(SCE_MATLAB_NUMBER);
			} else if (isalpha(sc.ch)) {
				sc.SetState(SCE_MATLAB_KEYWORD);
			} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
				if (sc.ch == ')' || sc.ch == ']') {
					transpose = true;
				} else {
					transpose = false;
				}
				sc.SetState(SCE_MATLAB_OPERATOR);
			} else {
				transpose = false;
			}
		}
	}
	sc.Complete();
}

static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
  ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}

static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
  ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}

static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
                          WordList *[], Accessor &styler,
                          bool (*IsComment)(Accessor&,int,int)) {

	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
  FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
}

static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
  FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
}

static const char * const matlabWordListDesc[] = {
	"Keywords",
	0
};

static const char * const octaveWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);

LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
<commit_msg>Patch from Bob M to handle \\ at end of string.<commit_after>// Scintilla source code edit control
/** @file LexMatlab.cxx
 ** Lexer for Matlab.
 ** Written by Jos Fonseca
 **
 ** Changes by Christoph Dalitz 2003/12/04:
 **   - added support for Octave
 **   - Strings can now be included both in single or double quotes
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static bool IsMatlabCommentChar(int c) {
	return (c == '%') ;
}

static bool IsOctaveCommentChar(int c) {
	return (c == '%' || c == '#') ;
}

static bool IsMatlabComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsMatlabCommentChar(styler[pos]) ;
}

static bool IsOctaveComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsOctaveCommentChar(styler[pos]) ;
}

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static void ColouriseMatlabOctaveDoc(
            unsigned int startPos, int length, int initStyle,
            WordList *keywordlists[], Accessor &styler,
            bool (*IsCommentChar)(int)) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool transpose = false;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.state == SCE_MATLAB_OPERATOR) {
			if (sc.chPrev == '.') {
				if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				} else {
					sc.SetState(SCE_MATLAB_DEFAULT);
				}
			} else {
				sc.SetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_KEYWORD) {
			if (!isalnum(sc.ch) && sc.ch != '_') {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else {
					sc.ChangeState(SCE_MATLAB_IDENTIFIER);
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				}
			}
		} else if (sc.state == SCE_MATLAB_NUMBER) {
			if (!isdigit(sc.ch) && sc.ch != '.'
			        && !(sc.ch == 'e' || sc.ch == 'E')
			        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = true;
			}
		} else if (sc.state == SCE_MATLAB_STRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\'') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = false;
			}
		}

		if (sc.state == SCE_MATLAB_DEFAULT) {
			if (IsCommentChar(sc.ch)) {
				sc.SetState(SCE_MATLAB_COMMENT);
			} else if (sc.ch == '!') {
				sc.SetState(SCE_MATLAB_COMMAND);
			} else if (sc.ch == '\'') {
				if (transpose) {
					sc.SetState(SCE_MATLAB_OPERATOR);
				} else {
					sc.SetState(SCE_MATLAB_STRING);
				}
			} else if (sc.ch == '"') {
				sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
				sc.SetState(SCE_MATLAB_NUMBER);
			} else if (isalpha(sc.ch)) {
				sc.SetState(SCE_MATLAB_KEYWORD);
			} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
				if (sc.ch == ')' || sc.ch == ']') {
					transpose = true;
				} else {
					transpose = false;
				}
				sc.SetState(SCE_MATLAB_OPERATOR);
			} else {
				transpose = false;
			}
		}
	}
	sc.Complete();
}

static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}

static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}

static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
                                WordList *[], Accessor &styler,
                                bool (*IsComment)(Accessor&, int, int)) {

	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
}

static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
}

static const char * const matlabWordListDesc[] = {
	"Keywords",
	0
};

static const char * const octaveWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);

LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
<|endoftext|>


<commit_before>#include "mission_item_impl.h"
#include "global_include.h"
#include "log.h"
#include <cmath>

namespace dronecode_sdk {

MissionItemImpl::MissionItemImpl() {}

MissionItemImpl::~MissionItemImpl() {}

void MissionItemImpl::set_position(double latitude_deg, double longitude_deg)
{
    _latitude_deg = latitude_deg;
    _longitude_deg = longitude_deg;
}

void MissionItemImpl::set_relative_altitude(float relative_altitude_m)
{
    _relative_altitude_m = relative_altitude_m;
}

void MissionItemImpl::set_speed(float speed_m_s)
{
    _speed_m_s = speed_m_s;
}

void MissionItemImpl::set_fly_through(bool fly_through)
{
    _fly_through = fly_through;
}

void MissionItemImpl::set_gimbal_pitch_and_yaw(float pitch_deg, float yaw_deg)
{
    _gimbal_pitch_deg = pitch_deg;
    _gimbal_yaw_deg = yaw_deg;
}

void MissionItemImpl::set_loiter_time(float loiter_time_s)
{
    _loiter_time_s = loiter_time_s;
}

void MissionItemImpl::set_camera_action(MissionItem::CameraAction action)
{
    _camera_action = action;
}

void MissionItemImpl::set_camera_photo_interval(double interval_s)
{
    if (interval_s > 0.0) {
        _camera_photo_interval_s = interval_s;
    } else {
        LogWarn() << "Invalid interval argument";
    }
}

MAV_FRAME MissionItemImpl::get_mavlink_frame() const
{
    return MAV_FRAME_GLOBAL_RELATIVE_ALT_INT;
}

MAV_CMD MissionItemImpl::get_mavlink_cmd() const
{
    return MAV_CMD_NAV_WAYPOINT;
}

uint8_t MissionItemImpl::get_mavlink_autocontinue() const
{
    return 1;
}

float MissionItemImpl::get_mavlink_param1() const
{
    float hold_time_s;
    if (_fly_through) {
        hold_time_s = 0.0f;
    } else {
        hold_time_s = 0.5f;
    }

    return hold_time_s;
}

float MissionItemImpl::get_mavlink_param2() const
{
    float acceptance_radius_m;
    if (_fly_through) {
        acceptance_radius_m = 3.0f;
    } else {
        acceptance_radius_m = 1.0f;
    }

    return acceptance_radius_m;
}

float MissionItemImpl::get_mavlink_param3() const
{
    return 0.0f;
}

float MissionItemImpl::get_mavlink_param4() const
{
    float yaw_angle_deg = 0.0f;
    return yaw_angle_deg;
}

int32_t MissionItemImpl::get_mavlink_x() const
{
    return int32_t(_latitude_deg * 1e7);
}

int32_t MissionItemImpl::get_mavlink_y() const
{
    return int32_t(_longitude_deg * 1e7);
}

float MissionItemImpl::get_mavlink_z() const
{
    return _relative_altitude_m;
}

bool MissionItemImpl::is_position_finite() const
{
    return std::isfinite(_latitude_deg) && std::isfinite(_longitude_deg) &&
           std::isfinite(_relative_altitude_m);
}

} // namespace dronecode_sdk
<commit_msg>mission: fix yawing at non-fly-through waypoints<commit_after>#include "mission_item_impl.h"
#include "global_include.h"
#include "log.h"
#include <cmath>

namespace dronecode_sdk {

MissionItemImpl::MissionItemImpl() {}

MissionItemImpl::~MissionItemImpl() {}

void MissionItemImpl::set_position(double latitude_deg, double longitude_deg)
{
    _latitude_deg = latitude_deg;
    _longitude_deg = longitude_deg;
}

void MissionItemImpl::set_relative_altitude(float relative_altitude_m)
{
    _relative_altitude_m = relative_altitude_m;
}

void MissionItemImpl::set_speed(float speed_m_s)
{
    _speed_m_s = speed_m_s;
}

void MissionItemImpl::set_fly_through(bool fly_through)
{
    _fly_through = fly_through;
}

void MissionItemImpl::set_gimbal_pitch_and_yaw(float pitch_deg, float yaw_deg)
{
    _gimbal_pitch_deg = pitch_deg;
    _gimbal_yaw_deg = yaw_deg;
}

void MissionItemImpl::set_loiter_time(float loiter_time_s)
{
    _loiter_time_s = loiter_time_s;
}

void MissionItemImpl::set_camera_action(MissionItem::CameraAction action)
{
    _camera_action = action;
}

void MissionItemImpl::set_camera_photo_interval(double interval_s)
{
    if (interval_s > 0.0) {
        _camera_photo_interval_s = interval_s;
    } else {
        LogWarn() << "Invalid interval argument";
    }
}

MAV_FRAME MissionItemImpl::get_mavlink_frame() const
{
    return MAV_FRAME_GLOBAL_RELATIVE_ALT_INT;
}

MAV_CMD MissionItemImpl::get_mavlink_cmd() const
{
    return MAV_CMD_NAV_WAYPOINT;
}

uint8_t MissionItemImpl::get_mavlink_autocontinue() const
{
    return 1;
}

float MissionItemImpl::get_mavlink_param1() const
{
    float hold_time_s;
    if (_fly_through) {
        hold_time_s = 0.0f;
    } else {
        hold_time_s = 0.5f;
    }

    return hold_time_s;
}

float MissionItemImpl::get_mavlink_param2() const
{
    float acceptance_radius_m;
    if (_fly_through) {
        acceptance_radius_m = 3.0f;
    } else {
        acceptance_radius_m = 1.0f;
    }

    return acceptance_radius_m;
}

float MissionItemImpl::get_mavlink_param3() const
{
    return 0.0f;
}

float MissionItemImpl::get_mavlink_param4() const
{
    // Just let the drone fly forward.
    float yaw_angle_deg = NAN;
    return yaw_angle_deg;
}

int32_t MissionItemImpl::get_mavlink_x() const
{
    return int32_t(_latitude_deg * 1e7);
}

int32_t MissionItemImpl::get_mavlink_y() const
{
    return int32_t(_longitude_deg * 1e7);
}

float MissionItemImpl::get_mavlink_z() const
{
    return _relative_altitude_m;
}

bool MissionItemImpl::is_position_finite() const
{
    return std::isfinite(_latitude_deg) && std::isfinite(_longitude_deg) &&
           std::isfinite(_relative_altitude_m);
}

} // namespace dronecode_sdk
<|endoftext|>


<commit_before>//
//                 INTEL CORPORATION PROPRIETARY INFORMATION
//
//    This software is supplied under the terms of a license agreement or
//    nondisclosure agreement with Intel Corporation and may not be copied
//    or disclosed except in accordance with the terms of that agreement.
//    Copyright (C) 2014 Intel Corporation. All Rights Reserved.
//

#include <cassert>
#include "ospray/volume/BrickedVolume.h"
#include "BrickedVolume_ispc.h"

namespace ospray {

    void BrickedVolume::createEquivalentISPC() {

        //! Get the voxel type.
        voxelType = getParamString("voxelType", "unspecified");  exitOnCondition(getVoxelType() == OSP_UNKNOWN, "unrecognized voxel type");

        //! Create an ISPC BrickedVolume object and assign type-specific function pointers.
        ispcEquivalent = ispc::BrickedVolume_createInstance((int) getVoxelType());

        //! Get the volume dimensions.
        volumeDimensions = getParam3i("dimensions", vec3i(0));  exitOnCondition(reduce_min(volumeDimensions) <= 0, "invalid volume dimensions");

        //! Get the transfer function.
        transferFunction = getParamObject("transferFunction", NULL);  exitOnCondition(transferFunction == NULL, "no volume transfer function specified");

        //! Get the gamma correction coefficient and exponent.
        vec2f gammaCorrection = getParam2f("gammaCorrection", vec2f(1.0f));

        //! Set the volume dimensions.
        ispc::BrickedVolume_setVolumeDimensions(ispcEquivalent, (const ispc::vec3i &) volumeDimensions);

        //! Set the transfer function.
        ispc::BrickedVolume_setTransferFunction(ispcEquivalent, ((TransferFunction *) transferFunction)->getEquivalentISPC());

        //! Set the sampling step size for ray casting based renderers.
        ispc::BrickedVolume_setStepSize(ispcEquivalent, 1.0f / reduce_max(volumeDimensions) / getParam1f("samplingRate", 1.0f));

        //! Set the gamma correction coefficient and exponent.
        ispc::BrickedVolume_setGammaCorrection(ispcEquivalent, (const ispc::vec2f &) gammaCorrection);

        //! Allocate memory for the voxel data in the ISPC object.
        ispc::BrickedVolume_allocateMemory(ispcEquivalent);

    }

    void BrickedVolume::setRegion(const void *source, const vec3i &index, const vec3i &count) {

        //! Range check.
        assert(inRange(index, vec3i(0), voxelDimensions) && inRange(count, vec3i(1), voxelDimensions + vec3i(1)));

        //! Copy voxel data into the volume.
        ispc::BrickedVolume_setRegion(ispcEquivalent, source, (const ispc::vec3i &) index, (const ispc::vec3i &) count);

    }

} // namespace ospray

<commit_msg>disabled broken range check in brickedvolume.cpp<commit_after>//
//                 INTEL CORPORATION PROPRIETARY INFORMATION
//
//    This software is supplied under the terms of a license agreement or
//    nondisclosure agreement with Intel Corporation and may not be copied
//    or disclosed except in accordance with the terms of that agreement.
//    Copyright (C) 2014 Intel Corporation. All Rights Reserved.
//

#include <cassert>
#include "ospray/volume/BrickedVolume.h"
#include "BrickedVolume_ispc.h"

namespace ospray {

    void BrickedVolume::createEquivalentISPC() {

        //! Get the voxel type.
        voxelType = getParamString("voxelType", "unspecified");  exitOnCondition(getVoxelType() == OSP_UNKNOWN, "unrecognized voxel type");

        //! Create an ISPC BrickedVolume object and assign type-specific function pointers.
        ispcEquivalent = ispc::BrickedVolume_createInstance((int) getVoxelType());

        //! Get the volume dimensions.
        volumeDimensions = getParam3i("dimensions", vec3i(0));  exitOnCondition(reduce_min(volumeDimensions) <= 0, "invalid volume dimensions");

        //! Get the transfer function.
        transferFunction = getParamObject("transferFunction", NULL);  exitOnCondition(transferFunction == NULL, "no volume transfer function specified");

        //! Get the gamma correction coefficient and exponent.
        vec2f gammaCorrection = getParam2f("gammaCorrection", vec2f(1.0f));

        //! Set the volume dimensions.
        ispc::BrickedVolume_setVolumeDimensions(ispcEquivalent, (const ispc::vec3i &) volumeDimensions);

        //! Set the transfer function.
        ispc::BrickedVolume_setTransferFunction(ispcEquivalent, ((TransferFunction *) transferFunction)->getEquivalentISPC());

        //! Set the sampling step size for ray casting based renderers.
        ispc::BrickedVolume_setStepSize(ispcEquivalent, 1.0f / reduce_max(volumeDimensions) / getParam1f("samplingRate", 1.0f));

        //! Set the gamma correction coefficient and exponent.
        ispc::BrickedVolume_setGammaCorrection(ispcEquivalent, (const ispc::vec2f &) gammaCorrection);

        //! Allocate memory for the voxel data in the ISPC object.
        ispc::BrickedVolume_allocateMemory(ispcEquivalent);

    }

    void BrickedVolume::setRegion(const void *source, const vec3i &index, const vec3i &count) {

        //! Range check.
      //        assert(inRange(index, vec3i(0), voxelDimensions) && inRange(count, vec3i(1), voxelDimensions + vec3i(1)));

        //! Copy voxel data into the volume.
        ispc::BrickedVolume_setRegion(ispcEquivalent, source, (const ispc::vec3i &) index, (const ispc::vec3i &) count);

    }

} // namespace ospray

<|endoftext|>


<commit_before><commit_msg>Update abi defs for type changes<commit_after><|endoftext|>


<commit_before><commit_msg>Updated for new memory manager call<commit_after><|endoftext|>


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

#include <x0/http/HttpPlugin.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/io/BufferSource.h>
#include <x0/strutils.h>
#include <x0/Url.h>
#include <x0/Types.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>

/* {{{ -- configuration proposal:
 *
 * handler setup {
 * }
 *
 * handler main {
 *     proxy.reverse 'http://127.0.0.1:3000';
 * }
 *
 * --------------------------------------------------------------------------
 * possible tweaks:
 *  - bufsize (0 = unbuffered)
 *  - timeout.connect
 *  - timeout.write
 *  - timeout.read
 *  - ignore_clientabort
 * };
 *
 *
 */ // }}}

#if 1
#	define TRACE(msg...) DEBUG("proxy: " msg)
#else
#	define TRACE(msg...) /*!*/
#endif

// {{{ ProxyConnection API
class ProxyConnection :
	public x0::HttpMessageProcessor
{
private:
	// client
	x0::HttpRequest *request_;		//!< client's request

	// backend
	x0::Socket backend_;
	std::string hostname_;			//!< origin's hostname
	int port_;						//!< origin's port

	int connectTimeout_;
	int readTimeout_;
	int writeTimeout_;

	x0::Buffer writeBuffer_;
	size_t writeOffset_;
	size_t writeProgress_;

	x0::Buffer readBuffer_;

	// tweaks
	bool cloak_;

private:
	bool isClosed() const { return backend_.isClosed(); }

	inline void close();
	inline void destroy(x0::HttpError code = x0::HttpError::Undefined);

	inline bool connect();

	inline void readSome();
	inline void writeSome();

	void onConnected(x0::Socket* s, int revents);
	void io(x0::Socket* s, int revents);
	void onRequestChunk(x0::BufferRef&& chunk);

	static void onAbort(void *p);

	// response (HttpMessageProcessor)
	virtual void messageBegin(int version_major, int version_minor, int code, x0::BufferRef&& text);
	virtual void messageHeader(x0::BufferRef&& name, x0::BufferRef&& value);
	virtual bool messageContent(x0::BufferRef&& chunk);
	virtual bool messageEnd();

public:
	inline ProxyConnection(const char *origin, x0::HttpRequest *r, bool cloak = true);
	~ProxyConnection();

	inline void start();
};
// }}}

// {{{ ProxyConnection impl
ProxyConnection::ProxyConnection(const char *origin, x0::HttpRequest *r, bool cloak) :
	x0::HttpMessageProcessor(x0::HttpMessageProcessor::RESPONSE),
	request_(r),
	backend_(r->connection.worker().loop()),
	hostname_(),
	port_(),
	connectTimeout_(0),
	readTimeout_(0),
	writeTimeout_(0),
	writeBuffer_(),
	writeOffset_(0),
	writeProgress_(0),
	readBuffer_(),
	cloak_(cloak)
{
	TRACE("ProxyConnection()");

	request_->setAbortHandler(&ProxyConnection::onAbort, this);

	x0::BufferRef ref(origin);
	if (ref.begins("unix:")) {
		// UNIX domain socket
		hostname_ = origin + 5;
		port_ = 0;
	} else {
		// TCP/IP
		auto pos = ref.rfind(':');
		if (pos != ref.npos) {
			hostname_ = origin;
			hostname_[pos] = '\0';
			port_ = ref.ref(pos + 1).toInt();
		} else {
			hostname_ = origin;
			port_ = 80; // default to port 80, if not specified
		}
	}
}

void ProxyConnection::onAbort(void *p)
{
	ProxyConnection *self = reinterpret_cast<ProxyConnection *>(p);

	delete self;
}

ProxyConnection::~ProxyConnection()
{
	TRACE("~ProxyConnection()");

	close();

	if (request_) {
		request_->finish();
	}
}

void ProxyConnection::start()
{
	// request line
	writeBuffer_.push_back(request_->method);
	writeBuffer_.push_back(' ');
	writeBuffer_.push_back(request_->uri);
	writeBuffer_.push_back(" HTTP/1.1\r\n");

	// request headers
	for (auto i = request_->requestHeaders.begin(), e = request_->requestHeaders.end(); i != e; ++i)
	{
		if (iequals(i->name, "Content-Transfer")
				|| iequals(i->name, "Expect")
				|| iequals(i->name, "Connection"))
			continue;

		TRACE("pass requestHeader(%s: %s)", i->name.str().c_str(), i->value.str().c_str());
		writeBuffer_.push_back(i->name);
		writeBuffer_.push_back(": ");
		writeBuffer_.push_back(i->value);
		writeBuffer_.push_back("\r\n");
	}

	// request headers terminator
	writeBuffer_.push_back("\r\n");

	if (backend_.state() == x0::Socket::Operational) {
		backend_.setMode(x0::Socket::Write);
	}
}

/** transferres a request body chunk to the origin server.  */
void ProxyConnection::onRequestChunk(x0::BufferRef&& chunk)
{
	TRACE("onRequestChunk(nb:%ld)", chunk.size());
	writeBuffer_.push_back(chunk);
	backend_.setMode(x0::Socket::Write);
}

inline bool validateResponseHeader(const x0::BufferRef& name)
{
	// XXX do not allow origin's connection-level response headers to be passed to the client.
	if (iequals(name, "Connection"))
		return false;

	if (iequals(name, "Transfer-Encoding"))
		return false;

	return true;
}

/** callback, invoked when the origin server has passed us the response status line.
 *
 * We will use the status code only.
 * However, we could pass the text field, too - once x0 core supports it.
 */
void ProxyConnection::messageBegin(int major, int minor, int code, x0::BufferRef&& text)
{
	TRACE("ProxyConnection(%p).status(HTTP/%d.%d, %d, '%s')", (void*)this, major, minor, code, text.str().c_str());

	request_->status = static_cast<x0::HttpError>(code);
	TRACE("status: %d", (int)request_->status);
}

/** callback, invoked on every successfully parsed response header.
 *
 * We will pass this header directly to the client's response,
 * if that is NOT a connection-level header.
 */
void ProxyConnection::messageHeader(x0::BufferRef&& name, x0::BufferRef&& value)
{
	TRACE("ProxyConnection(%p).onHeader('%s', '%s')", (void*)this, name.str().c_str(), value.str().c_str());

	if (!validateResponseHeader(name))
		return;

	if (cloak_ && iequals(name, "Server"))
		return;

	request_->responseHeaders.push_back(name.str(), value.str());
}

/** callback, invoked on a new response content chunk. */
bool ProxyConnection::messageContent(x0::BufferRef&& chunk)
{
	TRACE("messageContent(nb:%lu) state:%s", chunk.size(), backend_.state_str());

	// stop watching for more input
	backend_.setMode(x0::Socket::None);

	// transfer response-body chunk to client
	request_->write<x0::BufferSource>(std::move(chunk));

	// start listening on backend I/O when chunk has been fully transmitted
	request_->writeCallback([&]() {
		TRACE("chunk write complete: %s", state_str());
		backend_.setMode(x0::Socket::Read);
	});

	return true;
}

bool ProxyConnection::messageEnd()
{
	TRACE("messageEnd() state:%s", backend_.state_str());
	return true;
}

bool ProxyConnection::connect()
{
	TRACE("connect(): hostname=%s, port=%d) %s", hostname_.c_str(), port_, state_str());

	bool rv = port_
		? backend_.openTcp(hostname_, port_, O_NONBLOCK | O_CLOEXEC) // tcp/ip socket
		: backend_.openUnix(hostname_, O_NONBLOCK | O_CLOEXEC);      // unix socket

	if (!rv)
		return false;

	if (backend_.state() == x0::Socket::Connecting)
		backend_.setReadyCallback<ProxyConnection, &ProxyConnection::onConnected>(this);
	else // Operational
		backend_.setReadyCallback<ProxyConnection, &ProxyConnection::io>(this);
}

void ProxyConnection::close()
{
	backend_.close();
}

void ProxyConnection::destroy(x0::HttpError code)
{
	backend_.close();

	if (request_)
	{
		if (code != x0::HttpError::Undefined)
			request_->status = code;

		request_->finish();
		request_ = nullptr;
	}

	delete this;
}

void ProxyConnection::onConnected(x0::Socket* s, int revents)
{
	if (backend_.state() == x0::Socket::Operational) {
		backend_.setReadyCallback<ProxyConnection, &ProxyConnection::io>(this);
		backend_.setMode(x0::Socket::Write); // flush already serialized request
	} else {
		destroy(x0::HttpError::ServiceUnavailable);
	}
}

void ProxyConnection::io(x0::Socket* s, int revents)
{
	TRACE("io(0x%04x)", revents);

	if (revents & ev::READ)
		readSome();

	if (revents & ev::WRITE)
		writeSome();
}

void ProxyConnection::writeSome()
{
	TRACE("writeSome() - %s (%d)", state_str(), request_->contentAvailable());

	ssize_t rv = backend_.write(writeBuffer_.data() + writeOffset_, writeBuffer_.size() - writeOffset_);

	if (rv > 0)
	{
		TRACE("write request: %ld (of %ld) bytes", rv, writeBuffer_.size() - writeOffset_);

		writeOffset_ += rv;
		writeProgress_ += rv;

		if (writeOffset_ == writeBuffer_.size())
		{
			TRACE("writeOffset == writeBuffser.size (%ld) p:%ld, ca: %d, clr:%ld",
				writeOffset_,
				writeProgress_,
				request_->contentAvailable(),
				request_->connection.contentLength());

			writeOffset_ = 0;
			writeBuffer_.clear();

			if (request_->contentAvailable()) {
				backend_.setMode(x0::Socket::None);
				request_->read(std::bind(&ProxyConnection::onRequestChunk, this, std::placeholders::_1));
			} else {
				// request fully transmitted, let's read response then.
				backend_.setMode(x0::Socket::Read);
			}
		}
	}
	else
	{
		TRACE("write request failed(%ld): %s", rv, strerror(errno));
		close();
	}
}

void ProxyConnection::readSome()
{
	TRACE("readSome() - %s", state_str());

	std::size_t lower_bound = readBuffer_.size();

	if (lower_bound == readBuffer_.capacity())
		readBuffer_.setCapacity(lower_bound + 4096);

	ssize_t rv = backend_.read(readBuffer_);

	if (rv > 0) {
		TRACE("read response: %ld bytes", rv);
		std::size_t np = 0;
		std::error_code ec = process(readBuffer_.ref(lower_bound, rv), np);
		TRACE("readSome(): process(): %s", ec.message().c_str());
		if (ec == x0::HttpMessageError::Success) {
			destroy();
		} else if (ec == x0::HttpMessageError::Partial) {
			TRACE("resume with io:%d, state:%s", backend_.mode(), backend_.state_str());
			backend_.setMode(x0::Socket::Read);
		} else {
			destroy(x0::HttpError::InternalServerError);
		}
	} else if (rv == 0) {
		TRACE("http server connection closed");
		close();
	} else {
		TRACE("read response failed(%ld): %s", rv, strerror(errno));

		switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
		case EWOULDBLOCK:
#endif
		case EAGAIN:
		case EINTR:
			backend_.setMode(x0::Socket::Read);
			break;
		default:
			close();
			break;
		}
	}
}

// }}}

// {{{ plugin class
/**
 * \ingroup plugins
 * \brief proxy content generator plugin
 */
class proxy_plugin :
	public x0::HttpPlugin
{
private:
	bool cloak_;

public:
	proxy_plugin(x0::HttpServer& srv, const std::string& name) :
		x0::HttpPlugin(srv, name),
		cloak_(true)
	{
		registerHandler<proxy_plugin, &proxy_plugin::proxy_reverse>("proxy.reverse");
		registerSetupProperty<proxy_plugin, &proxy_plugin::proxy_cloak>("proxy.cloak", x0::FlowValue::BOOLEAN);
	}

	~proxy_plugin()
	{
	}

private:
	void proxy_cloak(x0::FlowValue& result, const x0::Params& args)
	{
		if (args.count() && (args[0].isBool() || args[0].isNumber()))
		{
			cloak_ = args[0].toBool();
			printf("proxy cloak: %s\n", cloak_ ? "true" : "false");
		}

		result.set(cloak_);
	}

	bool proxy_reverse(x0::HttpRequest *r, const x0::Params& args)
	{
		// TODO: reuse already spawned proxy connections instead of recreating each time.

		const char *origin = args[0].toString();
		ProxyConnection *pc = new ProxyConnection(origin, r, cloak_);
		if (!pc)
			return false; // XXX handle as 500 instead?

		pc->start();

		return true;
	}
};
// }}}

X0_EXPORT_PLUGIN(proxy)
<commit_msg>[plugins] proxy: this one now works again (with request body transfer, too)<commit_after>/* <x0/plugins/proxy.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 * http://www.xzero.ws/
 *
 * (c) 2009-2010 Christian Parpart <trapni@gentoo.org>
 */

#include <x0/http/HttpPlugin.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/io/BufferSource.h>
#include <x0/strutils.h>
#include <x0/Url.h>
#include <x0/Types.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>

/* {{{ -- configuration proposal:
 *
 * handler setup {
 * }
 *
 * handler main {
 *     proxy.reverse 'http://127.0.0.1:3000';
 * }
 *
 * --------------------------------------------------------------------------
 * possible tweaks:
 *  - bufsize (0 = unbuffered)
 *  - timeout.connect
 *  - timeout.write
 *  - timeout.read
 *  - ignore_clientabort
 * };
 *
 *
 */ // }}}

#if 1
#	define TRACE(msg...) DEBUG("proxy: " msg)
#else
#	define TRACE(msg...) /*!*/
#endif

// {{{ ProxyConnection API
class ProxyConnection :
	public x0::HttpMessageProcessor
{
private:
	int refCount_;

	x0::HttpRequest *request_;		//!< client's request
	x0::Socket* backend_;			//!< connection to backend app
	bool cloak_;					//!< to cloak or not to cloak the "Server" response header

	int connectTimeout_;
	int readTimeout_;
	int writeTimeout_;

	x0::Buffer writeBuffer_;
	size_t writeOffset_;
	size_t writeProgress_;

	x0::Buffer readBuffer_;

private:
	void ref();
	void unref();
	inline void close();
	inline void readSome();
	inline void writeSome();

	void onConnected(x0::Socket* s, int revents);
	void io(x0::Socket* s, int revents);
	void onRequestChunk(x0::BufferRef&& chunk);

	static void onAbort(void *p);

	// response (HttpMessageProcessor)
	virtual void messageBegin(int version_major, int version_minor, int code, x0::BufferRef&& text);
	virtual void messageHeader(x0::BufferRef&& name, x0::BufferRef&& value);
	virtual bool messageContent(x0::BufferRef&& chunk);
	virtual bool messageEnd();

public:
	inline ProxyConnection();
	~ProxyConnection();

	void start(x0::HttpRequest* in, x0::Socket* backend, bool cloak);
};
// }}}

// {{{ ProxyConnection impl
ProxyConnection::ProxyConnection() :
	x0::HttpMessageProcessor(x0::HttpMessageProcessor::RESPONSE),
	refCount_(1),
	request_(nullptr),
	backend_(nullptr),
	cloak_(false),

	connectTimeout_(0),
	readTimeout_(0),
	writeTimeout_(0),
	writeBuffer_(),
	writeOffset_(0),
	writeProgress_(0),
	readBuffer_()
{
	TRACE("ProxyConnection()");
}

ProxyConnection::~ProxyConnection()
{
	TRACE("~ProxyConnection()");

	if (backend_) {
		backend_->close();

		delete backend_;
	}

	if (request_) {
		if (request_->status == x0::HttpError::Undefined)
			request_->status = x0::HttpError::ServiceUnavailable;

		request_->finish();
	}
}

void ProxyConnection::ref()
{
	++refCount_;
}

void ProxyConnection::unref()
{
	assert(refCount_ > 0);

	--refCount_;

	if (refCount_ == 0) {
		delete this;
	}
}

void ProxyConnection::close()
{
	unref(); // the one from the constructor
}

void ProxyConnection::onAbort(void *p)
{
	ProxyConnection *self = reinterpret_cast<ProxyConnection *>(p);
	self->close();
}

void ProxyConnection::start(x0::HttpRequest* in, x0::Socket* backend, bool cloak)
{
	request_ = in;
	request_->setAbortHandler(&ProxyConnection::onAbort, this);
	backend_ = backend;
	cloak_ = cloak_;

	// request line
	writeBuffer_.push_back(request_->method);
	writeBuffer_.push_back(' ');
	writeBuffer_.push_back(request_->uri);
	writeBuffer_.push_back(" HTTP/1.1\r\n");

	// request headers
	for (auto i = request_->requestHeaders.begin(), e = request_->requestHeaders.end(); i != e; ++i) {
		if (iequals(i->name, "Content-Transfer")
				|| iequals(i->name, "Expect")
				|| iequals(i->name, "Connection"))
			continue;

		TRACE("pass requestHeader(%s: %s)", i->name.str().c_str(), i->value.str().c_str());
		writeBuffer_.push_back(i->name);
		writeBuffer_.push_back(": ");
		writeBuffer_.push_back(i->value);
		writeBuffer_.push_back("\r\n");
	}

	// request headers terminator
	writeBuffer_.push_back("\r\n");

	if (request_->contentAvailable()) {
		TRACE("start: request content available: reading.");
		request_->read(std::bind(&ProxyConnection::onRequestChunk, this, std::placeholders::_1));
	}

	if (backend_->state() == x0::Socket::Connecting) {
		TRACE("start: connect in progress");
		backend_->setReadyCallback<ProxyConnection, &ProxyConnection::onConnected>(this);
	} else { // connected
		TRACE("start: flushing");
		backend_->setReadyCallback<ProxyConnection, &ProxyConnection::io>(this);
		backend_->setMode(x0::Socket::ReadWrite);
	}
}

void ProxyConnection::onConnected(x0::Socket* s, int revents)
{
	TRACE("onConnected: content? %d", request_->contentAvailable());
	TRACE("onConnected.pending:\n%s\n", writeBuffer_.c_str());

	if (backend_->state() == x0::Socket::Operational) {
		backend_->setReadyCallback<ProxyConnection, &ProxyConnection::io>(this);
		if (request_->contentAvailable()) {
			TRACE("onConnected: request content available: reading.");
			request_->read(std::bind(&ProxyConnection::onRequestChunk, this, std::placeholders::_1));
		} else {
			TRACE("onConnected: flushing");
			backend_->setMode(x0::Socket::ReadWrite); // flush already serialized request
		}
	} else {
		close();
	}
}

/** transferres a request body chunk to the origin server.  */
void ProxyConnection::onRequestChunk(x0::BufferRef&& chunk)
{
	TRACE("onRequestChunk(nb:%ld)", chunk.size());
	writeBuffer_.push_back(chunk);

	if (backend_->state() == x0::Socket::Operational) {
		backend_->setMode(x0::Socket::ReadWrite);
	}
}

inline bool validateResponseHeader(const x0::BufferRef& name)
{
	// XXX do not allow origin's connection-level response headers to be passed to the client.
	if (iequals(name, "Connection"))
		return false;

	if (iequals(name, "Transfer-Encoding"))
		return false;

	return true;
}

/** callback, invoked when the origin server has passed us the response status line.
 *
 * We will use the status code only.
 * However, we could pass the text field, too - once x0 core supports it.
 */
void ProxyConnection::messageBegin(int major, int minor, int code, x0::BufferRef&& text)
{
	TRACE("ProxyConnection(%p).status(HTTP/%d.%d, %d, '%s')", (void*)this, major, minor, code, text.str().c_str());

	request_->status = static_cast<x0::HttpError>(code);
	TRACE("status: %d", (int)request_->status);
}

/** callback, invoked on every successfully parsed response header.
 *
 * We will pass this header directly to the client's response,
 * if that is NOT a connection-level header.
 */
void ProxyConnection::messageHeader(x0::BufferRef&& name, x0::BufferRef&& value)
{
	TRACE("ProxyConnection(%p).onHeader('%s', '%s')", (void*)this, name.str().c_str(), value.str().c_str());

	if (!validateResponseHeader(name))
		return;

	if (cloak_ && iequals(name, "Server"))
		return;

	request_->responseHeaders.push_back(name.str(), value.str());
}

/** callback, invoked on a new response content chunk. */
bool ProxyConnection::messageContent(x0::BufferRef&& chunk)
{
	TRACE("messageContent(nb:%lu) state:%s", chunk.size(), backend_->state_str());

	// stop watching for more input
	backend_->setMode(x0::Socket::None);

	// transfer response-body chunk to client
	request_->write<x0::BufferSource>(std::move(chunk));

	// start listening on backend I/O when chunk has been fully transmitted
	request_->writeCallback([&]() {
		TRACE("chunk write complete: %s", state_str());
		backend_->setMode(x0::Socket::Read);
	});

	return true;
}

bool ProxyConnection::messageEnd()
{
	TRACE("messageEnd() state:%s", backend_->state_str());
	return true;
}

void ProxyConnection::io(x0::Socket* s, int revents)
{
	TRACE("io(0x%04x)", revents);

	if (revents & x0::Socket::Read)
		readSome();

	if (revents & x0::Socket::Write)
		writeSome();
}

void ProxyConnection::writeSome()
{
	TRACE("writeSome() - %s (%d)", state_str(), request_->contentAvailable());

	ssize_t rv = backend_->write(writeBuffer_.data() + writeOffset_, writeBuffer_.size() - writeOffset_);

	if (rv > 0) {
		TRACE("write request: %ld (of %ld) bytes", rv, writeBuffer_.size() - writeOffset_);

		writeOffset_ += rv;
		writeProgress_ += rv;

		if (writeOffset_ == writeBuffer_.size()) {
			TRACE("writeOffset == writeBuffser.size (%ld) p:%ld, ca: %d, clr:%ld", writeOffset_,
				writeProgress_, request_->contentAvailable(), request_->connection.contentLength());

			writeOffset_ = 0;
			writeBuffer_.clear();

			if (request_->contentAvailable()) {
				TRACE("writeSome: request content available: reading.");
				backend_->setMode(x0::Socket::Read);
				request_->read(std::bind(&ProxyConnection::onRequestChunk, this, std::placeholders::_1));
			} else {
				// request fully transmitted, let's read response then.
				backend_->setMode(x0::Socket::Read);
				TRACE("writeSome: watching for 'read'");
			}
		}
	} else {
		TRACE("write request failed(%ld): %s", rv, strerror(errno));
		close();
	}
}

void ProxyConnection::readSome()
{
	TRACE("readSome() - %s", state_str());

	std::size_t lower_bound = readBuffer_.size();

	if (lower_bound == readBuffer_.capacity())
		readBuffer_.setCapacity(lower_bound + 4096);

	ssize_t rv = backend_->read(readBuffer_);

	if (rv > 0) {
		TRACE("read response: %ld bytes", rv);
		std::size_t np = 0;
		std::error_code ec = process(readBuffer_.ref(lower_bound, rv), np);
		TRACE("readSome(): process(): %s", ec.message().c_str());
		if (ec == x0::HttpMessageError::Success) {
			close();
		} else if (ec == x0::HttpMessageError::Partial) {
			TRACE("resume with io:%d, state:%s", backend_->mode(), backend_->state_str());
			backend_->setMode(x0::Socket::Read);
		} else {
			close();
		}
	} else if (rv == 0) {
		TRACE("http server connection closed");
		close();
	} else {
		TRACE("read response failed(%ld): %s", rv, strerror(errno));

		switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
		case EWOULDBLOCK:
#endif
		case EAGAIN:
		case EINTR:
			backend_->setMode(x0::Socket::Read);
			break;
		default:
			close();
			break;
		}
	}
}

// }}}

// {{{ plugin class
/**
 * \ingroup plugins
 * \brief proxy content generator plugin
 */
class proxy_plugin :
	public x0::HttpPlugin
{
private:
	bool cloak_;

public:
	proxy_plugin(x0::HttpServer& srv, const std::string& name) :
		x0::HttpPlugin(srv, name),
		cloak_(true)
	{
		registerHandler<proxy_plugin, &proxy_plugin::proxy_reverse>("proxy.reverse");
		registerSetupProperty<proxy_plugin, &proxy_plugin::proxy_cloak>("proxy.cloak", x0::FlowValue::BOOLEAN);
	}

	~proxy_plugin()
	{
	}

private:
	void proxy_cloak(x0::FlowValue& result, const x0::Params& args)
	{
		if (args.count() && (args[0].isBool() || args[0].isNumber())) {
			cloak_ = args[0].toBool();
			printf("proxy cloak: %s\n", cloak_ ? "true" : "false");
		}

		result.set(cloak_);
	}

	bool proxy_reverse(x0::HttpRequest *in, const x0::Params& args)
	{
		// TODO: reuse already spawned proxy connections instead of recreating each time.

		x0::BufferRef origin = args[0].toString();

		x0::Socket* backend = new x0::Socket(in->connection.worker().loop());

		if (origin.begins("unix:")) { // UNIX domain socket
			backend->openUnix(origin.str());
		} else { // TCP/IP
			auto pos = origin.rfind(':');
			if (pos != origin.npos) {
				std::string hostname = origin.substr(0, pos);
				int port = origin.ref(pos + 1).toInt();
				backend->openTcp(hostname, port);
			} else {
				// default to port 80 (FIXME not really good?)
				backend->openTcp(origin.str(), 80);
			}
		}

		if (backend->isOpen()) {
			TRACE("in.content? %d", in->contentAvailable());
			if (ProxyConnection* pc = new ProxyConnection()) {
				pc->start(in, backend, cloak_);
				return true;
			}
		}

		in->status = x0::HttpError::ServiceUnavailable;
		in->finish();

		return true;
	}
};
// }}}

X0_EXPORT_PLUGIN(proxy)
<|endoftext|>


<commit_before>#include "Image.hpp"

#include "Misc.hpp"
#include "TargaImage.hpp"
#include "PNGImage.hpp"

namespace Core
{
	Image::Image()
		: m_width(0), m_height(0), m_format(0), m_bytesPerPixel(0)
	{
	}

	Image::~Image()
	{
	}

	GLushort Image::GetWidth() const
	{
		return m_width;
	}

	GLushort Image::GetHeight() const
	{
		return m_height;
	}

	GLushort Image::GetBytesPerPixel() const
	{
		return m_bytesPerPixel;
	}

	GLint Image::GetFormat() const
	{
		return m_format;
	}

	Image* LoadImage(const char *pPath)
	{
		LOGD("LoadImage: pPath = %s",pPath);

		string ext;
		Misc::PathExtension(pPath,ext);
		Misc::StringUpper(ext);
		Image *image=NULL;
		if(ext=="TGA")
		{
			LOGD("LoadImage: TGA format");
			image=new TargaImage;
		}
		else if(ext=="PNG")
		{
			LOGD("LoadImage: PNG format");
			image=new PNGImage;
		}

		if(image->Load(pPath)==RETURN_VALUE_KO)
		{
			LOGE("LoadImage: Failed to load");
			delete image;
			image=NULL;
		}
		if(!image)
		{
			LOGE("LoadImage: invalid format %s",pPath);
		}
		return image;
	}

	GLushort GetBPP(GLint format)
	{
		switch(format)
		{
			case GL_RGB:
				return 3;
			break;
			case GL_RGBA:
				return 4;
			break;
			case GL_LUMINANCE:
				return 1;
			break;
			case GL_LUMINANCE_ALPHA:
				return 2;
			break;
		}
		return 0;
	}
}
<commit_msg>Fixed usage of StringEx<commit_after>#include "Image.hpp"

#include "StringEx.hpp"
#include "TargaImage.hpp"
#include "PNGImage.hpp"

namespace Core
{
	Image::Image()
		: m_width(0), m_height(0), m_format(0), m_bytesPerPixel(0)
	{
	}

	Image::~Image()
	{
	}

	GLushort Image::GetWidth() const
	{
		return m_width;
	}

	GLushort Image::GetHeight() const
	{
		return m_height;
	}

	GLushort Image::GetBytesPerPixel() const
	{
		return m_bytesPerPixel;
	}

	GLint Image::GetFormat() const
	{
		return m_format;
	}

	Image* LoadImage(const char *pPath)
	{
		LOGD("LoadImage: pPath = %s",pPath);

		string ext;
		Core::StringEx::GetExtension(pPath,ext);
		Core::StringEx::Upper(ext);
		Image *image=NULL;
		if(ext=="TGA")
		{
			LOGD("LoadImage: TGA format");
			image=new TargaImage;
		}
		else if(ext=="PNG")
		{
			LOGD("LoadImage: PNG format");
			image=new PNGImage;
		}

		if(image->Load(pPath)==RETURN_VALUE_KO)
		{
			LOGE("LoadImage: Failed to load");
			delete image;
			image=NULL;
		}
		if(!image)
		{
			LOGE("LoadImage: invalid format %s",pPath);
		}
		return image;
	}

	GLushort GetBPP(GLint format)
	{
		switch(format)
		{
			case GL_RGB:
				return 3;
			break;
			case GL_RGBA:
				return 4;
			break;
			case GL_LUMINANCE:
				return 1;
			break;
			case GL_LUMINANCE_ALPHA:
				return 2;
			break;
		}
		return 0;
	}
}
<|endoftext|>


<commit_before><commit_msg>coverity#708261 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreD3D11HardwareVertexBuffer.h"
#include "OgreD3D11HardwareBuffer.h"
#include "OgreD3D11Device.h"

namespace Ogre {

	//---------------------------------------------------------------------
	D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize,
		size_t numVertices, HardwareBuffer::Usage usage, D3D11Device & device,
		bool useSystemMemory, bool useShadowBuffer)
		: HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMemory, useShadowBuffer)
	{
		// everything is done via internal generalisation
		mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER,
			mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer);

	}
	//---------------------------------------------------------------------
	D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer()
	{
		delete mBufferImpl;
	}
	//---------------------------------------------------------------------
	void* D3D11HardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options)
	{
		return mBufferImpl->lock(offset, length, options);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::unlock(void)
	{
		mBufferImpl->unlock();
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest)
	{
		mBufferImpl->readData(offset, length, pDest);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource,
		bool discardWholeBuffer)
	{
		mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset,
		size_t dstOffset, size_t length, bool discardWholeBuffer)
	{
		D3D11HardwareVertexBuffer& d3dBuf = static_cast<D3D11HardwareVertexBuffer&>(srcBuffer);

		mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer);
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::isLocked(void) const
	{
		return mBufferImpl->isLocked();
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::releaseIfDefaultPool(void)
	{
		/*		if (mD3DPool == D3DPOOL_DEFAULT)
		{
		SAFE_RELEASE(mlpD3DBuffer);
		return true;
		}
		return false;
		*/
		return true;
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::recreateIfDefaultPool(D3D11Device & device)
	{
		/*	if (mD3DPool == D3DPOOL_DEFAULT)
		{
		// Create the Index buffer
		HRESULT hr = device->CreateIndexBuffer(
		static_cast<UINT>(mSizeInBytes),
		D3D11Mappings::get(mUsage),
		D3D11Mappings::get(mIndexType),
		mD3DPool,
		&mlpD3DBuffer,
		NULL
		);

		if (FAILED(hr))
		{
		String msg = DXGetErrorDescription(hr);
		OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
		"Cannot create D3D11 Index buffer: " + msg,
		"D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer");
		}

		return true;
		}
		return false;
		*/
		return true;
	}
	//---------------------------------------------------------------------
	ID3D11Buffer * D3D11HardwareVertexBuffer::getD3DVertexBuffer( void ) const
	{
		return mBufferImpl->getD3DBuffer();
	}
	//---------------------------------------------------------------------

}

<commit_msg>D3D11 render system: Added code to support copy of vertex buffers that where allocated in system memory. (The terrain sample does such a copy).<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreD3D11HardwareVertexBuffer.h"
#include "OgreD3D11HardwareBuffer.h"
#include "OgreD3D11Device.h"

namespace Ogre {

	//---------------------------------------------------------------------
	D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize,
		size_t numVertices, HardwareBuffer::Usage usage, D3D11Device & device,
		bool useSystemMemory, bool useShadowBuffer)
		: HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMemory, useShadowBuffer),
		  mBufferImpl(0)

	{
		// everything is done via internal generalisation
		mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER,
			mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer);

	}
	//---------------------------------------------------------------------
	D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer()
	{
		SAFE_DELETE(mBufferImpl);
	}
	//---------------------------------------------------------------------
	void* D3D11HardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options)
	{
		return mBufferImpl->lock(offset, length, options);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::unlock(void)
	{
		mBufferImpl->unlock();
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest)
	{
		mBufferImpl->readData(offset, length, pDest);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource,
		bool discardWholeBuffer)
	{
		mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer);
	}
	//---------------------------------------------------------------------
	void D3D11HardwareVertexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset,
		size_t dstOffset, size_t length, bool discardWholeBuffer)
	{
		// check if the other buffer is also a D3D11HardwareVertexBuffer
		if (srcBuffer.isSystemMemory())
		{
			// src is not not a D3D11HardwareVertexBuffer - use default copy
			HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer);
		}
		else
		{
			// src is a D3D11HardwareVertexBuffer use d3d11 optimized copy
			D3D11HardwareVertexBuffer& d3dBuf = static_cast<D3D11HardwareVertexBuffer&>(srcBuffer);

			mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer);
		}
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::isLocked(void) const
	{
		return mBufferImpl->isLocked();
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::releaseIfDefaultPool(void)
	{
		/*		if (mD3DPool == D3DPOOL_DEFAULT)
		{
		SAFE_RELEASE(mlpD3DBuffer);
		return true;
		}
		return false;
		*/
		return true;
	}
	//---------------------------------------------------------------------
	bool D3D11HardwareVertexBuffer::recreateIfDefaultPool(D3D11Device & device)
	{
		/*	if (mD3DPool == D3DPOOL_DEFAULT)
		{
		// Create the Index buffer
		HRESULT hr = device->CreateIndexBuffer(
		static_cast<UINT>(mSizeInBytes),
		D3D11Mappings::get(mUsage),
		D3D11Mappings::get(mIndexType),
		mD3DPool,
		&mlpD3DBuffer,
		NULL
		);

		if (FAILED(hr))
		{
		String msg = DXGetErrorDescription(hr);
		OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
		"Cannot create D3D11 Index buffer: " + msg,
		"D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer");
		}

		return true;
		}
		return false;
		*/
		return true;
	}
	//---------------------------------------------------------------------
	ID3D11Buffer * D3D11HardwareVertexBuffer::getD3DVertexBuffer( void ) const
	{
		return mBufferImpl->getD3DBuffer();
	}
	//---------------------------------------------------------------------

}

<|endoftext|>


<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Rice University
*  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 the Rice University 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.
*********************************************************************/

/* Author: Ioan Sucan */

#include "ompl/base/Planner.h"
#include "ompl/util/Exception.h"
#include "ompl/base/GoalSampleableRegion.h"
#include <boost/thread.hpp>
#include <utility>

ompl::base::Planner::Planner(const SpaceInformationPtr &si, const std::string &name) :
    si_(si), pis_(this), name_(name), type_(PLAN_UNKNOWN), setup_(false), msg_(name)
{
    if (!si_)
	throw Exception(name_, "Invalid space information instance for planner");
}

ompl::base::PlannerType ompl::base::Planner::getType(void) const
{
    return type_;
}

const std::string& ompl::base::Planner::getName(void) const
{
    return name_;
}

void ompl::base::Planner::setName(const std::string &name)
{
    name_ = name;
}

const ompl::base::SpaceInformationPtr&  ompl::base::Planner::getSpaceInformation(void) const
{
    return si_;
}

const ompl::base::ProblemDefinitionPtr& ompl::base::Planner::getProblemDefinition(void) const
{
    return pdef_;
}

void ompl::base::Planner::setProblemDefinition(const ProblemDefinitionPtr &pdef)
{
    pdef_ = pdef;
    pis_.update();
}

void ompl::base::Planner::setup(void)
{
    if (!si_->isSetup())
    {
	msg_.inform("Space information setup was not yet called. Calling now.");
	si_->setup();
    }

    if (setup_)
	msg_.warn("Planner setup called multiple times");
    else
	setup_ = true;
}

bool ompl::base::Planner::isSetup(void) const
{
    return setup_;
}

void ompl::base::Planner::clear(void)
{
    pis_.clear();
    pis_.update();
}

void ompl::base::Planner::getPlannerData(PlannerData &data) const
{
    data.clear();
    data.si = si_;
}

namespace ompl
{
    // return true if a certain point in time has passed
    static bool timePassed(const time::point &endTime)
    {
	return time::now() > endTime;
    }

    // return if an externally passed flag is true
    static bool evaluateFlag(const bool *flag)
    {
	return *flag;
    }

    // periodically evaluate a termination condition and store the result at an indicated location
    static void periodicConditionEvaluator(const base::PlannerTerminationCondition &ptc, double checkInterval, bool *flag)
    {
	time::duration s = time::seconds(checkInterval);
	do
	{
	    bool shouldTerminate = ptc();
	    if (shouldTerminate)
		*flag = true;
	    if (*flag == false)
		boost::this_thread::sleep(s);
	} while (*flag == false);
    }

    static bool alwaysTrue(void)
    {
	return true;
    }
}

bool ompl::base::Planner::solve(const PlannerTerminationCondition &ptc, double checkInterval)
{
    bool flag = false;
    boost::thread condEvaluator(boost::bind(&periodicConditionEvaluator, ptc, checkInterval, &flag));
    bool result = solve(boost::bind(&evaluateFlag, &flag));
    flag = true;
    condEvaluator.interrupt();
    condEvaluator.join();
    return result;
}

bool ompl::base::Planner::solve(double solveTime)
{
    if (solveTime < 1.0)
	return solve(boost::bind(&timePassed, time::now() + time::seconds(solveTime)));
    else
	return solve(boost::bind(&timePassed, time::now() + time::seconds(solveTime)), std::min(solveTime / 100.0, 0.1));
}

void ompl::base::PlannerData::clear(void)
{
    stateIndex.clear();
    states.clear();
    edges.clear();
    properties.clear();
    si.reset();
}

void ompl::base::PlannerData::recordEdge(const State *s1, const State *s2)
{
    if (s1 == NULL || s2 == NULL)
    {
	const State *s = s1 == NULL ? s2 : s1;
	if (s != NULL)
	{
	    std::map<const State*, unsigned int>::iterator it = stateIndex.find(s);
	    if (it == stateIndex.end())
	    {
		unsigned int p = states.size();
		states.push_back(s);
		stateIndex[s] = p;
		edges.resize(states.size());
	    }
	}
    }
    else
    {
	std::map<const State*, unsigned int>::iterator it1 = stateIndex.find(s1);
	std::map<const State*, unsigned int>::iterator it2 = stateIndex.find(s2);

	unsigned int p1;
	if (it1 == stateIndex.end())
	{
	    p1 = states.size();
	    states.push_back(s1);
	    stateIndex[s1] = p1;
	    edges.resize(states.size());
	}
	else
	    p1 = it1->second;

	unsigned int p2;
	if (it2 == stateIndex.end())
	{
	    p2 = states.size();
	    states.push_back(s2);
	    stateIndex[s2] = p2;
	    edges.resize(states.size());
	}
	else
	    p2 = it2->second;

	edges[p1].push_back(p2);
    }
}

void ompl::base::PlannerData::print(std::ostream &out) const
{
    out << states.size() << std::endl;
    for (unsigned int i = 0 ; i < states.size() ; ++i)
    {
	out << i << ": ";
	if (si)
	    si->printState(states[i], out);
	else
	    out << states[i] << std::endl;
    }

    for (unsigned int i = 0 ; i < edges.size() ; ++i)
    {
	if (edges[i].empty())
	    continue;
	out << i << ": ";
	for (unsigned int j = 0 ; j < edges[i].size() ; ++j)
	    out << edges[i][j] << ' ';
	out << std::endl;
    }
}

void ompl::base::PlannerInputStates::clear(void)
{
    if (tempState_)
    {
	si_->freeState(tempState_);
	tempState_ = NULL;
    }
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
    pdef_ = NULL;
    si_ = NULL;
}

bool ompl::base::PlannerInputStates::update(void)
{
    if (!planner_)
	throw Exception("No planner set for PlannerInputStates");
    return use(planner_->getSpaceInformation(), planner_->getProblemDefinition());
}

void ompl::base::PlannerInputStates::checkValidity(void) const
{
    std::string error;

    if (!pdef_)
	error = "Problem definition not specified";
    else
    {
	if (pdef_->getStartStateCount() <= 0)
	    error = "No start states specified";
	else
	    if (!pdef_->getGoal())
		error = "No goal specified";
    }

    if (!error.empty())
    {
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformationPtr &si, const ProblemDefinitionPtr &pdef)
{
    if (si && pdef)
	return use(si.get(), pdef.get());
    else
    {
	clear();
	return true;
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformation *si, const ProblemDefinition *pdef)
{
    if (pdef_ != pdef || si_ != si)
    {
	clear();
	pdef_ = pdef;
	si_ = si;
	return true;
    }
    return false;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextStart(void)
{
    if (pdef_ == NULL || si_ == NULL)
    {
	std::string error = "Missing space information or problem definition";
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }

    while (addedStartStates_ < pdef_->getStartStateCount())
    {
	const base::State *st = pdef_->getStartState(addedStartStates_);
	addedStartStates_++;
	if (si_->satisfiesBounds(st) && si_->isValid(st))
	    return st;
	else
	{
	    msg::Interface msg(planner_ ? planner_->getName() : "");
	    msg.warn("Skipping invalid start state");
	}
    }
    return NULL;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(void)
{
    static PlannerTerminationCondition ptc = boost::bind(&alwaysTrue);
    return nextGoal(ptc);
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(const PlannerTerminationCondition &ptc)
{
    if (pdef_ == NULL || si_ == NULL)
    {
	std::string error = "Missing space information or problem definition";
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }

    const GoalSampleableRegion *goal = dynamic_cast<const GoalSampleableRegion*>(pdef_->getGoal().get());

    if (goal)
	if (sampledGoalsCount_ < goal->maxSampleCount())
	{
	    if (tempState_ == NULL)
		tempState_ = si_->allocState();

	    do
	    {
		goal->sampleGoal(tempState_);
		sampledGoalsCount_++;

		if (si_->satisfiesBounds(tempState_) && si_->isValid(tempState_))
		    return tempState_;
		else
		{
		    msg::Interface msg(planner_ ? planner_->getName() : "");
		    msg.warn("Skipping invalid goal state");
		}
	    }
	    while (sampledGoalsCount_ < goal->maxSampleCount() && !ptc());
	}
    return NULL;
}

bool ompl::base::PlannerInputStates::haveMoreStartStates(void) const
{
    if (pdef_)
	return addedStartStates_ < pdef_->getStartStateCount();
    return false;
}

bool ompl::base::PlannerInputStates::haveMoreGoalStates(void) const
{
    if (pdef_ && pdef_->getGoal())
    {
	const GoalSampleableRegion *goal = dynamic_cast<const GoalSampleableRegion*>(pdef_->getGoal().get());
	if (goal)
	    return sampledGoalsCount_ < goal->maxSampleCount();
    }
    return false;
}
<commit_msg>no need to wait for maxSampleCount() > 0 when using GoalLazySamples<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Rice University
*  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 the Rice University 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.
*********************************************************************/

/* Author: Ioan Sucan */

#include "ompl/base/Planner.h"
#include "ompl/util/Exception.h"
#include "ompl/base/GoalSampleableRegion.h"
#include "ompl/base/GoalLazySamples.h"
#include <boost/thread.hpp>
#include <utility>

ompl::base::Planner::Planner(const SpaceInformationPtr &si, const std::string &name) :
    si_(si), pis_(this), name_(name), type_(PLAN_UNKNOWN), setup_(false), msg_(name)
{
    if (!si_)
	throw Exception(name_, "Invalid space information instance for planner");
}

ompl::base::PlannerType ompl::base::Planner::getType(void) const
{
    return type_;
}

const std::string& ompl::base::Planner::getName(void) const
{
    return name_;
}

void ompl::base::Planner::setName(const std::string &name)
{
    name_ = name;
}

const ompl::base::SpaceInformationPtr&  ompl::base::Planner::getSpaceInformation(void) const
{
    return si_;
}

const ompl::base::ProblemDefinitionPtr& ompl::base::Planner::getProblemDefinition(void) const
{
    return pdef_;
}

void ompl::base::Planner::setProblemDefinition(const ProblemDefinitionPtr &pdef)
{
    pdef_ = pdef;
    pis_.update();
}

void ompl::base::Planner::setup(void)
{
    if (!si_->isSetup())
    {
	msg_.inform("Space information setup was not yet called. Calling now.");
	si_->setup();
    }

    if (setup_)
	msg_.warn("Planner setup called multiple times");
    else
	setup_ = true;
}

bool ompl::base::Planner::isSetup(void) const
{
    return setup_;
}

void ompl::base::Planner::clear(void)
{
    pis_.clear();
    pis_.update();
}

void ompl::base::Planner::getPlannerData(PlannerData &data) const
{
    data.clear();
    data.si = si_;
}

namespace ompl
{
    // return true if a certain point in time has passed
    static bool timePassed(const time::point &endTime)
    {
	return time::now() > endTime;
    }

    // return if an externally passed flag is true
    static bool evaluateFlag(const bool *flag)
    {
	return *flag;
    }

    // periodically evaluate a termination condition and store the result at an indicated location
    static void periodicConditionEvaluator(const base::PlannerTerminationCondition &ptc, double checkInterval, bool *flag)
    {
	time::duration s = time::seconds(checkInterval);
	do
	{
	    bool shouldTerminate = ptc();
	    if (shouldTerminate)
		*flag = true;
	    if (*flag == false)
		boost::this_thread::sleep(s);
	} while (*flag == false);
    }

    static bool alwaysTrue(void)
    {
	return true;
    }
}

bool ompl::base::Planner::solve(const PlannerTerminationCondition &ptc, double checkInterval)
{
    bool flag = false;
    boost::thread condEvaluator(boost::bind(&periodicConditionEvaluator, ptc, checkInterval, &flag));
    bool result = solve(boost::bind(&evaluateFlag, &flag));
    flag = true;
    condEvaluator.interrupt();
    condEvaluator.join();
    return result;
}

bool ompl::base::Planner::solve(double solveTime)
{
    if (solveTime < 1.0)
	return solve(boost::bind(&timePassed, time::now() + time::seconds(solveTime)));
    else
	return solve(boost::bind(&timePassed, time::now() + time::seconds(solveTime)), std::min(solveTime / 100.0, 0.1));
}

void ompl::base::PlannerData::clear(void)
{
    stateIndex.clear();
    states.clear();
    edges.clear();
    properties.clear();
    si.reset();
}

void ompl::base::PlannerData::recordEdge(const State *s1, const State *s2)
{
    if (s1 == NULL || s2 == NULL)
    {
	const State *s = s1 == NULL ? s2 : s1;
	if (s != NULL)
	{
	    std::map<const State*, unsigned int>::iterator it = stateIndex.find(s);
	    if (it == stateIndex.end())
	    {
		unsigned int p = states.size();
		states.push_back(s);
		stateIndex[s] = p;
		edges.resize(states.size());
	    }
	}
    }
    else
    {
	std::map<const State*, unsigned int>::iterator it1 = stateIndex.find(s1);
	std::map<const State*, unsigned int>::iterator it2 = stateIndex.find(s2);

	unsigned int p1;
	if (it1 == stateIndex.end())
	{
	    p1 = states.size();
	    states.push_back(s1);
	    stateIndex[s1] = p1;
	    edges.resize(states.size());
	}
	else
	    p1 = it1->second;

	unsigned int p2;
	if (it2 == stateIndex.end())
	{
	    p2 = states.size();
	    states.push_back(s2);
	    stateIndex[s2] = p2;
	    edges.resize(states.size());
	}
	else
	    p2 = it2->second;

	edges[p1].push_back(p2);
    }
}

void ompl::base::PlannerData::print(std::ostream &out) const
{
    out << states.size() << std::endl;
    for (unsigned int i = 0 ; i < states.size() ; ++i)
    {
	out << i << ": ";
	if (si)
	    si->printState(states[i], out);
	else
	    out << states[i] << std::endl;
    }

    for (unsigned int i = 0 ; i < edges.size() ; ++i)
    {
	if (edges[i].empty())
	    continue;
	out << i << ": ";
	for (unsigned int j = 0 ; j < edges[i].size() ; ++j)
	    out << edges[i][j] << ' ';
	out << std::endl;
    }
}

void ompl::base::PlannerInputStates::clear(void)
{
    if (tempState_)
    {
	si_->freeState(tempState_);
	tempState_ = NULL;
    }
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
    pdef_ = NULL;
    si_ = NULL;
}

bool ompl::base::PlannerInputStates::update(void)
{
    if (!planner_)
	throw Exception("No planner set for PlannerInputStates");
    return use(planner_->getSpaceInformation(), planner_->getProblemDefinition());
}

void ompl::base::PlannerInputStates::checkValidity(void) const
{
    std::string error;

    if (!pdef_)
	error = "Problem definition not specified";
    else
    {
	if (pdef_->getStartStateCount() <= 0)
	    error = "No start states specified";
	else
	    if (!pdef_->getGoal())
		error = "No goal specified";
    }

    if (!error.empty())
    {
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformationPtr &si, const ProblemDefinitionPtr &pdef)
{
    if (si && pdef)
	return use(si.get(), pdef.get());
    else
    {
	clear();
	return true;
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformation *si, const ProblemDefinition *pdef)
{
    if (pdef_ != pdef || si_ != si)
    {
	clear();
	pdef_ = pdef;
	si_ = si;
	return true;
    }
    return false;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextStart(void)
{
    if (pdef_ == NULL || si_ == NULL)
    {
	std::string error = "Missing space information or problem definition";
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }

    while (addedStartStates_ < pdef_->getStartStateCount())
    {
	const base::State *st = pdef_->getStartState(addedStartStates_);
	addedStartStates_++;
	if (si_->satisfiesBounds(st) && si_->isValid(st))
	    return st;
	else
	{
	    msg::Interface msg(planner_ ? planner_->getName() : "");
	    msg.warn("Skipping invalid start state");
	}
    }
    return NULL;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(void)
{
    static PlannerTerminationCondition ptc = boost::bind(&alwaysTrue);
    return nextGoal(ptc);
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(const PlannerTerminationCondition &ptc)
{
    if (pdef_ == NULL || si_ == NULL)
    {
	std::string error = "Missing space information or problem definition";
	if (planner_)
	    throw Exception(planner_->getName(), error);
	else
	    throw Exception(error);
    }

    const GoalSampleableRegion *goal = dynamic_cast<const GoalSampleableRegion*>(pdef_->getGoal().get());

    if (goal)
    {
	const GoalLazySamples *gls = dynamic_cast<const GoalLazySamples*>(goal);
	bool attempt = true;
	while (attempt)
	{
	    attempt = false;

	    if (sampledGoalsCount_ < goal->maxSampleCount())
	    {
		if (tempState_ == NULL)
		    tempState_ = si_->allocState();

		do
		{
		    goal->sampleGoal(tempState_);
		    sampledGoalsCount_++;

		    if (si_->satisfiesBounds(tempState_) && si_->isValid(tempState_))
			return tempState_;
		    else
		    {
			msg::Interface msg(planner_ ? planner_->getName() : "");
			msg.warn("Skipping invalid goal state");
		    }
		}
		while (sampledGoalsCount_ < goal->maxSampleCount() && !ptc());
	    }

	    if (gls && !ptc())
	    {
		boost::this_thread::sleep(time::seconds(0.01));
		attempt = !ptc();
	    }
	}
    }
    return NULL;
}

bool ompl::base::PlannerInputStates::haveMoreStartStates(void) const
{
    if (pdef_)
	return addedStartStates_ < pdef_->getStartStateCount();
    return false;
}

bool ompl::base::PlannerInputStates::haveMoreGoalStates(void) const
{
    if (pdef_ && pdef_->getGoal())
    {
	const GoalSampleableRegion *goal = dynamic_cast<const GoalSampleableRegion*>(pdef_->getGoal().get());
	if (goal)
	    return sampledGoalsCount_ < goal->maxSampleCount();
    }
    return false;
}
<|endoftext|>