1(* 2 Title: Standard Basis Library: PACK_WORD signature and structures 3 Author: David Matthews 4 Copyright David Matthews 2000, 2005 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19*) 20 21(* G&R 2004 status: updated, the structure names have changed. *) 22 23signature PACK_WORD = 24sig 25 val bytesPerElem : int 26 val isBigEndian : bool 27 val subVec : Word8Vector.vector * int -> LargeWord.word 28 val subVecX : Word8Vector.vector * int -> LargeWord.word 29 val subArr : Word8Array.array * int -> LargeWord.word 30 val subArrX : Word8Array.array * int -> LargeWord.word 31 val update : Word8Array.array * int * LargeWord.word -> unit 32end; 33 34(* I'm not sure what use Pack8Big and Pack8Little are since 35 they don't do any packing. *) 36structure PackWord8Big : PACK_WORD = 37struct 38 val bytesPerElem = 1 39 val isBigEndian = true 40 val subVec = Word8.toLargeWord o Word8Vector.sub 41 val subVecX = Word8.toLargeWordX o Word8Vector.sub 42 val subArr = Word8.toLargeWord o Word8Array.sub 43 val subArrX = Word8.toLargeWordX o Word8Array.sub 44 fun update(a, i, v) = Word8Array.update(a, i, Word8.fromLargeWord v) 45end; 46 47structure PackWord8Little : PACK_WORD = 48struct 49(* Exactly the same as Pack8Big except for the value of isBigEndian *) 50 open PackWord8Big 51 val isBigEndian = false 52end; 53 54local 55 infix << >> 56 infix andb 57 infix orb 58 val op orb = LargeWord.orb 59 and op << = LargeWord.<< 60 and op >> = LargeWord.>> 61 62 fun twoBytesToWord(hi: Word8.word, lo: Word8.word) = 63 (Word8.toLargeWord hi << 0w8) orb Word8.toLargeWord lo 64 65 fun twoBytesToWordX(hi: Word8.word, lo: Word8.word) = 66 (Word8.toLargeWordX hi << 0w8) orb Word8.toLargeWord lo 67 68 fun fourBytesToWord(highest, higher, lower, low) = 69 (Word8.toLargeWord highest << 0w24) orb 70 (Word8.toLargeWord higher << 0w16) orb 71 (Word8.toLargeWord lower << 0w8) orb 72 Word8.toLargeWord low 73 74 fun fourBytesToWordX(highest, higher, lower, low) = 75 (Word8.toLargeWordX highest << 0w24) orb 76 (Word8.toLargeWord higher << 0w16) orb 77 (Word8.toLargeWord lower << 0w8) orb 78 Word8.toLargeWord low 79 80in 81 structure PackWord16Big : PACK_WORD = 82 struct 83 val bytesPerElem = 2 84 val isBigEndian = true 85 86 fun subVec(a, i) = 87 twoBytesToWord( 88 Word8Vector.sub(a, i*2), Word8Vector.sub(a, i*2+1)) 89 90 fun subVecX(a, i) = 91 twoBytesToWordX( 92 Word8Vector.sub(a, i*2), Word8Vector.sub(a, i*2+1)) 93 94 fun subArr(a, i) = 95 twoBytesToWord( 96 Word8Array.sub(a, i*2), Word8Array.sub(a, i*2+1)) 97 98 fun subArrX(a, i) = 99 twoBytesToWordX( 100 Word8Array.sub(a, i*2), Word8Array.sub(a, i*2+1)) 101 102 fun update(a, i, v) = 103 (* Check the index before doing any update. *) 104 if i < 0 orelse i*2+1 >= Word8Array.length a 105 then raise Subscript 106 else 107 (Word8Array.update(a, i*2+1, Word8.fromLargeWord v); 108 Word8Array.update(a, i*2, Word8.fromLargeWord(v >> 0w8)) 109 ) 110 end; 111 112 structure PackWord16Little : PACK_WORD = 113 struct 114 val bytesPerElem = 2 115 val isBigEndian = false 116 117 fun subVec(a, i) = 118 twoBytesToWord( 119 Word8Vector.sub(a, i*2+1), Word8Vector.sub(a, i*2)) 120 121 fun subVecX(a, i) = 122 twoBytesToWordX( 123 Word8Vector.sub(a, i*2+1), Word8Vector.sub(a, i*2)) 124 125 fun subArr(a, i) = 126 twoBytesToWord( 127 Word8Array.sub(a, i*2+1), Word8Array.sub(a, i*2)) 128 129 fun subArrX(a, i) = 130 twoBytesToWordX( 131 Word8Array.sub(a, i*2+1), Word8Array.sub(a, i*2)) 132 133 fun update(a, i, v) = 134 (* Check the index before doing any update. *) 135 if i < 0 orelse i*2+1 >= Word8Array.length a 136 then raise Subscript 137 else 138 (Word8Array.update(a, i*2, Word8.fromLargeWord v); 139 Word8Array.update(a, i*2+1, Word8.fromLargeWord(v >> 0w8)) 140 ) 141 end; 142 143 structure PackWord32Big : PACK_WORD = 144 struct 145 val bytesPerElem = 4 146 val isBigEndian = true 147 148 fun subVec(a, i) = 149 fourBytesToWord( 150 Word8Vector.sub(a, i*4), Word8Vector.sub(a, i*4+1), 151 Word8Vector.sub(a, i*4+2), Word8Vector.sub(a, i*4+3)) 152 153 fun subVecX(a, i) = 154 fourBytesToWordX( 155 Word8Vector.sub(a, i*4), Word8Vector.sub(a, i*4+1), 156 Word8Vector.sub(a, i*4+2), Word8Vector.sub(a, i*4+3)) 157 158 fun subArr(a, i) = 159 fourBytesToWord( 160 Word8Array.sub(a, i*4), Word8Array.sub(a, i*4+1), 161 Word8Array.sub(a, i*4+2), Word8Array.sub(a, i*4+3)) 162 163 fun subArrX(a, i) = 164 fourBytesToWordX( 165 Word8Array.sub(a, i*4), Word8Array.sub(a, i*4+1), 166 Word8Array.sub(a, i*4+2), Word8Array.sub(a, i*4+3)) 167 168 fun update(a, i, v) = 169 (* Check the index before doing any update. *) 170 if i < 0 orelse i*4+3 >= Word8Array.length a 171 then raise Subscript 172 else 173 (Word8Array.update(a, i*4+3, Word8.fromLargeWord v); 174 Word8Array.update(a, i*4+2, Word8.fromLargeWord(v >> 0w8)); 175 Word8Array.update(a, i*4+1, Word8.fromLargeWord(v >> 0w16)); 176 Word8Array.update(a, i*4, Word8.fromLargeWord(v >> 0w24)) 177 ) 178 end; 179 180 structure PackWord32Little : PACK_WORD = 181 struct 182 val bytesPerElem = 4 183 val isBigEndian = false 184 185 fun subVec(a, i) = 186 fourBytesToWord( 187 Word8Vector.sub(a, i*4+3), Word8Vector.sub(a, i*4+2), 188 Word8Vector.sub(a, i*4+1), Word8Vector.sub(a, i*4)) 189 190 fun subVecX(a, i) = 191 fourBytesToWordX( 192 Word8Vector.sub(a, i*4+3), Word8Vector.sub(a, i*4+2), 193 Word8Vector.sub(a, i*4+1), Word8Vector.sub(a, i*4)) 194 195 fun subArr(a, i) = 196 fourBytesToWord( 197 Word8Array.sub(a, i*4+3), Word8Array.sub(a, i*4+2), 198 Word8Array.sub(a, i*4+1), Word8Array.sub(a, i*4)) 199 200 fun subArrX(a, i) = 201 fourBytesToWordX( 202 Word8Array.sub(a, i*4+3), Word8Array.sub(a, i*4+2), 203 Word8Array.sub(a, i*4+1), Word8Array.sub(a, i*4)) 204 205 fun update(a, i, v) = 206 (* Check the index before doing any update. *) 207 if i < 0 orelse i*4+3 >= Word8Array.length a 208 then raise Subscript 209 else 210 (Word8Array.update(a, i*4, Word8.fromLargeWord v); 211 Word8Array.update(a, i*4+1, Word8.fromLargeWord(v >> 0w8)); 212 Word8Array.update(a, i*4+2, Word8.fromLargeWord(v >> 0w16)); 213 Word8Array.update(a, i*4+3, Word8.fromLargeWord(v >> 0w24)) 214 ) 215 end 216 217end; 218 219