@@ -539,41 +539,81 @@ convertsimple1(arg, p_format, p_va)
539539
540540 case 's' : /* string */
541541 {
542- char * * p = va_arg (* p_va , char * * );
543- if (PyString_Check (arg ))
544- * p = PyString_AsString (arg );
545- else
546- return "string" ;
547- if (* format == '#' ) {
542+ if (* format == '#' ) { /* any buffer-like object */
543+ void * * p = (void * * )va_arg (* p_va , char * * );
544+ PyBufferProcs * pb = arg -> ob_type -> tp_as_buffer ;
548545 int * q = va_arg (* p_va , int * );
549- * q = PyString_Size (arg );
546+ int count ;
547+
548+ if ( pb == NULL ||
549+ pb -> bf_getreadbuffer == NULL ||
550+ pb -> bf_getsegcount == NULL )
551+ return "read-only buffer" ;
552+ if ( (* pb -> bf_getsegcount )(arg , NULL ) != 1 )
553+ return "single-segment read-only buffer" ;
554+ if ( (count =
555+ (* pb -> bf_getreadbuffer )(arg , 0 , p )) < 0 )
556+ return "(unspecified)" ;
557+ * q = count ;
550558 format ++ ;
559+ } else {
560+ char * * p = va_arg (* p_va , char * * );
561+
562+ if (PyString_Check (arg ))
563+ * p = PyString_AsString (arg );
564+ else
565+ return "string" ;
566+ if ((int )strlen (* p ) != PyString_Size (arg ))
567+ return "string without null bytes" ;
551568 }
552- else if ((int )strlen (* p ) != PyString_Size (arg ))
553- return "string without null bytes" ;
554569 break ;
555570 }
556-
571+
557572 case 'z' : /* string, may be NULL (None) */
558573 {
559- char * * p = va_arg (* p_va , char * * );
560- if (arg == Py_None )
561- * p = 0 ;
562- else if (PyString_Check (arg ))
563- * p = PyString_AsString (arg );
564- else
565- return "None or string" ;
566- if (* format == '#' ) {
574+ if (* format == '#' ) { /* any buffer-like object */
575+ void * * p = (void * * )va_arg (* p_va , char * * );
576+ PyBufferProcs * pb = arg -> ob_type -> tp_as_buffer ;
567577 int * q = va_arg (* p_va , int * );
568- if (arg == Py_None )
569- * q = 0 ;
570- else
571- * q = PyString_Size (arg );
578+ int count ;
579+
580+ if (arg == Py_None ) {
581+ * p = 0 ;
582+ * q = 0 ;
583+ } else {
584+ if ( pb == NULL ||
585+ pb -> bf_getreadbuffer == NULL ||
586+ pb -> bf_getsegcount == NULL )
587+ return "read-only buffer" ;
588+ if ( (* pb -> bf_getsegcount )(arg , NULL ) != 1 )
589+ return "single-segment read-only buffer" ;
590+ if ( (count = (* pb -> bf_getreadbuffer )
591+ (arg , 0 , p )) < 0 )
592+ return "(unspecified)" ;
593+ * q = count ;
594+ }
572595 format ++ ;
596+ } else {
597+ char * * p = va_arg (* p_va , char * * );
598+
599+ if (arg == Py_None )
600+ * p = 0 ;
601+ else if (PyString_Check (arg ))
602+ * p = PyString_AsString (arg );
603+ else
604+ return "None or string" ;
605+ if (* format == '#' ) {
606+ int * q = va_arg (* p_va , int * );
607+ if (arg == Py_None )
608+ * q = 0 ;
609+ else
610+ * q = PyString_Size (arg );
611+ format ++ ;
612+ }
613+ else if (* p != NULL &&
614+ (int )strlen (* p ) != PyString_Size (arg ))
615+ return "None or string without null bytes" ;
573616 }
574- else if (* p != NULL &&
575- (int )strlen (* p ) != PyString_Size (arg ))
576- return "None or string without null bytes" ;
577617 break ;
578618 }
579619
@@ -624,6 +664,30 @@ convertsimple1(arg, p_format, p_va)
624664 }
625665 break ;
626666 }
667+
668+
669+ case 'w' : /* memory buffer, read-write access */
670+ {
671+ void * * p = va_arg (* p_va , void * * );
672+ PyBufferProcs * pb = arg -> ob_type -> tp_as_buffer ;
673+ int count ;
674+
675+ if ( pb == NULL || pb -> bf_getwritebuffer == NULL ||
676+ pb -> bf_getsegcount == NULL )
677+ return "read-write buffer" ;
678+ if ( (* pb -> bf_getsegcount )(arg , NULL ) != 1 )
679+ return "single-segment read-write buffer" ;
680+ if ( (count = pb -> bf_getwritebuffer (arg , 0 , p )) < 0 )
681+ return "(unspecified)" ;
682+ if (* format == '#' ) {
683+ int * q = va_arg (* p_va , int * );
684+
685+ * q = count ;
686+ format ++ ;
687+ }
688+ break ;
689+ }
690+
627691
628692 default :
629693 return "impossible<bad format char>" ;
0 commit comments