1 /*
2  *******************************************************************************
3  * Copyright (C) 2003-2010, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6 */
7 package com.ibm.icu.dev.test.stringprep;
8 
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.UnsupportedEncodingException;
12 import java.util.MissingResourceException;
13 
14 import com.ibm.icu.text.StringPrep;
15 import com.ibm.icu.text.StringPrepParseException;
16 import com.ibm.icu.text.UCharacterIterator;
17 
18 /**
19  * @author ram
20  *
21  * This is a dumb implementation of NFS4 profiles. It is a direct port of
22  * C code, does not use Object Oriented principles. Quick and Dirty implementation
23  * for testing.
24  */
25 public final class NFS4StringPrep {
26 
27     private StringPrep nfscss = null;
28     private StringPrep nfscsi = null;
29     private StringPrep nfscis = null;
30     private StringPrep nfsmxp = null;
31     private StringPrep nfsmxs = null;
32     //singleton instance
33     private static final NFS4StringPrep prep = new NFS4StringPrep();
34 
35 
NFS4StringPrep()36     private  NFS4StringPrep (){
37         ClassLoader loader = NFS4StringPrep.class.getClassLoader();
38         try{
39             InputStream  nfscsiFile = loader.getResourceAsStream("com/ibm/icu/dev/data/testdata/nfscsi.spp");
40             nfscsi = new StringPrep(nfscsiFile);
41             nfscsiFile.close();
42 
43             InputStream  nfscssFile = loader.getResourceAsStream("com/ibm/icu/dev/data/testdata/nfscss.spp");
44             nfscss = new StringPrep(nfscssFile);
45             nfscssFile.close();
46 
47             InputStream  nfscisFile = loader.getResourceAsStream("com/ibm/icu/dev/data/testdata/nfscis.spp");
48             nfscis = new StringPrep(nfscisFile);
49             nfscisFile.close();
50 
51             InputStream  nfsmxpFile = loader.getResourceAsStream("com/ibm/icu/dev/data/testdata/nfsmxp.spp");
52             nfsmxp = new StringPrep(nfsmxpFile);
53             nfsmxpFile.close();
54 
55             InputStream  nfsmxsFile = loader.getResourceAsStream("com/ibm/icu/dev/data/testdata/nfsmxs.spp");
56             nfsmxs = new StringPrep(nfsmxsFile);
57             nfsmxsFile.close();
58         }catch(IOException e){
59             throw new MissingResourceException(e.toString(),"","");
60         }
61     }
62 
prepare(byte[] src, StringPrep strprep)63     private static byte[] prepare(byte[] src, StringPrep strprep)
64                 throws StringPrepParseException, UnsupportedEncodingException{
65         String s = new String(src, "UTF-8");
66         UCharacterIterator iter =  UCharacterIterator.getInstance(s);
67         StringBuffer out = strprep.prepare(iter,StringPrep.DEFAULT);
68         return out.toString().getBytes("UTF-8");
69     }
70 
cs_prepare(byte[] src, boolean isCaseSensitive)71     public static byte[] cs_prepare(byte[] src, boolean isCaseSensitive)
72                          throws StringPrepParseException, UnsupportedEncodingException{
73         if(isCaseSensitive == true ){
74             return prepare(src, prep.nfscss);
75         }else{
76             return prepare(src, prep.nfscsi);
77         }
78     }
79 
cis_prepare(byte[] src)80     public static byte[] cis_prepare(byte[] src)
81                          throws IOException, StringPrepParseException, UnsupportedEncodingException{
82         return prepare(src, prep.nfscis);
83     }
84 
85     /* sorted array for binary search*/
86     private static final String[] special_prefixes={
87         "ANONYMOUS",
88         "AUTHENTICATED",
89         "BATCH",
90         "DIALUP",
91         "EVERYONE",
92         "GROUP",
93         "INTERACTIVE",
94         "NETWORK",
95         "OWNER",
96     };
97 
98 
99     /* binary search the sorted array */
findStringIndex(String[] sortedArr,String target)100     private static final int findStringIndex(String[] sortedArr,String target){
101 
102         int left, middle, right,rc;
103 
104         left =0;
105         right= sortedArr.length-1;
106 
107         while(left <= right){
108             middle = (left+right)/2;
109             rc= sortedArr[middle].compareTo(target);
110 
111             if(rc<0){
112                 left = middle+1;
113             }else if(rc >0){
114                 right = middle -1;
115             }else{
116                 return middle;
117             }
118         }
119         return -1;
120     }
121     private static final char AT_SIGN = '@';
122 
mixed_prepare(byte[] src)123     public static byte[] mixed_prepare(byte[] src)
124                          throws IOException, StringPrepParseException, UnsupportedEncodingException{
125         String s = new String(src, "UTF-8");
126         int index = s.indexOf(AT_SIGN);
127         StringBuffer out = new StringBuffer();
128 
129         if(index > -1){
130             /* special prefixes must not be followed by suffixes! */
131             String prefixString = s.substring(0,index);
132             int i= findStringIndex(special_prefixes, prefixString);
133             String suffixString = s.substring(index+1, s.length());
134             if(i>-1 && !suffixString.equals("")){
135                 throw new StringPrepParseException("Suffix following a special index", StringPrepParseException.INVALID_CHAR_FOUND);
136             }
137             UCharacterIterator prefix = UCharacterIterator.getInstance(prefixString);
138             UCharacterIterator suffix = UCharacterIterator.getInstance(suffixString);
139             out.append(prep.nfsmxp.prepare(prefix,StringPrep.DEFAULT));
140             out.append(AT_SIGN); // add the delimiter
141             out.append(prep.nfsmxs.prepare(suffix, StringPrep.DEFAULT));
142         }else{
143             UCharacterIterator iter = UCharacterIterator.getInstance(s);
144             out.append(prep.nfsmxp.prepare(iter,StringPrep.DEFAULT));
145 
146         }
147        return out.toString().getBytes("UTF-8");
148     }
149 
150 }
151