<commit_before># Copyright 2012 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

import ctypes
from ctypes import POINTER

from pgi.codegen.backend import CodeGenBackend
from pgi.codegen.utils import CodeBlock
from pgi.gir import GIRepositoryPtr, GITypeTag, GIInfoType
from pgi.glib import gboolean, gfloat, gdouble
from pgi.glib import GErrorPtr, gchar_p, guint32, gint32, gpointer
from pgi.gobject import G_TYPE_FROM_INSTANCE, GTypeInstancePtr, GType
from pgi.gtype import PGType
from pgi.util import import_attribute


def typeinfo_to_ctypes(info):

    tag = info.tag.value
    ptr = info.is_pointer

    if ptr:
        if tag == GITypeTag.UTF8:
            return gchar_p
        elif tag == GITypeTag.VOID:
            return gpointer
        elif tag == GITypeTag.UTF8 or tag == GITypeTag.FILENAME:
            return gchar_p
        elif tag == GITypeTag.ARRAY:
            return gpointer
        elif tag == GITypeTag.INTERFACE:
            return gpointer
        elif tag == GITypeTag.INT32:
            return POINTER(gint32)
        elif tag == GITypeTag.UINT32:
            return POINTER(gint32)
        elif tag == GITypeTag.FLOAT:
            return POINTER(gfloat)
        elif tag == GITypeTag.VOID:
            return gpointer
    else:
        if tag == GITypeTag.BOOLEAN:
            return gboolean
        elif tag == GITypeTag.INTERFACE:
            iface = info.get_interface()
            iface_type = iface.type.value
            iface.unref()
            if iface_type == GIInfoType.ENUM:
                return guint32
        elif tag == GITypeTag.UINT32:
            return guint32
        elif tag == GITypeTag.INT32:
            return gint32
        elif tag == GITypeTag.FLOAT:
            return gfloat
        elif tag == GITypeTag.DOUBLE:
            return gdouble
        elif tag == GITypeTag.VOID:
            return
        elif tag == GITypeTag.GTYPE:
            return GType


class BasicTypes(object):

    def pack_string(self, name):
        # https://bugs.pypy.org/issue466
        block, var = self.parse("""
# https://bugs.pypy.org/issue466
if not isinstance($var, basestring):
    raise TypeError("$var must be a string")
""", var=name)

        return block, name

    def pack_string_null(self, name):
        # https://bugs.pypy.org/issue466
        block, var = self.parse("""
# https://bugs.pypy.org/issue466
if $var is not None and not isinstance($var, basestring):
    raise TypeError("$var must be a string or None")
""", var=name)

        return block, name

    def unpack_string(self, name):
        return CodeBlock(), name

    def pack_bool(self, name):
        block, var = self.parse("""
$boolean = bool($var) # https://bugs.pypy.org/issue1367
""", var=name)

        return block, var["boolean"]

    def unpack_bool(self, name):
        return None, name

    def unpack_basic_ptr(self, name):
        block, var = self.parse("""
# unpack basic pointer
$value = $ctypes_value.value
""", ctypes_value=name)

        block.add_dependency("ctypes", ctypes)
        return block, var["value"]

    def pack_uint32(self, name):
        block, var = self.parse("""
if not isinstance($uint, (float, int, long)):
    raise TypeError("Value '$uint' not a number")
$uint = int($uint)
# overflow check for uint32
if not 0 <= $uint < 4294967296:
    raise ValueError("Value '$uint' not in range")
""", uint=name)

        return block, var["uint"]

    def pack_uint32_ptr(self):
        block, var = self.parse("""
# pack uint32<commit_msg>pypy: fix bool return type<commit_after># Copyright 2012 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

import ctypes
from ctypes import POINTER

from pgi.codegen.backend import CodeGenBackend
from pgi.codegen.utils import CodeBlock
from pgi.gir import GIRepositoryPtr, GITypeTag, GIInfoType
from pgi.glib import gboolean, gfloat, gdouble
from pgi.glib import GErrorPtr, gchar_p, guint32, gint32, gpointer
from pgi.gobject import G_TYPE_FROM_INSTANCE, GTypeInstancePtr, GType
from pgi.gtype import PGType
from pgi.util import import_attribute


def typeinfo_to_ctypes(info):

    tag = info.tag.value
    ptr = info.is_pointer

    if ptr:
        if tag == GITypeTag.UTF8:
            return gchar_p
        elif tag == GITypeTag.VOID:
            return gpointer
        elif tag == GITypeTag.UTF8 or tag == GITypeTag.FILENAME:
            return gchar_p
        elif tag == GITypeTag.ARRAY:
            return gpointer
        elif tag == GITypeTag.INTERFACE:
            return gpointer
        elif tag == GITypeTag.INT32:
            return POINTER(gint32)
        elif tag == GITypeTag.UINT32:
            return POINTER(gint32)
        elif tag == GITypeTag.FLOAT:
            return POINTER(gfloat)
        elif tag == GITypeTag.VOID:
            return gpointer
    else:
        if tag == GITypeTag.BOOLEAN:
            return gboolean
        elif tag == GITypeTag.INTERFACE:
            iface = info.get_interface()
            iface_type = iface.type.value
            iface.unref()
            if iface_type == GIInfoType.ENUM:
                return guint32
        elif tag == GITypeTag.UINT32:
            return guint32
        elif tag == GITypeTag.INT32:
            return gint32
        elif tag == GITypeTag.FLOAT:
            return gfloat
        elif tag == GITypeTag.DOUBLE:
            return gdouble
        elif tag == GITypeTag.VOID:
            return
        elif tag == GITypeTag.GTYPE:
            return GType


class BasicTypes(object):

    def pack_string(self, name):
        # https://bugs.pypy.org/issue466
        block, var = self.parse("""
# https://bugs.pypy.org/issue466
if not isinstance($var, basestring):
    raise TypeError("$var must be a string")
""", var=name)

        return block, name

    def pack_string_null(self, name):
        # https://bugs.pypy.org/issue466
        block, var = self.parse("""
# https://bugs.pypy.org/issue466
if $var is not None and not isinstance($var, basestring):
    raise TypeError("$var must be a string or None")
""", var=name)

        return block, name

    def unpack_string(self, name):
        return CodeBlock(), name

    def pack_bool(self, name):
        block, var = self.parse("""
$boolean = bool($var) # https://bugs.pypy.org/issue1367
""", var=name)

        return block, var["boolean"]

    def unpack_bool(self, name):
        block, var = self.parse("""
# pypy returns int instead of bool
$value = bool($value)
""", value=name)

        return block, name

    def unpack_basic_ptr(self, name):
        block, var = self.parse("""
# unpack basic pointer
$value = $ctypes_value.value
""", ctypes_value=name)

        block.add_dependency("ctypes", ctypes)
        return block, var["value"]

    def pack_uint32(self, name):
        block, var = self.parse("""
if not isinstance($uint, (float, int, long)):
    raise TypeError("Value '$uint' not a number")
$uint = int($uint)
# overflow check for uint32
if not 0 <= $uint < 4294967296:
    raise ValueError("Value '$uint' not in range")
""", uint=name)

        return block, var["uint"]

    def pack_uint32_ptr(self):
        block, var = self.parse("""
# pack uint32
{'fraction_non_alphanumeric': 0.10146650812524773, 'fraction_numerical': 0.01717532038578412, 'mean_word_length': 2.496535796766744, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4912682', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2337, 'n_words': 693}