Beispiel #1
0
 def get_new_array_length(self, w_value):
     space = self.space
     if (space.isinstance_w(w_value, space.w_list) or
         space.isinstance_w(w_value, space.w_tuple)):
         return (w_value, space.int_w(space.len(w_value)))
     elif space.isinstance_w(w_value, space.w_bytes):
         # from a string, we add the null terminator
         s = space.bytes_w(w_value)
         return (w_value, len(s) + 1)
     elif space.isinstance_w(w_value, space.w_unicode):
         from pypy.module._cffi_backend import wchar_helper
         u = space.unicode_w(w_value)
         if self.ctitem.size == 2:
             length = wchar_helper.unicode_size_as_char16(u)
         else:
             length = wchar_helper.unicode_size_as_char32(u)
         return (w_value, length + 1)
     else:
         try:
             explicitlength = space.getindex_w(w_value,
                                               space.w_OverflowError)
         except OperationError as e:
             if e.match(space, space.w_TypeError):
                 raise oefmt(space.w_TypeError,
                     "expected new array length or list/tuple/str, "
                     "not %T", w_value)
             raise
         if explicitlength < 0:
             raise oefmt(space.w_ValueError, "negative array length")
         return (space.w_None, explicitlength)
Beispiel #2
0
 def _prepare_pointer_call_argument(self, w_init, cdata, keepalives, i):
     space = self.space
     if self.accept_str and space.isinstance_w(w_init, space.w_bytes):
         # special case to optimize strings passed to a "char *" argument
         value = space.bytes_w(w_init)
         if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool):
             self._must_be_string_of_zero_or_one(value)
         keepalives[i] = value
         buf, buf_flag = rffi.get_nonmovingbuffer_final_null(value)
         rffi.cast(rffi.CCHARPP, cdata)[0] = buf
         return ord(buf_flag)  # 4, 5 or 6
     #
     if (space.isinstance_w(w_init, space.w_list)
             or space.isinstance_w(w_init, space.w_tuple)):
         length = space.int_w(space.len(w_init))
     elif space.isinstance_w(w_init, space.w_bytes):
         # from a string, we add the null terminator
         s = space.bytes_w(w_init)
         length = len(s) + 1
     elif space.isinstance_w(w_init, space.w_unicode):
         from pypy.module._cffi_backend import wchar_helper
         u = space.unicode_w(w_init)
         if self.ctitem.size == 2:
             length = wchar_helper.unicode_size_as_char16(u)
         else:
             length = wchar_helper.unicode_size_as_char32(u)
         length += 1
     elif self.is_file:
         result = self.prepare_file(w_init)
         if result:
             rffi.cast(rffi.CCHARPP, cdata)[0] = result
             return 2
         return 0
     else:
         return 0
     itemsize = self.ctitem.size
     if itemsize <= 0:
         if isinstance(self.ctitem, ctypevoid.W_CTypeVoid):
             itemsize = 1
         else:
             return 0
     try:
         datasize = ovfcheck(length * itemsize)
     except OverflowError:
         raise oefmt(space.w_OverflowError,
                     "array size would overflow a ssize_t")
     result = lltype.malloc(rffi.CCHARP.TO,
                            datasize,
                            flavor='raw',
                            zero=True)
     try:
         self.convert_array_from_object(result, w_init)
     except Exception:
         lltype.free(result, flavor='raw')
         raise
     rffi.cast(rffi.CCHARPP, cdata)[0] = result
     return 1
Beispiel #3
0
 def convert_array_from_object(self, cdata, w_ob):
     space = self.space
     if (space.isinstance_w(w_ob, space.w_list)
             or space.isinstance_w(w_ob, space.w_tuple)):
         if self.ctitem.pack_list_of_items(cdata, w_ob):  # fast path
             pass
         else:
             self._convert_array_from_listview(cdata, space.listview(w_ob))
     elif self.accept_str:
         if not space.isinstance_w(w_ob, space.w_bytes):
             raise self._convert_error("str or list or tuple", w_ob)
         s = space.bytes_w(w_ob)
         n = len(s)
         if self.length >= 0 and n > self.length:
             raise oefmt(
                 space.w_IndexError,
                 "initializer string is too long for '%s' (got %d "
                 "characters)", self.name, n)
         if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool):
             self._must_be_string_of_zero_or_one(s)
         copy_string_to_raw(llstr(s), cdata, 0, n)
         if n != self.length:
             cdata[n] = '\x00'
     elif isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveUniChar):
         from pypy.module._cffi_backend import wchar_helper
         if not space.isinstance_w(w_ob, space.w_unicode):
             raise self._convert_error("unicode or list or tuple", w_ob)
         s = space.unicode_w(w_ob)
         if self.ctitem.size == 2:
             n = wchar_helper.unicode_size_as_char16(s)
         else:
             n = wchar_helper.unicode_size_as_char32(s)
         if self.length >= 0 and n > self.length:
             raise oefmt(
                 space.w_IndexError,
                 "initializer unicode string is too long for '%s' "
                 "(got %d characters)", self.name, n)
         add_final_zero = (n != self.length)
         if self.ctitem.size == 2:
             try:
                 wchar_helper.unicode_to_char16(s, cdata, n, add_final_zero)
             except wchar_helper.OutOfRange as e:
                 raise oefmt(
                     self.space.w_ValueError,
                     "unicode character ouf of range for "
                     "conversion to char16_t: %s", hex(e.ordinal))
         else:
             wchar_helper.unicode_to_char32(s, cdata, n, add_final_zero)
     else:
         raise self._convert_error("list or tuple", w_ob)