<commit_before>/*
  Copyright 2009 Larry Gritz and the other authors and contributors.
  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 software's owners 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.

  (This is the Modified BSD License)
*/

#include "py_oiio.h"

namespace PyOpenImageIO
{
using namespace boost::python;
using namespace OpenImageIO;

// This our stand-in ProgressCallback which allows oiio to call a Python function.
bool PythonProgressCallback(void* opaque_data, float portion_done)
{
	// When oiio calls our ProgressCallback, it will give back the opaque_data which
	// we can turn back into a Python object, which will turn out to be the
	// function we are supposed to call.
	boost::python::object* obj = reinterpret_cast<boost::python::object*>(opaque_data);

	// One-liner to call the function and return a result as a bool
	return boost::python::extract<bool>((*obj)(portion_done));
}

// This is standing in for a method from oiio which takes a ProgressCallback.
void progress_callback_example_original(ProgressCallback pc, void* opaque_data)
{
	for (float f = 0.0; f < 10.0; ++f)
	{
		bool result = pc(opaque_data, f);
		if (!result)
		{
			std::cout << "Callback example terminated at " << f << std::endl;
			return;
		}
	}
}

// This is a wrapper for the above stand-in oiio function.
void progress_callback_wrapper(object progress_callback)
{
	// Casting the object to a pointer is kind of dangerious, but safe in this case
	// because we know its lifetime will be tied to this function.
	progress_callback_example_original(&PythonProgressCallback, &progress_callback);
}

object create_array(int length)
{
	// Make some dummy data - this would normally be coming
	// from oiio, and wouldn't necessarily be int. In fact,
	// it would usually be void - we'd have to determine the
	// desired type from the TypeDesc.
	int* test = new int[length];
	for (int i = 0; i < length; ++i) test[i] = i;

	// Import the Python array module and instantly wrap it
	// in a Boost.Python handle. This means BP will take care
	// of reference-counting Python objects for us.
	object module(handle<>(PyImport_ImportModule("array")));

	// This is Boost.Python's way of finding and calling a
	// function within the module. It's a bit like doing
	// >>> import array as module
	// >>> array = getattr(module, "array")("i")
	object array = module.attr("array")("i");

	// Now for something ugly. The array module doesn't
	// provide a convenient way to construct an array
	// from C, so we will abuse the fromstring method.
	// First we create a Python string using the most
	// direct method available to us (i.e. avoiding boost)
	// and then we pass that into the fromstring method.
	// It only actually results in one extra copy so it's
	// not all that bad.
	object data(
		handle<>(
			PyString_FromStringAndSize(
					reinterpret_cast<const char*>(test),
					sizeof(int) * length)));

	array.attr("fromstring")(data);

	// Tidy up and prove to ourselves that the returned
	// array really stands on its own.
	delete[] test;

	return array;
}

// OIIO often expects the user to allocate an array, pass in
// the pointer and have that array filled. Python provides
// the buffer interface for that. The array module is one way
// of creating a buffer. If an array is passed into this
// function, it will be treated as an int array and filled
// with int data. So it's up to the user to pass the right
// kind of array, of the right size - just like the OIIO C++
// interface.
void fill_array(const object& buffer)
{
	// We'll pretend it's an int array but we don't actually
	// know - it's just an area of memory.
	int* array;
	Py_ssize_t length;
	int success = PyObject_AsWriteBuffer(buffer.ptr(), reinterpret_cast<void**>(&array), &length);

	// throw_error_already_set is Boost.Python's way of
	// throwing Python exceptions from within C++.
	if (success != 0) throw_error_already_set();

	// Fill the buffer with dummy data.
	for (int i = 0; i < length / static_cast<int>(sizeof(int)); ++i)
	{
		array[i] = i;
	}
}

void print_array(const object& buffer)
{
	using namespace std;

	object module(handle<>(PyImport_ImportModule("array")));

	int isArray = PyObject_IsInstance(buffer.ptr(), object(module.attr("array")).ptr());
	if (isArray == -1) throw_error_already_set();

	char type = 'i';
	int size = sizeof(int);

	if (isArray) {
		type = extract<string>(buffer.attr("typecode"))()[0];
		size = extract<int>(buffer.attr("itemsize"));
	}

	const void* array;
	Py_ssize_t length;
	int success = PyObject_AsReadBuffer(buffer.ptr(), &array, &length);

    if (success != 0) boost::python::throw_error_already_set();

	switch (type)
	{
	case 'i':
		for (int i = 0; i < length / size; ++i) cout << ((int*)array)[i] << endl;
		break;
	case 'f':
		for (int i = 0; i < length / size; ++i) cout << ((float*)array)[i] << endl;
		break;
	case 'c':
		for (int i = 0; i < length / size; ++i) cout << ((char*)array)[i] << endl;
		break;
	default:
		throw std::runtime_error("Can't print this array type");
	}
}

bool PyProgressCallback(void *function, float data) {
    boost::python::object *func = reinterpret_cast<boost::python::object*>(function);
    return boost::python::extract<bool>((*func)(data));
}

BOOST_PYTHON_MODULE(OpenImageIO) {
    declare_imageinput();
    declare_imagespec();
    declare_imageoutput();
    declare_typedesc();
    declare_imagecache();
    declare_imagebuf();
    declare_paramvalue();
	def("progress_callback_example", &progress_callback_wrapper);
	def("create_array", &create_array);
	def("fill_array",   &fill_array);
	def("print_array",  &print_array);
}

} // namespace PyOpenImageIO

<commit_msg>Python: to/from Python conversion for ustring<commit_after>/*
  Copyright 2009 Larry Gritz and the other authors and contributors.
  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 software's owners 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.

  (This is the Modified BSD License)
*/

#include "py_oiio.h"

namespace PyOpenImageIO
{
using namespace boost::python;
using namespace OpenImageIO;

// This our stand-in ProgressCallback which allows oiio to call a Python function.
bool PythonProgressCallback(void* opaque_data, float portion_done)
{
	// When oiio calls our ProgressCallback, it will give back the opaque_data which
	// we can turn back into a Python object, which will turn out to be the
	// function we are supposed to call.
	boost::python::object* obj = reinterpret_cast<boost::python::object*>(opaque_data);

	// One-liner to call the function and return a result as a bool
	return boost::python::extract<bool>((*obj)(portion_done));
}

// This is standing in for a method from oiio which takes a ProgressCallback.
void progress_callback_example_original(ProgressCallback pc, void* opaque_data)
{
	for (float f = 0.0; f < 10.0; ++f)
	{
		bool result = pc(opaque_data, f);
		if (!result)
		{
			std::cout << "Callback example terminated at " << f << std::endl;
			return;
		}
	}
}

// This is a wrapper for the above stand-in oiio function.
void progress_callback_wrapper(object progress_callback)
{
	// Casting the object to a pointer is kind of dangerious, but safe in this case
	// because we know its lifetime will be tied to this function.
	progress_callback_example_original(&PythonProgressCallback, &progress_callback);
}

object create_array(int length)
{
	// Make some dummy data - this would normally be coming
	// from oiio, and wouldn't necessarily be int. In fact,
	// it would usually be void - we'd have to determine the
	// desired type from the TypeDesc.
	int* test = new int[length];
	for (int i = 0; i < length; ++i) test[i] = i;

	// Import the Python array module and instantly wrap it
	// in a Boost.Python handle. This means BP will take care
	// of reference-counting Python objects for us.
	object module(handle<>(PyImport_ImportModule("array")));

	// This is Boost.Python's way of finding and calling a
	// function within the module. It's a bit like doing
	// >>> import array as module
	// >>> array = getattr(module, "array")("i")
	object array = module.attr("array")("i");

	// Now for something ugly. The array module doesn't
	// provide a convenient way to construct an array
	// from C, so we will abuse the fromstring method.
	// First we create a Python string using the most
	// direct method available to us (i.e. avoiding boost)
	// and then we pass that into the fromstring method.
	// It only actually results in one extra copy so it's
	// not all that bad.
	object data(
		handle<>(
			PyString_FromStringAndSize(
					reinterpret_cast<const char*>(test),
					sizeof(int) * length)));

	array.attr("fromstring")(data);

	// Tidy up and prove to ourselves that the returned
	// array really stands on its own.
	delete[] test;

	return array;
}

// OIIO often expects the user to allocate an array, pass in
// the pointer and have that array filled. Python provides
// the buffer interface for that. The array module is one way
// of creating a buffer. If an array is passed into this
// function, it will be treated as an int array and filled
// with int data. So it's up to the user to pass the right
// kind of array, of the right size - just like the OIIO C++
// interface.
void fill_array(const object& buffer)
{
	// We'll pretend it's an int array but we don't actually
	// know - it's just an area of memory.
	int* array;
	Py_ssize_t length;
	int success = PyObject_AsWriteBuffer(buffer.ptr(), reinterpret_cast<void**>(&array), &length);

	// throw_error_already_set is Boost.Python's way of
	// throwing Python exceptions from within C++.
	if (success != 0) throw_error_already_set();

	// Fill the buffer with dummy data.
	for (int i = 0; i < length / static_cast<int>(sizeof(int)); ++i)
	{
		array[i] = i;
	}
}

void print_array(const object& buffer)
{
	using namespace std;

	object module(handle<>(PyImport_ImportModule("array")));

	int isArray = PyObject_IsInstance(buffer.ptr(), object(module.attr("array")).ptr());
	if (isArray == -1) throw_error_already_set();

	char type = 'i';
	int size = sizeof(int);

	if (isArray) {
		type = extract<string>(buffer.attr("typecode"))()[0];
		size = extract<int>(buffer.attr("itemsize"));
	}

	const void* array;
	Py_ssize_t length;
	int success = PyObject_AsReadBuffer(buffer.ptr(), &array, &length);

    if (success != 0) boost::python::throw_error_already_set();

	switch (type)
	{
	case 'i':
		for (int i = 0; i < length / size; ++i) cout << ((int*)array)[i] << endl;
		break;
	case 'f':
		for (int i = 0; i < length / size; ++i) cout << ((float*)array)[i] << endl;
		break;
	case 'c':
		for (int i = 0; i < length / size; ++i) cout << ((char*)array)[i] << endl;
		break;
	default:
		throw std::runtime_error("Can't print this array type");
	}
}

bool PyProgressCallback(void *function, float data) {
    boost::python::object *func = reinterpret_cast<boost::python::object*>(function);
    return boost::python::extract<bool>((*func)(data));
}

struct ustring_to_python_str {
    static PyObject* convert(ustring const& s) {
        return boost::python::incref(boost::python::object(s.string()).ptr());
    }
};

struct ustring_from_python_str
{
    ustring_from_python_str() {
        boost::python::converter::registry::push_back(
                &convertible,
                &construct,
                boost::python::type_id<ustring>());
    }

    static void* convertible(PyObject* obj_ptr) {
        if (!PyString_Check(obj_ptr)) return 0;
        return obj_ptr;
    }

    static void construct(
            PyObject* obj_ptr,
            boost::python::converter::rvalue_from_python_stage1_data* data) {
        const char* value = PyString_AsString(obj_ptr);
        if (value == 0) boost::python::throw_error_already_set();
        void* storage = (
                (boost::python::converter::rvalue_from_python_storage<ustring>*)
                data)->storage.bytes;
        new (storage) ustring(value);
        data->convertible = storage;
    }
};

BOOST_PYTHON_MODULE(OpenImageIO) {

    boost::python::to_python_converter<
        ustring,
        ustring_to_python_str>();

    ustring_from_python_str();

    declare_imageinput();
    declare_imagespec();
    declare_imageoutput();
    declare_typedesc();
    declare_imagecache();
    declare_imagebuf();
    declare_paramvalue();
	def("progress_callback_example", &progress_callback_wrapper);
	def("create_array", &create_array);
	def("fill_array",   &fill_array);
	def("print_array",  &print_array);
}

} // namespace PyOpenImageIO

<|endoftext|>


<commit_before>#ifdef WIN32
#define UNICODE
#define _UNICODE

#include <stdlib.h>

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
(JNIEnv *, jclass, jlong hkey)
{
    return RegCloseKey((HKEY)hkey);
}

JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);

    RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
                   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
                   NULL, &hkeyResult, NULL);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LONG    lResult  = RegDeleteKey((HKEY)hkey, lpSubkey);
    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return lResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lResult     = RegDeleteValue((HKEY)hkey, lpValueName);
    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return lResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szBuffer[MAX_PATH + 1];

    if(RegEnumKey((HKEY)hkey, index, szBuffer,
                  sizeof(szBuffer)) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szBuffer,
                                   lstrlen(szBuffer));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szValueName[MAX_PATH + 1];
    DWORD   cbValueName = sizeof(szValueName);

    if(RegEnumValue((HKEY)hkey, index, szValueName,
                    &cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szValueName,
                                   lstrlen(szValueName));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
(JNIEnv *env, jclass, long hkey)
{
    return RegFlushKey((HKEY)hkey);
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LPCTSTR lpFile   = (LPCTSTR)env->GetStringChars(file, NULL);

    LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    env->ReleaseStringChars(file, (const jchar *)lpFile);

    return lResult;
}

JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    jsize len = env->GetStringLength(subkey);
    LPTSTR lpSubkey = (LPTSTR)env->GetStringChars(subkey, NULL);
    LPTSTR copy;

    /* required under IBM/WebSphere 4.0 for certain keys */
    if (lpSubkey[len] != '\0') {
        copy = wcsdup(lpSubkey);
        copy[len] = '\0';
    }
    else {
        copy = lpSubkey;
    }
    RegOpenKey((HKEY)hkey, copy, &hkeyResult);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    if (copy != lpSubkey) {
        free(copy);
    }
    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    DWORD   dwResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey, lpValueName,
                                          NULL, (LPDWORD)&dwType,
                                          NULL, &cbValue);

    if(lErr == ERROR_SUCCESS) {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL,
                           NULL, lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                dwResult = *(LPDWORD)lpValue;
                break;
            case REG_SZ:
                dwResult = _ttol((LPCTSTR)lpValue);
                break;
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }
    else
        // Make an error out of not seeing a REG_DWORD
        lErr = ERROR_SUCCESS - 1;

    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    if(lErr != ERROR_SUCCESS)
    {
        jclass cls =
            env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, NULL);
    }

    return dwResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name)
{
    jstring strResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey,
                                          lpValueName, NULL,
                                          (LPDWORD)&dwType, NULL, &cbValue);

    if(lErr == ERROR_SUCCESS)
    {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL, NULL,
                           lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                TCHAR   szBuf[20];
                _ltot(*(LPDWORD)lpValue, szBuf, 10);
                strResult = env->NewString((const jchar *)szBuf,
                                           lstrlen(szBuf));
                break;
            case REG_SZ:
            case REG_EXPAND_SZ: {
                DWORD len;
                LPTSTR dest = NULL;
                len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
                dest = (LPTSTR)malloc(len * sizeof(TCHAR));
                ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
                strResult = env->NewString((const jchar *)dest, len);
                free(dest);
                break;
            }
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }

    env->ReleaseStringChars(name, (const jchar *)lpValueName);

    if(lErr == ERROR_SUCCESS)
        return strResult;
    else
    {
        jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, "");
        return NULL;
    }
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
{
    LPCTSTR lpValueName;

    if(valueName != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    else
        lpValueName = NULL;

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_DWORD, (LPBYTE)&value, sizeof(value));

    if(valueName != NULL)
        env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return iResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
{
    LPCTSTR lpValueName;

    if(name != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    else
        lpValueName = NULL;

    LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_SZ, (LPBYTE)lpValue,
                                (lstrlen(lpValue) + 1) * sizeof(TCHAR));

    if(name != NULL)
        env->ReleaseStringChars(name, (const jchar *)lpValueName);
    env->ReleaseStringChars(value, (const jchar *)lpValue);

    return iResult;
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<commit_msg>more fixes for ibm/websphere4 jdk<commit_after>#ifdef WIN32
#define UNICODE
#define _UNICODE

#include <stdlib.h>

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
(JNIEnv *, jclass, jlong hkey)
{
    return RegCloseKey((HKEY)hkey);
}

JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);

    RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
                   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
                   NULL, &hkeyResult, NULL);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LONG    lResult  = RegDeleteKey((HKEY)hkey, lpSubkey);
    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return lResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lResult     = RegDeleteValue((HKEY)hkey, lpValueName);
    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return lResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szBuffer[MAX_PATH + 1];

    if(RegEnumKey((HKEY)hkey, index, szBuffer,
                  sizeof(szBuffer)) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szBuffer,
                                   lstrlen(szBuffer));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szValueName[MAX_PATH + 1];
    DWORD   cbValueName = sizeof(szValueName);

    if(RegEnumValue((HKEY)hkey, index, szValueName,
                    &cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szValueName,
                                   lstrlen(szValueName));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
(JNIEnv *env, jclass, long hkey)
{
    return RegFlushKey((HKEY)hkey);
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LPCTSTR lpFile   = (LPCTSTR)env->GetStringChars(file, NULL);

    LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    env->ReleaseStringChars(file, (const jchar *)lpFile);

    return lResult;
}

JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    jsize len = env->GetStringLength(subkey);
    LPTSTR lpSubkey = (LPTSTR)env->GetStringChars(subkey, NULL);
    LPTSTR copy;

    /* required under IBM/WebSphere 4.0 for certain keys */
    if (lpSubkey[len] != '\0') {
        copy = wcsdup(lpSubkey);
        copy[len] = '\0';
    }
    else {
        copy = lpSubkey;
    }
    RegOpenKey((HKEY)hkey, copy, &hkeyResult);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    if (copy != lpSubkey) {
        free(copy);
    }
    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    DWORD   dwResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;
    LPTSTR copy;
    jsize len = env->GetStringLength(valueName);
    LPTSTR lpValueName = (LPTSTR)env->GetStringChars(valueName, NULL);
    LONG    lErr;
    /* required under IBM/WebSphere 4.0 for certain keys */
    if (lpValueName[len] != '\0') {
        copy = wcsdup(lpValueName);
        copy[len] = '\0';
    }
    else {
        copy = lpValueName;
    }

    lErr = RegQueryValueEx((HKEY)hkey, copy,
                           NULL, (LPDWORD)&dwType,
                           NULL, &cbValue);
    if(lErr == ERROR_SUCCESS) {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, copy, NULL,
                           NULL, lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                dwResult = *(LPDWORD)lpValue;
                break;
            case REG_SZ:
                dwResult = _ttol((LPCTSTR)lpValue);
                break;
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }
    else
        // Make an error out of not seeing a REG_DWORD
        lErr = ERROR_SUCCESS - 1;

    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
    if (copy != lpValueName) {
        free(copy);
    }

    if(lErr != ERROR_SUCCESS)
    {
        jclass cls =
            env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, NULL);
    }

    return dwResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name)
{
    jstring strResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;
    jsize len = env->GetStringLength(name);
    LPTSTR lpValueName = (LPTSTR)env->GetStringChars(name, NULL);
    LPTSTR copy;
    LONG    lErr;
    /* required under IBM/WebSphere 4.0 for certain keys */
    if (lpValueName[len] != '\0') {
        copy = wcsdup(lpValueName);
        copy[len] = '\0';
    }
    else {
        copy = lpValueName;
    }

    lErr = RegQueryValueEx((HKEY)hkey,
                           copy, NULL,
                           (LPDWORD)&dwType, NULL, &cbValue);
    if(lErr == ERROR_SUCCESS)
    {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, copy, NULL, NULL,
                           lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                TCHAR   szBuf[20];
                _ltot(*(LPDWORD)lpValue, szBuf, 10);
                strResult = env->NewString((const jchar *)szBuf,
                                           lstrlen(szBuf));
                break;
            case REG_SZ:
            case REG_EXPAND_SZ: {
                DWORD len;
                LPTSTR dest = NULL;
                len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
                dest = (LPTSTR)malloc(len * sizeof(TCHAR));
                ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
                strResult = env->NewString((const jchar *)dest, len);
                free(dest);
                break;
            }
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }

    env->ReleaseStringChars(name, (const jchar *)lpValueName);
    if (copy != lpValueName) {
        free(copy);
    }

    if(lErr == ERROR_SUCCESS)
        return strResult;
    else
    {
        jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, "");
        return NULL;
    }
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
{
    LPCTSTR lpValueName;

    if(valueName != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    else
        lpValueName = NULL;

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_DWORD, (LPBYTE)&value, sizeof(value));

    if(valueName != NULL)
        env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return iResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
{
    LPCTSTR lpValueName;

    if(name != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    else
        lpValueName = NULL;

    LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_SZ, (LPBYTE)lpValue,
                                (lstrlen(lpValue) + 1) * sizeof(TCHAR));

    if(name != NULL)
        env->ReleaseStringChars(name, (const jchar *)lpValueName);
    env->ReleaseStringChars(value, (const jchar *)lpValue);

    return iResult;
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <mapnik/raster_colorizer.hpp>

using mapnik::raster_colorizer;
using mapnik::raster_colorizer_ptr;
using mapnik::color_band;
using mapnik::color_bands;
using mapnik::color;

namespace {
void append_band1(raster_colorizer_ptr & rc, color_band b)
{
    rc->append_band(b);
}
void append_band2(raster_colorizer_ptr & rc, color_band b, unsigned m)
{
    rc->append_band(b, m);
}
void append_band3(raster_colorizer_ptr & rc, float v, color c)
{
    rc->append_band(v, c);
}
void append_band4(raster_colorizer_ptr & rc, float v, color c, unsigned m)
{
    rc->append_band(v, c, m);
}
void append_band5(raster_colorizer_ptr & rc, float v, float vm, color c, unsigned m)
{
    rc->append_band(v, vm, c, m);
}
void append_band6(raster_colorizer_ptr & rc, float v, float vm, color c)
{
    rc->append_band(v, vm, c);
}
color_bands const& get_color_bands(raster_colorizer_ptr & rc)
{
    return rc->get_color_bands();
}
}

void export_raster_colorizer()
{
    using namespace boost::python;

    class_<raster_colorizer,raster_colorizer_ptr>("RasterColorizer", init<>("Default ctor."))

        .add_property("bands",make_function
                      (get_color_bands,
                       return_value_policy<reference_existing_object>()))
        .def("append_band", append_band1,
            (arg("color_band")),
            "Append a color band to the raster colorizer.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.ColorBand()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> color_band = mapnik.ColorBand(3, color)\n"
            ">>> colorizer.append_band(color_band)\n"
            )
        .def("append_band", append_band2,
            (arg("color_band"), arg("midpoint")),
            "Append a color band with a midpoint to the raster colorizer.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.ColorBand()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> color_band = mapnik.ColorBand(3, color)\n"
            ">>> colorizer.append_band(color_band, 1)\n"
            )
        .def("append_band", append_band3,
            (arg("value"), arg("color")),
            "Append a color for a specific value to the raster colorizer\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, color)\n"
            )
        .def("append_band", append_band4,
            (arg("value"), arg("color"), arg("midpoints")),
            "Append a color for a certain value to the raster colorizer,\n"
            "with a specified midpoint.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, color, 4)\n"
            )
        .def("append_band", append_band5,
            (arg("value"), arg("value_max"), arg("color"), arg("midpoints")),
            "Append a color for a value range from value to value_max\n"
            "to the raster colorizer, with a specified midpoint.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color, 4)\n"
            )
        .def("append_band", append_band6,
            (arg("value"), arg("value_max"), arg("color")),
            "Append a color for a value range from value to value_max\n"
            "to the raster colorizer.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color)\n"
            )
        .def("get_color", &raster_colorizer::get_color,
            "Get the color assigned to a certain value in raster data.\n"
            "By default, returns Color(\"transparent\")\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color)\n"
            ">>> colorizer.get_color(35)\n"
            "Color('#0044cc')\n"
            )
        ;

    class_<color_bands>("ColorBands",init<>("Default ctor."))
        .def(vector_indexing_suite<color_bands>())
        ;

    class_<color_band>("ColorBand",init<float,color const&>(
                       "A Color Band object.\n"
                       "Create with a value and color\n"
                       "\n"
                       "Usage:"
                       ">>> color = mapnik.Color(\"#fff000\")\n"
                       ">>> color_band = mapnik.ColorBand(4, color)\n"
          ))
        .add_property("color", make_function
                      (&color_band::get_color,
                       return_value_policy<reference_existing_object>()))
        .add_property("value", &color_band::get_value)
        .add_property("max_value", &color_band::get_max_value)
        .def(self == self)
        .def("__str__",&color_band::to_string)
        ;
}
<commit_msg>improved RasterColorizer's docstrings as requested in #619<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <mapnik/raster_colorizer.hpp>

using mapnik::raster_colorizer;
using mapnik::raster_colorizer_ptr;
using mapnik::color_band;
using mapnik::color_bands;
using mapnik::color;

namespace {
void append_band1(raster_colorizer_ptr & rc, color_band b)
{
    rc->append_band(b);
}
void append_band2(raster_colorizer_ptr & rc, color_band b, unsigned m)
{
    rc->append_band(b, m);
}
void append_band3(raster_colorizer_ptr & rc, float v, color c)
{
    rc->append_band(v, c);
}
void append_band4(raster_colorizer_ptr & rc, float v, color c, unsigned m)
{
    rc->append_band(v, c, m);
}
void append_band5(raster_colorizer_ptr & rc, float v, float vm, color c, unsigned m)
{
    rc->append_band(v, vm, c, m);
}
void append_band6(raster_colorizer_ptr & rc, float v, float vm, color c)
{
    rc->append_band(v, vm, c);
}
color_bands const& get_color_bands(raster_colorizer_ptr & rc)
{
    return rc->get_color_bands();
}
}

void export_raster_colorizer()
{
    using namespace boost::python;

    class_<raster_colorizer,raster_colorizer_ptr>("RasterColorizer", init<>("Default ctor."))

        .add_property("bands",make_function
                      (get_color_bands,
                       return_value_policy<reference_existing_object>()))
        .def("append_band", append_band1,
            (arg("color_band")),
            "Append a color band to the raster colorizer.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.ColorBand()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> color_band = mapnik.ColorBand(3, color)\n"
            ">>> colorizer.append_band(color_band)\n"
            )
        .def("append_band", append_band2,
            (arg("color_band"), arg("midpoints")),
            "Append a color band to the raster colorizer with midpoints "
            "lineally interpolated color bands between this one and the "
            "previous one.\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.ColorBand()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> color_band = mapnik.ColorBand(3, color)\n"
            ">>> colorizer.append_band(color_band, 1)\n"
            )
        .def("append_band", append_band3,
            (arg("value"), arg("color")),
            "Create and append a color band to color the range "
            "[value, next_val) where next_val is the next band's color or "
            "inifinity if there is no next band.\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, color)\n"
            )
        .def("append_band", append_band4,
            (arg("value"), arg("color"), arg("midpoints")),
            "Create and append a color band to the raster colorizer with "
            "midpoints lineally interpolated color bands between this one and "
            "the previous one.\n"
            "color will be applied to all values in the "
            "range [value, next_val) where next_val is the next band's color "
            "or infinity if there is no next band\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, color, 4)\n"
            )
        .def("append_band", append_band5,
            (arg("value"), arg("value_max"), arg("color"), arg("midpoints")),
            "Create and append a color band to the raster colorizer with "
            "midpoints lineally interpolated color bands between this one and "
            "the previous one.\n"
            "color will be applied to all values in the "
            "range [value, next_val) where next_val is the next band's color "
            "or value_max if there is no next band\n"
            "\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color, 4)\n"
            )
        .def("append_band", append_band6,
            (arg("value"), arg("value_max"), arg("color")),
            "Create and append a color band to color the range "
            "[value, next_val) where next_val is the next band's color or "
            "value_max if there is no next band.\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color)\n"
            )
        .def("get_color", &raster_colorizer::get_color,
            "Get the color assigned to a certain value in raster data.\n"
            "By default, returns Color(\"transparent\")\n"
            "\n"
            "Usage:\n"
            ">>> colorizer = mapnik.RasterColorizer()\n"
            ">>> color = mapnik.Color(\"#0044cc\")\n"
            ">>> colorizer.append_band(30, 40, color)\n"
            ">>> colorizer.get_color(35)\n"
            "Color('#0044cc')\n"
            )
        ;

    class_<color_bands>("ColorBands",
        "A RasterColorizer's collection of ordered color bands.\n"
        "This class is not meant to be instantiated from python. However, "
        "it can be accessed at a RasterColorizer's \"bands\" attribute for "
        "introspection purposes",
        no_init)
        .def(vector_indexing_suite<color_bands>())
        ;

    class_<color_band>("ColorBand",init<float,color const&>(
                       "A Color Band object.\n"
                       "Create with a value and color\n"
                       "\n"
                       "Usage:"
                       ">>> color = mapnik.Color(\"#fff000\")\n"
                       ">>> color_band = mapnik.ColorBand(4, color)\n"
          ))
        .add_property("color", make_function
                      (&color_band::get_color,
                       return_value_policy<reference_existing_object>()))
        .add_property("value", &color_band::get_value)
        .add_property("max_value", &color_band::get_max_value)
        .def(self == self)
        .def("__str__",&color_band::to_string)
        ;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////////////////////
///
/// @file
/// @author     Kuba Sejdak
/// @date       21.08.2016
///
/// @copyright  This file is a part of cosmos OS. All rights reserved.
///
////////////////////////////////////////////////////////////////////////////////////////////////

#include "beaglebone_black.h"
#include "beaglebone_black_pinmux.h"

#include <core/console.h>
#include <dev/device_manager.h>
#include <dev/gpio.h>
#include <dev/uart.h>
#include <dev/ti_am335x/am335x_gpio.h>
#include <dev/ti_am335x/am335x_uart.h>

using namespace Device;
using namespace Device::GPIO;
using namespace Device::UART;

namespace Board {

IBoard* IBoard::create()
{
    return new BeagleBoneBlack();
}

BeagleBoneBlack::BeagleBoneBlack()
{
    m_name = "BeagleBone Black";
    m_vendor = "Texas Instruments";
    m_version = "1.0";
}

bool BeagleBoneBlack::initDevice()
{
    DeviceManager<IGPIOPort>::init();
    DeviceManager<IUART>::init();

    initUserLED();
    initConsole();

    return true;
}

bool BeagleBoneBlack::initUserLED()
{
    // Init user led0.
    GPIOPin led0(PIN_USER_LED0);
    led0.setFunction(GPIO::PAD_FUNC_7);
    led0.setDirection(DIRECTION_OUTPUT);
    led0.setResistor(RESISTOR_NONE);
    led0.write(true);

    return true;
}

bool BeagleBoneBlack::initConsole()
{
    // Init console on UART1.
    GPIOPin consoleTx(PIN_P9_24);
    consoleTx.setFunction(GPIO::PAD_FUNC_0);
    consoleTx.setDirection(DIRECTION_OUTPUT);

    AM335x_UART consoleUart(UART_1);
    consoleUart.setBaudRate(115200);

    return console.init();

}

} // namespace Board
<commit_msg>board: Initialize console in proper way.<commit_after>////////////////////////////////////////////////////////////////////////////////////////////////
///
/// @file
/// @author     Kuba Sejdak
/// @date       21.08.2016
///
/// @copyright  This file is a part of cosmos OS. All rights reserved.
///
////////////////////////////////////////////////////////////////////////////////////////////////

#include "beaglebone_black.h"
#include "beaglebone_black_pinmux.h"

#include <core/console.h>
#include <dev/device_manager.h>
#include <dev/gpio.h>
#include <dev/uart.h>
#include <dev/ti_am335x/am335x_gpio.h>
#include <dev/ti_am335x/am335x_uart.h>

using namespace Device;
using namespace Device::GPIO;
using namespace Device::UART;

namespace Board {

IBoard* IBoard::create()
{
    return new BeagleBoneBlack();
}

BeagleBoneBlack::BeagleBoneBlack()
{
    m_name = "BeagleBone Black";
    m_vendor = "Texas Instruments";
    m_version = "1.0";
}

bool BeagleBoneBlack::initDevice()
{
    DeviceManager<IGPIOPort>::init();
    DeviceManager<IUART>::init();

    initUserLED();
    initConsole();

    return true;
}

bool BeagleBoneBlack::initUserLED()
{
    // Init user led0.
    GPIOPin led0(PIN_USER_LED0);
    led0.setFunction(GPIO::PAD_FUNC_7);
    led0.setDirection(DIRECTION_OUTPUT);
    led0.setResistor(RESISTOR_NONE);
    led0.write(true);

    return true;
}

bool BeagleBoneBlack::initConsole()
{
    // Init console on UART1.
    GPIOPin consoleTx(PIN_SERIAL_DEBUG_TX);
    consoleTx.setFunction(GPIO::PAD_FUNC_0);
    consoleTx.setDirection(DIRECTION_OUTPUT);
    consoleTx.setResistor(RESISTOR_NONE);

    AM335x_UART consoleUart(UART_0);
    consoleUart.setBaudRate(115200);
    consoleUart.setDataBits(DATA_BITS_8);
    consoleUart.setStopBits(STOP_BITS_1);
    consoleUart.setPartity(PARTITY_NONE);
    consoleUart.setFlowControl(FLOW_CONTROL_NONE);
    consoleUart.setDirection(DIRECTION_WRITE);
    consoleUart.setTransmissionMode(MODE_ASYNCHRONOUS);

    consoleUart.write("DUPA BLADA\r\n", 12);

    return console.init();

}

} // namespace Board
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WrappedIgnoreProperty.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-25 08:48:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CHART_WRAPPED_IGNORE_PROPERTY_HXX
#define CHART_WRAPPED_IGNORE_PROPERTY_HXX

#include "WrappedProperty.hxx"

#include <vector>

//.............................................................................
namespace chart
{
//.............................................................................

class WrappedIgnoreProperty : public WrappedProperty
{
public:
    WrappedIgnoreProperty( const ::rtl::OUString& rOuterName, const ::com::sun::star::uno::Any& rDefaultValue );
    virtual ~WrappedIgnoreProperty();

    virtual void setPropertyValue( const ::com::sun::star::uno::Any& rOuterValue, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xInnerPropertySet ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any getPropertyValue( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xInnerPropertySet ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual void setPropertyToDefault( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any getPropertyDefault( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::beans::PropertyState getPropertyState( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);

protected:
    ::com::sun::star::uno::Any          m_aDefaultValue;
    mutable ::com::sun::star::uno::Any  m_aCurrentValue;
};

class WrappedIgnoreProperties
{
public:
    static void addIgnoreLineProperties( std::vector< WrappedProperty* >& rList );

    static void addIgnoreFillProperties( std::vector< WrappedProperty* >& rList );
    static void addIgnoreFillProperties_without_BitmapProperties( std::vector< WrappedProperty* >& rList );
    static void addIgnoreFillProperties_only_BitmapProperties( std::vector< WrappedProperty* >& rList );
};

//.............................................................................
} //namespace chart
//.............................................................................

// CHART_WRAPPED_IGNORE_PROPERTY_HXX
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.94); FILE MERGED 2008/03/28 16:43:58 rt 1.3.94.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: WrappedIgnoreProperty.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART_WRAPPED_IGNORE_PROPERTY_HXX
#define CHART_WRAPPED_IGNORE_PROPERTY_HXX

#include "WrappedProperty.hxx"

#include <vector>

//.............................................................................
namespace chart
{
//.............................................................................

class WrappedIgnoreProperty : public WrappedProperty
{
public:
    WrappedIgnoreProperty( const ::rtl::OUString& rOuterName, const ::com::sun::star::uno::Any& rDefaultValue );
    virtual ~WrappedIgnoreProperty();

    virtual void setPropertyValue( const ::com::sun::star::uno::Any& rOuterValue, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xInnerPropertySet ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any getPropertyValue( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xInnerPropertySet ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual void setPropertyToDefault( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any getPropertyDefault( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::beans::PropertyState getPropertyState( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const
                        throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);

protected:
    ::com::sun::star::uno::Any          m_aDefaultValue;
    mutable ::com::sun::star::uno::Any  m_aCurrentValue;
};

class WrappedIgnoreProperties
{
public:
    static void addIgnoreLineProperties( std::vector< WrappedProperty* >& rList );

    static void addIgnoreFillProperties( std::vector< WrappedProperty* >& rList );
    static void addIgnoreFillProperties_without_BitmapProperties( std::vector< WrappedProperty* >& rList );
    static void addIgnoreFillProperties_only_BitmapProperties( std::vector< WrappedProperty* >& rList );
};

//.............................................................................
} //namespace chart
//.............................................................................

// CHART_WRAPPED_IGNORE_PROPERTY_HXX
#endif
<|endoftext|>


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

#include "chrome/browser/chrome_process_finder_win.h"

#include <shellapi.h>
#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/process/process_handle.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/message_window.h"
#include "base/win/metro.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "chrome/browser/metro_utils/metro_chrome_win.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"

namespace {

const int kTimeoutInSeconds = 20;

// The following is copied from net/base/escape.cc. We don't want to depend on
// net here because this gets compiled into chrome.exe to facilitate
// fast-rendezvous (see https://codereview.chromium.org/14617003/).

// TODO(koz): Move these functions out of net/base/escape.cc into base/escape.cc
// so we can depend on it directly.

// BEGIN COPY from net/base/escape.cc

// A fast bit-vector map for ascii characters.
//
// Internally stores 256 bits in an array of 8 ints.
// Does quick bit-flicking to lookup needed characters.
struct Charmap {
  bool Contains(unsigned char c) const {
    return ((map[c >> 5] & (1 << (c & 31))) != 0);
  }

  uint32 map[8];
};

const char kHexString[] = "0123456789ABCDEF";
inline char IntToHex(int i) {
  DCHECK_GE(i, 0) << i << " not a hex value";
  DCHECK_LE(i, 15) << i << " not a hex value";
  return kHexString[i];
}

// Given text to escape and a Charmap defining which values to escape,
// return an escaped string.  If use_plus is true, spaces are converted
// to +, otherwise, if spaces are in the charmap, they are converted to
// %20.
std::string Escape(const std::string& text, const Charmap& charmap,
                   bool use_plus) {
  std::string escaped;
  escaped.reserve(text.length() * 3);
  for (unsigned int i = 0; i < text.length(); ++i) {
    unsigned char c = static_cast<unsigned char>(text[i]);
    if (use_plus && ' ' == c) {
      escaped.push_back('+');
    } else if (charmap.Contains(c)) {
      escaped.push_back('%');
      escaped.push_back(IntToHex(c >> 4));
      escaped.push_back(IntToHex(c & 0xf));
    } else {
      escaped.push_back(c);
    }
  }
  return escaped;
}

// Everything except alphanumerics and !'()*-._~
// See RFC 2396 for the list of reserved characters.
static const Charmap kQueryCharmap = {{
  0xffffffffL, 0xfc00987dL, 0x78000001L, 0xb8000001L,
  0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
}};

std::string EscapeQueryParamValue(const std::string& text, bool use_plus) {
  return Escape(text, kQueryCharmap, use_plus);
}

// END COPY from net/base/escape.cc

}  // namespace

namespace chrome {

HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
  return base::win::MessageWindow::FindWindow(user_data_dir.value());
}

NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
                                                bool fast_start) {
  DCHECK(remote_window);
  static const char kSearchUrl[] =
      "http://www.google.com/search?q=%s&sourceid=chrome&ie=UTF-8";
  DWORD process_id = 0;
  DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
  if (!thread_id || !process_id)
    return NOTIFY_FAILED;

  if (base::win::IsMetroProcess()) {
    // Interesting corner case. We are launched as a metro process but we
    // found another chrome running. Since metro enforces single instance then
    // the other chrome must be desktop chrome and this must be a search charm
    // activation. This scenario is unique; other cases should be properly
    // handled by the delegate_execute which will not activate a second chrome.
    string16 terms;
    base::win::MetroLaunchType launch = base::win::GetMetroLaunchParams(&terms);
    if (launch != base::win::METRO_SEARCH) {
      LOG(WARNING) << "In metro mode, but and launch is " << launch;
    } else {
      std::string query = EscapeQueryParamValue(UTF16ToUTF8(terms), true);
      std::string url = base::StringPrintf(kSearchUrl, query.c_str());
      SHELLEXECUTEINFOA sei = { sizeof(sei) };
      sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
      sei.nShow = SW_SHOWNORMAL;
      sei.lpFile = url.c_str();
      OutputDebugStringA(sei.lpFile);
      sei.lpDirectory = "";
      ::ShellExecuteExA(&sei);
    }
    return NOTIFY_SUCCESS;
  }

  base::win::ScopedHandle process_handle;
  if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
      base::OpenProcessHandleWithAccess(
          process_id, PROCESS_QUERY_INFORMATION,
          process_handle.Receive()) &&
      base::win::IsProcessImmersive(process_handle.Get())) {
    chrome::ActivateMetroChrome();
  }

  CommandLine command_line(*CommandLine::ForCurrentProcess());
  command_line.AppendSwitchASCII(
      switches::kOriginalProcessStartTime,
      base::Int64ToString(
          base::CurrentProcessInfo::CreationTime().ToInternalValue()));

  if (fast_start)
    command_line.AppendSwitch(switches::kFastStart);

  // Send the command line to the remote chrome window.
  // Format is "START\0<<<current directory>>>\0<<<commandline>>>".
  std::wstring to_send(L"START\0", 6);  // want the NULL in the string.
  base::FilePath cur_dir;
  if (!file_util::GetCurrentDirectory(&cur_dir))
    return NOTIFY_FAILED;
  to_send.append(cur_dir.value());
  to_send.append(L"\0", 1);  // Null separator.
  to_send.append(command_line.GetCommandLineString());
  to_send.append(L"\0", 1);  // Null separator.

  // Allow the current running browser window to make itself the foreground
  // window (otherwise it will just flash in the taskbar).
  ::AllowSetForegroundWindow(process_id);

  COPYDATASTRUCT cds;
  cds.dwData = 0;
  cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t));
  cds.lpData = const_cast<wchar_t*>(to_send.c_str());
  DWORD_PTR result = 0;
  if (::SendMessageTimeout(remote_window,
                           WM_COPYDATA,
                           NULL,
                           reinterpret_cast<LPARAM>(&cds),
                           SMTO_ABORTIFHUNG,
                           kTimeoutInSeconds * 1000,
                           &result)) {
    return result ? NOTIFY_SUCCESS : NOTIFY_FAILED;
  }

  // It is possible that the process owning this window may have died by now.
  if (!::IsWindow(remote_window))
    return NOTIFY_FAILED;

  // If the window couldn't be notified but still exists, assume it is hung.
  return NOTIFY_WINDOW_HUNG;
}

}  // namespace chrome
<commit_msg>comment metro code in chrome_process_finder_win.cc<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chrome_process_finder_win.h"

#include <shellapi.h>
#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/process/process_handle.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/message_window.h"
#include "base/win/metro.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "chrome/browser/metro_utils/metro_chrome_win.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"

namespace {

const int kTimeoutInSeconds = 20;

// The following is copied from net/base/escape.cc. We don't want to depend on
// net here because this gets compiled into chrome.exe to facilitate
// fast-rendezvous (see https://codereview.chromium.org/14617003/).

// TODO(koz): Move these functions out of net/base/escape.cc into base/escape.cc
// so we can depend on it directly.

// BEGIN COPY from net/base/escape.cc

// A fast bit-vector map for ascii characters.
//
// Internally stores 256 bits in an array of 8 ints.
// Does quick bit-flicking to lookup needed characters.
struct Charmap {
  bool Contains(unsigned char c) const {
    return ((map[c >> 5] & (1 << (c & 31))) != 0);
  }

  uint32 map[8];
};

const char kHexString[] = "0123456789ABCDEF";
inline char IntToHex(int i) {
  DCHECK_GE(i, 0) << i << " not a hex value";
  DCHECK_LE(i, 15) << i << " not a hex value";
  return kHexString[i];
}

// Given text to escape and a Charmap defining which values to escape,
// return an escaped string.  If use_plus is true, spaces are converted
// to +, otherwise, if spaces are in the charmap, they are converted to
// %20.
std::string Escape(const std::string& text, const Charmap& charmap,
                   bool use_plus) {
  std::string escaped;
  escaped.reserve(text.length() * 3);
  for (unsigned int i = 0; i < text.length(); ++i) {
    unsigned char c = static_cast<unsigned char>(text[i]);
    if (use_plus && ' ' == c) {
      escaped.push_back('+');
    } else if (charmap.Contains(c)) {
      escaped.push_back('%');
      escaped.push_back(IntToHex(c >> 4));
      escaped.push_back(IntToHex(c & 0xf));
    } else {
      escaped.push_back(c);
    }
  }
  return escaped;
}

// Everything except alphanumerics and !'()*-._~
// See RFC 2396 for the list of reserved characters.
static const Charmap kQueryCharmap = {{
  0xffffffffL, 0xfc00987dL, 0x78000001L, 0xb8000001L,
  0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
}};

std::string EscapeQueryParamValue(const std::string& text, bool use_plus) {
  return Escape(text, kQueryCharmap, use_plus);
}

// END COPY from net/base/escape.cc

}  // namespace

namespace chrome {

HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
  return base::win::MessageWindow::FindWindow(user_data_dir.value());
}

NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
                                                bool fast_start) {
  DCHECK(remote_window);
  static const char kSearchUrl[] =
      "http://www.google.com/search?q=%s&sourceid=chrome&ie=UTF-8";
  DWORD process_id = 0;
  DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
  if (!thread_id || !process_id)
    return NOTIFY_FAILED;

  if (base::win::IsMetroProcess()) {
    // Interesting corner case. We are launched as a metro process but we
    // found another chrome running. Since metro enforces single instance then
    // the other chrome must be desktop chrome and this must be a search charm
    // activation. This scenario is unique; other cases should be properly
    // handled by the delegate_execute which will not activate a second chrome.
    string16 terms;
    base::win::MetroLaunchType launch = base::win::GetMetroLaunchParams(&terms);
    if (launch != base::win::METRO_SEARCH) {
      LOG(WARNING) << "In metro mode, but and launch is " << launch;
    } else {
      std::string query = EscapeQueryParamValue(UTF16ToUTF8(terms), true);
      std::string url = base::StringPrintf(kSearchUrl, query.c_str());
      SHELLEXECUTEINFOA sei = { sizeof(sei) };
      sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
      sei.nShow = SW_SHOWNORMAL;
      sei.lpFile = url.c_str();
      OutputDebugStringA(sei.lpFile);
      sei.lpDirectory = "";
      ::ShellExecuteExA(&sei);
    }
    return NOTIFY_SUCCESS;
  }

  base::win::ScopedHandle process_handle;
  if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
      base::OpenProcessHandleWithAccess(
          process_id, PROCESS_QUERY_INFORMATION,
          process_handle.Receive()) &&
      base::win::IsProcessImmersive(process_handle.Get())) {
    // chrome::ActivateMetroChrome();
  }

  CommandLine command_line(*CommandLine::ForCurrentProcess());
  command_line.AppendSwitchASCII(
      switches::kOriginalProcessStartTime,
      base::Int64ToString(
          base::CurrentProcessInfo::CreationTime().ToInternalValue()));

  if (fast_start)
    command_line.AppendSwitch(switches::kFastStart);

  // Send the command line to the remote chrome window.
  // Format is "START\0<<<current directory>>>\0<<<commandline>>>".
  std::wstring to_send(L"START\0", 6);  // want the NULL in the string.
  base::FilePath cur_dir;
  if (!file_util::GetCurrentDirectory(&cur_dir))
    return NOTIFY_FAILED;
  to_send.append(cur_dir.value());
  to_send.append(L"\0", 1);  // Null separator.
  to_send.append(command_line.GetCommandLineString());
  to_send.append(L"\0", 1);  // Null separator.

  // Allow the current running browser window to make itself the foreground
  // window (otherwise it will just flash in the taskbar).
  ::AllowSetForegroundWindow(process_id);

  COPYDATASTRUCT cds;
  cds.dwData = 0;
  cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t));
  cds.lpData = const_cast<wchar_t*>(to_send.c_str());
  DWORD_PTR result = 0;
  if (::SendMessageTimeout(remote_window,
                           WM_COPYDATA,
                           NULL,
                           reinterpret_cast<LPARAM>(&cds),
                           SMTO_ABORTIFHUNG,
                           kTimeoutInSeconds * 1000,
                           &result)) {
    return result ? NOTIFY_SUCCESS : NOTIFY_FAILED;
  }

  // It is possible that the process owning this window may have died by now.
  if (!::IsWindow(remote_window))
    return NOTIFY_FAILED;

  // If the window couldn't be notified but still exists, assume it is hung.
  return NOTIFY_WINDOW_HUNG;
}

}  // namespace chrome
<|endoftext|>


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

