blob: 349f4e5c6161ba96ff0fd7fcaf0f59838648de74 [file] [log] [blame]
Meki Cherkaoui97e7a592012-04-14 02:50:06 -07001
2var XML_EXT = 0x00;
3
4var XML_TAG = 0x01;
5
6var XML_DTAG = 0x02;
7
8var XML_ATTR = 0x03;
9
10var XML_DATTR = 0x04;
11
12var XML_BLOB = 0x05;
13
14var XML_UDATA = 0x06;
15
16var XML_CLOSE = 0x0;
17
18var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16;
19
20
21var XML_TT_BITS = 3;
22var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
23var XML_TT_VAL_BITS = XML_TT_BITS + 1;
24var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
25var XML_REG_VAL_BITS = 7;
26var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
27var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
28var BYTE_MASK = 0xFF;
29var LONG_BYTES = 8;
30var LONG_BITS = 64;
31
32var bits_11 = 0x0000007FF;
33var bits_18 = 0x00003FFFF;
34var bits_32 = 0x0FFFFFFFF;
35
36
37var TypeAndVal = function TypeAndVal(_type,_val) {
38 this.type = _type;
39 this.val = _val;
40
41};
42
43var BinaryXMLCodec = function BinaryXMLCodec(){
44 this.CODEC_NAME = "Binary";
45};
46
47BinaryXMLCodec.prototype.encodeTypeAndValOffset = function(
48 //int
49 type,
50 //long
51 val,
52 //byte []
53 buf,
54 //int
55 offset) {
56
57 if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
58 throw new Exception("Tag and value must be positive, and tag valid.");
59 }
60
61 // Encode backwards. Calculate how many bytes we need:
62 var/*int*/ numEncodingBytes = numEncodingBytes(val);
63
64 if ((offset + numEncodingBytes) > buf.length) {
65 throw new Exception("Buffer space of " + (buf.length-offset) +
66 " bytes insufficient to hold " +
67 numEncodingBytes + " of encoded type and value.");
68 }
69
70
71 buf[offset + numEncodingBytes - 1] =
72 (BYTE_MASK &
73 (((XML_TT_MASK & type) |
74 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
75 XML_TT_NO_MORE);
76 val = val >>> XML_TT_VAL_BITS;;
77
78 var /*int*/ i = offset + numEncodingBytes - 2;
79 while ((0 != val) && (i >= offset)) {
80 buf[i] = (BYTE_MASK &
81 (val & XML_REG_VAL_MASK));
82 val = val >>> XML_REG_VAL_BITS;
83 --i;
84 }
85
86 return numEncodingBytes;
87};
88
89//BinaryXMLCodec.prototype.encodeTypeAndVal = function(
90 // //final int
91 //type,
92 //final long
93 //value,
94 //final OutputStream
95 //ostream,
96 //offset){
97
98 /*
99 We exploit the fact that encoding is done from the right, so this actually means
100 there is a deterministic encoding from a long to a Type/Value pair:
101
102 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
103 |ABCD.EFGH|IJKL.MNOP|QRST.UVWX|YZ01.2345|6789.abcd|efgh.ijkl|mnop.qrst|uvwx.yz@#
104
105 60> 53> 46> 39> 32> 25> 18> 11> 4>
106 |_000.ABCD|_EFG.HIJK|_LMN.OPQR|_STU.VWXY|_Z01.2345|_678.9abc|_defg.hij|_klm.nopq|_rst.uvwx|_yz@#___
107
108 What we want to do is compute the result in MSB order and write it directly
109 to the channel without any intermediate form.
110 */
111
112 //var/*int*/ bits;
113 //var/*int*/ count = 0;
114
115 // once we start writing bits, we keep writing bits even if they are "0"
116 // var/*bool*/ writing = false;
117
118 // a few heuristic to catch the small-bit length patterns
119 /*if( value < 0 || value > 15 ) {
120 var start = 60;
121 if( 0 <= value ) {
122 if( value < bits_11 )
123 start = 4;
124 else if( value < bits_18 )
125 start = 11;
126 else if( value < bits_32 )
127 start = 25;
128 }
129
130 for( var i = start; i >= 4; i -= 7) {
131 bits = (value >>> i) & BinaryXMLCodec.XML_REG_VAL_MASK;
132 if( bits != 0 || writing ) {
133 ostream.write(bits);
134 count++;
135 writing = true;
136 }
137 }
138 }
139
140 // Explicit computation of the bottom byte
141 bits = type & BinaryXMLCodec.XML_TT_MASK;
142 var bottom4 = value & BinaryXMLCodec.XML_TT_VAL_MASK;
143 bits |= bottom4 << BinaryXMLCodec.XML_TT_BITS;
144 // the bottom byte always has the NO_MORE flag
145 bits |= BinaryXMLCodec.XML_TT_NO_MORE;
146
147 //console.log(ostream.constructor.name);
148 //console.log(ostream);
149
150 //ostream.writable = true;
151 //console.log(ostream.)
152 ostream.write(bits.toString());
153
154 count++;
155
156// byte [] encoding = encodeTypeAndVal(tag, val);
157// ostream.write(encoding);
158 return count;
159
160}*/
161
162
163BinaryXMLCodec.prototype.encodeTypeAndVal = function(
164 //int
165 type,
166 //long
167 val,
168 //byte []
169 buf,
170 //int
171 offset) {
172
173 if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
174 throw new Exception("Tag and value must be positive, and tag valid.");
175 }
176
177 // Encode backwards. Calculate how many bytes we need:
178 //int
179 var numEncodingBytes = numEncodingBytes(val);
180
181 if ((offset + numEncodingBytes) > buf.length) {
182 throw new Exception("Buffer space of " + (buf.length-offset) +
183 " bytes insufficient to hold " +
184 numEncodingBytes + " of encoded type and value.");
185 }
186
187 // Bottom 4 bits of val go in last byte with tag.
188 buf[offset + numEncodingBytes - 1] =
189 //(byte)
190 (BYTE_MASK &
191 (((XML_TT_MASK & type) |
192 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
193 XML_TT_NO_MORE); // set top bit for last byte
194 val = val >>> XML_TT_VAL_BITS;;
195
196 // Rest of val goes into preceding bytes, 7 bits per byte, top bit
197 // is "more" flag.
198 var i = offset + numEncodingBytes - 2;
199 while ((0 != val) && (i >= offset)) {
200 buf[i] = //(byte)
201 (BYTE_MASK &
202 (val & XML_REG_VAL_MASK)); // leave top bit unset
203 val = val >>> XML_REG_VAL_BITS;
204 --i;
205 }
206 if (val != 0) {
207 throw new Exception( "This should not happen: miscalculated encoding");
208 //Log.warning(Log.FAC_ENCODING, "This should not happen: miscalculated encoding length, have " + val + " left.");
209 }
210
211 return numEncodingBytes;
212}
213
214
215
216BinaryXMLCodec.prototype.decodeTypeAndVal = function(
217 /*InputStream*/
218 istream) {
219
220 /*int*/next;
221 /*int*/type = -1;
222 /*long*/val = 0;
223 /*boolean*/more = true;
224
225 do {
226 next = istream.read();
227
228 if (next < 0) {
229 return null;
230 }
231
232 if ((0 == next) && (0 == val)) {
233 return null;
234 }
235
236 more = (0 == (next & XML_TT_NO_MORE));
237
238 if (more) {
239 val = val << XML_REG_VAL_BITS;
240 val |= (next & XML_REG_VAL_MASK);
241 } else {
242
243 type = next & XML_TT_MASK;
244 val = val << XML_TT_VAL_BITS;
245 val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
246 }
247
248 } while (more);
249
250 return new TypeAndVal(type, val);
251};
252
253BinaryXMLCodec.prototype.encodeUString = function(
254 //OutputStream
255 ostream,
256 //String
257 ustring,
258 //byte
259 type,
260 offset) {
261
262 // We elide the encoding of a 0-length UString
263 if ((null == ustring) || (ustring.length == 0)) {
264 //if (Log.isLoggable(Log.FAC_ENCODING, Level.FINER))
265 //Log.finer(Log.FAC_ENCODING, "Eliding 0-length UString.");
266 return;
267 }
268
269 //byte [] data utils
270 /*custom*/
271 //byte[]
272 strBytes = new Array(ustring.Length);
273 var i = 0;
274 for( ;i<ustring.lengh;i++) //in InStr.ToCharArray())
275 {
276 strBytes[i] = ustring[i];
277 }
278 //strBytes = DataUtils.getBytesFromUTF8String(ustring);
279
280 this.encodeTypeAndVal(type,
281 (((type == XML_TAG) || (type == XML_ATTR)) ?
282 (strBytes.length-1) :
283 strBytes.length), ostream);
284 //
285 console.log(strBytes.toString());
286
287 ostream.write(strBytes.toString(),offset);
288
289 //
290};
291
292BinaryXMLCodec.prototype.encodeBlob = function(
293 //OutputStream
294 ostream,
295 //byte []
296 blob,
297 //int
298 offset,
299 //int
300 length) {
301 // We elide the encoding of a 0-length blob
302 if ((null == blob) || (length == 0)) {
303
304 return;
305 }
306
307 encodeTypeAndVal(XML_BLOB, length, ostream,offset);
308 if (null != blob) {
309 ostream.write(blob, this.offset, length);
310 this.offset += length;
311 }
312};
313
314
315var ENCODING_LIMIT_1_BYTE = ((1 << (XML_TT_VAL_BITS)) - 1);
316var ENCODING_LIMIT_2_BYTES = ((1 << (XML_TT_VAL_BITS + XML_REG_VAL_BITS)) - 1);
317var ENCODING_LIMIT_3_BYTES = ((1 << (XML_TT_VAL_BITS + 2 * XML_REG_VAL_BITS)) - 1);
318
319var numEncodingBytes = function(
320 //long
321 x) {
322 if (x <= ENCODING_LIMIT_1_BYTE) return (1);
323 if (x <= ENCODING_LIMIT_2_BYTES) return (2);
324 if (x <= ENCODING_LIMIT_3_BYTES) return (3);
325
326 var numbytes = 1;
327
328 // Last byte gives you XML_TT_VAL_BITS
329 // Remainder each give you XML_REG_VAL_BITS
330 x = x >>> XML_TT_VAL_BITS;
331 while (x != 0) {
332 numbytes++;
333 x = x >>> XML_REG_VAL_BITS;
334 }
335 return (numbytes);
336}
337
338//TODO