2009 Aug 10 9:52 AM
Hello all,
in my utf-16 little endian system (unicode system, 4103 system code page), I have this little program which dumps at the ASSIGN statement (exception ASSIGN_BASE_WRONG_ALIGNMENT). For information, I made sure that the program has the unicode check property active (in case there would be some bug around that).
Maybe it's a kernel problem, I use Linux x86_64.
Could you check this code, and if it works for you, could you please tell your kernel + your system code page (via SNLS transaction).
DATA x1 type x length 4.
field-symbols <c> type c.
x1 = '41004100'. "AA in utf-16 little endian
assign x1(4) to <c> casting. "<--- DUMP
write <c>.
The dump says:
In the current program, an error occurred when setting the field symbol "<C>" with ASSIGN or ASSIGNING (maybe in the combination with the CASTING addition).
When converting the base entry of the field symbol "<C>" (number in base table: 13), it was found that the target type requests a memory alignment of 2.
However, the source data object has an invalid memory alignment, that is an alignment not divisible by 2.
You may be able to avoid the error by using a different offset. The following must apply: Offset = n * 2, n >= 0
I forgot to say that I checked SAP notes and none corresponds to that issue; they only explain the general problems of alignment which is not the case here (I guess) <-- Added by: Sandra Rossi on Aug 10, 2009 11:08 AM
2009 Aug 10 10:20 AM
I Ran this code snippet and did not get any Dump. O/P was A#A#(Looks like not appropriate Code page as well)
Database codepage 1100
Current Codepage of Appl. Server 1100
Codepage of Front End 1160
Kernal :700_REL
Hello all,
in my utf-16 little endian system (unicode system, 4103 system code page), I have this little program which dumps at the ASSIGN statement (exception ASSIGN_BASE_WRONG_ALIGNMENT). For information, I made sure that the program has the unicode check property active (in case there would be some bug around that).
Maybe it's a kernel problem, I use Linux x86_64.
Could you check this code, and if it works for you, could you please tell your kernel + your system code page (via SNLS transaction).
DATA x1 type x length 4.
field-symbols <c> type c.
x1 = '41004100'. "AA in utf-16 little endian
assign x1(4) to <c> casting. "<--- DUMP
write <c>.
The dump says:
In the current program, an error occurred when setting the field symbol "<C>" with ASSIGN or ASSIGNING (maybe in the combination with the CASTING addition).
When converting the base entry of the field symbol "<C>" (number in base table: 13), it was found that the target type requests a memory alignment of 2.
However, the source data object has an invalid memory alignment, that is an alignment not divisible by 2.
You may be able to avoid the error by using a different offset. The following must apply: Offset = n * 2, n >= 0
I forgot to say that I checked SAP notes and none corresponds to that issue; they only explain the general problems of alignment which is not the case here (I guess) <-- Added by: Sandra Rossi on Aug 10, 2009 11:08 AM
2009 Aug 10 10:20 AM
I Ran this code snippet and did not get any Dump. O/P was A#A#(Looks like not appropriate Code page as well)
Database codepage 1100
Current Codepage of Appl. Server 1100
Codepage of Front End 1160
Kernal :700_REL
2009 Aug 10 10:36 AM
thank you Amit and Max.
What operating systems do you use (windows 32/64, linux, unix...), and do you think it could be a bug in the sap kernel, or is there an easy workaround? (I made a "little" routine as a workaround which is not so simple!)
2009 Aug 10 11:03 AM
2009 Aug 10 11:43 AM
Yes. These notes just point out casting and alignment issues in "old" releases (*), and I feel I understand everything that is mentioned. But in the case of X to C, there shouldn't be any alignment issue (I made sure to have an X length which is a multiple of 4 bytes, the widest character size possible).
(*) I forgot to say my SAP system is 7.0 SP 13, and sap kernel is 700 Linux GNU SLES-9 patch 179.
2009 Aug 18 11:00 AM
Here I just share my "little" generic routine to cast from X (or xstring) to C (string, N... or any other character-type data). I would be happy if someone could share a simplest way to do the same (I close this thread but don't hesitate to answer this last question ). After this routine, there is a demo.
*----------------------------------------------------------------------*
FORM cast_copy_xstring_to_string
USING
i_xsequence TYPE xsequence
i_ignore_size_error TYPE flag
CHANGING
e_string TYPE clike
e_xstring_size_error TYPE flag.
CONSTANTS con_xbuffer_size TYPE i VALUE 10000. "large buffer, max 65535, multiple of charsize
DATA l_xbuffer TYPE x LENGTH con_xbuffer_size.
FIELD-SYMBOLS <l_c> TYPE c.
DATA l_xsequence_len TYPE i.
DATA l_xsequence_type TYPE c.
DATA l_pos TYPE i.
DATA l_len TYPE i.
DATA l_temp TYPE i.
CLEAR e_string.
CLEAR e_xstring_size_error.
* make sure the buffer size is a multiple of charsize
l_temp = con_xbuffer_size MOD cl_abap_char_utilities=>charsize.
ASSERT l_temp = 0 AND con_xbuffer_size >= cl_abap_char_utilities=>charsize.
l_pos = 0.
DESCRIBE FIELD i_xsequence TYPE l_xsequence_type LENGTH l_xsequence_len IN BYTE MODE.
IF l_xsequence_type = cl_abap_typedescr=>TYPEKIND_XSTRING.
l_xsequence_len = XSTRLEN( I_xsequence ). "before 6.10, use STRLEN
ENDIF.
l_temp = l_xsequence_len MOD cl_abap_char_utilities=>charsize.
IF l_temp <> 0 AND i_ignore_size_error IS INITIAL.
e_xstring_size_error = 'X'.
ELSE.
l_len = con_xbuffer_size.
DO.
IF l_pos >= l_xsequence_len.
EXIT.
ENDIF.
l_temp = l_pos + con_xbuffer_size.
IF l_temp >= l_xsequence_len.
* last bytes
l_len = l_xsequence_len - l_pos.
l_xbuffer = i_xsequence+l_pos(l_len).
* Adjust length on the last bytes in case the input x size does not fit character size
IF i_ignore_size_error IS NOT INITIAL.
l_len = ( l_len / cl_abap_char_utilities=>charsize ) * cl_abap_char_utilities=>charsize.
ENDIF.
ELSE.
l_xbuffer = i_xsequence+l_pos(l_len).
ENDIF.
ASSIGN l_xbuffer(l_len) TO <l_c> CASTING.
CONCATENATE e_string <l_c> INTO e_string.
ADD con_xbuffer_size TO l_pos.
ENDDO.
ENDIF.
ENDFORM.
2009 Aug 18 11:00 AM
I forgot the demo part:
DATA l_string TYPE string.
DATA l_error TYPE flag.
IF cl_i18n_search_utils=>system_codepage( ) = '1100'. "iso-8859-1
PERFORM cast_copy_xstring_to_string USING '41424344' '' CHANGING l_string l_error.
ASSERT l_error IS INITIAL AND l_string = 'ABCD'.
ELSEIF cl_i18n_search_utils=>system_codepage( ) = '4103'. "utf16-le
PERFORM cast_copy_xstring_to_string USING '4100420043004400' '' CHANGING l_string l_error.
ASSERT l_error IS INITIAL AND l_string = 'ABCD'.
PERFORM cast_copy_xstring_to_string USING '41004200430044' '' CHANGING l_string l_error.
ASSERT l_error = 'X'.
PERFORM cast_copy_xstring_to_string USING '41004200430044' 'X' CHANGING l_string l_error.
ASSERT l_error IS INITIAL AND l_string = 'ABCD'.
ENDIF.
2009 Oct 05 10:37 AM
More simple version of the routine above. It assumes the input X or XSTRING is a valid string of characters in the system encoding (codepage), so that to simplify the code (I removed the 2 error parameters). It is based on the fact that the conversion classes do not convert bytes if the input and output encodings (i.e. codepages) are the same.
FORM cast_copy_xstring_to_string
USING
i_xsequence TYPE xsequence
CHANGING
e_string TYPE clike.
DATA enc TYPE abap_encod.
DATA conv TYPE REF TO cl_abap_conv_in_ce.
enc = cl_i18n_search_utils=>system_codepage( ).
conv = cl_abap_conv_in_ce=>create( ENCODING = enc ).
conv->convert(
EXPORTING INPUT = i_xsequence
IMPORTING DATA = e_string ).
ENDFORM.
2009 Aug 10 10:20 AM
| User | Count |
|---|---|
| 3 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |