nakedmudv3.3/
nakedmudv3.3/lib/
nakedmudv3.3/lib/logs/
nakedmudv3.3/lib/misc/
nakedmudv3.3/lib/players/
nakedmudv3.3/lib/txt/
nakedmudv3.3/lib/world/
nakedmudv3.3/lib/world/examples/
nakedmudv3.3/lib/world/examples/mproto/
nakedmudv3.3/lib/world/examples/oproto/
nakedmudv3.3/lib/world/examples/reset/
nakedmudv3.3/lib/world/examples/rproto/
nakedmudv3.3/lib/world/examples/trigger/
nakedmudv3.3/lib/world/limbo/
nakedmudv3.3/lib/world/limbo/room/
nakedmudv3.3/lib/world/limbo/rproto/
nakedmudv3.3/src/alias/
nakedmudv3.3/src/char_vars/
nakedmudv3.3/src/editor/
nakedmudv3.3/src/example_module/
nakedmudv3.3/src/help/
nakedmudv3.3/src/set_val/
nakedmudv3.3/src/socials/
nakedmudv3.3/src/time/
//*****************************************************************************
//
// pystorage.c
//
// Provides a wrapper around NakedMud's storage structure for use by scripts
// and python modules.
//
//*****************************************************************************

#include <Python.h>
#include <structmember.h>

#include "../mud.h"
#include "../storage.h"

#include "pystorage.h"



//*****************************************************************************
// local data structures
//*****************************************************************************
typedef struct {
  PyObject_HEAD
  STORAGE_SET *set;
} PyStorageSet;

typedef struct {
  PyObject_HEAD
  STORAGE_SET_LIST *list;
} PyStorageList;



//*****************************************************************************
// local function prototypes
//*****************************************************************************
PyObject *newPyStorageList(STORAGE_SET_LIST *list);
int     PyStorageSet_Check(PyObject *value);
int    PyStorageList_Check(PyObject *value);



//*****************************************************************************
// py storage lists
//*****************************************************************************

//
// deallocate the storage list
void PyStorageList_dealloc(PyStorageList *self) {
  // do NOT free this!! People will need to close the encapsulating set
  //  if(self->list) storage_list_delete(self->list);
  self->ob_type->tp_free((PyObject*)self);
}

//
// create a new python storage list
PyObject *PyStorageList_new(PyTypeObject *type, PyObject *args, PyObject *kwds){
    PyStorageList *self = (PyStorageList *)type->tp_alloc(type, 0);
    self->list = NULL;
    return (PyObject *)self;
}

//
// initialize a new storage list
int PyStorageList_init(PyStorageList *self, PyObject *args, PyObject *kwds) {
  self->list = new_storage_list();
  return 0;
}

//
// return a python list of the sets in our storage list
PyObject *PyStorageList_sets(PyObject *self, PyObject *args) {
  STORAGE_SET_LIST *set_list = ((PyStorageList *)self)->list;
  STORAGE_SET           *set = NULL;
  PyObject             *list = PyList_New(0);

  // add in all of the elements
  while( (set = storage_list_next(set_list)) != NULL) {
    PyObject *pyset = newPyStorageSet(set);
    PyList_Append(list, pyset);
    Py_DECREF(pyset);
  }

  // return the new list
  PyObject *retval = Py_BuildValue("O", list);
  Py_DECREF(list);
  return retval;
}

//
// add a new set to the storage list
PyObject *PyStorageList_add(PyObject *self, PyObject *args) {
  PyStorageSet *set = NULL;
  if(!PyArg_ParseTuple(args, "O", &set)) {
    PyErr_Format(PyExc_TypeError,
		 "Only storage sets can be added to storage lists");
    return NULL;
  }

  // make sure it is indeed a storage set
  if(!PyStorageSet_Check((PyObject *)set)) {
    PyErr_Format(PyExc_TypeError,
		 "Only storage sets can be added to storage lists");
    return NULL;
  }

  // add it to the list and return
  storage_list_put(((PyStorageList *)self)->list, set->set);
  return Py_BuildValue("i", 1);
}



//*****************************************************************************
// The type object for PyStorageLists and method list
//*****************************************************************************
PyMethodDef PyStorageList_class_methods[] = {
  {"sets", PyStorageList_sets, METH_VARARGS,
   "Returns a python list of all the sets in the storage list" },
  {"add",  PyStorageList_add,  METH_VARARGS,
   "Adds a new storage set to the list" },
  {NULL, NULL, 0, NULL}  /* Sentinel */
};

