python/py_tdbpack.c

ソースコードを見る。

関数

static PyObject * pytdbpack_number (char ch, PyObject *val_iter, PyObject *packed_list)
static PyObject * pytdbpack_str (char ch, PyObject *val_iter, PyObject *packed_list, const char *encoding)
static PyObject * pytdbpack_buffer (PyObject *val_iter, PyObject *packed_list)
static PyObject * pytdbunpack_item (char, char **pbuf, int *plen, PyObject *)
static PyObject * pytdbpack_data (const char *format_str, PyObject *val_seq, PyObject *val_list)
static PyObject * pytdbunpack_string (char **pbuf, int *plen, const char *encoding)
static void pack_le_uint32 (unsigned long val_long, unsigned char *pbuf)
static PyObject * pytdbpack_bad_type (char ch, const char *expected, PyObject *val_obj)
static PyObject * pytdbpack (PyObject *self, PyObject *args)
static void pack_bytes (long len, const char *from, unsigned char **pbuf)
static PyObject * pytdbunpack (PyObject *self, PyObject *args)
static void pytdbunpack_err_too_short (void)
static PyObject * pytdbunpack_uint32 (char **pbuf, int *plen)
static PyObject * pytdbunpack_int16 (char **pbuf, int *plen)
static PyObject * pytdbunpack_buffer (char **pbuf, int *plen, PyObject *val_list)
 DL_EXPORT (void)

変数

static const char * pytdbpack_docstring
static char const pytdbpack_doc []
static char const pytdbunpack_doc []
const char * pytdb_dos_encoding = "cp850"
const char * pytdb_unix_encoding = NULL
static PyMethodDef pytdbpack_methods []


関数

static PyObject * pytdbpack_number ( char  ch,
PyObject *  val_iter,
PyObject *  packed_list 
) [static]

py_tdbpack.c272 行で定義されています。

参照先 pack_le_uint32()pytdbpack_bad_type().

参照元 pytdbpack_buffer()pytdbpack_data().

00273 {
00274         unsigned long val_long;
00275         PyObject *val_obj = NULL, *long_obj = NULL, *result_obj = NULL;
00276         PyObject *new_list = NULL;
00277         unsigned char pack_buf[4];
00278 
00279         if (!(val_obj = PyIter_Next(val_iter)))
00280                 goto out;
00281 
00282         if (!(long_obj = PyNumber_Long(val_obj))) {
00283                 pytdbpack_bad_type(ch, "Number", val_obj);
00284                 goto out;
00285         }
00286 
00287         val_long = PyLong_AsUnsignedLong(long_obj);
00288         pack_le_uint32(val_long, pack_buf);
00289 
00290         /* pack as 32-bit; if just packing a 'w' 16-bit word then only take
00291            the first two bytes. */
00292         
00293         if (!(result_obj = PyString_FromStringAndSize(pack_buf, ch == 'w' ? 2 : 4)))
00294                 goto out;
00295 
00296         if (PyList_Append(packed_list, result_obj) != -1)
00297                 new_list = packed_list;
00298 
00299   out:
00300         Py_XDECREF(val_obj);
00301         Py_XDECREF(long_obj);
00302         Py_XDECREF(result_obj);
00303 
00304         return new_list;
00305 }

static PyObject * pytdbpack_str ( char  ch,
PyObject *  val_iter,
PyObject *  packed_list,
const char *  encoding 
) [static]

py_tdbpack.c326 行で定義されています。

参照先 pytdbpack_bad_type().

参照元 pytdbpack_data().

