Line data Source code
1 : /* File: io_xml_writer.inl; Copyright and License: see below */ 2 : 3 : #include <assert.h> 4 : #include "utf8stringbuf/utf8error.h" 5 : #include "utf8stringbuf/utf8codepoint.h" 6 : #include "utf8stringbuf/utf8codepointiterator.h" 7 : 8 15 : static inline u8_error_t io_xml_writer_write_plain ( io_xml_writer_t *this_, utf8string_t *text ) 9 : { 10 15 : assert ( UTF8STRING_NULL != text ); 11 : u8_error_t write_err; 12 : 13 15 : const size_t text_len = utf8string_get_length(text); 14 15 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_plain_table ); 15 15 : write_err = universal_escaping_output_stream_write ( &((*this_).esc_output), text, text_len ); 16 : 17 15 : return ( write_err ); 18 : } 19 : 20 : static inline u8_error_t io_xml_writer_write_plain_view ( io_xml_writer_t *this_, const utf8stringview_t *string_view ) 21 : { 22 : u8_error_t write_err; 23 : 24 : const size_t length = utf8stringview_get_length( string_view ); 25 : const char *const start = utf8stringview_get_start( string_view ); 26 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_plain_table ); 27 : write_err = universal_escaping_output_stream_write( &((*this_).esc_output), start, length ); 28 : 29 : return ( write_err ); 30 : } 31 : 32 8 : static inline u8_error_t io_xml_writer_write_xml_enc ( io_xml_writer_t *this_, utf8string_t *text ) 33 : { 34 8 : assert ( UTF8STRING_NULL != text ); 35 : u8_error_t write_err; 36 : 37 8 : const size_t text_len = utf8string_get_length(text); 38 8 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_encode_table ); 39 8 : write_err = universal_escaping_output_stream_write( &((*this_).esc_output), text, text_len ); 40 : 41 8 : return write_err; 42 : } 43 : 44 9 : static inline u8_error_t io_xml_writer_write_xml_enc_view ( io_xml_writer_t *this_, const utf8stringview_t *string_view ) 45 : { 46 : u8_error_t write_err; 47 : 48 9 : const size_t length = utf8stringview_get_length( string_view ); 49 9 : const char *const start = utf8stringview_get_start( string_view ); 50 9 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_encode_table ); 51 9 : write_err = universal_escaping_output_stream_write( &((*this_).esc_output), start, length ); 52 : 53 9 : return write_err; 54 : } 55 : 56 0 : static inline u8_error_t io_xml_writer_write_xml_comment ( io_xml_writer_t *this_, utf8string_t *text ) 57 : { 58 0 : assert ( UTF8STRING_NULL != text ); 59 : u8_error_t write_err; 60 : 61 0 : const size_t text_len = utf8string_get_length(text); 62 0 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_comments_encode_table ); 63 0 : write_err = universal_escaping_output_stream_write( &((*this_).esc_output), text, text_len ); 64 : 65 0 : return write_err; 66 : } 67 : 68 0 : static inline u8_error_t io_xml_writer_write_xml_comment_view ( io_xml_writer_t *this_, const utf8stringview_t *string_view ) 69 : { 70 : u8_error_t write_err; 71 : 72 0 : const size_t length = utf8stringview_get_length( string_view ); 73 0 : const char *const start = utf8stringview_get_start( string_view ); 74 0 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_comments_encode_table ); 75 0 : write_err = universal_escaping_output_stream_write( &((*this_).esc_output), start, length ); 76 : 77 0 : return write_err; 78 : } 79 : 80 0 : static inline bool io_xml_writer_contains_xml_tag_name_characters ( io_xml_writer_t *this_, const utf8stringview_t *string_view ) 81 : { 82 0 : bool result = false; 83 : 84 : utf8codepointiterator_t it; 85 0 : utf8codepointiterator_init( &it, string_view ); 86 0 : while( utf8codepointiterator_has_next( &it ) && ( ! result ) ) 87 : { 88 0 : utf8codepoint_t next = utf8codepointiterator_next( &it ); 89 0 : if ( io_xml_writer_private_is_xml_tag_name_character( this_, utf8codepoint_get_char( next ), true ) ) 90 : { 91 0 : result = true; 92 : } 93 : } 94 0 : utf8codepointiterator_destroy( &it ); 95 : 96 0 : return result; 97 : } 98 : 99 : static inline u8_error_t io_xml_writer_write_xml_tag_name_characters ( io_xml_writer_t *this_, const utf8stringview_t *string_view ) 100 : { 101 : u8_error_t result = U8_ERROR_NOT_FOUND; 102 : bool is_start = true; 103 : 104 : universal_escaping_output_stream_change_rules( &((*this_).esc_output), (*this_).xml_plain_table ); 105 : 106 : utf8codepointiterator_t it; 107 : utf8codepointiterator_init( &it, string_view ); 108 : while( utf8codepointiterator_has_next( &it ) ) 109 : { 110 : utf8codepoint_t next = utf8codepointiterator_next( &it ); 111 : if ( io_xml_writer_private_is_xml_tag_name_character( this_, utf8codepoint_get_char( next ), is_start ) ) 112 : { 113 : if ( is_start ) 114 : { 115 : is_start = false; 116 : result = U8_ERROR_NONE; 117 : } 118 : 119 : const utf8codepointseq_t text = utf8codepoint_get_utf8( next ); 120 : const unsigned int text_len = utf8codepoint_get_length( next ); 121 : result |= universal_escaping_output_stream_write ( &((*this_).esc_output), &(text.seq), text_len ); 122 : } 123 : } 124 : utf8codepointiterator_destroy( &it ); 125 : 126 : return result; 127 : } 128 : 129 0 : static inline void io_xml_writer_reset_indent ( io_xml_writer_t *this_ ) 130 : { 131 0 : (*this_).indent_level = 0; 132 0 : io_xml_writer_private_update_encoding_tables( this_ ); 133 0 : } 134 : 135 0 : static inline void io_xml_writer_increase_indent ( io_xml_writer_t *this_ ) 136 : { 137 0 : (*this_).indent_level++; 138 0 : io_xml_writer_private_update_encoding_tables( this_ ); 139 0 : } 140 : 141 0 : static inline void io_xml_writer_decrease_indent ( io_xml_writer_t *this_ ) 142 : { 143 0 : if ( (*this_).indent_level > 0 ) 144 : { 145 0 : (*this_).indent_level--; 146 0 : io_xml_writer_private_update_encoding_tables( this_ ); 147 : } 148 : else 149 : { 150 0 : assert(false); 151 : } 152 0 : } 153 : 154 0 : static inline bool io_xml_writer_private_is_xml_tag_name_character ( io_xml_writer_t *this_, uint32_t codepoint, bool start ) 155 : { 156 0 : bool result = false; 157 : 158 : result 159 0 : = (( codepoint >= 'A' )&&( codepoint <= 'Z' )) /* [A-Z] */ 160 0 : || ( codepoint == '_' ) /* _ */ 161 0 : || (( codepoint >= 'a' )&&( codepoint <= 'z' )) /* [a-z] */ 162 0 : || (( codepoint >= 0xC0 )&&( codepoint <= 0xD6 )) /* [#xC0-#xD6] */ 163 0 : || (( codepoint >= 0xD8 )&&( codepoint <= 0xF6 )) /* [#xD8-#xF6] */ 164 0 : || (( codepoint >= 0xF8 )&&( codepoint <= 0x2FF )) /* [#xF8-#x2FF] */ 165 0 : || (( codepoint >= 0x370 )&&( codepoint <= 0x37D )) /* [#x370-#x37D] */ 166 0 : || (( codepoint >= 0x37F )&&( codepoint <= 0x1FFF )) /* [#x37F-#x1FFF] */ 167 0 : || (( codepoint >= 0x200C )&&( codepoint <= 0x200D )) /* [#x200C-#x200D] */ 168 0 : || (( codepoint >= 0x2070 )&&( codepoint <= 0x218F )) /* [#x2070-#x218F] */ 169 0 : || (( codepoint >= 0x2C00 )&&( codepoint <= 0x2FEF )) /* [#x2C00-#x2FEF] */ 170 0 : || (( codepoint >= 0x3001 )&&( codepoint <= 0xD7FF )) /* [#x3001-#xD7FF] */ 171 0 : || (( codepoint >= 0xF900 )&&( codepoint <= 0xFDCF )) /* [#xF900-#xFDCF] */ 172 0 : || (( codepoint >= 0xFDF0 )&&( codepoint <= 0xFFFD )) /* [#xFDF0-#xFFFD] */ 173 0 : || (( codepoint >= 0x10000 )&&( codepoint <= 0xEFFFF )); /* [#x10000-#xEFFFF] */ 174 : 175 0 : if (( ! result )&&( ! start )) 176 : { 177 : /* after name start, more characters are allowed: */ 178 : result 179 0 : = ( codepoint == '-' ) /* - */ 180 0 : || ( codepoint == '.' ) /* . */ 181 0 : || (( codepoint >= '0' )&&( codepoint <= '9' )) /* [0-9] */ 182 0 : || ( codepoint == 0xB7 ) /* xB7 */ 183 0 : || (( codepoint >= 0x0300 )&&( codepoint <= 0x036F )) /* [#x0300-#x036F] */ 184 0 : || (( codepoint >= 0x203F )&&( codepoint <= 0x2040 )); /* [#x203F-#x2040] */ 185 : } 186 : 187 0 : return result; 188 : } 189 : 190 : 191 : /* 192 : Copyright 2019-2024 Andreas Warnke 193 : 194 : Licensed under the Apache License, Version 2.0 (the "License"); 195 : you may not use this file except in compliance with the License. 196 : You may obtain a copy of the License at 197 : 198 : http://www.apache.org/licenses/LICENSE-2.0 199 : 200 : Unless required by applicable law or agreed to in writing, software 201 : distributed under the License is distributed on an "AS IS" BASIS, 202 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 203 : See the License for the specific language governing permissions and 204 : limitations under the License. 205 : */