#include "chrome/browser/chromeos/external_metrics.h"

#include <map>
#include <string>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/chromeos_metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/serialization/metric_sample.h"
#include "components/metrics/serialization/serialization_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h"

using base::UserMetricsAction;
using content::BrowserThread;

namespace chromeos {

namespace {

bool CheckValues(const std::string& name,
                 int minimum,
                 int maximum,
                 size_t bucket_count) {
  if (!base::Histogram::InspectConstructionArguments(
      name, &minimum, &maximum, &bucket_count))
    return false;
  base::HistogramBase* histogram =
      base::StatisticsRecorder::FindHistogram(name);
  if (!histogram)
    return true;
  return histogram->HasConstructionArguments(minimum, maximum, bucket_count);
}

bool CheckLinearValues(const std::string& name, int maximum) {
  return CheckValues(name, 1, maximum, maximum + 1);
}

// Establishes field trial for wifi scanning in chromeos.  crbug.com/242733.
void SetupProgressiveScanFieldTrial() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  const char name_of_experiment[] = "ProgressiveScan";
  const base::FilePath group_file_path(
      "/home/chronos/.progressive_scan_variation");
  const base::FieldTrial::Probability kDivisor = 1000;
  scoped_refptr<base::FieldTrial> trial =
      base::FieldTrialList::FactoryGetFieldTrial(
          name_of_experiment, kDivisor, "Default", 2013, 12, 31,
          base::FieldTrial::SESSION_RANDOMIZED, NULL);

