1/* 2 * intfile - integer to file and file to integer conversion 3 * 4 * Copyright (C) 2001,2021 Landon Curt Noll 5 * 6 * Calc is open software; you can redistribute it and/or modify it under 7 * the terms of the version 2.1 of the GNU Lesser General Public License 8 * as published by the Free Software Foundation. 9 * 10 * Calc is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 13 * Public License for more details. 14 * 15 * A copy of version 2.1 of the GNU Lesser General Public License is 16 * distributed with calc under the filename COPYING-LGPL. You should have 17 * received a copy with calc; if not, write to Free Software Foundation, Inc. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * 20 * Under source code control: 2001/03/31 08:13:11 21 * File existed as early as: 2001 22 * 23 * chongo <was here> /\oo/\ http://www.isthe.com/chongo/ 24 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ 25 */ 26 27 28/* 29 * NOTE: Because leading HALF values are trimmed from integer, a file 30 * that begins with lots of 0 bits (in the case of big Endian) 31 * or that ends with lots of 0 bits (in the case of little Endian) 32 * will be changed when the subsequent integer is written back. 33 */ 34 35 36/* 37 * file2be - convert a file into an big Endian integer 38 * 39 * given: 40 * filename filename to read 41 * 42 * returns: 43 * integer read from its contents on big Endian order 44 */ 45define file2be(filename) 46{ 47 local fd; /* open file */ 48 local ret; /* integer to return */ 49 local c; /* character read from the file */ 50 local i; 51 52 /* 53 * open the file for reading 54 */ 55 fd = fopen(filename, "rb"); 56 if (!isfile(fd)) quit "file2be: cannot open file for reading"; 57 58 /* 59 * read the contents of the file 60 * 61 * The first octets become the most significant bits of the integer. 62 */ 63 ret = 0; 64 while (! isnull(c = fgetc(fd))) { 65 ret <<= 8; 66 ret += ord(c); 67 } 68 69 /* 70 * cleanup and return the integer 71 */ 72 fclose(fd); 73 return ret; 74} 75 76 77/* 78 * file2le - convert a file into an little Endian integer 79 * 80 * given: 81 * filename filename to read 82 * 83 * returns: 84 * integer read from its contents on little Endian order 85 */ 86define file2le(filename) 87{ 88 local fd; /* open file */ 89 local ret; /* integer to return */ 90 local c; /* character read from the file */ 91 local shft; /* bit shift for the c value */ 92 local i; 93 94 /* 95 * open the file for reading 96 */ 97 fd = fopen(filename, "rb"); 98 if (!isfile(fd)) quit "file2le: cannot open file for reading"; 99 100 /* 101 * read the contents of the file into a string 102 * 103 * The first octets become are the least significant bits of the integer. 104 */ 105 ret = 0; 106 shft = 0; 107 while (! isnull(c = fgetc(fd))) { 108 ret |= (ord(c) << shft); 109 shft += 8; 110 } 111 112 /* 113 * cleanup and return the integer 114 */ 115 fclose(fd); 116 return ret; 117} 118 119 120/* 121 * be2file - convert a big Endian integer into a file 122 * 123 * given: 124 * v integer to write to the file 125 * filename filename to write 126 * 127 * returns: 128 * The number of octets written to the file. 129 * 130 * NOTE: The absolute value of the integer is written to the file. 131 */ 132define be2file(v, filename) 133{ 134 local fd; /* open file */ 135 local octlen; /* length of v in octets */ 136 local i; 137 138 /* 139 * firewall 140 */ 141 if (!isint(v)) { 142 quit "be2file: 1st arg not an integer"; 143 } 144 v = abs(v); 145 146 /* 147 * open the file for writing 148 */ 149 fd = fopen(filename, "wb"); 150 if (!isfile(fd)) quit "be2file: cannot open file for writing"; 151 152 /* 153 * write the octets to the file 154 * 155 * The most significant bits of the integer become the first file octets. 156 */ 157 octlen = int((highbit(v)+8) / 8); 158 for (i=octlen-1; i >= 0; --i) { 159 fputc(fd, char(v >> (i*8))); 160 } 161 162 /* 163 * cleanup 164 */ 165 fclose(fd); 166 return octlen; 167} 168 169 170/* 171 * le2file - convert a little Endian integer into a file 172 * 173 * given: 174 * v integer to write to the file 175 * filename filename to write 176 * 177 * returns: 178 * The number of octets written to the file. 179 * 180 * NOTE: The absolute value of the integer is written to the file. 181 */ 182define le2file(v, filename) 183{ 184 local fd; /* open file */ 185 local cnt; /* octets written */ 186 187 /* 188 * firewall 189 */ 190 if (!isint(v)) { 191 quit "be2file: 1st arg not an integer"; 192 } 193 v = abs(v); 194 195 /* 196 * open the file for writing 197 */ 198 fd = fopen(filename, "wb"); 199 if (!isfile(fd)) quit "le2file: cannot open file for writing"; 200 201 /* 202 * Write the octets to the file. 203 * 204 * The least significant bits of the integer become the first file octets. 205 */ 206 cnt = 0; 207 while (v > 0) { 208 fputc(fd, char(v)); 209 v >>= 8; 210 ++cnt; 211 } 212 213 /* 214 * cleanup 215 */ 216 fclose(fd); 217 return cnt; 218} 219