00328 {
00329         PyObject *val_obj = NULL;
00330         PyObject *unicode_obj = NULL;
00331         PyObject *coded_str = NULL;
00332         PyObject *nul_str = NULL;
00333         PyObject *new_list = NULL;
00334 
00335         if (!(val_obj = PyIter_Next(val_iter)))
00336                 goto out;
00337 
00338         if (PyUnicode_Check(val_obj)) {
00339                 if (!(coded_str = PyUnicode_AsEncodedString(val_obj, encoding, NULL)))
00340                         goto out;
00341         }
00342         else if (PyString_Check(val_obj) && !encoding) {
00343                 /* For efficiency, we assume that the Python interpreter has
00344                    the same default string encoding as Samba's native string
00345                    encoding.  On the PSA, both are always 8859-1. */
00346                 coded_str = val_obj;
00347                 Py_INCREF(coded_str);
00348         }
00349         else if (PyString_Check(val_obj)) {
00350                 /* String, but needs to be converted */
00351                 if (!(unicode_obj = PyString_AsDecodedObject(val_obj, NULL, NULL)))
00352                         goto out;
00353                 if (!(coded_str = PyUnicode_AsEncodedString(unicode_obj, encoding, NULL)))
00354                         goto out;
00355         }
00356         else {
00357                 pytdbpack_bad_type(ch, "String or Unicode", val_obj);
00358                 goto out;
00359         }
00360 
00361         if (!nul_str)
00362                 /* this is constant and often-used; hold it forever */
00363                 if (!(nul_str = PyString_FromStringAndSize("", 1)))
00364                         goto out;
00365 
00366         if ((PyList_Append(packed_list, coded_str) != -1)
00367             && (PyList_Append(packed_list, nul_str) != -1))
00368                 new_list = packed_list;
00369 
00370   out:
00371         Py_XDECREF(val_obj);
00372         Py_XDECREF(unicode_obj);
00373         Py_XDECREF(coded_str);
00374 
00375         return new_list;
00376 }

static PyObject * pytdbpack_buffer ( PyObject *  val_iter,
PyObject *  packed_list 
) [static]

py_tdbpack.c386 行で定義されています。

参照先 pytdbpack_bad_type()pytdbpack_number().

参照元 pytdbpack_data().

00387 {
00388         PyObject *val_obj;
00389         PyObject *new_list = NULL;
00390         
00391         /* pull off integer and stick onto list */
00392         if (!(packed_list = pytdbpack_number('d', val_iter, packed_list)))
00393                 return NULL;
00394 
00395         /* this assumes that the string is the right length; the old code did
00396            the same. */
00397         if (!(val_obj = PyIter_Next(val_iter)))
00398                 return NULL;
00399 
00400         if (!PyString_Check(val_obj)) {
00401                 pytdbpack_bad_type('B', "String", val_obj);
00402                 goto out;
00403         }
00404         
00405         if (PyList_Append(packed_list, val_obj) != -1)
00406                 new_list = packed_list;
00407 
00408   out:
00409         Py_XDECREF(val_obj);
00410         return new_list;
00411 }

static PyObject * pytdbunpack_item ( char  ,
char **  pbuf,
int *  plen,
PyObject *   
) [static]

py_tdbpack.c665 行で定義されています。

参照先 pytdb_unix_encodingpytdbunpack_buffer()pytdbunpack_int16()pytdbunpack_string()pytdbunpack_uint32().

参照元 pytdbunpack().

00669 {
00670         PyObject *unpacked;
00671         
00672         if (ch == 'w') {        /* 16-bit int */
00673                 unpacked = pytdbunpack_int16(pbuf, plen);
00674         }
00675         else if (ch == 'd' || ch == 'p') { /* 32-bit int */
00676                 /* pointers can just come through as integers */
00677                 unpacked = pytdbunpack_uint32(pbuf, plen);
00678         }
00679         else if (ch == 'f' || ch == 'P') { /* nul-term string  */
00680                 unpacked = pytdbunpack_string(pbuf, plen, pytdb_unix_encoding);
00681         }
00682         else if (ch == 'B') { /* length, buffer */
00683                 return pytdbunpack_buffer(pbuf, plen, val_list);
00684         }
00685         else {
00686                 PyErr_Format(PyExc_ValueError,
00687                              "%s: format character '%c' is not supported", 
00688                              FUNCTION_MACRO, ch);
00689                 
00690                 return NULL;
00691         }
00692 
00693         /* otherwise OK */
00694         if (!unpacked)
00695                 return NULL;
00696 
00697         if (PyList_Append(val_list, unpacked) == -1)
00698                 val_list = NULL;
00699 
00700         /* PyList_Append takes a new reference to the inserted object.
00701            Therefore, we no longer need the original reference. */
00702         Py_DECREF(unpacked);
00703         
00704         return val_list;
00705 }

