package uk.co.mmscomputing.sms; import java.io.*; public class SMSNibbleOutputStream extends FilterOutputStream{ // [1] p.40 9.1.2.3 Semi-octet representation // 1010="*", 1011="#", 1100="a", 1101="b", 1110="c" private int nibble; private boolean haveNibble; public SMSNibbleOutputStream(OutputStream out){ super(out); nibble=0; haveNibble=false; } private int convert(int b){ if((0x30<=b)&&(b<=0x39)){ return b-0x30; } switch(b){ case '*': return 10; case '#': return 11; case 'a': return 12; case 'b': return 13; case 'c': return 14; } return 15; // 15: 1111 filler nibble at end } public void write(int b)throws IOException{ if(haveNibble){ b = convert(b)<<4; out.write(b|nibble); haveNibble=false; }else{ nibble = convert(b); haveNibble=true; } } public void write(byte[] b)throws IOException{ write(b,0,b.length); } public void write(byte[] b,int off,int len)throws IOException{ for(int i=0;i<len;i++){write(b[off+i]);} } public void flush()throws IOException{ if(haveNibble){ write('f'); haveNibble=false; } // super.flush(); // DON'T flush SMSOutputStream here ! } public static void main(String[] argv){ try{ String s="0044123456789"; ByteArrayOutputStream baos=new ByteArrayOutputStream(); SMSNibbleOutputStream out=new SMSNibbleOutputStream(baos); out.write(s.getBytes()); out.flush(); ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray()); SMSNibbleInputStream in=new SMSNibbleInputStream(bais); byte[] bytes=new byte[20]; int len=in.read(bytes); System.err.println("len = "+len); System.err.println(new String(bytes,0,len)); }catch(Exception e){ e.printStackTrace(); } } } // [1] ETSI TS 123 040 (2004-09) // [2] 3GPP TS 23.038 V7.0.0 (2006-03) // [3] GSM 44.008