@@ -985,7 +985,7 @@ class Array(BaseType):
985985 When using the default C-style parser, the following syntax is supported:
986986
987987 x[3] -> 3 -> static length.
988- x[] -> None -> null-terminated .
988+ x[] -> None -> length based on data buf length (to the end of buffer) (VLA/VSA) .
989989 x[expr] -> expr -> dynamic length.
990990 """
991991
@@ -1522,14 +1522,30 @@ def gen_struct_class(self, structure):
15221522 num = 'max(0, Expression(self.cstruct, "{expr}").evaluate(r))' .format (
15231523 expr = num .expr
15241524 )
1525-
1526- struct_read += (
1527- 'r["{name}"] = []\n '
1528- 'for _ in xrange({num}):\n '
1529- ' r["{name}"].append(self.cstruct.{struct_name}._read(stream))\n ' .format (
1530- name = field .name , num = num , struct_name = ft .type .name
1525+ if ft .dynamic : #To the end of buffer
1526+ struct_read += (
1527+ 'r["{name}"] = []\n '
1528+ 'while True:\n '
1529+ ' bufSize = stream.getbuffer().nbytes\n '
1530+ ' bufPos = stream.tell()\n '
1531+ ' try:'
1532+ ' a = self.cstruct.{struct_name}._read(stream)\n '
1533+ ' except:\n '
1534+ ' if bufSize == bufPos:\n '
1535+ ' break;\n '
1536+ ' raise EOFError()\n '
1537+ ' r["{name}"].append(a)\n ' .format (
1538+ name = field .name , num = num , struct_name = ft .type .name
1539+ )
1540+ )
1541+ else :
1542+ struct_read += (
1543+ 'r["{name}"] = []\n '
1544+ 'for _ in xrange({num}):\n '
1545+ ' r["{name}"].append(self.cstruct.{struct_name}._read(stream))\n ' .format (
1546+ name = field .name , num = num , struct_name = ft .type .name
1547+ )
15311548 )
1532- )
15331549 else :
15341550 struct_read += 'r["{name}"] = self.cstruct.{struct_name}._read(stream)\n ' .format (
15351551 name = field .name , struct_name = ft .name
@@ -1713,14 +1729,14 @@ def gen_dynamic_block(self, field):
17131729 t = field .type .type
17141730 reader = None
17151731
1716- if not field .type .count : # Null terminated
1732+ if not field .type .count : #To the end of buffer
17171733 if isinstance (t , PackedType ):
17181734 reader = (
17191735 't = []\n while True:\n '
17201736 ' d = stream.read({size})\n '
1737+ ' if len(d) == 0: break\n '
17211738 ' if len(d) != {size}: raise EOFError()\n '
17221739 ' v = struct.unpack(self.cstruct.endian + "{packchar}", d)[0]\n '
1723- ' if v == 0: break\n '
17241740 ' t.append(v)' .format (size = t .size , packchar = t .packchar )
17251741 )
17261742
@@ -1738,14 +1754,14 @@ def gen_dynamic_block(self, field):
17381754
17391755 if isinstance (t , WcharType ):
17401756 reader += ".decode('utf-16-le' if self.cstruct.endian == '<' else 'utf-16-be')"
1741- elif isinstance (t , BytesInteger ):
1757+ elif isinstance (t , BytesInteger ): #To the end of buffer
17421758 reader = (
17431759 't = []\n '
17441760 'while True:\n '
17451761 ' d = stream.read({size})\n '
1762+ ' if len(d) == 0: break\n '
17461763 ' if len(d) != {size}: raise EOFError()\n '
17471764 ' v = BytesInteger.parse(d, {size}, 1, {signed}, self.cstruct.endian)\n '
1748- ' if v == 0: break\n '
17491765 ' t.append(v)' .format (size = t .size , signed = t .signed )
17501766 )
17511767
0 commit comments