PyObject * pytdbpack_data ( const char *  format_str,
PyObject *  val_seq,
PyObject *  val_list 
) [static]

py_tdbpack.c228 行で定義されています。

参照先 pytdb_unix_encodingpytdbpack_buffer()pytdbpack_number()pytdbpack_str().

参照元 pytdbpack().

00231 {
00232         int format_i, val_i = 0;
00233 
00234         for (format_i = 0, val_i = 0; format_str[format_i]; format_i++) {
00235                 char ch = format_str[format_i];
00236 
00237                 switch (ch) {
00238                         /* dispatch to the appropriate packer for this type,
00239                            which should pull things off the iterator, and
00240                            append them to the packed_list */
00241                 case 'w':
00242                 case 'd':
00243                 case 'p':
00244                         if (!(packed_list = pytdbpack_number(ch, val_iter, packed_list)))
00245                                 return NULL;
00246                         break;
00247 
00248                 case 'f':
00249                 case 'P':
00250                         if (!(packed_list = pytdbpack_str(ch, val_iter, packed_list, pytdb_unix_encoding)))
00251                                 return NULL;
00252                         break;
00253 
00254                 case 'B':
00255                         if (!(packed_list = pytdbpack_buffer(val_iter, packed_list)))
00256                                 return NULL;
00257                         break;
00258 
00259                 default:
00260                         PyErr_Format(PyExc_ValueError,
00261                                      "%s: format character '%c' is not supported",
00262                                      FUNCTION_MACRO, ch);
00263                         return NULL;
00264                 }
00265         }
00266 
00267         return packed_list;
00268 }

static PyObject * pytdbunpack_string ( char **  pbuf,
int *  plen,
const char *  encoding 
) [static]

py_tdbpack.c573 行で定義されています。

参照先 lenpytdbunpack_err_too_short().

参照元 pytdbunpack_item().

00574 {
00575         int len;
00576         char *nul_ptr, *start;
00577 
00578         start = *pbuf;
00579         
00580         nul_ptr = memchr(start, '\0', *plen);
00581         if (!nul_ptr) {
00582                 pytdbunpack_err_too_short();
00583                 return NULL;
00584         }
00585 
00586         len = nul_ptr - start;
00587 
00588         *pbuf += len + 1;       /* skip \0 */
00589         *plen -= len + 1;
00590 
00591         return PyString_Decode(start, len, encoding, NULL);
00592 }

static void pack_le_uint32 ( unsigned long  val_long,
unsigned char *  pbuf 
) [static]

py_tdbpack.c435 行で定義されています。

参照元 pytdbpack_number().

00436 {
00437         pbuf[0] =         val_long & 0xff;
00438         pbuf[1] = (val_long >> 8)  & 0xff;
00439         pbuf[2] = (val_long >> 16) & 0xff;
00440         pbuf[3] = (val_long >> 24) & 0xff;
00441 }

static PyObject * pytdbpack_bad_type ( char  ch,
const char *  expected,
PyObject *  val_obj 
) [static]

py_tdbpack.c414 行で定義されています。

参照元 pytdbpack_buffer()pytdbpack_number()pytdbpack_str().

