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

#include "annoylib.h"
#include "kissrandom.h"
#include "Python.h"
#include "structmember.h"
#include <exception>
#include <stdint.h>

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#endif

#ifndef Py_TYPE
    #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif

#ifdef IS_PY3K
    #define PyInt_FromLong PyLong_FromLong
#endif

template class AnnoyIndexInterface<int32_t, float>;

// annoy python object
typedef struct {
  PyObject_HEAD
  int f;
  AnnoyIndexInterface<int32_t, float>* ptr;
} py_annoy;

static PyObject *
py_an_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
  py_annoy *self;

  self = (py_annoy *)type->tp_alloc(type, 0);
  if (self != NULL) {
    self->f = 0;
    self->ptr = NULL;
  }

  return (PyObject *)self;
}

static int
py_an_init(py_annoy *self, PyObject *args, PyObject *kwds) {
  const char *metric;

  if (!PyArg_ParseTuple(args, "is", &self->f, &metric))
    return -1;
  switch(metric[0]) {
  case 'a':
    self->ptr = new AnnoyIndex<int32_t, float, Angular, Kiss64Random>(self->f);
    break;
  case 'e':
    self->ptr = new AnnoyIndex<int32_t, float, Euclidean, Kiss64Random>(self->f);
    break;
  }
  return 0;
}

static void
py_an_dealloc(py_annoy* self) {
  if (self->ptr) {
    delete self->ptr;
  }
  Py_TYPE(self)->tp_free((PyObject*)self);
}

static PyMemberDef py_annoy_members[] = {
  {(char*)"_f", T_INT, offsetof(py_annoy, f), 0,
   (char*)""},
  {NULL}	/* Sentinel */
};

static PyObject *
py_an_load(py_annoy *self, PyObject *args) {
  char* filename;
  bool res = false;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "s", &filename))
    Py_RETURN_NONE;

  res = self->ptr->load(filename);

  if (!res) {
    PyErr_SetFromErrno(PyExc_IOError);
    return NULL;
  }
  Py_RETURN_TRUE;
}

static PyObject *
py_an_save(py_annoy *self, PyObject *args) {
  char *filename;
  bool res = false;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "s", &filename))
    Py_RETURN_NONE;

  res = self->ptr->save(filename);

  if (!res) {
    PyErr_SetFromErrno(PyExc_IOError);
    return NULL;
  }
  Py_RETURN_TRUE;
}

PyObject*
get_nns_to_python(const vector<int32_t>& result, const vector<float>& distances, int include_distances) {
  PyObject* l = PyList_New(result.size());
  for (size_t i = 0; i < result.size(); i++)
    PyList_SetItem(l, i, PyInt_FromLong(result[i]));
  if (!include_distances)
    return l;

  PyObject* d = PyList_New(distances.size());
  for (size_t i = 0; i < distances.size(); i++)
    PyList_SetItem(d, i, PyFloat_FromDouble(distances[i]));

  PyObject* t = PyTuple_New(2);
  PyTuple_SetItem(t, 0, l);
  PyTuple_SetItem(t, 1, d);

  return t;
}

static PyObject*
py_an_get_nns_by_item(py_annoy *self, PyObject *args) {
  int32_t item, n, search_k=-1, include_distances=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "ii|ii", &item, &n, &search_k, &include_distances))
    Py_RETURN_NONE;

  vector<int32_t> result;
  vector<float> distances;
  self->ptr->get_nns_by_item(item, n, search_k, &result, include_distances ? &distances : NULL);

  return get_nns_to_python(result, distances, include_distances);
}

static PyObject*
py_an_get_nns_by_vector(py_annoy *self, PyObject *args) {
  PyObject* v;
  int32_t n, search_k=-1, include_distances=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "Oi|ii", &v, &n, &search_k, &include_distances))
    Py_RETURN_NONE;

  vector<float> w(self->f);
  for (int z = 0; z < PyList_Size(v) && z < self->f; z++) {
    PyObject *pf = PyList_GetItem(v,z);
    w[z] = PyFloat_AsDouble(pf);
  }

  vector<int32_t> result;
  vector<float> distances;
  self->ptr->get_nns_by_vector(&w[0], n, search_k, &result, include_distances ? &distances : NULL);

  return get_nns_to_python(result, distances, include_distances);
}

static PyObject*
py_an_get_item_vector(py_annoy *self, PyObject *args) {
  int32_t item;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &item))
    Py_RETURN_NONE;

  vector<float> v;
  self->ptr->get_item(item, &v);
  PyObject* l = PyList_New(self->f);
  for (int z = 0; z < self->f; z++) {
    PyList_SetItem(l, z, PyFloat_FromDouble(v[z]));
  }

  return l;
}

static PyObject*
py_an_add_item(py_annoy *self, PyObject *args) {
  vector<float> w;

  PyObject* l;
  int32_t item;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "iO", &item, &l))
    Py_RETURN_NONE;
  for (int z = 0; z < PyList_Size(l); z++) {
    PyObject *pf = PyList_GetItem(l,z);
    w.push_back(PyFloat_AsDouble(pf));
  }
  self->ptr->add_item(item, &w[0]);

  Py_RETURN_NONE;
}

static PyObject *
py_an_build(py_annoy *self, PyObject *args) {
  int q;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &q))
    Py_RETURN_NONE;

  self->ptr->build(q);

  Py_RETURN_TRUE;
}

static PyObject *
py_an_unload(py_annoy *self, PyObject *args) {
  if (!self->ptr)
    Py_RETURN_NONE;

  self->ptr->unload();

  Py_RETURN_TRUE;
}

static PyObject *
py_an_get_distance(py_annoy *self, PyObject *args) {
  int32_t i,j;
  double d=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "ii", &i, &j))
    Py_RETURN_NONE;

  d = self->ptr->get_distance(i,j);

  return PyFloat_FromDouble(d);
}

static PyObject *
py_an_get_n_items(py_annoy *self, PyObject *args) {
  int32_t n=0;
  bool is_n=false;
  if (!self->ptr)
    Py_RETURN_NONE;

  n = self->ptr->get_n_items();
  is_n = true;

  if (is_n) return PyInt_FromLong(n);
  Py_RETURN_NONE;
}

static PyObject *
py_an_verbose(py_annoy *self, PyObject *args) {
  int verbose;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &verbose))
    Py_RETURN_NONE;

  self->ptr->verbose((bool)verbose);

  Py_RETURN_TRUE;
}

static PyMethodDef AnnoyMethods[] = {
  {"load",	(PyCFunction)py_an_load, METH_VARARGS, ""},
  {"save",	(PyCFunction)py_an_save, METH_VARARGS, ""},
  {"get_nns_by_item",(PyCFunction)py_an_get_nns_by_item, METH_VARARGS, ""},
  {"get_nns_by_vector",(PyCFunction)py_an_get_nns_by_vector, METH_VARARGS, ""},
  {"get_item_vector",(PyCFunction)py_an_get_item_vector, METH_VARARGS, ""},
  {"add_item",(PyCFunction)py_an_add_item, METH_VARARGS, ""},
  {"build",(PyCFunction)py_an_build, METH_VARARGS, ""},
  {"unload",(PyCFunction)py_an_unload, METH_VARARGS, ""},
  {"get_distance",(PyCFunction)py_an_get_distance, METH_VARARGS, ""},
  {"get_n_items",(PyCFunction)py_an_get_n_items, METH_VARARGS, ""},
  {"verbose",(PyCFunction)py_an_verbose, METH_VARARGS, ""},
  {NULL, NULL, 0, NULL}		 /* Sentinel */
};

static PyTypeObject PyAnnoyType = {
  PyVarObject_HEAD_INIT(NULL, 0)
  "annoy.Annoy",          /*tp_name*/
  sizeof(py_annoy),       /*tp_basicsize*/
  0,                      /*tp_itemsize*/
  (destructor)py_an_dealloc, /*tp_dealloc*/
  0,                      /*tp_print*/
  0,                      /*tp_getattr*/
  0,                      /*tp_setattr*/
  0,                      /*tp_compare*/
  0,                      /*tp_repr*/
  0,                      /*tp_as_number*/
  0,                      /*tp_as_sequence*/
  0,                      /*tp_as_mapping*/
  0,                      /*tp_hash */
  0,                      /*tp_call*/
  0,                      /*tp_str*/
  0,                      /*tp_getattro*/
  0,                      /*tp_setattro*/
  0,                      /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "annoy objects",        /* tp_doc */
  0,                      /* tp_traverse */
  0,                      /* tp_clear */
  0,                      /* tp_richcompare */
  0,                      /* tp_weaklistoffset */
  0,                      /* tp_iter */
  0,                      /* tp_iternext */
  AnnoyMethods,           /* tp_methods */
  py_annoy_members,       /* tp_members */
  0,                      /* tp_getset */
  0,                      /* tp_base */
  0,                      /* tp_dict */
  0,                      /* tp_descr_get */
  0,                      /* tp_descr_set */
  0,                      /* tp_dictoffset */
  (initproc)py_an_init,   /* tp_init */
  0,                      /* tp_alloc */
  py_an_new,              /* tp_new */
};

static PyMethodDef module_methods[] = {
  {NULL}	/* Sentinel */
};

#if PY_MAJOR_VERSION >= 3
  static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "annoylib",          /* m_name */
    "",                  /* m_doc */
    -1,                  /* m_size */
    module_methods,      /* m_methods */
    NULL,                /* m_reload */
    NULL,                /* m_traverse */
    NULL,                /* m_clear */
    NULL,                /* m_free */
  };
#endif

PyObject *create_module(void) {
  PyObject *m;

  if (PyType_Ready(&PyAnnoyType) < 0)
    return NULL;

#if PY_MAJOR_VERSION >= 3
  m = PyModule_Create(&moduledef);
#else
  m = Py_InitModule("annoylib", module_methods);
#endif

  if (m == NULL)
    return NULL;

  Py_INCREF(&PyAnnoyType);
  PyModule_AddObject(m, "Annoy", (PyObject *)&PyAnnoyType);
  return m;
}

#if PY_MAJOR_VERSION >= 3
  PyMODINIT_FUNC PyInit_annoylib(void) {
    return create_module();      // it should return moudule object in py3
  }
#else
  PyMODINIT_FUNC initannoylib(void) {
    create_module();
  }
#endif

// vim: tabstop=2 shiftwidth=2
<commit_msg>preallocate vector for add_item<commit_after>// Copyright (c) 2013 Spotify AB
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "annoylib.h"
#include "kissrandom.h"
#include "Python.h"
#include "structmember.h"
#include <exception>
#include <stdint.h>

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#endif

#ifndef Py_TYPE
    #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif

#ifdef IS_PY3K
    #define PyInt_FromLong PyLong_FromLong
#endif

template class AnnoyIndexInterface<int32_t, float>;

// annoy python object
typedef struct {
  PyObject_HEAD
  int f;
  AnnoyIndexInterface<int32_t, float>* ptr;
} py_annoy;

static PyObject *
py_an_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
  py_annoy *self;

  self = (py_annoy *)type->tp_alloc(type, 0);
  if (self != NULL) {
    self->f = 0;
    self->ptr = NULL;
  }

  return (PyObject *)self;
}

static int
py_an_init(py_annoy *self, PyObject *args, PyObject *kwds) {
  const char *metric;

  if (!PyArg_ParseTuple(args, "is", &self->f, &metric))
    return -1;
  switch(metric[0]) {
  case 'a':
    self->ptr = new AnnoyIndex<int32_t, float, Angular, Kiss64Random>(self->f);
    break;
  case 'e':
    self->ptr = new AnnoyIndex<int32_t, float, Euclidean, Kiss64Random>(self->f);
    break;
  }
  return 0;
}

static void
py_an_dealloc(py_annoy* self) {
  if (self->ptr) {
    delete self->ptr;
  }
  Py_TYPE(self)->tp_free((PyObject*)self);
}

static PyMemberDef py_annoy_members[] = {
  {(char*)"_f", T_INT, offsetof(py_annoy, f), 0,
   (char*)""},
  {NULL}	/* Sentinel */
};

