The Perl source is for a test program written to test the C/C++ functions in Perl before the Unicode library was utilized in live projects. It checks all of the functionality of the Unicode C/C++ library, although probably not as exhaustively as could be. For example, failure cases were not written, which should be part of any testing regime.
What the Perl file is really good for, is learning how a SWIG interfaced C/C++ library looks like at the coding level. Scalars are used as the package (class) object, and have the type of the SWIG project name, in this case, new objects have the ref() value of "Unicode::Unicode". Class methods are called using the "Unicode::"package prefix, and are not called directly as methods of the objects created. Note that three subclasses are created by the Unicode SWIG code based upon struct definitions in the C/C++ code. They are:
In the code you will see goto START, goto DONE statements, they were only used for debugging initially and can be disregarded. You will see that a $debug variable is available on line 77, which is set to false (0) by default. If you set it to true (1), you will get extra verbose output on the timing of certain core functions of the C/C++ library.
The best way to understand the SWIG interface, is just to go through the file and see how it works in each test. So, here is the source code, with the POD documentation intact:
#!/usr/bin/env perl
# vim: fileencoding=utf8
#===============================================================================
#
# FILE: testunicode.pl
#
# USAGE: ./testunicode.pl
#
# DESCRIPTION: Test SWIG "Unicode" Module for Perl 5.10+
#
# REQUIREMENTS: Unicode.pm and Unicode.so
# NOTES: Contains POD documentation for Unicode SWIG Perl interface
# VERSION: 1.6
# CREATED: 12/23/2017
# REVISION: 1.1 04/21/2018
# Added Unicode_from_array(), Unicode_to_array()
# Moved all ->can() routines into first test for easier maintenance
# REVISION: 1.2 07/01/2018
# Added Time::HiRes module and debug timing
# REVISION: 1.3 10/22/2018
# Added tests for operators eq,ne,lt,le,gt,ge,==,!=,<,<=,>,>=,+
# REVISION: 1.4 11/08/2018
# Changed utf8::decode to Encode::decode calls
# REVISION: 1.5 12/24/2018
# Added total execution time at end
# REVISION: 1.6 05/13/2021
# Added Config module to test for longlong and longdouble support
#
# This is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================
=head1 NAME
testunicode.pl - SWIG Unicode Test Program and Unicode.pm Interface Documentation
=cut
use strict;
use warnings;
use utf8;
use open qw(:std :utf8);
use locale;
use feature ':5.10';
use Test::More;
BEGIN {
use_ok("POSIX", qw(locale_h));
use_ok("Time::Piece");
use_ok("Time::Seconds");
use_ok("Time::HiRes", qw(gettimeofday));
use_ok("Encode", qw(encode decode));
}
setlocale(LC_ALL, 'en_US.utf8');
sub Test ($&) {
my ($test, $sub) = @_;
my ($ok, $diag) = &$sub();
ok($ok, $test) or diag($diag);
}
my $version = '1.6';
my $true = 1;
my $false = 0;
my $debug = 0;
my $starttime = 0;
my $endtime = 0;
require_ok('Unicode') or BAIL_OUT('Cannot require "Unicode" module');
goto START;
START:
my $begintime = gettimeofday();
Test('Check availablity of all needed Unicode methods', sub {
return $false, 'Unicode::Unicode::new() method does not exist' unless Unicode::Unicode->can('new');
return $false, 'Unicode::UnicodeArray::new() method does not exist' unless Unicode::UnicodeArray->can('new');
return $false, 'Unicode::UnicodeTesseract::new() method does not exist' unless Unicode::UnicodeTesseract->can('new');
return $false, 'clear() method does not exist' unless Unicode->can('clear');
return $false, 'empty() method does not exist' unless Unicode->can('empty');
return $false, 'codepoints() method does not exist' unless Unicode->can('codepoints');
return $false, 'bytes() method does not exist' unless Unicode->can('bytes');
return $false, 'import_string() method does not exist' unless Unicode->can('import_string');
return $false, 'export_string() method does not exist' unless Unicode->can('export_string');
return $false, 'from_string() method does not exist' unless Unicode->can('from_string');
return $false, 'from_int() method does not exist' unless Unicode->can('from_int');
return $false, 'from_long() method does not exist' unless Unicode->can('from_long');
return $false, 'from_longlong() method does not exist' unless Unicode->can('from_longlong');
return $false, 'from_float() method does not exist' unless Unicode->can('from_float');
return $false, 'from_double() method does not exist' unless Unicode->can('from_double');
return $false, 'from_longdouble() method does not exist' unless Unicode->can('from_longdouble');
return $false, 'to_int() method does not exist' unless Unicode->can('to_int');
return $false, 'to_long() method does not exist' unless Unicode->can('to_long');
return $false, 'to_longlong() method does not exist' unless Unicode->can('to_longlong');
return $false, 'to_float() method does not exist' unless Unicode->can('to_float');
return $false, 'to_double() method does not exist' unless Unicode->can('to_double');
return $false, 'to_longdouble() method does not exist' unless Unicode->can('to_longdouble');
return $false, 'copy() method does not exist' unless Unicode->can('copy');
return $false, 'append() method does not exist' unless Unicode->can('append');
return $false, 'append_multiple() method does not exist' unless Unicode->can('append_multiple');
return $false, 'swap() method does not exist' unless Unicode->can('swap');
return $false, 'find() method does not exist' unless Unicode->can('find');
return $false, 'extract() method does not exist' unless Unicode->can('extract');
return $false, 'replace() method does not exist' unless Unicode->can('replace');
return $false, 'compare_ascendingstring() method does not exist' unless Unicode->can('compare_ascendingstring');
return $false, 'compare_descendingstring() method does not exist' unless Unicode->can('compare_descendingstring');
return $false, 'compare_ascendingnumeric() method does not exist' unless Unicode->can('compare_ascendingnumeric');
return $false, 'compare_descendingnumeric() method does not exist' unless Unicode->can('compare_descendingnumeric');
return $false, 'uppercase() method does not exist' unless Unicode->can('uppercase');
return $false, 'lowercase() method does not exist' unless Unicode->can('lowercase');
return $false, 'swapcase() method does not exist' unless Unicode->can('swapcase');
return $false, 'concatenate() method does not exist' unless Unicode->can('concatenate');
return $false, 'split() method does not exist' unless Unicode->can('split');
return $false, 'join() method does not exist' unless Unicode->can('join');
return $false, 'from_array() method does not exist' unless Unicode->can('from_array');
return $false, 'to_array() method does not exist' unless Unicode->can('to_array');
return $false, 'Unicode::UnicodeArray::set_element() method does not exist' unless Unicode::UnicodeArray->can('set_element'); # see unicode.i
return $false, 'Unicode::UnicodeArray::get_element() method does not exist' unless Unicode::UnicodeArray->can('get_element'); # see unicode.i
return $false, 'from_subvalues() method does not exist' unless Unicode->can('from_subvalues');
return $false, 'to_subvalues() method does not exist' unless Unicode->can('to_subvalues');
return $false, 'count_subvalues() method does not exist' unless Unicode->can('count_subvalues');
return $false, 'sort_subvalues() method does not exist' unless Unicode->can('sort_subvalues');
return $false, 'locate_subvalue() method does not exist' unless Unicode->can('locate_subvalue');
return $false, 'extract_subvalue() method does not exist' unless Unicode->can('extract_subvalue');
return $false, 'replace_subvalue() method does not exist' unless Unicode->can('replace_subvalue');
return $false, 'insert_subvalue() method does not exist' unless Unicode->can('insert_subvalue');
return $false, 'append_subvalue() method does not exist' unless Unicode->can('append_subvalue');
return $false, 'delete_subvalue() method does not exist' unless Unicode->can('delete_subvalue');
return $false, 'get_codepoint() method does not exist' unless Unicode->can('get_codepoint');
return $false, 'set_codepoint() method does not exist' unless Unicode->can('set_codepoint');
return $false, 'find_codepoint() method does not exist' unless Unicode->can('find_codepoint');
return $false, 'isalnum_codepoint() method does not exist' unless Unicode->can('isalnum_codepoint');
return $false, 'isalpha_codepoint() method does not exist' unless Unicode->can('isalpha_codepoint');
return $false, 'islower_codepoint() method does not exist' unless Unicode->can('islower_codepoint');
return $false, 'isupper_codepoint() method does not exist' unless Unicode->can('isupper_codepoint');
return $false, 'isdigit_codepoint() method does not exist' unless Unicode->can('isdigit_codepoint');
return $false, 'isxdigit_codepoint() method does not exist' unless Unicode->can('isxdigit_codepoint');
return $false, 'iscntrl_codepoint() method does not exist' unless Unicode->can('iscntrl_codepoint');
return $false, 'isgraph_codepoint() method does not exist' unless Unicode->can('isgraph_codepoint');
return $false, 'isspace_codepoint() method does not exist' unless Unicode->can('isspace_codepoint');
return $false, 'isblank_codepoint() method does not exist' unless Unicode->can('isblank_codepoint');
return $false, 'isprint_codepoint() method does not exist' unless Unicode->can('isprint_codepoint');
return $false, 'ispunct_codepoint() method does not exist' unless Unicode->can('ispunct_codepoint');
return $false, 'tolower_codepoint() method does not exist' unless Unicode->can('tolower_codepoint');
return $false, 'toupper_codepoint() method does not exist' unless Unicode->can('toupper_codepoint');
return $false, 'save() method does not exist' unless Unicode->can('save');
return $false, 'load() method does not exist' unless Unicode->can('load');
return $false, 'to_tesseract() method does not exist' unless Unicode->can('to_tesseract');
return $false, 'from_tesseract() method does not exist' unless Unicode->can('from_tesseract');
return $false, 'set_element() method does not exist' unless Unicode->can('set_element');
return $false, 'get_element() method does not exist' unless Unicode->can('get_element');
return $true;
}
);
Test('Construct empty Unicode object', sub {
$starttime = gettimeofday() if $debug;
my $l_uniObject = new Unicode::Unicode();
$endtime = gettimeofday() if $debug;
printf "new Unicode::Unicode debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'undef returned instead of new Unicode::Unicode object' unless defined($l_uniObject);
return $false, 'unexpected "' . ref($l_uniObject) . '" for ref(object)' unless ref($l_uniObject) eq 'Unicode::Unicode';
return $true;
}
);
Test('Determine if Unicode object is empty after construction', sub {
my $l_uniObject = new Unicode::Unicode();
return $false, 'new Unicode object $l_uniObject->empty() failure' unless $l_uniObject->empty();
return $true;
}
);
Test('Initialize a Unicode object with a UTF string value', sub {
my $l_strValue = 'João Méroço';
my $l_uniImportstring = new Unicode::Unicode();
$starttime = gettimeofday() if $debug;
my $l_inInbytes = $l_uniImportstring->import_string($l_strValue, 0, 'UTF8');
$endtime = gettimeofday() if $debug;
printf "import_string debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, '$l_uniImportstring object is empty' if $l_uniImportstring->empty();
return $false, 'Expected 14 bytes in but got ' . $l_inInbytes unless $l_inInbytes == 14;
return $false, 'Expected 11 codepoints out but got ' . $l_uniImportstring->{m_sizCodepoints} unless $l_uniImportstring->{m_sizCodepoints} == 11;
return $false, 'Expected 44 bytes out but got ' . $l_uniImportstring->{m_sizBytes} unless $l_uniImportstring->{m_sizBytes} == 44;
$starttime = gettimeofday() if $debug;
my $l_uniFromstring = Unicode::from_string($l_strValue, 0, 'UTF8');
$endtime = gettimeofday() if $debug;
printf "Unicode::from_string debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, '$l_uniFromstring object is empty' if $l_uniImportstring->empty();
return $false, 'Expected $l_uniImportstring->{m_sizCodepoints} == $l_uniFromstring->{m_sizCodepoints}' unless $l_uniImportstring->{m_sizCodepoints} == $l_uniFromstring->{m_sizCodepoints};
return $false, 'Expected $l_uniImportstring->{m_sizBytes} == $l_uniFromstring->{m_sizBytes}' unless $l_uniImportstring->{m_sizBytes} == $l_uniFromstring->{m_sizBytes};
return $true;
}
);
Test('Get codepoint count of Unicode object content', sub {
my $l_strValue = 'João Méroço';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Expected $l_uniObject->codepoints() == $l_uniObject->{m_sizCodepoints}' unless $l_uniObject->codepoints() == $l_uniObject->{m_sizCodepoints};
return $true;
}
);
Test('Get byte count of Unicode object content', sub {
my $l_strValue = 'João Méroço';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
my $l_inBytes = $l_uniObject->bytes();
return $false, 'Expected $l_uniObject->bytes() == $l_uniObject->{m_sizBytes}' unless $l_uniObject->bytes() == $l_uniObject->{m_sizBytes};
return $true;
}
);
Test('Initialize Unicode object from an integer', sub {
my $l_inValue = 12345;
$starttime = gettimeofday() if $debug;
my $l_uniInt = Unicode::from_int($l_inValue); # %d
$endtime = gettimeofday() if $debug;
printf "Unicode::from_int debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_int() returned empty object' if $l_uniInt->empty();
my $l_inCodepoints = $l_uniInt->codepoints();
return $false, 'Expected 5 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 5;
my $l_inBytes = $l_uniInt->bytes();
return $false, 'Expected 20 bytes output but got ' . $l_inBytes unless $l_inBytes == 20;
return $true;
}
);
Test('Initialize Unicode object from a long integer', sub {
my $l_loValue = 1234567890;
$starttime = gettimeofday() if $debug;
my $l_uniLong = Unicode::from_long($l_loValue); # %ld
$endtime = gettimeofday() if $debug;
printf "Unicode::from_long debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_long() returned empty object' if $l_uniLong->empty();
my $l_inCodepoints = $l_uniLong->codepoints();
return $false, 'Expected 10 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 10;
my $l_inBytes = $l_uniLong->bytes();
return $false, 'Expected 40 bytes output but got ' . $l_inBytes unless $l_inBytes == 40;
return $true;
}
);
SKIP: {
Test('Initialize Unicode object from a long long integer', sub {
my $l_uniObject = Unicode::from_string('1234567890987654321', 0, 'UTF8');
skip "Perl does not support long long type", 1 if ref($l_uniObject->to_longlong()) ne '';
my $l_llValue = 1234567890987654321;
$starttime = gettimeofday() if $debug;
my $l_uniLonglong = Unicode::from_longlong($l_llValue); # %lld
$endtime = gettimeofday() if $debug;
printf "Unicode::from_longlong debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_longlong() returned empty object' if $l_uniLonglong->empty();
my $l_inCodepoints = $l_uniLonglong->codepoints();
return $false, 'Expected 19 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 19;
my $l_inBytes = $l_uniLonglong->bytes();
return $false, 'Expected 76 bytes output but got ' . $l_inBytes unless $l_inBytes == 76;
return $true;
}
);
}
Test('Initialize Unicode object from a float', sub {
my $l_flValue = 123.45;
$starttime = gettimeofday() if $debug;
my $l_uniFloat = Unicode::from_float($l_flValue); # %.7e
$endtime = gettimeofday() if $debug;
printf "Unicode::from_float debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_float() returned empty object' if $l_uniFloat->empty();
my $l_inCodepoints = $l_uniFloat->codepoints();
return $false, 'Expected 13 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 13;
my $l_inBytes = $l_uniFloat->bytes();
return $false, 'Expected 52 bytes output but got ' . $l_inBytes unless $l_inBytes == 52;
return $true;
}
);
Test('Initialize Unicode object from a double', sub {
my $l_doValue = 12345.6789;
$starttime = gettimeofday() if $debug;
my $l_uniDouble = Unicode::from_double($l_doValue); # %.15le
$endtime = gettimeofday() if $debug;
printf "Unicode::from_double debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_double() returned empty object' if $l_uniDouble->empty();
my $l_inCodepoints = $l_uniDouble->codepoints();
return $false, 'Expected 21 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 21;
my $l_inBytes = $l_uniDouble->bytes();
return $false, 'Expected 84 bytes output but got ' . $l_inBytes unless $l_inBytes == 84;
return $true;
}
);
SKIP: {
Test('Initialize Unicode object from a long double', sub {
my $l_uniObject = Unicode::from_string('1234567890.987654321', 0, 'UTF8');
skip "Perl does not support long double type", 1 if ref($l_uniObject->to_longdouble()) ne '';
my $l_ldValue = $l_uniObject->to_longdouble();
$starttime = gettimeofday() if $debug;
my $l_uniLongdouble = Unicode::from_longdouble($l_ldValue); # %.18Le
$endtime = gettimeofday() if $debug;
printf "Unicode::from_longdouble debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'from_longdouble() returned empty object' if $l_uniLongdouble->empty();
my $l_inCodepoints = $l_uniLongdouble->codepoints();
return $false, 'Expected 36 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 36;
my $l_inBytes = $l_uniLongdouble->bytes();
return $false, 'Expected 144 bytes output but got ' . $l_inBytes unless $l_inBytes == 144;
return $true;
}
);
}
Test('Convert Unicode object to a string', sub {
my $l_uniObject = new Unicode::Unicode();
my $l_strUtf8 = 'João Méroço';
return $false, 'expected utf8::is_utf8($l_strUtf8) == 1 but got undef' unless utf8::is_utf8($l_strUtf8);
my $l_inInbytes = $l_uniObject->import_string($l_strUtf8, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
return $false, 'Expected 14 bytes input but got ' . $l_inInbytes unless $l_inInbytes == 14;
my $l_inCodepoints = $l_uniObject->codepoints();
my $l_inBytes = $l_uniObject->bytes();
return $false, 'Expected 11 codepoints output but got ' . $l_inCodepoints unless $l_inCodepoints == 11;
return $false, 'Expected 44 bytes output but got ' . $l_inBytes unless $l_inBytes == 44;
$starttime = gettimeofday() if $debug;
my $l_strResult = $l_uniObject->export_string(0, 'UTF8');
$endtime = gettimeofday() if $debug;
printf "export_string debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected utf8::is_utf8($l_strResult) == undef but got 1' if utf8::is_utf8($l_strResult);
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected utf8::is_utf8($l_strResult) == 1 but got undef' unless utf8::is_utf8($l_strResult);
return $false, 'expected $l_strResult eq $l_strUtf8 but got ne' unless $l_strResult eq $l_strUtf8;
return $true;
}
);
Test('Convert Unicode object to an integer', sub {
my $l_strValue = '12345';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_inValue = $l_uniObject->to_int();
$endtime = gettimeofday() if $debug;
printf "to_int debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected $l_strValue == $l_inValue but got !=' unless $l_strValue == $l_inValue;
return $true;
}
);
Test('Convert Unicode object to a long integer', sub {
my $l_strValue = '1234567890';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_loValue = $l_uniObject->to_long();
$endtime = gettimeofday() if $debug;
printf "to_long debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected $l_strValue == $l_loValue but got !=' unless $l_strValue == $l_loValue;
return $true;
}
);
SKIP: {
Test('Convert Unicode object to a long long integer', sub {
my $l_strValue = '1234567890987654321';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
skip "Perl does not support long long type", 1 if ref($l_uniObject->to_longlong()) ne '';
$starttime = gettimeofday() if $debug;
my $l_llValue = $l_uniObject->to_longlong();
$endtime = gettimeofday() if $debug;
printf "to_longlong debug time = %.9lf\n", $endtime - $starttime if $debug;
skip 'Perl does not support long long type', 1 if ref($l_llValue) ne '';
return $false, 'expected $l_strValue == $l_llValue but got !=' unless $l_strValue == $l_llValue;
return $true;
}
);
}
Test('Convert Unicode object to a float', sub {
my $l_strValue = '1.2345000e+02';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_flValue = $l_uniObject->to_float();
$endtime = gettimeofday() if $debug;
printf "to_float debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected sprintf("%.2f", $l_strValue) eq sprintf("%.2f", $l_flValue) but got ' . sprintf('%.2f', $l_strValue) . ' ne ' . sprintf('%.2f', $l_flValue) unless sprintf('%.2f', $l_strValue) eq sprintf('%.2f', $l_flValue);
return $true;
}
);
Test('Convert Unicode object to a double', sub {
my $l_strValue = '1.234567890000000e+04';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_doValue = $l_uniObject->to_double();
$endtime = gettimeofday() if $debug;
printf "to_double debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected sprintf("%.4lf", $l_strValue) eq sprintf("%.4lf", $l_doValue) but got ' . sprintf('%.4lf', $l_strValue) . ' ne ' . sprintf('%.4lf', $l_doValue) unless sprintf('%.4lf', $l_strValue) eq sprintf('%.4lf', $l_doValue);
return $true;
}
);
SKIP: {
Test('Convert Unicode object to a long double', sub {
my $l_strValue = '1234567890.987654321';
my $l_uniObject = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object is empty' if $l_uniObject->empty();
skip "Perl does not support long double type", 1 if ref($l_uniObject->to_longdouble()) ne '';
$starttime = gettimeofday() if $debug;
my $l_ldValue = $l_uniObject->to_longdouble();
$endtime = gettimeofday() if $debug;
printf "to_longdouble debug time = %.9lf\n", $endtime - $starttime if $debug;
skip 'Perl does not support long double type', 1 if ref($l_ldValue) ne '';
return $false, 'expected sprintf("%.9Lf", $l_strValue) eq sprintf("%.9Lf", $l_ldValue) but got ' . sprintf('%.9Lf', $l_strValue) . ' ne ' . sprintf('%.9Lf', $l_ldValue) unless sprintf('%.9Lf', $l_strValue) eq sprintf('%.9Lf', $l_ldValue);
return $true;
}
);
}
Test('Copy another Unicode object codepoints to Unicode Object', sub {
my $l_strValue = 'João Méroço';
my $l_uniObject1 = Unicode::from_string($l_strValue, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_uniObject2 = new Unicode::Unicode();
$starttime = gettimeofday() if $debug;
$l_uniObject2->copy($l_uniObject1);
$endtime = gettimeofday() if $debug;
printf "copy debug time = %.9lf\n", $endtime - $starttime if $debug;
# compare Unicode object pointer addresses
return $false, 'expected int($l_uniObject1) != int($l_uniObject2) but got ==' unless int($l_uniObject1) != int($l_uniObject2);
# compare raw exported UTF-8 byte strings
return $false, 'expected $l_uniObject1->export_string() eq $l_uniObject2->export_string() but got ne' unless $l_uniObject1->export_string(0, 'UTF8') eq $l_uniObject2->export_string(0, 'UTF8');
# compare UTF-8 codepoints in Unicode object buffer
return $false, 'expected $l_uniObject1 eq $l_uniObject2 but got ne' unless $l_uniObject1 eq $l_uniObject2;
return $true;
}
);
Test('Append another Unicode object codepoints to Unicode Object', sub {
my $l_strValue1 = 'João';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = 'Méroço';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
$l_uniObject1->append($l_uniObject2);
$endtime = gettimeofday() if $debug;
printf "append debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strResult = $l_uniObject1->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected $l_strResult eq "$l_strValue1$l_strValue2" but got ne'
unless $l_strResult eq "$l_strValue1$l_strValue2";
return $true;
}
);
Test('Append multiple copies of a Unicode object codepoints to Unicode Object', sub {
my $l_inCount = 1000;
my $l_strValue1 = 'João Méroço';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = ' Woot!' x $l_inCount;
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
$l_uniObject1->append_multiple($l_uniObject2, $l_inCount);
$endtime = gettimeofday() if $debug;
printf "append_multiple debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strResult = $l_uniObject1->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected $l_strResult eq "' . $l_strValue1 . '" + "' . $l_strValue2 . '" x ' . $l_inCount . ' but got ne'
unless $l_strResult eq $l_strValue1 . $l_strValue2 x $l_inCount;
return $true;
}
);
Test('Swap another Unicode object codepoints with Unicode Object codepoints', sub {
my $l_strValue1 = 'João';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = ' Méroço';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
$l_uniObject1->swap($l_uniObject2);
$endtime = gettimeofday() if $debug;
printf "swap debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strResult1 = $l_uniObject1->export_string(0, 'UTF8');
$l_strResult1 = decode('UTF8', $l_strResult1);
my $l_strResult2 = $l_uniObject2->export_string(0, 'UTF8');
$l_strResult2 = decode('UTF8', $l_strResult2);
return $false, 'expected $l_strResult1 eq $l_strValue2 but got ne' unless $l_strResult1 eq $l_strValue2;
return $false, 'expected $l_strResult2 eq $l_strValue1 but got ne' unless $l_strResult2 eq $l_strValue1;
return $true;
}
);
Test('Find offset of codepoints of a Unicode object inside another Unicode object', sub {
my $l_strValue1 = 'João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = 'João Méroço';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
my $l_sizOffset = $l_uniObject1->find($l_uniObject2, 4);
$endtime = gettimeofday() if $debug;
printf "find debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected $l_sizOffset == 48 but got ' . $l_sizOffset unless $l_sizOffset == 48;
$l_sizOffset = $l_uniObject1->find($l_uniObject2, -19);
return $false, 'expected $l_sizOffset == 48 but got ' . $l_sizOffset unless $l_sizOffset == 48;
return $true;
}
);
Test('Return extracted codepoints inside Unicode object in new Unicode object', sub {
my $l_strValue1 = 'João Méroço';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = 'Méroço';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
my $l_uniObject3 = $l_uniObject1->extract(5, 6);
$endtime = gettimeofday() if $debug;
printf "extract debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'Unicode::Unicode object3 is empty' if $l_uniObject3->empty();
my $l_strResult2 = $l_uniObject2->export_string(0, 'UTF8');
$l_strResult2 = decode('UTF8', $l_strResult2);
my $l_strResult3 = $l_uniObject3->export_string(0, 'UTF8');
$l_strResult3 = decode('UTF8', $l_strResult3);
return $false, 'expected $l_strResult2 eq $l_strResult3 but got ne' unless $l_strResult2 eq $l_strResult3;
return $true;
}
);
Test('Replace existing Unicode object codepoints with other Unicode object codepoints', sub {
my $l_strValue1 = 'Jack Von Mercer';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = 'João';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
my $l_strValue3 = 'Méroço';
my $l_uniObject3 = Unicode::from_string($l_strValue3, 0, 'UTF8');
return $false, 'Unicode::Unicode object3 is empty' if $l_uniObject3->empty();
$starttime = gettimeofday() if $debug;
$l_uniObject1->replace($l_uniObject2, 0, 4); # "Jack Von Mercer" -> "João Von Mercer"
$endtime = gettimeofday() if $debug;
printf "replace debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniObject2->clear();
$l_uniObject1->replace($l_uniObject2, 5, 4); # -> "João Mercer"
$l_uniObject1->replace($l_uniObject3, 5, 6); # -> "João Méroço"
my $l_strResult = 'João Méroço';
my $l_strObject1 = $l_uniObject1->export_string(0, 'UTF8');
$l_strObject1 = decode('UTF8', $l_strObject1);
return $false, "expected \$l_strObject1 eq '$l_strResult' but got '$l_strObject1'" unless $l_strObject1 eq $l_strResult;
return $true;
}
);
Test('Compare Unicode object with another Unicode object as strings', sub {
my $l_uniObject = Unicode::from_string('Joao Meroco', 0, 'ASCII');
return $false, 'export_string() returned an empty Unicode::Unicode object' if $l_uniObject->empty();
my $l_uniCompare = Unicode::from_string('João Méroço', 0, 'UTF8');
return $false, 'export_string() returned an empty Unicode::Unicode object' if $l_uniCompare->empty();
$starttime = gettimeofday() if $debug;
my $l_inResult = $l_uniObject cmp $l_uniCompare;
$endtime = gettimeofday() if $debug;
printf "'cmp' debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII string to "cmp" compare less than UTF8 string' unless $l_inResult < 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject eq $l_uniCompare;
$endtime = gettimeofday() if $debug;
printf "'eq' debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII string to "eq" compare not equal to UTF8 string' unless $l_inResult == 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject->compare_ascendingstring($l_uniCompare);
$endtime = gettimeofday() if $debug;
printf "compare_ascendingstring debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII string to ascending compare less than UTF8 string' unless $l_inResult < 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject->compare_descendingstring($l_uniCompare);
$endtime = gettimeofday() if $debug;
printf "compare_descendingstring debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII string to descending compare more than UTF8 string' unless $l_inResult > 0;
return $true;
}
);
Test('Compare Unicode object with another Unicode object as numbers', sub {
my $l_uniObject = Unicode::from_string('1234567890.0', 0, 'ASCII');
return $false, 'from_string() returned an empty Unicode::Unicode object' if $l_uniObject->empty();
my $l_uniCompare = Unicode::from_string('1234567890.0', 0, 'UTF8');
return $false, 'from_string() returned an empty Unicode::Unicode object' if $l_uniCompare->empty();
$starttime = gettimeofday() if $debug;
my $l_inResult = $l_uniObject <=> $l_uniCompare;
$endtime = gettimeofday() if $debug;
printf "'<=>' debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII number to "<=>" compare equal to UTF8 number' unless $l_inResult == 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject == $l_uniCompare;
$endtime = gettimeofday() if $debug;
printf "'==' debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII number to be equal to UTF8 number' unless $l_inResult != 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject->compare_ascendingnumeric($l_uniCompare);
$endtime = gettimeofday() if $debug;
printf "compare_ascendingnumeric debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII number to be equal to UTF8 number' unless $l_inResult == 0;
$starttime = gettimeofday() if $debug;
$l_inResult = $l_uniObject->compare_descendingnumeric($l_uniCompare);
$endtime = gettimeofday() if $debug;
printf "compare_descendingnumeric debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected ASCII number to be equal to UTF8 number' unless $l_inResult == 0;
return $true;
}
);
Test('Return uppercased Unicode object content in new Unicode object', sub {
my $l_inCount = 1000;
my $l_strObject = 'João Méroço' x $l_inCount;
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
return $false, 'from_string() returned an empty Unicode::Unicode object' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_uniUpper = $l_uniObject->uppercase();
$endtime = gettimeofday() if $debug;
printf "uppercase debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strUpper = $l_uniUpper->export_string(0, 'UTF8');
$l_strUpper = decode('UTF8', $l_strUpper);
return $false, "expected uppercase('$l_strObject') eq 'JOÃO MÉROÇO' x $l_inCount but got '$l_strUpper'"
unless $l_strUpper eq 'JOÃO MÉROÇO' x $l_inCount;
return $true;
}
);
Test('Return lowercased Unicode object content in new Unicode object', sub {
my $l_strObject = 'João Méroço';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
return $false, 'from_string() returned an empty Unicode::Unicode object' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_uniLower = $l_uniObject->lowercase();
$endtime = gettimeofday() if $debug;
printf "lowercase debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strLower = $l_uniLower->export_string(0, 'UTF8');
$l_strLower = decode('UTF8', $l_strLower);
return $false, "expected lowercase('$l_strObject') eq 'joão méroço' but got '$l_strLower'" unless $l_strLower eq 'joão méroço';
return $true;
}
);
Test('Return swapcased Unicode object content in new Unicode object', sub {
my $l_strObject = 'João Méroço';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
return $false, 'from_string() returned an empty Unicode::Unicode object' if $l_uniObject->empty();
$starttime = gettimeofday() if $debug;
my $l_uniSwap = $l_uniObject->swapcase();
$endtime = gettimeofday() if $debug;
printf "swapcase debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strSwap = $l_uniSwap->export_string(0, 'UTF8');
$l_strSwap = decode('UTF8', $l_strSwap);
return $false, "expected swapcase('$l_strObject') eq 'jOÃO mÉROÇO' but got '$l_strSwap'" unless $l_strSwap eq 'jOÃO mÉROÇO';
return $true;
}
);
Test('Return concatenated Unicode objects in new Unicode Object', sub {
my $l_strValue1 = 'João';
my $l_uniObject1 = Unicode::from_string($l_strValue1, 0, 'UTF8');
return $false, 'Unicode::Unicode object1 is empty' if $l_uniObject1->empty();
my $l_strValue2 = 'Méroço';
my $l_uniObject2 = Unicode::from_string($l_strValue2, 0, 'UTF8');
return $false, 'Unicode::Unicode object2 is empty' if $l_uniObject2->empty();
$starttime = gettimeofday() if $debug;
my $l_uniResult = $l_uniObject1->concatenate($l_uniObject2);
$endtime = gettimeofday() if $debug;
printf "concatenate debug time = %.9lf\n", $endtime - $starttime if $debug;
$starttime = gettimeofday() if $debug;
$l_uniResult = $l_uniObject1 + $l_uniObject2;
$endtime = gettimeofday() if $debug;
printf "'+' debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_strResult = $l_uniResult->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected $l_strResult eq "$l_strValue1$l_strValue2" but got ne'
unless $l_strResult eq "$l_strValue1$l_strValue2";
return $true;
}
);
Test('Split Unicode object into UnicodeArray object', sub {
my $l_strDelimiter = '*';
my $l_uniDelimiter = Unicode::from_string($l_strDelimiter, 0, 'UTF8');
my $l_strObject = 'ft1*ft2**ft4';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$starttime = gettimeofday() if $debug;
my $l_unaObject = $l_uniObject->split($l_uniDelimiter, 0);
$endtime = gettimeofday() if $debug;
printf "split debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected 4 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 4;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 1);
return $false, 'expected 3 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 3;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 2);
return $false, 'expected 2 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 2;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 3);
return $false, 'expected 1 element but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 1;
$l_strObject = '*ft1*ft2**ft4*';
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 0);
return $false, 'expected 6 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 6;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 1);
return $false, 'expected 3 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 3;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 2);
return $false, 'expected 4 elements but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 4;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 3);
return $false, 'expected 3 element but got ' . $l_unaObject->{m_sizObjects} unless $l_unaObject->{m_sizObjects} == 3;
return $true;
}
);
Test('Join UnicodeArray object into Unicode object', sub {
my $l_strDelimiter = '*';
my $l_uniDelimiter = Unicode::from_string($l_strDelimiter, 0, 'UTF8');
my $l_strObject = 'ft1*ft2**ft4';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_unaObject = $l_uniObject->split($l_uniDelimiter, 0);
my $l_strJoin = 'ft1*ft2**ft4';
$starttime = gettimeofday() if $debug;
my $l_uniJoin = $l_unaObject->join($l_uniDelimiter, 0);
$endtime = gettimeofday() if $debug;
printf "join debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected "' . $l_strJoin . '" but got "' . $l_uniJoin->export_string(0, 'UTF8') . '"'
unless $l_strJoin eq $l_uniJoin->export_string(0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 1);
$l_strJoin = 'ft1*ft2*ft4';
$l_uniJoin = $l_unaObject->join($l_uniDelimiter, 1);
return $false, 'expected "' . $l_strJoin . '" but got "' . $l_uniJoin->export_string(0, 'UTF8') . '"'
unless $l_strJoin eq $l_uniJoin->export_string(0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 2);
$l_strJoin = '*ft2**';
$l_uniJoin = $l_unaObject->join($l_uniDelimiter, 2);
return $false, 'expected "' . $l_strJoin . '" but got "' . $l_uniJoin->export_string(0, 'UTF8') . '"'
unless $l_strJoin eq $l_uniJoin->export_string(0, 'UTF8');
$l_unaObject = $l_uniObject->split($l_uniDelimiter, 3);
$l_strJoin = '*ft2*';
$l_uniJoin = $l_unaObject->join($l_uniDelimiter, 3);
return $false, 'expected "' . $l_strJoin . '" but got "' . $l_uniJoin->export_string(0, 'UTF8') . '"'
unless $l_strJoin eq $l_uniJoin->export_string(0, 'UTF8');
return $true;
}
);
Test('Convert Perl array of strings into UnicodeArray object', sub {
my $l_arrStrings = ["The", "quick", "brown", "fox", "jumps", "over", "the", "cow"];
$starttime = gettimeofday() if $debug;
my $l_unaObject = new Unicode::UnicodeArray(1);
$endtime = gettimeofday() if $debug;
printf "new Unicode::UnicodeArray debug time = %.9lf\n", $endtime - $starttime if $debug;
$starttime = gettimeofday() if $debug;
$l_unaObject->to_array($l_arrStrings);
$endtime = gettimeofday() if $debug;
printf "to_array debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected 8 elements but got "' . $l_unaObject->{m_sizObjects} . '"' unless $l_unaObject->{m_sizObjects} == 8;
for (my $l_inOffset = 0; $l_inOffset < $l_unaObject->{m_sizObjects}; $l_inOffset++) {
my $l_strObject = $l_unaObject->get_element($l_inOffset)->export_string(0, "ASCII");
return $false, 'expected element ' . $l_inOffset . ' equal to "' . $l_arrStrings->[$l_inOffset] . '" but got "' . $l_strObject . '"'
unless $l_arrStrings->[$l_inOffset] eq $l_strObject;
}
return $true;
}
);
Test('Convert UnicodeArray object into a Perl array of strings', sub {
my $l_uniDelimiters = Unicode::from_string(" ,*", 0, "ASCII");
my $l_uniObject = Unicode::from_string("The quick, brown fox jumps *over* the cow " x 1000, 0, "ASCII");
my $l_unaObject = $l_uniObject->split($l_uniDelimiters, 1); # 1=trim delimiters between tokens
$starttime = gettimeofday() if $debug;
my $l_arrWords = $l_unaObject->from_array();
$endtime = gettimeofday() if $debug;
printf "from_array debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected "The" but got "' . $l_arrWords->[0] . '"' unless $l_arrWords->[0] eq 'The';
return $false, 'expected "quick" but got "' . $l_arrWords->[1] . '"' unless $l_arrWords->[1] eq 'quick';
return $false, 'expected "brown" but got "' . $l_arrWords->[2] . '"' unless $l_arrWords->[2] eq 'brown';
return $false, 'expected "fox" but got "' . $l_arrWords->[3] . '"' unless $l_arrWords->[3] eq 'fox';
return $false, 'expected "jumps" but got "' . $l_arrWords->[4] . '"' unless $l_arrWords->[4] eq 'jumps';
return $false, 'expected "over" but got "' . $l_arrWords->[5] . '"' unless $l_arrWords->[5] eq 'over';
return $false, 'expected "the" but got "' . $l_arrWords->[6] . '"' unless $l_arrWords->[6] eq 'the';
return $false, 'expected "cow" but got "' . $l_arrWords->[7] . '"' unless $l_arrWords->[7] eq 'cow';
}
);
Test('Return Unicode object subvalues in Perl array', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "${fs}ft1${fs}ft2${fs}ft3${fs}ft4${fs}${gs}gt1${gs}gt2${gs}gt3${gs}gt4${gs}${rs}rt1${rs}rt2${rs}rt3${rs}rt4${rs}${us}üt1${us}üt2${us}üt3${us}üt4${us}üt5${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_rearFS = $l_uniObject->from_subvalues(0, 0, 0);
return $false, 'expected array of five level 1 subvalues' unless $l_rearFS->[0] eq 'ft1' and $l_rearFS->[1] eq 'ft2' and $l_rearFS->[2] eq 'ft3' and $l_rearFS->[3] eq 'ft4' and length($l_rearFS->[4]) > 0;
my $l_rearGS = $l_uniObject->from_subvalues(5, 0, 0);
return $false, 'expected array of five level 2 subvalues' unless $l_rearGS->[0] eq 'gt1' and $l_rearGS->[1] eq 'gt2' and $l_rearGS->[2] eq 'gt3' and $l_rearGS->[3] eq 'gt4' and length($l_rearGS->[4]) > 0;
my $l_rearRS = $l_uniObject->from_subvalues(5, -1, 0);
return $false, 'expected array of five level 3 subvalues' unless $l_rearRS->[0] eq 'rt1' and $l_rearRS->[1] eq 'rt2' and $l_rearRS->[2] eq 'rt3' and $l_rearRS->[3] eq 'rt4' and length($l_rearRS->[4]) > 0;
$starttime = gettimeofday() if $debug;
my $l_rearUS = $l_uniObject->from_subvalues(-1, -1, 5);
$endtime = gettimeofday() if $debug;
printf "from_subvalues debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected array of five level 4 subvalues' unless decode('UTF-8', $l_rearUS->[0]) eq 'üt1' and decode('UTF-8', $l_rearUS->[1]) eq 'üt2' and decode('UTF-8', $l_rearUS->[2]) eq 'üt3' and decode('UTF-8', $l_rearUS->[3]) eq 'üt4' and decode('UTF-8', $l_rearUS->[4]) eq 'üt5';
return $true;
}
);
Test('Store Perl array as Unicode object subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_uniObject = new Unicode::Unicode;
my $l_rearLevel1 = [ 'João-ft1', 'João-ft2', 'João-ft3', 'João-ft4' ];
$l_uniObject->to_subvalues($l_rearLevel1, 0, 0, 0);
my $l_strObject = $l_uniObject->export_string(0, 'UTF8');
$l_strObject = decode('UTF8', $l_strObject);
return $false, 'expected subvalues of four level 1 subvalues' unless $l_strObject eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}";
my $l_rearLevel2 = [ 'João-gt1', 'João-gt2', 'João-gt3', 'João-gt4' ];
$l_uniObject->to_subvalues($l_rearLevel2, 5, 0, 0);
$l_strObject = $l_uniObject->export_string(0, 'UTF8');
$l_strObject = decode('UTF8', $l_strObject);
return $false, 'expected subvalues of four level 2 subvalues' unless $l_strObject eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${fs}";
my $l_rearLevel3 = [ 'João-rt1', 'João-rt2', 'João-rt3', 'João-rt4' ];
$l_uniObject->to_subvalues($l_rearLevel3, 5, 5, 0);
$l_strObject = $l_uniObject->export_string(0, 'UTF8');
$l_strObject = decode('UTF8', $l_strObject);
return $false, 'expected subvalues of four level 3 subvalues' unless $l_strObject eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${gs}${fs}";
my $l_rearLevel4 = [ 'João-ut1', 'João-ut2', 'João-ut3', 'João-ut4' ];
$starttime = gettimeofday() if $debug;
$l_uniObject->to_subvalues($l_rearLevel4, 5, 5, 5);
$endtime = gettimeofday() if $debug;
printf "to_subvalues debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_strObject = $l_uniObject->export_string(0, 'UTF8');
$l_strObject = decode('UTF8', $l_strObject);
return $false, 'expected subvalues of four level 4 subvalues' unless $l_strObject eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
return $true;
}
);
Test('Count Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_inCount = $l_uniObject->count_subvalues(0, 0, 0);
return $false, "expected subvalue count in (0, 0, 0) of 5 but got $l_inCount" unless $l_inCount == 5;
$l_inCount = $l_uniObject->count_subvalues(5, 0, 0);
return $false, "expected subvalue count in (5, 0, 0) of 5 but got $l_inCount" unless $l_inCount == 5;
$l_inCount = $l_uniObject->count_subvalues(5, 5, 0);
return $false, "expected subvalue count in (5, 5, 0) of 5 but got $l_inCount" unless $l_inCount == 5;
$l_inCount = $l_uniObject->count_subvalues(5, 5, 5);
return $false, "expected subvalue count in (5, 5, 5) of 4 but got $l_inCount" unless $l_inCount == 4;
$l_inCount = $l_uniObject->count_subvalues(-1, -1, -1);
return $false, "expected subvalue count in (-1, -1, -1) of 4 but got $l_inCount" unless $l_inCount == 4;
$l_inCount = $l_uniObject->count_subvalues(999, 0, 0);
return $false, "expected subvalue count in (999, 0, 0) of 0 but got $l_inCount" unless $l_inCount == 0;
$l_inCount = $l_uniObject->count_subvalues(1, 999, 0);
return $false, "expected subvalue count in (1, 999, 0) of 0 but got $l_inCount" unless $l_inCount == 0;
$starttime = gettimeofday() if $debug;
$l_inCount = $l_uniObject->count_subvalues(1, 1, 999);
$endtime = gettimeofday() if $debug;
printf "count debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, "expected subvalue count in (1, 1, 999) of 0 but got $l_inCount" unless $l_inCount == 0;
return $true;
}
);
Test('Extract Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "João Méroço${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_strSubvalue = $l_uniObject->extract_subvalue(0, 0, 0, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected object value in (0, 0, 0, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João Méroço";
$l_strSubvalue = $l_uniObject->extract_subvalue(2, 0, 0, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 1 subvalue in (2, 0, 0, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ft2";
$l_strSubvalue = $l_uniObject->extract_subvalue(-4, 0, 0, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 1 subvalue in (-4, 0, 0, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ft2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, 2, 0, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 2 subvalue in (5, 2, 0, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-gt2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, -4, 0, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 2 subvalue in (5, -4, 0, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-gt2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, 5, 2, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 3 subvalue in (5, 5, 2, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-rt2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, 5, -4, 0)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 3 subvalue in (5, 5, -4, 0) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-rt2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 2)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 4 subvalue in (5, 5, 5, 2) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ut2";
$l_strSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, -3)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 4 subvalue in (5, 5, 5, -3) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ut2";
$l_strSubvalue = $l_uniObject->extract_subvalue(-1, -1, -1, -1)->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 4 subvalue in (-1, -1, -1, -1) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ut4";
$starttime = gettimeofday() if $debug;
$l_strSubvalue = $l_uniObject->extract_subvalue(-1, -1, -1, -999)->export_string(0, 'UTF8');
$endtime = gettimeofday() if $debug;
printf "extract_subvalue debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, "expected level 4 subvalue in (-1, -1, -1, -999) but got '$l_strSubvalue'" unless $l_strSubvalue eq "João-ut1";
return $true;
}
);
Test('Replace Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "João Méroço${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_strReplace = "Lee Trevino";
my $l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 0, 0, 0, 0);
my $l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (0, 0, 0, 0)' unless $l_strResult eq "Lee Trevino${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ft7";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 7, 0, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (7, 0, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}${fs}João-ft7${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ft6";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 6, 0, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (6, 0, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}João-ft6${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ft5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 5, 0, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (5, 0, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}João-ft5${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-gt5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 5, 5, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (5, 5, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}João-gt5${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-rt5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 5, 5, 5, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (5, 5, 5, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}João-rt5${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ut5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 5, 5, 5, 5);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (5, 5, 5, 5)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}João-ut5${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ft3.5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 3, 0, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (3, 0, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}João-ft3.5${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-gt3.5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 3, 3, 0, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (3, 3, 0, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}${gs}${gs}${gs}João-gt3.5${gs}${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-rt3.5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 3, 3, 3, 0);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (3, 3, 3, 0)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}${gs}${gs}${gs}${rs}${rs}${rs}João-rt3.5${rs}${gs}${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ut3.5";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$l_uniObject->replace_subvalue($l_uniReplace, 3, 3, 3, 3);
$l_strResult = $l_uniObject->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (3, 3, 3, 3)' unless $l_strResult eq "${fs}João-ft1${fs}João-ft2${fs}${gs}${gs}${gs}${rs}${rs}${rs}${us}${us}${us}João-ut3.5${us}${rs}${gs}${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strReplace = "João-ft999999-gt999999-rt999999-ut999999";
$l_uniReplace = Unicode::from_string($l_strReplace, 0, 'UTF8');
$starttime = gettimeofday() if $debug;
$l_uniObject->replace_subvalue($l_uniReplace, 999999, 999999, 999999, 999999);
$endtime = gettimeofday() if $debug;
printf "replace_subvalue debug time = %.9lf\n", $endtime - $starttime if $debug;
my $l_uniResult = $l_uniObject->extract_subvalue(999999, 999999, 999999, 999999);
$l_strResult = $l_uniResult->export_string(0, 'UTF8');
$l_strResult = decode('UTF8', $l_strResult);
return $false, 'expected replacement of subvalue in (999999, 999999, 999999, 999999)' unless $l_strResult eq $l_strReplace;
return $true;
}
);
Test('Insert Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_strInsert = "João Méroço";
my $l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 0, 0, 0, 0);
my $l_uniSubvalue = $l_uniObject->extract_subvalue(0, 0, 0, 0);
my $l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (0, 0, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft7";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 7, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(7, 0, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (7, 0, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft6";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 6, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(6, 0, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (6, 0, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft5";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 5, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 0, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (5, 0, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-gt5";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 5, 5, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (5, 5, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-rt5";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 5, 5, 5, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (5, 5, 5, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ut5";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 5, 5, 5, 5);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 5);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (5, 5, 5, 5)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft2.5";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 3, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 0, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (3, 0, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft3-gt3";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 3, 3, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 0, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (3, 3, 0, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft3-gt3-rt3";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 3, 3, 3, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 3, 0);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (3, 3, 3, 0)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft3-gt3-rt3-ut3";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, 3, 3, 3, 3);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 3, 3);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (3, 3, 3, 3)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft1-gt1-rt1-ut1";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$l_uniObject->insert_subvalue($l_uniInsert, -99, -99, -99, -99);
$l_uniSubvalue = $l_uniObject->extract_subvalue(-99, -99, -99, -99);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (-99, -99, -99, -99)' unless $l_strSubvalue eq $l_strInsert;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_strInsert = "João-ft99999-gt99999-rt99999-ut99999";
$l_uniInsert = Unicode::from_string($l_strInsert, 0, 'UTF8');
$starttime = gettimeofday() if $debug;
$l_uniObject->insert_subvalue($l_uniInsert, 99999, 99999, 99999, 99999);
$endtime = gettimeofday() if $debug;
printf "insert_subvalue debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniSubvalue = $l_uniObject->extract_subvalue(99999, 99999, 99999, 99999);
$l_strSubvalue = $l_uniSubvalue->export_string(0, 'UTF8');
$l_strSubvalue = decode('UTF8', $l_strSubvalue);
return $false, 'expected insertion of subvalue in (99999, 99999, 99999, 99999)' unless $l_strSubvalue eq $l_strInsert;
return $true;
}
);
Test('Append Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_uniObject = new Unicode::Unicode();
my $l_uniAppend = Unicode::from_string("João-ft1", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, -1, 0, 0, 0);
my $l_uniSubvalue = $l_uniObject->extract_subvalue(2, 0, 0, 0);
return $false, 'expected append of subvalue at (-1, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = new Unicode::Unicode();
$l_uniAppend = Unicode::from_string("João-gt1", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 1, -1, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(1, 2, 0, 0);
return $false, 'expected append of subvalue at (1, -1, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = new Unicode::Unicode();
$l_uniAppend = Unicode::from_string("João-rt1", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 1, 1, -1, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(1, 1, 2, 0);
return $false, 'expected append of subvalue at (1, 1, -1, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = new Unicode::Unicode();
$l_uniAppend = Unicode::from_string("João-ut1", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 1, 1, 1, -1);
$l_uniSubvalue = $l_uniObject->extract_subvalue(1, 1, 1, 2);
return $false, 'expected append of subvalue at (1, 1, 1, -1) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
my $l_strObject = "${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João Méroço", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 0, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(0, 0, 0, 0);
return $false, 'expected append of subvalue in (0, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft8", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 7, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(8, 0, 0, 0);
return $false, 'expected append of subvalue in (7, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft7", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 6, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(7, 0, 0, 0);
return $false, 'expected append of subvalue in (6, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(6, 0, 0, 0);
return $false, 'expected append of subvalue in (5, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, -1, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(6, 0, 0, 0);
return $false, 'expected append of subvalue in (-1, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-gt6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 5, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 6, 0, 0);
return $false, 'expected append of subvalue in (5, 5, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-gt6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, -1, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 6, 0, 0);
return $false, 'expected append of subvalue in (5, -1, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-rt6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 5, 5, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 6, 0);
return $false, 'expected append of subvalue in (5, 5, 5, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-rt6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 5, -1, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 6, 0);
return $false, 'expected append of subvalue in (5, 5, -1, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ut6", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 5, 5, 5);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 6);
return $false, 'expected append of subvalue in (5, 5, 5, 5) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ut5", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 5, 5, 5, -1);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 5);
return $false, 'expected append of subvalue in (5, 5, 5, -1) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft3.5", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 3, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(4, 0, 0, 0);
return $false, 'expected append of subvalue in (3, 0, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft3-gt4", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 3, 3, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 4, 0, 0);
return $false, 'expected append of subvalue in (3, 3, 0, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft3-gt3-rt4", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 3, 3, 3, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 4, 0);
return $false, 'expected append of subvalue in (3, 3, 3, 0) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft3-gt3-rt3-ut4", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, 3, 3, 3, 3);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 3, 4);
return $false, 'expected append of subvalue in (3, 3, 3, 3) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft-99-gt-99-rt-99-ut2", 0, 'UTF8');
$l_uniObject->append_subvalue($l_uniAppend, -99, -99, -99, -99);
$l_uniSubvalue = $l_uniObject->extract_subvalue(-99, -99, -99, 2);
return $false, 'expected append of subvalue in (-99, -99, -99, -99) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniAppend = Unicode::from_string("João-ft999999-gt999999-rt999999-ut1000000", 0, 'UTF8');
$starttime = gettimeofday() if $debug;
$l_uniObject->append_subvalue($l_uniAppend, 999999, 999999, 999999, 999999);
$endtime = gettimeofday() if $debug;
printf "append_subvalue debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniSubvalue = $l_uniObject->extract_subvalue(999999, 999999, 999999, 1000000);
return $false, 'expected append of subvalue in (999999, 999999, 999999, 999999) but got "' . $l_uniObject->export_string(0, 'UTF8') . '"' unless $l_uniAppend->compare_ascendingstring($l_uniSubvalue) == 0;
return $true;
}
);
Test('Delete Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "João Méroço${fs}João-ft1${fs}João-ft2${fs}João-ft3${fs}João-ft4${fs}${gs}João-gt1${gs}João-gt2${gs}João-gt3${gs}João-gt4${gs}${rs}João-rt1${rs}João-rt2${rs}João-rt3${rs}João-rt4${rs}${us}João-ut1${us}João-ut2${us}João-ut3${us}João-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_uniCompare = Unicode::from_string('', 0, 'UTF8');
$l_uniObject->delete_subvalue(0, 0, 0, 0);
my $l_uniSubvalue = $l_uniObject->extract_subvalue(0, 0, 0, 0);
return $false, 'expected delete of value in (0, 0, 0, 0)' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniCompare = Unicode::from_string('João-ft1', 0, 'UTF8');
$l_uniSubvalue = $l_uniObject->extract_subvalue(1, 0, 0, 0);
return $false, 'expected no delete of subvalue in (1, 0, 0, 0)' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(8, 0, 0, 0);
$l_uniObject->delete_subvalue(7, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(7, 0, 0, 0);
return $false, 'expected delete of subvalue in (7, 0, 0, 0)' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(7, 0, 0, 0);
$l_uniObject->delete_subvalue(6, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(6, 0, 0, 0);
return $false, 'expected delete of subvalue in (6, 0, 0, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(6, 0, 0, 0);
$l_uniObject->delete_subvalue(5, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 0, 0, 0);
return $false, 'expected delete of subvalue in (5, 0, 0, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 6, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 0, 0);
$l_uniObject->delete_subvalue(5, 5, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 0, 0);
return $false, 'expected delete of subvalue in (5, 5, 0, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 5, 6, 0);
$l_uniObject->delete_subvalue(5, 5, 5, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 0);
return $false, 'expected delete of subvalue in (5, 5, 5, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 5, 5, 6);
$l_uniObject->delete_subvalue(5, 5, 5, 5);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 5, 5, 5);
return $false, 'expected delete of subvalue in (5, 5, 5, 5);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 1, 1, 2);
$l_uniObject->delete_subvalue(5, 1, 1, 1);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 1, 1, 1);
return $false, 'expected delete of subvalue in (5, 1, 1, 1);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 2, 2, 3);
$l_uniObject->delete_subvalue(5, 2, 2, 2);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 2, 2, 2);
return $false, 'expected delete of subvalue in (5, 2, 2, 2);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 3, 3, 4);
$l_uniObject->delete_subvalue(5, 3, 3, 3);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 3, 3, 3);
return $false, 'expected delete of subvalue in (5, 3, 3, 3);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(5, 4, 4, 5);
$l_uniObject->delete_subvalue(5, 4, 4, 4);
$l_uniSubvalue = $l_uniObject->extract_subvalue(5, 4, 4, 4);
return $false, 'expected delete of subvalue in (5, 4, 4, 4);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(4, 0, 0, 0);
$l_uniObject->delete_subvalue(3, 0, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 0, 0, 0);
return $false, 'expected delete of subvalue in (3, 0, 0, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(3, 4, 0, 0);
$l_uniObject->delete_subvalue(3, 3, 0, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 0, 0);
return $false, 'expected delete of subvalue in (3, 3, 0, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(3, 3, 4, 0);
$l_uniObject->delete_subvalue(3, 3, 3, 0);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 3, 0);
return $false, 'expected delete of subvalue in (3, 3, 3, 0);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(3, 3, 3, 4);
$l_uniObject->delete_subvalue(3, 3, 3, 3);
$l_uniSubvalue = $l_uniObject->extract_subvalue(3, 3, 3, 3);
return $false, 'expected delete of subvalue in (3, 3, 3, 3);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(-99, -99, -99, 2);
$l_uniObject->delete_subvalue(-99, -99, -99, 1);
$l_uniSubvalue = $l_uniObject->extract_subvalue(-99, -99, -99, 1);
return $false, 'expected delete of subvalue in (-99, -99, -99, 1);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniCompare = $l_uniObject->extract_subvalue(99999, 99999, 99999, 10000);
$starttime = gettimeofday() if $debug;
$l_uniObject->delete_subvalue(99999, 99999, 99999, 99999);
$endtime = gettimeofday() if $debug;
printf "delete_subvalue debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniSubvalue = $l_uniObject->extract_subvalue(99999, 99999, 99999, 99999);
return $false, 'expected delete of subvalue in (99999, 99999, 99999, 99999);' unless $l_uniSubvalue->compare_ascendingstring($l_uniCompare) == 0;
return $true;
}
);
Test('Sort Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(0, 0, 0, 0);
my $l_strSorted = $l_uniObject->export_string(0, 'ASCII');
return $false, 'expected sorted ascending string subvalues in (0, 0, 0)' unless $l_strSorted eq "${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(0, 0, 0, 1);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending string subvalues in (0, 0, 0)' unless $l_strSorted eq "${fs}4-ft4${fs}30-ft3${fs}200-ft2${fs}1000-ft1${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(0, 0, 0, 2);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending numeric subvalues in (0, 0, 0)' unless $l_strSorted eq "${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}4-ft4${fs}30-ft3${fs}200-ft2${fs}1000-ft1${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(0, 0, 0, 3);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending numeric subvalues in (0, 0, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 0, 0, 0);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending string subvalues in (5, 0, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 0, 0, 1);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending string subvalues in (5, 0, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}4-gt4${gs}30-gt3${gs}200-gt2${gs}1000-gt1${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 0, 0, 2);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending numeric subvalues in (5, 0, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}4-gt4${gs}30-gt3${gs}200-gt2${gs}1000-gt1${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 0, 0, 3);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending numeric subvalues in (5, 0, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 0, 0);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending string subvalues in (5, 5, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 0, 1);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending string subvalues in (5, 5, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}4-rt4${rs}30-rt3${rs}200-rt2${rs}1000-rt1${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 0, 2);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending numeric subvalues in (5, 5, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}4-rt4${rs}30-rt3${rs}200-rt2${rs}1000-rt1${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 0, 3);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending numeric subvalues in (5, 5, 0)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 5, 0);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending string subvalues in (5, 5, 5)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 5, 1);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending string subvalues in (5, 5, 5)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}4-ut4${us}30-ut3${us}200-ut2${us}1000-ut1${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$l_uniObject->sort_subvalues(5, 5, 5, 2);
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted ascending numeric subvalues in (5, 5, 5)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}4-ut4${us}30-ut3${us}200-ut2${us}1000-ut1${us}${rs}${gs}${fs}";
$l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$starttime = gettimeofday() if $debug;
$l_uniObject->sort_subvalues(5, 5, 5, 3);
$endtime = gettimeofday() if $debug;
printf "sort_subvalues debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_strSorted = $l_uniObject->export_string(0, 'UTF8');
return $false, 'expected sorted descending numeric subvalues in (5, 5, 5)' unless $l_strSorted eq "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}${us}1000-ut1${us}200-ut2${us}30-ut3${us}4-ut4${us}${rs}${gs}${fs}";
return $true;
}
);
Test('Locate Unicode object 4-dimensional dynamic array subvalues', sub {
my $fs = "\x1c"; # ASCII FS control separator character (level 1 subvalue delimiter)
my $gs = "\x1d"; # ASCII GS control separator character (level 2 subvalue delimiter)
my $rs = "\x1e"; # ASCII RS control separator character (level 3 subvalue delimiter)
my $us = "\x1f"; # ASCII US control separator character (level 4 subvalue delimiter)
my $l_strObject = "${fs}1000-ft1${fs}200-ft2${fs}30-ft3${fs}4-ft4${fs}";
$l_strObject .= "${gs}1000-gt1${gs}200-gt2${gs}30-gt3${gs}4-gt4${gs}";
$l_strObject .= "${rs}1000-rt1${rs}200-rt2${rs}30-rt3${rs}4-rt4${rs}";
$l_strObject .= "${us}${_}-ut${_}" for 1 ... 1000;
$l_strObject .= "${us}${rs}${gs}${fs}";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_uniKey = Unicode::from_string('1000-ft1', 0, 'UTF8');
my $l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 0, 0, 0, 0);
return $false, 'expected to locate key in unsorted subvalues in (0, 0, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 0, 0, 0, 1);
return $false, 'expected to locate key in ascending string subvalues in (0, 0, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 0, 0, 0, 2);
return $false, 'expected to locate key in descending string subvalues in (0, 0, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 0, 0, 0, 3);
return $false, 'expected to locate key in ascending numeric subvalues in (0, 0, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 0, 0, 0, 4);
return $false, 'expected to locate key in descending numeric subvalues in (0, 0, 0)' unless $l_inIndex == 1;
$l_uniKey = Unicode::from_string('1000-gt1', 0, 'UTF8');
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 0, 0, 0);
return $false, 'expected to locate key in unsorted subvalues in (5, 0, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 0, 0, 1);
return $false, 'expected to locate key in ascending string subvalues in (5, 0, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 0, 0, 2);
return $false, 'expected to locate key in descending string subvalues in (5, 0, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 0, 0, 3);
return $false, 'expected to locate key in ascending numeric subvalues in (5, 0, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 0, 0, 4);
return $false, 'expected to locate key in descending numeric subvalues in (5, 0, 0)' unless $l_inIndex == 1;
$l_uniKey = Unicode::from_string('1000-rt1', 0, 'UTF8');
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 0, 0);
return $false, 'expected to locate key in unsorted subvalues in (5, 5, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 0, 1);
return $false, 'expected to locate key in ascending string subvalues in (5, 5, 0)' unless $l_inIndex == 1;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 0, 2);
return $false, 'expected to locate key in descending string subvalues in (5, 5, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 0, 3);
return $false, 'expected to locate key in ascending numeric subvalues in (5, 5, 0)' unless $l_inIndex == 0;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 0, 4);
return $false, 'expected to locate key in descending numeric subvalues in (5, 5, 0)' unless $l_inIndex == 1;
my $l_strKey = '500-ut500';
$starttime = gettimeofday() if $debug;
$l_uniObject->sort_subvalues(5, 5, 5, 0);
$endtime = gettimeofday() if $debug;
printf "sort_subvalues(ascending string) debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniKey = Unicode::from_string($l_strKey, 0, 'UTF8');
$l_inIndex = 0;
$starttime = gettimeofday() if $debug;
my $l_rearSubvalues = $l_uniObject->from_subvalues(5, 5, 5);
for (my $l_inOffset = 0; $l_inOffset <= $#$l_rearSubvalues; $l_inOffset++) {
if ($l_rearSubvalues->[$l_inOffset] eq $l_strKey) {
$l_inIndex = $l_inOffset + 1;
last;
}
}
$endtime = gettimeofday() if $debug;
printf "for-loop(left-to-right scan) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in for loop in extracted (5, 5, 5)' unless $l_inIndex == 448;
$starttime = gettimeofday() if $debug;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 5, 0);
$endtime = gettimeofday() if $debug;
printf "locate_subvalue(left-to-right scan) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in unsorted subvalues in (5, 5, 5)' unless $l_inIndex == 448;
$starttime = gettimeofday() if $debug;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 5, 1);
$endtime = gettimeofday() if $debug;
printf "locate_subvalue(ascending string search) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in ascending string subvalues in (5, 5, 5)' unless $l_inIndex == 448;
$starttime = gettimeofday() if $debug;
$l_uniObject->sort_subvalues(5, 5, 5, 1);
$endtime = gettimeofday() if $debug;
printf "sort_subvalues(descending string) debug time = %.9lf\n", $endtime - $starttime if $debug;
$starttime = gettimeofday() if $debug;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 5, 2);
$endtime = gettimeofday() if $debug;
printf "locate_subvalue(descending string search) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in descending string subvalues in (5, 5, 5)' unless $l_inIndex == 553;
$starttime = gettimeofday() if $debug;
$l_uniObject->sort_subvalues(5, 5, 5, 2);
$endtime = gettimeofday() if $debug;
printf "sort_subvalues(ascending numeric) debug time = %.9lf\n", $endtime - $starttime if $debug;
$starttime = gettimeofday() if $debug;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 5, 3);
$endtime = gettimeofday() if $debug;
printf "locate_subvalue(ascending numeric search) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in ascending numeric subvalues in (5, 5, 5)' unless $l_inIndex == 500;
$starttime = gettimeofday() if $debug;
$l_uniObject->sort_subvalues(5, 5, 5, 3);
$endtime = gettimeofday() if $debug;
printf "sort_subvalues(descending numeric) debug time = %.9lf\n", $endtime - $starttime if $debug;
$starttime = gettimeofday() if $debug;
$l_inIndex = $l_uniObject->locate_subvalue($l_uniKey, 5, 5, 5, 4);
$endtime = gettimeofday() if $debug;
printf "locate_subvalue(descending numeric search) debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected to locate key in descending numeric subvalues in (5, 5, 5)' unless $l_inIndex == 501;
return $true;
}
);
Test('Store one-year calendar data in 4-dimensional dynamic array', sub {
$starttime = gettimeofday() if $debug;
my $l_uniObject = new Unicode::Unicode;
my $date = Time::Piece->strptime('2017-01-01', '%Y-%m-%d');
for (my $i = 0; $i < 365; $i++) {
my $l_arrInfo = [ $date->ymd, $date->yday + 1, $date->wday, $date->fullmonth, $date->fullday ];
$l_uniObject->to_subvalues($l_arrInfo, $date->year, $date->mon, $date->mday);
$date += ONE_DAY;
}
my $l_arrLastday = $l_uniObject->from_subvalues(2017, 12, 31);
return $false, 'expected calendar info on 2017-12-31'
unless $l_arrLastday->[0] eq '2017-12-31'
&& $l_arrLastday->[1] == 365
&& $l_arrLastday->[2] == 1
&& $l_arrLastday->[3] eq 'December'
&& $l_arrLastday->[4] eq 'Sunday';
$endtime = gettimeofday() if $debug;
printf "one-year calendar debug time = %.9lf\n", $endtime - $starttime if $debug;
return $true;
}
);
Test('Get Unicode object codepoints', sub {
my $l_strObject = "João Méroço;";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
for (my $l_inOffset = 0; $l_inOffset < $l_uniObject->codepoints; $l_inOffset++) {
$starttime = gettimeofday() if $debug && $l_inOffset == 0;
my $l_loCodepoint = $l_uniObject->get_codepoint($l_inOffset);
$endtime = gettimeofday() if $debug && $l_inOffset == 0;
printf "get_codepoint debug time = %.9lf\n", $endtime - $starttime if $debug && $l_inOffset == 0;
return $false, "expected to get codepoint at offset $l_inOffset" unless $l_loCodepoint == ord(substr($l_strObject, $l_inOffset, 1));
}
return $true;
}
);
Test('Set Unicode object codepoints', sub {
my $l_strObject = "João Méroço";
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
$starttime = gettimeofday() if $debug;
$l_uniObject->set_codepoint(2, ord('a'));
$endtime = gettimeofday() if $debug;
printf "set_codepoint debug time = %.9lf\n", $endtime - $starttime if $debug;
$l_uniObject->set_codepoint(6, ord('e'));
$l_uniObject->set_codepoint(9, ord('c'));
$l_strObject = $l_uniObject->export_string(0, 'UTF8');
my $l_strResult = "Joao Meroco";
return $false, "expected to set ASCII codepoints" unless $l_strObject eq $l_strResult;
return $true;
}
);
Test('Find a specific codepoint inside Unicode object', sub {
my $l_strObject = 'João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_loAtilde = ord('ã');
my $l_loEacute = ord('é');
my $l_loCumlat = ord('ç');
for (my $l_inCount = 0; $l_inCount < 23; $l_inCount++) {
$starttime = gettimeofday() if $debug && $l_inCount == 0;
my $l_inOffset = $l_uniObject->find_codepoint($l_loAtilde, $l_inCount);
$endtime = gettimeofday() if $debug && $l_inCount == 0;
printf "find_codepoint debug time = %.9lf\n", $endtime - $starttime if $debug && $l_inCount == 0;
return $false, "expected to find offset of 'ã' #$l_inCount left-to-right" unless ($l_inOffset % 12) == 2;
$l_inOffset = $l_uniObject->find_codepoint($l_loAtilde, -1 * ($l_inCount + 1));
return $false, "expected to find offset of 'ã' #$l_inCount right-to-left" unless ($l_inOffset % 12) == 2;
$l_inOffset = $l_uniObject->find_codepoint($l_loEacute, $l_inCount);
return $false, "expected to find offset of 'é' #$l_inCount left-to-right" unless ($l_inOffset % 12) == 6;
$l_inOffset = $l_uniObject->find_codepoint($l_loEacute, -1 * ($l_inCount + 1));
return $false, "expected to find offset of 'é' #$l_inCount right-to-left" unless ($l_inOffset % 12) == 6;
$l_inOffset = $l_uniObject->find_codepoint($l_loCumlat, $l_inCount);
return $false, "expected to find offset of 'ç' #$l_inCount left-to-right" unless ($l_inOffset % 12) == 9;
$l_inOffset = $l_uniObject->find_codepoint($l_loCumlat, -1 * ($l_inCount + 1));
return $false, "expected to find offset of 'ç' #$l_inCount right-to-left" unless ($l_inOffset % 12) == 9;
}
return $true;
}
);
Test('Get POSIX class of a single codepoint inside Unicode object', sub {
my @l_arinClasses = (0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x340, 0x140, 0x140, 0x140, 0x140, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x700, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80,
0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0x4b1, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80,
0xc80, 0x4ab, 0x4ab, 0x4ab, 0x4ab, 0x4ab, 0x4ab, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b,
0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0x48b, 0xc80, 0xc80, 0xc80, 0xc80, 0xc80,
0xc80, 0x4a7, 0x4a7, 0x4a7, 0x4a7, 0x4a7, 0x4a7, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487,
0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0x487, 0xc80, 0xc80, 0xc80, 0xc80, 0x40);
my $l_strObject = join '', map { chr($_); } (0 .. 127);
my $l_uniObject = Unicode::from_string($l_strObject, 128, 'ASCII');
for (0 .. 127) {
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:alnum:] class"
unless $l_uniObject->isalnum_codepoint($_) == ($l_arinClasses[$_] & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:alpha:] class"
unless $l_uniObject->isalpha_codepoint($_) == ($l_arinClasses[$_] >> 1 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:lower:] class"
unless $l_uniObject->islower_codepoint($_) == ($l_arinClasses[$_] >> 2 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:upper:] class"
unless $l_uniObject->isupper_codepoint($_) == ($l_arinClasses[$_] >> 3 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:digit:] class"
unless $l_uniObject->isdigit_codepoint($_) == ($l_arinClasses[$_] >> 4 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:xdigit:] class"
unless $l_uniObject->isxdigit_codepoint($_) == ($l_arinClasses[$_] >> 5 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:cntrl:] class"
unless $l_uniObject->iscntrl_codepoint($_) == ($l_arinClasses[$_] >> 6 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:graph:] class"
unless $l_uniObject->isgraph_codepoint($_) == ($l_arinClasses[$_] >> 7 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:space:] class"
unless $l_uniObject->isspace_codepoint($_) == ($l_arinClasses[$_] >> 8 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:blank:] class"
unless $l_uniObject->isblank_codepoint($_) == ($l_arinClasses[$_] >> 9 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:print:] class"
unless $l_uniObject->isprint_codepoint($_) == ($l_arinClasses[$_] >> 10 & 1);
return $false, "ASCII character code $_ ('" . chr($_) . "') does not match POSIX [:punct:] class"
unless $l_uniObject->ispunct_codepoint($_) == ($l_arinClasses[$_] >> 11 & 1);
}
return $true;
}
);
Test('Get lowercase values of codepoints inside Unicode object', sub {
my $l_strObject = 'João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_loJlower = ord('j');
my $l_loMlower = ord('m');
for (my $l_inCount = 0; $l_inCount < 23; $l_inCount++) {
my $l_inOffset = $l_inCount * 12;
return $false, "expected lowercase 'j' at offset $l_inOffset"
unless $l_uniObject->tolower_codepoint($l_inOffset) == $l_loJlower;
$l_inOffset = $l_inCount * 12 + 5;
return $false, "expected lowercase 'm' at offset $l_inOffset"
unless $l_uniObject->tolower_codepoint($l_inOffset) == $l_loMlower;
}
return $true;
}
);
Test('Get uppercase values of codepoints inside Unicode object', sub {
my $l_strObject = 'João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço';
my $l_uniObject = Unicode::from_string($l_strObject, 0, 'UTF8');
my $l_loAtilde = ord('Ã');
my $l_loEacute = ord('É');
my $l_loCumlat = ord('Ç');
for (my $l_inCount = 0; $l_inCount < 23; $l_inCount++) {
my $l_inOffset = $l_inCount * 12 + 2;
return $false, "expected uppercase 'ã' at offset $l_inOffset"
unless $l_uniObject->toupper_codepoint($l_inOffset) == $l_loAtilde;
$l_inOffset = $l_inCount * 12 + 6;
return $false, "expected uppercase 'é' at offset $l_inOffset"
unless $l_uniObject->toupper_codepoint($l_inOffset) == $l_loEacute;
$l_inOffset = $l_inCount * 12 + 9;
return $false, "expected uppercase 'ç' at offset $l_inOffset"
unless $l_uniObject->toupper_codepoint($l_inOffset) == $l_loCumlat;
}
return $true;
}
);
Test('Save and load Unicode object content in specified encoding with specified file', sub {
my $l_uniFile = Unicode::from_string('WideString.txt', 0, 'UTF8');
my $l_uniSave = Unicode::from_string('João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço João Méroço', 0, 'UTF8');
$starttime = gettimeofday() if $debug;
my $l_inByteswritten = $l_uniSave->save($l_uniFile, 'UTF16LE');
$endtime = gettimeofday() if $debug;
printf "save debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected all bytes written to file "WideString.txt"' unless $l_inByteswritten > 0;
my $l_uniLoad = new Unicode::Unicode();
$starttime = gettimeofday() if $debug;
my $l_inBytesread = $l_uniLoad->load($l_uniFile, 'UTF16LE');
$endtime = gettimeofday() if $debug;
printf "load debug time = %.9lf\n", $endtime - $starttime if $debug;
return $false, 'expected all bytes read from file "WideString.txt"' unless $l_inBytesread == $l_inByteswritten;
return $false, 'expected same content as written to file "WideString.txt"' unless $l_uniLoad->compare_ascendingstring($l_uniSave) == 0;
unlink 'WideString.txt';
return $true;
}
);
Test('Test four-dimensional UnicodeTesseract object', sub {
my ($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4) = (10, 1, 12, 31, 24);
my ($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4) = (0, 0, 0, 0);
my ($l_untObject, $l_uniObject) = (undef, undef);
$starttime = gettimeofday() if $debug;
$l_untObject = new Unicode::UnicodeTesseract($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4);
$endtime = gettimeofday() if $debug;
printf "new Unicode::UnicodeTesseract debug time = %.9lf\n", $endtime - $starttime if $debug;
say "new Unicode::UnicodeTesseract($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4) = $l_untObject->{m_sizBytes} bytes" if $debug;
my $first = 1;
for ($l_inLevel1 = 1; $l_inLevel1 <= $l_inDim1; $l_inLevel1++) {
for ($l_inLevel2 = 1; $l_inLevel2 <= $l_inDim2; $l_inLevel2++) {
for ($l_inLevel3 = 1; $l_inLevel3 <= $l_inDim3; $l_inLevel3++) {
for ($l_inLevel4 = 1; $l_inLevel4 <= $l_inDim4; $l_inLevel4++) {
my $l_uniElement = Unicode::from_string("$l_inLevel1$l_inLevel2$l_inLevel3$l_inLevel4", 0, 'UTF8');
if ($first) {
$starttime = gettimeofday() if $debug;
}
$l_untObject->set_element($l_uniElement, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
if ($first) {
$endtime = gettimeofday() if $debug;
printf "set_element debug time = %.9lf\n", $endtime - $starttime if $debug;
$first = 0;
}
}
}
}
}
$starttime = gettimeofday() if $debug;
$l_uniObject = $l_untObject->from_tesseract();
$endtime = gettimeofday() if $debug;
printf "from_tesseract debug time = %.9lf\n", $endtime - $starttime if $debug;
undef $l_untObject;
$starttime = gettimeofday() if $debug;
$l_untObject = $l_uniObject->to_tesseract($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4);
$endtime = gettimeofday() if $debug;
printf "to_tesseract debug time = %.9lf\n", $endtime - $starttime if $debug;
undef $l_uniObject;
$first = 1;
for ($l_inLevel1 = 1; $l_inLevel1 <= $l_inDim1; $l_inLevel1++) {
for ($l_inLevel2 = 1; $l_inLevel2 <= $l_inDim2; $l_inLevel2++) {
for ($l_inLevel3 = 1; $l_inLevel3 <= $l_inDim3; $l_inLevel3++) {
for ($l_inLevel4 = 1; $l_inLevel4 <= $l_inDim4; $l_inLevel4++) {
if ($first) {
$starttime = gettimeofday() if $debug;
}
my $l_uniElement = $l_untObject->get_element($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
if ($first) {
$endtime = gettimeofday() if $debug;
printf "get_element debug time = %.9lf\n", $endtime - $starttime if $debug;
$first = 0;
}
return $false, 'undef returned instead of new Unicode::Unicode object' unless defined($l_uniElement);
return $false, 'unexpected "' . ref($l_uniElement) . '" for ref(object)' unless ref($l_uniElement) eq 'Unicode::Unicode';
my $l_strElement = $l_uniElement->export_string(0, 'UTF8');
my $l_strExpected = "$l_inLevel1$l_inLevel2$l_inLevel3$l_inLevel4";
return $false, "expected tesseract[$l_inLevel1][$l_inLevel2][$l_inLevel3][$l_inLevel4] to equal '$l_strExpected' but got '$l_strElement'" unless $l_strElement eq $l_strExpected;
}
}
}
}
return $true;
}
);
goto DONE;
DONE:
printf "Time: %.6lf seconds\n", gettimeofday() - $begintime;
done_testing();
1;
__END__
=head1 SYNOPSIS
=head2 RUN TESTS
$ perl testunicode.pl
=head2 GENERATE DOCUMENTATION
$ perldoc testunicode.pl
=head2 PERL5 METHODS
This documentation only provides a quick reference of all the B<< Unicode >> library class and object methods available. For code examples, refer to the source code of this test script.
=head3 VARIABLE NAMING CONVENTIONS
Originally adopted from C/C++ programming, this program documentation uses the following variable naming convention. It is a custom form of Hungarian Notation used to make the code more readable. Here is what it means.
=head4 FORMAT
$scope_typePurpose
For example, you can read the name "$l_inError" as indicating a local scope variable that contains an integer indicating an error code.
=head4 SCOPE
Use only one of the following lowercase scopes followed by an underscore.
=over 4
=item * m = member scope -- Example: our $m_inError = 0;
=item * l = local scope -- Example: my $l_inError = 0;
=back
=head4 TYPE
=over 4
=item * bo = boolean
=item * in = integer
=item * lo = long int
=item * ll = long long
=item * fl = float
=item * do = double
=item * ld = long double
=item * str = null-terminated char string
=item * uni = Unicode object
=item * una = UnicodeArray object
=item * unt = UnicodeTesseract object
=back
=head3 CLASS CONSTRUCTORS
my $l_uniObject = new Unicode::Unicode();
my $l_unaObject = new Unicode::UnicodeArray($l_inElements);
my $l_untObject = new Unicode::UnicodeTesseract($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4);
=head3 CLASS DESTRUCTORS
Normally unnecessary since Perl automatically destructs objects when they go out of scope. But you can manually delete B<< Unicode >> library objects using the following Perl commands.
undef $l_uniObject;
undef $l_unaObject;
undef $l_untObject;
=head3 CLASS METHODS
These are class methods used to convert from a Perl5 built-in type to a B<< Unicode >> object directly. Consider these as static class methods, not object methods, and therefore they require the B<< Unicode:: >> package class prefix so that Perl5 can find them.
my $l_uniString = Unicode::from_string($l_strString, $l_inMaxbytes, $l_strEncoding);
my $l_uniInt = Unicode::from_int($l_inValue);
my $l_uniLong = Unicode::from_long($l_loValue);
my $l_uniLonglong = Unicode::from_longlong($l_llValue);
my $l_uniFloat = Unicode::from_float($l_flValue);
my $l_uniDouble = Unicode::from_double($l_doValue);
my $l_uniLongdouble = Unicode::from_longdouble($l_ldValue);
=head3 OBJECT METHODS
$l_uniObject->clear();
my $l_boEmpty = $l_uniObject->empty();
my $l_inCodepoints = $l_uniObject->codepoints();
my $l_inBytes = $l_uniObject->bytes();
my $l_inInbytes = $l_uniObject->import_string($l_strCodepoints, $l_inMaxbytes, $l_strEncoding);
$l_strCodepoints = $l_uniObject->export_string($l_inMaxbytes, $l_strEncoding);
my $l_inValue = $l_uniObject->to_int();
my $l_loValue = $l_uniObject->to_long();
my $l_llValue = $l_uniObject->to_longlong();
my $l_flValue = $l_uniObject->to_float();
my $l_doValue = $l_uniObject->to_double();
my $l_ldValue = $l_uniObject->to_longdouble();
$l_uniObject2->copy($l_uniObject1);
$l_uniObject1->append($l_uniObject2);
$l_uniObject1->append_multiple($l_uniObject2, $l_inCopies);
$l_uniObject1->swap($l_uniObject2);
my $l_inOffset = $l_uniObject1->find($l_uniObject2, $l_inCount);
my $l_uniObject2 = $l_uniObject1->extract($l_inOffset, $l_inLength);
$l_uniObject1->replace($l_uniObject2, $l_inOffset, $l_inLength);
my $l_boEqual = $l_uniObject1->compare_ascendingstring($l_uniObject2) == 0;
my $l_boNotequal = $l_uniObject1->compare_descendingstring($l_uniObject2) != 0;
my $l_boLess = $l_uniObject1->compare_ascendingnumeric($l_uniObject2) < 0;
my $l_boLess = $l_uniObject1->compare_descendingnumeric($l_uniObject2) > 0;
my $l_uniUppercase = $l_uniObject->uppercase();
my $l_uniLowercase = $l_uniObject->lowercase();
my $l_uniSwapcase = $l_uniObject->swapcase();
my $l_uniObject3 = $l_uniObject1->concatenate($l_uniObject2);
my $l_unaObject = $l_uniObject->split($l_uniDelimiters, $l_inTrim);
my $l_uniObject = $l_unaObject->join($l_uniDelimiter, $l_inTrim);
my $l_strArrayref = $l_uniObject->from_subvalues($l_inLevel1, $l_inLevel2, $l_inLevel3);
$l_uniObject->to_subvalues($l_strArrayref, $l_inLevel1, $l_inLevel2, $l_inLevel3);
my $l_inCount = $l_uniObject->count_subvalues($l_inLevel1, $l_inLevel2, $l_inLevel3);
$l_uniObject->sort_subvalues($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inSort);
$l_inIndex = $l_uniObject->locate_subvalue($l_uniSubvalue, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
$l_uniSubvalue = $l_uniObject->extract_subvalue($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
$l_uniObject->replace_subvalue($l_uniSubvalue, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
$l_uniObject->insert_subvalue($l_uniSubvalue, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
$l_uniObject->append_subvalue($l_uniSubvalue, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
$l_uniObject->delete_subvalue($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
my $l_loCodepoint = $l_uniObject->get_codepoint($l_inOffset);
$l_uniObject->set_codepoint($l_inOffset, ord($l_strCodepoint));
my $l_inOffset = $l_uniObject->find_codepoint($l_loCodepoint, $l_inCount);
my $l_boFlag = $l_uniObject->isalnum_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isalpha_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->islower_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isupper_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isdigit_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isxdigit_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->iscntrl_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isgraph_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isspace_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isblank_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->isprint_codepoint($l_inOffset);
my $l_boFlag = $l_uniObject->ispunct_codepoint($l_inOffset);
my $l_loCodepoint = $l_uniObject->tolower_codepoint($l_inOffset);
my $l_loCodepoint = $l_uniObject->toupper_codepoint($l_inOffset);
my $l_inByteswritten = $l_uniObject->save($l_uniFile, $l_strEncoding);
my $l_inBytesread = $l_uniObject->load($l_uniFile, $l_strEncoding);
my $l_untObject = $l_uniObject->to_tesseract($l_inCodepoints, $l_inDim1, $l_inDim2, $l_inDim3, $l_inDim4);
my $l_uniObject = $l_untObject->from_tesseract();
$l_untObject->set_element($l_uniElement, $l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
my $l_uniElement = $l_untObject->get_element($l_inLevel1, $l_inLevel2, $l_inLevel3, $l_inLevel4);
=head2 PERL5 OVERLOADED OPERATORS
The following Perl5 overloaded operators work directly with B<< Unicode >> objects. This is only syntacic sugar, and due to the fact that they are Perl subroutines instead of C functions there is a bit of overhead when using them. But in some cases it makes sense for readability of the code. For example, using the concatentation operator B<< + >> if there are a lot of B<< Unicode >> objects can save a lot of typing instead of using the B<< contactenate() >> method. The comparison operators of Perl5 retain their meaning for number and string comparisons and can be useful if sorting arrays of B<< Unicode >> objects or testing values in a series of statements. It is advisable to use them where it makes the code more readable, but keep in mind the performance penalty they bring to the processing.
use overload
"=" => sub { my $class = ref($_[0]); $class->new($_[0]) },
"+" => sub { $_[0]->concatenate($_[1]) },
"<=>" => sub { $_[0]->compare_ascendingnumeric($_[1]) },
"==" => sub { $_[0]->compare_ascendingnumeric($_[1]) == 0 },
"!=" => sub { $_[0]->compare_ascendingnumeric($_[1]) != 0 },
"<" => sub { $_[0]->compare_ascendingnumeric($_[1]) < 0 },
"<=" => sub { $_[0]->compare_ascendingnumeric($_[1]) <= 0 },
">" => sub { $_[0]->compare_ascendingnumeric($_[1]) > 0 },
">=" => sub { $_[0]->compare_ascendingnumeric($_[1]) >= 0 },
"cmp" => sub { $_[0]->compare_ascendingstring($_[1]) },
"eq" => sub { $_[0]->compare_ascendingstring($_[1]) == 0 },
"ne" => sub { $_[0]->compare_ascendingstring($_[1]) != 0 },
"lt" => sub { $_[0]->compare_ascendingstring($_[1]) < 0 },
"le" => sub { $_[0]->compare_ascendingstring($_[1]) <= 0 },
"gt" => sub { $_[0]->compare_ascendingstring($_[1]) > 0 },
"ge" => sub { $_[0]->compare_ascendingstring($_[1]) >= 0 },
"fallback" => 1;
=head1 DESCRIPTION
This library brings B<< Unicode >> codepoint compliant string functions to Perl5 that can:
=over 4
=item * Construct and destruct B<< Unicode >>, B<< UnicodeArray >> and B<< UnicodeTesseract >> objects
=item * Get and set B<< Unicode >>, B<< UnicodeArray >> and B<< UnicodeTesseract >> object metadata
=item * Convert from/to C integral numeric types int, long and long long
=item * Convert from/to C floating point types float, double and long double
=item * Convert strings from/to any L<< iconv(3) >> supported encoding
=item * Count, copy, swap, append, find, extract and replace B<< Unicode >> codepoints
=item * Compare locale-aware B<< Unicode >> codepoints as strings
=item * Compare locale-aware B<< Unicode >> codepoints as numbers
=item * Convert B<< Unicode >> codepoints to uppercase, lowercase or swapcase
=item * Count, extract, replace, insert, append, delete, sort and locate delimited subvalues
=item * Extract or replace B<< Unicode >> subvalues using Perl5 dynamic arrays
=item * Get, set, determine character types and case-convert single codepoints
=item * File load/save B<< Unicode >> codepoints using any L<< iconv(3) >> supported encoding
=item * Separate virtual memory space support for big data that cannot fit on stack or heap
=back
=head2 DEPENDENCIES
This B<< Unicode >> library is generated using the L<< SWIG (Simple Wrapper Interface Generator)|http://www.swig.org >> software version 3.0.12 to generate the XS interface files used with Perl5. It is recommended that Perl versions 5.10 or later be used with this library. Earlier versions may work but have not been tested. It is also dependent on the GCC C compiler version 4.4 (or higher). Other than this, there are no other library dependencies. This library was developed and tested using Ubuntu 12.04/16.04 x86_64 GNU/Linux.
=head2 DOCUMENTATION
The B<< Doxygen >> documentation inside the F<< unicode.h >> header file is for the C struct (object) definitions. The B<< Doxygen >> documentation inside the F<< unicode.c >> C source code file is for the C functions as used in C/C++. The Perl5 B<< perldoc >> documentation inside the F<< testunicode.pl >> file is written using Perl's B<< POD >> format.
=head2 IMPLEMENTATION
Most functions are passed a pointer to a struct as their first parameter, normally referred to as an object. SWIG uses the first pointer to any imported C functions similar to how a I<< this >> pointer is used in C++ functions. Internally, Unicode strings are stored in an internal buffer in UTF32BE encoding. Each codepoint is represented internally as a wide character type I<< wchar_t >>. Since Perl5 does not support working directly with wide characters, there are conversion functions between B<< Unicode >> objects and Perl5 strings that are available. Any encoding supported by the operating system's L<< iconv(3) >> function can be imported or exported from a B<< Unicode >> object, not just UTF8 or ASCII.
=head3 C/C++ INTERFACE
Unicode library functions are written in C as standalone functions. Pointers to struct objects are passed as parameters, along with other non-pointer parameters. Functions provided to construct new objects include B<< Unicode_new() >>, B<< UnicodeArray_new() >> and B<< UnicodeTesseract_new() >>. Functions are provided to destruct old objects include B<< Unicode_delete() >>, B<< UnicodeArray_delete() >> and B<< UnicodeTesseract_delete() >>. All other Unicode library function names begin with the prefix B<< Unicode_ >>.
=head3 PERL5 INTERFACE
The mapped SWIG interface in Perl5 of the Unicode library uses an object-oriented syntax.
=head4 OBJECT CONSTRUCTORS AND DESTRUCTORS
To construct new objects in Perl5, class methods are used with the B<< Unicode:: >> package prefix. Object destructors are called automatically by Perl5 when the objects fall out of scope, however, it is also possible to delete the object manually using the L<< perlfunc/undef >> command.
=head4 OBJECT METHODS
All other Unicode functions are called as Perl5 object methods, and are mapped by SWIG into the B<< Unicode >> Perl5 package. The names of the object methods do not have the B<< Unicode:: >> prefix that class methods have nor the B<< Unicode_ >> prefix that C functions have. Object methods are called by appending the B<< -> >> operator to the object itself, like for example:
my $l_inByteswritten = $l_uniObject->save($l_uniFile, $l_strEncoding);
The first parameter in the C functions are pointers to a struct. SWIG uses this first parameter similarly to how a I<< this >> pointer is used in C++ functions. This means the first parameter passed to C functions is not passed as a parameter to the equivalent Perl5 object methods. An example follows.
=over 4
=item * C function call
char * l_poszEbcdic = Unicode_export_string(l_pouniObject, 0, "EBCDIC-US");
=item * Perl5 object method call
my $l_strEbcdic = $l_uniObject->export_string(0, 'EBCDIC-US');
=back
=head4 CHARACTER ENCODING
Internally, Unicode strings are stored in an internal buffer in UTF32BE encoding. Each codepoint is represented internally as a wide character type I<< wchar_t >>. Since Perl5 does not support working directly with wide characters, there are conversion functions between B<< Unicode >> objects and Perl5 strings that are available. Any encoding supported by the operating system's L<< iconv(3) >> function can be imported or exported from a B<< Unicode >> object, not just UTF8 or ASCII.
=head3 USING UTF8 IN PERL5
Perl scripts can often experience a large performance increase using these functions when working with B<< Unicode >> data. It is often helpful to include the following headers in your Perl script to get the most benefit from UTF8:
use strict;
use warnings;
use utf8; # allow UTF-8 in Perl script
use open qw(:std :utf8); # assume UTF-8 encoding in standard I/O
use locale; # import and use server locale information
use feature ':5.10'; # not tested with earlier versions
=head2 USING SWIG
Running SWIG and compiling the source code is really simple. A L<< sh(1) >> script can be created to re-generate the B<< Unicode >> library using SWIG and then using GCC to recompile the source code. Here is example script below. Note that it compiles in parallel for a faster response.
#!/bin/sh
# vim: fileencoding=utf8
swig -perl unicode.i
gcc -Wall -pipe -c `perl -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, "-I$Config{archlib}/CORE")'` unicode.c &
gcc -pipe -c `perl -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, "-I$Config{archlib}/CORE")'` unicode_wrap.c &
wait
g++ `perl -MConfig -e 'print $Config{lddlflags}'` unicode.o unicode_wrap.o -o Unicode.so
=cut
1;