1 /* $NetBSD: fileio.c,v 1.10 2024/12/23 02:58:03 blymn Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef LIBHACK 33 #include <sys/cdefs.h> 34 #ifndef lint 35 __RCSID("$NetBSD: fileio.c,v 1.10 2024/12/23 02:58:03 blymn Exp $"); 36 #endif /* not lint */ 37 38 #include "curses.h" 39 #include "curses_private.h" 40 #include "fileio.h" 41 #include <stdio.h> 42 #include <stdlib.h> 43 44 #ifdef HAVE_WCHAR 45 static int __putnsp(nschar_t *, FILE *); 46 static int __getnsp(nschar_t *, FILE *); 47 #endif /* HAVE_WCHAR */ 48 49 #ifdef HAVE_WCHAR 50 /* 51 * __putnsp -- 52 * Write non-spacing character chain to file, consisting of: 53 * ((int) 1, (wchar_t) ch) pairs followed by (int) 0. 54 */ 55 static int 56 __putnsp(nschar_t *nsp, FILE *fp) 57 { 58 int n; 59 60 n = 1; 61 while (nsp != NULL) { 62 if (fwrite(&n, sizeof(int), 1, fp) != 1) 63 return ERR; 64 if (fwrite(&nsp->ch, sizeof(wchar_t), 1, fp) != 1) 65 return ERR; 66 } 67 n = 0; 68 if (fwrite(&n, sizeof(int), 1, fp) != 1) 69 return ERR; 70 71 return OK; 72 } 73 #endif /* HAVE_WCHAR */ 74 75 /* 76 * putwin -- 77 * Write window data to file 78 */ 79 int 80 putwin(WINDOW *win, FILE *fp) 81 { 82 int major = CURSES_LIB_MAJOR; 83 int minor = CURSES_LIB_MINOR; 84 int y, x; 85 __LDATA *sp; 86 87 __CTRACE(__CTRACE_FILEIO, "putwin: win %p\n", win); 88 89 if (__predict_false(win == NULL)) 90 return ERR; 91 92 /* win can't be a subwin */ 93 if (win->orig != NULL) 94 return ERR; 95 96 /* Library version */ 97 if (fwrite(&major, sizeof(int), 1, fp) != 1) 98 return ERR; 99 if (fwrite(&minor, sizeof(int), 1, fp) != 1) 100 return ERR; 101 102 /* Window parameters */ 103 if (fwrite(win, sizeof(WINDOW), 1, fp) != 1) 104 return ERR; 105 #ifdef HAVE_WCHAR 106 /* Background non-spacing character */ 107 if (__putnsp(win->bnsp, fp) == ERR) 108 return ERR; 109 #endif /* HAVE_WCHAR */ 110 111 /* Lines and line data */ 112 for (y = 0; y < win->maxy; y++) 113 for (sp = win->alines[y]->line, x = 0; x < win->maxx; 114 x++, sp++) { 115 if (fwrite(&sp->ch, sizeof(wchar_t), 1, fp) != 1) 116 return ERR; 117 if (fwrite(&sp->attr, sizeof(attr_t), 1, fp) != 1) 118 return ERR; 119 #ifdef HAVE_WCHAR 120 if (sp->nsp != NULL) { 121 if (__putnsp(win->bnsp, fp) == ERR) 122 return ERR; 123 } 124 #endif /* HAVE_WCHAR */ 125 } 126 127 return OK; 128 } 129 130 #ifdef HAVE_WCHAR 131 /* 132 * __getnsp -- 133 * Read non-spacing character chain from file 134 */ 135 static int 136 __getnsp(nschar_t *nsp, FILE *fp) 137 { 138 int n; 139 nschar_t *onsp, *tnsp; 140 141 if (fread(&n, sizeof(int), 1, fp) != 1) 142 return ERR; 143 onsp = nsp; 144 while (n != 0) { 145 tnsp = malloc(sizeof(nschar_t)); 146 if (tnsp == NULL) { 147 __cursesi_free_nsp(nsp); 148 return OK; 149 } 150 if (fread(&tnsp->ch, sizeof(wchar_t), 1, fp) != 1) { 151 __cursesi_free_nsp(nsp); 152 return OK; 153 } 154 tnsp->next = NULL; 155 onsp->next = tnsp; 156 onsp = onsp->next; 157 if (fread(&n, sizeof(int), 1, fp) != 1) { 158 __cursesi_free_nsp(nsp); 159 return ERR; 160 } 161 } 162 return OK; 163 } 164 #endif /* HAVE_WCHAR */ 165 166 /* 167 * getwin -- 168 * Read window data from file 169 */ 170 WINDOW * 171 getwin(FILE *fp) 172 { 173 int major, minor; 174 WINDOW *wtmp, *win; 175 int y, x; 176 __LDATA *sp; 177 178 __CTRACE(__CTRACE_FILEIO, "getwin\n"); 179 180 /* Check library version */ 181 if (fread(&major, sizeof(int), 1, fp) != 1) 182 return NULL; 183 if (fread(&minor, sizeof(int), 1, fp) != 1) 184 return NULL; 185 if(major != CURSES_LIB_MAJOR || minor != CURSES_LIB_MINOR) 186 return NULL; 187 188 /* Window parameters */ 189 wtmp = malloc(sizeof(WINDOW)); 190 if (wtmp == NULL) 191 return NULL; 192 if (fread(wtmp, sizeof(WINDOW), 1, fp) != 1) 193 goto error0; 194 win = __newwin(_cursesi_screen, wtmp->maxy, wtmp->maxx, 195 wtmp->begy, wtmp->begx, FALSE, FALSE); 196 if (win == NULL) 197 goto error0; 198 win->cury = wtmp->cury; 199 win->curx = wtmp->curx; 200 win->reqy = wtmp->reqy; 201 win->reqx = wtmp->reqx; 202 win->flags = wtmp->flags; 203 win->delay = wtmp->delay; 204 win->wattr = wtmp->wattr; 205 win->bch = wtmp->bch; 206 win->battr = wtmp->battr; 207 win->scr_t = wtmp->scr_t; 208 win->scr_b = wtmp->scr_b; 209 free(wtmp); 210 wtmp = NULL; 211 __swflags(win); 212 213 #ifdef HAVE_WCHAR 214 if (__getnsp(win->bnsp, fp) == ERR) 215 goto error1; 216 #endif /* HAVE_WCHAR */ 217 218 /* Lines and line data */ 219 for (y = 0; y < win->maxy; y++) { 220 for (sp = win->alines[y]->line, x = 0; x < win->maxx; 221 x++, sp++) { 222 if (fread(&sp->ch, sizeof(wchar_t), 1, fp) != 1) 223 goto error1; 224 if (fread(&sp->attr, sizeof(attr_t), 1, fp) != 1) 225 goto error1; 226 #ifdef HAVE_WCHAR 227 if (sp->nsp != NULL) { 228 if (__getnsp(win->bnsp, fp) == ERR) 229 goto error1; 230 } 231 #endif /* HAVE_WCHAR */ 232 } 233 __touchline(win, y, 0, (int) win->maxx - 1); 234 } 235 __CTRACE(__CTRACE_FILEIO, "getwin: win = %p\n", win); 236 return win; 237 238 error1: 239 delwin(win); 240 error0: 241 if (wtmp) 242 free(wtmp); 243 return NULL; 244 } 245 #endif /* !LIBHACK */ 246