  // Announce the groups with 0 percentage; the actual percentages come from
  // the server configuration.
  std::map<int, std::string> group_to_char;
  group_to_char[trial->AppendGroup("FullScan", 0)] = "c";
  group_to_char[trial->AppendGroup("33Percent_4MinMax", 0)] = "1";
  group_to_char[trial->AppendGroup("50Percent_4MinMax", 0)] = "2";
  group_to_char[trial->AppendGroup("50Percent_8MinMax", 0)] = "3";
  group_to_char[trial->AppendGroup("100Percent_8MinMax", 0)] = "4";
  group_to_char[trial->AppendGroup("100Percent_1MinSeen_A", 0)] = "5";
  group_to_char[trial->AppendGroup("100Percent_1MinSeen_B", 0)] = "6";
  group_to_char[trial->AppendGroup("100Percent_1Min_4Max", 0)] = "7";

  // Announce the experiment to any listeners (especially important is the UMA
  // software, which will append the group names to UMA statistics).
  const int group_num = trial->group();
  std::string group_char = "x";
  if (ContainsKey(group_to_char, group_num))
    group_char = group_to_char[group_num];

  // Write the group to the file to be read by ChromeOS.
  int size = static_cast<int>(group_char.length());
  if (base::WriteFile(group_file_path, group_char.c_str(), size) == size) {
    VLOG(1) << "Configured in group '" << trial->group_name()
            << "' ('" << group_char << "') for "
            << name_of_experiment << " field trial";
  } else {
    VLOG(1) << "Couldn't write to " << group_file_path.value();
  }
}

}  // namespace

