OSDN Git Service

- setTimeout を setInterval に変更 (SWFヘッダを読んで FrameRate が分かった時にタイマーをかけ直し)
[flapp/flapp.git] / src / ibit.js
1 /*
2  input bit stream reader
3  (c) 2012/11/17- yoya@awm.jp
4 */
5 goog.provide('FlappIBit');
6
7 goog.scope(function() {
8
9 /**
10  * @constructor
11  */
12 FlappIBit = function() {
13     this.byteOffset = 0;
14     this.bitOffset = 0;
15     this.dataAllocLen = 0;
16     this.data = null;
17     this.dataLen = 0;
18 };
19
20 FlappIBit.prototype = {
21     input: function(data) {
22         if (typeof data === 'string') {
23             this.inputStr(data);
24         } else {
25             this.inputArray(data);
26         }
27     },
28     inputStr: function(data) {
29         var dataLen = data.length;
30         if (this.dataAllocLen < dataLen) {
31             var oldData = this.data;
32             this.data = new Uint8Array(dataLen);
33             for (var i = 0 , l = this.dataLen; i < l ; i++) {
34                 this.data[i] = data.charCodeAt(i);
35             }
36             this.dataAllocLen = dataLen;
37         }
38         for (var i = this.dataLen ; i < dataLen ; i++) {
39             this.data[i] = data.charCodeAt(i);
40         }
41         this.dataLen = dataLen;
42     },
43     inputArray: function(data) {
44         this.data = data;
45         this.dataAllocLen = this.dataLen = data.length;
46     },
47     len: function() { // data lengh
48         return this.dataLen;
49     },
50     hasNext: function(len) {
51         var nextOffset = this.byteOffset + (this.bitOffset?1:0) + len;
52         return (nextOffset < this.dataLen);
53     },
54     getBytePos: function() { // get byte position
55         return this.byteOffset;
56     },
57     setPos: function(byteOffset, bitOffset) { // set byte position
58         this.byteOffset = byteOffset;
59         this.bitOffset = bitOffset;
60     },
61     seek: function(byteDelta, bitDelta) { // relative seek
62         this.byteOffset += byteDelta;
63         this.bitOffset += bitDelta;
64         if (this.bitOffset < 0) {
65             do {
66                 this.byteOffset --;
67                 this.bitOffset += 8;
68             } while (this.bitOffset < 0);
69         } else if (this.bitOffset > 7) {
70             do {
71                 this.byteOffset ++;
72                 this.bitOffset -= 8;
73             } while (this.bitOffset > 7);
74         }
75     },
76     a: function() { // skip bit
77         if (this.bitOffset) {
78             this.byteOffset++;
79             this.bitOffset = 0;
80         }
81     },
82     b: function() { // bit
83         var value = (this.data[this.byteOffset] >>> (7 - this.bitOffset++)) & 1;
84         if (this.bitOffset === 8) {
85             this.byteOffset++;
86             this.bitOffset = 0;
87         }
88         return value;
89     },
90     ub: function(len) { // unsigned bits
91         var value = 0;
92         while (len--) {
93             value = (value << 1) | this.b();
94         }
95         return value;
96     },
97     sb: function(len) { // signed bits
98         var value = 0;
99         if (len === 0) return 0; // XXX
100         var msb = this.b();
101         if (msb) {
102             var orig_len = len;
103         }
104         while (--len) {
105             value = (value << 1) | this.b();
106         }
107         if (msb) {
108             return value - (1 << (orig_len - 1));
109         }
110         return value;
111     },
112     si8: function() { // snsigned 8-bit integer
113         var value = this.ui8();
114         return (value & 0x80)?(value - 0x100):value;
115     },
116     si16: function() { // snsigned 16-bit integer
117         var value = this.ui16();
118         return (value & 0x8000)?(value - 0x10000):value;
119
120     },
121     si32: function() { // snsigned 32-bit integer
122         var value = this.ui32();
123         return (value & 0x80000000)?(value - 0x100000000):value;
124     },
125     ui8: function() { // unsigned 8-bit integer
126         this.a();
127         return this.data[this.byteOffset++];
128     },
129     ui16: function() { // unsigned 16-bit integer
130         this.a();
131         return this.data[this.byteOffset++] |
132             (this.data[this.byteOffset++] << 8);
133     },
134     ui32: function() { // unsigned 32-bit integer
135         this.a();
136         return this.data[this.byteOffset++] |
137             (this.data[this.byteOffset++] << 8) |
138             (this.data[this.byteOffset++] << 16) |
139             (this.data[this.byteOffset++] << 24);
140     },
141     ui16be: function() { // unsigned 16-bit integer
142         this.a();
143         return (this.data[this.byteOffset++] << 8) |
144             this.data[this.byteOffset++];
145     },
146     sub: function(len) {
147         this.a();
148         var data = this.data.subarray(this.byteOffset, this.byteOffset + len);
149         this.byteOffset += len;
150         return data;
151     },
152     strN: function(len) {
153         this.a();
154         var data = this.data;
155         var str = [];
156         for (var i = this.byteOffset, l = this.byteOffset + len ; i < len ; i++) {
157             str.push(String.fromCharCode(data[i]))
158         }
159         this.byteOffset += len;
160 //          return new FlappUTF8().fromSJISArray(data);
161         return str.join('');
162     },
163     str: function(len) {
164         this.a();
165         var byteOffset = this.byteOffset;
166         var dataLen = this.dataLen;
167         var data;
168         for (var i = byteOffset ; i < dataLen ; i++) {
169             if (this.data[i] === 0) {
170                 data = this.strN(i - byteOffset);
171                 this.byteOffset++; // skip "\0"
172                 return data;
173             }
174         }
175         return this.strN(i - byteOffset);
176     }
177 };
178
179 });