static PyObject *
py_an_load(py_annoy *self, PyObject *args) {
  char* filename;
  bool res = false;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "s", &filename))
    Py_RETURN_NONE;

  res = self->ptr->load(filename);

  if (!res) {
    PyErr_SetFromErrno(PyExc_IOError);
    return NULL;
  }
  Py_RETURN_TRUE;
}

static PyObject *
py_an_save(py_annoy *self, PyObject *args) {
  char *filename;
  bool res = false;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "s", &filename))
    Py_RETURN_NONE;

  res = self->ptr->save(filename);

  if (!res) {
    PyErr_SetFromErrno(PyExc_IOError);
    return NULL;
  }
  Py_RETURN_TRUE;
}

PyObject*
get_nns_to_python(const vector<int32_t>& result, const vector<float>& distances, int include_distances) {
  PyObject* l = PyList_New(result.size());
  for (size_t i = 0; i < result.size(); i++)
    PyList_SetItem(l, i, PyInt_FromLong(result[i]));
  if (!include_distances)
    return l;

  PyObject* d = PyList_New(distances.size());
  for (size_t i = 0; i < distances.size(); i++)
    PyList_SetItem(d, i, PyFloat_FromDouble(distances[i]));

  PyObject* t = PyTuple_New(2);
  PyTuple_SetItem(t, 0, l);
  PyTuple_SetItem(t, 1, d);

  return t;
}

static PyObject*
py_an_get_nns_by_item(py_annoy *self, PyObject *args) {
  int32_t item, n, search_k=-1, include_distances=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "ii|ii", &item, &n, &search_k, &include_distances))
    Py_RETURN_NONE;

  vector<int32_t> result;
  vector<float> distances;
  self->ptr->get_nns_by_item(item, n, search_k, &result, include_distances ? &distances : NULL);

  return get_nns_to_python(result, distances, include_distances);
}

static PyObject*
py_an_get_nns_by_vector(py_annoy *self, PyObject *args) {
  PyObject* v;
  int32_t n, search_k=-1, include_distances=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "Oi|ii", &v, &n, &search_k, &include_distances))
    Py_RETURN_NONE;

  vector<float> w(self->f);
  for (int z = 0; z < PyList_Size(v) && z < self->f; z++) {
    PyObject *pf = PyList_GetItem(v,z);
    w[z] = PyFloat_AsDouble(pf);
  }

  vector<int32_t> result;
  vector<float> distances;
  self->ptr->get_nns_by_vector(&w[0], n, search_k, &result, include_distances ? &distances : NULL);

  return get_nns_to_python(result, distances, include_distances);
}

static PyObject*
py_an_get_item_vector(py_annoy *self, PyObject *args) {
  int32_t item;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &item))
    Py_RETURN_NONE;

  vector<float> v;
  self->ptr->get_item(item, &v);
  PyObject* l = PyList_New(self->f);
  for (int z = 0; z < self->f; z++) {
    PyList_SetItem(l, z, PyFloat_FromDouble(v[z]));
  }

  return l;
}

static PyObject*
py_an_add_item(py_annoy *self, PyObject *args) {
  PyObject* l;
  int32_t item;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "iO", &item, &l))
    Py_RETURN_NONE;

  vector<float> w(self->f, 0.0);
  for (int z = 0; z < self->f; z++) {
    PyObject *pf = PyList_GetItem(l,z);
    w[z] = PyFloat_AsDouble(pf);
  }
  self->ptr->add_item(item, &w[0]);

  Py_RETURN_NONE;
}

static PyObject *
py_an_build(py_annoy *self, PyObject *args) {
  int q;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &q))
    Py_RETURN_NONE;

  self->ptr->build(q);

  Py_RETURN_TRUE;
}

static PyObject *
py_an_unload(py_annoy *self, PyObject *args) {
  if (!self->ptr)
    Py_RETURN_NONE;

  self->ptr->unload();

  Py_RETURN_TRUE;
}

static PyObject *
py_an_get_distance(py_annoy *self, PyObject *args) {
  int32_t i,j;
  double d=0;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "ii", &i, &j))
    Py_RETURN_NONE;

  d = self->ptr->get_distance(i,j);

  return PyFloat_FromDouble(d);
}

static PyObject *
py_an_get_n_items(py_annoy *self, PyObject *args) {
  int32_t n=0;
  bool is_n=false;
  if (!self->ptr)
    Py_RETURN_NONE;

  n = self->ptr->get_n_items();
  is_n = true;

  if (is_n) return PyInt_FromLong(n);
  Py_RETURN_NONE;
}

static PyObject *
py_an_verbose(py_annoy *self, PyObject *args) {
  int verbose;
  if (!self->ptr)
    Py_RETURN_NONE;
  if (!PyArg_ParseTuple(args, "i", &verbose))
    Py_RETURN_NONE;

  self->ptr->verbose((bool)verbose);

  Py_RETURN_TRUE;
}

static PyMethodDef AnnoyMethods[] = {
  {"load",	(PyCFunction)py_an_load, METH_VARARGS, ""},
  {"save",	(PyCFunction)py_an_save, METH_VARARGS, ""},
  {"get_nns_by_item",(PyCFunction)py_an_get_nns_by_item, METH_VARARGS, ""},
  {"get_nns_by_vector",(PyCFunction)py_an_get_nns_by_vector, METH_VARARGS, ""},
  {"get_item_vector",(PyCFunction)py_an_get_item_vector, METH_VARARGS, ""},
  {"add_item",(PyCFunction)py_an_add_item, METH_VARARGS, ""},
  {"build",(PyCFunction)py_an_build, METH_VARARGS, ""},
  {"unload",(PyCFunction)py_an_unload, METH_VARARGS, ""},
  {"get_distance",(PyCFunction)py_an_get_distance, METH_VARARGS, ""},
  {"get_n_items",(PyCFunction)py_an_get_n_items, METH_VARARGS, ""},
  {"verbose",(PyCFunction)py_an_verbose, METH_VARARGS, ""},
  {NULL, NULL, 0, NULL}		 /* Sentinel */
};

static PyTypeObject PyAnnoyType = {
  PyVarObject_HEAD_INIT(NULL, 0)
  "annoy.Annoy",          /*tp_name*/
  sizeof(py_annoy),       /*tp_basicsize*/
  0,                      /*tp_itemsize*/
  (destructor)py_an_dealloc, /*tp_dealloc*/
  0,                      /*tp_print*/
  0,                      /*tp_getattr*/
  0,                      /*tp_setattr*/
  0,                      /*tp_compare*/
  0,                      /*tp_repr*/
  0,                      /*tp_as_number*/
  0,                      /*tp_as_sequence*/
  0,                      /*tp_as_mapping*/
  0,                      /*tp_hash */
  0,                      /*tp_call*/
  0,                      /*tp_str*/
  0,                      /*tp_getattro*/
  0,                      /*tp_setattro*/
  0,                      /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "annoy objects",        /* tp_doc */
  0,                      /* tp_traverse */
  0,                      /* tp_clear */
  0,                      /* tp_richcompare */
  0,                      /* tp_weaklistoffset */
  0,                      /* tp_iter */
  0,                      /* tp_iternext */
  AnnoyMethods,           /* tp_methods */
  py_annoy_members,       /* tp_members */
  0,                      /* tp_getset */
  0,                      /* tp_base */
  0,                      /* tp_dict */
  0,                      /* tp_descr_get */
  0,                      /* tp_descr_set */
  0,                      /* tp_dictoffset */
  (initproc)py_an_init,   /* tp_init */
  0,                      /* tp_alloc */
  py_an_new,              /* tp_new */
};

static PyMethodDef module_methods[] = {
  {NULL}	/* Sentinel */
};

#if PY_MAJOR_VERSION >= 3
  static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "annoylib",          /* m_name */
    "",                  /* m_doc */
    -1,                  /* m_size */
    module_methods,      /* m_methods */
    NULL,                /* m_reload */
    NULL,                /* m_traverse */
    NULL,                /* m_clear */
    NULL,                /* m_free */
  };
#endif

PyObject *create_module(void) {
  PyObject *m;

  if (PyType_Ready(&PyAnnoyType) < 0)
    return NULL;

#if PY_MAJOR_VERSION >= 3
  m = PyModule_Create(&moduledef);
#else
  m = Py_InitModule("annoylib", module_methods);
#endif

  if (m == NULL)
    return NULL;

  Py_INCREF(&PyAnnoyType);
  PyModule_AddObject(m, "Annoy", (PyObject *)&PyAnnoyType);
  return m;
}

#if PY_MAJOR_VERSION >= 3
  PyMODINIT_FUNC PyInit_annoylib(void) {
    return create_module();      // it should return moudule object in py3
  }
#else
  PyMODINIT_FUNC initannoylib(void) {
    create_module();
  }
#endif

// vim: tabstop=2 shiftwidth=2
<|endoftext|>


<commit_before>#include "cmdline.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "miutils.h"

// global object
ExecutableInfo params;

ExecutableInfo::ExecutableInfo()
	: argCount(0)
	, verbose(false)
	, miMode(false)
	, silent(false)
	, stopOnEntry(false)
{
	setDir(getCurrentDirectory());
}

void ExecutableInfo::clear() {
	exename.clear();
	dir.clear();
	for (int i = 0; i < argCount; i++) {
		args[i].clear();
	}
	argCount = 0;
}

ExecutableInfo::~ExecutableInfo() {
	clear();
}

bool ExecutableInfo::hasExecutableSpecified() {
	return !exename.empty();
}

void ExecutableInfo::setExecutable(std::wstring  exe) {
	if (exe.empty()) {
		exename.clear();
		return;
	}
	std::wstring tmp = unquoteString(exe);
	exename = relativeToAbsolutePath(tmp);
}

void ExecutableInfo::setDir(std::wstring directory) {
	if (directory.empty()) {
		dir.clear();
		return;
	}
	std::wstring tmp = unquoteString(directory);
	dir = relativeToAbsolutePath(tmp);
}

void ExecutableInfo::addArg(std::wstring param) {
	if (argCount >= MAX_PARAM_COUNT) {
		fprintf(stderr, "Too many executable file parameters");
		exit(3);
	}
	args[argCount++] = param;
}

void ExecutableInfo::dumpParams() {
	if (!exename.empty()) {
		wprintf(L"Executable file: %s\n", exename.c_str());
		if (argCount) {
			wprintf(L"Inferior arguments: ");
			for (int i = 0; i < argCount; i++) {
				wprintf(L"%s ", args[i].c_str());
			}
			wprintf(L"\n");
		}
	}
	if (!dir.empty())
		wprintf(L"Directory: %s\n", dir.c_str());
}

enum CmdLineParamType {
	NO_PARAMS,
	STRING_PARAM,
};

struct CmdLineParamDef;
typedef void(*parameterHandler)(CmdLineParamDef * param, const wchar_t * value);

struct CmdLineParamDef {
	const char * shortName;
	const char * longName;
	CmdLineParamType paramType;
	const char * description;
	const char * defValue;
	parameterHandler handler;
	bool isHelpSection() {
		return !shortName && !longName && description;
	}
	bool isLast() {
		return !shortName && !longName && !description;
	}

	// for normal parameter
	CmdLineParamDef(const char * _shortName, const char * _longName, CmdLineParamType _paramType, const char * _description, const char * _defValue, parameterHandler _handler)
		: shortName(_shortName), longName(_longName), paramType(_paramType), description(_description), defValue(_defValue), handler(_handler) {
	}
	// for help section
	CmdLineParamDef(const char * _description)
		: shortName(NULL), longName(NULL), paramType(NO_PARAMS), description(_description), defValue(NULL), handler(NULL) {
	}
	// for last item
	CmdLineParamDef()
		: shortName(NULL), longName(NULL), paramType(NO_PARAMS), description(NULL), defValue(NULL), handler(NULL) {
	}
};

void dumpParameterHelp();

static void showHelp(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	printf("This is Mago debugger command line interface. Usage:\n");
	printf("    mago-mi [options] [executable-file]\n");
	printf("    mago-mi [options] --args executable-file [inferior-arguments ...]\n");
	dumpParameterHelp();
	exit(0);
}

