Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10618 - (show annotations) (download) (as text)
Fri Mar 3 15:15:16 2023 UTC (13 months, 1 week ago) by zmatsuo
File MIME type: text/x-csrc
File size: 12715 byte(s)
ttxsshで tttset.UIMsg[] ではなく TInstVar.UIMsg[] を使用するよう修正

- lng(i18n)用文字列領域
- ttxssh 以外は tttset.UIMsg[] を使用しなくなった
  - Unicode(wchar_t)版動的な文字列取得に切り替えた
  - tttset.UIMsg[] は ANSI(char) 文字列
- プラグイン用ワーク内に TInstVar.UIMsg[] を新設した
1 /*
2 * Copyright (c) 1998-2001, Robert O'Callahan
3 * (C) 2004- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 This code is copyright (C) 1998-1999 Robert O'Callahan.
32 See LICENSE.TXT for the license.
33 */
34
35 #include "ttxssh.h"
36 #include "codeconv.h"
37
38 void UTIL_init_sock_write_buf(UTILSockWriteBuf *buf)
39 {
40 buf_create(&buf->bufdata, &buf->buflen);
41 buf->datastart = 0;
42 buf->datalen = 0;
43 }
44
45 static int send_until_block(PTInstVar pvar, SOCKET s,
46 const char *data, int len)
47 {
48 int total_sent = 0;
49
50 while (len > 0) {
51 int sent_amount = (pvar->Psend) (s, data, len, 0);
52
53 if (sent_amount < 0) {
54 if (WSAGetLastError() == WSAEWOULDBLOCK) {
55 return total_sent;
56 } else {
57 return sent_amount;
58 }
59 } else {
60 total_sent += sent_amount;
61 data += sent_amount;
62 len -= sent_amount;
63 }
64 }
65
66 return total_sent;
67 }
68
69 /* Tera Term��������������PC���� X �T�[�o�v���O�������������A�f�[�^�������B
70 * ���x�����������������A�����O�o�b�t�@���i�[���A�x���z�������B
71 *
72 * �����t���[�����L�������B
73 * (1) �������f�[�^�������B���������A�����O�o�b�t�@�����B
74 * (2) non-blocking�����M���������B�S���M��������return�B
75 * (3) ���M�������������f�[�^�������O�o�b�t�@���i�[���Areturn�B
76 * (4) �����f�[�^�������B
77 * (5) �����O�o�b�t�@���i�[���Areturn�B
78 * (6) �����f�[�^�������B
79 * (7) �����O�o�b�t�@���t�������������A�o�b�t�@���c���������f�[�^�� blocking �����M���������B
80 * ���M���s�������A�G���[return�B
81 * (8) ���[�U�f�[�^(data/len)�����M�� blocking �����M���������B
82 * ���M���s�������A�G���[return�B
83 * (9) ���M���������������[�U�f�[�^�������O�o�b�t�@���i�[���Areturn�B
84 * (10) �����O�o�b�t�@���c���������f�[�^�� non-blocking�����M���������B
85 *
86 * pvar: ���L���\�[�X
87 * buf: �����O�o�b�t�@
88 * blocking_write: �����^���p�P�b�g���M����
89 * socket: �������^���\�P�b�g�n���h��
90 * data: �f�[�^
91 * len: �f�[�^��
92 *
93 * return TRUE: ���M����
94 * FALSE: ���M�G���[
95 */
96 BOOL UTIL_sock_buffered_write(PTInstVar pvar, UTILSockWriteBuf *buf,
97 UTILBlockingWriteCallback blocking_write,
98 SOCKET socket, const char *data,
99 int len)
100 {
101 int curlen;
102 int desiredlen;
103 int space_required;
104 int amount_to_write_from_buffer;
105 BOOL did_block = FALSE;
106 int first_copy_start;
107 int first_copy_amount;
108
109 // ���������o�������A�����������L if ���������B
110 /* Fast path case: buffer is empty, try nonblocking write */
111 if (buf->datalen == 0) {
112 #if 1
113 // ������ non-blocking ���p�P�b�g���M�����B���x���� WSAEWOULDBLOCK �G���[�����������A
114 // �������u���M�����f�[�^���v�������B
115 // ���������AX �T�[�o�v���O����������"xterm"���N���������������Axterm���[����������
116 // �������\���������������������A�[�����E�B���h�E���h���b�O�������A������ 0 �������������B
117 int sent_amount = send_until_block(pvar, socket, data, len);
118
119 if (sent_amount < 0) {
120 return FALSE;
121 }
122 data += sent_amount;
123 len -= sent_amount;
124 #else
125 // �m���u���b�L���O���[�h�������������������A���~���������������A�o�O�����������A
126 // �����������������B�������A�������u���b�L���O���[�h���g���A�m�������M�����������B
127 // �|�[�g�]��(local-to-remote)���������A�������p�P�b�g�����M���������������������B
128 // (2007.11.29 yutaka)
129 // �I���W�i���R�[�h���o�O���������v�����������ASSH�x�����M�����������������������A
130 // ���������{�����������A�I���W�i���R�[�h���������������������l�����B
131 // �{�����m���u���b�L���O�������������������A���������u���b�L���O�����������������A
132 // Tera Term���u���������v�AXming���uCPU�X�g�[���v�������s���v�c���������o��������
133 // �������������B���������A�{�����R�[�h���������������f�����B
134 // (2012.10.14 yutaka)
135 if (!blocking_write(pvar, socket, data, len)) {
136 return FALSE;
137 } else {
138 len = 0;
139 }
140 #endif
141 }
142
143 // ���������o������ non-blocking ���M���A�������������������A�����������������B
144 if (len == 0) {
145 return TRUE;
146 }
147
148 // �����O�o�b�t�@(buf)���c�����������f�[�^���A�V�K���M�f�[�^��������(desiredlen)�A
149 // �������o�b�t�@��(curlen)�������������v�Z�����B
150 //
151 // (1)�f�[�^���������i�[�����������P�[�X
152 //
153 // <----- buflen ------------->
154 // buf->bufdata -> +--------------------------+
155 // |XXXXXXX |
156 // +--------------------------+
157 // <------>
158 // buf->datalen
159 // ^
160 // |
161 // buf->datastart
162 //
163 //
164 // (2)�f�[�^�����[���i�[�����������P�[�X
165 //
166 // <----- buflen ------------->
167 // buf->bufdata -> +--------------------------+
168 // |XXXX XXXX|
169 // +--------------------------+
170 // <---> <-->
171 // (a) (b)
172 // (a)+(b) = buf->datalen
173 // ^
174 // |
175 // buf->datastart
176 //
177 /* We blocked or the buffer has data in it. We need to put this data
178 into the buffer.
179 First, expand buffer as much as possible and necessary. */
180 curlen = buf->buflen;
181 desiredlen =
182 min(pvar->session_settings.WriteBufferSize, buf->datalen + len);
183
184 if (curlen < desiredlen) {
185 int wrap_amount = buf->datastart + buf->datalen - curlen;
186 int newlen =
187 min(pvar->session_settings.WriteBufferSize, 2 * desiredlen);
188
189 buf->bufdata = realloc(buf->bufdata, newlen);
190 buf->buflen = newlen;
191
192 if (wrap_amount > 0) {
193 int wrap_to_copy = min(wrap_amount, newlen - curlen);
194
195 memmove(buf->bufdata + curlen, buf->bufdata, wrap_to_copy);
196 memmove(buf->bufdata, buf->bufdata + wrap_to_copy,
197 wrap_amount - wrap_to_copy);
198 }
199 }
200
201 /* 1) Write data from buffer
202 2) Write data from user
203 3) Copy remaining user data into buffer
204 */
205 // �o�b�t�@�����������������A�V�����f�[�^(data)�������������� space_required �����������B
206 // ���������Aspace_required���u���������v���\���B
207 //
208 // space_required
209 // <----- buflen -------------><-------->
210 // buf->bufdata -> +--------------------------+
211 // |XXXXXXXXXXXXXXXXX |
212 // +--------------------------+
213 // <----------------><------------------>
214 // buf->datalen len
215 // ^
216 // |
217 // buf->datastart
218 space_required = max(0, buf->datalen + len - buf->buflen);
219 amount_to_write_from_buffer = min(buf->datalen, space_required);
220
221 if (amount_to_write_from_buffer > 0) {
222 int first_part =
223 min(amount_to_write_from_buffer, buf->buflen - buf->datastart);
224
225 did_block = TRUE;
226 if (!blocking_write
227 (pvar, socket, buf->bufdata + buf->datastart, first_part)) {
228 return FALSE;
229 }
230 if (first_part < amount_to_write_from_buffer) {
231 if (!blocking_write
232 (pvar, socket, buf->bufdata,
233 amount_to_write_from_buffer - first_part)) {
234 return FALSE;
235 }
236 }
237
238 buf->datalen -= amount_to_write_from_buffer;
239 if (buf->datalen == 0) {
240 buf->datastart = 0;
241 } else {
242 buf->datastart =
243 (buf->datastart +
244 amount_to_write_from_buffer) % buf->buflen;
245 }
246 space_required -= amount_to_write_from_buffer;
247 }
248
249 if (space_required > 0) {
250 did_block = TRUE;
251 if (!blocking_write(pvar, socket, data, space_required)) {
252 return FALSE;
253 }
254 data += space_required;
255 len -= space_required;
256 }
257
258 first_copy_start = (buf->datastart + buf->datalen) % buf->buflen;
259 first_copy_amount = min(len, buf->buflen - first_copy_start);
260 memcpy(buf->bufdata + first_copy_start, data, first_copy_amount);
261 if (first_copy_amount < len) {
262 memcpy(buf->bufdata, data + first_copy_amount,
263 len - first_copy_amount);
264 }
265 buf->datalen += len;
266
267 if (did_block) {
268 return UTIL_sock_write_more(pvar, buf, socket);
269 } else {
270 return TRUE;
271 }
272 }
273
274 BOOL UTIL_sock_write_more(PTInstVar pvar, UTILSockWriteBuf *buf,
275 SOCKET socket)
276 {
277 int first_amount = min(buf->buflen - buf->datastart, buf->datalen);
278 int sent =
279 send_until_block(pvar, socket, buf->bufdata + buf->datastart,
280 first_amount);
281
282 if (sent < 0) {
283 return FALSE;
284 } else {
285 if (sent == first_amount && first_amount < buf->datalen) {
286 int sentmore =
287 send_until_block(pvar, socket, buf->bufdata,
288 buf->datalen - first_amount);
289
290 if (sentmore < 0) {
291 return FALSE;
292 }
293 sent += sentmore;
294 }
295
296 buf->datalen -= sent;
297 if (buf->datalen == 0) {
298 buf->datastart = 0;
299 } else {
300 buf->datastart = (buf->datastart + sent) % buf->buflen;
301 }
302 }
303
304 return TRUE;
305 }
306
307 void UTIL_destroy_sock_write_buf(UTILSockWriteBuf *buf)
308 {
309 SecureZeroMemory(buf->bufdata, buf->buflen);
310 buf_destroy(&buf->bufdata, &buf->buflen);
311 }
312
313 BOOL UTIL_is_sock_deeply_buffered(UTILSockWriteBuf *buf)
314 {
315 return buf->buflen / 2 < buf->datalen;
316 }
317
318 void UTIL_get_lang_msg(const char *key, PTInstVar pvar, const char *def)
319 {
320 wchar_t *defW = ToWcharA(def);
321 wchar_t *strW;
322 GetI18nStrWW("TTSSH", key, defW, pvar->ts->UILanguageFileW, &strW);
323 WideCharToACP_t(strW, pvar->UIMsg, sizeof(pvar->UIMsg));
324 free(strW);
325 free(defW);
326 }
327
328 void UTIL_get_lang_msgU8(const char *key, PTInstVar pvar, const char *def)
329 {
330 const wchar_t *UILanguageFileW = pvar->ts->UILanguageFileW;
331 char *strU8;
332 GetI18nStrU8W("TTSSH", key, def, UILanguageFileW, &strU8);
333 strcpy_s(pvar->UIMsg, MAX_UIMSG, strU8);
334 free(strU8);
335 }
336
337 void UTIL_get_lang_msgW(const char *key, PTInstVar pvar, const wchar_t *def, wchar_t *UIMsg)
338 {
339 const wchar_t *UILanguageFileW = pvar->ts->UILanguageFileW;
340 wchar_t *strW;
341 GetI18nStrWW("TTSSH", key, def, UILanguageFileW, &strW);
342 wcscpy_s(UIMsg, MAX_UIMSG, strW);
343 free(strW);
344 }
345
346 /*
347 * �����t�H���g������
348 * @retval �t�H���g�n���h��
349 * @retval NULL(�G���[)
350 */
351 HFONT UTIL_get_lang_fixedfont(HWND hWnd, const wchar_t *UILanguageFile)
352 {
353 HFONT hFont;
354 LOGFONTW logfont;
355 int dpi = GetMonitorDpiFromWindow(hWnd);
356 BOOL result = GetI18nLogfontW(L"TTSSH", L"DLG_ABOUT_FONT", &logfont,
357 dpi, UILanguageFile);
358 if (result == FALSE) {
359 // ���������������������������t�H���g���w�������B
360 // �G�f�B�b�g�R���g���[�����_�C�A���O�������t�H���g������������
361 // �����t�H���g�������������B
362
363 // �E�B���h�E(�_�C�A���O)���t�H���g�������A�t�H���g�����Q������
364 HFONT hFontDlg;
365 LOGFONTW logfontDlg;
366 hFontDlg = (HFONT)SendMessage(hWnd, WM_GETFONT, (WPARAM)0, (LPARAM)0);
367 GetObject(hFontDlg, sizeof(logfontDlg), &logfontDlg);
368
369 memset(&logfont, 0, sizeof(logfont));
370 wcsncpy_s(logfont.lfFaceName, _countof(logfont.lfFaceName), L"Courier New", _TRUNCATE);
371 logfont.lfCharSet = ANSI_CHARSET; // = 0
372 logfont.lfHeight = logfontDlg.lfHeight;
373 logfont.lfWidth = 0;
374 }
375 hFont = CreateFontIndirectW(&logfont); // �G���[�� NULL
376 #if 1
377 if (hFont == NULL) {
378 // �t�H���g���������������������� stock object ���g�p����
379 // DeleteObject() ������ok������
380 // It is not necessary (but it is not harmful) to
381 // delete stock objects by calling DeleteObject.
382 hFont = GetStockObject(ANSI_FIXED_FONT);
383 }
384 #endif
385 return hFont;
386 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26