00417 {
00418         PyObject *r = PyObject_Repr(val_obj);
00419         if (!r)
00420                 return NULL;
00421         PyErr_Format(PyExc_TypeError,
00422                      "tdbpack: format '%c' requires %s, not %s",
00423                      ch, expected, PyString_AS_STRING(r));
00424         Py_DECREF(r);
00425         return val_obj;
00426 }

static PyObject* pytdbpack ( PyObject *  self,
PyObject *  args 
) [static]

py_tdbpack.c178 行で定義されています。

参照先 pytdbpack_data().

00180 {
00181         char *format_str;
00182         PyObject *val_seq, *val_iter = NULL,
00183                 *packed_list = NULL, *packed_str = NULL,
00184                 *empty_str = NULL;
00185 
00186         /* TODO: Test passing wrong types or too many arguments */
00187         if (!PyArg_ParseTuple(args, "sO", &format_str, &val_seq))
00188                 return NULL;
00189 
00190         if (!(val_iter = PyObject_GetIter(val_seq)))
00191                 goto out;
00192 
00193         /* Create list to hold strings until we're done, then join them all. */
00194         if (!(packed_list = PyList_New(0)))
00195                 goto out;
00196 
00197         if (!pytdbpack_data(format_str, val_iter, packed_list))
00198                 goto out;
00199 
00200         /* this function is not officially documented but it works */
00201         if (!(empty_str = PyString_InternFromString("")))
00202                 goto out;
00203         
00204         packed_str = _PyString_Join(empty_str, packed_list);
00205 
00206   out:
00207         Py_XDECREF(empty_str);
00208         Py_XDECREF(val_iter);
00209         Py_XDECREF(packed_list);
00210 
00211         return packed_str;
00212 }

static void pack_bytes ( long  len,
const char *  from,
unsigned char **  pbuf 
) [static]

py_tdbpack.c445 行で定義されています。

00447 {
00448         memcpy(*pbuf, from, len);
00449         (*pbuf) += len;
00450 }

static PyObject* pytdbunpack ( PyObject *  self,
PyObject *  args 
) [static]

py_tdbpack.c455 行で定義されています。

参照先 failedpytdbunpack_item().

00457 {
00458         char *format_str, *packed_str, *ppacked;
00459         PyObject *val_list = NULL, *ret_tuple = NULL;
00460         PyObject *rest_string = NULL;
00461         int format_len, packed_len;
00462         char last_format = '#'; /* invalid */
00463         int i;
00464         
00465         /* get arguments */
00466         if (!PyArg_ParseTuple(args, "ss#", &format_str, &packed_str, &packed_len))
00467                 return NULL;
00468 
00469         format_len = strlen(format_str);
00470         
00471         /* Allocate list to hold results.  Initially empty, and we append
00472            results as we go along. */
00473         val_list = PyList_New(0);
00474         if (!val_list)
00475                 goto failed;
00476         ret_tuple = PyTuple_New(2);
00477         if (!ret_tuple)
00478                 goto failed;
00479         
00480         /* For every object, unpack.  */
00481         for (ppacked = packed_str, i = 0; i < format_len && format_str[i] != '$'; i++) {
00482                 last_format = format_str[i];
00483                 /* packed_len is reduced in place */
00484                 if (!pytdbunpack_item(format_str[i], &ppacked, &packed_len, val_list))
00485                         goto failed;
00486         }
00487 
00488         /* If the last character was '$', keep going until out of space */
00489         if (format_str[i] == '$') {
00490                 if (i == 0) {
00491                         PyErr_Format(PyExc_ValueError,
00492                                      "%s: '$' may not be first character in format",
00493                                      FUNCTION_MACRO);
00494                         return NULL;
00495                 } 
00496                 while (packed_len > 0)
00497                         if (!pytdbunpack_item(last_format, &ppacked, &packed_len, val_list))
00498                                 goto failed;
00499         }
00500         
00501         /* save leftovers for next time */
00502         rest_string = PyString_FromStringAndSize(ppacked, packed_len);
00503         if (!rest_string)
00504                 goto failed;
00505 
00506         /* return (values, rest) tuple; give up references to them */
00507         PyTuple_SET_ITEM(ret_tuple, 0, val_list);
00508         val_list = NULL;
00509         PyTuple_SET_ITEM(ret_tuple, 1, rest_string);
00510         val_list = NULL;
00511         return ret_tuple;
00512 
00513   failed:
00514         /* handle failure: deallocate anything.  XDECREF forms handle NULL
00515            pointers for objects that haven't been allocated yet. */
00516         Py_XDECREF(val_list);
00517         Py_XDECREF(ret_tuple);
00518         Py_XDECREF(rest_string);
00519         return NULL;
00520 }