static void showVersion(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	printf("mago-mi debugger v0.1\n");
	exit(0);
}

void defParamHandler(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	// TODO
}

static void handleInterpreter(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (wcscmp(value, L"mi2")) {
		fprintf(stderr, "Only mi2 interpreter is supported");
		exit(2);
	}
	params.miMode = true;
}

static bool argsFound = false;

static void handleArgs(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (params.hasExecutableSpecified()) {
		fprintf(stderr, "Executable file already specified");
		exit(3);
	}
	params.setExecutable(value);
	argsFound = true;
}

static void handleExec(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (params.hasExecutableSpecified()) {
		fprintf(stderr, "Executable file already specified");
		exit(3);
	}
	params.setExecutable(std::wstring(value));
}

static void handleDir(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	params.setDir(value);
}

static void handleVerbose(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	params.verbose = true;
}

static void handleSilent(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	params.silent = true;
}

void nonParamHandler(const wchar_t * value) {
	if (params.exename.empty()) {
		params.setExecutable(std::wstring(value));
		return;
	}
	if (!argsFound) {
		fprintf(stderr, "Use --args to provide inferior arguments");
		exit(3);
	}
	params.addArg(std::wstring(value));
}

CmdLineParamDef paramDefs[] = {
	CmdLineParamDef("Selection of debuggee and its files"),
	CmdLineParamDef(NULL, "--args", STRING_PARAM, "Arguments after executable-file are passed to inferior", NULL, &handleArgs),
	CmdLineParamDef(NULL, "--exec=EXECFILE", STRING_PARAM, "Use EXECFILE as the executable.", NULL, &handleExec),
	CmdLineParamDef("Output and user interface control"),
	CmdLineParamDef(NULL, "--interpreter=mi2", STRING_PARAM, "Turn on GDB MI interface mode", NULL, &handleInterpreter),
	CmdLineParamDef("Operating modes"),
	CmdLineParamDef(NULL, "--help", NO_PARAMS, "Print this message and then exit", NULL, &showHelp),
	CmdLineParamDef(NULL, "--version", NO_PARAMS, "Print version information and then exit", NULL, &showVersion),
	CmdLineParamDef("-v", NULL, NO_PARAMS, "Verbose output", NULL, &handleVerbose),
	CmdLineParamDef(NULL, "--silent", NO_PARAMS, "Don't print version info on startup", NULL, &handleSilent),
	CmdLineParamDef("Other options"),
	CmdLineParamDef(NULL, "--cd=DIR", STRING_PARAM, "Change current directory to DIR.", NULL, &handleDir),
	CmdLineParamDef()
};

void dumpParameterHelp() {
	for (int i = 0; !paramDefs[i].isLast(); i++) {
		if (paramDefs[i].isHelpSection()) {
			printf("\n%s:\n\n", paramDefs[i].description);
		} else {
			if (paramDefs[i].longName)
				printf("  %-16s %s\n", paramDefs[i].longName, paramDefs[i].description);
			if (paramDefs[i].shortName)
				printf("  %-16s %s\n", paramDefs[i].shortName, paramDefs[i].description);
		}
	}
}

CmdLineParamDef * findParam(const wchar_t * &name) {
	if (name[0] == '-' && name[1] != '-') {
		for (int i = 0; !paramDefs[i].isLast(); i++) {
			if (paramDefs[i].isHelpSection())
				continue;
			if (!paramDefs[i].shortName)
				continue;
			if (paramDefs[i].shortName[1] == name[1]) {
				name += 2;
				return &paramDefs[i];
			}
		}
	} else if (name[0] == '-' && name[1] == '-') {
		for (int i = 0; !paramDefs[i].isLast(); i++) {
			if (paramDefs[i].isHelpSection())
				continue;
			if (!paramDefs[i].longName)
				continue;
			int j = 0;
			for (; name[j] && paramDefs[i].longName[j] && (paramDefs[i].longName[j] != '=') && name[j] == paramDefs[i].longName[j]; j++)
				;
			if ((!paramDefs[i].longName[j] || paramDefs[i].longName[j] == '=') && (!name[j] || name[j] == '=')) {
				name += j;
				if (name[0] == '=')
					name++;
				return &paramDefs[i];
			}
		}
	}
	return NULL;
}

void parseCommandLine(int argc, wchar_t *argv[]) {
	for (int i = 1; i < argc; i++) {
		wchar_t * v = argv[i];
		if (v[0] == '-') {
			const wchar_t * value = v;
			CmdLineParamDef * param = findParam(value);
			if (!param) {
				fwprintf(stderr, L"Unknown command line parameter %s", v);
				exit(1);
			}
			if (param->paramType != NO_PARAMS) {
				if (!value[0]) {
					if (i == argc - 1) {
						fwprintf(stderr, L"Value not specified for parameter %s", v);
						exit(1);
					}
					i++;
					value = argv[i];
				}
			}
			else {
				if (value[0]) {
					fwprintf(stderr, L"Value not allowed for parameter %s", v);
					exit(1);
				}
			}
			if (param->handler) {
				param->handler(param, value);
			} else {
				defParamHandler(param, value);
			}
		}
		else {
			nonParamHandler(v);
		}
	}
}
<commit_msg>interpreter options<commit_after>#include "cmdline.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "miutils.h"

// global object
ExecutableInfo params;

ExecutableInfo::ExecutableInfo()
	: argCount(0)
	, verbose(false)
	, miMode(false)
	, silent(false)
	, stopOnEntry(false)
{
	setDir(getCurrentDirectory());
}

void ExecutableInfo::clear() {
	exename.clear();
	dir.clear();
	for (int i = 0; i < argCount; i++) {
		args[i].clear();
	}
	argCount = 0;
}

ExecutableInfo::~ExecutableInfo() {
	clear();
}

bool ExecutableInfo::hasExecutableSpecified() {
	return !exename.empty();
}

void ExecutableInfo::setExecutable(std::wstring  exe) {
	if (exe.empty()) {
		exename.clear();
		return;
	}
	std::wstring tmp = unquoteString(exe);
	exename = relativeToAbsolutePath(tmp);
}

void ExecutableInfo::setDir(std::wstring directory) {
	if (directory.empty()) {
		dir.clear();
		return;
	}
	std::wstring tmp = unquoteString(directory);
	dir = relativeToAbsolutePath(tmp);
}

void ExecutableInfo::addArg(std::wstring param) {
	if (argCount >= MAX_PARAM_COUNT) {
		fprintf(stderr, "Too many executable file parameters");
		exit(3);
	}
	args[argCount++] = param;
}

void ExecutableInfo::dumpParams() {
	if (!exename.empty()) {
		wprintf(L"Executable file: %s\n", exename.c_str());
		if (argCount) {
			wprintf(L"Inferior arguments: ");
			for (int i = 0; i < argCount; i++) {
				wprintf(L"%s ", args[i].c_str());
			}
			wprintf(L"\n");
		}
	}
	if (!dir.empty())
		wprintf(L"Directory: %s\n", dir.c_str());
}

enum CmdLineParamType {
	NO_PARAMS,
	STRING_PARAM,
};

struct CmdLineParamDef;
typedef void(*parameterHandler)(CmdLineParamDef * param, const wchar_t * value);

struct CmdLineParamDef {
	const char * shortName;
	const char * longName;
	CmdLineParamType paramType;
	const char * description;
	const char * defValue;
	parameterHandler handler;
	bool isHelpSection() {
		return !shortName && !longName && description;
	}
	bool isLast() {
		return !shortName && !longName && !description;
	}

	// for normal parameter
	CmdLineParamDef(const char * _shortName, const char * _longName, CmdLineParamType _paramType, const char * _description, const char * _defValue, parameterHandler _handler)
		: shortName(_shortName), longName(_longName), paramType(_paramType), description(_description), defValue(_defValue), handler(_handler) {
	}
	// for help section
	CmdLineParamDef(const char * _description)
		: shortName(NULL), longName(NULL), paramType(NO_PARAMS), description(_description), defValue(NULL), handler(NULL) {
	}
	// for last item
	CmdLineParamDef()
		: shortName(NULL), longName(NULL), paramType(NO_PARAMS), description(NULL), defValue(NULL), handler(NULL) {
	}
};

void dumpParameterHelp();

static void showHelp(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	printf("This is Mago debugger command line interface. Usage:\n");
	printf("    mago-mi [options] [executable-file]\n");
	printf("    mago-mi [options] --args executable-file [inferior-arguments ...]\n");
	dumpParameterHelp();
	exit(0);
}

static void showVersion(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	printf("mago-mi debugger v0.1\n");
	exit(0);
}

void defParamHandler(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	// TODO
}

static void handleInterpreter(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (!wcscmp(value, L"mi2") || !wcscmp(value, L"mi") || !wcscmp(value, L"mi1")) {
		params.miMode = true;
		return;
	}
	if (!wcscmp(value, L"console")) {
		params.miMode = false;
		return;
	}
	fprintf(stderr, "Unknown interpreter is specified");
	exit(-3);
}

static bool argsFound = false;

static void handleArgs(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (params.hasExecutableSpecified()) {
		fprintf(stderr, "Executable file already specified");
		exit(3);
	}
	params.setExecutable(value);
	argsFound = true;
}

static void handleExec(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	if (params.hasExecutableSpecified()) {
		fprintf(stderr, "Executable file already specified");
		exit(3);
	}
	params.setExecutable(std::wstring(value));
}

static void handleDir(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	params.setDir(value);
}

static void handleVerbose(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	params.verbose = true;
}

static void handleSilent(CmdLineParamDef * param, const wchar_t * value) {
	UNREFERENCED_PARAMETER(param);
	UNREFERENCED_PARAMETER(value);
	params.silent = true;
}

void nonParamHandler(const wchar_t * value) {
	if (params.exename.empty()) {
		params.setExecutable(std::wstring(value));
		return;
	}
	if (!argsFound) {
		fprintf(stderr, "Use --args to provide inferior arguments");
		exit(3);
	}
	params.addArg(std::wstring(value));
}

CmdLineParamDef paramDefs[] = {
	CmdLineParamDef("Selection of debuggee and its files"),
	CmdLineParamDef(NULL, "--args", STRING_PARAM, "Arguments after executable-file are passed to inferior", NULL, &handleArgs),
	CmdLineParamDef(NULL, "--exec=EXECFILE", STRING_PARAM, "Use EXECFILE as the executable.", NULL, &handleExec),
	CmdLineParamDef("Output and user interface control"),
	CmdLineParamDef(NULL, "--interpreter=mi2", STRING_PARAM, "Turn on GDB MI interface mode", NULL, &handleInterpreter),
	CmdLineParamDef("Operating modes"),
	CmdLineParamDef(NULL, "--help", NO_PARAMS, "Print this message and then exit", NULL, &showHelp),
	CmdLineParamDef(NULL, "--version", NO_PARAMS, "Print version information and then exit", NULL, &showVersion),
	CmdLineParamDef("-v", NULL, NO_PARAMS, "Verbose output", NULL, &handleVerbose),
	CmdLineParamDef(NULL, "--silent", NO_PARAMS, "Don't print version info on startup", NULL, &handleSilent),
	CmdLineParamDef("Other options"),
	CmdLineParamDef(NULL, "--cd=DIR", STRING_PARAM, "Change current directory to DIR.", NULL, &handleDir),
	CmdLineParamDef()
};

void dumpParameterHelp() {
	for (int i = 0; !paramDefs[i].isLast(); i++) {
		if (paramDefs[i].isHelpSection()) {
			printf("\n%s:\n\n", paramDefs[i].description);
		} else {
			if (paramDefs[i].longName)
				printf("  %-16s %s\n", paramDefs[i].longName, paramDefs[i].description);
			if (paramDefs[i].shortName)
				printf("  %-16s %s\n", paramDefs[i].shortName, paramDefs[i].description);
		}
	}
}

