Issues 155.2 -- add %f for format
[zxing.git] / csharp / common / BitSource.cs
1 /*\r
2 * Copyright 2007 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 namespace com.google.zxing.common\r
18 {\r
19         \r
20         /// <summary> <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the\r
21         /// number of bits read is not often a multiple of 8.</p>\r
22         /// \r
23         /// <p>This class is thread-safe but not reentrant. Unless the caller modifies the bytes array\r
24         /// it passed in, in which case all bets are off.</p>\r
25         /// \r
26         /// </summary>\r
27         /// <author>  Sean Owen\r
28         /// </author>\r
29         /// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source \r
30         /// </author>\r
31         public sealed class BitSource\r
32         {\r
33                 \r
34                 //UPGRADE_NOTE: Final was removed from the declaration of 'bytes '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"\r
35                 private sbyte[] bytes;\r
36                 private int byteOffset;\r
37                 private int bitOffset;\r
38                 \r
39                 /// <param name="bytes">bytes from which this will read bits. Bits will be read from the first byte first.\r
40                 /// Bits are read within a byte from most-significant to least-significant bit.\r
41                 /// </param>\r
42                 public BitSource(sbyte[] bytes)\r
43                 {\r
44                         this.bytes = bytes;\r
45                 }\r
46                 \r
47                 /// <param name="numBits">number of bits to read\r
48                 /// </param>\r
49                 /// <returns> int representing the bits read. The bits will appear as the least-significant\r
50                 /// bits of the int\r
51                 /// </returns>\r
52                 /// <throws>  IllegalArgumentException if numBits isn't in [1,32] </throws>\r
53                 public int readBits(int numBits)\r
54                 {\r
55                         if (numBits < 1 || numBits > 32)\r
56                         {\r
57                                 throw new System.ArgumentException();\r
58                         }\r
59                         \r
60                         int result = 0;\r
61                         \r
62                         // First, read remainder from current byte\r
63                         if (bitOffset > 0)\r
64                         {\r
65                                 int bitsLeft = 8 - bitOffset;\r
66                                 int toRead = numBits < bitsLeft?numBits:bitsLeft;\r
67                                 int bitsToNotRead = bitsLeft - toRead;\r
68                                 int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;\r
69                                 result = (bytes[byteOffset] & mask) >> bitsToNotRead;\r
70                                 numBits -= toRead;\r
71                                 bitOffset += toRead;\r
72                                 if (bitOffset == 8)\r
73                                 {\r
74                                         bitOffset = 0;\r
75                                         byteOffset++;\r
76                                 }\r
77                         }\r
78                         \r
79                         // Next read whole bytes\r
80                         if (numBits > 0)\r
81                         {\r
82                                 while (numBits >= 8)\r
83                                 {\r
84                                         result = (result << 8) | (bytes[byteOffset] & 0xFF);\r
85                                         byteOffset++;\r
86                                         numBits -= 8;\r
87                                 }\r
88                                 \r
89                                 // Finally read a partial byte\r
90                                 if (numBits > 0)\r
91                                 {\r
92                                         int bitsToNotRead = 8 - numBits;\r
93                                         int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;\r
94                                         result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);\r
95                                         bitOffset += numBits;\r
96                                 }\r
97                         }\r
98                         \r
99                         return result;\r
100                 }\r
101                 \r
102                 /// <returns> number of bits that can be read successfully\r
103                 /// </returns>\r
104                 public int available()\r
105                 {\r
106                         return 8 * (bytes.Length - byteOffset) - bitOffset;\r
107                 }\r
108         }\r
109 }