1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: dk4strmo32.ctr
12 */
13 
14 /**	@file dk4strmo32.c The dk4strmo32 module.
15 */
16 
17 
18 #include "dk4conf.h"
19 #include <libdk4c/dk4strmo32.h>
20 #include <libdk4base/dk4mem.h>
21 #include <libdk4c/dk4ansi.h>
22 #include <libdk4c/dk4utf8.h>
23 #include <libdk4c/dk4utf16.h>
24 #include <libdk4c/dk4enc.h>
25 #include <libdk4c/dk4rec26.h>
26 
27 #if DK4_HAVE_ASSERT_H
28 #ifndef	ASSERT_H_INCLUDED
29 #include <assert.h>
30 #define	ASSERT_H_INCLUDED 1
31 #endif
32 #endif
33 
34 
35 
36 
37 
38 
39 void
dk4stream_set_output_encoding(dk4_stream_t * strm,int oe)40 dk4stream_set_output_encoding(dk4_stream_t *strm, int oe)
41 {
42 
43 #if	DK4_USE_ASSERT
44   assert(NULL != strm);
45 #endif
46   if (NULL != strm) {
47     switch (oe) {
48       case DK4_FILE_ENCODING_PLAIN:
49       case DK4_FILE_ENCODING_WIN1252:
50       case DK4_FILE_ENCODING_UTF8:
51       case DK4_FILE_ENCODING_UTF16_LE:
52       case DK4_FILE_ENCODING_UTF16_BE:
53       case DK4_FILE_ENCODING_32_LE:
54       case DK4_FILE_ENCODING_32_BE:
55       {
56         strm->oenc = oe;
57       } break;
58     }
59   }
60 }
61 
62 
63 
64 int
dk4stream_c32_putc(dk4_stream_t * strm,dk4_c32_t c32,dk4_er_t * erp)65 dk4stream_c32_putc(dk4_stream_t *strm, dk4_c32_t c32, dk4_er_t *erp)
66 {
67   unsigned char	buf[16];
68   dk4_c16_t	b16[4];
69   size_t	sz;
70   int		back	=	0;
71 
72 #if	DK4_USE_ASSERT
73   assert(NULL != strm);
74 #endif
75   if (NULL != strm) {
76     if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
77       switch (strm->oenc) {
78         case DK4_FILE_ENCODING_PLAIN: {
79 	  if (dkC32(0x00000100) > c32) {
80 	    back = dk4stream_write_byte(strm, (char)c32, erp);
81 	  } else {
82             dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
83 	  }
84 	} break;
85         case DK4_FILE_ENCODING_WIN1252: {
86 	  if (0 != dk4ansi_encode(buf, c32)) {
87 	    back = dk4stream_write_byte(strm, (char)(buf[0]), erp);
88 	  } else {
89 	    dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
90 	  }
91 	} break;
92         case DK4_FILE_ENCODING_UTF8: {
93 	  sz = sizeof(buf);
94 	  if (0 != dk4utf8_encode(buf, &sz, c32, NULL)) {
95 	    back = dk4stream_write(strm, (void *)buf, sz, erp);
96 	  } else {
97 	    dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
98 	  }
99 	} break;
100         case DK4_FILE_ENCODING_UTF16_LE: {
101 	  sz = DK4_SIZEOF(b16,dk4_c16_t);
102 	  if (0 != dk4utf16_encode(b16, &sz, c32, erp)) {
103 	    if ((1 == sz) || (2 == sz)) {
104 	      buf[0] = (unsigned char)( b16[0]       & 0x00FF);
105 	      buf[1] = (unsigned char)((b16[0] >> 8) & 0x00FF);
106 	      if (2 == sz) {
107 	        buf[2] = (unsigned char)( b16[1]       & 0x00FF);
108 		buf[3] = (unsigned char)((b16[1] >> 8) & 0x00FF);
109 
110 		back = dk4stream_write(strm, (void *)buf, 4, erp);
111 	      } else {
112 
113 	        back = dk4stream_write(strm, (void *)buf, 2, erp);
114 	      }
115 	    } else {
116 	      dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
117 	    }
118 	  } else {
119 	    dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
120 	  }
121 	} break;
122         case DK4_FILE_ENCODING_UTF16_BE: {
123 	  sz = DK4_SIZEOF(b16,dk4_c16_t);
124 	  if (0 != dk4utf16_encode(b16, &sz, c32, erp)) {
125 	    if ((1 == sz) || (2 == sz)) {
126 	      buf[1] = (unsigned char)( b16[0]       & 0x00FF);
127 	      buf[0] = (unsigned char)((b16[0] >> 8) & 0x00FF);
128 	      if (2 == sz) {
129 	        buf[3] = (unsigned char)( b16[1]       & 0x00FF);
130 		buf[2] = (unsigned char)((b16[1] >> 8) & 0x00FF);
131 		back = dk4stream_write(strm, (void *)buf, 4, erp);
132 	      } else {
133 	        back = dk4stream_write(strm, (void *)buf, 2, erp);
134 	      }
135 	    } else {
136 	      dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
137 	    }
138 	  } else {
139 	    dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
140 	  }
141 	} break;
142         case DK4_FILE_ENCODING_32_LE: {
143 	  buf[0] = (unsigned char)( c32        & dkC32(0x000000FF));
144 	  buf[1] = (unsigned char)((c32 >>  8) & dkC32(0x000000FF));
145 	  buf[2] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
146 	  buf[3] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
147 	  back   = dk4stream_write(strm, (void *)buf, 4, erp);
148 	} break;
149         case DK4_FILE_ENCODING_32_BE: {
150 	  buf[3] = (unsigned char)( c32        & dkC32(0x000000FF));
151 	  buf[2] = (unsigned char)((c32 >>  8) & dkC32(0x000000FF));
152 	  buf[1] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
153 	  buf[0] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
154 	  back   = dk4stream_write(strm, (void *)buf, 4, erp);
155 	} break;
156 	default: {
157 	  dk4error_set_simple_error_code(erp, DK4_E_BUG);
158 	} break;
159       }
160     } else{
161       dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
162     }
163   } else {
164     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
165   }
166   return back;
167 }
168 
169 
170 
171 int
dk4stream_c32_puts(dk4_stream_t * strm,const dk4_c32_t * txt,dk4_er_t * erp)172 dk4stream_c32_puts(dk4_stream_t *strm, const dk4_c32_t *txt, dk4_er_t *erp)
173 {
174   int		 back = 0;
175 #if	DK4_USE_ASSERT
176   assert(NULL != strm);
177   assert(NULL != txt);
178 #endif
179   if ((NULL != strm) && (NULL != txt)) {
180     if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
181       back = 1;
182       while ((dkC32(0) != *txt) && (1 == back)) {
183         if (0 == dk4stream_c32_putc(strm, *(txt++), erp)) {
184 	  back = 0;
185 	}
186       }
187     } else {
188       dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
189     }
190   } else {
191     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
192   }
193   return back;
194 }
195 
196 
197 
198 int
dk4stream_write_bom_if_necessary(dk4_stream_t * strm,dk4_er_t * erp)199 dk4stream_write_bom_if_necessary(dk4_stream_t *strm, dk4_er_t *erp)
200 {
201   int		 back = 0;
202 
203 #if	DK4_USE_ASSERT
204   assert(NULL != strm);
205 #endif
206   if (NULL != strm) {
207     if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
208       switch (strm->oenc) {
209 #if VERSION_BEFORE_20141218
210 	/*	For UTF-8 files most text editors do not handle
211 		the BOM correctly, they show a glyph for unrepresentable
212 		characters.
213 		So I decided to write a BOM only for 16 bit and 32 bit
214 		character output.
215 	*/
216         case DK4_FILE_ENCODING_UTF8:
217 #endif
218         case DK4_FILE_ENCODING_UTF16_LE:
219         case DK4_FILE_ENCODING_UTF16_BE:
220         case DK4_FILE_ENCODING_32_LE:
221         case DK4_FILE_ENCODING_32_BE:
222 	{
223 	  back = dk4stream_c32_putc(strm, dkC32(0x0000FEFF), erp);
224 	} break;
225 	default: {
226 	  back = 1;
227 	} break;
228       }
229     } else {
230       dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
231     }
232   } else {
233     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
234   }
235   return back;
236 }
237 
238 
239