1    // Copyright (C) 2003 Adam Megacz <adam@xwt.org> all rights reserved.
2    //
3    // You may modify, copy, and redistribute this code under the terms of
4    // the GNU Library Public License version 2.1, with the exception of
5    // the portion of clause 6a after the semicolon (aka the "obnoxious
6    // relink clause")
7    
8    package org.xwt.util;
9    import java.io.*;
10   import java.util.*;
11   
12   /** packs 8-bit bytes into a String of 7-bit chars (to avoid the UTF-8 non-ASCII penalty) */
13   public class PackBytesIntoString {
14   
15       public static String pack(byte[] b, int off, int len) throws IllegalArgumentException {
16           if (len % 7 != 0) throw new IllegalArgumentException("len must be a multiple of 7");
17           StringBuffer ret = new StringBuffer();
18           for(int i=off; i<off+len; i += 7) {
19               long l = 0;
20               for(int j=6; j>=0; j--) {
21                   l <<= 8;
22                   l |= (b[i + j] & 0xff);
23               }
24               for(int j=0; j<8; j++) {
25                   ret.append((char)(l & 0x7f));
26                   l >>= 7;
27               }
28           }
29           return ret.toString();
30       }
31   
32       public static byte[] unpack(String s) throws IllegalArgumentException {
33           if (s.length() % 8 != 0) throw new IllegalArgumentException("string length must be a multiple of 8");
34           byte[] ret = new byte[(s.length() / 8) * 7];
35           for(int i=0; i<s.length(); i += 8) {
36               long l = 0;
37               for(int j=7; j>=0; j--) {
38                   l <<= 7;
39                   l |= (s.charAt(i + j) & 0x7fL);
40               }
41               for(int j=0; j<7; j++) {
42                   ret[(i / 8) * 7 + j] = (byte)(l & 0xff);
43                   l >>= 8;
44               }
45           }
46           return ret;
47       }
48   }
49    
50