Bitsplitter-Plugin: add methods to recover reased fragment in the codec
[splitter-ng] / Splitter-ng-plugin-bitsplitter / src / bitsplitterplugin / CodecBitsplitter.java
1 package bitsplitterplugin;
2
3
4
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.nio.file.Files;
10 import java.nio.file.Path;
11 import java.util.Arrays;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.Map.Entry;
16
17 import splitterng.plugin.CodecDescription;
18 import splitterng.plugin.interfaces.SplitterCodec;
19 import BitSplitter.BitSplitter;
20
21
22 public class CodecBitsplitter implements SplitterCodec {
23
24         public final static String codecID = "bitsplitter";
25         public final static String codecName = "Bitsplitter";
26         public final static String codecDescriptionText = "Simple bitsplitter. 1234567812345678 -> 12341234 56785678";
27
28         public final static Map <String, Integer []> codecParameterMinMax;
29
30         private int k,m,w,packetsize;
31         
32         static {
33                 Map <String, Integer []> tmpMap = new HashMap<String, Integer[]>();
34                 tmpMap.put("k", new Integer[] {new Integer(2),new Integer(Integer.MAX_VALUE)});
35                 tmpMap.put("m", new Integer[] {new Integer(0),new Integer(1)});
36                 
37                 codecParameterMinMax  = Collections.unmodifiableMap(tmpMap);                            
38         }
39         
40         
41         private static final CodecDescription codecDescription = new CodecDescription(
42         codecID, codecName, codecDescriptionText, codecParameterMinMax);
43         
44     private byte[][] coding_ptrs;
45         private byte[][] data_ptrs;
46         private byte[][] dataAndCoding_ptrs;
47         BitSplitter bs;
48         private int [] erasures;
49         private byte[] data_ptrs_flat;
50         
51         
52         public static final CodecDescription getCodecDescription(){
53                 //System.out.println("JerasureCodecParity: getCodecDescription: "+JerasureCodecParity.codecDescription);
54                 return CodecBitsplitter.codecDescription;
55         }
56         
57         /**
58          * @param codecParameter
59          */
60         public CodecBitsplitter(Map<String, Integer> codecParameter) {
61                 super();
62                 //Test CodecParameter
63                 for (Entry<String, Integer[]> requiredEntry : CodecBitsplitter.codecParameterMinMax
64                                 .entrySet()) {
65                         if (codecParameter.containsKey(requiredEntry.getKey())) {
66                                 // Test ob Parameter vorhanden und in den gültigen grenzen
67                                 // liegen
68                                 //System.out.println("Test" +codecParameter.get(requiredEntry.getKey()) +" "+  requiredEntry.getValue()[0]);
69                                 if (codecParameter.get(requiredEntry.getKey()) < requiredEntry.getValue()[0])
70                                         throw new IllegalArgumentException(
71                                                         "unzulässiger Wert für Parameter: "
72                                                                         + requiredEntry.getKey() + " < "
73                                                                         + requiredEntry.getValue()[0]);
74                                 if (codecParameter.get(requiredEntry.getKey()) > requiredEntry.getValue()[1])
75                                         throw new IllegalArgumentException(
76                                                         "unzulässiger Wert für Parameter: "
77                                                                         + requiredEntry.getKey() + " > "
78                                                                         + requiredEntry.getValue()[1]);
79                         } else {
80                                 throw new IllegalArgumentException("Missing Codec Parameter: "
81                                                 + requiredEntry.getKey());
82                         }
83                 }
84                 
85                 k=(int)codecParameter.get("k");
86                 m=(int)codecParameter.get("m");
87                 //System.out.println("Init Bitsplitter");
88                 bs = new BitSplitter();
89         }
90
91         @Override
92         public byte[][] decode(byte[][] dataAndCoding_ptrs, boolean [] erased){
93                 //TODO Array Testen ob zulässig? eventuell nicht, da es hier bremsen könnte
94                 
95                 int fragmentsize = dataAndCoding_ptrs[0].length;
96                 int erased_index=0;
97                 for (boolean e: erased){
98                         if (e){
99                                 recoverFragment(dataAndCoding_ptrs,erased_index);
100                                 break;
101                         } else {
102                                 erased_index++;
103                         }
104                 }
105                 
106                 if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
107                         data_ptrs_flat = new byte[k * fragmentsize];
108                 }
109                 if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
110                         data_ptrs = new byte[k][fragmentsize];
111                 }                       
112                 
113                 bs.bitjoinbuffer(dataAndCoding_ptrs, data_ptrs_flat, k);
114
115                 for (int i=0; i<k; i++){
116                         System.arraycopy(data_ptrs_flat, i*fragmentsize, data_ptrs[i], 0, fragmentsize);
117                 }
118                 return data_ptrs;
119         }
120
121         private void recoverFragment(byte[][] dataAndCoding_ptrs2, int erased_index) {
122                 // TODO Auto-generated method stub
123                 int parts= dataAndCoding_ptrs2.length;
124                 Arrays.fill(dataAndCoding_ptrs2[erased_index],(byte)0);
125                 int i = 0;
126                 for (byte [] array : dataAndCoding_ptrs2){
127                         if (i != erased_index){
128                                 int j = 0;
129                                 for (byte b : array)
130                                         dataAndCoding_ptrs2[erased_index][j] = (byte) (b ^ dataAndCoding_ptrs2[erased_index][j++]);
131                         }
132                         i++;
133                 }
134         }
135
136         @Override
137         public byte[][] encode(byte[][] data_ptrs){
138                 //TODO Array Testen ob zulässig? eventuell nicht, da es hier bremsen könnte
139                 // buffersize%(sizeof(int)*w*k) == 0
140                 int fragmentsize = data_ptrs[0].length;
141                 
142                 if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
143                         data_ptrs_flat = new byte[k * fragmentsize];
144                 }
145                 for (int i=0; i < k; i++) {
146                         System.arraycopy(data_ptrs[i], 0, data_ptrs_flat, i*fragmentsize , fragmentsize);
147                 }               
148                 if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != Math.ceil(fragmentsize/k))){
149                         //System.out.println("dataAndCoding_ptrs neu");
150                         dataAndCoding_ptrs = new byte[k+m][(int) Math.ceil(fragmentsize/k)];
151                 }else {
152                         //System.out.println("dataAndCoding_ptrs reuse");
153                 }
154                 bs.bitsplitbuffer(data_ptrs_flat, dataAndCoding_ptrs, k, m);
155                                 
156                 return dataAndCoding_ptrs;
157         }
158         private void checkArraySizes(int fragmentsize) {
159                 
160                 if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
161                         data_ptrs = new byte[k][fragmentsize];
162                 }                       
163                 
164                 //Test reuse or create new
165 //              if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
166 //                      data_ptrs_flat = new byte[k * fragmentsize];
167 //              }
168 //              
169 //              
170 //              if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m * fragmentsize)){
171 //                      coding_ptrs_flat = new byte[m * fragmentsize];
172 //              }
173                 
174 //              if (coding_ptrs == null || (coding_ptrs.length != m ) || (coding_ptrs[0].length != fragmentsize)){
175 //                      coding_ptrs = new byte[m][fragmentsize];
176 //              }
177                 
178                 if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != fragmentsize/k +1)){
179                         //System.out.println("dataAndCoding_ptrs neu");
180                         dataAndCoding_ptrs = new byte[k+m][fragmentsize/k +1];
181                 }else {
182                         //System.out.println("dataAndCoding_ptrs reuse");
183                 }
184         }
185 }