CmdLineParamDef * findParam(const wchar_t * &name) {
	if (name[0] == '-' && name[1] != '-') {
		for (int i = 0; !paramDefs[i].isLast(); i++) {
			if (paramDefs[i].isHelpSection())
				continue;
			if (!paramDefs[i].shortName)
				continue;
			if (paramDefs[i].shortName[1] == name[1]) {
				name += 2;
				return &paramDefs[i];
			}
		}
	} else if (name[0] == '-' && name[1] == '-') {
		for (int i = 0; !paramDefs[i].isLast(); i++) {
			if (paramDefs[i].isHelpSection())
				continue;
			if (!paramDefs[i].longName)
				continue;
			int j = 0;
			for (; name[j] && paramDefs[i].longName[j] && (paramDefs[i].longName[j] != '=') && name[j] == paramDefs[i].longName[j]; j++)
				;
			if ((!paramDefs[i].longName[j] || paramDefs[i].longName[j] == '=') && (!name[j] || name[j] == '=')) {
				name += j;
				if (name[0] == '=')
					name++;
				return &paramDefs[i];
			}
		}
	}
	return NULL;
}

void parseCommandLine(int argc, wchar_t *argv[]) {
	for (int i = 1; i < argc; i++) {
		wchar_t * v = argv[i];
		if (v[0] == '-') {
			const wchar_t * value = v;
			CmdLineParamDef * param = findParam(value);
			if (!param) {
				fwprintf(stderr, L"Unknown command line parameter %s", v);
				exit(1);
			}
			if (param->paramType != NO_PARAMS) {
				if (!value[0]) {
					if (i == argc - 1) {
						fwprintf(stderr, L"Value not specified for parameter %s", v);
						exit(1);
					}
					i++;
					value = argv[i];
				}
			}
			else {
				if (value[0]) {
					fwprintf(stderr, L"Value not allowed for parameter %s", v);
					exit(1);
				}
			}
			if (param->handler) {
				param->handler(param, value);
			} else {
				defParamHandler(param, value);
			}
		}
		else {
			nonParamHandler(v);
		}
	}
}
<|endoftext|>


<commit_before>/*
    This file is part of the KOrganizer alarm daemon.

    Copyright (c) 2000,2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <QLabel>
#include <QFile>
#include <QSpinBox>
#include <QLayout>
#include <QPushButton>
#include <QDataStream>
//Added by qt3to4:
#include <QVBoxLayout>
#include <QBoxLayout>
#include <QtDBus>
#include <kapplication.h>
#include <klocale.h>
#include <kprocess.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <knotification.h>
#include <kcombobox.h>
#include <kwin.h>
#include <klockfile.h>
#include <kpushbutton.h>
#include <phonon/audioplayer.h>

#include <kcal/event.h>
#include <ktoolinvocation.h>
#include <kglobal.h>
#include <kvbox.h>

#include "koeventviewer.h"

#include "alarmdialog.h"
#include "alarmdialog.moc"

AlarmDialog::AlarmDialog( QWidget *parent )
  : KDialog( parent/*, Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_StaysOnTop |
                     Qt::WStyle_DialogBorder,*/ ),
                 mSuspendTimer(this)
{
  QWidget *topBox = new QWidget( this);
  setMainWidget( topBox );
  setCaption( i18n("Reminder") );
  setButtons( Ok | User1 | User2 );
  setDefaultButton( User1 );
  setButtonText( User1, i18n("Suspend") );
  setButtonText( User2, i18n("Edit...") );
  QBoxLayout *topLayout = new QVBoxLayout( topBox );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("The following events triggered reminders:"),
                              topBox );
  topLayout->addWidget( label );

  mEventViewer = new KOEventViewer( topBox );
  topLayout->addWidget( mEventViewer );

  KHBox *suspendBox = new KHBox( topBox );
  suspendBox->setSpacing( spacingHint() );
  topLayout->addWidget( suspendBox );

  new QLabel( i18n("Suspend duration:"), suspendBox );
  mSuspendSpin = new QSpinBox( suspendBox );
  mSuspendSpin->setRange( 1, 9999 );
  mSuspendSpin->setValue( 5 );  // default suspend duration

  mSuspendUnit = new KComboBox( suspendBox );
  mSuspendUnit->addItem( i18n("minute(s)") );
  mSuspendUnit->addItem( i18n("hour(s)") );
  mSuspendUnit->addItem( i18n("day(s)") );
  mSuspendUnit->addItem( i18n("week(s)") );

  connect( mSuspendSpin, SIGNAL( valueChanged(int) ), this, SLOT( suspendValueChanged() ) );
  connect( mSuspendUnit, SIGNAL( activated(int) ), this, SLOT( suspendUnitChanged() ) );
  connect( mSuspendUnit, SIGNAL( activated(int) ), this, SLOT( suspendUnitChanged() ) );

  // showButton( User2/*3*/, false );

  setMinimumSize( 300, 200 );
}

AlarmDialog::~AlarmDialog()
{
  delete mIncidence;
}

void AlarmDialog::setIncidence( Incidence *incidence )
{
  mIncidence = incidence->clone();
  mEventViewer->appendIncidence( mIncidence );
}

void AlarmDialog::setRemindAt( QDateTime dt )
{
  mRemindAt = dt;
}

void AlarmDialog::slotOk()
{
  accept();
  emit finishedSignal( this );
}

void AlarmDialog::slotUser1()
{
  if ( !isVisible() )
    return;

  int unit=1;
  switch ( mSuspendUnit->currentIndex() ) {
    case 3: // weeks
      unit *=  7;
    case 2: // days
      unit *= 24;
    case 1: // hours
      unit *= 60;
    case 0: // minutes
      unit *= 60;
    default:
      break;
  }

  setTimer( unit * mSuspendSpin->value() );
  accept();
}

void AlarmDialog::setTimer( int seconds )
{
  connect( &mSuspendTimer, SIGNAL( timeout() ), SLOT( show() ) );
  mSuspendTimer.setSingleShot( true );
  mSuspendTimer.start( 1000 * seconds );
  mRemindAt = QDateTime::currentDateTime();
  mRemindAt = mRemindAt.addSecs( seconds );
}

void AlarmDialog::slotUser2()
{
  if ( !QDBus::sessionBus().interface()->isServiceRegistered( "korganizer" ) ) {
    if ( KToolInvocation::startServiceByDesktopName( "korganizer", QString() ) )
      KMessageBox::error( 0, i18n("Could not start KOrganizer.") );
  }
  QDBusInterface korganizer("org.kde.korganizer", "/KOrganizer", "org.kde.korganizer.KOrganizer");
  korganizer.call( "editIncidence",mIncidence->uid() );

  // get desktop # where korganizer (or kontact) runs
  QString object = QDBus::sessionBus().interface()->isServiceRegistered( "kontact" ) ?
           "kontact-mainwindow_1" : "KOrganizer MainWindow";
  QDBusInterface korganizerObj("org.kde.korganizer", "/"+object);
  QDBusReply<int> reply = korganizerObj.call( "getWinID" );
  if ( reply.isValid() ) {
    int window = reply;
    int desktop = KWin::windowInfo( window ).desktop();

    if ( KWin::currentDesktop() == desktop ) {
      KWin::iconifyWindow( winId(), false );
    }
    else
      KWin::setCurrentDesktop( desktop );

    KWin::activateWindow( KWin::transientFor( window ) );
  }
}

void AlarmDialog::show()
{
  KDialog::show();
  KWin::setState( winId(), NET::KeepAbove );
  KWin::setOnAllDesktops( winId(), true );
  eventNotification();
}

void AlarmDialog::suspendValueChanged()
{
  setButtonFocus( User1 );
}

void AlarmDialog::suspendUnitChanged()
{
  setButtonFocus( User1 );
  setButtonFocus( User2 );
}

void AlarmDialog::eventNotification()
{
  bool beeped = false;
  Alarm::List alarms = mIncidence->alarms();
  Alarm::List::ConstIterator it;
  for ( it = alarms.begin(); it != alarms.end(); ++it ) {
    Alarm *alarm = *it;
// FIXME: Check whether this should be done for all multiple alarms
    if (alarm->type() == Alarm::Procedure) {
// FIXME: Add a message box asking whether the procedure should really be executed
      kDebug(5890) << "Starting program: '" << alarm->programFile() << "'" << endl;
      KProcess proc;
      proc << QFile::encodeName(alarm->programFile());
      proc.start(KProcess::DontCare);
    }
    else if (alarm->type() == Alarm::Audio) {
      beeped = true;
      Phonon::AudioPlayer* player = new Phonon::AudioPlayer( Phonon::NotificationCategory, this );
      player->play( KUrl( QFile::encodeName(alarm->audioFile() ) ) );
    }
  }

  if ( !beeped ) {
    KNotification::beep();
  }
}

void AlarmDialog::wakeUp()
{
  if ( mRemindAt <= QDateTime::currentDateTime() )
    show();
  else
    setTimer( QDateTime::currentDateTime().secsTo( mRemindAt ) );
}

void AlarmDialog::slotSave()
{
  KConfig *config = KGlobal::config();
  KLockFile::Ptr lock = config->lockFile();
  if ( lock.data()->lock() != KLockFile::LockOK )
    return;

  config->setGroup( "General" );
  int numReminders = config->readEntry("Reminders", 0);
  config->writeEntry( "Reminders", ++numReminders );

  config->setGroup( QString("Incidence-%1").arg(numReminders) );
  config->writeEntry( "UID", mIncidence->uid() );
  config->writeEntry( "RemindAt", mRemindAt );
  config->sync();
  lock.data()->unlock();
}

<commit_msg>minor QString+"*" -> QString+'*' change.<commit_after>/*
    This file is part of the KOrganizer alarm daemon.

    Copyright (c) 2000,2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <QLabel>
#include <QFile>
#include <QSpinBox>
#include <QLayout>
#include <QPushButton>
#include <QDataStream>
//Added by qt3to4:
#include <QVBoxLayout>
#include <QBoxLayout>
#include <QtDBus>
#include <kapplication.h>
#include <klocale.h>
#include <kprocess.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <knotification.h>
#include <kcombobox.h>
#include <kwin.h>
#include <klockfile.h>
#include <kpushbutton.h>
#include <phonon/audioplayer.h>

#include <kcal/event.h>
#include <ktoolinvocation.h>
#include <kglobal.h>
#include <kvbox.h>

#include "koeventviewer.h"

#include "alarmdialog.h"
#include "alarmdialog.moc"

AlarmDialog::AlarmDialog( QWidget *parent )
  : KDialog( parent/*, Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_StaysOnTop |
                     Qt::WStyle_DialogBorder,*/ ),
                 mSuspendTimer(this)
{
  QWidget *topBox = new QWidget( this);
  setMainWidget( topBox );
  setCaption( i18n("Reminder") );
  setButtons( Ok | User1 | User2 );
  setDefaultButton( User1 );
  setButtonText( User1, i18n("Suspend") );
  setButtonText( User2, i18n("Edit...") );
  QBoxLayout *topLayout = new QVBoxLayout( topBox );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("The following events triggered reminders:"),
                              topBox );
  topLayout->addWidget( label );

  mEventViewer = new KOEventViewer( topBox );
  topLayout->addWidget( mEventViewer );

  KHBox *suspendBox = new KHBox( topBox );
  suspendBox->setSpacing( spacingHint() );
  topLayout->addWidget( suspendBox );

  new QLabel( i18n("Suspend duration:"), suspendBox );
  mSuspendSpin = new QSpinBox( suspendBox );
  mSuspendSpin->setRange( 1, 9999 );
  mSuspendSpin->setValue( 5 );  // default suspend duration

  mSuspendUnit = new KComboBox( suspendBox );
  mSuspendUnit->addItem( i18n("minute(s)") );
  mSuspendUnit->addItem( i18n("hour(s)") );
  mSuspendUnit->addItem( i18n("day(s)") );
  mSuspendUnit->addItem( i18n("week(s)") );

  connect( mSuspendSpin, SIGNAL( valueChanged(int) ), this, SLOT( suspendValueChanged() ) );
  connect( mSuspendUnit, SIGNAL( activated(int) ), this, SLOT( suspendUnitChanged() ) );
  connect( mSuspendUnit, SIGNAL( activated(int) ), this, SLOT( suspendUnitChanged() ) );

  // showButton( User2/*3*/, false );

  setMinimumSize( 300, 200 );
}

AlarmDialog::~AlarmDialog()
{
  delete mIncidence;
}