// The interval between external metrics collections in seconds
static const int kExternalMetricsCollectionIntervalSeconds = 30;
const char kEventsFilePath[] = "/var/run/metrics/uma-events";

ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) {
}

ExternalMetrics::~ExternalMetrics() {}

void ExternalMetrics::Start() {
  // Register user actions external to the browser.
  // tools/metrics/actions/extract_actions.py won't understand these lines, so
  // all of these are explicitly added in that script.
  // TODO(derat): We shouldn't need to verify actions before reporting them;
  // remove all of this once http://crosbug.com/11125 is fixed.
  valid_user_actions_.insert("Cryptohome.PKCS11InitFail");
  valid_user_actions_.insert("Updater.ServerCertificateChanged");
  valid_user_actions_.insert("Updater.ServerCertificateFailed");

  // Initialize here field trials that don't need to read from files.
  // (None for the moment.)

  // Initialize any chromeos field trials that need to read from a file (e.g.,
  // those that have an upstart script determine their experimental group for
  // them) then schedule the data collection.  All of this is done on the file
  // thread.
  bool task_posted = BrowserThread::PostTask(
      BrowserThread::FILE,
      FROM_HERE,
      base::Bind(&chromeos::ExternalMetrics::SetupFieldTrialsOnFileThread,
                 this));
  DCHECK(task_posted);
}