static void pytdbunpack_err_too_short ( void   )  [static]

py_tdbpack.c524 行で定義されています。

参照元 pytdbunpack_buffer()pytdbunpack_int16()pytdbunpack_string()pytdbunpack_uint32().

00525 {
00526         PyErr_Format(PyExc_IndexError,
00527                      "%s: data too short for unpack format", FUNCTION_MACRO);
00528 }

static PyObject* pytdbunpack_uint32 ( char **  pbuf,
int *  plen 
) [static]

py_tdbpack.c532 行で定義されています。

参照先 pytdbunpack_err_too_short().

参照元 pytdbunpack_item().

00533 {
00534         unsigned long v;
00535         unsigned char *b;
00536         
00537         if (*plen < 4) {
00538                 pytdbunpack_err_too_short();
00539                 return NULL;
00540         }
00541 
00542         b = *pbuf;
00543         v = b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
00544         
00545         (*pbuf) += 4;
00546         (*plen) -= 4;
00547 
00548         return PyLong_FromUnsignedLong(v);
00549 }

static PyObject* pytdbunpack_int16 ( char **  pbuf,
int *  plen 
) [static]

py_tdbpack.c552 行で定義されています。

参照先 pytdbunpack_err_too_short().

参照元 pytdbunpack_item().

00553 {
00554         long v;
00555         unsigned char *b;
00556         
00557         if (*plen < 2) {
00558                 pytdbunpack_err_too_short();
00559                 return NULL;
00560         }
00561 
00562         b = *pbuf;
00563         v = b[0] | b[1]<<8;
00564         
00565         (*pbuf) += 2;
00566         (*plen) -= 2;
00567 
00568         return PyInt_FromLong(v);
00569 }

static PyObject* pytdbunpack_buffer ( char **  pbuf,
int *  plen,
PyObject *  val_list 
) [static]

py_tdbpack.c596 行で定義されています。

参照先 failedpytdbunpack_err_too_short().

参照元 pytdbunpack_item().

00597 {
00598         /* first get 32-bit len */
00599         long slen;
00600         unsigned char *b;
00601         unsigned char *start;
00602         PyObject *str_obj = NULL, *len_obj = NULL;
00603         
00604         if (*plen < 4) {
00605                 pytdbunpack_err_too_short();
00606                 return NULL;
00607         }
00608         
00609         b = *pbuf;
00610         slen = b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
00611 
00612         if (slen < 0) { /* surely you jest */
00613                 PyErr_Format(PyExc_ValueError,
00614                              "%s: buffer seems to have negative length", FUNCTION_MACRO);
00615                 return NULL;
00616         }
00617 
00618         (*pbuf) += 4;
00619         (*plen) -= 4;
00620         start = *pbuf;
00621 
00622         if (*plen < slen) {
00623                 PyErr_Format(PyExc_IndexError,
00624                              "%s: not enough data to unpack buffer: "
00625                              "need %d bytes, have %d", FUNCTION_MACRO,
00626                              (int) slen, *plen);
00627                 return NULL;
00628         }
00629 
00630         (*pbuf) += slen;
00631         (*plen) -= slen;
00632 
00633         if (!(len_obj = PyInt_FromLong(slen)))
00634                 goto failed;
00635 
00636         if (PyList_Append(val_list, len_obj) == -1)
00637                 goto failed;
00638         
00639         if (!(str_obj = PyString_FromStringAndSize(start, slen)))
00640                 goto failed;
00641         
00642         if (PyList_Append(val_list, str_obj) == -1)
00643                 goto failed;
00644         
00645         Py_DECREF(len_obj);
00646         Py_DECREF(str_obj);
00647         
00648         return val_list;
00649 
00650   failed:
00651         Py_XDECREF(len_obj);    /* handles NULL */
00652         Py_XDECREF(str_obj);
00653         return NULL;
00654 }

