// Copyright © 2009 Jiří Zárevúcky // // Vala binding for GNU libidn library. // This file doesn't bind unicode and charset processing functions, as those are already present in GLib. // namespace libidn { [CCode (cname="STRINGPREP_VERSION")] public const string LIBIDN_VERSION; [CCode (cheader_filename="stringprep.h", cprefix="stringprep_rfc3454_")] // Stringprep character tables defined in RFC3454 namespace RFC3454 { public const Stringprep.TableElement[] A_1; public const Stringprep.TableElement[] B_1; public const Stringprep.TableElement[] B_2; public const Stringprep.TableElement[] B_3; public const Stringprep.TableElement[] C_1_1; public const Stringprep.TableElement[] C_1_2; public const Stringprep.TableElement[] C_2_1; public const Stringprep.TableElement[] C_2_2; public const Stringprep.TableElement[] C_3; public const Stringprep.TableElement[] C_4; public const Stringprep.TableElement[] C_5; public const Stringprep.TableElement[] C_6; public const Stringprep.TableElement[] C_7; public const Stringprep.TableElement[] C_8; public const Stringprep.TableElement[] C_9; public const Stringprep.TableElement[] D_1; public const Stringprep.TableElement[] D_2; } [CCode (cheader_filename="stringprep.h", cprefix="Stringprep_", lower_case_cprefix="stringprep_")] namespace Stringprep { /* constants */ public const int MAX_MAP_CHARS; /* enums */ [CCode (cname="Stringprep_rc", cprefix="STRINGPREP_")] public enum ReturnCode { OK, CONTAINS_UNASSIGNED, CONTAINS_PROHIBITED, BIDI_BOTH_L_AND_RAL, BIDI_LEADTRAIL_NOT_RAL, BIDI_CONTAINS_PROHIBITED, TOO_SMALL_BUFFER, PROFILE_ERROR, FLAG_ERROR, UNKNOWN_PROFILE, NFKC_FAILED, MALLOC_ERROR } [Flags] [CCode (cname="Stringprep_profile_flags", cprefix="STRINGPREP_")] public enum ProfileFlags { NO_NFKC, NO_BIDI, NO_UNASSIGNED } [CCode (cname="Stringprep_profile_steps", cprefix="STRINGPREP_")] public enum ProfileSteps { NFKC, BIDI, MAP_TABLE, UNASSIGNED_TABLE, PROHIBIT_TABLE, BIDI_PROHIBIT_TABLE, BIDI_RAL_TABLE, BIDI_L_TABLE } /* structs */ [Compact] [CCode (cname="Stringprep_table_element", set_type_id=false)] public struct TableElement { // start of the range, or a single charater to replace unichar start; // end of the range, or 0 if only one character unichar end; // characters to replace with, or null if element is a range // this shouldn't have more than MAP_MAX_CHARS members (== 4) unichar[] map; } [Compact] [CCode (cname="Stringprep_profile", set_type_id=false)] public struct ProfileTable { ProfileSteps operation; ProfileFlags flags; TableElement[] table; } [Compact] [CCode (cname="Stringprep_profiles", set_type_id=false)] public struct NamedProfile { string name; ProfileTable[] tables; } /* predefined profiles */ [CCode (cname="stringprep_profiles", array_null_terminated=true, array_length=false)] // Contains all built-in profiles with appropriate names public NamedProfile[] ProfileList; [CCode (cname="stringprep_nameprep", array_null_terminated=true, array_length=false)] public ProfileTable[] nameprep_profile; [CCode (cname="stringprep_saslprep", array_null_terminated=true, array_length=false)] public ProfileTable[] saslprep_profile; [CCode (cname="stringprep_plain", array_null_terminated=true, array_length=false)] public ProfileTable[] plain_profile; [CCode (cname="stringprep_trace", array_null_terminated=true, array_length=false)] public ProfileTable[] trace_profile; [CCode (cname="stringprep_kerberos5", array_null_terminated=true, array_length=false)] public ProfileTable[] kerberos5_profile; [CCode (cname="stringprep_xmpp_nodeprep_prohibit", array_null_terminated=true, array_length=false)] // Characters prohibited in the nodeprep profile public TableElement[] xmpp_nodeprep_prohibited; [CCode (cname="stringprep_xmpp_nodeprep", array_null_terminated=true, array_length=false)] public ProfileTable[] xmpp_nodeprep_profile; [CCode (cname="stringprep_xmpp_resourceprep", array_null_terminated=true, array_length=false)] public ProfileTable[] xmpp_resourceprep_profile; [CCode (cname="stringprep_iscsi", array_null_terminated=true, array_length=false)] public ProfileTable[] iscsi_profile; /* bound C functions - some of them not really usable in Vala */ // @param requested version of libidn your program requires, or null // @return if the request is satisfied, lib's version; null otherwise public unowned string check_version (string? requested); [CCode (cname="stringprep_4i")] private ReturnCode _stringprep_4i ([CCode (array_length = false, array_null_terminated = false)] unichar[] ucs4, ref size_t len, size_t max_len, ProfileFlags flags, [CCode (array_length = false)] ProfileTable[] profile); // [CCode (cname="stringprep_4zi")] // private ReturnCode _stringprep_4zi ([CCode (array_null_terminated = true)] unichar[] ucs4, size_t max_len // ProfileFlags flags, [CCode (array_length = false)] Profile[] profile); [CCode (cname="stringprep")] private ReturnCode _stringprep (uchar[] buffer, ProfileFlags flags, [CCode (array_length = false)] ProfileTable[] profile); [CCode (cname="stringprep_profile")] // @param profile has to be builtin profile; i.e. one of: "Nameprep", "Nodeprep", "Resourceprep", "plain", "trace", "SASLprep", "iSCSI" public ReturnCode stringprep_with_profile (string input, out string output, string profile, ProfileFlags flags = 0); [CCode (cname="stringprep_strerror")] public string return_code_to_string (ReturnCode code); /* interface methods */ // The same as stringprep (), except it takes and outputs UCS4 string (unichar array) public ReturnCode stringprep_ucs4 (unichar[] input, out unichar[] output, ProfileTable[] profile, ProfileFlags flags = 0) { ReturnCode code = 0; unichar[] buffer; var buffer_length = input.length; size_t len; do { buffer = input; buffer.resize (buffer_length += 32); code = _stringprep_4i (buffer, ref len, buffer_length, flags, profile); } while (code == ReturnCode.TOO_SMALL_BUFFER); if (code == ReturnCode.OK) { buffer.resize ((int) len); output = buffer; } return code; } // Prepare the input string according to the stringprep profile public ReturnCode stringprep (string input, out string output, ProfileTable[] profile, ProfileFlags flags = 0) { ReturnCode code = 0; string tmp; unowned uchar[] buffer; var buffer_length = input.size (); do { tmp = input; buffer = (uchar[]) tmp; buffer.length = (int) input.size () + 1; buffer.resize ((int) (buffer_length += 32)); code = _stringprep (buffer, flags, profile); } while (code == ReturnCode.TOO_SMALL_BUFFER); if (code == ReturnCode.OK) { output = tmp; } return code; } } [CCode (cheader_filename="punycode.h", cprefix="Punycode_")] namespace Punycode { [CCode (cname="Punycode_status", cprefix="PUNYCODE_")] public enum Status { SUCCESS, BAD_INPUT, BIG_OUTPUT, OVERFLOW } [CCode (cname="punycode_encode")] // output has to be preallocated private Status _encode ([CCode (array_length_pos = 0.9)] unichar[] input, [CCode (array_length = false)] uint8[]? case_flags, ref size_t output_length, [CCode (array_length = false)] uchar[] output); [CCode (cname="punycode_decode")] private Status _decode (size_t input_length, string input, ref size_t output_length, [CCode (array_length = false)] unichar[] output, [CCode (array_length = false)] uint8[]? case_flags); public Status encode (unichar[] input, uint8[]? case_flags, out string output) { Status status = 0; size_t output_length = input.length; uchar[] buffer; size_t real_length; do { real_length = (output_length += 32); buffer = new uchar [real_length]; status = _encode (input, case_flags, ref real_length, buffer); } while (status == Status.BIG_OUTPUT); if (status == Status.SUCCESS) { buffer.resize ((int) real_length + 1); buffer [real_length] = 0x00; output = (string) buffer; } return status; } // @param input has to be ASCII encoded string public Status decode (string input, out unichar[] output, out uint8[] case_flags) { var copy = input; // I have no idea why, but it sometimes crashes if this is not here var length = (size_t) input.size (); output = new unichar [length]; case_flags = new uint8 [length]; var status = _decode (length, input, ref length, output, case_flags); if (status == Status.SUCCESS) { output.resize ((int) length); case_flags.resize ((int) length); } else { output = null; case_flags = null; } return status; } } }