// static
scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting(
    const std::string& filename) {
  scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics());
  external_metrics->uma_events_file_ = filename;
  return external_metrics;
}

void ExternalMetrics::RecordActionUI(std::string action_string) {
  if (valid_user_actions_.count(action_string)) {
    content::RecordComputedAction(action_string);
  } else {
    DLOG(ERROR) << "undefined UMA action: " << action_string;
  }
}

void ExternalMetrics::RecordAction(const std::string& action) {
  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&ExternalMetrics::RecordActionUI, this, action));
}

void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) {
  ChromeOSMetricsProvider::LogCrash(crash_kind);
}

void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind));
}

void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type());
  if (!CheckValues(
          sample.name(), sample.min(), sample.max(), sample.bucket_count())) {
    DLOG(ERROR) << "Invalid histogram: " << sample.name();
    return;
  }

  base::HistogramBase* counter =
      base::Histogram::FactoryGet(sample.name(),
                                  sample.min(),
                                  sample.max(),
                                  sample.bucket_count(),
                                  base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

void ExternalMetrics::RecordLinearHistogram(
    const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type());
  if (!CheckLinearValues(sample.name(), sample.max())) {
    DLOG(ERROR) << "Invalid linear histogram: " << sample.name();
    return;
  }
  base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
      sample.name(),
      1,
      sample.max(),
      sample.max() + 1,
      base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

void ExternalMetrics::RecordSparseHistogram(
    const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
  base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
      sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

int ExternalMetrics::CollectEvents() {
  ScopedVector<metrics::MetricSample> samples;
  metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_,
                                                              &samples);

  for (ScopedVector<metrics::MetricSample>::iterator it = samples.begin();
       it != samples.end();
       ++it) {
    const metrics::MetricSample& sample = **it;

    // Do not use the UMA_HISTOGRAM_... macros here.  They cache the Histogram
    // instance and thus only work if |sample.name()| is constant.
    switch (sample.type()) {
      case metrics::MetricSample::CRASH:
        RecordCrash(sample.name());
        break;
      case metrics::MetricSample::USER_ACTION:
        RecordAction(sample.name());
        break;
      case metrics::MetricSample::HISTOGRAM:
        RecordHistogram(sample);
        break;
      case metrics::MetricSample::LINEAR_HISTOGRAM:
        RecordLinearHistogram(sample);
        break;
      case metrics::MetricSample::SPARSE_HISTOGRAM:
        RecordSparseHistogram(sample);
        break;
    }
  }

  return samples.size();
}

void ExternalMetrics::CollectEventsAndReschedule() {
  base::ElapsedTimer timer;
  CollectEvents();
  UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed());
  ScheduleCollector();
}

