diff options
author | Guido van Rossum <guido@python.org> | 1997-09-05 07:08:39 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-09-05 07:08:39 (GMT) |
commit | 9eb671fac3ab8b47c7511513ab9576fee0aefc91 (patch) | |
tree | e411af973b408de343c6fbda36ec7c955fc80d02 /Modules | |
parent | bd4435abcc272cab7f97bd483410fac5ab14cc5f (diff) | |
download | cpython-9eb671fac3ab8b47c7511513ab9576fee0aefc91.zip cpython-9eb671fac3ab8b47c7511513ab9576fee0aefc91.tar.gz cpython-9eb671fac3ab8b47c7511513ab9576fee0aefc91.tar.bz2 |
Contribution by Hannu Krosing (with some changes).
Added 'p' format character for Pascal string (i.e. leading length
byte). This uses the count prefix line 's' does, except that the
count includes the length byte; i.e. '10p' takes 10 bytes packed but
has space for a length byte and 9 data bytes.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/structmodule.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/Modules/structmodule.c b/Modules/structmodule.c index 54ca631..ef35bd7 100644 --- a/Modules/structmodule.c +++ b/Modules/structmodule.c @@ -631,6 +631,7 @@ static formatdef native_table[] = { {'B', sizeof(char), 0, nu_ubyte, np_byte}, {'c', sizeof(char), 0, nu_char, np_char}, {'s', sizeof(char), 0, NULL}, + {'p', sizeof(char), 0, NULL}, {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short}, {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short}, {'i', sizeof(int), INT_ALIGN, nu_int, np_int}, @@ -761,6 +762,7 @@ static formatdef bigendian_table[] = { {'B', 1, 0, bu_uint, bp_int}, {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, + {'p', 1, 0, NULL}, {'h', 2, 0, bu_int, bp_int}, {'H', 2, 0, bu_uint, bp_uint}, {'i', 4, 0, bu_int, bp_int}, @@ -891,6 +893,7 @@ static formatdef lilendian_table[] = { {'B', 1, 0, lu_uint, lp_int}, {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, + {'p', 1, 0, NULL}, {'h', 2, 0, lu_int, lp_int}, {'H', 2, 0, lu_uint, lp_uint}, {'i', 4, 0, lu_int, lp_int}, @@ -1132,6 +1135,28 @@ struct_pack(self, args) res += num; break; } + else if (c == 'p') { + /* num is string size + 1, + to fit in the count byte */ + int n; + num--; /* now num is max string size */ + if (!PyString_Check(v)) { + PyErr_SetString(StructError, + "argument for 'p' must be a string"); + goto fail; + } + n = PyString_Size(v); + if (n > num) + n = num; + if (n > 0) + memcpy(res+1, PyString_AsString(v), n); + if (n < num) + /* no real need, just to be nice */ + memset(res+1+n, '\0', num-n); + *res++ = n; /* store the length byte */ + res += num; + break; + } else { if (e->pack(res, v, e) < 0) goto fail; @@ -1216,6 +1241,19 @@ struct_unpack(self, args) str += num; num = 0; } + else if (c == 'p') { + /* num is string buffer size, + not repeat count */ + int n = *(unsigned char*)str; + /* first byte (unsigned) is string size */ + if (n >= num) + n = num-1; + v = PyString_FromStringAndSize(str+1, n); + if (v == NULL) + goto fail; + str += num; + num = 0; + } else { v = e->unpack(str, e); if (v == NULL) |