void AlarmDialog::setIncidence( Incidence *incidence )
{
  mIncidence = incidence->clone();
  mEventViewer->appendIncidence( mIncidence );
}

void AlarmDialog::setRemindAt( QDateTime dt )
{
  mRemindAt = dt;
}

void AlarmDialog::slotOk()
{
  accept();
  emit finishedSignal( this );
}

void AlarmDialog::slotUser1()
{
  if ( !isVisible() )
    return;

  int unit=1;
  switch ( mSuspendUnit->currentIndex() ) {
    case 3: // weeks
      unit *=  7;
    case 2: // days
      unit *= 24;
    case 1: // hours
      unit *= 60;
    case 0: // minutes
      unit *= 60;
    default:
      break;
  }

  setTimer( unit * mSuspendSpin->value() );
  accept();
}

void AlarmDialog::setTimer( int seconds )
{
  connect( &mSuspendTimer, SIGNAL( timeout() ), SLOT( show() ) );
  mSuspendTimer.setSingleShot( true );
  mSuspendTimer.start( 1000 * seconds );
  mRemindAt = QDateTime::currentDateTime();
  mRemindAt = mRemindAt.addSecs( seconds );
}

void AlarmDialog::slotUser2()
{
  if ( !QDBus::sessionBus().interface()->isServiceRegistered( "korganizer" ) ) {
    if ( KToolInvocation::startServiceByDesktopName( "korganizer", QString() ) )
      KMessageBox::error( 0, i18n("Could not start KOrganizer.") );
  }
  QDBusInterface korganizer("org.kde.korganizer", "/KOrganizer", "org.kde.korganizer.KOrganizer");
  korganizer.call( "editIncidence",mIncidence->uid() );

  // get desktop # where korganizer (or kontact) runs
  QString object = QDBus::sessionBus().interface()->isServiceRegistered( "kontact" ) ?
           "kontact-mainwindow_1" : "KOrganizer MainWindow";
  QDBusInterface korganizerObj("org.kde.korganizer", '/'+object);
  QDBusReply<int> reply = korganizerObj.call( "getWinID" );
  if ( reply.isValid() ) {
    int window = reply;
    int desktop = KWin::windowInfo( window ).desktop();

    if ( KWin::currentDesktop() == desktop ) {
      KWin::iconifyWindow( winId(), false );
    }
    else
      KWin::setCurrentDesktop( desktop );

    KWin::activateWindow( KWin::transientFor( window ) );
  }
}

void AlarmDialog::show()
{
  KDialog::show();
  KWin::setState( winId(), NET::KeepAbove );
  KWin::setOnAllDesktops( winId(), true );
  eventNotification();
}

void AlarmDialog::suspendValueChanged()
{
  setButtonFocus( User1 );
}

void AlarmDialog::suspendUnitChanged()
{
  setButtonFocus( User1 );
  setButtonFocus( User2 );
}

void AlarmDialog::eventNotification()
{
  bool beeped = false;
  Alarm::List alarms = mIncidence->alarms();
  Alarm::List::ConstIterator it;
  for ( it = alarms.begin(); it != alarms.end(); ++it ) {
    Alarm *alarm = *it;
// FIXME: Check whether this should be done for all multiple alarms
    if (alarm->type() == Alarm::Procedure) {
// FIXME: Add a message box asking whether the procedure should really be executed
      kDebug(5890) << "Starting program: '" << alarm->programFile() << "'" << endl;
      KProcess proc;
      proc << QFile::encodeName(alarm->programFile());
      proc.start(KProcess::DontCare);
    }
    else if (alarm->type() == Alarm::Audio) {
      beeped = true;
      Phonon::AudioPlayer* player = new Phonon::AudioPlayer( Phonon::NotificationCategory, this );
      player->play( KUrl( QFile::encodeName(alarm->audioFile() ) ) );
    }
  }

  if ( !beeped ) {
    KNotification::beep();
  }
}

void AlarmDialog::wakeUp()
{
  if ( mRemindAt <= QDateTime::currentDateTime() )
    show();
  else
    setTimer( QDateTime::currentDateTime().secsTo( mRemindAt ) );
}

void AlarmDialog::slotSave()
{
  KConfig *config = KGlobal::config();
  KLockFile::Ptr lock = config->lockFile();
  if ( lock.data()->lock() != KLockFile::LockOK )
    return;

  config->setGroup( "General" );
  int numReminders = config->readEntry("Reminders", 0);
  config->writeEntry( "Reminders", ++numReminders );

  config->setGroup( QString("Incidence-%1").arg(numReminders) );
  config->writeEntry( "UID", mIncidence->uid() );
  config->writeEntry( "RemindAt", mRemindAt );
  config->sync();
  lock.data()->unlock();
}

<|endoftext|>


<commit_before>#pragma once
#include "pch.h"

/**
*sum of squard difference (distance metric)
*starting from ax,ay in image a and bx,by in image b, with a width and height given
*indicies out of bounds results in MAX_DOUBLE
*/
double ssd(Mat& a, Mat& b, int ax, int ay, int bx, int by, int width, int height){
	//check <0 >width >height, els MAX_DOUBLE
	//for 0 to height
		//for 0 to width
			//sum += (a[ay+y][ax+x] - b[by+y][bx+x])^2
}

/**
*result(y,x) is dot product of filter and img centered at y,x
*/
void imfilter(Mat& img, Mat& filter, Mat* result){
	//TODO:: for each y,x in img, apply dot product of filter and image centered at y,x
	//store in result[y][x]
}

/**
*resizes the image to size(img)*ratio, blurs if downsampling
*result stores new image matrix
*/
void imresize(Mat& img, float ratio, Mat* result){

}

/**
*singlular vaue decomposition, results are returned in destU, destS, and destV
*may pass in nil to disregaurd certian results
*/
void svd(Mat& a, Mat*destU, Mat*destS, Mat*destV){
	//TODO::compute singluar value decomposition of a
}

/**
*uses RANSAC to compute map from a onto b with maximum number of points
*threadhold is the maximum distance between to valid matches
*H is the resulting 3x3 projective trasnformation
*num_matches is the number of points used to compute the homography
*/
void findHomographyRANSAC(KeyPoints& a, KeyPoints& b, double threshhold, Mat* H, int* num_matches){

}

/**
*helper function for computeHomographyRANSAC
*computes a homography from a onto b
*/
void findHomography(KeyPoints& a, KeyPoints& b, Mat* H){

}

/**
*matches the descriptors of a to the descriptors of b
*returns the indexes of a that match the index of b
*/
void match(Descriptors& a, Descriptors& b,  vector<int> * indexesA, vector<int> * indexesB){

}

/**
*performs harris cornder detections, and returns the key points of the image, and descriptors
*/
void harrisCorners(Mat& a, KeyPoints * keyspoints, Descriptors * decriptors){

}

/**
*applies H to the plane of a onto the plane of b, returns the new points in result
*/
void projectiveTransform(KeyPoints& a, KeyPoints& b, Mat& H, KeyPoints* result){

}<commit_msg>removed mat_ops from feature2d.cpp<commit_after>#pragma once
#include "pch.h"

/**
*uses RANSAC to compute map from a onto b with maximum number of points
*threadhold is the maximum distance between to valid matches
*H is the resulting 3x3 projective trasnformation
*num_matches is the number of points used to compute the homography
*/
void findHomographyRANSAC(KeyPoints& a, KeyPoints& b, double threshhold, Mat* H, int* num_matches){

}

/**
*helper function for computeHomographyRANSAC
*computes a homography from a onto b
*/
void findHomography(KeyPoints& a, KeyPoints& b, Mat* H){

}

/**
*matches the descriptors of a to the descriptors of b
*returns the indexes of a that match the index of b
*/
void match(Descriptors& a, Descriptors& b,  vector<int> * indexesA, vector<int> * indexesB){

}

/**
*performs harris cornder detections, and returns the key points of the image, and descriptors
*/
void harrisCorners(Mat& a, KeyPoints * keyspoints, Descriptors * decriptors){

}

/**
*applies H to the plane of a onto the plane of b, returns the new points in result
*/
void projectiveTransform(KeyPoints& a, KeyPoints& b, Mat& H, KeyPoints* result){

}<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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 GIO_MOUNT_HXX
#define GIO_MOUNT_HXX

#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <gio/gio.h>

G_BEGIN_DECLS

#define OOO_TYPE_MOUNT_OPERATION         (ooo_mount_operation_get_type ())
#define OOO_MOUNT_OPERATION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperation))
#define OOO_MOUNT_OPERATION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))
#define OOO_IS_MOUNT_OPERATION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), OOO_TYPE_MOUNT_OPERATION))
#define OOO_IS_MOUNT_OPERATION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), OOO_TYPE_MOUNT_OPERATION))
#define OOO_MOUNT_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))

typedef struct OOoMountOperation         OOoMountOperation;
typedef struct OOoMountOperationClass    OOoMountOperationClass;
typedef struct OOoMountOperationPrivate  OOoMountOperationPrivate;

struct OOoMountOperation
{
    GMountOperation parent_instance;

    const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > *pEnv;
    char *m_pPrevUsername;
    char *m_pPrevPassword;
};

struct OOoMountOperationClass
{
    GMountOperationClass parent_class;

    /* Padding for future expansion */
    void (*_gtk_reserved1) (void);
    void (*_gtk_reserved2) (void);
    void (*_gtk_reserved3) (void);
    void (*_gtk_reserved4) (void);
};

GType            ooo_mount_operation_get_type   (void);
GMountOperation *ooo_mount_operation_new(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& rEnv);

G_END_DECLS
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>drop typedef, don't need it for C++<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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 GIO_MOUNT_HXX
#define GIO_MOUNT_HXX

#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <gio/gio.h>

G_BEGIN_DECLS

#define OOO_TYPE_MOUNT_OPERATION         (ooo_mount_operation_get_type ())
#define OOO_MOUNT_OPERATION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperation))
#define OOO_MOUNT_OPERATION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))
#define OOO_IS_MOUNT_OPERATION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), OOO_TYPE_MOUNT_OPERATION))
#define OOO_IS_MOUNT_OPERATION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), OOO_TYPE_MOUNT_OPERATION))
#define OOO_MOUNT_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))

struct OOoMountOperation
{
    GMountOperation parent_instance;

    const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > *pEnv;
    char *m_pPrevUsername;
    char *m_pPrevPassword;
};

struct OOoMountOperationClass
{
    GMountOperationClass parent_class;

    /* Padding for future expansion */
    void (*_gtk_reserved1) (void);
    void (*_gtk_reserved2) (void);
    void (*_gtk_reserved3) (void);
    void (*_gtk_reserved4) (void);
};

GType            ooo_mount_operation_get_type   (void);
GMountOperation *ooo_mount_operation_new(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& rEnv);

G_END_DECLS
#endif

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


<commit_before>#include "BLEUuid.h"

#include "BLEDeviceLimits.h"

#include "BLEPeripheral.h"

//#define BLE_PERIPHERAL_DEBUG

#define DEFAULT_DEVICE_NAME "Arduino"
#define DEFAULT_APPEARANCE  0x0000

BLEPeripheral::BLEPeripheral(unsigned char req, unsigned char rdy, unsigned char rst) :
#ifdef NRF51
  _nRF51822(),
#else
  _nRF8001(req, rdy, rst),
#endif

  _localName(NULL),
  _manufacturerData(NULL),
  _manufacturerDataLength(0),

  _attributes(NULL),
  _numAttributes(0),

  _genericAccessService("1800"),
  _deviceNameCharacteristic("2a00", BLERead, 19),
  _appearanceCharacteristic("2a01", BLERead, 2),
  _genericAttributeService("1801"),
  _servicesChangedCharacteristic("2a05", BLEIndicate, 4),

  _central(this)
{
#ifdef NRF51
  this->_device = &this->_nRF51822;
#else
  this->_device = &this->_nRF8001;
#endif

  memset(this->_eventHandlers, 0x00, sizeof(this->_eventHandlers));

  this->setDeviceName(DEFAULT_DEVICE_NAME);
  this->setAppearance(DEFAULT_APPEARANCE);

  this->_device->setEventListener(this);
}

