1 /* $NetBSD: fileio.c,v 1.6 2018/10/02 17:35:44 roy 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 #include <sys/cdefs.h> 33 #ifndef lint 34 __RCSID("$NetBSD: fileio.c,v 1.6 2018/10/02 17:35:44 roy Exp $"); 35 #endif /* not lint */ 36 37 #include "curses.h" 38 #include "curses_private.h" 39 #include "fileio.h" 40 #include <stdio.h> 41 #include <stdlib.h> 42 43 #ifdef HAVE_WCHAR 44 static int __putnsp(nschar_t *, FILE *); 45 static int __getnsp(nschar_t *, FILE *); 46 #endif /* HAVE_WCHAR */ 47 48 #ifdef HAVE_WCHAR 49 /* 50 * __putnsp -- 51 * Write non-spacing character chain to file, consisting of: 52 * ((int) 1, (wchar_t) ch) pairs followed by (int) 0. 53 */ 54 static int 55 __putnsp(nschar_t *nsp, FILE *fp) 56 { 57 int n; 58 59 n = 1; 60 while (nsp != NULL) { 61 if (fwrite(&n, sizeof(int), 1, fp) != 1) 62 return ERR; 63 if (fwrite(&nsp->ch, sizeof(wchar_t), 1, fp) != 1) 64 return ERR; 65 } 66 n = 0; 67 if (fwrite(&n, sizeof(int), 1, fp) != 1) 68 return ERR; 69 70 return OK; 71 } 72 #endif /* HAVE_WCHAR */ 73 74 /* 75 * putwin -- 76 * Write window data to file 77 */ 78 int 79 putwin(WINDOW *win, FILE *fp) 80 { 81 int major = CURSES_LIB_MAJOR; 82 int minor = CURSES_LIB_MINOR; 83 int y, x; 84 __LDATA *sp; 85 86 #ifdef DEBUG 87 __CTRACE(__CTRACE_FILEIO, "putwin: win %p\n", win); 88 #endif 89 90 if (win == NULL) 91 return ERR; 92 93 /* win can't be a subwin */ 94 if (win->orig != NULL) 95 return ERR; 96 97 /* Library version */ 98 if (fwrite(&major, sizeof(int), 1, fp) != 1) 99 return ERR; 100 if (fwrite(&minor, sizeof(int), 1, fp) != 1) 101 return ERR; 102 103 /* Window parameters */ 104 if (fwrite(win, sizeof(WINDOW), 1, fp) != 1) 105 return ERR; 106 #ifdef HAVE_WCHAR 107 /* Background non-spacing character */ 108 if (__putnsp(win->bnsp, fp) == ERR) 109 return ERR; 110 #endif /* HAVE_WCHAR */ 111 112 /* Lines and line data */ 113 for (y = 0; y < win->maxy; y++) 114 for (sp = win->alines[y]->line, x = 0; x < win->maxx; 115 x++, sp++) { 116 if (fwrite(&sp->ch, sizeof(wchar_t), 1, fp) != 1) 117 return ERR; 118 if (fwrite(&sp->attr, sizeof(attr_t), 1, fp) != 1) 119 return ERR; 120 #ifdef HAVE_WCHAR 121 if (sp->nsp != NULL) { 122 if (__putnsp(win->bnsp, fp) == ERR) 123 return ERR; 124 } 125 #endif /* HAVE_WCHAR */ 126 } 127 128 return OK; 129 } 130 131 #ifdef HAVE_WCHAR 132 /* 133 * __getnsp -- 134 * Read non-spacing character chain from file 135 */ 136 static int 137 __getnsp(nschar_t *nsp, FILE *fp) 138 { 139 int n; 140 nschar_t *onsp, *tnsp; 141 142 if (fread(&n, sizeof(int), 1, fp) != 1) 143 return ERR; 144 onsp = nsp; 145 while (n != 0) { 146 tnsp = malloc(sizeof(nschar_t)); 147 if (tnsp == NULL) { 148 __cursesi_free_nsp(nsp); 149 return OK; 150 } 151 if (fread(&tnsp->ch, sizeof(wchar_t), 1, fp) != 1) { 152 __cursesi_free_nsp(nsp); 153 return OK; 154 } 155 tnsp->next = NULL; 156 onsp->next = tnsp; 157 onsp = onsp->next; 158 if (fread(&n, sizeof(int), 1, fp) != 1) { 159 __cursesi_free_nsp(nsp); 160 return ERR; 161 } 162 } 163 return OK; 164 } 165 #endif /* HAVE_WCHAR */ 166 167 /* 168 * getwin -- 169 * Read window data from file 170 */ 171 WINDOW * 172 getwin(FILE *fp) 173 { 174 int major, minor; 175 WINDOW *wtmp, *win; 176 int y, x; 177 __LDATA *sp; 178 179 #ifdef DEBUG 180 __CTRACE(__CTRACE_FILEIO, "getwin\n"); 181 #endif 182 183 /* Check library version */ 184 if (fread(&major, sizeof(int), 1, fp) != 1) 185 return NULL; 186 if (fread(&minor, sizeof(int), 1, fp) != 1) 187 return NULL; 188 if(major != CURSES_LIB_MAJOR || minor != CURSES_LIB_MINOR) 189 return NULL; 190 191 /* Window parameters */ 192 wtmp = malloc(sizeof(WINDOW)); 193 if (wtmp == NULL) 194 return NULL; 195 if (fread(wtmp, sizeof(WINDOW), 1, fp) != 1) 196 goto error0; 197 win = __newwin(_cursesi_screen, wtmp->maxy, wtmp->maxx, 198 wtmp->begy, wtmp->begx, FALSE, FALSE); 199 if (win == NULL) 200 goto error0; 201 win->cury = wtmp->cury; 202 win->curx = wtmp->curx; 203 win->reqy = wtmp->reqy; 204 win->reqx = wtmp->reqx; 205 win->flags = wtmp->flags; 206 win->delay = wtmp->delay; 207 win->wattr = wtmp->wattr; 208 win->bch = wtmp->bch; 209 win->battr = wtmp->battr; 210 win->scr_t = wtmp->scr_t; 211 win->scr_b = wtmp->scr_b; 212 free(wtmp); 213 wtmp = NULL; 214 __swflags(win); 215 216 #ifdef HAVE_WCHAR 217 if (__getnsp(win->bnsp, fp) == ERR) 218 goto error1; 219 #endif /* HAVE_WCHAR */ 220 221 /* Lines and line data */ 222 for (y = 0; y < win->maxy; y++) { 223 for (sp = win->alines[y]->line, x = 0; x < win->maxx; 224 x++, sp++) { 225 if (fread(&sp->ch, sizeof(wchar_t), 1, fp) != 1) 226 goto error1; 227 if (fread(&sp->attr, sizeof(attr_t), 1, fp) != 1) 228 goto error1; 229 #ifdef HAVE_WCHAR 230 if (sp->nsp != NULL) { 231 if (__getnsp(win->bnsp, fp) == ERR) 232 goto error1; 233 } 234 #endif /* HAVE_WCHAR */ 235 } 236 __touchline(win, y, 0, (int) win->maxx - 1); 237 } 238 #ifdef DEBUG 239 __CTRACE(__CTRACE_FILEIO, "getwin: win = 0x%p\n", win); 240 #endif 241 return win; 242 243 error1: 244 delwin(win); 245 error0: 246 if (wtmp) 247 free(wtmp); 248 return NULL; 249 } 250