1
// Copyright (c) 1994 - 2010, Lawrence Livermore National Security, LLC.
3
// All rights reserved.
5
// This file is part of Silo. For details, see silo.llnl.gov.
7
// Redistribution and use in source and binary forms, with or without
8
// modification, are permitted provided that the following conditions
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the disclaimer below.
13
// * Redistributions in binary form must reproduce the above copyright
14
// notice, this list of conditions and the disclaimer (as noted
15
// below) in the documentation and/or other materials provided with
17
// * Neither the name of the LLNS/LLNL nor the names of its
18
// contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE
25
// LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR
26
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
// This work was produced at Lawrence Livermore National Laboratory under
35
// Contract No. DE-AC52-07NA27344 with the DOE. Neither the United
36
// States Government nor Lawrence Livermore National Security, LLC nor
37
// any of their employees, makes any warranty, express or implied, or
38
// assumes any liability or responsibility for the accuracy,
39
// completeness, or usefulness of any information, apparatus, product, or
40
// process disclosed, or represents that its use would not infringe
41
// privately-owned rights. Any reference herein to any specific
42
// commercial products, process, or services by trade name, trademark,
43
// manufacturer or otherwise does not necessarily constitute or imply its
44
// endorsement, recommendation, or favoring by the United States
45
// Government or Lawrence Livermore National Security, LLC. The views and
46
// opinions of authors expressed herein do not necessarily state or
47
// reflect those of the United States Government or Lawrence Livermore
48
// National Security, LLC, and shall not be used for advertising or
49
// product endorsement purposes.
55
// ****************************************************************************
56
// Method: DBfile_DBGetToc
59
// Encapsulates DBGetToc
64
// Programmer: Jeremy Meredith
65
// Creation: July 12, 2005
67
// ****************************************************************************
68
static PyObject *DBfile_DBGetToc(PyObject *self, PyObject *args)
70
DBfileObject *obj = (DBfileObject*)self;
74
SiloErrorFunc("This file has been closed.");
78
DBtoc *toc = DBGetToc(obj->db);
80
DBtocObject *retval = PyObject_NEW(DBtocObject, &DBtocType);
85
return (PyObject*)retval;
88
// ****************************************************************************
89
// Method: DBfile_DBGetVar
92
// Encapsulates DBGetVar
97
// Programmer: Jeremy Meredith
98
// Creation: July 12, 2005
102
// Mark C. Miller, Tue Aug 5 11:04:14 PDT 2008
103
// I modifed case where we're returning a string valued variable to strip
104
// off the trailing null character. The PyString_FromStringAndSize method
105
// was being given a length argument that included the trailing null and
106
// the result was a bit if an odd string in python.
108
// ****************************************************************************
109
static PyObject *DBfile_DBGetVar(PyObject *self, PyObject *args)
111
DBfile *db = ((DBfileObject*)self)->db;
115
SiloErrorFunc("This file has been closed.");
120
if(!PyArg_ParseTuple(args, "s", &str))
123
int vartype = DBInqVarType(db, str);
124
if (vartype != DB_VARIABLE)
126
SiloErrorFunc("Only flat variables are supported.");
130
int len = DBGetVarLength(db,str);
131
int type = DBGetVarType(db,str);
132
void *var = DBGetVar(db,str);
133
if (len == 1 || type == DB_CHAR)
138
return PyInt_FromLong(*((int*)var));
140
return PyInt_FromLong(*((short*)var));
142
return PyInt_FromLong(*((long*)var));
144
return PyFloat_FromDouble(*((float*)var));
146
return PyFloat_FromDouble(*((double*)var));
149
return PyInt_FromLong(*((char*)var));
152
// strip trailing null if one exists
153
char *p = (char *) var;
154
if (p[len-1] == '\0') len--;
155
return PyString_FromStringAndSize((char*)var, len);
158
SiloErrorFunc("Unknown variable type.");
164
PyObject *retval = PyTuple_New(len);
165
for (int i=0; i<len; i++)
171
tmp = PyInt_FromLong(((int*)var)[i]);
174
tmp = PyInt_FromLong(((short*)var)[i]);
177
tmp = PyInt_FromLong(((long*)var)[i]);
180
tmp = PyFloat_FromDouble(((float*)var)[i]);
183
tmp = PyFloat_FromDouble(((double*)var)[i]);
186
tmp = PyInt_FromLong(((char*)var)[i]);
189
SiloErrorFunc("Unknown variable type.");
192
PyTuple_SET_ITEM(retval, i, tmp);
198
// ****************************************************************************
199
// Method: DBfile_DBGetVar
202
// Encapsulates DBGetVar
205
// form 1: varname, integer
206
// form 2: varname, real
207
// form 3: varname, string
208
// form 4: varname, tuple
210
// Programmer: Jeremy Meredith
211
// Creation: July 12, 2005
213
// ****************************************************************************
214
static PyObject *DBfile_DBWrite(PyObject *self, PyObject *args)
216
DBfile *db = ((DBfileObject*)self)->db;
220
SiloErrorFunc("This file has been closed.");
232
if (PyArg_ParseTuple(args, "si", &str, &ivar) &&
233
PyArg_ParseTuple(args, "sd", &str, &dvar))
238
err = DBWrite(db, str, &ivar, &dims,1, DB_INT);
242
err = DBWrite(db, str, &dvar, &dims,1, DB_DOUBLE);
245
else if (PyArg_ParseTuple(args, "si", &str, &ivar))
248
err = DBWrite(db, str, &ivar, &dims,1, DB_INT);
250
else if (PyArg_ParseTuple(args, "sd", &str, &dvar))
253
err = DBWrite(db, str, &dvar, &dims,1, DB_DOUBLE);
255
else if (PyArg_ParseTuple(args, "ss", &str, &svar))
258
err = DBWrite(db, str, svar, &dims,1, DB_CHAR);
260
else if (PyArg_ParseTuple(args, "sO", &str, &tuple))
262
if(!PyTuple_Check(tuple))
265
int len = PyTuple_Size(tuple);
268
PyErr_SetString(PyExc_TypeError, "Tuple must be of size > 0");
272
PyObject *item = PyTuple_GET_ITEM(tuple, 0);
273
if (PyInt_Check(item))
275
int *values = new int[len];
276
for (int i=0; i<len; i++)
278
item = PyTuple_GET_ITEM(tuple, i);
279
if (PyInt_Check(item))
280
values[i] = int(PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, i)));
281
else if (PyFloat_Check(item))
282
values[i] = int(PyFloat_AS_DOUBLE(PyTuple_GET_ITEM(tuple, i)));
285
PyErr_SetString(PyExc_TypeError,
286
"Only int or float tuples are supported");
292
err = DBWrite(db, str, values, &len,1, DB_INT);
294
else if (PyFloat_Check(item))
296
double *values = new double[len];
297
for (int i=0; i<len; i++)
299
item = PyTuple_GET_ITEM(tuple, i);
300
if (PyInt_Check(item))
301
values[i] = double(PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, i)));
302
else if (PyFloat_Check(item))
303
values[i] = double(PyFloat_AS_DOUBLE(PyTuple_GET_ITEM(tuple, i)));
306
PyErr_SetString(PyExc_TypeError,
307
"Only int or float tuples are supported");
313
err = DBWrite(db, str, values, &len,1, DB_DOUBLE);
317
PyErr_SetString(PyExc_TypeError,
318
"Only int or float tuples are supported");
324
PyErr_SetString(PyExc_TypeError, "Function takes 2 arguments");
330
PyErr_SetString(PyExc_TypeError, "DBWrite failed");
339
// ****************************************************************************
340
// Method: DBfile_DBMkDir
343
// Encapsulates DBMkDir
348
// Programmer: Jeremy Meredith
349
// Creation: July 12, 2005
351
// ****************************************************************************
352
static PyObject *DBfile_DBMkDir(PyObject *self, PyObject *args)
354
DBfile *db = ((DBfileObject*)self)->db;
358
SiloErrorFunc("This file has been closed.");
363
if(!PyArg_ParseTuple(args, "s", &str))
366
if (DBMkDir(db, str))
368
SiloErrorFunc("Could not make the directory.");
378
// ****************************************************************************
379
// Method: DBfile_DBSetDir
382
// Encapsulates DBSetDir
387
// Programmer: Jeremy Meredith
388
// Creation: July 12, 2005
390
// ****************************************************************************
391
static PyObject *DBfile_DBSetDir(PyObject *self, PyObject *args)
393
DBfile *db = ((DBfileObject*)self)->db;
397
SiloErrorFunc("This file has been closed.");
402
if(!PyArg_ParseTuple(args, "s", &str))
405
if (DBSetDir(db, str))
407
SiloErrorFunc("Could not change directories.");
417
// ****************************************************************************
418
// Method: DBfile_DBClose
421
// Encapsulates DBClose
426
// Programmer: Jeremy Meredith
427
// Creation: July 12, 2005
429
// ****************************************************************************
430
static PyObject *DBfile_DBClose(PyObject *self, PyObject *args)
432
DBfile *db = ((DBfileObject*)self)->db;
436
SiloErrorFunc("This file has been closed.");
440
if(!PyArg_ParseTuple(args, ""))
445
SiloErrorFunc("Could not close the file.");
450
((DBfileObject*)self)->db = NULL;
456
// ****************************************************************************
457
// DBfile method definitions
459
// Programmer: Jeremy Meredith
460
// Creation: July 12, 2005
462
// ****************************************************************************
463
static struct PyMethodDef DBfile_methods[] = {
464
{"GetToc", DBfile_DBGetToc, METH_VARARGS},
465
{"GetVar", DBfile_DBGetVar, METH_VARARGS},
466
{"Write", DBfile_DBWrite, METH_VARARGS},
467
{"MkDir", DBfile_DBMkDir, METH_VARARGS},
468
{"SetDir", DBfile_DBSetDir, METH_VARARGS},
469
{"Close", DBfile_DBClose, METH_VARARGS},
473
// ****************************************************************************
474
// Method: DBfile_dealloc
477
// Deallocate the object.
482
// Programmer: Jeremy Meredith
483
// Creation: July 12, 2005
485
// ****************************************************************************
486
static void DBfile_dealloc(PyObject *self)
491
// ****************************************************************************
492
// Method: DBfile_as_string
495
// Convert the DBfileObject to a string representation.
498
// s the target string, with space already allocated
500
// Programmer: Jeremy Meredith
501
// Creation: July 12, 2005
503
// ****************************************************************************
504
static void DBfile_as_string(PyObject *self, char *s)
506
DBfileObject *obj = (DBfileObject*)self;
508
sprintf(s, "<DBfile object, filename='%s'>", obj->db->pub.name);
510
sprintf(s, "<closed DBfile object>");
513
// ****************************************************************************
514
// Method: DBfile_str
517
// Convert the DBfileObject to a PyString
522
// Programmer: Jeremy Meredith
523
// Creation: July 12, 2005
525
// ****************************************************************************
526
static PyObject *DBfile_str(PyObject *self)
529
DBfile_as_string(self, str);
530
return PyString_FromString(str);
533
// ****************************************************************************
534
// Method: DBfile_print
537
// Print the DBfileObject into a file as text
540
// fp the file pointer
543
// Programmer: Jeremy Meredith
544
// Creation: July 12, 2005
546
// ****************************************************************************
547
static int DBfile_print(PyObject *self, FILE *fp, int flags)
550
DBfile_as_string(self, str);
555
// ****************************************************************************
556
// Method: DBfile_getattr
559
// Return an attribute by name. There is only one attribute of a
560
// DBfile, which is its filename.
563
// name the name of the attribute to return
565
// Programmer: Jeremy Meredith
566
// Creation: July 12, 2005
568
// ****************************************************************************
569
static PyObject *DBfile_getattr(PyObject *self, char *name)
571
DBfileObject *obj = (DBfileObject*)self;
575
SiloErrorFunc("This file has been closed.");
579
if (!strcmp(name, "filename"))
583
return PyString_FromString(obj->db->pub.name);
587
return PyString_FromString("<closed file>");
591
return Py_FindMethod(DBfile_methods, self, name);
594
// ****************************************************************************
595
// Method: DBfile_compare
598
// Compare two DBfileObjects.
601
// u, v the objects to compare
603
// Programmer: Jeremy Meredith
604
// Creation: July 12, 2005
606
// ****************************************************************************
607
static int DBfile_compare(PyObject *v, PyObject *w)
609
DBfile *a = ((DBfileObject *)v)->db;
610
DBfile *b = ((DBfileObject *)w)->db;
611
return (a<b) ? -1 : ((a==b) ? 0 : +1);
615
// ****************************************************************************
616
// DBfile Python Type Object
618
// Programmer: Jeremy Meredith
619
// Creation: July 12, 2005
621
// ****************************************************************************
622
static char *DBfile_Purpose = "This class wraps a Silo DBfile object.";
623
PyTypeObject DBfileType =
628
PyObject_HEAD_INIT(&PyType_Type)
631
sizeof(DBfileObject), // tp_basicsize
636
(destructor)DBfile_dealloc, // tp_dealloc
637
(printfunc)DBfile_print, // tp_print
638
(getattrfunc)DBfile_getattr, // tp_getattr
639
0,//(setattrfunc)DBfile_setattr, // tp_setattr -- this object is read-only
640
(cmpfunc)DBfile_compare, // tp_compare
641
(reprfunc)0, // tp_repr
653
(reprfunc)DBfile_str, // tp_str
657
Py_TPFLAGS_CHECKTYPES, // tp_flags
658
DBfile_Purpose, // tp_doc
662
0 // tp_weaklistoffset
665
// ****************************************************************************
666
// Method: DBfile_NEW
669
// Allocate and initialize a DBfileObject.
672
// init the initial value
674
// Programmer: Jeremy Meredith
675
// Creation: July 12, 2005
677
// ****************************************************************************
678
PyObject *DBfile_NEW(DBfile *init)
680
DBfileObject *obj = PyObject_NEW(DBfileObject, &DBfileType);
685
return (PyObject*)obj;
688
// ****************************************************************************
689
// Method: DBfile_NEW
692
// Allocate and initialize a DBfileObject with default values.
697
// Programmer: Jeremy Meredith
698
// Creation: July 12, 2005
700
// ****************************************************************************
701
PyObject *DBfile_new(PyObject *self, PyObject *args)
703
return DBfile_NEW(NULL);