// fil InnBBUtBB.java import inf101.*; // BB st?r for 'Bits & Bytes' /** * Utvider klassen Inn med metode for ? lese enkeltbit eller * en kode p? opptil 21000 verdier p? fil i en eller to byter, * og en metode for ? lese neste ord p? fila. ************************************************************/ class InnBB extends Inn { private int bitInnVerdi = 0; private int antBitIgjen = 0; /** Avoids cotrol characters. : 10, 13, 128-160 * @param i a byte value read from file with inChar() * @return 'code' as used when calling corresponding utKonv(int code) */ int inKonv (int i) { int ret = i; if (i >= 10 ) ret -= 4; if (i >= 128 ) ret -= 32; return ret; } InnBB (String s) { super(s);} InnBB (){super();} /** * Reads next code from file. : lower 100 values (2 digits in code) in byte 1. * if value of code on file >= 100 then byte 1 > 100 and byte 2 = upper 3 digits (up to 210 values). * @return max value = 210*100 (can easily be extended to 3,4.. byte encoding) *************************************************************************/ public int innKode( ) { int c,k; c = inKonv((int) inChar()); if (c >= 100) { k = c - 100; c = inKonv((int) inChar()); return c*100 +k; } else { return c; } } // end innKode /** * Reads next word from file. Skips whitespace as determined * by parameter to inString() */ public String lesNesteOrd () { return inString(" "); // Pr?v her andre avgrnsninger i tillegg som :.,\n- } /** * Reads next 13 bit Huffman code from file. */ int innBKode() { // gets 2 byte input from utKode. All leading bits might be '0' int i = innKode(); if ( i >= 20000 ) bitInnVerdi = i - 20000; else bitInnVerdi = i; return bitInnVerdi; } // end outKode /** * Writes bit value in int i' to file: 14 bits in two bytes. * Remember to call flushBit to get out last bits */ public int innBit() { if (antBitIgjen == 0 ) { bitInnVerdi = innBKode() << (31-13); // upper bit to read antBitIgjen = 13; } antBitIgjen--; bitInnVerdi <<= 1; if ( bitInnVerdi < 0) return 1 ; else return 0; } // end innBit } // end class InnB /** * Utvider klassen Ut med metode for ? skrive enten bitm?nstre eller * en kode p? opptil 21000 verdier p? fil i en eller to byter. * BB = Bit og Byte ************************************************************/ class UtBB extends Ut { private int bitUtVerdi = 0; private int antBitSkrevet = 0; /** Avoids cotrol characters. : 10, 13, 128-160 @return 'code' to be output on file, read by corresponding innKonv(int code) **/ int utKonv(int i) { int ret = i; if (i >= 10 ) ret += 4; if (i >= 124 ) ret += 32; return ret; } UtBB (String s) { super(s);} UtBB (){super();} /** * Writes code 'k' to file: lower 100 values (2 digits in code) in byte 1. * if value of code >= 100 then byte 1 >=100 and byte 2 = upper 3 digits (up to 210 values). * Max code value = 210*100 (can easily be extended to 3,4.. byte encoding) */ public void utKode(int k) { int c1,c2; if (k >= 100) { c1 = utKonv( (k %100) + 100 ); outChar( (char) c1); c2 = utKonv(k/100); outChar( (char) c2 ); } else { c1 = utKonv(k); outChar((char)c1); } } // end outKode /** * Writes code 'k' to file: lower 100 values (2 digits in code) in byte 1. * if value of code >= 100 then byte 1 >=100 and byte 2 = upper 3 digits (up to 210 values). * Max code value = 210*100 (can easily be extended to 3,4.. byte encoding) */ public void utBKode(int k) { // assure 2 byte output from utKode. All leading bits might be '0' if ( k < 100) utKode( k + 20000); else utKode(k); } // end outKode /** * Writes bit value in int i' to file: 13 bits in two bytes. * Assumes i == 0 or i == 1. * Remember to call flushBit to get out last bits *************************************************************************/ public void utBit(int i) { antBitSkrevet++; bitUtVerdi = (bitUtVerdi <<1) | i; if (antBitSkrevet == 13 ) { utBKode(bitUtVerdi); bitUtVerdi = 0; antBitSkrevet = 0; } } // end utBit /** * Writes 'len' bitsin int 'i' to file. * Remember to call flushBit to get out last bits *************************************************************************/ public void utHuffKode(int i, int len) { if (13 - antBitSkrevet > len ) { antBitSkrevet += len; bitUtVerdi = (bitUtVerdi <<len) + i; } else if (13 - antBitSkrevet == len) { utBKode((bitUtVerdi <<len) + i); antBitSkrevet = 0; bitUtVerdi = 0; } else { // too many bits in i int len1 = (13 - antBitSkrevet), len2 = len - len1; int kode1 = i >>> len2, kode2 = i - ( kode1 << len2); utBKode((bitUtVerdi <<len1) + kode1); bitUtVerdi = 0; antBitSkrevet = 0; utHuffKode(kode2,len2); // take any code length } } // end utHiffKode /** * Flushes bitbuffer used by utBit & utHuffKode */ public void flushBit() { if (antBitSkrevet > 0 ) { utKode(bitUtVerdi<<(13 -antBitSkrevet)); bitUtVerdi = 0; antBitSkrevet = 0; } } // end flushBit } // end class UtB