Small style stuff
[zxing.git] / csharp / datamatrix / decoder / DecodedBitStreamParser.cs
1 /*\r
2 * Copyright 2008 ZXing authors\r
3 *\r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5 * you may not use this file except in compliance with the License.\r
6 * You may obtain a copy of the License at\r
7 *\r
8 *      http://www.apache.org/licenses/LICENSE-2.0\r
9 *\r
10 * Unless required by applicable law or agreed to in writing, software\r
11 * distributed under the License is distributed on an "AS IS" BASIS,\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 * See the License for the specific language governing permissions and\r
14 * limitations under the License.\r
15 */\r
16 using System;\r
17 using ReaderException = com.google.zxing.ReaderException;\r
18 using BitSource = com.google.zxing.common.BitSource;\r
19 using DecoderResult = com.google.zxing.common.DecoderResult;\r
20 namespace com.google.zxing.datamatrix.decoder\r
21 {\r
22         \r
23         /// <summary> <p>Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes\r
24         /// in one Data Matrix Code. This class decodes the bits back into text.</p>\r
25         /// \r
26         /// <p>See ISO 16022:2006, 5.2.1 - 5.2.9.2</p>\r
27         /// \r
28         /// </summary>\r
29         /// <author>  bbrown@google.com (Brian Brown)\r
30         /// </author>\r
31         /// <author>  Sean Owen\r
32         /// </author>\r
33         /// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source \r
34         /// </author>\r
35         sealed class DecodedBitStreamParser\r
36         {\r
37                 \r
38                 /// <summary> See ISO 16022:2006, Annex C Table C.1\r
39                 /// The C40 Basic Character Set (*'s used for placeholders for the shift values)\r
40                 /// </summary>\r
41                 //UPGRADE_NOTE: Final was removed from the declaration of 'C40_BASIC_SET_CHARS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"\r
42                 private static readonly char[] C40_BASIC_SET_CHARS = new char[]{'*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};\r
43                 \r
44                 //UPGRADE_NOTE: Final was removed from the declaration of 'C40_SHIFT2_SET_CHARS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"\r
45                 private static readonly char[] C40_SHIFT2_SET_CHARS = new char[]{'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'};\r
46                 \r
47                 /// <summary> See ISO 16022:2006, Annex C Table C.2\r
48                 /// The Text Basic Character Set (*'s used for placeholders for the shift values)\r
49                 /// </summary>\r
50                 //UPGRADE_NOTE: Final was removed from the declaration of 'TEXT_BASIC_SET_CHARS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"\r
51                 private static readonly char[] TEXT_BASIC_SET_CHARS = new char[]{'*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};\r
52                 \r
53                 private static char[] TEXT_SHIFT3_SET_CHARS = new char[]{'\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (char) 127};\r
54                 \r
55                 private const int PAD_ENCODE = 0; // Not really an encoding\r
56                 private const int ASCII_ENCODE = 1;\r
57                 private const int C40_ENCODE = 2;\r
58                 private const int TEXT_ENCODE = 3;\r
59                 private const int ANSIX12_ENCODE = 4;\r
60                 private const int EDIFACT_ENCODE = 5;\r
61                 private const int BASE256_ENCODE = 6;\r
62                 \r
63                 private DecodedBitStreamParser()\r
64                 {\r
65                 }\r
66                 \r
67                 internal static DecoderResult decode(sbyte[] bytes)\r
68                 {\r
69                         BitSource bits = new BitSource(bytes);\r
70                         System.Text.StringBuilder result = new System.Text.StringBuilder(100);\r
71                         System.Text.StringBuilder resultTrailer = new System.Text.StringBuilder(0);\r
72                         System.Collections.ArrayList byteSegments = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(1));\r
73                         int mode = ASCII_ENCODE;\r
74                         do \r
75                         {\r
76                                 if (mode == ASCII_ENCODE)\r
77                                 {\r
78                                         mode = decodeAsciiSegment(bits, result, resultTrailer);\r
79                                 }\r
80                                 else\r
81                                 {\r
82                                         switch (mode)\r
83                                         {\r
84                                                 \r
85                                                 case C40_ENCODE: \r
86                                                         decodeC40Segment(bits, result);\r
87                                                         break;\r
88                                                 \r
89                                                 case TEXT_ENCODE: \r
90                                                         decodeTextSegment(bits, result);\r
91                                                         break;\r
92                                                 \r
93                                                 case ANSIX12_ENCODE: \r
94                                                         decodeAnsiX12Segment(bits, result);\r
95                                                         break;\r
96                                                 \r
97                                                 case EDIFACT_ENCODE: \r
98                                                         decodeEdifactSegment(bits, result);\r
99                                                         break;\r
100                                                 \r
101                                                 case BASE256_ENCODE: \r
102                                                         decodeBase256Segment(bits, result, byteSegments);\r
103                                                         break;\r
104                                                 \r
105                                                 default: \r
106                                                         throw ReaderException.Instance;\r
107                                                 \r
108                                         }\r
109                                         mode = ASCII_ENCODE;\r
110                                 }\r
111                         }\r
112                         while (mode != PAD_ENCODE && bits.available() > 0);\r
113                         if (resultTrailer.Length > 0)\r
114                         {\r
115                                 result.Append(resultTrailer.ToString());\r
116                         }\r
117                         return new DecoderResult(bytes, result.ToString(), (byteSegments.Count == 0)?null:byteSegments, null);\r
118                 }\r
119                 \r
120                 /// <summary> See ISO 16022:2006, 5.2.3 and Annex C, Table C.2</summary>\r
121                 private static int decodeAsciiSegment(BitSource bits, System.Text.StringBuilder result, System.Text.StringBuilder resultTrailer)\r
122                 {\r
123                         bool upperShift = false;\r
124                         do \r
125                         {\r
126                                 int oneByte = bits.readBits(8);\r
127                                 if (oneByte == 0)\r
128                                 {\r
129                                         throw ReaderException.Instance;\r
130                                 }\r
131                                 else if (oneByte <= 128)\r
132                                 {\r
133                                         // ASCII data (ASCII value + 1)\r
134                                         oneByte = upperShift?(oneByte + 128):oneByte;\r
135                                         upperShift = false;\r
136                                         result.Append((char) (oneByte - 1));\r
137                                         return ASCII_ENCODE;\r
138                                 }\r
139                                 else if (oneByte == 129)\r
140                                 {\r
141                                         // Pad\r
142                                         return PAD_ENCODE;\r
143                                 }\r
144                                 else if (oneByte <= 229)\r
145                                 {\r
146                                         // 2-digit data 00-99 (Numeric Value + 130)\r
147                                         int value_Renamed = oneByte - 130;\r
148                                         if (value_Renamed < 10)\r
149                                         {\r
150                                                 // padd with '0' for single digit values\r
151                                                 result.Append('0');\r
152                                         }\r
153                                         result.Append(value_Renamed);\r
154                                 }\r
155                                 else if (oneByte == 230)\r
156                                 {\r
157                                         // Latch to C40 encodation\r
158                                         return C40_ENCODE;\r
159                                 }\r
160                                 else if (oneByte == 231)\r
161                                 {\r
162                                         // Latch to Base 256 encodation\r
163                                         return BASE256_ENCODE;\r
164                                 }\r
165                                 else if (oneByte == 232)\r
166                                 {\r
167                                         // FNC1\r
168                                         //throw ReaderException.getInstance();\r
169                                         // Ignore this symbol for now\r
170                                 }\r
171                                 else if (oneByte == 233)\r
172                                 {\r
173                                         // Structured Append\r
174                                         //throw ReaderException.getInstance();\r
175                                         // Ignore this symbol for now\r
176                                 }\r
177                                 else if (oneByte == 234)\r
178                                 {\r
179                                         // Reader Programming\r
180                                         //throw ReaderException.getInstance();\r
181                                         // Ignore this symbol for now\r
182                                 }\r
183                                 else if (oneByte == 235)\r
184                                 {\r
185                                         // Upper Shift (shift to Extended ASCII)\r
186                                         upperShift = true;\r
187                                 }\r
188                                 else if (oneByte == 236)\r
189                                 {\r
190                                         // 05 Macro\r
191                                         result.Append("[)>\u001E05\u001D");\r
192                                         resultTrailer.Insert(0, "\u001E\u0004");\r
193                                 }\r
194                                 else if (oneByte == 237)\r
195                                 {\r
196                                         // 06 Macro\r
197                                         result.Append("[)>\u001E06\u001D");\r
198                                         resultTrailer.Insert(0, "\u001E\u0004");\r
199                                 }\r
200                                 else if (oneByte == 238)\r
201                                 {\r
202                                         // Latch to ANSI X12 encodation\r
203                                         return ANSIX12_ENCODE;\r
204                                 }\r
205                                 else if (oneByte == 239)\r
206                                 {\r
207                                         // Latch to Text encodation\r
208                                         return TEXT_ENCODE;\r
209                                 }\r
210                                 else if (oneByte == 240)\r
211                                 {\r
212                                         // Latch to EDIFACT encodation\r
213                                         return EDIFACT_ENCODE;\r
214                                 }\r
215                                 else if (oneByte == 241)\r
216                                 {\r
217                                         // ECI Character\r
218                                         // TODO(bbrown): I think we need to support ECI\r
219                                         //throw ReaderException.getInstance();\r
220                                         // Ignore this symbol for now\r
221                                 }\r
222                                 else if (oneByte >= 242)\r
223                                 {\r
224                                         // Not to be used in ASCII encodation\r
225                                         throw ReaderException.Instance;\r
226                                 }\r
227                         }\r
228                         while (bits.available() > 0);\r
229                         return ASCII_ENCODE;\r
230                 }\r
231                 \r
232                 /// <summary> See ISO 16022:2006, 5.2.5 and Annex C, Table C.1</summary>\r
233                 private static void  decodeC40Segment(BitSource bits, System.Text.StringBuilder result)\r
234                 {\r
235                         // Three C40 values are encoded in a 16-bit value as\r
236                         // (1600 * C1) + (40 * C2) + C3 + 1\r
237                         // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time\r
238                         bool upperShift = false;\r
239                         \r
240                         int[] cValues = new int[3];\r
241                         do \r
242                         {\r
243                                 // If there is only one byte left then it will be encoded as ASCII\r
244                                 if (bits.available() == 8)\r
245                                 {\r
246                                         return ;\r
247                                 }\r
248                                 int firstByte = bits.readBits(8);\r
249                                 if (firstByte == 254)\r
250                                 {\r
251                                         // Unlatch codeword\r
252                                         return ;\r
253                                 }\r
254                                 \r
255                                 parseTwoBytes(firstByte, bits.readBits(8), cValues);\r
256                                 \r
257                                 int shift = 0;\r
258                                 for (int i = 0; i < 3; i++)\r
259                                 {\r
260                                         int cValue = cValues[i];\r
261                                         switch (shift)\r
262                                         {\r
263                                                 \r
264                                                 case 0: \r
265                                                         if (cValue < 3)\r
266                                                         {\r
267                                                                 shift = cValue + 1;\r
268                                                         }\r
269                                                         else\r
270                                                         {\r
271                                                                 if (upperShift)\r
272                                                                 {\r
273                                                                         result.Append((char) (C40_BASIC_SET_CHARS[cValue] + 128));\r
274                                                                         upperShift = false;\r
275                                                                 }\r
276                                                                 else\r
277                                                                 {\r
278                                                                         result.Append(C40_BASIC_SET_CHARS[cValue]);\r
279                                                                 }\r
280                                                         }\r
281                                                         break;\r
282                                                 \r
283                                                 case 1: \r
284                                                         if (upperShift)\r
285                                                         {\r
286                                                                 result.Append((char) (cValue + 128));\r
287                                                                 upperShift = false;\r
288                                                         }\r
289                                                         else\r
290                                                         {\r
291                                                                 result.Append(cValue);\r
292                                                         }\r
293                                                         shift = 0;\r
294                                                         break;\r
295                                                 \r
296                                                 case 2: \r
297                                                         if (cValue < 27)\r
298                                                         {\r
299                                                                 if (upperShift)\r
300                                                                 {\r
301                                                                         result.Append((char) (C40_SHIFT2_SET_CHARS[cValue] + 128));\r
302                                                                         upperShift = false;\r
303                                                                 }\r
304                                                                 else\r
305                                                                 {\r
306                                                                         result.Append(C40_SHIFT2_SET_CHARS[cValue]);\r
307                                                                 }\r
308                                                         }\r
309                                                         else if (cValue == 27)\r
310                                                         {\r
311                                                                 // FNC1\r
312                                                                 throw ReaderException.Instance;\r
313                                                         }\r
314                                                         else if (cValue == 30)\r
315                                                         {\r
316                                                                 // Upper Shift\r
317                                                                 upperShift = true;\r
318                                                         }\r
319                                                         else\r
320                                                         {\r
321                                                                 throw ReaderException.Instance;\r
322                                                         }\r
323                                                         shift = 0;\r
324                                                         break;\r
325                                                 \r
326                                                 case 3: \r
327                                                         if (upperShift)\r
328                                                         {\r
329                                                                 result.Append((char) (cValue + 224));\r
330                                                                 upperShift = false;\r
331                                                         }\r
332                                                         else\r
333                                                         {\r
334                                                                 result.Append((char) (cValue + 96));\r
335                                                         }\r
336                                                         shift = 0;\r
337                                                         break;\r
338                                                 \r
339                                                 default: \r
340                                                         throw ReaderException.Instance;\r
341                                                 \r
342                                         }\r
343                                 }\r
344                         }\r
345                         while (bits.available() > 0);\r
346                 }\r
347                 \r
348                 /// <summary> See ISO 16022:2006, 5.2.6 and Annex C, Table C.2</summary>\r
349                 private static void  decodeTextSegment(BitSource bits, System.Text.StringBuilder result)\r
350                 {\r
351                         // Three Text values are encoded in a 16-bit value as\r
352                         // (1600 * C1) + (40 * C2) + C3 + 1\r
353                         // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time\r
354                         bool upperShift = false;\r
355                         \r
356                         int[] cValues = new int[3];\r
357                         do \r
358                         {\r
359                                 // If there is only one byte left then it will be encoded as ASCII\r
360                                 if (bits.available() == 8)\r
361                                 {\r
362                                         return ;\r
363                                 }\r
364                                 int firstByte = bits.readBits(8);\r
365                                 if (firstByte == 254)\r
366                                 {\r
367                                         // Unlatch codeword\r
368                                         return ;\r
369                                 }\r
370                                 \r
371                                 parseTwoBytes(firstByte, bits.readBits(8), cValues);\r
372                                 \r
373                                 int shift = 0;\r
374                                 for (int i = 0; i < 3; i++)\r
375                                 {\r
376                                         int cValue = cValues[i];\r
377                                         switch (shift)\r
378                                         {\r
379                                                 \r
380                                                 case 0: \r
381                                                         if (cValue < 3)\r
382                                                         {\r
383                                                                 shift = cValue + 1;\r
384                                                         }\r
385                                                         else\r
386                                                         {\r
387                                                                 if (upperShift)\r
388                                                                 {\r
389                                                                         result.Append((char) (TEXT_BASIC_SET_CHARS[cValue] + 128));\r
390                                                                         upperShift = false;\r
391                                                                 }\r
392                                                                 else\r
393                                                                 {\r
394                                                                         result.Append(TEXT_BASIC_SET_CHARS[cValue]);\r
395                                                                 }\r
396                                                         }\r
397                                                         break;\r
398                                                 \r
399                                                 case 1: \r
400                                                         if (upperShift)\r
401                                                         {\r
402                                                                 result.Append((char) (cValue + 128));\r
403                                                                 upperShift = false;\r
404                                                         }\r
405                                                         else\r
406                                                         {\r
407                                                                 result.Append(cValue);\r
408                                                         }\r
409                                                         shift = 0;\r
410                                                         break;\r
411                                                 \r
412                                                 case 2: \r
413                                                         // Shift 2 for Text is the same encoding as C40\r
414                                                         if (cValue < 27)\r
415                                                         {\r
416                                                                 if (upperShift)\r
417                                                                 {\r
418                                                                         result.Append((char) (C40_SHIFT2_SET_CHARS[cValue] + 128));\r
419                                                                         upperShift = false;\r
420                                                                 }\r
421                                                                 else\r
422                                                                 {\r
423                                                                         result.Append(C40_SHIFT2_SET_CHARS[cValue]);\r
424                                                                 }\r
425                                                         }\r
426                                                         else if (cValue == 27)\r
427                                                         {\r
428                                                                 // FNC1\r
429                                                                 throw ReaderException.Instance;\r
430                                                         }\r
431                                                         else if (cValue == 30)\r
432                                                         {\r
433                                                                 // Upper Shift\r
434                                                                 upperShift = true;\r
435                                                         }\r
436                                                         else\r
437                                                         {\r
438                                                                 throw ReaderException.Instance;\r
439                                                         }\r
440                                                         shift = 0;\r
441                                                         break;\r
442                                                 \r
443                                                 case 3: \r
444                                                         if (upperShift)\r
445                                                         {\r
446                                                                 result.Append((char) (TEXT_SHIFT3_SET_CHARS[cValue] + 128));\r
447                                                                 upperShift = false;\r
448                                                         }\r
449                                                         else\r
450                                                         {\r
451                                                                 result.Append(TEXT_SHIFT3_SET_CHARS[cValue]);\r
452                                                         }\r
453                                                         shift = 0;\r
454                                                         break;\r
455                                                 \r
456                                                 default: \r
457                                                         throw ReaderException.Instance;\r
458                                                 \r
459                                         }\r
460                                 }\r
461                         }\r
462                         while (bits.available() > 0);\r
463                 }\r
464                 \r
465                 /// <summary> See ISO 16022:2006, 5.2.7</summary>\r
466                 private static void  decodeAnsiX12Segment(BitSource bits, System.Text.StringBuilder result)\r
467                 {\r
468                         // Three ANSI X12 values are encoded in a 16-bit value as\r
469                         // (1600 * C1) + (40 * C2) + C3 + 1\r
470                         \r
471                         int[] cValues = new int[3];\r
472                         do \r
473                         {\r
474                                 // If there is only one byte left then it will be encoded as ASCII\r
475                                 if (bits.available() == 8)\r
476                                 {\r
477                                         return ;\r
478                                 }\r
479                                 int firstByte = bits.readBits(8);\r
480                                 if (firstByte == 254)\r
481                                 {\r
482                                         // Unlatch codeword\r
483                                         return ;\r
484                                 }\r
485                                 \r
486                                 parseTwoBytes(firstByte, bits.readBits(8), cValues);\r
487                                 \r
488                                 for (int i = 0; i < 3; i++)\r
489                                 {\r
490                                         int cValue = cValues[i];\r
491                                         if (cValue == 0)\r
492                                         {\r
493                                                 // X12 segment terminator <CR>\r
494                                                 result.Append('\r');\r
495                                         }\r
496                                         else if (cValue == 1)\r
497                                         {\r
498                                                 // X12 segment separator *\r
499                                                 result.Append('*');\r
500                                         }\r
501                                         else if (cValue == 2)\r
502                                         {\r
503                                                 // X12 sub-element separator >\r
504                                                 result.Append('>');\r
505                                         }\r
506                                         else if (cValue == 3)\r
507                                         {\r
508                                                 // space\r
509                                                 result.Append(' ');\r
510                                         }\r
511                                         else if (cValue < 14)\r
512                                         {\r
513                                                 // 0 - 9\r
514                                                 result.Append((char) (cValue + 44));\r
515                                         }\r
516                                         else if (cValue < 40)\r
517                                         {\r
518                                                 // A - Z\r
519                                                 result.Append((char) (cValue + 51));\r
520                                         }\r
521                                         else\r
522                                         {\r
523                                                 throw ReaderException.Instance;\r
524                                         }\r
525                                 }\r
526                         }\r
527                         while (bits.available() > 0);\r
528                 }\r
529                 \r
530                 private static void  parseTwoBytes(int firstByte, int secondByte, int[] result)\r
531                 {\r
532                         int fullBitValue = (firstByte << 8) + secondByte - 1;\r
533                         int temp = fullBitValue / 1600;\r
534                         result[0] = temp;\r
535                         fullBitValue -= temp * 1600;\r
536                         temp = fullBitValue / 40;\r
537                         result[1] = temp;\r
538                         result[2] = fullBitValue - temp * 40;\r
539                 }\r
540                 \r
541                 /// <summary> See ISO 16022:2006, 5.2.8 and Annex C Table C.3</summary>\r
542                 private static void  decodeEdifactSegment(BitSource bits, System.Text.StringBuilder result)\r
543                 {\r
544                         bool unlatch = false;\r
545                         do \r
546                         {\r
547                                 // If there is only two or less bytes left then it will be encoded as ASCII\r
548                                 if (bits.available() <= 16)\r
549                                 {\r
550                                         return ;\r
551                                 }\r
552                                 \r
553                                 for (int i = 0; i < 4; i++)\r
554                                 {\r
555                                         int edifactValue = bits.readBits(6);\r
556                                         \r
557                                         // Check for the unlatch character\r
558                                         if (edifactValue == 0x2B67)\r
559                                         {\r
560                                                 // 011111\r
561                                                 unlatch = true;\r
562                                                 // If we encounter the unlatch code then continue reading because the Codeword triple\r
563                                                 // is padded with 0's\r
564                                         }\r
565                                         \r
566                                         if (!unlatch)\r
567                                         {\r
568                                                 if ((edifactValue & 32) == 0)\r
569                                                 {\r
570                                                         // no 1 in the leading (6th) bit\r
571                                                         edifactValue |= 64; // Add a leading 01 to the 6 bit binary value\r
572                                                 }\r
573                                                 result.Append(edifactValue);\r
574                                         }\r
575                                 }\r
576                         }\r
577                         while (!unlatch && bits.available() > 0);\r
578                 }\r
579                 \r
580                 /// <summary> See ISO 16022:2006, 5.2.9 and Annex B, B.2</summary>\r
581                 private static void  decodeBase256Segment(BitSource bits, System.Text.StringBuilder result, System.Collections.ArrayList byteSegments)\r
582                 {\r
583                         // Figure out how long the Base 256 Segment is.\r
584                         int d1 = bits.readBits(8);\r
585                         int count;\r
586                         if (d1 == 0)\r
587                         {\r
588                                 // Read the remainder of the symbol\r
589                                 count = bits.available() / 8;\r
590                         }\r
591                         else if (d1 < 250)\r
592                         {\r
593                                 count = d1;\r
594                         }\r
595                         else\r
596                         {\r
597                                 count = 250 * (d1 - 249) + bits.readBits(8);\r
598                         }\r
599                         sbyte[] bytes = new sbyte[count];\r
600                         for (int i = 0; i < count; i++)\r
601                         {\r
602                                 bytes[i] = unrandomize255State(bits.readBits(8), i);\r
603                         }\r
604                         byteSegments.Add(SupportClass.ToByteArray(bytes));\r
605                         try\r
606                         {\r
607                                 //UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"\r
608                                 result.Append(System.Text.Encoding.GetEncoding("ISO8859_1").GetString(SupportClass.ToByteArray(bytes)));\r
609                         }\r
610                         catch (System.IO.IOException uee)\r
611                         {\r
612                                 //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"\r
613                                 throw new System.SystemException("Platform does not support required encoding: " + uee);\r
614                         }\r
615                 }\r
616                 \r
617                 /// <summary> See ISO 16022:2006, Annex B, B.2</summary>\r
618                 private static sbyte unrandomize255State(int randomizedBase256Codeword, int base256CodewordPosition)\r
619                 {\r
620                         int pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;\r
621                         int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;\r
622                         return (sbyte) (tempVariable >= 0?tempVariable:(tempVariable + 256));\r
623                 }\r
624         }\r
625 }