DL_EXPORT ( void   ) 

py_tdbpack.c717 行で定義されています。

参照先 pytdbpack_docstringpytdbpack_methods.

00719 {
00720         Py_InitModule3("tdbpack", pytdbpack_methods,
00721                        (char *) pytdbpack_docstring);
00722 }


変数

const char* pytdbpack_docstring [static]

py_tdbpack.c68 行で定義されています。

参照元 DL_EXPORT().

char const pytdbpack_doc[] [static]

初期値:

 
"pack(format, values) -> buffer\n"
"Pack Python objects into Samba binary format according to format string.\n"
"\n"
"arguments:\n"
"    format -- string of tdbpack format characters\n"
"    values -- sequence of value objects corresponding 1:1 to format characters\n"
"\n"
"returns:\n"
"    buffer -- string containing packed data\n"
"\n"
"raises:\n"
"    IndexError -- if there are too few values for the format\n"
"    ValueError -- if any of the format characters is illegal\n"
"    TypeError  -- if the format is not a string, or values is not a sequence,\n"
"        or any of the values is of the wrong type for the corresponding\n"
"        format character\n"
"\n"
"notes:\n"
"    For historical reasons, it is not an error to pass more values than are consumed\n"
"    by the format.\n"

py_tdbpack.c113 行で定義されています。

char const pytdbunpack_doc[] [static]

初期値:

"unpack(format, buffer) -> (values, rest)\n"
"Unpack Samba binary data according to format string.\n"
"\n"
"arguments:\n"
"    format -- string of tdbpack characters\n"
"    buffer -- string of packed binary data\n"
"\n"
"returns:\n"
"    2-tuple of:\n"
"        values -- sequence of values corresponding 1:1 to format characters\n"
"        rest -- string containing data that was not decoded, or '' if the\n"
"            whole string was consumed\n"
"\n"
"raises:\n"
"    IndexError -- if there is insufficient data in the buffer for the\n"
"        format (or if the data is corrupt and contains a variable-length\n"
"        field extending past the end)\n"
"    ValueError -- if any of the format characters is illegal\n"
"\n"
"notes:\n"
"    Because unconsumed data is returned, you can feed it back in to the\n"
"    unpacker to extract further fields.  Alternatively, if you wish to modify\n"
"    some fields near the start of the data, you may be able to save time by\n"
"    only unpacking and repacking the necessary part.\n"

py_tdbpack.c136 行で定義されています。

const char* pytdb_dos_encoding = "cp850"

py_tdbpack.c163 行で定義されています。

const char* pytdb_unix_encoding = NULL

py_tdbpack.c167 行で定義されています。

参照元 pytdbpack_data()pytdbunpack_item().

PyMethodDef pytdbpack_methods[] [static]

初期値:

 {
        { "pack", pytdbpack, METH_VARARGS, (char *) pytdbpack_doc },
        { "unpack", pytdbunpack, METH_VARARGS, (char *) pytdbunpack_doc },
}

py_tdbpack.c712 行で定義されています。

参照元 DL_EXPORT().


Sambaに対してSat Aug 29 21:24:05 2009に生成されました。  doxygen 1.4.7