<commit_before>use Switch;

# This function takes the string of a value to be converted and its
# type, and generates the corresponding code to convert the type from
# c++ to Python. Note that the $type argument is a SPL::CodeGen type,
# and not a string literal
#
sub cppToPythonPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
#
# (or the equivalent for this function)

    my ($convert_from_string, $type) = @_;
    if(SPL::CodeGen::Type::isSigned($type)) {
	return "PyLong_FromLong($convert_from_string)";
    } elsif(SPL::CodeGen::Type::isUnsigned($type)) {
	return "PyLong_FromUnsignedLong($convert_from_string)";
    } elsif(SPL::CodeGen::Type::isFloatingpoint($type)) {
	return "PyFloat_FromDouble($convert_from_string)";
    } elsif (SPL::CodeGen::Type::isRString($type) || SPL::CodeGen::Type::isBString($type)) {
	return "PyUnicode_FromString(" . $convert_from_string . ".c_str())";
    } elsif (SPL::CodeGen::Type::isUString($type)) {
	return 'PyUnicode_DecodeUTF16((const char*)  (' . $convert_from_string . ".getBuffer()), " . $convert_from_string . ".length()*2, NULL, NULL)";
    } elsif(SPL::CodeGen::Type::isBoolean($type)) {
	return "$convert_from_string ? Py_True : Py_False; Py_INCREF(pyValue)";
    } elsif (SPL::CodeGen::Type::isComplex32($type) || SPL::CodeGen::Type::isComplex64($type)) {
	return "PyComplex_FromDoubles(". $convert_from_string . ".real(), ". $convert_from_string . ".imag())";
    }
    else{
	SPL::CodeGen::errorln("An unknown type was encountered when converting to python types."); 
    }
}

# This function is identical to the cppToPythonPrimitiveConversion,
# except the type of the object to be converted is passed as a string,
# instead of an SPL::CodeGen type. This is necessary because there are
# functions in the CodeGen API that return strings and not a CodeGen
# types, such as OutputPort::getAttributeAt().
#
sub stringBasedCppToPythonPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
#
# (or the equivalent for this function)

    my ($convert_from_string, $type) = @_;
    switch ($type) {
      case ['int8', 'int16', 'int32', 'int64'] { return "PyLong_FromLong($convert_from_string)";}
      case ['uint8', 'uint16', 'uint32', 'uint64'] { return "PyLong_FromUnsignedLong($convert_from_string)";}
      case ['float32', 'float64'] { return "PyFloat_FromDouble($convert_from_string)";}
      case 'rstring' { return "PyUnicode_FromString(" . $convert_from_string . ".c_str())";}
      case 'ustring' {return 'PyUnicode_DecodeUTF16((const char*)  (' . $convert_from_string . ".getBuffer()), " . $convert_from_string . ".length()*2, NULL, NULL)";}
      case 'boolean' { return "$convert_from_string ? Py_True : Py_False; Py_INCREF(pyValue)";}
      case ['complex32', 'complex64'] { return "PyComplex_FromDoubles(". $convert_from_string . ".real(), ". $convert_from_string . ".imag())";}
      else { SPL::CodeGen::errorln("An unknown type was encountered when converting to python types: $type"); }
    }
}

# This function does the reverse, converting a Python type back to a
# c++ type based on the $type argument which is a string literal.
#
sub pythonToCppPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
 
  my ($convert_from_string, $type) = @_;<commit_msg>Don't copy rstring data on coversion to Python<commit_after>use Switch;

# This function takes the string of a value to be converted and its
# type, and generates the corresponding code to convert the type from
# c++ to Python. Note that the $type argument is a SPL::CodeGen type,
# and not a string literal
#
sub cppToPythonPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
#
# (or the equivalent for this function)

    my ($convert_from_string, $type) = @_;
    if(SPL::CodeGen::Type::isSigned($type)) {
	return "PyLong_FromLong($convert_from_string)";
    } elsif(SPL::CodeGen::Type::isUnsigned($type)) {
	return "PyLong_FromUnsignedLong($convert_from_string)";
    } elsif(SPL::CodeGen::Type::isFloatingpoint($type)) {
	return "PyFloat_FromDouble($convert_from_string)";
    } elsif (SPL::CodeGen::Type::isRString($type) || SPL::CodeGen::Type::isBString($type)) {
	return rstring2python($convert_from_string);
    } elsif (SPL::CodeGen::Type::isUString($type)) {
	return ustring2python($convert_from_string);
    } elsif(SPL::CodeGen::Type::isBoolean($type)) {
	return "$convert_from_string ? Py_True : Py_False; Py_INCREF(pyValue)";
    } elsif (SPL::CodeGen::Type::isComplex32($type) || SPL::CodeGen::Type::isComplex64($type)) {
	return "PyComplex_FromDoubles(". $convert_from_string . ".real(), ". $convert_from_string . ".imag())";
    }
    else{
	SPL::CodeGen::errorln("An unknown type was encountered when converting to python types."); 
    }
}

sub rstring2python {
    my ($convert_from_string) = @_;
    return 'PyUnicode_DecodeUTF8((const char*)  (' . $convert_from_string . ".data()), " . $convert_from_string . ".size(), NULL)";
}
sub ustring2python {
    my ($convert_from_string) = @_;
    return 'PyUnicode_DecodeUTF16((const char*)  (' . $convert_from_string . ".getBuffer()), " . $convert_from_string . ".length()*2, NULL, NULL)";
}

# This function is identical to the cppToPythonPrimitiveConversion,
# except the type of the object to be converted is passed as a string,
# instead of an SPL::CodeGen type. This is necessary because there are
# functions in the CodeGen API that return strings and not a CodeGen
# types, such as OutputPort::getAttributeAt().
#
sub stringBasedCppToPythonPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
#
# (or the equivalent for this function)

    my ($convert_from_string, $type) = @_;
    switch ($type) {
      case ['int8', 'int16', 'int32', 'int64'] { return "PyLong_FromLong($convert_from_string)";}
      case ['uint8', 'uint16', 'uint32', 'uint64'] { return "PyLong_FromUnsignedLong($convert_from_string)";}
      case ['float32', 'float64'] { return "PyFloat_FromDouble($convert_from_string)";}
      case 'rstring' { return rstring2python($convert_from_string);}
      case 'ustring' { return ustring2python($convert_from_string);}
      case 'boolean' { return "$convert_from_string ? Py_True : Py_False; Py_INCREF(pyValue)";}
      case ['complex32', 'complex64'] { return "PyComplex_FromDoubles(". $convert_from_string . ".real(), ". $convert_from_string . ".imag())";}
      else { SPL::CodeGen::errorln("An unknown type was encountered when converting to python types: $type"); }
    }
}

# This function does the reverse, converting a Python type back to a
# c++ type based on the $type argument which is a string literal.
#
sub pythonToCppPrimitiveConversion{
# TODO: do error checking for the conversions. E.g., 
# char * str = PyUnicode_AsUTF8(pyAttrValue)
# if(str==NULL) exit(0);
 
  my ($convert_from_string, $type) = @_;
{'fraction_non_alphanumeric': 0.1459519511179003, 'fraction_numerical': 0.011109568115539509, 'mean_word_length': 5.21397756686799, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '1793545', 'n_tokens_mistral': 2370, 'n_tokens_neox': 2356, 'n_words': 614}