@@ -314,12 +314,12 @@ private CharSequence generateVarData(final List<Token> tokens)
314314 " def get%1$s(self):\n "  +
315315 " sizeOfLengthField = %3$d\n "  +
316316 " lengthPosition = self.getPosition()\n "  +
317-  " dataLength = struct.unpack_from('%5$s', self.buffer_, lengthPosition[0] )[0]\n "  +
318-  " self.setPosition(lengthPosition[0]  + sizeOfLengthField)\n "  +
317+  " dataLength = struct.unpack_from('%5$s', self.buffer_, lengthPosition)[0]\n "  +
318+  " self.setPosition(lengthPosition + sizeOfLengthField)\n "  +
319319 " pos = self.getPosition()\n "  +
320-  " fmt = '"  + byteOrder  + "'+ str(dataLength)+'c '\n "  +
321-  " data = struct.unpack_from(fmt, self.buffer_, lengthPosition [0]) \n "  +
322-  " self.setPosition(pos[0]  + dataLength)\n "  +
320+  " fmt = '"  + byteOrder  + "' +  str(dataLength) + 's '\n "  +
321+  " data = struct.unpack_from(fmt, self.buffer_, pos) [0]\n "  +
322+  " self.setPosition(pos + dataLength)\n "  +
323323 " return data\n \n " ,
324324 propertyName ,
325325 generateArrayFieldNotPresentCondition (token .version (), BASE_INDENT ),
@@ -332,13 +332,12 @@ private CharSequence generateVarData(final List<Token> tokens)
332332 " def set%1$s(self, buffer):\n "  +
333333 " sizeOfLengthField = %2$d\n "  +
334334 " lengthPosition = self.getPosition()\n "  +
335-  " struct.pack_into('%3$s', self.buffer_, lengthPosition[0] , len(buffer))\n "  +
336-  " self.setPosition(lengthPosition[0]  + sizeOfLengthField)\n "  +
335+  " struct.pack_into('%3$s', self.buffer_, lengthPosition, len(buffer))\n "  +
336+  " self.setPosition(lengthPosition + sizeOfLengthField)\n "  +
337337 " pos = self.getPosition()\n "  +
338-  " fmt = '"  + byteOrder  + "c'\n "  +
339-  " for i in range(0,len(buffer)):\n "  +
340-  " struct.pack_into(fmt, self.buffer_, lengthPosition[0]+i, buffer[i])\n "  +
341-  " self.setPosition(pos[0] + len(buffer))\n \n " ,
338+  " fmt = '"  + byteOrder  + "' + str(len(buffer)) + 's'\n "  +
339+  " struct.pack_into(fmt, self.buffer_, pos, buffer)\n "  +
340+  " self.setPosition(pos + len(buffer))\n \n " ,
342341 propertyName ,
343342 sizeOfLengthField ,
344343 lengthPythonType ,
@@ -394,7 +393,7 @@ private void generateVarDataDescriptors(
394393
395394 sb .append (String .format (
396395 " def %1$sLength(self):\n "  +
397-  " return struct.unpack_from('%4$s', self.buffer_, position ())[0]\n \n " ,
396+  " return struct.unpack_from('%4$s', self.buffer_, getPosition ())[0]\n \n " ,
398397 formatPropertyName (propertyName ),
399398 generateArrayFieldNotPresentCondition (token .version (), BASE_INDENT ),
400399 formatByteOrderEncoding (lengthToken .encoding ().byteOrder (), lengthToken .encoding ().primitiveType ()),
@@ -432,9 +431,9 @@ private void generateEnum(final List<Token> tokens) throws IOException
432431 try  (final  Writer  out  = outputManager .createOutput (enumName ))
433432 {
434433 out .append (generateFileHeader (ir .applicableNamespace ().replace ('.' , '_' ), null ));
435-  out .append (generateEnumDeclaration (enumName ));
434+  out .append (generateClassDeclaration (enumName ));
436435 out .append (generateEnumValues (tokens .subList (1 , tokens .size () - 1 ), enumToken ));
437-  out .append (generateEnumLookupMethod ( tokens . subList ( 1 ,  tokens . size () -  1 ),  enumToken ));
436+  out .append (generateEnumMethods ( enumName ));
438437 }
439438 }
440439
@@ -514,55 +513,65 @@ private CharSequence generateEnumValues(final List<Token> tokens, final Token en
514513 final  StringBuilder  sb  = new  StringBuilder ();
515514 final  Encoding  encoding  = encodingToken .encoding ();
516515
517-  sb .append (" class Value:\n " );
516+  for  (final  Token  token  : tokens )
517+  {
518+  if  (encoding .primitiveType () == PrimitiveType .CHAR )
519+  {
520+  final  char  constVal  = (char ) token .encoding ().constValue ().longValue ();
521+  sb .append (" " ).append (token .name ()).append (" = '" ).append (constVal ).append ("'\n " );
522+  }
523+  else 
524+  {
525+  final  CharSequence  constVal  = generateLiteral (
526+  token .encoding ().primitiveType (), token .encoding ().constValue ().toString ());
527+  sb .append (" " ).append (token .name ()).append (" = " ).append (constVal ).append ("\n " );
528+  }
529+  }
530+ 
531+  // generate the null value 
518532
533+  if  (encoding .primitiveType () == PrimitiveType .CHAR )
534+  {
535+  sb .append (" NULL_VALUE = '\\ 0'" );
536+  }
537+  else 
538+  {
539+  sb .append (String .format (
540+  " NULL_VALUE = %1$s" ,
541+  generateLiteral (encoding .primitiveType (), encoding .applicableNullValue ().toString ())
542+  ));
543+  }
544+  sb .append ("\n \n " );
545+ 
546+  sb .append (" VALID_VALUES = {\n " );
519547 for  (final  Token  token  : tokens )
520548 {
521-  final  CharSequence  constVal  = generateLiteral (
522-  token .encoding ().primitiveType (), token .encoding ().constValue ().toString ());
523-  sb .append (" " ).append (token .name ()).append (" = " ).append (constVal ).append ("\n " );
549+  sb .append (" " ).append (token .name ()).append (",\n " );
524550 }
551+  sb .append (" NULL_VALUE,\n  }\n \n " );
525552
526-  sb .append (String .format (
527-  " NULL_VALUE = %1$s" ,
528-  generateLiteral (encoding .primitiveType (), encoding .applicableNullValue ().toString ())
529-  ));
553+  sb .append (" AS_TEXT = {\n " );
530554
531-  sb .append ("\n \n " );
555+  for  (final  Token  token  : tokens )
556+  {
557+  sb .append (" " ).append (token .name ()).append (" : '" ).append (token .name ()).append ("',\n " );
558+  }
559+  sb .append (" NULL_VALUE : 'NULL_VALUE',\n  }\n \n " );
532560
533561 return  sb ;
534562 }
535563
536-  private  CharSequence  generateEnumLookupMethod (final  List < Token >  tokens ,  final   Token   encodingToken )
564+  private  CharSequence  generateEnumMethods (final  String   name )
537565 {
538-  final  String  enumName  = formatClassName (encodingToken .name ());
539566 final  StringBuilder  sb  = new  StringBuilder ();
540567
541-  sb .append (
542-  " @staticmethod\n "  +
543-  " def get(value):\n "  +
544-  " values = {\n " );
545- 
546-  for  (final  Token  token  : tokens )
547-  {
548-  sb .append (String .format (
549-  " %1$s : %3$s.Value.%2$s,\n " ,
550-  token .encoding ().constValue ().toString (),
551-  token .name (),
552-  enumName )
553-  );
554-  }
555- 
556-  sb .append (String .format (
557-  " %1$s : %2$s.Value.NULL_VALUE\n "  +
558-  " }\n "  +
559-  " if type(value) is int:\n "  +
560-  " return values[value]\n "  +
561-  " else:\n "  +
562-  " return values[ord(value)]\n " ,
563-  encodingToken .encoding ().applicableNullValue ().toString (),
564-  enumName 
565-  ));
568+  sb .append (" def __init__(self, value):\n " );
569+  sb .append (" self.value = value\n " );
570+  sb .append (" if self.value not in " ).append (name ).append (".VALID_VALUES:\n " );
571+  sb .append (" raise ValueError('Invalid value for " ).append (name ).append (": {}'.format(value))\n " );
572+  sb .append ("\n " );
573+  sb .append (" def __str__(self):\n " );
574+  sb .append (" return " ).append (name ).append (".AS_TEXT[self.value]\n " );
566575
567576 return  sb ;
568577 }
@@ -624,11 +633,6 @@ private CharSequence generateClassDeclaration(final String name)
624633 return  "class "  + name  + ":\n " ;
625634 }
626635
627-  private  CharSequence  generateEnumDeclaration (final  String  name )
628-  {
629-  return  "class "  + name  + ":\n " ;
630-  }
631- 
632636 private  CharSequence  generatePrimitivePropertyEncodings (
633637 final  String  containingClassName , final  List <Token > tokens , final  String  indent )
634638 {
@@ -784,12 +788,12 @@ private CharSequence generateArrayProperty(
784788 ));
785789
786790 sb .append (String .format (
787-  indent  + " def set%1 $s(self, index, value):\n "  +
791+  indent  + " def set%2 $s(self, index, value):\n "  +
788792 indent  + " if index < 0 or index >= %3$d:\n "  +
789-  indent  + " raise Exception('index out of range for %1 $s')\n "  +
790-  indent  + " struct.pack_into('%2 $s', self.buffer_, self.offset_ + %4$d + (index * %5$d), value)\n " ,
791-  propertyName ,
792-  toUpperFirstChar (pythonTypeName ),
793+  indent  + " raise Exception('index out of range for %2 $s')\n "  +
794+  indent  + " struct.pack_into('%1 $s', self.buffer_, self.offset_ + %4$d + (index * %5$d), value)\n " ,
795+  pythonTypeName ,
796+  toUpperFirstChar (propertyName ),
793797 token .arrayLength (),
794798 offset ,
795799 token .encoding ().primitiveType ().size (),
@@ -928,15 +932,15 @@ private CharSequence generateMessageFlyweightCode(final Token token)
928932 " return self\n \n "  +
929933
930934 " def getPosition(self):\n "  +
931-  " return self.position_\n \n "  +
935+  " return self.position_[0] \n \n "  +
932936
933937 " def setPosition(self, position):\n "  +
934938 " if position > self.bufferLength_:\n "  +
935939 " raise Exception('buffer too short')\n "  +
936940 " self.position_[0] = position\n \n "  +
937941
938942 " def encodedLength(self):\n "  +
939-  " return self.position () - self.offset_\n \n "  +
943+  " return self.getPosition () - self.offset_\n \n "  +
940944
941945 " def buffer(self):\n "  +
942946 " return self.buffer_\n \n "  +
@@ -1054,7 +1058,7 @@ private CharSequence generateEnumProperty(
10541058 sb .append (String .format (
10551059 "\n "  +
10561060 indent  + " def get%2$s(self):\n "  +
1057-  indent  + " return %1$s.%1$s.get (struct.unpack_from( '%5$s', self.buffer_, self.offset_ + %6$d)[0])\n \n " ,
1061+  indent  + " return %1$s.%1$s(struct.unpack_from( '%5$s', self.buffer_, self.offset_ + %6$d)[0])\n \n " ,
10581062 enumName ,
10591063 toUpperFirstChar (propertyName ),
10601064 generateEnumFieldNotPresentCondition (token .version (), enumName , indent ),
0 commit comments