PyTypeObject PyStorageList_Type = {
    PyObject_HEAD_INIT(NULL)
    0,                                /*ob_size*/
    "storage.StorageList",            /*tp_name*/
    sizeof(PyStorageList),            /*tp_basicsize*/
    0,                                /*tp_itemsize*/
    (destructor)PyStorageList_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*/
    "storage lists",                  /* tp_doc */
    0,		                      /* tp_traverse */
    0,		                      /* tp_clear */
    0,		                      /* tp_richcompare */
    0,		                      /* tp_weaklistoffset */
    0,		                      /* tp_iter */
    0,		                      /* tp_iternext */
    PyStorageList_class_methods,      /* tp_methods */
    0,                                /* tp_members */
    0,                                /* tp_getset */
    0,                                /* tp_base */
    0,                                /* tp_dict */
    0,                                /* tp_descr_get */
    0,                                /* tp_descr_set */
    0,                                /* tp_dictoffset */
    (initproc)PyStorageList_init,     /* tp_init */
    0,                                /* tp_alloc */
    PyStorageList_new,                /* tp_new */
};




//*****************************************************************************
// py storage sets
//*****************************************************************************

//
// deallocate the storage set
void PyStorageSet_dealloc(PyStorageSet *self) {
  // do NOT close or free this!! People will need to use the close() function
  //  if(self->set) storage_close(self->set);
  self->ob_type->tp_free((PyObject*)self);
}

//
// create a new python storage set
PyObject *PyStorageSet_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
    PyStorageSet *self = (PyStorageSet *)type->tp_alloc(type, 0);
    self->set = NULL;
    return (PyObject *)self;
}

//
// initialize a new storage set
int PyStorageSet_init(PyStorageSet *self, PyObject *args, PyObject *kwds) {
  static char *kwlist[] = {"file", NULL};
  char            *file = NULL;

  // get the universal id
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &file)) {
    PyErr_Format(PyExc_TypeError,
		 "Storage Set initializers may only take filename args.");
    return -1;
  }

  // if we have a filename, load up the storage set there
  if(file != NULL) {
    self->set = storage_read(file);
    // the file doesn't exist... just make a blank storage set
    if(self->set == NULL)
      self->set = new_storage_set();
  }
  // no argument... make a new storage set
  else
    self->set = new_storage_set();

  // no errors
  return 0;
}


//
// parses out the key of some argument list provided to a read function
char *PyStorageSet_readParseKey(PyObject *args) {
  char *key = NULL;
  if(!PyArg_ParseTuple(args, "s", &key)) {
    PyErr_Format(PyExc_TypeError, 
		 "String keys must be provided for storage read methods");
    return NULL;
  }
  return key;
}


//
// read a string from the storage set
PyObject *PyStorageSet_readString(PyObject *self, PyObject *args) { 
  char *key = PyStorageSet_readParseKey(args);
  if(key != NULL) 
    return Py_BuildValue("s", read_string(((PyStorageSet *)self)->set, key));
  else            
    return NULL;
}

//
// read an integer value from the storage set
PyObject *PyStorageSet_readInt   (PyObject *self, PyObject *args) { 
  char *key = PyStorageSet_readParseKey(args);
  if(key != NULL) 
    return Py_BuildValue("i", read_int(((PyStorageSet *)self)->set, key));
  else
    return NULL;
}

//
// read a double value from the storage set
PyObject *PyStorageSet_readDouble(PyObject *self, PyObject *args) {
  char *key = PyStorageSet_readParseKey(args);
  if(key != NULL) 
    return Py_BuildValue("d", read_double(((PyStorageSet *)self)->set, key));
  else
    return NULL;
}

//
// read a boolean value from the storage set
PyObject *PyStorageSet_readBool  (PyObject *self, PyObject *args) { 
  char *key = PyStorageSet_readParseKey(args);
  if(key != NULL) 
    return Py_BuildValue("i", read_bool(((PyStorageSet *)self)->set, key));
  else
    return NULL;
}

//
// read a storage list from the storage set
PyObject *PyStorageSet_readList  (PyObject *self, PyObject *args) { 
  char *key = PyStorageSet_readParseKey(args);
  if(key == NULL)
    return NULL;
  else {
    PyObject *pylist =
      newPyStorageList(read_list(((PyStorageSet*)self)->set, key));
    PyObject *retval = Py_BuildValue("O", pylist);
    Py_DECREF(pylist);
    return retval;
  }
}

//
// read a storage set from within the set
PyObject *PyStorageSet_readSet   (PyObject *self, PyObject *args) { 
  char *key = PyStorageSet_readParseKey(args);
  if(key == NULL)
    return NULL;
  else {
    PyObject *pyset = 
      newPyStorageSet(read_set(((PyStorageSet *)self)->set, key));
    PyObject *retval = Py_BuildValue("O", pyset);
    Py_DECREF(pyset);
    return retval;
  }
}