BLEPeripheral::~BLEPeripheral() {
  if (this->_attributes) {
    free(this->_attributes);
  }
}

void BLEPeripheral::begin() {
  unsigned char advertisementDataType = 0;
  unsigned char scanDataType = 0;

  unsigned char advertisementDataLength = 0;
  unsigned char scanDataLength = 0;

  unsigned char advertisementData[BLE_ADVERTISEMENT_DATA_MAX_VALUE_LENGTH];
  unsigned char scanData[BLE_SCAN_DATA_MAX_VALUE_LENGTH];

  if (this->_advertisedServiceUuid){
    BLEUuid advertisedServiceUuid = BLEUuid(this->_advertisedServiceUuid);

    advertisementDataLength = advertisedServiceUuid.length();
    advertisementDataType = (advertisementDataLength > 2) ? 0x06 : 0x02;

    memcpy(advertisementData, advertisedServiceUuid.data(), advertisementDataLength);
  } else if (this->_manufacturerData && this->_manufacturerDataLength > 0) {
    advertisementDataLength = this->_manufacturerDataLength;

    if (advertisementDataLength > sizeof(advertisementData)) {
      advertisementDataLength = sizeof(advertisementData);
    }

    advertisementDataType = 0xff;

    memcpy(advertisementData, this->_manufacturerData, advertisementDataLength);
  }

  if (this->_localName){
    unsigned char localNameLength = strlen(this->_localName);
    scanDataLength = localNameLength;

    if (scanDataLength > sizeof(scanData)) {
      scanDataLength = sizeof(scanData);
    }

    scanDataType = (localNameLength > scanDataLength) ? 0x08 : 0x09;

    memcpy(scanData, this->_localName, scanDataLength);
  }

  for (int i = 0; i < this->_numAttributes; i++) {
    BLEAttribute* attribute = this->_attributes[i];
    if (attribute->type() == BLETypeCharacteristic) {
      BLECharacteristic* characteristic = (BLECharacteristic*)attribute;

      characteristic->setValueChangeListener(*this);
    }
  }

  this->_device->begin(advertisementDataType, advertisementDataLength, advertisementData, scanDataType, scanDataLength, scanData, this->_attributes, this->_numAttributes);
  this->_device->requestAddress();
}

void BLEPeripheral::poll() {
  this->_device->poll();
}

void BLEPeripheral::setAdvertisedServiceUuid(const char* advertisedServiceUuid) {
  this->_advertisedServiceUuid = advertisedServiceUuid;
}

void BLEPeripheral::setManufacturerData(const unsigned char manufacturerData[], unsigned char manufacturerDataLength) {
  this->_manufacturerData = manufacturerData;
  this->_manufacturerDataLength = manufacturerDataLength;
}

void BLEPeripheral::setLocalName(const char* localName) {
  this->_localName = localName;
}

void BLEPeripheral::setDeviceName(const char* deviceName) {
  this->_deviceNameCharacteristic.setValue(deviceName);
}

void BLEPeripheral::setAppearance(unsigned short appearance) {
  this->_appearanceCharacteristic.setValue((unsigned char *)&appearance, sizeof(appearance));
}

void BLEPeripheral::addAttribute(BLEAttribute& attribute) {
  if (this->_attributes == NULL) {
    this->_attributes = (BLEAttribute**)malloc(BLEAttribute::numAttributes() * sizeof(BLEAttribute*));

    this->_attributes[0] = &this->_genericAccessService;
    this->_attributes[1] = &this->_deviceNameCharacteristic;
    this->_attributes[2] = &this->_appearanceCharacteristic;

    this->_attributes[3] = &this->_genericAttributeService;
    this->_attributes[4] = &this->_servicesChangedCharacteristic;

    this->_numAttributes = 5;
  }

  this->_attributes[this->_numAttributes] = &attribute;
  this->_numAttributes++;
}

void BLEPeripheral::disconnect() {
  this->_device->disconnect();
}

BLECentral BLEPeripheral::central() {
  this->poll();

  return this->_central;
}

bool BLEPeripheral::connected() {
  this->poll();

  return this->_central;
}

void BLEPeripheral::setEventHandler(BLEPeripheralEvent event, BLEPeripheralEventHandler eventHandler) {
  if (event < sizeof(this->_eventHandlers)) {
    this->_eventHandlers[event] = eventHandler;
  }
}

bool BLEPeripheral::characteristicValueChanged(BLECharacteristic& characteristic) {
  this->_device->updateCharacteristicValue(characteristic);
}

bool BLEPeripheral::canNotifyCharacteristic(BLECharacteristic& characteristic) {
  this->_device->canNotifyCharacteristic(characteristic);
}

bool BLEPeripheral::canIndicateCharacteristic(BLECharacteristic& characteristic) {
  this->_device->canIndicateCharacteristic(characteristic);
}

void BLEPeripheral::BLEDeviceConnected(BLEDevice& device, const unsigned char* address) {
  this->_central.setAddress(address);

#ifdef BLE_PERIPHERAL_DEBUG
  Serial.print(F("Peripheral connected to central: "));
  Serial.println(this->_central.address());
#endif

  BLEPeripheralEventHandler eventHandler = this->_eventHandlers[BLEConnected];
  if (eventHandler) {
    eventHandler(this->_central);
  }
}

void BLEPeripheral::BLEDeviceDisconnected(BLEDevice& device) {
#ifdef BLE_PERIPHERAL_DEBUG
  Serial.print(F("Peripheral disconnected from central: "));
  Serial.println(this->_central.address());
#endif

  BLEPeripheralEventHandler eventHandler = this->_eventHandlers[BLEDisconnected];
  if (eventHandler) {
    eventHandler(this->_central);
  }

  this->_central.clearAddress();
}

void BLEPeripheral::BLEDeviceCharacteristicValueChanged(BLEDevice& device, BLECharacteristic& characteristic, const unsigned char* value, unsigned char valueLength) {
  characteristic.setValue(this->_central, value, valueLength);
}

void BLEPeripheral::BLEDeviceCharacteristicSubscribedChanged(BLEDevice& device, BLECharacteristic& characteristic, bool subscribed) {
  characteristic.setSubscribed(this->_central, subscribed);
}

void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& device, const unsigned char* address) {
#ifdef BLE_PERIPHERAL_DEBUG
  char addressStr[18];

  sprintf(addressStr, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
    address[5],
    address[4],
    address[3],
    address[2],
    address[1],
    address[0]);

  Serial.print(F("Peripheral address: "));
  Serial.println(addressStr);
#endif
}

void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& device, float temperature) {
}

void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& device, float batteryLevel) {
}
<commit_msg>- missing returns<commit_after>#include "BLEUuid.h"

#include "BLEDeviceLimits.h"

#include "BLEPeripheral.h"

//#define BLE_PERIPHERAL_DEBUG

#define DEFAULT_DEVICE_NAME "Arduino"
#define DEFAULT_APPEARANCE  0x0000

BLEPeripheral::BLEPeripheral(unsigned char req, unsigned char rdy, unsigned char rst) :
#ifdef NRF51
  _nRF51822(),
#else
  _nRF8001(req, rdy, rst),
#endif

  _localName(NULL),
  _manufacturerData(NULL),
  _manufacturerDataLength(0),

  _attributes(NULL),
  _numAttributes(0),

  _genericAccessService("1800"),
  _deviceNameCharacteristic("2a00", BLERead, 19),
  _appearanceCharacteristic("2a01", BLERead, 2),
  _genericAttributeService("1801"),
  _servicesChangedCharacteristic("2a05", BLEIndicate, 4),

  _central(this)
{
#ifdef NRF51
  this->_device = &this->_nRF51822;
#else
  this->_device = &this->_nRF8001;
#endif

  memset(this->_eventHandlers, 0x00, sizeof(this->_eventHandlers));

  this->setDeviceName(DEFAULT_DEVICE_NAME);
  this->setAppearance(DEFAULT_APPEARANCE);

  this->_device->setEventListener(this);
}

BLEPeripheral::~BLEPeripheral() {
  if (this->_attributes) {
    free(this->_attributes);
  }
}

void BLEPeripheral::begin() {
  unsigned char advertisementDataType = 0;
  unsigned char scanDataType = 0;

  unsigned char advertisementDataLength = 0;
  unsigned char scanDataLength = 0;

  unsigned char advertisementData[BLE_ADVERTISEMENT_DATA_MAX_VALUE_LENGTH];
  unsigned char scanData[BLE_SCAN_DATA_MAX_VALUE_LENGTH];

  if (this->_advertisedServiceUuid){
    BLEUuid advertisedServiceUuid = BLEUuid(this->_advertisedServiceUuid);

    advertisementDataLength = advertisedServiceUuid.length();
    advertisementDataType = (advertisementDataLength > 2) ? 0x06 : 0x02;

    memcpy(advertisementData, advertisedServiceUuid.data(), advertisementDataLength);
  } else if (this->_manufacturerData && this->_manufacturerDataLength > 0) {
    advertisementDataLength = this->_manufacturerDataLength;

    if (advertisementDataLength > sizeof(advertisementData)) {
      advertisementDataLength = sizeof(advertisementData);
    }

    advertisementDataType = 0xff;

    memcpy(advertisementData, this->_manufacturerData, advertisementDataLength);
  }

  if (this->_localName){
    unsigned char localNameLength = strlen(this->_localName);
    scanDataLength = localNameLength;

    if (scanDataLength > sizeof(scanData)) {
      scanDataLength = sizeof(scanData);
    }

    scanDataType = (localNameLength > scanDataLength) ? 0x08 : 0x09;

    memcpy(scanData, this->_localName, scanDataLength);
  }

  for (int i = 0; i < this->_numAttributes; i++) {
    BLEAttribute* attribute = this->_attributes[i];
    if (attribute->type() == BLETypeCharacteristic) {
      BLECharacteristic* characteristic = (BLECharacteristic*)attribute;

      characteristic->setValueChangeListener(*this);
    }
  }

  this->_device->begin(advertisementDataType, advertisementDataLength, advertisementData, scanDataType, scanDataLength, scanData, this->_attributes, this->_numAttributes);
  this->_device->requestAddress();
}

void BLEPeripheral::poll() {
  this->_device->poll();
}

void BLEPeripheral::setAdvertisedServiceUuid(const char* advertisedServiceUuid) {
  this->_advertisedServiceUuid = advertisedServiceUuid;
}

void BLEPeripheral::setManufacturerData(const unsigned char manufacturerData[], unsigned char manufacturerDataLength) {
  this->_manufacturerData = manufacturerData;
  this->_manufacturerDataLength = manufacturerDataLength;
}

void BLEPeripheral::setLocalName(const char* localName) {
  this->_localName = localName;
}

void BLEPeripheral::setDeviceName(const char* deviceName) {
  this->_deviceNameCharacteristic.setValue(deviceName);
}

void BLEPeripheral::setAppearance(unsigned short appearance) {
  this->_appearanceCharacteristic.setValue((unsigned char *)&appearance, sizeof(appearance));
}

void BLEPeripheral::addAttribute(BLEAttribute& attribute) {
  if (this->_attributes == NULL) {
    this->_attributes = (BLEAttribute**)malloc(BLEAttribute::numAttributes() * sizeof(BLEAttribute*));

    this->_attributes[0] = &this->_genericAccessService;
    this->_attributes[1] = &this->_deviceNameCharacteristic;
    this->_attributes[2] = &this->_appearanceCharacteristic;

    this->_attributes[3] = &this->_genericAttributeService;
    this->_attributes[4] = &this->_servicesChangedCharacteristic;

    this->_numAttributes = 5;
  }

  this->_attributes[this->_numAttributes] = &attribute;
  this->_numAttributes++;
}

void BLEPeripheral::disconnect() {
  this->_device->disconnect();
}

BLECentral BLEPeripheral::central() {
  this->poll();

  return this->_central;
}

bool BLEPeripheral::connected() {
  this->poll();

  return this->_central;
}

void BLEPeripheral::setEventHandler(BLEPeripheralEvent event, BLEPeripheralEventHandler eventHandler) {
  if (event < sizeof(this->_eventHandlers)) {
    this->_eventHandlers[event] = eventHandler;
  }
}