void ExternalMetrics::ScheduleCollector() {
  bool result;
  result = BrowserThread::PostDelayedTask(
      BrowserThread::FILE, FROM_HERE,
      base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule, this),
      base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds));
  DCHECK(result);
}

void ExternalMetrics::SetupFieldTrialsOnFileThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  // Field trials that do not read from files can be initialized in
  // ExternalMetrics::Start() above.
  SetupProgressiveScanFieldTrial();

  ScheduleCollector();
}

}  // namespace chromeos
<commit_msg>chromeos metrics: use /var/lib/metrics instead of /var/run/metrics<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/external_metrics.h"

#include <map>
#include <string>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/chromeos_metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/serialization/metric_sample.h"
#include "components/metrics/serialization/serialization_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h"

using base::UserMetricsAction;
using content::BrowserThread;

namespace chromeos {

namespace {

bool CheckValues(const std::string& name,
                 int minimum,
                 int maximum,
                 size_t bucket_count) {
  if (!base::Histogram::InspectConstructionArguments(
      name, &minimum, &maximum, &bucket_count))
    return false;
  base::HistogramBase* histogram =
      base::StatisticsRecorder::FindHistogram(name);
  if (!histogram)
    return true;
  return histogram->HasConstructionArguments(minimum, maximum, bucket_count);
}

bool CheckLinearValues(const std::string& name, int maximum) {
  return CheckValues(name, 1, maximum, maximum + 1);
}

// Establishes field trial for wifi scanning in chromeos.  crbug.com/242733.
void SetupProgressiveScanFieldTrial() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  const char name_of_experiment[] = "ProgressiveScan";
  const base::FilePath group_file_path(
      "/home/chronos/.progressive_scan_variation");
  const base::FieldTrial::Probability kDivisor = 1000;
  scoped_refptr<base::FieldTrial> trial =
      base::FieldTrialList::FactoryGetFieldTrial(
          name_of_experiment, kDivisor, "Default", 2013, 12, 31,
          base::FieldTrial::SESSION_RANDOMIZED, NULL);

  // Announce the groups with 0 percentage; the actual percentages come from
  // the server configuration.
  std::map<int, std::string> group_to_char;
  group_to_char[trial->AppendGroup("FullScan", 0)] = "c";
  group_to_char[trial->AppendGroup("33Percent_4MinMax", 0)] = "1";
  group_to_char[trial->AppendGroup("50Percent_4MinMax", 0)] = "2";
  group_to_char[trial->AppendGroup("50Percent_8MinMax", 0)] = "3";
  group_to_char[trial->AppendGroup("100Percent_8MinMax", 0)] = "4";
  group_to_char[trial->AppendGroup("100Percent_1MinSeen_A", 0)] = "5";
  group_to_char[trial->AppendGroup("100Percent_1MinSeen_B", 0)] = "6";
  group_to_char[trial->AppendGroup("100Percent_1Min_4Max", 0)] = "7";

  // Announce the experiment to any listeners (especially important is the UMA
  // software, which will append the group names to UMA statistics).
  const int group_num = trial->group();
  std::string group_char = "x";
  if (ContainsKey(group_to_char, group_num))
    group_char = group_to_char[group_num];

  // Write the group to the file to be read by ChromeOS.
  int size = static_cast<int>(group_char.length());
  if (base::WriteFile(group_file_path, group_char.c_str(), size) == size) {
    VLOG(1) << "Configured in group '" << trial->group_name()
            << "' ('" << group_char << "') for "
            << name_of_experiment << " field trial";
  } else {
    VLOG(1) << "Couldn't write to " << group_file_path.value();
  }
}

}  // namespace

// The interval between external metrics collections in seconds
static const int kExternalMetricsCollectionIntervalSeconds = 30;
const char kEventsFilePath[] = "/var/lib/metrics/uma-events";

ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) {
}

ExternalMetrics::~ExternalMetrics() {}

void ExternalMetrics::Start() {
  // Register user actions external to the browser.
  // tools/metrics/actions/extract_actions.py won't understand these lines, so
  // all of these are explicitly added in that script.
  // TODO(derat): We shouldn't need to verify actions before reporting them;
  // remove all of this once http://crosbug.com/11125 is fixed.
  valid_user_actions_.insert("Cryptohome.PKCS11InitFail");
  valid_user_actions_.insert("Updater.ServerCertificateChanged");
  valid_user_actions_.insert("Updater.ServerCertificateFailed");

  // Initialize here field trials that don't need to read from files.
  // (None for the moment.)

  // Initialize any chromeos field trials that need to read from a file (e.g.,
  // those that have an upstart script determine their experimental group for
  // them) then schedule the data collection.  All of this is done on the file
  // thread.
  bool task_posted = BrowserThread::PostTask(
      BrowserThread::FILE,
      FROM_HERE,
      base::Bind(&chromeos::ExternalMetrics::SetupFieldTrialsOnFileThread,
                 this));
  DCHECK(task_posted);
}

// static
scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting(
    const std::string& filename) {
  scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics());
  external_metrics->uma_events_file_ = filename;
  return external_metrics;
}

void ExternalMetrics::RecordActionUI(std::string action_string) {
  if (valid_user_actions_.count(action_string)) {
    content::RecordComputedAction(action_string);
  } else {
    DLOG(ERROR) << "undefined UMA action: " << action_string;
  }
}

void ExternalMetrics::RecordAction(const std::string& action) {
  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&ExternalMetrics::RecordActionUI, this, action));
}

void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) {
  ChromeOSMetricsProvider::LogCrash(crash_kind);
}

void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind));
}

void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type());
  if (!CheckValues(
          sample.name(), sample.min(), sample.max(), sample.bucket_count())) {
    DLOG(ERROR) << "Invalid histogram: " << sample.name();
    return;
  }

  base::HistogramBase* counter =
      base::Histogram::FactoryGet(sample.name(),
                                  sample.min(),
                                  sample.max(),
                                  sample.bucket_count(),
                                  base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

void ExternalMetrics::RecordLinearHistogram(
    const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type());
  if (!CheckLinearValues(sample.name(), sample.max())) {
    DLOG(ERROR) << "Invalid linear histogram: " << sample.name();
    return;
  }
  base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
      sample.name(),
      1,
      sample.max(),
      sample.max() + 1,
      base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

void ExternalMetrics::RecordSparseHistogram(
    const metrics::MetricSample& sample) {
  CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
  base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
      sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->Add(sample.sample());
}

int ExternalMetrics::CollectEvents() {
  ScopedVector<metrics::MetricSample> samples;
  metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_,
                                                              &samples);

  for (ScopedVector<metrics::MetricSample>::iterator it = samples.begin();
       it != samples.end();
       ++it) {
    const metrics::MetricSample& sample = **it;

    // Do not use the UMA_HISTOGRAM_... macros here.  They cache the Histogram
    // instance and thus only work if |sample.name()| is constant.
    switch (sample.type()) {
      case metrics::MetricSample::CRASH:
        RecordCrash(sample.name());
        break;
      case metrics::MetricSample::USER_ACTION:
        RecordAction(sample.name());
        break;
      case metrics::MetricSample::HISTOGRAM:
        RecordHistogram(sample);
        break;
      case metrics::MetricSample::LINEAR_HISTOGRAM:
        RecordLinearHistogram(sample);
        break;
      case metrics::MetricSample::SPARSE_HISTOGRAM:
        RecordSparseHistogram(sample);
        break;
    }
  }

  return samples.size();
}

void ExternalMetrics::CollectEventsAndReschedule() {
  base::ElapsedTimer timer;
  CollectEvents();
  UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed());
  ScheduleCollector();
}

void ExternalMetrics::ScheduleCollector() {
  bool result;
  result = BrowserThread::PostDelayedTask(
      BrowserThread::FILE, FROM_HERE,
      base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule, this),
      base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds));
  DCHECK(result);
}

void ExternalMetrics::SetupFieldTrialsOnFileThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  // Field trials that do not read from files can be initialized in
  // ExternalMetrics::Start() above.
  SetupProgressiveScanFieldTrial();

  ScheduleCollector();
}

}  // namespace chromeos
<|endoftext|>