//
// here's a yucky macro for handling to store end of thigns
#define PYSTORE_PARSE(args, key, val, fmt)			\
  if(!PyArg_ParseTuple(args, fmt, &key, &val)) {		\
    PyErr_Format(PyExc_TypeError,				\
		 "Invalid types supplied to storage method");	\
    return NULL;						\
  }


//
// store a string in the set
PyObject *PyStorageSet_storeString(PyObject *self, PyObject *args) { 
  char *key = NULL;
  char *val = NULL;
  PYSTORE_PARSE(args, key, val, "ss");
  store_string(((PyStorageSet *)self)->set, key, val);
  return Py_BuildValue("i", 1);
}

//
// store an integer in the set
PyObject *PyStorageSet_storeInt   (PyObject *self, PyObject *args) { 
  char *key = NULL;
  int   val = 0;
  PYSTORE_PARSE(args, key, val, "si");
  store_int(((PyStorageSet *)self)->set, key, val);
  return Py_BuildValue("i", 1);
}

//
// store a double in the set
PyObject *PyStorageSet_storeDouble(PyObject *self, PyObject *args) { 
  char  *key = NULL;
  double val = 0;
  PYSTORE_PARSE(args, key, val, "sd");
  store_double(((PyStorageSet *)self)->set, key, val);
  return Py_BuildValue("i", 1);
}

//
// store a boolean in the set
PyObject *PyStorageSet_storeBool  (PyObject *self, PyObject *args) { 
  return PyStorageSet_storeInt(self, args);
}

//
// store a list in the set
PyObject *PyStorageSet_storeList  (PyObject *self, PyObject *args) { 
  PyStorageList *val = NULL;
  char          *key = NULL;
  PYSTORE_PARSE(args, key, val, "sO");
  store_list(((PyStorageSet *)self)->set, key, val->list);
  return Py_BuildValue("i", 1);
}

//
// store a set in the set
PyObject *PyStorageSet_storeSet   (PyObject *self, PyObject *args) { 
  PyStorageSet *val = NULL;
  char         *key = NULL;
  PYSTORE_PARSE(args, key, val, "sO");
  store_set(((PyStorageSet *)self)->set, key, val->set);
  return Py_BuildValue("i", 1);
}

//
// write the set to file
PyObject *PyStorageSet_write      (PyObject *self, PyObject *args) { 
  char *fname = NULL;
  if(!PyArg_ParseTuple(args, "s", &fname)) {
    PyErr_Format(PyExc_TypeError, 
		 "Filenames must be in string form");
    return NULL;
  }
  storage_write(((PyStorageSet *)self)->set, fname);
  return Py_BuildValue("i", 1);
}

//
// close a storage set, and clean up its memory
PyObject *PyStorageSet_close      (PyObject *self, PyObject *args) { 
  storage_close(((PyStorageSet *)self)->set);
  ((PyStorageSet *)self)->set = NULL;
  return Py_BuildValue("i", 1);
}

//
// return whether or not the set contains a given key
PyObject *PyStorageSet_contains   (PyObject *self, PyObject *args) { 
  char *key = NULL;
  if(!PyArg_ParseTuple(args, "s", &key)) {
    PyErr_Format(PyExc_TypeError, 
		"You can only check if storage sets contain string key values");
    return NULL;
  }
  return Py_BuildValue("i", storage_contains(((PyStorageSet *)self)->set, key));
}