bool BLEPeripheral::characteristicValueChanged(BLECharacteristic& characteristic) {
  return this->_device->updateCharacteristicValue(characteristic);
}

bool BLEPeripheral::canNotifyCharacteristic(BLECharacteristic& characteristic) {
  return this->_device->canNotifyCharacteristic(characteristic);
}

bool BLEPeripheral::canIndicateCharacteristic(BLECharacteristic& characteristic) {
  return this->_device->canIndicateCharacteristic(characteristic);
}

void BLEPeripheral::BLEDeviceConnected(BLEDevice& device, const unsigned char* address) {
  this->_central.setAddress(address);

#ifdef BLE_PERIPHERAL_DEBUG
  Serial.print(F("Peripheral connected to central: "));
  Serial.println(this->_central.address());
#endif

  BLEPeripheralEventHandler eventHandler = this->_eventHandlers[BLEConnected];
  if (eventHandler) {
    eventHandler(this->_central);
  }
}

void BLEPeripheral::BLEDeviceDisconnected(BLEDevice& device) {
#ifdef BLE_PERIPHERAL_DEBUG
  Serial.print(F("Peripheral disconnected from central: "));
  Serial.println(this->_central.address());
#endif

  BLEPeripheralEventHandler eventHandler = this->_eventHandlers[BLEDisconnected];
  if (eventHandler) {
    eventHandler(this->_central);
  }

  this->_central.clearAddress();
}

void BLEPeripheral::BLEDeviceCharacteristicValueChanged(BLEDevice& device, BLECharacteristic& characteristic, const unsigned char* value, unsigned char valueLength) {
  characteristic.setValue(this->_central, value, valueLength);
}

void BLEPeripheral::BLEDeviceCharacteristicSubscribedChanged(BLEDevice& device, BLECharacteristic& characteristic, bool subscribed) {
  characteristic.setSubscribed(this->_central, subscribed);
}

void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& device, const unsigned char* address) {
#ifdef BLE_PERIPHERAL_DEBUG
  char addressStr[18];

  sprintf(addressStr, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
    address[5],
    address[4],
    address[3],
    address[2],
    address[1],
    address[0]);

  Serial.print(F("Peripheral address: "));
  Serial.println(addressStr);
#endif
}

void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& device, float temperature) {
}

void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& device, float batteryLevel) {
}
<|endoftext|>


<commit_before>#include <mcl/op.hpp>
#include <mcl/util.hpp>
#include <mcl/conversion.hpp>
#ifdef USE_MONT_FP
#include <mcl/fp_generator.hpp>
#endif
#include <mcl/fp_proto.hpp>

namespace mcl { namespace fp {

#ifdef USE_MONT_FP
FpGenerator *Op::createFpGenerator()
{
	return new FpGenerator();
}
void Op::destroyFpGenerator(FpGenerator *fg)
{
	delete fg;
}
#else
FpGenerator *Op::createFpGenerator()
{
	return 0;
}
void Op::destroyFpGenerator(FpGenerator *)
{
}
#endif

inline const char *verifyStr(bool *isMinus, int *base, const std::string& str)
{
	const char *p = str.c_str();
	if (*p == '-') {
		*isMinus = true;
		p++;
	} else {
		*isMinus = false;
	}
	if (p[0] == '0') {
		if (p[1] == 'x') {
			if (*base != 0 && *base != 16) {
				throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
			}
			*base = 16;
			p += 2;
		} else if (p[1] == 'b') {
			if (*base != 0 && *base != 2) {
				throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
			}
			*base = 2;
			p += 2;
		}
	}
	if (*base == 0) *base = 10;
	if (*p == '\0') throw cybozu::Exception("fp:verifyStr:str is empty");
	return p;
}

bool strToMpzArray(size_t *pBitSize, Unit *y, size_t maxBitSize, mpz_class& x, const std::string& str, int base)
{
	bool isMinus;
	const char *p = verifyStr(&isMinus, &base, str);
	if (!Gmp::setStr(x, p, base)) {
		throw cybozu::Exception("fp:strToMpzArray:bad format") << str;
	}
	const size_t bitSize = Gmp::getBitSize(x);
	if (bitSize > maxBitSize) throw cybozu::Exception("fp:strToMpzArray:too large str") << str << bitSize << maxBitSize;
	if (pBitSize) *pBitSize = bitSize;
	Gmp::getArray(y, (maxBitSize + UnitBitSize - 1) / UnitBitSize, x);
	return isMinus;
}

template<size_t bitSize>
struct OpeFunc {
	static const size_t N = (bitSize + UnitBitSize - 1) / UnitBitSize;
	static inline void set_mpz_t(mpz_t& z, const Unit* p, int n = (int)N)
	{
		z->_mp_alloc = n;
		z->_mp_size = getNonZeroArraySize(p, n);
		z->_mp_d = (mp_limb_t*)const_cast<Unit*>(p);
	}
	static inline void set_zero(mpz_t& z, Unit *p, size_t n)
	{
		z->_mp_alloc = (int)n;
		z->_mp_size = 0;
		z->_mp_d = (mp_limb_t*)p;
	}
	static inline void clearC(Unit *x)
	{
		clearArray(x, 0, N);
	}
	static inline void copyC(Unit *y, const Unit *x)
	{
		copyArray(y, x, N);
	}
	static inline void addC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
	{
		Unit ret[N + 2]; // not N + 1
		mpz_t mz, mx, my, mp;
		set_zero(mz, ret, N + 2);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		set_mpz_t(mp, p);
		mpz_add(mz, mx, my);
		if (mpz_cmp(mz, mp) >= 0) {
			mpz_sub(mz, mz, mp);
		}
		Gmp::getArray(z, N, mz);
	}
	static inline void subC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
	{
		Unit ret[N + 1];
		mpz_t mz, mx, my;
		set_zero(mz, ret, N + 1);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		mpz_sub(mz, mx, my);
		if (mpz_sgn(mz) < 0) {
			mpz_t mp;
			set_mpz_t(mp, p);
			mpz_add(mz, mz, mp);
		}
		Gmp::getArray(z, N, mz);
	}
	static inline void mulPreC(Unit *z, const Unit *x, const Unit *y)
	{
		mpz_t mx, my, mz;
		set_zero(mz, z, N * 2);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		mpz_mul(mz, mx, my);
		Gmp::getArray(z, N * 2, mz);
	}
	// x[N * 2] -> y[N]
	static inline void modC(Unit *y, const Unit *x, const Unit *p)
	{
		mpz_t mx, my, mp;
		set_mpz_t(mx, x, N * 2);
		set_mpz_t(my, y);
		set_mpz_t(mp, p);
		mpz_mod(my, mx, mp);
		clearArray(y, my->_mp_size, N);
	}
	static inline void invOp(Unit *y, const Unit *x, const Op& op)
	{
		mpz_class my;
		mpz_t mx, mp;
		set_mpz_t(mx, x);
		set_mpz_t(mp, op.p);
		mpz_invert(my.get_mpz_t(), mx, mp);
		Gmp::getArray(y, N, my);
	}
	static inline bool isZeroC(const Unit *x)
	{
		return isZeroArray(x, N);
	}
	static inline void negC(Unit *y, const Unit *x, const Unit *p)
	{
		if (isZeroC(x)) {
			if (x != y) clearC(y);
			return;
		}
		subC(y, p, x, p);
	}
};

#ifdef MCL_USE_LLVM
	#define SET_OP_LLVM(n) \
		addP = mcl_fp_add ## n ##S; \
		subP = mcl_fp_sub ## n ##S; \
		mulPreP = mcl_fp_mulPre ## n; \
		mont = mcl_fp_mont ## n;
#else
	#define SET_OP_LLVM(n)
#endif

#define SET_OP(n) \
		N = n / UnitBitSize; \
		isZero = OpeFunc<n>::isZeroC; \
		clear = OpeFunc<n>::clearC; \
		copy = OpeFunc<n>::copyC; \
		negP = OpeFunc<n>::negC; \
		invOp = OpeFunc<n>::invOp; \
		addP = OpeFunc<n>::addC; \
		subP = OpeFunc<n>::subC; \
		mulPreP = OpeFunc<n>::mulPreC; \
		modP = OpeFunc<n>::modC; \
		SET_OP_LLVM(n)

#ifdef USE_MONT_FP
inline void invOpForMont(Unit *y, const Unit *x, const Op& op)
{
	Unit r[maxOpUnitSize];
	int k = op.preInv(r, x);
	/*
		xr = 2^k
		R = 2^(N * 64)
		get r2^(-k)R^2 = r 2^(N * 64 * 2 - k)
	*/
	op.mul(y, r, op.invTbl.data() + k * op.N);
}

static void initInvTbl(Op& op)
{
	const size_t N = op.N;
	const size_t invTblN = N * sizeof(Unit) * 8 * 2;
	op.invTbl.resize(invTblN * N);
	Unit *tbl = op.invTbl.data() + (invTblN - 1) * N;
	Unit t[maxOpUnitSize] = {};
	t[0] = 2;
	op.toMont(tbl, t);
	for (size_t i = 0; i < invTblN - 1; i++) {
		op.add(tbl - N, tbl, tbl);
		tbl -= N;
	}
}
#endif

static void initForMont(Op& op, const Unit *p)
{
	const size_t N = op.N;
	assert(N >= 2);
	mpz_class t = 1;
	Gmp::getArray(op.one, N, t);
	t = (t << (N * 64)) % op.mp;
	t = (t * t) % op.mp;
	Gmp::getArray(op.RR, N, t);
	op.rp = getMontgomeryCoeff(p[0]);
#ifdef USE_MONT_FP
	FpGenerator *fg = op.fg;
	if (fg == 0) return;
	fg->init(p, (int)N);

	op.neg = Xbyak::CastTo<void2u>(fg->neg_);
	op.add = Xbyak::CastTo<void3u>(fg->add_);
	op.sub = Xbyak::CastTo<void3u>(fg->sub_);
	op.mul = Xbyak::CastTo<void3u>(fg->mul_);
	op.preInv = Xbyak::CastTo<int2u>(op.fg->preInv_);
	op.invOp = &invOpForMont;

	initInvTbl(op);
#endif
}

void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
{
	cybozu::disable_warning_unused_variable(mode);
	bool isMinus = fp::strToMpzArray(&bitSize, p, maxBitSize, mp, mstr, base);
	if (isMinus) throw cybozu::Exception("Op:init:mstr is minus") << mstr;
	if (mp == 0) throw cybozu::Exception("Op:init:mstr is zero") << mstr;

	const size_t roundBit = (bitSize + UnitBitSize - 1) & ~(UnitBitSize - 1);
	switch (roundBit) {
	case 32:
	case 64:
	case 96:
	case 128: SET_OP(128); break;
	case 192: SET_OP(192); break;
	case 256: SET_OP(256); break;
	case 320: SET_OP(320); break;
	case 384: SET_OP(384); break;
	case 448: SET_OP(448); break;
	case 512: SET_OP(512); break;
#if CYBOZU_OS_BIT == 64
	case 576: SET_OP(576); break;
#else
	case 160: SET_OP(160); break;
	case 224: SET_OP(224); break;
	case 288: SET_OP(288); break;
	case 352: SET_OP(352); break;
	case 416: SET_OP(416); break;
	case 480: SET_OP(480); break;
	case 544: SET_OP(544); break;
#endif
	default:
		throw cybozu::Exception("Op::init:not:support") << mstr;
	}
#ifdef MCL_USE_LLVM
	if (mp == mpz_class("0xfffffffffffffffffffffffffffffffeffffffffffffffff")) {
		mul = &mcl_fp_mul_NIST_P192; // slower than MontFp192
	}
#endif
	if (useMont) {
		fp::initForMont(*this, p);
	}
	sq.set(mp);
}

void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPrefix)
{
	switch (base) {
	case 10:
		{
			mpz_class t;
			Gmp::setArray(t, x, n);
			Gmp::getStr(str, t, 10);
		}
		return;
	case 16:
		mcl::fp::toStr16(str, x, n, withPrefix);
		return;
	case 2:
		mcl::fp::toStr2(str, x, n, withPrefix);
		return;
	default:
		throw cybozu::Exception("fp:arrayToStr:bad base") << base;
	}
}

void copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask)
{
	const size_t fpByteSize = sizeof(Unit) * op.N;
	if (xByteSize > fpByteSize) {
		if (!doMask) throw cybozu::Exception("fp:copyAndMask:bad size") << xByteSize << fpByteSize;
		xByteSize = fpByteSize;
	}
	memcpy(y, x, xByteSize);
	memset((char *)y + xByteSize, 0, fpByteSize - xByteSize);
	if (!doMask) {
		if (compareArray(y, op.p, op.N) >= 0) throw cybozu::Exception("fp:copyAndMask:large x");
		return;
	}
	maskArray(y, op.N, op.bitSize - 1);
	assert(compareArray(y, op.p, op.N) < 0);
}

} } // mcl::fp

<commit_msg>add invMontOp<commit_after>#include <mcl/op.hpp>
#include <mcl/util.hpp>
#include <mcl/conversion.hpp>
#ifdef USE_MONT_FP
#include <mcl/fp_generator.hpp>
#endif
#include <mcl/fp_proto.hpp>

namespace mcl { namespace fp {

#ifdef USE_MONT_FP
FpGenerator *Op::createFpGenerator()
{
	return new FpGenerator();
}
void Op::destroyFpGenerator(FpGenerator *fg)
{
	delete fg;
}
#else
FpGenerator *Op::createFpGenerator()
{
	return 0;
}
void Op::destroyFpGenerator(FpGenerator *)
{
}
#endif

inline const char *verifyStr(bool *isMinus, int *base, const std::string& str)
{
	const char *p = str.c_str();
	if (*p == '-') {
		*isMinus = true;
		p++;
	} else {
		*isMinus = false;
	}
	if (p[0] == '0') {
		if (p[1] == 'x') {
			if (*base != 0 && *base != 16) {
				throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
			}
			*base = 16;
			p += 2;
		} else if (p[1] == 'b') {
			if (*base != 0 && *base != 2) {
				throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
			}
			*base = 2;
			p += 2;
		}
	}
	if (*base == 0) *base = 10;
	if (*p == '\0') throw cybozu::Exception("fp:verifyStr:str is empty");
	return p;
}

bool strToMpzArray(size_t *pBitSize, Unit *y, size_t maxBitSize, mpz_class& x, const std::string& str, int base)
{
	bool isMinus;
	const char *p = verifyStr(&isMinus, &base, str);
	if (!Gmp::setStr(x, p, base)) {
		throw cybozu::Exception("fp:strToMpzArray:bad format") << str;
	}
	const size_t bitSize = Gmp::getBitSize(x);
	if (bitSize > maxBitSize) throw cybozu::Exception("fp:strToMpzArray:too large str") << str << bitSize << maxBitSize;
	if (pBitSize) *pBitSize = bitSize;
	Gmp::getArray(y, (maxBitSize + UnitBitSize - 1) / UnitBitSize, x);
	return isMinus;
}

template<size_t bitSize>
struct OpeFunc {
	static const size_t N = (bitSize + UnitBitSize - 1) / UnitBitSize;
	static inline void set_mpz_t(mpz_t& z, const Unit* p, int n = (int)N)
	{
		z->_mp_alloc = n;
		z->_mp_size = getNonZeroArraySize(p, n);
		z->_mp_d = (mp_limb_t*)const_cast<Unit*>(p);
	}
	static inline void set_zero(mpz_t& z, Unit *p, size_t n)
	{
		z->_mp_alloc = (int)n;
		z->_mp_size = 0;
		z->_mp_d = (mp_limb_t*)p;
	}
	static inline void clearC(Unit *x)
	{
		clearArray(x, 0, N);
	}
	static inline void copyC(Unit *y, const Unit *x)
	{
		copyArray(y, x, N);
	}
	static inline void addC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
	{
		Unit ret[N + 2]; // not N + 1
		mpz_t mz, mx, my, mp;
		set_zero(mz, ret, N + 2);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		set_mpz_t(mp, p);
		mpz_add(mz, mx, my);
		if (mpz_cmp(mz, mp) >= 0) {
			mpz_sub(mz, mz, mp);
		}
		Gmp::getArray(z, N, mz);
	}
	static inline void subC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
	{
		Unit ret[N + 1];
		mpz_t mz, mx, my;
		set_zero(mz, ret, N + 1);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		mpz_sub(mz, mx, my);
		if (mpz_sgn(mz) < 0) {
			mpz_t mp;
			set_mpz_t(mp, p);
			mpz_add(mz, mz, mp);
		}
		Gmp::getArray(z, N, mz);
	}
	static inline void mulPreC(Unit *z, const Unit *x, const Unit *y)
	{
		mpz_t mx, my, mz;
		set_zero(mz, z, N * 2);
		set_mpz_t(mx, x);
		set_mpz_t(my, y);
		mpz_mul(mz, mx, my);
		Gmp::getArray(z, N * 2, mz);
	}
	// x[N * 2] -> y[N]
	static inline void modC(Unit *y, const Unit *x, const Unit *p)
	{
		mpz_t mx, my, mp;
		set_mpz_t(mx, x, N * 2);
		set_mpz_t(my, y);
		set_mpz_t(mp, p);
		mpz_mod(my, mx, mp);
		clearArray(y, my->_mp_size, N);
	}
	static inline void invOp(Unit *y, const Unit *x, const Op& op)
	{
		mpz_class my;
		mpz_t mx, mp;
		set_mpz_t(mx, x);
		set_mpz_t(mp, op.p);
		mpz_invert(my.get_mpz_t(), mx, mp);
		Gmp::getArray(y, N, my);
	}
	/*
		inv(x/R) = (1/x)R -toMont-> 1/x -toMont-> (1/x)R^-1
	*/
	static void invMontOp(Unit *y, const Unit *x, const Op& op)
	{
		invOp(y, x, op);
		op.toMont(y, y);
		op.toMont(y, y);
	}
	static inline bool isZeroC(const Unit *x)
	{
		return isZeroArray(x, N);
	}
	static inline void negC(Unit *y, const Unit *x, const Unit *p)
	{
		if (isZeroC(x)) {
			if (x != y) clearC(y);
			return;
		}
		subC(y, p, x, p);
	}
};

#ifdef MCL_USE_LLVM
	#define SET_OP_LLVM(n) \
		addP = mcl_fp_add ## n ##S; \
		subP = mcl_fp_sub ## n ##S; \
		mulPreP = mcl_fp_mulPre ## n; \
		mont = mcl_fp_mont ## n;
#else
	#define SET_OP_LLVM(n)
#endif

#define SET_OP(n) \
		N = n / UnitBitSize; \
		isZero = OpeFunc<n>::isZeroC; \
		clear = OpeFunc<n>::clearC; \
		copy = OpeFunc<n>::copyC; \
		negP = OpeFunc<n>::negC; \
		if (useMont) { \
			invOp = OpeFunc<n>::invMontOp; \
		} else { \
			invOp = OpeFunc<n>::invOp; \
		} \
		addP = OpeFunc<n>::addC; \
		subP = OpeFunc<n>::subC; \
		mulPreP = OpeFunc<n>::mulPreC; \
		modP = OpeFunc<n>::modC; \
		SET_OP_LLVM(n)

#ifdef USE_MONT_FP
inline void invOpForMont(Unit *y, const Unit *x, const Op& op)
{
	Unit r[maxOpUnitSize];
	int k = op.preInv(r, x);
	/*
		xr = 2^k
		R = 2^(N * 64)
		get r2^(-k)R^2 = r 2^(N * 64 * 2 - k)
	*/
	op.mul(y, r, op.invTbl.data() + k * op.N);
}

static void initInvTbl(Op& op)
{
	const size_t N = op.N;
	const size_t invTblN = N * sizeof(Unit) * 8 * 2;
	op.invTbl.resize(invTblN * N);
	Unit *tbl = op.invTbl.data() + (invTblN - 1) * N;
	Unit t[maxOpUnitSize] = {};
	t[0] = 2;
	op.toMont(tbl, t);
	for (size_t i = 0; i < invTblN - 1; i++) {
		op.add(tbl - N, tbl, tbl);
		tbl -= N;
	}
}
#endif

static void initForMont(Op& op, const Unit *p)
{
	const size_t N = op.N;
	assert(N >= 2);
	mpz_class t = 1;
	Gmp::getArray(op.one, N, t);
	t = (t << (N * 64)) % op.mp;
	t = (t * t) % op.mp;
	Gmp::getArray(op.RR, N, t);
	op.rp = getMontgomeryCoeff(p[0]);
#ifdef USE_MONT_FP
	FpGenerator *fg = op.fg;
	if (fg == 0) return;
	fg->init(p, (int)N);

	op.neg = Xbyak::CastTo<void2u>(fg->neg_);
	op.add = Xbyak::CastTo<void3u>(fg->add_);
	op.sub = Xbyak::CastTo<void3u>(fg->sub_);
	op.mul = Xbyak::CastTo<void3u>(fg->mul_);
	op.preInv = Xbyak::CastTo<int2u>(op.fg->preInv_);
	op.invOp = &invOpForMont;

	initInvTbl(op);
#endif
}

void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
{
	cybozu::disable_warning_unused_variable(mode);
	bool isMinus = fp::strToMpzArray(&bitSize, p, maxBitSize, mp, mstr, base);
	if (isMinus) throw cybozu::Exception("Op:init:mstr is minus") << mstr;
	if (mp == 0) throw cybozu::Exception("Op:init:mstr is zero") << mstr;

	const size_t roundBit = (bitSize + UnitBitSize - 1) & ~(UnitBitSize - 1);
	switch (roundBit) {
	case 32:
	case 64:
	case 96:
	case 128: SET_OP(128); break;
	case 192: SET_OP(192); break;
	case 256: SET_OP(256); break;
	case 320: SET_OP(320); break;
	case 384: SET_OP(384); break;
	case 448: SET_OP(448); break;
	case 512: SET_OP(512); break;
#if CYBOZU_OS_BIT == 64
	case 576: SET_OP(576); break;
#else
	case 160: SET_OP(160); break;
	case 224: SET_OP(224); break;
	case 288: SET_OP(288); break;
	case 352: SET_OP(352); break;
	case 416: SET_OP(416); break;
	case 480: SET_OP(480); break;
	case 544: SET_OP(544); break;
#endif
	default:
		throw cybozu::Exception("Op::init:not:support") << mstr;
	}
#ifdef MCL_USE_LLVM
	if (mp == mpz_class("0xfffffffffffffffffffffffffffffffeffffffffffffffff")) {
		mul = &mcl_fp_mul_NIST_P192; // slower than MontFp192
	}
#endif
	if (useMont) {
		fp::initForMont(*this, p);
	}
	sq.set(mp);
}

void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPrefix)
{
	switch (base) {
	case 10:
		{
			mpz_class t;
			Gmp::setArray(t, x, n);
			Gmp::getStr(str, t, 10);
		}
		return;
	case 16:
		mcl::fp::toStr16(str, x, n, withPrefix);
		return;
	case 2:
		mcl::fp::toStr2(str, x, n, withPrefix);
		return;
	default:
		throw cybozu::Exception("fp:arrayToStr:bad base") << base;
	}
}

void copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask)
{
	const size_t fpByteSize = sizeof(Unit) * op.N;
	if (xByteSize > fpByteSize) {
		if (!doMask) throw cybozu::Exception("fp:copyAndMask:bad size") << xByteSize << fpByteSize;
		xByteSize = fpByteSize;
	}
	memcpy(y, x, xByteSize);
	memset((char *)y + xByteSize, 0, fpByteSize - xByteSize);
	if (!doMask) {
		if (compareArray(y, op.p, op.N) >= 0) throw cybozu::Exception("fp:copyAndMask:large x");
		return;
	}
	maskArray(y, op.N, op.bitSize - 1);
	assert(compareArray(y, op.p, op.N) < 0);
}

} } // mcl::fp

<|endoftext|>