//*****************************************************************************
// The type object for PyStorageSets and method list
//*****************************************************************************
PyMethodDef PyStorageSet_class_methods[] = {
  // read functions
  { "readString", PyStorageSet_readString, METH_VARARGS,
    "Read in the string value of a storage set entry, by key." },
  { "readInt",    PyStorageSet_readInt,    METH_VARARGS,
    "Read in the integer value of a storage set entry, by key." },
  { "readDouble", PyStorageSet_readDouble, METH_VARARGS,
    "Read in the double value of a storage set entry, by key." },
  { "readBool",   PyStorageSet_readBool,   METH_VARARGS,
    "Read in the boolean value of a storage set entry, by key." },
  { "readList",   PyStorageSet_readList,   METH_VARARGS,
    "Read in the list value of a storage set entry, by key." },
  { "readSet",    PyStorageSet_readSet,   METH_VARARGS,
    "Read in the set value of a storage set entry, by key." },

  // write store functions
  { "storeString", PyStorageSet_storeString, METH_VARARGS,
    "Store the string value of a storage set entry, by key." },
  { "storeInt",    PyStorageSet_storeInt,    METH_VARARGS,
    "Store the integer value of a storage set entry, by key." },
  { "storeDouble", PyStorageSet_storeDouble, METH_VARARGS,
    "Store the double value of a storage set entry, by key." },
  { "storeBool",   PyStorageSet_storeBool,   METH_VARARGS,
    "Store the boolean value of a storage set entry, by key." },
  { "storeList",   PyStorageSet_storeList,   METH_VARARGS,
    "Store the list value of a storage set entry, by key." },
  { "storeSet",    PyStorageSet_storeSet,    METH_VARARGS,
    "Store the set value of a storage set entry, by key." },

  // other functions
  { "write",       PyStorageSet_write,       METH_VARARGS,
    "Store the contents of the storage set to the specified filename" },
  { "close",       PyStorageSet_close,       METH_VARARGS,
    "Close a storage set. MUST be called when the storage set is done "
    "being used. Garbage collection will not delete the set." },
  { "contains",    PyStorageSet_contains,    METH_VARARGS,
    "Returns True if the set contains the given key, and false otherwise." },

  {NULL, NULL, 0, NULL}  /* Sentinel */
};


PyTypeObject PyStorageSet_Type = {
    PyObject_HEAD_INIT(NULL)
    0,                                /*ob_size*/
    "storage.StorageSet",             /*tp_name*/
    sizeof(PyStorageSet),             /*tp_basicsize*/
    0,                                /*tp_itemsize*/
    (destructor)PyStorageSet_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*/
    "storage sets",                   /* tp_doc */
    0,		                      /* tp_traverse */
    0,		                      /* tp_clear */
    0,		                      /* tp_richcompare */
    0,		                      /* tp_weaklistoffset */
    0,		                      /* tp_iter */
    0,		                      /* tp_iternext */
    PyStorageSet_class_methods,       /* tp_methods */
    0,                                /* tp_members */
    0,                                /* tp_getset */
    0,                                /* tp_base */
    0,                                /* tp_dict */
    0,                                /* tp_descr_get */
    0,                                /* tp_descr_set */
    0,                                /* tp_dictoffset */
    (initproc)PyStorageSet_init,      /* tp_init */
    0,                                /* tp_alloc */
    PyStorageSet_new,                 /* tp_new */
};



//
// all of the methods assocciated with the storage module
PyMethodDef PyStorage_module_methods[] = {
  {NULL, NULL, 0, NULL}  /* Sentinel */
};



//*****************************************************************************
// implementation of pystorage.h
//*****************************************************************************
PyMODINIT_FUNC init_PyStorage(void) {
  PyObject *module = Py_InitModule3("storage", PyStorage_module_methods,
				    "Python wrapper for storage sets.");
  // something went wrong... abort!
  if(module == NULL)
    return;

  // make sure the storage class is ready to be made
  if (!(PyType_Ready(&PyStorageSet_Type) < 0)) {
    // add our two classes
    PyTypeObject *type = &PyStorageSet_Type;
    Py_INCREF(&PyStorageSet_Type);
    PyModule_AddObject(module, "StorageSet", (PyObject *)type);
  }

  // make sure the list calss is ready to be made
  if(!(PyType_Ready(&PyStorageList_Type) < 0)) {
    PyTypeObject *type = &PyStorageList_Type;
    Py_INCREF(&PyStorageList_Type);
    PyModule_AddObject(module, "StorageList", (PyObject *)type);
  }
}


//
// create a new python representation of a storage set
PyObject *newPyStorageSet(STORAGE_SET *set) {
  PyStorageSet *pyset = 
    (PyStorageSet *)PyStorageSet_new(&PyStorageSet_Type, NULL, NULL);
  pyset->set = set;
  return (PyObject *)pyset;
}


//
// create a new list representation of a storage set
PyObject *newPyStorageList(STORAGE_SET_LIST *list) {
  PyStorageList *pylist = 
    (PyStorageList *)PyStorageList_new(&PyStorageList_Type, NULL, NULL);
  pylist->list = list;
  return (PyObject *)pylist;
}


//
// checks to see if the python object is a storage set
int PyStorageSet_Check(PyObject *value) {
  return PyObject_TypeCheck(value, &PyStorageSet_Type);
}


//
// checks to see if the python object is a storage list
int PyStorageList_Check(PyObject *value) {
  return PyObject_TypeCheck(value, &PyStorageList_Type);
}

//
// return the storage set that is contained within it.
STORAGE_SET *PyStorageSet_AsSet(PyObject *set) {
  return ((PyStorageSet *)set)->set;
}