正在显示
26 个修改的文件
包含
4563 行增加
和
6 行删除
@@ -12,23 +12,46 @@ var userController =function (){ | @@ -12,23 +12,46 @@ var userController =function (){ | ||
12 | userController.prototype.addUser = async(ctx, next) =>{ | 12 | userController.prototype.addUser = async(ctx, next) =>{ |
13 | var params = ctx.request.body; | 13 | var params = ctx.request.body; |
14 | const pw = saitMd5.md5AddSalt(params.password) | 14 | const pw = saitMd5.md5AddSalt(params.password) |
15 | + console.dir(params.password.length,7) | ||
16 | + console.dir(params.password.length<6) | ||
17 | + | ||
15 | 18 | ||
16 | if(!params.loginName){ | 19 | if(!params.loginName){ |
17 | return status.paramError('loginName'); | 20 | return status.paramError('loginName'); |
18 | }else if(!params.password){ | 21 | }else if(!params.password){ |
19 | - return status.paramError('password',' 不能为空'); | 22 | + return status.paramError('password','不能为空'); |
23 | + }if(params.password.length < 6){ | ||
24 | + return status.paramError('password','不得小于6位'); | ||
20 | } | 25 | } |
21 | - | ||
22 | var user = { | 26 | var user = { |
23 | loginName:params.loginName, | 27 | loginName:params.loginName, |
24 | password:pw.md5Pass, | 28 | password:pw.md5Pass, |
25 | - salt:pw.salt | 29 | + salt:pw.salt, |
30 | + userType:params.type | ||
26 | } | 31 | } |
27 | try{ | 32 | try{ |
28 | return await userService.addUser(user) | 33 | return await userService.addUser(user) |
29 | - }catch (we){ | 34 | + }catch (e){ |
35 | + throw new Error(e); | ||
36 | + } | ||
37 | +} | ||
38 | +userController.prototype.login = async(ctx, next) =>{ | ||
39 | + const body = ctx.request.body; | ||
40 | + if(!body.name){ | ||
41 | + return status.paramError('name'); | ||
42 | + }else if(!body.password){ | ||
43 | + return status.paramError('password'); | ||
44 | + } | ||
30 | 45 | ||
46 | + try{ | ||
47 | + // let userData = await userService.login(body.name ,body.password); | ||
48 | + // delete userData.password; | ||
49 | + // delete userData.salt; | ||
50 | + return await userService.login(body.name ,body.password); | ||
51 | + | ||
52 | + }catch (we){ | ||
53 | + throw new Error(we) | ||
31 | } | 54 | } |
32 | - | 55 | + |
33 | } | 56 | } |
34 | module.exports = new userController(); | 57 | module.exports = new userController(); |
docs/api.md
0 → 100644
1 | +# 网校接口文档 | ||
2 | + | ||
3 | + | ||
4 | +## 用户管理 | ||
5 | + | ||
6 | +### 用户注册 | ||
7 | + | ||
8 | +请求url: | ||
9 | + | ||
10 | + POST /users/addUser | ||
11 | + | ||
12 | +请求参数: | ||
13 | + | ||
14 | +名称|类型|描述 | ||
15 | +:--|:--|:-- | ||
16 | +|loginName |string |必须, 登录名 | | ||
17 | +|password |string |必须,密码 | | ||
18 | +|type | int |用户类型:0管理员 1监课 2老师 4学生 | | ||
19 | + | ||
20 | +请求示例: | ||
21 | + | ||
22 | + localhost:3000/users/addUser | ||
23 | + | ||
24 | + body | ||
25 | + { | ||
26 | + "loginName": "admin", | ||
27 | + "telephone": 11112112, | ||
28 | + "password": "123456", | ||
29 | + "type":1 | ||
30 | + } | ||
31 | +返回参数: | ||
32 | + | ||
33 | + { | ||
34 | + "id": "XWBreEM4OK0a5jQB2Q1bpkNlyq9AVmvd",// 用户ID | ||
35 | + "createTime": "2017-08-22T08:51:59.000Z", //创建时间 | ||
36 | + "endTime": "2017-08-22T08:51:59.000Z", | ||
37 | + "loginName": "admin", //登录名 | ||
38 | + "userType": 1 // 用户类型 | ||
39 | +} | ||
40 | + | ||
41 | +### 用户登录 | ||
42 | + | ||
43 | +请求url | ||
44 | + | ||
45 | + POST /users/login | ||
46 | + | ||
47 | +请求参数: | ||
48 | + | ||
49 | +名称|类型|描述 | ||
50 | +:--|:--|:-- | ||
51 | +|name |string |必须, 登录名 | | ||
52 | +|password |string |必须,密码 | | ||
53 | + | ||
54 | + | ||
55 | +请求示例: | ||
56 | + | ||
57 | + localhost:3000/users/login | ||
58 | + | ||
59 | + body | ||
60 | + { | ||
61 | + "name":"admin", | ||
62 | + "password":"123456" | ||
63 | + } | ||
64 | +返回参数: | ||
65 | + | ||
66 | + | ||
67 | + |
1 | +Tue Aug 22 2017 18:52:38 GMT+0800 (CST) |
node_modules/_bson@1.0.4@bson/HISTORY.md
0 → 100644
1 | +1.0.4 2016-01-11 | ||
2 | +---------------- | ||
3 | +- #204 remove Buffer.from as it's partially broken in early 4.x.x. series of node releases. | ||
4 | + | ||
5 | +1.0.3 2016-01-03 | ||
6 | +---------------- | ||
7 | +- Fixed toString for ObjectId so it will work with inspect. | ||
8 | + | ||
9 | +1.0.2 2016-01-02 | ||
10 | +---------------- | ||
11 | +- Minor optimizations for ObjectID to use Buffer.from where available. | ||
12 | + | ||
13 | +1.0.1 2016-12-06 | ||
14 | +---------------- | ||
15 | +- Reverse behavior for undefined to be serialized as NULL. MongoDB 3.4 does not allow for undefined comparisons. | ||
16 | + | ||
17 | +1.0.0 2016-12-06 | ||
18 | +---------------- | ||
19 | +- Introduced new BSON API and documentation. | ||
20 | + | ||
21 | +0.5.7 2016-11-18 | ||
22 | +----------------- | ||
23 | +- NODE-848 BSON Regex flags must be alphabetically ordered. | ||
24 | + | ||
25 | +0.5.6 2016-10-19 | ||
26 | +----------------- | ||
27 | +- NODE-833, Detects cyclic dependencies in documents and throws error if one is found. | ||
28 | +- Fix(deserializer): corrected the check for (size + index) comparison… (Issue #195, https://github.com/JoelParke). | ||
29 | + | ||
30 | +0.5.5 2016-09-15 | ||
31 | +----------------- | ||
32 | +- Added DBPointer up conversion to DBRef | ||
33 | + | ||
34 | +0.5.4 2016-08-23 | ||
35 | +----------------- | ||
36 | +- Added promoteValues flag (default to true) allowing user to specify if deserialization should be into wrapper classes only. | ||
37 | + | ||
38 | +0.5.3 2016-07-11 | ||
39 | +----------------- | ||
40 | +- Throw error if ObjectId is not a string or a buffer. | ||
41 | + | ||
42 | +0.5.2 2016-07-11 | ||
43 | +----------------- | ||
44 | +- All values encoded big-endian style for ObjectId. | ||
45 | + | ||
46 | +0.5.1 2016-07-11 | ||
47 | +----------------- | ||
48 | +- Fixed encoding/decoding issue in ObjectId timestamp generation. | ||
49 | +- Removed BinaryParser dependency from the serializer/deserializer. | ||
50 | + | ||
51 | +0.5.0 2016-07-05 | ||
52 | +----------------- | ||
53 | +- Added Decimal128 type and extended test suite to include entire bson corpus. | ||
54 | + | ||
55 | +0.4.23 2016-04-08 | ||
56 | +----------------- | ||
57 | +- Allow for proper detection of ObjectId or objects that look like ObjectId, improving compatibility across third party libraries. | ||
58 | +- Remove one package from dependency due to having been pulled from NPM. | ||
59 | + | ||
60 | +0.4.22 2016-03-04 | ||
61 | +----------------- | ||
62 | +- Fix "TypeError: data.copy is not a function" in Electron (Issue #170, https://github.com/kangas). | ||
63 | +- Fixed issue with undefined type on deserializing. | ||
64 | + | ||
65 | +0.4.21 2016-01-12 | ||
66 | +----------------- | ||
67 | +- Minor optimizations to avoid non needed object creation. | ||
68 | + | ||
69 | +0.4.20 2015-10-15 | ||
70 | +----------------- | ||
71 | +- Added bower file to repository. | ||
72 | +- Fixed browser pid sometimes set greater than 0xFFFF on browsers (Issue #155, https://github.com/rahatarmanahmed) | ||
73 | + | ||
74 | +0.4.19 2015-10-15 | ||
75 | +----------------- | ||
76 | +- Remove all support for bson-ext. | ||
77 | + | ||
78 | +0.4.18 2015-10-15 | ||
79 | +----------------- | ||
80 | +- ObjectID equality check should return boolean instead of throwing exception for invalid oid string #139 | ||
81 | +- add option for deserializing binary into Buffer object #116 | ||
82 | + | ||
83 | +0.4.17 2015-10-15 | ||
84 | +----------------- | ||
85 | +- Validate regexp string for null bytes and throw if there is one. | ||
86 | + | ||
87 | +0.4.16 2015-10-07 | ||
88 | +----------------- | ||
89 | +- Fixed issue with return statement in Map.js. | ||
90 | + | ||
91 | +0.4.15 2015-10-06 | ||
92 | +----------------- | ||
93 | +- Exposed Map correctly via index.js file. | ||
94 | + | ||
95 | +0.4.14 2015-10-06 | ||
96 | +----------------- | ||
97 | +- Exposed Map correctly via bson.js file. | ||
98 | + | ||
99 | +0.4.13 2015-10-06 | ||
100 | +----------------- | ||
101 | +- Added ES6 Map type serialization as well as a polyfill for ES5. | ||
102 | + | ||
103 | +0.4.12 2015-09-18 | ||
104 | +----------------- | ||
105 | +- Made ignore undefined an optional parameter. | ||
106 | + | ||
107 | +0.4.11 2015-08-06 | ||
108 | +----------------- | ||
109 | +- Minor fix for invalid key checking. | ||
110 | + | ||
111 | +0.4.10 2015-08-06 | ||
112 | +----------------- | ||
113 | +- NODE-38 Added new BSONRegExp type to allow direct serialization to MongoDB type. | ||
114 | +- Some performance improvements by in lining code. | ||
115 | + | ||
116 | +0.4.9 2015-08-06 | ||
117 | +---------------- | ||
118 | +- Undefined fields are omitted from serialization in objects. | ||
119 | + | ||
120 | +0.4.8 2015-07-14 | ||
121 | +---------------- | ||
122 | +- Fixed size validation to ensure we can deserialize from dumped files. | ||
123 | + | ||
124 | +0.4.7 2015-06-26 | ||
125 | +---------------- | ||
126 | +- Added ability to instruct deserializer to return raw BSON buffers for named array fields. | ||
127 | +- Minor deserialization optimization by moving inlined function out. | ||
128 | + | ||
129 | +0.4.6 2015-06-17 | ||
130 | +---------------- | ||
131 | +- Fixed serializeWithBufferAndIndex bug. | ||
132 | + | ||
133 | +0.4.5 2015-06-17 | ||
134 | +---------------- | ||
135 | +- Removed any references to the shared buffer to avoid non GC collectible bson instances. | ||
136 | + | ||
137 | +0.4.4 2015-06-17 | ||
138 | +---------------- | ||
139 | +- Fixed rethrowing of error when not RangeError. | ||
140 | + | ||
141 | +0.4.3 2015-06-17 | ||
142 | +---------------- | ||
143 | +- Start buffer at 64K and double as needed, meaning we keep a low memory profile until needed. | ||
144 | + | ||
145 | +0.4.2 2015-06-16 | ||
146 | +---------------- | ||
147 | +- More fixes for corrupt Bson | ||
148 | + | ||
149 | +0.4.1 2015-06-16 | ||
150 | +---------------- | ||
151 | +- More fixes for corrupt Bson | ||
152 | + | ||
153 | +0.4.0 2015-06-16 | ||
154 | +---------------- | ||
155 | +- New JS serializer serializing into a single buffer then copying out the new buffer. Performance is similar to current C++ parser. | ||
156 | +- Removed bson-ext extension dependency for now. | ||
157 | + | ||
158 | +0.3.2 2015-03-27 | ||
159 | +---------------- | ||
160 | +- Removed node-gyp from install script in package.json. | ||
161 | + | ||
162 | +0.3.1 2015-03-27 | ||
163 | +---------------- | ||
164 | +- Return pure js version on native() call if failed to initialize. | ||
165 | + | ||
166 | +0.3.0 2015-03-26 | ||
167 | +---------------- | ||
168 | +- Pulled out all C++ code into bson-ext and made it an optional dependency. | ||
169 | + | ||
170 | +0.2.21 2015-03-21 | ||
171 | +----------------- | ||
172 | +- Updated Nan to 1.7.0 to support io.js and node 0.12.0 | ||
173 | + | ||
174 | +0.2.19 2015-02-16 | ||
175 | +----------------- | ||
176 | +- Updated Nan to 1.6.2 to support io.js and node 0.12.0 | ||
177 | + | ||
178 | +0.2.18 2015-01-20 | ||
179 | +----------------- | ||
180 | +- Updated Nan to 1.5.1 to support io.js | ||
181 | + | ||
182 | +0.2.16 2014-12-17 | ||
183 | +----------------- | ||
184 | +- Made pid cycle on 0xffff to avoid weird overflows on creation of ObjectID's | ||
185 | + | ||
186 | +0.2.12 2014-08-24 | ||
187 | +----------------- | ||
188 | +- Fixes for fortify review of c++ extension | ||
189 | +- toBSON correctly allows returns of non objects | ||
190 | + | ||
191 | +0.2.3 2013-10-01 | ||
192 | +---------------- | ||
193 | +- Drying of ObjectId code for generation of id (Issue #54, https://github.com/moredip) | ||
194 | +- Fixed issue where corrupt CString's could cause endless loop | ||
195 | +- Support for Node 0.11.X > (Issue #49, https://github.com/kkoopa) | ||
196 | + | ||
197 | +0.1.4 2012-09-25 | ||
198 | +---------------- | ||
199 | +- Added precompiled c++ native extensions for win32 ia32 and x64 |
node_modules/_bson@1.0.4@bson/LICENSE.md
0 → 100644
1 | + Apache License | ||
2 | + Version 2.0, January 2004 | ||
3 | + http://www.apache.org/licenses/ | ||
4 | + | ||
5 | + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
6 | + | ||
7 | + 1. Definitions. | ||
8 | + | ||
9 | + "License" shall mean the terms and conditions for use, reproduction, | ||
10 | + and distribution as defined by Sections 1 through 9 of this document. | ||
11 | + | ||
12 | + "Licensor" shall mean the copyright owner or entity authorized by | ||
13 | + the copyright owner that is granting the License. | ||
14 | + | ||
15 | + "Legal Entity" shall mean the union of the acting entity and all | ||
16 | + other entities that control, are controlled by, or are under common | ||
17 | + control with that entity. For the purposes of this definition, | ||
18 | + "control" means (i) the power, direct or indirect, to cause the | ||
19 | + direction or management of such entity, whether by contract or | ||
20 | + otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
21 | + outstanding shares, or (iii) beneficial ownership of such entity. | ||
22 | + | ||
23 | + "You" (or "Your") shall mean an individual or Legal Entity | ||
24 | + exercising permissions granted by this License. | ||
25 | + | ||
26 | + "Source" form shall mean the preferred form for making modifications, | ||
27 | + including but not limited to software source code, documentation | ||
28 | + source, and configuration files. | ||
29 | + | ||
30 | + "Object" form shall mean any form resulting from mechanical | ||
31 | + transformation or translation of a Source form, including but | ||
32 | + not limited to compiled object code, generated documentation, | ||
33 | + and conversions to other media types. | ||
34 | + | ||
35 | + "Work" shall mean the work of authorship, whether in Source or | ||
36 | + Object form, made available under the License, as indicated by a | ||
37 | + copyright notice that is included in or attached to the work | ||
38 | + (an example is provided in the Appendix below). | ||
39 | + | ||
40 | + "Derivative Works" shall mean any work, whether in Source or Object | ||
41 | + form, that is based on (or derived from) the Work and for which the | ||
42 | + editorial revisions, annotations, elaborations, or other modifications | ||
43 | + represent, as a whole, an original work of authorship. For the purposes | ||
44 | + of this License, Derivative Works shall not include works that remain | ||
45 | + separable from, or merely link (or bind by name) to the interfaces of, | ||
46 | + the Work and Derivative Works thereof. | ||
47 | + | ||
48 | + "Contribution" shall mean any work of authorship, including | ||
49 | + the original version of the Work and any modifications or additions | ||
50 | + to that Work or Derivative Works thereof, that is intentionally | ||
51 | + submitted to Licensor for inclusion in the Work by the copyright owner | ||
52 | + or by an individual or Legal Entity authorized to submit on behalf of | ||
53 | + the copyright owner. For the purposes of this definition, "submitted" | ||
54 | + means any form of electronic, verbal, or written communication sent | ||
55 | + to the Licensor or its representatives, including but not limited to | ||
56 | + communication on electronic mailing lists, source code control systems, | ||
57 | + and issue tracking systems that are managed by, or on behalf of, the | ||
58 | + Licensor for the purpose of discussing and improving the Work, but | ||
59 | + excluding communication that is conspicuously marked or otherwise | ||
60 | + designated in writing by the copyright owner as "Not a Contribution." | ||
61 | + | ||
62 | + "Contributor" shall mean Licensor and any individual or Legal Entity | ||
63 | + on behalf of whom a Contribution has been received by Licensor and | ||
64 | + subsequently incorporated within the Work. | ||
65 | + | ||
66 | + 2. Grant of Copyright License. Subject to the terms and conditions of | ||
67 | + this License, each Contributor hereby grants to You a perpetual, | ||
68 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
69 | + copyright license to reproduce, prepare Derivative Works of, | ||
70 | + publicly display, publicly perform, sublicense, and distribute the | ||
71 | + Work and such Derivative Works in Source or Object form. | ||
72 | + | ||
73 | + 3. Grant of Patent License. Subject to the terms and conditions of | ||
74 | + this License, each Contributor hereby grants to You a perpetual, | ||
75 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
76 | + (except as stated in this section) patent license to make, have made, | ||
77 | + use, offer to sell, sell, import, and otherwise transfer the Work, | ||
78 | + where such license applies only to those patent claims licensable | ||
79 | + by such Contributor that are necessarily infringed by their | ||
80 | + Contribution(s) alone or by combination of their Contribution(s) | ||
81 | + with the Work to which such Contribution(s) was submitted. If You | ||
82 | + institute patent litigation against any entity (including a | ||
83 | + cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
84 | + or a Contribution incorporated within the Work constitutes direct | ||
85 | + or contributory patent infringement, then any patent licenses | ||
86 | + granted to You under this License for that Work shall terminate | ||
87 | + as of the date such litigation is filed. | ||
88 | + | ||
89 | + 4. Redistribution. You may reproduce and distribute copies of the | ||
90 | + Work or Derivative Works thereof in any medium, with or without | ||
91 | + modifications, and in Source or Object form, provided that You | ||
92 | + meet the following conditions: | ||
93 | + | ||
94 | + (a) You must give any other recipients of the Work or | ||
95 | + Derivative Works a copy of this License; and | ||
96 | + | ||
97 | + (b) You must cause any modified files to carry prominent notices | ||
98 | + stating that You changed the files; and | ||
99 | + | ||
100 | + (c) You must retain, in the Source form of any Derivative Works | ||
101 | + that You distribute, all copyright, patent, trademark, and | ||
102 | + attribution notices from the Source form of the Work, | ||
103 | + excluding those notices that do not pertain to any part of | ||
104 | + the Derivative Works; and | ||
105 | + | ||
106 | + (d) If the Work includes a "NOTICE" text file as part of its | ||
107 | + distribution, then any Derivative Works that You distribute must | ||
108 | + include a readable copy of the attribution notices contained | ||
109 | + within such NOTICE file, excluding those notices that do not | ||
110 | + pertain to any part of the Derivative Works, in at least one | ||
111 | + of the following places: within a NOTICE text file distributed | ||
112 | + as part of the Derivative Works; within the Source form or | ||
113 | + documentation, if provided along with the Derivative Works; or, | ||
114 | + within a display generated by the Derivative Works, if and | ||
115 | + wherever such third-party notices normally appear. The contents | ||
116 | + of the NOTICE file are for informational purposes only and | ||
117 | + do not modify the License. You may add Your own attribution | ||
118 | + notices within Derivative Works that You distribute, alongside | ||
119 | + or as an addendum to the NOTICE text from the Work, provided | ||
120 | + that such additional attribution notices cannot be construed | ||
121 | + as modifying the License. | ||
122 | + | ||
123 | + You may add Your own copyright statement to Your modifications and | ||
124 | + may provide additional or different license terms and conditions | ||
125 | + for use, reproduction, or distribution of Your modifications, or | ||
126 | + for any such Derivative Works as a whole, provided Your use, | ||
127 | + reproduction, and distribution of the Work otherwise complies with | ||
128 | + the conditions stated in this License. | ||
129 | + | ||
130 | + 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
131 | + any Contribution intentionally submitted for inclusion in the Work | ||
132 | + by You to the Licensor shall be under the terms and conditions of | ||
133 | + this License, without any additional terms or conditions. | ||
134 | + Notwithstanding the above, nothing herein shall supersede or modify | ||
135 | + the terms of any separate license agreement you may have executed | ||
136 | + with Licensor regarding such Contributions. | ||
137 | + | ||
138 | + 6. Trademarks. This License does not grant permission to use the trade | ||
139 | + names, trademarks, service marks, or product names of the Licensor, | ||
140 | + except as required for reasonable and customary use in describing the | ||
141 | + origin of the Work and reproducing the content of the NOTICE file. | ||
142 | + | ||
143 | + 7. Disclaimer of Warranty. Unless required by applicable law or | ||
144 | + agreed to in writing, Licensor provides the Work (and each | ||
145 | + Contributor provides its Contributions) on an "AS IS" BASIS, | ||
146 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
147 | + implied, including, without limitation, any warranties or conditions | ||
148 | + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
149 | + PARTICULAR PURPOSE. You are solely responsible for determining the | ||
150 | + appropriateness of using or redistributing the Work and assume any | ||
151 | + risks associated with Your exercise of permissions under this License. | ||
152 | + | ||
153 | + 8. Limitation of Liability. In no event and under no legal theory, | ||
154 | + whether in tort (including negligence), contract, or otherwise, | ||
155 | + unless required by applicable law (such as deliberate and grossly | ||
156 | + negligent acts) or agreed to in writing, shall any Contributor be | ||
157 | + liable to You for damages, including any direct, indirect, special, | ||
158 | + incidental, or consequential damages of any character arising as a | ||
159 | + result of this License or out of the use or inability to use the | ||
160 | + Work (including but not limited to damages for loss of goodwill, | ||
161 | + work stoppage, computer failure or malfunction, or any and all | ||
162 | + other commercial damages or losses), even if such Contributor | ||
163 | + has been advised of the possibility of such damages. | ||
164 | + | ||
165 | + 9. Accepting Warranty or Additional Liability. While redistributing | ||
166 | + the Work or Derivative Works thereof, You may choose to offer, | ||
167 | + and charge a fee for, acceptance of support, warranty, indemnity, | ||
168 | + or other liability obligations and/or rights consistent with this | ||
169 | + License. However, in accepting such obligations, You may act only | ||
170 | + on Your own behalf and on Your sole responsibility, not on behalf | ||
171 | + of any other Contributor, and only if You agree to indemnify, | ||
172 | + defend, and hold each Contributor harmless for any liability | ||
173 | + incurred by, or claims asserted against, such Contributor by reason | ||
174 | + of your accepting any such warranty or additional liability. | ||
175 | + | ||
176 | + END OF TERMS AND CONDITIONS | ||
177 | + | ||
178 | + APPENDIX: How to apply the Apache License to your work. | ||
179 | + | ||
180 | + To apply the Apache License to your work, attach the following | ||
181 | + boilerplate notice, with the fields enclosed by brackets "[]" | ||
182 | + replaced with your own identifying information. (Don't include | ||
183 | + the brackets!) The text should be enclosed in the appropriate | ||
184 | + comment syntax for the file format. We also recommend that a | ||
185 | + file or class name and description of purpose be included on the | ||
186 | + same "printed page" as the copyright notice for easier | ||
187 | + identification within third-party archives. | ||
188 | + | ||
189 | + Copyright [yyyy] [name of copyright owner] | ||
190 | + | ||
191 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
192 | + you may not use this file except in compliance with the License. | ||
193 | + You may obtain a copy of the License at | ||
194 | + | ||
195 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
196 | + | ||
197 | + Unless required by applicable law or agreed to in writing, software | ||
198 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
199 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
200 | + See the License for the specific language governing permissions and | ||
201 | + limitations under the License. |
node_modules/_bson@1.0.4@bson/README.md
0 → 100644
1 | +# BSON parser | ||
2 | + | ||
3 | +If you don't yet know what BSON actually is, read [the spec](http://bsonspec.org). | ||
4 | + | ||
5 | +The browser version of the BSON parser is compiled using webpack and the current | ||
6 | +version is pre-compiled in the browser_build directory. To build a new version perform the following operation. | ||
7 | + | ||
8 | +``` | ||
9 | +npm install | ||
10 | +npm run build | ||
11 | +``` | ||
12 | + | ||
13 | +A simple example of how to use BSON in the browser: | ||
14 | + | ||
15 | +```html | ||
16 | +<script src="./browser_build/bson.js"></script> | ||
17 | + | ||
18 | +<script> | ||
19 | + function start() { | ||
20 | + // Get the Long type | ||
21 | + var Long = BSON.Long; | ||
22 | + // Create a bson parser instance | ||
23 | + var bson = new BSON(); | ||
24 | + | ||
25 | + // Serialize document | ||
26 | + var doc = { long: Long.fromNumber(100) } | ||
27 | + | ||
28 | + // Serialize a document | ||
29 | + var data = bson.serialize(doc) | ||
30 | + // De serialize it again | ||
31 | + var doc_2 = bson.deserialize(data) | ||
32 | + } | ||
33 | +</script> | ||
34 | +``` | ||
35 | + | ||
36 | +A simple example of how to use BSON in `node.js`: | ||
37 | + | ||
38 | +```js | ||
39 | +// Get BSON parser class | ||
40 | +var BSON = require('bson') | ||
41 | +// Get the Long type | ||
42 | +var Long = BSON.Long; | ||
43 | +// Create a bson parser instance | ||
44 | +var bson = new BSON(); | ||
45 | + | ||
46 | +// Serialize document | ||
47 | +var doc = { long: Long.fromNumber(100) } | ||
48 | + | ||
49 | +// Serialize a document | ||
50 | +var data = bson.serialize(doc) | ||
51 | +console.log('data:', data) | ||
52 | + | ||
53 | +// Deserialize the resulting Buffer | ||
54 | +var doc_2 = bson.deserialize(data) | ||
55 | +console.log('doc_2:', doc_2) | ||
56 | +``` | ||
57 | + | ||
58 | +## Installation | ||
59 | + | ||
60 | +`npm install bson` | ||
61 | + | ||
62 | +## API | ||
63 | + | ||
64 | +### BSON types | ||
65 | + | ||
66 | +For all BSON types documentation, please refer to the documentation for the mongodb driver. | ||
67 | + | ||
68 | +https://github.com/mongodb/node-mongodb-native | ||
69 | + | ||
70 | +### BSON serialization and deserialiation | ||
71 | + | ||
72 | +**`new BSON()`** - Creates a new BSON seralizer/deserializer you can use to serialize and deserialize BSON. | ||
73 | + | ||
74 | +#### BSON.serialize | ||
75 | + | ||
76 | +The BSON serialize method takes a javascript object and an optional options object and returns a Node.js Buffer. | ||
77 | + | ||
78 | + * BSON.serialize(object, options) | ||
79 | + * @param {Object} object the Javascript object to serialize. | ||
80 | + * @param {Boolean} [options.checkKeys=false] the serializer will check if keys are valid. | ||
81 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript. functions. | ||
82 | + * @param {Boolean} [options.ignoreUndefined=true] | ||
83 | + * @return {Buffer} returns a Buffer instance. | ||
84 | + | ||
85 | +#### BSON.serializeWithBufferAndIndex | ||
86 | + | ||
87 | +The BSON serializeWithBufferAndIndex method takes an object, a target buffer instance and an optional options object and returns the end serialization index in the final buffer. | ||
88 | + | ||
89 | + * BSON.serializeWithBufferAndIndex(object, buffer, options) | ||
90 | + * @param {Object} object the Javascript object to serialize. | ||
91 | + * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. | ||
92 | + * @param {Boolean} [options.checkKeys=false] the serializer will check if keys are valid. | ||
93 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions. | ||
94 | + * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields. | ||
95 | + * @param {Number} [options.index=0] the index in the buffer where we wish to start serializing into. | ||
96 | + * @return {Number} returns the index pointing to the last written byte in the buffer. | ||
97 | + | ||
98 | +#### BSON.calculateObjectSize | ||
99 | + | ||
100 | +The BSON calculateObjectSize method takes a javascript object and an optional options object and returns the size of the BSON object. | ||
101 | + | ||
102 | + * BSON.calculateObjectSize(object, options) | ||
103 | + * @param {Object} object the Javascript object to serialize. | ||
104 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript. functions. | ||
105 | + * @param {Boolean} [options.ignoreUndefined=true] | ||
106 | + * @return {Buffer} returns a Buffer instance. | ||
107 | + | ||
108 | +#### BSON.deserialize | ||
109 | + | ||
110 | +The BSON deserialize method takes a node.js Buffer and an optional options object and returns a deserialized Javascript object. | ||
111 | + | ||
112 | + * BSON.deserialize(buffer, options) | ||
113 | + * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized. | ||
114 | + * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse. | ||
115 | + * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function. | ||
116 | + * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits | ||
117 | + * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance. | ||
118 | + * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types. | ||
119 | + * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer. | ||
120 | + * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances. | ||
121 | + * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. | ||
122 | + | ||
123 | +#### BSON.deserializeStream | ||
124 | + | ||
125 | +The BSON deserializeStream method takes a node.js Buffer, startIndex and allow more control over deserialization of a Buffer containing concatenated BSON documents. | ||
126 | + | ||
127 | + * BSON.deserializeStream(buffer, startIndex, numberOfDocuments, documents, docStartIndex, options) | ||
128 | + * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. | ||
129 | + * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. | ||
130 | + * @param {Number} numberOfDocuments number of documents to deserialize. | ||
131 | + * @param {Array} documents an array where to store the deserialized documents. | ||
132 | + * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. | ||
133 | + * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized. | ||
134 | + * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse. | ||
135 | + * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function. | ||
136 | + * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits | ||
137 | + * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance. | ||
138 | + * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types. | ||
139 | + * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer. | ||
140 | + * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances. | ||
141 | + * @return {Object} returns the deserialized Javascript Object. |
node_modules/_bson@1.0.4@bson/bower.json
0 → 100644
1 | +{ | ||
2 | + "name": "bson", | ||
3 | + "description": "A bson parser for node.js and the browser", | ||
4 | + "keywords": [ | ||
5 | + "mongodb", | ||
6 | + "bson", | ||
7 | + "parser" | ||
8 | + ], | ||
9 | + "author": "Christian Amor Kvalheim <christkv@gmail.com>", | ||
10 | + "main": "./browser_build/bson.js", | ||
11 | + "license": "Apache-2.0", | ||
12 | + "moduleType": [ | ||
13 | + "globals", | ||
14 | + "node" | ||
15 | + ], | ||
16 | + "ignore": [ | ||
17 | + "**/.*", | ||
18 | + "alternate_parsers", | ||
19 | + "benchmarks", | ||
20 | + "bower_components", | ||
21 | + "node_modules", | ||
22 | + "test", | ||
23 | + "tools" | ||
24 | + ] | ||
25 | +} |
此 diff 太大无法显示。
1 | +{ "name" : "bson" | ||
2 | +, "description" : "A bson parser for node.js and the browser" | ||
3 | +, "main": "../" | ||
4 | +, "directories" : { "lib" : "../lib/bson" } | ||
5 | +, "engines" : { "node" : ">=0.6.0" } | ||
6 | +, "licenses" : [ { "type" : "Apache License, Version 2.0" | ||
7 | + , "url" : "http://www.apache.org/licenses/LICENSE-2.0" } ] | ||
8 | +} |
node_modules/_bson@1.0.4@bson/index.js
0 → 100644
1 | +var BSON = require('./lib/bson/bson'), | ||
2 | + Binary = require('./lib/bson/binary'), | ||
3 | + Code = require('./lib/bson/code'), | ||
4 | + DBRef = require('./lib/bson/db_ref'), | ||
5 | + Decimal128 = require('./lib/bson/decimal128'), | ||
6 | + Double = require('./lib/bson/double'), | ||
7 | + Int32 = require('./lib/bson/int_32'), | ||
8 | + Long = require('./lib/bson/long'), | ||
9 | + Map = require('./lib/bson/map'), | ||
10 | + MaxKey = require('./lib/bson/max_key'), | ||
11 | + MinKey = require('./lib/bson/min_key'), | ||
12 | + ObjectId = require('./lib/bson/objectid'), | ||
13 | + BSONRegExp = require('./lib/bson/regexp'), | ||
14 | + Symbol = require('./lib/bson/symbol'), | ||
15 | + Timestamp = require('./lib/bson/timestamp'); | ||
16 | + | ||
17 | +// BSON MAX VALUES | ||
18 | +BSON.BSON_INT32_MAX = 0x7FFFFFFF; | ||
19 | +BSON.BSON_INT32_MIN = -0x80000000; | ||
20 | + | ||
21 | +BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; | ||
22 | +BSON.BSON_INT64_MIN = -Math.pow(2, 63); | ||
23 | + | ||
24 | +// JS MAX PRECISE VALUES | ||
25 | +BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. | ||
26 | +BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. | ||
27 | + | ||
28 | +// Add BSON types to function creation | ||
29 | +BSON.Binary = Binary; | ||
30 | +BSON.Code = Code; | ||
31 | +BSON.DBRef = DBRef; | ||
32 | +BSON.Decimal128 = Decimal128; | ||
33 | +BSON.Double = Double; | ||
34 | +BSON.Int32 = Int32; | ||
35 | +BSON.Long = Long; | ||
36 | +BSON.Map = Map; | ||
37 | +BSON.MaxKey = MaxKey; | ||
38 | +BSON.MinKey = MinKey; | ||
39 | +BSON.ObjectId = ObjectId; | ||
40 | +BSON.ObjectID = ObjectId; | ||
41 | +BSON.BSONRegExp = BSONRegExp; | ||
42 | +BSON.Symbol = Symbol; | ||
43 | +BSON.Timestamp = Timestamp; | ||
44 | + | ||
45 | +// Return the BSON | ||
46 | +module.exports = BSON; |
1 | +/** | ||
2 | + * Module dependencies. | ||
3 | + * @ignore | ||
4 | + */ | ||
5 | + | ||
6 | +// Test if we're in Node via presence of "global" not absence of "window" | ||
7 | +// to support hybrid environments like Electron | ||
8 | +if(typeof global !== 'undefined') { | ||
9 | + var Buffer = require('buffer').Buffer; // TODO just use global Buffer | ||
10 | +} | ||
11 | + | ||
12 | +/** | ||
13 | + * A class representation of the BSON Binary type. | ||
14 | + * | ||
15 | + * Sub types | ||
16 | + * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. | ||
17 | + * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. | ||
18 | + * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. | ||
19 | + * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. | ||
20 | + * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. | ||
21 | + * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. | ||
22 | + * | ||
23 | + * @class | ||
24 | + * @param {Buffer} buffer a buffer object containing the binary data. | ||
25 | + * @param {Number} [subType] the option binary type. | ||
26 | + * @return {Binary} | ||
27 | + */ | ||
28 | +function Binary(buffer, subType) { | ||
29 | + if(!(this instanceof Binary)) return new Binary(buffer, subType); | ||
30 | + | ||
31 | + this._bsontype = 'Binary'; | ||
32 | + | ||
33 | + if(buffer instanceof Number) { | ||
34 | + this.sub_type = buffer; | ||
35 | + this.position = 0; | ||
36 | + } else { | ||
37 | + this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; | ||
38 | + this.position = 0; | ||
39 | + } | ||
40 | + | ||
41 | + if(buffer != null && !(buffer instanceof Number)) { | ||
42 | + // Only accept Buffer, Uint8Array or Arrays | ||
43 | + if(typeof buffer == 'string') { | ||
44 | + // Different ways of writing the length of the string for the different types | ||
45 | + if(typeof Buffer != 'undefined') { | ||
46 | + this.buffer = new Buffer(buffer); | ||
47 | + } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { | ||
48 | + this.buffer = writeStringToArray(buffer); | ||
49 | + } else { | ||
50 | + throw new Error("only String, Buffer, Uint8Array or Array accepted"); | ||
51 | + } | ||
52 | + } else { | ||
53 | + this.buffer = buffer; | ||
54 | + } | ||
55 | + this.position = buffer.length; | ||
56 | + } else { | ||
57 | + if(typeof Buffer != 'undefined') { | ||
58 | + this.buffer = new Buffer(Binary.BUFFER_SIZE); | ||
59 | + } else if(typeof Uint8Array != 'undefined'){ | ||
60 | + this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); | ||
61 | + } else { | ||
62 | + this.buffer = new Array(Binary.BUFFER_SIZE); | ||
63 | + } | ||
64 | + // Set position to start of buffer | ||
65 | + this.position = 0; | ||
66 | + } | ||
67 | +}; | ||
68 | + | ||
69 | +/** | ||
70 | + * Updates this binary with byte_value. | ||
71 | + * | ||
72 | + * @method | ||
73 | + * @param {string} byte_value a single byte we wish to write. | ||
74 | + */ | ||
75 | +Binary.prototype.put = function put(byte_value) { | ||
76 | + // If it's a string and a has more than one character throw an error | ||
77 | + if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); | ||
78 | + if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); | ||
79 | + | ||
80 | + // Decode the byte value once | ||
81 | + var decoded_byte = null; | ||
82 | + if(typeof byte_value == 'string') { | ||
83 | + decoded_byte = byte_value.charCodeAt(0); | ||
84 | + } else if(byte_value['length'] != null) { | ||
85 | + decoded_byte = byte_value[0]; | ||
86 | + } else { | ||
87 | + decoded_byte = byte_value; | ||
88 | + } | ||
89 | + | ||
90 | + if(this.buffer.length > this.position) { | ||
91 | + this.buffer[this.position++] = decoded_byte; | ||
92 | + } else { | ||
93 | + if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { | ||
94 | + // Create additional overflow buffer | ||
95 | + var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); | ||
96 | + // Combine the two buffers together | ||
97 | + this.buffer.copy(buffer, 0, 0, this.buffer.length); | ||
98 | + this.buffer = buffer; | ||
99 | + this.buffer[this.position++] = decoded_byte; | ||
100 | + } else { | ||
101 | + var buffer = null; | ||
102 | + // Create a new buffer (typed or normal array) | ||
103 | + if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { | ||
104 | + buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); | ||
105 | + } else { | ||
106 | + buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); | ||
107 | + } | ||
108 | + | ||
109 | + // We need to copy all the content to the new array | ||
110 | + for(var i = 0; i < this.buffer.length; i++) { | ||
111 | + buffer[i] = this.buffer[i]; | ||
112 | + } | ||
113 | + | ||
114 | + // Reassign the buffer | ||
115 | + this.buffer = buffer; | ||
116 | + // Write the byte | ||
117 | + this.buffer[this.position++] = decoded_byte; | ||
118 | + } | ||
119 | + } | ||
120 | +}; | ||
121 | + | ||
122 | +/** | ||
123 | + * Writes a buffer or string to the binary. | ||
124 | + * | ||
125 | + * @method | ||
126 | + * @param {(Buffer|string)} string a string or buffer to be written to the Binary BSON object. | ||
127 | + * @param {number} offset specify the binary of where to write the content. | ||
128 | + * @return {null} | ||
129 | + */ | ||
130 | +Binary.prototype.write = function write(string, offset) { | ||
131 | + offset = typeof offset == 'number' ? offset : this.position; | ||
132 | + | ||
133 | + // If the buffer is to small let's extend the buffer | ||
134 | + if(this.buffer.length < offset + string.length) { | ||
135 | + var buffer = null; | ||
136 | + // If we are in node.js | ||
137 | + if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { | ||
138 | + buffer = new Buffer(this.buffer.length + string.length); | ||
139 | + this.buffer.copy(buffer, 0, 0, this.buffer.length); | ||
140 | + } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { | ||
141 | + // Create a new buffer | ||
142 | + buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) | ||
143 | + // Copy the content | ||
144 | + for(var i = 0; i < this.position; i++) { | ||
145 | + buffer[i] = this.buffer[i]; | ||
146 | + } | ||
147 | + } | ||
148 | + | ||
149 | + // Assign the new buffer | ||
150 | + this.buffer = buffer; | ||
151 | + } | ||
152 | + | ||
153 | + if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { | ||
154 | + string.copy(this.buffer, offset, 0, string.length); | ||
155 | + this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; | ||
156 | + // offset = string.length | ||
157 | + } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { | ||
158 | + this.buffer.write(string, offset, 'binary'); | ||
159 | + this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; | ||
160 | + // offset = string.length; | ||
161 | + } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' | ||
162 | + || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { | ||
163 | + for(var i = 0; i < string.length; i++) { | ||
164 | + this.buffer[offset++] = string[i]; | ||
165 | + } | ||
166 | + | ||
167 | + this.position = offset > this.position ? offset : this.position; | ||
168 | + } else if(typeof string == 'string') { | ||
169 | + for(var i = 0; i < string.length; i++) { | ||
170 | + this.buffer[offset++] = string.charCodeAt(i); | ||
171 | + } | ||
172 | + | ||
173 | + this.position = offset > this.position ? offset : this.position; | ||
174 | + } | ||
175 | +}; | ||
176 | + | ||
177 | +/** | ||
178 | + * Reads **length** bytes starting at **position**. | ||
179 | + * | ||
180 | + * @method | ||
181 | + * @param {number} position read from the given position in the Binary. | ||
182 | + * @param {number} length the number of bytes to read. | ||
183 | + * @return {Buffer} | ||
184 | + */ | ||
185 | +Binary.prototype.read = function read(position, length) { | ||
186 | + length = length && length > 0 | ||
187 | + ? length | ||
188 | + : this.position; | ||
189 | + | ||
190 | + // Let's return the data based on the type we have | ||
191 | + if(this.buffer['slice']) { | ||
192 | + return this.buffer.slice(position, position + length); | ||
193 | + } else { | ||
194 | + // Create a buffer to keep the result | ||
195 | + var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); | ||
196 | + for(var i = 0; i < length; i++) { | ||
197 | + buffer[i] = this.buffer[position++]; | ||
198 | + } | ||
199 | + } | ||
200 | + // Return the buffer | ||
201 | + return buffer; | ||
202 | +}; | ||
203 | + | ||
204 | +/** | ||
205 | + * Returns the value of this binary as a string. | ||
206 | + * | ||
207 | + * @method | ||
208 | + * @return {string} | ||
209 | + */ | ||
210 | +Binary.prototype.value = function value(asRaw) { | ||
211 | + asRaw = asRaw == null ? false : asRaw; | ||
212 | + | ||
213 | + // Optimize to serialize for the situation where the data == size of buffer | ||
214 | + if(asRaw && typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer) && this.buffer.length == this.position) | ||
215 | + return this.buffer; | ||
216 | + | ||
217 | + // If it's a node.js buffer object | ||
218 | + if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { | ||
219 | + return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); | ||
220 | + } else { | ||
221 | + if(asRaw) { | ||
222 | + // we support the slice command use it | ||
223 | + if(this.buffer['slice'] != null) { | ||
224 | + return this.buffer.slice(0, this.position); | ||
225 | + } else { | ||
226 | + // Create a new buffer to copy content to | ||
227 | + var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); | ||
228 | + // Copy content | ||
229 | + for(var i = 0; i < this.position; i++) { | ||
230 | + newBuffer[i] = this.buffer[i]; | ||
231 | + } | ||
232 | + // Return the buffer | ||
233 | + return newBuffer; | ||
234 | + } | ||
235 | + } else { | ||
236 | + return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); | ||
237 | + } | ||
238 | + } | ||
239 | +}; | ||
240 | + | ||
241 | +/** | ||
242 | + * Length. | ||
243 | + * | ||
244 | + * @method | ||
245 | + * @return {number} the length of the binary. | ||
246 | + */ | ||
247 | +Binary.prototype.length = function length() { | ||
248 | + return this.position; | ||
249 | +}; | ||
250 | + | ||
251 | +/** | ||
252 | + * @ignore | ||
253 | + */ | ||
254 | +Binary.prototype.toJSON = function() { | ||
255 | + return this.buffer != null ? this.buffer.toString('base64') : ''; | ||
256 | +} | ||
257 | + | ||
258 | +/** | ||
259 | + * @ignore | ||
260 | + */ | ||
261 | +Binary.prototype.toString = function(format) { | ||
262 | + return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; | ||
263 | +} | ||
264 | + | ||
265 | +/** | ||
266 | + * Binary default subtype | ||
267 | + * @ignore | ||
268 | + */ | ||
269 | +var BSON_BINARY_SUBTYPE_DEFAULT = 0; | ||
270 | + | ||
271 | +/** | ||
272 | + * @ignore | ||
273 | + */ | ||
274 | +var writeStringToArray = function(data) { | ||
275 | + // Create a buffer | ||
276 | + var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); | ||
277 | + // Write the content to the buffer | ||
278 | + for(var i = 0; i < data.length; i++) { | ||
279 | + buffer[i] = data.charCodeAt(i); | ||
280 | + } | ||
281 | + // Write the string to the buffer | ||
282 | + return buffer; | ||
283 | +} | ||
284 | + | ||
285 | +/** | ||
286 | + * Convert Array ot Uint8Array to Binary String | ||
287 | + * | ||
288 | + * @ignore | ||
289 | + */ | ||
290 | +var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { | ||
291 | + var result = ""; | ||
292 | + for(var i = startIndex; i < endIndex; i++) { | ||
293 | + result = result + String.fromCharCode(byteArray[i]); | ||
294 | + } | ||
295 | + return result; | ||
296 | +}; | ||
297 | + | ||
298 | +Binary.BUFFER_SIZE = 256; | ||
299 | + | ||
300 | +/** | ||
301 | + * Default BSON type | ||
302 | + * | ||
303 | + * @classconstant SUBTYPE_DEFAULT | ||
304 | + **/ | ||
305 | +Binary.SUBTYPE_DEFAULT = 0; | ||
306 | +/** | ||
307 | + * Function BSON type | ||
308 | + * | ||
309 | + * @classconstant SUBTYPE_DEFAULT | ||
310 | + **/ | ||
311 | +Binary.SUBTYPE_FUNCTION = 1; | ||
312 | +/** | ||
313 | + * Byte Array BSON type | ||
314 | + * | ||
315 | + * @classconstant SUBTYPE_DEFAULT | ||
316 | + **/ | ||
317 | +Binary.SUBTYPE_BYTE_ARRAY = 2; | ||
318 | +/** | ||
319 | + * OLD UUID BSON type | ||
320 | + * | ||
321 | + * @classconstant SUBTYPE_DEFAULT | ||
322 | + **/ | ||
323 | +Binary.SUBTYPE_UUID_OLD = 3; | ||
324 | +/** | ||
325 | + * UUID BSON type | ||
326 | + * | ||
327 | + * @classconstant SUBTYPE_DEFAULT | ||
328 | + **/ | ||
329 | +Binary.SUBTYPE_UUID = 4; | ||
330 | +/** | ||
331 | + * MD5 BSON type | ||
332 | + * | ||
333 | + * @classconstant SUBTYPE_DEFAULT | ||
334 | + **/ | ||
335 | +Binary.SUBTYPE_MD5 = 5; | ||
336 | +/** | ||
337 | + * User BSON type | ||
338 | + * | ||
339 | + * @classconstant SUBTYPE_DEFAULT | ||
340 | + **/ | ||
341 | +Binary.SUBTYPE_USER_DEFINED = 128; | ||
342 | + | ||
343 | +/** | ||
344 | + * Expose. | ||
345 | + */ | ||
346 | +module.exports = Binary; | ||
347 | +module.exports.Binary = Binary; |
1 | +"use strict" | ||
2 | + | ||
3 | +var writeIEEE754 = require('./float_parser').writeIEEE754, | ||
4 | + readIEEE754 = require('./float_parser').readIEEE754, | ||
5 | + Map = require('./map'), | ||
6 | + Long = require('./long'), | ||
7 | + Double = require('./double'), | ||
8 | + Timestamp = require('./timestamp'), | ||
9 | + ObjectID = require('./objectid'), | ||
10 | + BSONRegExp = require('./regexp'), | ||
11 | + Symbol = require('./symbol'), | ||
12 | + Int32 = require('./int_32'), | ||
13 | + Code = require('./code'), | ||
14 | + Decimal128 = require('./decimal128'), | ||
15 | + MinKey = require('./min_key'), | ||
16 | + MaxKey = require('./max_key'), | ||
17 | + DBRef = require('./db_ref'), | ||
18 | + Binary = require('./binary'); | ||
19 | + | ||
20 | +// Parts of the parser | ||
21 | +var deserialize = require('./parser/deserializer'), | ||
22 | + serializer = require('./parser/serializer'), | ||
23 | + calculateObjectSize = require('./parser/calculate_size'); | ||
24 | + | ||
25 | +/** | ||
26 | + * @ignore | ||
27 | + * @api private | ||
28 | + */ | ||
29 | +// Max Size | ||
30 | +var MAXSIZE = (1024*1024*17); | ||
31 | +// Max Document Buffer size | ||
32 | +var buffer = new Buffer(MAXSIZE); | ||
33 | + | ||
34 | +var BSON = function() { | ||
35 | +} | ||
36 | + | ||
37 | +/** | ||
38 | + * Serialize a Javascript object. | ||
39 | + * | ||
40 | + * @param {Object} object the Javascript object to serialize. | ||
41 | + * @param {Boolean} [options.checkKeys] the serializer will check if keys are valid. | ||
42 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**. | ||
43 | + * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**. | ||
44 | + * @return {Buffer} returns the Buffer object containing the serialized object. | ||
45 | + * @api public | ||
46 | + */ | ||
47 | +BSON.prototype.serialize = function serialize(object, options) { | ||
48 | + options = options || {}; | ||
49 | + // Unpack the options | ||
50 | + var checkKeys = typeof options.checkKeys == 'boolean' | ||
51 | + ? options.checkKeys : false; | ||
52 | + var serializeFunctions = typeof options.serializeFunctions == 'boolean' | ||
53 | + ? options.serializeFunctions : false; | ||
54 | + var ignoreUndefined = typeof options.ignoreUndefined == 'boolean' | ||
55 | + ? options.ignoreUndefined : true; | ||
56 | + | ||
57 | + // Attempt to serialize | ||
58 | + var serializationIndex = serializer(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, []); | ||
59 | + // Create the final buffer | ||
60 | + var finishedBuffer = new Buffer(serializationIndex); | ||
61 | + // Copy into the finished buffer | ||
62 | + buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length); | ||
63 | + // Return the buffer | ||
64 | + return finishedBuffer; | ||
65 | +} | ||
66 | + | ||
67 | +/** | ||
68 | + * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. | ||
69 | + * | ||
70 | + * @param {Object} object the Javascript object to serialize. | ||
71 | + * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. | ||
72 | + * @param {Boolean} [options.checkKeys] the serializer will check if keys are valid. | ||
73 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**. | ||
74 | + * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**. | ||
75 | + * @param {Number} [options.index] the index in the buffer where we wish to start serializing into. | ||
76 | + * @return {Number} returns the index pointing to the last written byte in the buffer. | ||
77 | + * @api public | ||
78 | + */ | ||
79 | +BSON.prototype.serializeWithBufferAndIndex = function(object, finalBuffer, options) { | ||
80 | + options = options || {}; | ||
81 | + // Unpack the options | ||
82 | + var checkKeys = typeof options.checkKeys == 'boolean' | ||
83 | + ? options.checkKeys : false; | ||
84 | + var serializeFunctions = typeof options.serializeFunctions == 'boolean' | ||
85 | + ? options.serializeFunctions : false; | ||
86 | + var ignoreUndefined = typeof options.ignoreUndefined == 'boolean' | ||
87 | + ? options.ignoreUndefined : true; | ||
88 | + var startIndex = typeof options.index == 'number' | ||
89 | + ? options.index : 0; | ||
90 | + | ||
91 | + // Attempt to serialize | ||
92 | + var serializationIndex = serializer(buffer, object, checkKeys, startIndex || 0, 0, serializeFunctions, ignoreUndefined); | ||
93 | + buffer.copy(finalBuffer, startIndex, 0, serializationIndex); | ||
94 | + | ||
95 | + // Return the index | ||
96 | + return serializationIndex - 1; | ||
97 | +} | ||
98 | + | ||
99 | +/** | ||
100 | + * Deserialize data as BSON. | ||
101 | + * | ||
102 | + * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. | ||
103 | + * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized. | ||
104 | + * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse. | ||
105 | + * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function. | ||
106 | + * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits | ||
107 | + * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance. | ||
108 | + * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types. | ||
109 | + * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer. | ||
110 | + * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances. | ||
111 | + * @return {Object} returns the deserialized Javascript Object. | ||
112 | + * @api public | ||
113 | + */ | ||
114 | +BSON.prototype.deserialize = function(buffer, options) { | ||
115 | + return deserialize(buffer, options); | ||
116 | +} | ||
117 | + | ||
118 | +/** | ||
119 | + * Calculate the bson size for a passed in Javascript object. | ||
120 | + * | ||
121 | + * @param {Object} object the Javascript object to calculate the BSON byte size for. | ||
122 | + * @param {Boolean} [options.serializeFunctions=false] serialize the javascript functions **(default:false)**. | ||
123 | + * @param {Boolean} [options.ignoreUndefined=true] ignore undefined fields **(default:true)**. | ||
124 | + * @return {Number} returns the number of bytes the BSON object will take up. | ||
125 | + * @api public | ||
126 | + */ | ||
127 | +BSON.prototype.calculateObjectSize = function(object, options) { | ||
128 | + options = options || {}; | ||
129 | + | ||
130 | + var serializeFunctions = typeof options.serializeFunctions == 'boolean' | ||
131 | + ? options.serializeFunctions : false; | ||
132 | + var ignoreUndefined = typeof options.ignoreUndefined == 'boolean' | ||
133 | + ? options.ignoreUndefined : true; | ||
134 | + | ||
135 | + return calculateObjectSize(object, serializeFunctions, ignoreUndefined); | ||
136 | +} | ||
137 | + | ||
138 | +/** | ||
139 | + * Deserialize stream data as BSON documents. | ||
140 | + * | ||
141 | + * @param {Buffer} data the buffer containing the serialized set of BSON documents. | ||
142 | + * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. | ||
143 | + * @param {Number} numberOfDocuments number of documents to deserialize. | ||
144 | + * @param {Array} documents an array where to store the deserialized documents. | ||
145 | + * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. | ||
146 | + * @param {Object} [options] additional options used for the deserialization. | ||
147 | + * @param {Object} [options.evalFunctions=false] evaluate functions in the BSON document scoped to the object deserialized. | ||
148 | + * @param {Object} [options.cacheFunctions=false] cache evaluated functions for reuse. | ||
149 | + * @param {Object} [options.cacheFunctionsCrc32=false] use a crc32 code for caching, otherwise use the string of the function. | ||
150 | + * @param {Object} [options.promoteLongs=true] when deserializing a Long will fit it into a Number if it's smaller than 53 bits | ||
151 | + * @param {Object} [options.promoteBuffers=false] when deserializing a Binary will return it as a node.js Buffer instance. | ||
152 | + * @param {Object} [options.promoteValues=false] when deserializing will promote BSON values to their Node.js closest equivalent types. | ||
153 | + * @param {Object} [options.fieldsAsRaw=null] allow to specify if there what fields we wish to return as unserialized raw buffer. | ||
154 | + * @param {Object} [options.bsonRegExp=false] return BSON regular expressions as BSONRegExp instances. | ||
155 | + * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. | ||
156 | + * @api public | ||
157 | + */ | ||
158 | +BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { | ||
159 | + options = options != null ? options : {}; | ||
160 | + var index = startIndex; | ||
161 | + // Loop over all documents | ||
162 | + for(var i = 0; i < numberOfDocuments; i++) { | ||
163 | + // Find size of the document | ||
164 | + var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; | ||
165 | + // Update options with index | ||
166 | + options['index'] = index; | ||
167 | + // Parse the document at this point | ||
168 | + documents[docStartIndex + i] = this.deserialize(data, options); | ||
169 | + // Adjust index by the document size | ||
170 | + index = index + size; | ||
171 | + } | ||
172 | + | ||
173 | + // Return object containing end index of parsing and list of documents | ||
174 | + return index; | ||
175 | +} | ||
176 | + | ||
177 | +/** | ||
178 | + * @ignore | ||
179 | + * @api private | ||
180 | + */ | ||
181 | +// BSON MAX VALUES | ||
182 | +BSON.BSON_INT32_MAX = 0x7FFFFFFF; | ||
183 | +BSON.BSON_INT32_MIN = -0x80000000; | ||
184 | + | ||
185 | +BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; | ||
186 | +BSON.BSON_INT64_MIN = -Math.pow(2, 63); | ||
187 | + | ||
188 | +// JS MAX PRECISE VALUES | ||
189 | +BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. | ||
190 | +BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. | ||
191 | + | ||
192 | +// Internal long versions | ||
193 | +var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. | ||
194 | +var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. | ||
195 | + | ||
196 | +/** | ||
197 | + * Number BSON Type | ||
198 | + * | ||
199 | + * @classconstant BSON_DATA_NUMBER | ||
200 | + **/ | ||
201 | +BSON.BSON_DATA_NUMBER = 1; | ||
202 | +/** | ||
203 | + * String BSON Type | ||
204 | + * | ||
205 | + * @classconstant BSON_DATA_STRING | ||
206 | + **/ | ||
207 | +BSON.BSON_DATA_STRING = 2; | ||
208 | +/** | ||
209 | + * Object BSON Type | ||
210 | + * | ||
211 | + * @classconstant BSON_DATA_OBJECT | ||
212 | + **/ | ||
213 | +BSON.BSON_DATA_OBJECT = 3; | ||
214 | +/** | ||
215 | + * Array BSON Type | ||
216 | + * | ||
217 | + * @classconstant BSON_DATA_ARRAY | ||
218 | + **/ | ||
219 | +BSON.BSON_DATA_ARRAY = 4; | ||
220 | +/** | ||
221 | + * Binary BSON Type | ||
222 | + * | ||
223 | + * @classconstant BSON_DATA_BINARY | ||
224 | + **/ | ||
225 | +BSON.BSON_DATA_BINARY = 5; | ||
226 | +/** | ||
227 | + * ObjectID BSON Type | ||
228 | + * | ||
229 | + * @classconstant BSON_DATA_OID | ||
230 | + **/ | ||
231 | +BSON.BSON_DATA_OID = 7; | ||
232 | +/** | ||
233 | + * Boolean BSON Type | ||
234 | + * | ||
235 | + * @classconstant BSON_DATA_BOOLEAN | ||
236 | + **/ | ||
237 | +BSON.BSON_DATA_BOOLEAN = 8; | ||
238 | +/** | ||
239 | + * Date BSON Type | ||
240 | + * | ||
241 | + * @classconstant BSON_DATA_DATE | ||
242 | + **/ | ||
243 | +BSON.BSON_DATA_DATE = 9; | ||
244 | +/** | ||
245 | + * null BSON Type | ||
246 | + * | ||
247 | + * @classconstant BSON_DATA_NULL | ||
248 | + **/ | ||
249 | +BSON.BSON_DATA_NULL = 10; | ||
250 | +/** | ||
251 | + * RegExp BSON Type | ||
252 | + * | ||
253 | + * @classconstant BSON_DATA_REGEXP | ||
254 | + **/ | ||
255 | +BSON.BSON_DATA_REGEXP = 11; | ||
256 | +/** | ||
257 | + * Code BSON Type | ||
258 | + * | ||
259 | + * @classconstant BSON_DATA_CODE | ||
260 | + **/ | ||
261 | +BSON.BSON_DATA_CODE = 13; | ||
262 | +/** | ||
263 | + * Symbol BSON Type | ||
264 | + * | ||
265 | + * @classconstant BSON_DATA_SYMBOL | ||
266 | + **/ | ||
267 | +BSON.BSON_DATA_SYMBOL = 14; | ||
268 | +/** | ||
269 | + * Code with Scope BSON Type | ||
270 | + * | ||
271 | + * @classconstant BSON_DATA_CODE_W_SCOPE | ||
272 | + **/ | ||
273 | +BSON.BSON_DATA_CODE_W_SCOPE = 15; | ||
274 | +/** | ||
275 | + * 32 bit Integer BSON Type | ||
276 | + * | ||
277 | + * @classconstant BSON_DATA_INT | ||
278 | + **/ | ||
279 | +BSON.BSON_DATA_INT = 16; | ||
280 | +/** | ||
281 | + * Timestamp BSON Type | ||
282 | + * | ||
283 | + * @classconstant BSON_DATA_TIMESTAMP | ||
284 | + **/ | ||
285 | +BSON.BSON_DATA_TIMESTAMP = 17; | ||
286 | +/** | ||
287 | + * Long BSON Type | ||
288 | + * | ||
289 | + * @classconstant BSON_DATA_LONG | ||
290 | + **/ | ||
291 | +BSON.BSON_DATA_LONG = 18; | ||
292 | +/** | ||
293 | + * MinKey BSON Type | ||
294 | + * | ||
295 | + * @classconstant BSON_DATA_MIN_KEY | ||
296 | + **/ | ||
297 | +BSON.BSON_DATA_MIN_KEY = 0xff; | ||
298 | +/** | ||
299 | + * MaxKey BSON Type | ||
300 | + * | ||
301 | + * @classconstant BSON_DATA_MAX_KEY | ||
302 | + **/ | ||
303 | +BSON.BSON_DATA_MAX_KEY = 0x7f; | ||
304 | + | ||
305 | +/** | ||
306 | + * Binary Default Type | ||
307 | + * | ||
308 | + * @classconstant BSON_BINARY_SUBTYPE_DEFAULT | ||
309 | + **/ | ||
310 | +BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; | ||
311 | +/** | ||
312 | + * Binary Function Type | ||
313 | + * | ||
314 | + * @classconstant BSON_BINARY_SUBTYPE_FUNCTION | ||
315 | + **/ | ||
316 | +BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; | ||
317 | +/** | ||
318 | + * Binary Byte Array Type | ||
319 | + * | ||
320 | + * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY | ||
321 | + **/ | ||
322 | +BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; | ||
323 | +/** | ||
324 | + * Binary UUID Type | ||
325 | + * | ||
326 | + * @classconstant BSON_BINARY_SUBTYPE_UUID | ||
327 | + **/ | ||
328 | +BSON.BSON_BINARY_SUBTYPE_UUID = 3; | ||
329 | +/** | ||
330 | + * Binary MD5 Type | ||
331 | + * | ||
332 | + * @classconstant BSON_BINARY_SUBTYPE_MD5 | ||
333 | + **/ | ||
334 | +BSON.BSON_BINARY_SUBTYPE_MD5 = 4; | ||
335 | +/** | ||
336 | + * Binary User Defined Type | ||
337 | + * | ||
338 | + * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED | ||
339 | + **/ | ||
340 | +BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; | ||
341 | + | ||
342 | +// Return BSON | ||
343 | +module.exports = BSON; | ||
344 | +module.exports.Code = Code; | ||
345 | +module.exports.Map = Map; | ||
346 | +module.exports.Symbol = Symbol; | ||
347 | +module.exports.BSON = BSON; | ||
348 | +module.exports.DBRef = DBRef; | ||
349 | +module.exports.Binary = Binary; | ||
350 | +module.exports.ObjectID = ObjectID; | ||
351 | +module.exports.Long = Long; | ||
352 | +module.exports.Timestamp = Timestamp; | ||
353 | +module.exports.Double = Double; | ||
354 | +module.exports.Int32 = Int32; | ||
355 | +module.exports.MinKey = MinKey; | ||
356 | +module.exports.MaxKey = MaxKey; | ||
357 | +module.exports.BSONRegExp = BSONRegExp; | ||
358 | +module.exports.Decimal128 = Decimal128; |
1 | +/** | ||
2 | + * A class representation of the BSON Code type. | ||
3 | + * | ||
4 | + * @class | ||
5 | + * @param {(string|function)} code a string or function. | ||
6 | + * @param {Object} [scope] an optional scope for the function. | ||
7 | + * @return {Code} | ||
8 | + */ | ||
9 | +var Code = function Code(code, scope) { | ||
10 | + if(!(this instanceof Code)) return new Code(code, scope); | ||
11 | + this._bsontype = 'Code'; | ||
12 | + this.code = code; | ||
13 | + this.scope = scope; | ||
14 | +}; | ||
15 | + | ||
16 | +/** | ||
17 | + * @ignore | ||
18 | + */ | ||
19 | +Code.prototype.toJSON = function() { | ||
20 | + return {scope:this.scope, code:this.code}; | ||
21 | +} | ||
22 | + | ||
23 | +module.exports = Code; | ||
24 | +module.exports.Code = Code; |
1 | +/** | ||
2 | + * A class representation of the BSON DBRef type. | ||
3 | + * | ||
4 | + * @class | ||
5 | + * @param {string} namespace the collection name. | ||
6 | + * @param {ObjectID} oid the reference ObjectID. | ||
7 | + * @param {string} [db] optional db name, if omitted the reference is local to the current db. | ||
8 | + * @return {DBRef} | ||
9 | + */ | ||
10 | +function DBRef(namespace, oid, db) { | ||
11 | + if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); | ||
12 | + | ||
13 | + this._bsontype = 'DBRef'; | ||
14 | + this.namespace = namespace; | ||
15 | + this.oid = oid; | ||
16 | + this.db = db; | ||
17 | +}; | ||
18 | + | ||
19 | +/** | ||
20 | + * @ignore | ||
21 | + * @api private | ||
22 | + */ | ||
23 | +DBRef.prototype.toJSON = function() { | ||
24 | + return { | ||
25 | + '$ref':this.namespace, | ||
26 | + '$id':this.oid, | ||
27 | + '$db':this.db == null ? '' : this.db | ||
28 | + }; | ||
29 | +} | ||
30 | + | ||
31 | +module.exports = DBRef; | ||
32 | +module.exports.DBRef = DBRef; |
1 | +"use strict" | ||
2 | + | ||
3 | +var Long = require('./long'); | ||
4 | + | ||
5 | +var PARSE_STRING_REGEXP = /^(\+|\-)?(\d+|(\d*\.\d*))?(E|e)?([\-\+])?(\d+)?$/; | ||
6 | +var PARSE_INF_REGEXP = /^(\+|\-)?(Infinity|inf)$/i; | ||
7 | +var PARSE_NAN_REGEXP = /^(\+|\-)?NaN$/i; | ||
8 | + | ||
9 | +var EXPONENT_MAX = 6111; | ||
10 | +var EXPONENT_MIN = -6176; | ||
11 | +var EXPONENT_BIAS = 6176; | ||
12 | +var MAX_DIGITS = 34; | ||
13 | + | ||
14 | +// Nan value bits as 32 bit values (due to lack of longs) | ||
15 | +var NAN_BUFFER = [0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].reverse(); | ||
16 | +// Infinity value bits 32 bit values (due to lack of longs) | ||
17 | +var INF_NEGATIVE_BUFFER = [0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].reverse(); | ||
18 | +var INF_POSITIVE_BUFFER = [0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].reverse(); | ||
19 | + | ||
20 | +var EXPONENT_REGEX = /^([\-\+])?(\d+)?$/; | ||
21 | + | ||
22 | + | ||
23 | +// Detect if the value is a digit | ||
24 | +var isDigit = function(value) { | ||
25 | + return !isNaN(parseInt(value, 10)); | ||
26 | +} | ||
27 | + | ||
28 | +// Divide two uint128 values | ||
29 | +var divideu128 = function(value) { | ||
30 | + var DIVISOR = Long.fromNumber(1000 * 1000 * 1000); | ||
31 | + var _rem = Long.fromNumber(0); | ||
32 | + var i = 0; | ||
33 | + | ||
34 | + if(!value.parts[0] && !value.parts[1] && | ||
35 | + !value.parts[2] && !value.parts[3]) { | ||
36 | + return { quotient: value, rem: _rem }; | ||
37 | + } | ||
38 | + | ||
39 | + for(var i = 0; i <= 3; i++) { | ||
40 | + // Adjust remainder to match value of next dividend | ||
41 | + _rem = _rem.shiftLeft(32); | ||
42 | + // Add the divided to _rem | ||
43 | + _rem = _rem.add(new Long(value.parts[i], 0)); | ||
44 | + value.parts[i] = _rem.div(DIVISOR).low_; | ||
45 | + _rem = _rem.modulo(DIVISOR); | ||
46 | + } | ||
47 | + | ||
48 | + return { quotient: value, rem: _rem }; | ||
49 | +} | ||
50 | + | ||
51 | +// Multiply two Long values and return the 128 bit value | ||
52 | +var multiply64x2 = function(left, right) { | ||
53 | + if(!left && !right) { | ||
54 | + return {high: Long.fromNumber(0), low: Long.fromNumber(0)}; | ||
55 | + } | ||
56 | + | ||
57 | + var leftHigh = left.shiftRightUnsigned(32); | ||
58 | + var leftLow = new Long(left.getLowBits(), 0); | ||
59 | + var rightHigh = right.shiftRightUnsigned(32); | ||
60 | + var rightLow = new Long(right.getLowBits(), 0); | ||
61 | + | ||
62 | + var productHigh = leftHigh.multiply(rightHigh); | ||
63 | + var productMid = leftHigh.multiply(rightLow); | ||
64 | + var productMid2 = leftLow.multiply(rightHigh); | ||
65 | + var productLow = leftLow.multiply(rightLow); | ||
66 | + | ||
67 | + productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); | ||
68 | + productMid = new Long(productMid.getLowBits(), 0) | ||
69 | + .add(productMid2) | ||
70 | + .add(productLow.shiftRightUnsigned(32)); | ||
71 | + | ||
72 | + productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); | ||
73 | + productLow = productMid.shiftLeft(32).add(new Long(productLow.getLowBits(), 0)); | ||
74 | + | ||
75 | + // Return the 128 bit result | ||
76 | + return {high: productHigh, low: productLow}; | ||
77 | +} | ||
78 | + | ||
79 | +var lessThan = function(left, right) { | ||
80 | + // Make values unsigned | ||
81 | + var uhleft = left.high_ >>> 0; | ||
82 | + var uhright = right.high_ >>> 0; | ||
83 | + | ||
84 | + // Compare high bits first | ||
85 | + if(uhleft < uhright) { | ||
86 | + return true | ||
87 | + } else if(uhleft == uhright) { | ||
88 | + var ulleft = left.low_ >>> 0; | ||
89 | + var ulright = right.low_ >>> 0; | ||
90 | + if(ulleft < ulright) return true; | ||
91 | + } | ||
92 | + | ||
93 | + return false; | ||
94 | +} | ||
95 | + | ||
96 | +var longtoHex = function(value) { | ||
97 | + var buffer = new Buffer(8); | ||
98 | + var index = 0; | ||
99 | + // Encode the low 64 bits of the decimal | ||
100 | + // Encode low bits | ||
101 | + buffer[index++] = value.low_ & 0xff; | ||
102 | + buffer[index++] = (value.low_ >> 8) & 0xff; | ||
103 | + buffer[index++] = (value.low_ >> 16) & 0xff; | ||
104 | + buffer[index++] = (value.low_ >> 24) & 0xff; | ||
105 | + // Encode high bits | ||
106 | + buffer[index++] = value.high_ & 0xff; | ||
107 | + buffer[index++] = (value.high_ >> 8) & 0xff; | ||
108 | + buffer[index++] = (value.high_ >> 16) & 0xff; | ||
109 | + buffer[index++] = (value.high_ >> 24) & 0xff; | ||
110 | + return buffer.reverse().toString('hex'); | ||
111 | +} | ||
112 | + | ||
113 | +var int32toHex = function(value) { | ||
114 | + var buffer = new Buffer(4); | ||
115 | + var index = 0; | ||
116 | + // Encode the low 64 bits of the decimal | ||
117 | + // Encode low bits | ||
118 | + buffer[index++] = value & 0xff; | ||
119 | + buffer[index++] = (value >> 8) & 0xff; | ||
120 | + buffer[index++] = (value >> 16) & 0xff; | ||
121 | + buffer[index++] = (value >> 24) & 0xff; | ||
122 | + return buffer.reverse().toString('hex'); | ||
123 | +} | ||
124 | + | ||
125 | +var Decimal128 = function(bytes) { | ||
126 | + this._bsontype = 'Decimal128'; | ||
127 | + this.bytes = bytes; | ||
128 | +} | ||
129 | + | ||
130 | +Decimal128.fromString = function(string) { | ||
131 | + // Parse state tracking | ||
132 | + var isNegative = false; | ||
133 | + var sawRadix = false; | ||
134 | + var foundNonZero = false; | ||
135 | + | ||
136 | + // Total number of significant digits (no leading or trailing zero) | ||
137 | + var significantDigits = 0; | ||
138 | + // Total number of significand digits read | ||
139 | + var nDigitsRead = 0; | ||
140 | + // Total number of digits (no leading zeros) | ||
141 | + var nDigits = 0; | ||
142 | + // The number of the digits after radix | ||
143 | + var radixPosition = 0; | ||
144 | + // The index of the first non-zero in *str* | ||
145 | + var firstNonZero = 0; | ||
146 | + | ||
147 | + // Digits Array | ||
148 | + var digits = [0]; | ||
149 | + // The number of digits in digits | ||
150 | + var nDigitsStored = 0; | ||
151 | + // Insertion pointer for digits | ||
152 | + var digitsInsert = 0; | ||
153 | + // The index of the first non-zero digit | ||
154 | + var firstDigit = 0; | ||
155 | + // The index of the last digit | ||
156 | + var lastDigit = 0; | ||
157 | + | ||
158 | + // Exponent | ||
159 | + var exponent = 0; | ||
160 | + // loop index over array | ||
161 | + var i = 0; | ||
162 | + // The high 17 digits of the significand | ||
163 | + var significandHigh = [0, 0]; | ||
164 | + // The low 17 digits of the significand | ||
165 | + var significandLow = [0, 0]; | ||
166 | + // The biased exponent | ||
167 | + var biasedExponent = 0; | ||
168 | + | ||
169 | + // Read index | ||
170 | + var index = 0; | ||
171 | + | ||
172 | + // Trim the string | ||
173 | + string = string.trim(); | ||
174 | + | ||
175 | + // Results | ||
176 | + var stringMatch = string.match(PARSE_STRING_REGEXP); | ||
177 | + var infMatch = string.match(PARSE_INF_REGEXP); | ||
178 | + var nanMatch = string.match(PARSE_NAN_REGEXP); | ||
179 | + | ||
180 | + // Validate the string | ||
181 | + if(!stringMatch | ||
182 | + && ! infMatch | ||
183 | + && ! nanMatch || string.length == 0) { | ||
184 | + throw new Error("" + string + " not a valid Decimal128 string"); | ||
185 | + } | ||
186 | + | ||
187 | + // Check if we have an illegal exponent format | ||
188 | + if(stringMatch && stringMatch[4] && stringMatch[2] === undefined) { | ||
189 | + throw new Error("" + string + " not a valid Decimal128 string"); | ||
190 | + } | ||
191 | + | ||
192 | + // Get the negative or positive sign | ||
193 | + if(string[index] == '+' || string[index] == '-') { | ||
194 | + isNegative = string[index++] == '-'; | ||
195 | + } | ||
196 | + | ||
197 | + // Check if user passed Infinity or NaN | ||
198 | + if(!isDigit(string[index]) && string[index] != '.') { | ||
199 | + if(string[index] == 'i' || string[index] == 'I') { | ||
200 | + return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)); | ||
201 | + } else if(string[index] == 'N') { | ||
202 | + return new Decimal128(new Buffer(NAN_BUFFER)); | ||
203 | + } | ||
204 | + } | ||
205 | + | ||
206 | + // Read all the digits | ||
207 | + while(isDigit(string[index]) || string[index] == '.') { | ||
208 | + if(string[index] == '.') { | ||
209 | + if(sawRadix) { | ||
210 | + return new Decimal128(new Buffer(NAN_BUFFER)); | ||
211 | + } | ||
212 | + | ||
213 | + sawRadix = true; | ||
214 | + index = index + 1; | ||
215 | + continue; | ||
216 | + } | ||
217 | + | ||
218 | + if(nDigitsStored < 34) { | ||
219 | + if(string[index] != '0' || foundNonZero) { | ||
220 | + if(!foundNonZero) { | ||
221 | + firstNonZero = nDigitsRead; | ||
222 | + } | ||
223 | + | ||
224 | + foundNonZero = true; | ||
225 | + | ||
226 | + // Only store 34 digits | ||
227 | + digits[digitsInsert++] = parseInt(string[index], 10); | ||
228 | + nDigitsStored = nDigitsStored + 1; | ||
229 | + } | ||
230 | + } | ||
231 | + | ||
232 | + if(foundNonZero) { | ||
233 | + nDigits = nDigits + 1; | ||
234 | + } | ||
235 | + | ||
236 | + if(sawRadix) { | ||
237 | + radixPosition = radixPosition + 1; | ||
238 | + } | ||
239 | + | ||
240 | + nDigitsRead = nDigitsRead + 1; | ||
241 | + index = index + 1; | ||
242 | + } | ||
243 | + | ||
244 | + if(sawRadix && !nDigitsRead) { | ||
245 | + throw new Error("" + string + " not a valid Decimal128 string"); | ||
246 | + } | ||
247 | + | ||
248 | + // Read exponent if exists | ||
249 | + if(string[index] == 'e' || string[index] == 'E') { | ||
250 | + // Read exponent digits | ||
251 | + var match = string.substr(++index).match(EXPONENT_REGEX); | ||
252 | + | ||
253 | + // No digits read | ||
254 | + if(!match || !match[2]) { | ||
255 | + return new Decimal128(new Buffer(NAN_BUFFER)); | ||
256 | + } | ||
257 | + | ||
258 | + // Get exponent | ||
259 | + exponent = parseInt(match[0], 10); | ||
260 | + | ||
261 | + // Adjust the index | ||
262 | + index = index + match[0].length; | ||
263 | + } | ||
264 | + | ||
265 | + // Return not a number | ||
266 | + if(string[index]) { | ||
267 | + return new Decimal128(new Buffer(NAN_BUFFER)); | ||
268 | + } | ||
269 | + | ||
270 | + // Done reading input | ||
271 | + // Find first non-zero digit in digits | ||
272 | + firstDigit = 0; | ||
273 | + | ||
274 | + if(!nDigitsStored) { | ||
275 | + firstDigit = 0; | ||
276 | + lastDigit = 0; | ||
277 | + digits[0] = 0; | ||
278 | + nDigits = 1; | ||
279 | + nDigitsStored = 1; | ||
280 | + significantDigits = 0; | ||
281 | + } else { | ||
282 | + lastDigit = nDigitsStored - 1; | ||
283 | + significantDigits = nDigits; | ||
284 | + | ||
285 | + if(exponent != 0 && significantDigits != 1) { | ||
286 | + while(string[firstNonZero + significantDigits - 1] == '0') { | ||
287 | + significantDigits = significantDigits - 1; | ||
288 | + } | ||
289 | + } | ||
290 | + } | ||
291 | + | ||
292 | + // Normalization of exponent | ||
293 | + // Correct exponent based on radix position, and shift significand as needed | ||
294 | + // to represent user input | ||
295 | + | ||
296 | + // Overflow prevention | ||
297 | + if(exponent <= radixPosition && radixPosition - exponent > (1 << 14)) { | ||
298 | + exponent = EXPONENT_MIN; | ||
299 | + } else { | ||
300 | + exponent = exponent - radixPosition; | ||
301 | + } | ||
302 | + | ||
303 | + // Attempt to normalize the exponent | ||
304 | + while(exponent > EXPONENT_MAX) { | ||
305 | + // Shift exponent to significand and decrease | ||
306 | + lastDigit = lastDigit + 1; | ||
307 | + | ||
308 | + if(lastDigit - firstDigit > MAX_DIGITS) { | ||
309 | + // Check if we have a zero then just hard clamp, otherwise fail | ||
310 | + var digitsString = digits.join(''); | ||
311 | + if(digitsString.match(/^0+$/)) { | ||
312 | + exponent = EXPONENT_MAX; | ||
313 | + break; | ||
314 | + } else { | ||
315 | + return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)); | ||
316 | + } | ||
317 | + } | ||
318 | + | ||
319 | + exponent = exponent - 1; | ||
320 | + } | ||
321 | + | ||
322 | + while(exponent < EXPONENT_MIN || nDigitsStored < nDigits) { | ||
323 | + // Shift last digit | ||
324 | + if(lastDigit == 0) { | ||
325 | + exponent = EXPONENT_MIN; | ||
326 | + significantDigits = 0; | ||
327 | + break; | ||
328 | + } | ||
329 | + | ||
330 | + if(nDigitsStored < nDigits) { | ||
331 | + // adjust to match digits not stored | ||
332 | + nDigits = nDigits - 1; | ||
333 | + } else { | ||
334 | + // adjust to round | ||
335 | + lastDigit = lastDigit - 1; | ||
336 | + } | ||
337 | + | ||
338 | + if(exponent < EXPONENT_MAX) { | ||
339 | + exponent = exponent + 1; | ||
340 | + } else { | ||
341 | + // Check if we have a zero then just hard clamp, otherwise fail | ||
342 | + var digitsString = digits.join(''); | ||
343 | + if(digitsString.match(/^0+$/)) { | ||
344 | + exponent = EXPONENT_MAX; | ||
345 | + break; | ||
346 | + } else { | ||
347 | + return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)) | ||
348 | + } | ||
349 | + } | ||
350 | + } | ||
351 | + | ||
352 | + | ||
353 | + // Round | ||
354 | + // We've normalized the exponent, but might still need to round. | ||
355 | + if((lastDigit - firstDigit + 1 < significantDigits) && string[significantDigits] != '0') { | ||
356 | + var endOfString = nDigitsRead; | ||
357 | + | ||
358 | + // If we have seen a radix point, 'string' is 1 longer than we have | ||
359 | + // documented with ndigits_read, so inc the position of the first nonzero | ||
360 | + // digit and the position that digits are read to. | ||
361 | + if(sawRadix && exponent == EXPONENT_MIN) { | ||
362 | + firstNonZero = firstNonZero + 1; | ||
363 | + endOfString = endOfString + 1; | ||
364 | + } | ||
365 | + | ||
366 | + var roundDigit = parseInt(string[firstNonZero + lastDigit + 1], 10); | ||
367 | + var roundBit = 0; | ||
368 | + | ||
369 | + if(roundDigit >= 5) { | ||
370 | + roundBit = 1; | ||
371 | + | ||
372 | + if(roundDigit == 5) { | ||
373 | + roundBit = digits[lastDigit] % 2 == 1; | ||
374 | + | ||
375 | + for(var i = firstNonZero + lastDigit + 2; i < endOfString; i++) { | ||
376 | + if(parseInt(string[i], 10)) { | ||
377 | + roundBit = 1; | ||
378 | + break; | ||
379 | + } | ||
380 | + } | ||
381 | + } | ||
382 | + } | ||
383 | + | ||
384 | + if(roundBit) { | ||
385 | + var dIdx = lastDigit; | ||
386 | + | ||
387 | + for(; dIdx >= 0; dIdx--) { | ||
388 | + if(++digits[dIdx] > 9) { | ||
389 | + digits[dIdx] = 0; | ||
390 | + | ||
391 | + // overflowed most significant digit | ||
392 | + if(dIdx == 0) { | ||
393 | + if(exponent < EXPONENT_MAX) { | ||
394 | + exponent = exponent + 1; | ||
395 | + digits[dIdx] = 1; | ||
396 | + } else { | ||
397 | + return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)) | ||
398 | + } | ||
399 | + } | ||
400 | + } else { | ||
401 | + break; | ||
402 | + } | ||
403 | + } | ||
404 | + } | ||
405 | + } | ||
406 | + | ||
407 | + // Encode significand | ||
408 | + // The high 17 digits of the significand | ||
409 | + significandHigh = Long.fromNumber(0); | ||
410 | + // The low 17 digits of the significand | ||
411 | + significandLow = Long.fromNumber(0); | ||
412 | + | ||
413 | + // read a zero | ||
414 | + if(significantDigits == 0) { | ||
415 | + significandHigh = Long.fromNumber(0); | ||
416 | + significandLow = Long.fromNumber(0); | ||
417 | + } else if(lastDigit - firstDigit < 17) { | ||
418 | + var dIdx = firstDigit; | ||
419 | + significandLow = Long.fromNumber(digits[dIdx++]); | ||
420 | + significandHigh = new Long(0, 0); | ||
421 | + | ||
422 | + for(; dIdx <= lastDigit; dIdx++) { | ||
423 | + significandLow = significandLow.multiply(Long.fromNumber(10)); | ||
424 | + significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); | ||
425 | + } | ||
426 | + } else { | ||
427 | + var dIdx = firstDigit; | ||
428 | + significandHigh = Long.fromNumber(digits[dIdx++]); | ||
429 | + | ||
430 | + for(; dIdx <= lastDigit - 17; dIdx++) { | ||
431 | + significandHigh = significandHigh.multiply(Long.fromNumber(10)); | ||
432 | + significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx])); | ||
433 | + } | ||
434 | + | ||
435 | + significandLow = Long.fromNumber(digits[dIdx++]); | ||
436 | + | ||
437 | + for(; dIdx <= lastDigit; dIdx++) { | ||
438 | + significandLow = significandLow.multiply(Long.fromNumber(10)); | ||
439 | + significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); | ||
440 | + } | ||
441 | + } | ||
442 | + | ||
443 | + var significand = multiply64x2(significandHigh, Long.fromString("100000000000000000")); | ||
444 | + | ||
445 | + significand.low = significand.low.add(significandLow); | ||
446 | + | ||
447 | + if(lessThan(significand.low, significandLow)) { | ||
448 | + significand.high = significand.high.add(Long.fromNumber(1)); | ||
449 | + } | ||
450 | + | ||
451 | + // Biased exponent | ||
452 | + var biasedExponent = (exponent + EXPONENT_BIAS); | ||
453 | + var dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) }; | ||
454 | + | ||
455 | + // Encode combination, exponent, and significand. | ||
456 | + if(significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber)) { | ||
457 | + // Encode '11' into bits 1 to 3 | ||
458 | + dec.high = dec.high.or(Long.fromNumber(0x3).shiftLeft(61)); | ||
459 | + dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(0x3fff).shiftLeft(47))); | ||
460 | + dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x7fffffffffff))); | ||
461 | + } else { | ||
462 | + dec.high = dec.high.or(Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49)); | ||
463 | + dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x1ffffffffffff))); | ||
464 | + } | ||
465 | + | ||
466 | + dec.low = significand.low; | ||
467 | + | ||
468 | + // Encode sign | ||
469 | + if(isNegative) { | ||
470 | + dec.high = dec.high.or(Long.fromString('9223372036854775808')); | ||
471 | + } | ||
472 | + | ||
473 | + // Encode into a buffer | ||
474 | + var buffer = new Buffer(16); | ||
475 | + var index = 0; | ||
476 | + | ||
477 | + // Encode the low 64 bits of the decimal | ||
478 | + // Encode low bits | ||
479 | + buffer[index++] = dec.low.low_ & 0xff; | ||
480 | + buffer[index++] = (dec.low.low_ >> 8) & 0xff; | ||
481 | + buffer[index++] = (dec.low.low_ >> 16) & 0xff; | ||
482 | + buffer[index++] = (dec.low.low_ >> 24) & 0xff; | ||
483 | + // Encode high bits | ||
484 | + buffer[index++] = dec.low.high_ & 0xff; | ||
485 | + buffer[index++] = (dec.low.high_ >> 8) & 0xff; | ||
486 | + buffer[index++] = (dec.low.high_ >> 16) & 0xff; | ||
487 | + buffer[index++] = (dec.low.high_ >> 24) & 0xff; | ||
488 | + | ||
489 | + // Encode the high 64 bits of the decimal | ||
490 | + // Encode low bits | ||
491 | + buffer[index++] = dec.high.low_ & 0xff; | ||
492 | + buffer[index++] = (dec.high.low_ >> 8) & 0xff; | ||
493 | + buffer[index++] = (dec.high.low_ >> 16) & 0xff; | ||
494 | + buffer[index++] = (dec.high.low_ >> 24) & 0xff; | ||
495 | + // Encode high bits | ||
496 | + buffer[index++] = dec.high.high_ & 0xff; | ||
497 | + buffer[index++] = (dec.high.high_ >> 8) & 0xff; | ||
498 | + buffer[index++] = (dec.high.high_ >> 16) & 0xff; | ||
499 | + buffer[index++] = (dec.high.high_ >> 24) & 0xff; | ||
500 | + | ||
501 | + // Return the new Decimal128 | ||
502 | + return new Decimal128(buffer); | ||
503 | +} | ||
504 | + | ||
505 | +// Extract least significant 5 bits | ||
506 | +var COMBINATION_MASK = 0x1f; | ||
507 | +// Extract least significant 14 bits | ||
508 | +var EXPONENT_MASK = 0x3fff; | ||
509 | +// Value of combination field for Inf | ||
510 | +var COMBINATION_INFINITY = 30; | ||
511 | +// Value of combination field for NaN | ||
512 | +var COMBINATION_NAN = 31; | ||
513 | +// Value of combination field for NaN | ||
514 | +var COMBINATION_SNAN = 32; | ||
515 | +// decimal128 exponent bias | ||
516 | +var EXPONENT_BIAS = 6176; | ||
517 | + | ||
518 | +Decimal128.prototype.toString = function() { | ||
519 | + // Note: bits in this routine are referred to starting at 0, | ||
520 | + // from the sign bit, towards the coefficient. | ||
521 | + | ||
522 | + // bits 0 - 31 | ||
523 | + var high; | ||
524 | + // bits 32 - 63 | ||
525 | + var midh; | ||
526 | + // bits 64 - 95 | ||
527 | + var midl; | ||
528 | + // bits 96 - 127 | ||
529 | + var low; | ||
530 | + // bits 1 - 5 | ||
531 | + var combination; | ||
532 | + // decoded biased exponent (14 bits) | ||
533 | + var biased_exponent; | ||
534 | + // the number of significand digits | ||
535 | + var significand_digits = 0; | ||
536 | + // the base-10 digits in the significand | ||
537 | + var significand = new Array(36); | ||
538 | + for(var i = 0; i < significand.length; i++) significand[i] = 0; | ||
539 | + // read pointer into significand | ||
540 | + var index = 0; | ||
541 | + | ||
542 | + // unbiased exponent | ||
543 | + var exponent; | ||
544 | + // the exponent if scientific notation is used | ||
545 | + var scientific_exponent; | ||
546 | + | ||
547 | + // true if the number is zero | ||
548 | + var is_zero = false; | ||
549 | + | ||
550 | + // the most signifcant significand bits (50-46) | ||
551 | + var significand_msb; | ||
552 | + // temporary storage for significand decoding | ||
553 | + var significand128 = {parts: new Array(4)}; | ||
554 | + // indexing variables | ||
555 | + var i; | ||
556 | + var j, k; | ||
557 | + | ||
558 | + // Output string | ||
559 | + var string = []; | ||
560 | + | ||
561 | + // Unpack index | ||
562 | + var index = 0; | ||
563 | + | ||
564 | + // Buffer reference | ||
565 | + var buffer = this.bytes; | ||
566 | + | ||
567 | + // Unpack the low 64bits into a long | ||
568 | + low = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
569 | + midl = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
570 | + | ||
571 | + // Unpack the high 64bits into a long | ||
572 | + midh = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
573 | + high = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
574 | + | ||
575 | + // Unpack index | ||
576 | + var index = 0; | ||
577 | + | ||
578 | + // Create the state of the decimal | ||
579 | + var dec = { | ||
580 | + low: new Long(low, midl), | ||
581 | + high: new Long(midh, high) }; | ||
582 | + | ||
583 | + if(dec.high.lessThan(Long.ZERO)) { | ||
584 | + string.push('-'); | ||
585 | + } | ||
586 | + | ||
587 | + // Decode combination field and exponent | ||
588 | + combination = (high >> 26) & COMBINATION_MASK; | ||
589 | + | ||
590 | + if((combination >> 3) == 3) { | ||
591 | + // Check for 'special' values | ||
592 | + if(combination == COMBINATION_INFINITY) { | ||
593 | + return string.join('') + "Infinity"; | ||
594 | + } else if(combination == COMBINATION_NAN) { | ||
595 | + return "NaN"; | ||
596 | + } else { | ||
597 | + biased_exponent = (high >> 15) & EXPONENT_MASK; | ||
598 | + significand_msb = 0x08 + ((high >> 14) & 0x01); | ||
599 | + } | ||
600 | + } else { | ||
601 | + significand_msb = (high >> 14) & 0x07; | ||
602 | + biased_exponent = (high >> 17) & EXPONENT_MASK; | ||
603 | + } | ||
604 | + | ||
605 | + exponent = biased_exponent - EXPONENT_BIAS; | ||
606 | + | ||
607 | + // Create string of significand digits | ||
608 | + | ||
609 | + // Convert the 114-bit binary number represented by | ||
610 | + // (significand_high, significand_low) to at most 34 decimal | ||
611 | + // digits through modulo and division. | ||
612 | + significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14); | ||
613 | + significand128.parts[1] = midh; | ||
614 | + significand128.parts[2] = midl; | ||
615 | + significand128.parts[3] = low; | ||
616 | + | ||
617 | + if(significand128.parts[0] == 0 && significand128.parts[1] == 0 | ||
618 | + && significand128.parts[2] == 0 && significand128.parts[3] == 0) { | ||
619 | + is_zero = true; | ||
620 | + } else { | ||
621 | + for(var k = 3; k >= 0; k--) { | ||
622 | + var least_digits = 0; | ||
623 | + // Peform the divide | ||
624 | + var result = divideu128(significand128); | ||
625 | + significand128 = result.quotient; | ||
626 | + least_digits = result.rem.low_; | ||
627 | + | ||
628 | + // We now have the 9 least significant digits (in base 2). | ||
629 | + // Convert and output to string. | ||
630 | + if(!least_digits) continue; | ||
631 | + | ||
632 | + for(var j = 8; j >= 0; j--) { | ||
633 | + // significand[k * 9 + j] = Math.round(least_digits % 10); | ||
634 | + significand[k * 9 + j] = least_digits % 10; | ||
635 | + // least_digits = Math.round(least_digits / 10); | ||
636 | + least_digits = Math.floor(least_digits / 10); | ||
637 | + } | ||
638 | + } | ||
639 | + } | ||
640 | + | ||
641 | + // Output format options: | ||
642 | + // Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd | ||
643 | + // Regular - ddd.ddd | ||
644 | + | ||
645 | + if(is_zero) { | ||
646 | + significand_digits = 1; | ||
647 | + significand[index] = 0; | ||
648 | + } else { | ||
649 | + significand_digits = 36; | ||
650 | + var i = 0; | ||
651 | + | ||
652 | + while(!significand[index]) { | ||
653 | + i++; | ||
654 | + significand_digits = significand_digits - 1; | ||
655 | + index = index + 1; | ||
656 | + } | ||
657 | + } | ||
658 | + | ||
659 | + scientific_exponent = significand_digits - 1 + exponent; | ||
660 | + | ||
661 | + // The scientific exponent checks are dictated by the string conversion | ||
662 | + // specification and are somewhat arbitrary cutoffs. | ||
663 | + // | ||
664 | + // We must check exponent > 0, because if this is the case, the number | ||
665 | + // has trailing zeros. However, we *cannot* output these trailing zeros, | ||
666 | + // because doing so would change the precision of the value, and would | ||
667 | + // change stored data if the string converted number is round tripped. | ||
668 | + | ||
669 | + if(scientific_exponent >= 34 || scientific_exponent <= -7 || | ||
670 | + exponent > 0) { | ||
671 | + // Scientific format | ||
672 | + string.push(significand[index++]); | ||
673 | + significand_digits = significand_digits - 1; | ||
674 | + | ||
675 | + if(significand_digits) { | ||
676 | + string.push('.'); | ||
677 | + } | ||
678 | + | ||
679 | + for(var i = 0; i < significand_digits; i++) { | ||
680 | + string.push(significand[index++]); | ||
681 | + } | ||
682 | + | ||
683 | + // Exponent | ||
684 | + string.push('E'); | ||
685 | + if(scientific_exponent > 0) { | ||
686 | + string.push('+' + scientific_exponent); | ||
687 | + } else { | ||
688 | + string.push(scientific_exponent); | ||
689 | + } | ||
690 | + } else { | ||
691 | + // Regular format with no decimal place | ||
692 | + if(exponent >= 0) { | ||
693 | + for(var i = 0; i < significand_digits; i++) { | ||
694 | + string.push(significand[index++]); | ||
695 | + } | ||
696 | + } else { | ||
697 | + var radix_position = significand_digits + exponent; | ||
698 | + | ||
699 | + // non-zero digits before radix | ||
700 | + if(radix_position > 0) { | ||
701 | + for(var i = 0; i < radix_position; i++) { | ||
702 | + string.push(significand[index++]); | ||
703 | + } | ||
704 | + } else { | ||
705 | + string.push('0'); | ||
706 | + } | ||
707 | + | ||
708 | + string.push('.'); | ||
709 | + // add leading zeros after radix | ||
710 | + while(radix_position++ < 0) { | ||
711 | + string.push('0'); | ||
712 | + } | ||
713 | + | ||
714 | + for(var i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) { | ||
715 | + string.push(significand[index++]); | ||
716 | + } | ||
717 | + } | ||
718 | + } | ||
719 | + | ||
720 | + return string.join(''); | ||
721 | +} | ||
722 | + | ||
723 | +Decimal128.prototype.toJSON = function() { | ||
724 | + return { "$numberDecimal": this.toString() }; | ||
725 | +} | ||
726 | + | ||
727 | +module.exports = Decimal128; | ||
728 | +module.exports.Decimal128 = Decimal128; |
1 | +/** | ||
2 | + * A class representation of the BSON Double type. | ||
3 | + * | ||
4 | + * @class | ||
5 | + * @param {number} value the number we want to represent as a double. | ||
6 | + * @return {Double} | ||
7 | + */ | ||
8 | +function Double(value) { | ||
9 | + if(!(this instanceof Double)) return new Double(value); | ||
10 | + | ||
11 | + this._bsontype = 'Double'; | ||
12 | + this.value = value; | ||
13 | +} | ||
14 | + | ||
15 | +/** | ||
16 | + * Access the number value. | ||
17 | + * | ||
18 | + * @method | ||
19 | + * @return {number} returns the wrapped double number. | ||
20 | + */ | ||
21 | +Double.prototype.valueOf = function() { | ||
22 | + return this.value; | ||
23 | +}; | ||
24 | + | ||
25 | +/** | ||
26 | + * @ignore | ||
27 | + */ | ||
28 | +Double.prototype.toJSON = function() { | ||
29 | + return this.value; | ||
30 | +} | ||
31 | + | ||
32 | +module.exports = Double; | ||
33 | +module.exports.Double = Double; |
1 | +// Copyright (c) 2008, Fair Oaks Labs, Inc. | ||
2 | +// All rights reserved. | ||
3 | +// | ||
4 | +// Redistribution and use in source and binary forms, with or without | ||
5 | +// modification, are permitted provided that the following conditions are met: | ||
6 | +// | ||
7 | +// * Redistributions of source code must retain the above copyright notice, | ||
8 | +// this list of conditions and the following disclaimer. | ||
9 | +// | ||
10 | +// * Redistributions in binary form must reproduce the above copyright notice, | ||
11 | +// this list of conditions and the following disclaimer in the documentation | ||
12 | +// and/or other materials provided with the distribution. | ||
13 | +// | ||
14 | +// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors | ||
15 | +// may be used to endorse or promote products derived from this software | ||
16 | +// without specific prior written permission. | ||
17 | +// | ||
18 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
19 | +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
22 | +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
23 | +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
24 | +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
25 | +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
26 | +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
27 | +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
28 | +// POSSIBILITY OF SUCH DAMAGE. | ||
29 | +// | ||
30 | +// | ||
31 | +// Modifications to writeIEEE754 to support negative zeroes made by Brian White | ||
32 | + | ||
33 | +var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { | ||
34 | + var e, m, | ||
35 | + bBE = (endian === 'big'), | ||
36 | + eLen = nBytes * 8 - mLen - 1, | ||
37 | + eMax = (1 << eLen) - 1, | ||
38 | + eBias = eMax >> 1, | ||
39 | + nBits = -7, | ||
40 | + i = bBE ? 0 : (nBytes - 1), | ||
41 | + d = bBE ? 1 : -1, | ||
42 | + s = buffer[offset + i]; | ||
43 | + | ||
44 | + i += d; | ||
45 | + | ||
46 | + e = s & ((1 << (-nBits)) - 1); | ||
47 | + s >>= (-nBits); | ||
48 | + nBits += eLen; | ||
49 | + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); | ||
50 | + | ||
51 | + m = e & ((1 << (-nBits)) - 1); | ||
52 | + e >>= (-nBits); | ||
53 | + nBits += mLen; | ||
54 | + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); | ||
55 | + | ||
56 | + if (e === 0) { | ||
57 | + e = 1 - eBias; | ||
58 | + } else if (e === eMax) { | ||
59 | + return m ? NaN : ((s ? -1 : 1) * Infinity); | ||
60 | + } else { | ||
61 | + m = m + Math.pow(2, mLen); | ||
62 | + e = e - eBias; | ||
63 | + } | ||
64 | + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); | ||
65 | +}; | ||
66 | + | ||
67 | +var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { | ||
68 | + var e, m, c, | ||
69 | + bBE = (endian === 'big'), | ||
70 | + eLen = nBytes * 8 - mLen - 1, | ||
71 | + eMax = (1 << eLen) - 1, | ||
72 | + eBias = eMax >> 1, | ||
73 | + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), | ||
74 | + i = bBE ? (nBytes-1) : 0, | ||
75 | + d = bBE ? -1 : 1, | ||
76 | + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; | ||
77 | + | ||
78 | + value = Math.abs(value); | ||
79 | + | ||
80 | + if (isNaN(value) || value === Infinity) { | ||
81 | + m = isNaN(value) ? 1 : 0; | ||
82 | + e = eMax; | ||
83 | + } else { | ||
84 | + e = Math.floor(Math.log(value) / Math.LN2); | ||
85 | + if (value * (c = Math.pow(2, -e)) < 1) { | ||
86 | + e--; | ||
87 | + c *= 2; | ||
88 | + } | ||
89 | + if (e+eBias >= 1) { | ||
90 | + value += rt / c; | ||
91 | + } else { | ||
92 | + value += rt * Math.pow(2, 1 - eBias); | ||
93 | + } | ||
94 | + if (value * c >= 2) { | ||
95 | + e++; | ||
96 | + c /= 2; | ||
97 | + } | ||
98 | + | ||
99 | + if (e + eBias >= eMax) { | ||
100 | + m = 0; | ||
101 | + e = eMax; | ||
102 | + } else if (e + eBias >= 1) { | ||
103 | + m = (value * c - 1) * Math.pow(2, mLen); | ||
104 | + e = e + eBias; | ||
105 | + } else { | ||
106 | + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); | ||
107 | + e = 0; | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); | ||
112 | + | ||
113 | + e = (e << mLen) | m; | ||
114 | + eLen += mLen; | ||
115 | + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); | ||
116 | + | ||
117 | + buffer[offset + i - d] |= s * 128; | ||
118 | +}; | ||
119 | + | ||
120 | +exports.readIEEE754 = readIEEE754; | ||
121 | +exports.writeIEEE754 = writeIEEE754; |
1 | +var Int32 = function(value) { | ||
2 | + if(!(this instanceof Int32)) return new Int32(value); | ||
3 | + | ||
4 | + this._bsontype = 'Int32'; | ||
5 | + this.value = value; | ||
6 | +} | ||
7 | + | ||
8 | +/** | ||
9 | + * Access the number value. | ||
10 | + * | ||
11 | + * @method | ||
12 | + * @return {number} returns the wrapped int32 number. | ||
13 | + */ | ||
14 | +Int32.prototype.valueOf = function() { | ||
15 | + return this.value; | ||
16 | +}; | ||
17 | + | ||
18 | +/** | ||
19 | + * @ignore | ||
20 | + */ | ||
21 | +Int32.prototype.toJSON = function() { | ||
22 | + return this.value; | ||
23 | +} | ||
24 | + | ||
25 | +module.exports = Int32; | ||
26 | +module.exports.Int32 = Int32; |
1 | +// Licensed under the Apache License, Version 2.0 (the "License"); | ||
2 | +// you may not use this file except in compliance with the License. | ||
3 | +// You may obtain a copy of the License at | ||
4 | +// | ||
5 | +// http://www.apache.org/licenses/LICENSE-2.0 | ||
6 | +// | ||
7 | +// Unless required by applicable law or agreed to in writing, software | ||
8 | +// distributed under the License is distributed on an "AS IS" BASIS, | ||
9 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
10 | +// See the License for the specific language governing permissions and | ||
11 | +// limitations under the License. | ||
12 | +// | ||
13 | +// Copyright 2009 Google Inc. All Rights Reserved | ||
14 | + | ||
15 | +/** | ||
16 | + * Defines a Long class for representing a 64-bit two's-complement | ||
17 | + * integer value, which faithfully simulates the behavior of a Java "Long". This | ||
18 | + * implementation is derived from LongLib in GWT. | ||
19 | + * | ||
20 | + * Constructs a 64-bit two's-complement integer, given its low and high 32-bit | ||
21 | + * values as *signed* integers. See the from* functions below for more | ||
22 | + * convenient ways of constructing Longs. | ||
23 | + * | ||
24 | + * The internal representation of a Long is the two given signed, 32-bit values. | ||
25 | + * We use 32-bit pieces because these are the size of integers on which | ||
26 | + * Javascript performs bit-operations. For operations like addition and | ||
27 | + * multiplication, we split each number into 16-bit pieces, which can easily be | ||
28 | + * multiplied within Javascript's floating-point representation without overflow | ||
29 | + * or change in sign. | ||
30 | + * | ||
31 | + * In the algorithms below, we frequently reduce the negative case to the | ||
32 | + * positive case by negating the input(s) and then post-processing the result. | ||
33 | + * Note that we must ALWAYS check specially whether those values are MIN_VALUE | ||
34 | + * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as | ||
35 | + * a positive number, it overflows back into a negative). Not handling this | ||
36 | + * case would often result in infinite recursion. | ||
37 | + * | ||
38 | + * @class | ||
39 | + * @param {number} low the low (signed) 32 bits of the Long. | ||
40 | + * @param {number} high the high (signed) 32 bits of the Long. | ||
41 | + * @return {Long} | ||
42 | + */ | ||
43 | +function Long(low, high) { | ||
44 | + if(!(this instanceof Long)) return new Long(low, high); | ||
45 | + | ||
46 | + this._bsontype = 'Long'; | ||
47 | + /** | ||
48 | + * @type {number} | ||
49 | + * @ignore | ||
50 | + */ | ||
51 | + this.low_ = low | 0; // force into 32 signed bits. | ||
52 | + | ||
53 | + /** | ||
54 | + * @type {number} | ||
55 | + * @ignore | ||
56 | + */ | ||
57 | + this.high_ = high | 0; // force into 32 signed bits. | ||
58 | +}; | ||
59 | + | ||
60 | +/** | ||
61 | + * Return the int value. | ||
62 | + * | ||
63 | + * @method | ||
64 | + * @return {number} the value, assuming it is a 32-bit integer. | ||
65 | + */ | ||
66 | +Long.prototype.toInt = function() { | ||
67 | + return this.low_; | ||
68 | +}; | ||
69 | + | ||
70 | +/** | ||
71 | + * Return the Number value. | ||
72 | + * | ||
73 | + * @method | ||
74 | + * @return {number} the closest floating-point representation to this value. | ||
75 | + */ | ||
76 | +Long.prototype.toNumber = function() { | ||
77 | + return this.high_ * Long.TWO_PWR_32_DBL_ + | ||
78 | + this.getLowBitsUnsigned(); | ||
79 | +}; | ||
80 | + | ||
81 | +/** | ||
82 | + * Return the JSON value. | ||
83 | + * | ||
84 | + * @method | ||
85 | + * @return {string} the JSON representation. | ||
86 | + */ | ||
87 | +Long.prototype.toJSON = function() { | ||
88 | + return this.toString(); | ||
89 | +} | ||
90 | + | ||
91 | +/** | ||
92 | + * Return the String value. | ||
93 | + * | ||
94 | + * @method | ||
95 | + * @param {number} [opt_radix] the radix in which the text should be written. | ||
96 | + * @return {string} the textual representation of this value. | ||
97 | + */ | ||
98 | +Long.prototype.toString = function(opt_radix) { | ||
99 | + var radix = opt_radix || 10; | ||
100 | + if (radix < 2 || 36 < radix) { | ||
101 | + throw Error('radix out of range: ' + radix); | ||
102 | + } | ||
103 | + | ||
104 | + if (this.isZero()) { | ||
105 | + return '0'; | ||
106 | + } | ||
107 | + | ||
108 | + if (this.isNegative()) { | ||
109 | + if (this.equals(Long.MIN_VALUE)) { | ||
110 | + // We need to change the Long value before it can be negated, so we remove | ||
111 | + // the bottom-most digit in this base and then recurse to do the rest. | ||
112 | + var radixLong = Long.fromNumber(radix); | ||
113 | + var div = this.div(radixLong); | ||
114 | + var rem = div.multiply(radixLong).subtract(this); | ||
115 | + return div.toString(radix) + rem.toInt().toString(radix); | ||
116 | + } else { | ||
117 | + return '-' + this.negate().toString(radix); | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + // Do several (6) digits each time through the loop, so as to | ||
122 | + // minimize the calls to the very expensive emulated div. | ||
123 | + var radixToPower = Long.fromNumber(Math.pow(radix, 6)); | ||
124 | + | ||
125 | + var rem = this; | ||
126 | + var result = ''; | ||
127 | + while (true) { | ||
128 | + var remDiv = rem.div(radixToPower); | ||
129 | + var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); | ||
130 | + var digits = intval.toString(radix); | ||
131 | + | ||
132 | + rem = remDiv; | ||
133 | + if (rem.isZero()) { | ||
134 | + return digits + result; | ||
135 | + } else { | ||
136 | + while (digits.length < 6) { | ||
137 | + digits = '0' + digits; | ||
138 | + } | ||
139 | + result = '' + digits + result; | ||
140 | + } | ||
141 | + } | ||
142 | +}; | ||
143 | + | ||
144 | +/** | ||
145 | + * Return the high 32-bits value. | ||
146 | + * | ||
147 | + * @method | ||
148 | + * @return {number} the high 32-bits as a signed value. | ||
149 | + */ | ||
150 | +Long.prototype.getHighBits = function() { | ||
151 | + return this.high_; | ||
152 | +}; | ||
153 | + | ||
154 | +/** | ||
155 | + * Return the low 32-bits value. | ||
156 | + * | ||
157 | + * @method | ||
158 | + * @return {number} the low 32-bits as a signed value. | ||
159 | + */ | ||
160 | +Long.prototype.getLowBits = function() { | ||
161 | + return this.low_; | ||
162 | +}; | ||
163 | + | ||
164 | +/** | ||
165 | + * Return the low unsigned 32-bits value. | ||
166 | + * | ||
167 | + * @method | ||
168 | + * @return {number} the low 32-bits as an unsigned value. | ||
169 | + */ | ||
170 | +Long.prototype.getLowBitsUnsigned = function() { | ||
171 | + return (this.low_ >= 0) ? | ||
172 | + this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; | ||
173 | +}; | ||
174 | + | ||
175 | +/** | ||
176 | + * Returns the number of bits needed to represent the absolute value of this Long. | ||
177 | + * | ||
178 | + * @method | ||
179 | + * @return {number} Returns the number of bits needed to represent the absolute value of this Long. | ||
180 | + */ | ||
181 | +Long.prototype.getNumBitsAbs = function() { | ||
182 | + if (this.isNegative()) { | ||
183 | + if (this.equals(Long.MIN_VALUE)) { | ||
184 | + return 64; | ||
185 | + } else { | ||
186 | + return this.negate().getNumBitsAbs(); | ||
187 | + } | ||
188 | + } else { | ||
189 | + var val = this.high_ != 0 ? this.high_ : this.low_; | ||
190 | + for (var bit = 31; bit > 0; bit--) { | ||
191 | + if ((val & (1 << bit)) != 0) { | ||
192 | + break; | ||
193 | + } | ||
194 | + } | ||
195 | + return this.high_ != 0 ? bit + 33 : bit + 1; | ||
196 | + } | ||
197 | +}; | ||
198 | + | ||
199 | +/** | ||
200 | + * Return whether this value is zero. | ||
201 | + * | ||
202 | + * @method | ||
203 | + * @return {boolean} whether this value is zero. | ||
204 | + */ | ||
205 | +Long.prototype.isZero = function() { | ||
206 | + return this.high_ == 0 && this.low_ == 0; | ||
207 | +}; | ||
208 | + | ||
209 | +/** | ||
210 | + * Return whether this value is negative. | ||
211 | + * | ||
212 | + * @method | ||
213 | + * @return {boolean} whether this value is negative. | ||
214 | + */ | ||
215 | +Long.prototype.isNegative = function() { | ||
216 | + return this.high_ < 0; | ||
217 | +}; | ||
218 | + | ||
219 | +/** | ||
220 | + * Return whether this value is odd. | ||
221 | + * | ||
222 | + * @method | ||
223 | + * @return {boolean} whether this value is odd. | ||
224 | + */ | ||
225 | +Long.prototype.isOdd = function() { | ||
226 | + return (this.low_ & 1) == 1; | ||
227 | +}; | ||
228 | + | ||
229 | +/** | ||
230 | + * Return whether this Long equals the other | ||
231 | + * | ||
232 | + * @method | ||
233 | + * @param {Long} other Long to compare against. | ||
234 | + * @return {boolean} whether this Long equals the other | ||
235 | + */ | ||
236 | +Long.prototype.equals = function(other) { | ||
237 | + return (this.high_ == other.high_) && (this.low_ == other.low_); | ||
238 | +}; | ||
239 | + | ||
240 | +/** | ||
241 | + * Return whether this Long does not equal the other. | ||
242 | + * | ||
243 | + * @method | ||
244 | + * @param {Long} other Long to compare against. | ||
245 | + * @return {boolean} whether this Long does not equal the other. | ||
246 | + */ | ||
247 | +Long.prototype.notEquals = function(other) { | ||
248 | + return (this.high_ != other.high_) || (this.low_ != other.low_); | ||
249 | +}; | ||
250 | + | ||
251 | +/** | ||
252 | + * Return whether this Long is less than the other. | ||
253 | + * | ||
254 | + * @method | ||
255 | + * @param {Long} other Long to compare against. | ||
256 | + * @return {boolean} whether this Long is less than the other. | ||
257 | + */ | ||
258 | +Long.prototype.lessThan = function(other) { | ||
259 | + return this.compare(other) < 0; | ||
260 | +}; | ||
261 | + | ||
262 | +/** | ||
263 | + * Return whether this Long is less than or equal to the other. | ||
264 | + * | ||
265 | + * @method | ||
266 | + * @param {Long} other Long to compare against. | ||
267 | + * @return {boolean} whether this Long is less than or equal to the other. | ||
268 | + */ | ||
269 | +Long.prototype.lessThanOrEqual = function(other) { | ||
270 | + return this.compare(other) <= 0; | ||
271 | +}; | ||
272 | + | ||
273 | +/** | ||
274 | + * Return whether this Long is greater than the other. | ||
275 | + * | ||
276 | + * @method | ||
277 | + * @param {Long} other Long to compare against. | ||
278 | + * @return {boolean} whether this Long is greater than the other. | ||
279 | + */ | ||
280 | +Long.prototype.greaterThan = function(other) { | ||
281 | + return this.compare(other) > 0; | ||
282 | +}; | ||
283 | + | ||
284 | +/** | ||
285 | + * Return whether this Long is greater than or equal to the other. | ||
286 | + * | ||
287 | + * @method | ||
288 | + * @param {Long} other Long to compare against. | ||
289 | + * @return {boolean} whether this Long is greater than or equal to the other. | ||
290 | + */ | ||
291 | +Long.prototype.greaterThanOrEqual = function(other) { | ||
292 | + return this.compare(other) >= 0; | ||
293 | +}; | ||
294 | + | ||
295 | +/** | ||
296 | + * Compares this Long with the given one. | ||
297 | + * | ||
298 | + * @method | ||
299 | + * @param {Long} other Long to compare against. | ||
300 | + * @return {boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. | ||
301 | + */ | ||
302 | +Long.prototype.compare = function(other) { | ||
303 | + if (this.equals(other)) { | ||
304 | + return 0; | ||
305 | + } | ||
306 | + | ||
307 | + var thisNeg = this.isNegative(); | ||
308 | + var otherNeg = other.isNegative(); | ||
309 | + if (thisNeg && !otherNeg) { | ||
310 | + return -1; | ||
311 | + } | ||
312 | + if (!thisNeg && otherNeg) { | ||
313 | + return 1; | ||
314 | + } | ||
315 | + | ||
316 | + // at this point, the signs are the same, so subtraction will not overflow | ||
317 | + if (this.subtract(other).isNegative()) { | ||
318 | + return -1; | ||
319 | + } else { | ||
320 | + return 1; | ||
321 | + } | ||
322 | +}; | ||
323 | + | ||
324 | +/** | ||
325 | + * The negation of this value. | ||
326 | + * | ||
327 | + * @method | ||
328 | + * @return {Long} the negation of this value. | ||
329 | + */ | ||
330 | +Long.prototype.negate = function() { | ||
331 | + if (this.equals(Long.MIN_VALUE)) { | ||
332 | + return Long.MIN_VALUE; | ||
333 | + } else { | ||
334 | + return this.not().add(Long.ONE); | ||
335 | + } | ||
336 | +}; | ||
337 | + | ||
338 | +/** | ||
339 | + * Returns the sum of this and the given Long. | ||
340 | + * | ||
341 | + * @method | ||
342 | + * @param {Long} other Long to add to this one. | ||
343 | + * @return {Long} the sum of this and the given Long. | ||
344 | + */ | ||
345 | +Long.prototype.add = function(other) { | ||
346 | + // Divide each number into 4 chunks of 16 bits, and then sum the chunks. | ||
347 | + | ||
348 | + var a48 = this.high_ >>> 16; | ||
349 | + var a32 = this.high_ & 0xFFFF; | ||
350 | + var a16 = this.low_ >>> 16; | ||
351 | + var a00 = this.low_ & 0xFFFF; | ||
352 | + | ||
353 | + var b48 = other.high_ >>> 16; | ||
354 | + var b32 = other.high_ & 0xFFFF; | ||
355 | + var b16 = other.low_ >>> 16; | ||
356 | + var b00 = other.low_ & 0xFFFF; | ||
357 | + | ||
358 | + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; | ||
359 | + c00 += a00 + b00; | ||
360 | + c16 += c00 >>> 16; | ||
361 | + c00 &= 0xFFFF; | ||
362 | + c16 += a16 + b16; | ||
363 | + c32 += c16 >>> 16; | ||
364 | + c16 &= 0xFFFF; | ||
365 | + c32 += a32 + b32; | ||
366 | + c48 += c32 >>> 16; | ||
367 | + c32 &= 0xFFFF; | ||
368 | + c48 += a48 + b48; | ||
369 | + c48 &= 0xFFFF; | ||
370 | + return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); | ||
371 | +}; | ||
372 | + | ||
373 | +/** | ||
374 | + * Returns the difference of this and the given Long. | ||
375 | + * | ||
376 | + * @method | ||
377 | + * @param {Long} other Long to subtract from this. | ||
378 | + * @return {Long} the difference of this and the given Long. | ||
379 | + */ | ||
380 | +Long.prototype.subtract = function(other) { | ||
381 | + return this.add(other.negate()); | ||
382 | +}; | ||
383 | + | ||
384 | +/** | ||
385 | + * Returns the product of this and the given Long. | ||
386 | + * | ||
387 | + * @method | ||
388 | + * @param {Long} other Long to multiply with this. | ||
389 | + * @return {Long} the product of this and the other. | ||
390 | + */ | ||
391 | +Long.prototype.multiply = function(other) { | ||
392 | + if (this.isZero()) { | ||
393 | + return Long.ZERO; | ||
394 | + } else if (other.isZero()) { | ||
395 | + return Long.ZERO; | ||
396 | + } | ||
397 | + | ||
398 | + if (this.equals(Long.MIN_VALUE)) { | ||
399 | + return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; | ||
400 | + } else if (other.equals(Long.MIN_VALUE)) { | ||
401 | + return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; | ||
402 | + } | ||
403 | + | ||
404 | + if (this.isNegative()) { | ||
405 | + if (other.isNegative()) { | ||
406 | + return this.negate().multiply(other.negate()); | ||
407 | + } else { | ||
408 | + return this.negate().multiply(other).negate(); | ||
409 | + } | ||
410 | + } else if (other.isNegative()) { | ||
411 | + return this.multiply(other.negate()).negate(); | ||
412 | + } | ||
413 | + | ||
414 | + // If both Longs are small, use float multiplication | ||
415 | + if (this.lessThan(Long.TWO_PWR_24_) && | ||
416 | + other.lessThan(Long.TWO_PWR_24_)) { | ||
417 | + return Long.fromNumber(this.toNumber() * other.toNumber()); | ||
418 | + } | ||
419 | + | ||
420 | + // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. | ||
421 | + // We can skip products that would overflow. | ||
422 | + | ||
423 | + var a48 = this.high_ >>> 16; | ||
424 | + var a32 = this.high_ & 0xFFFF; | ||
425 | + var a16 = this.low_ >>> 16; | ||
426 | + var a00 = this.low_ & 0xFFFF; | ||
427 | + | ||
428 | + var b48 = other.high_ >>> 16; | ||
429 | + var b32 = other.high_ & 0xFFFF; | ||
430 | + var b16 = other.low_ >>> 16; | ||
431 | + var b00 = other.low_ & 0xFFFF; | ||
432 | + | ||
433 | + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; | ||
434 | + c00 += a00 * b00; | ||
435 | + c16 += c00 >>> 16; | ||
436 | + c00 &= 0xFFFF; | ||
437 | + c16 += a16 * b00; | ||
438 | + c32 += c16 >>> 16; | ||
439 | + c16 &= 0xFFFF; | ||
440 | + c16 += a00 * b16; | ||
441 | + c32 += c16 >>> 16; | ||
442 | + c16 &= 0xFFFF; | ||
443 | + c32 += a32 * b00; | ||
444 | + c48 += c32 >>> 16; | ||
445 | + c32 &= 0xFFFF; | ||
446 | + c32 += a16 * b16; | ||
447 | + c48 += c32 >>> 16; | ||
448 | + c32 &= 0xFFFF; | ||
449 | + c32 += a00 * b32; | ||
450 | + c48 += c32 >>> 16; | ||
451 | + c32 &= 0xFFFF; | ||
452 | + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; | ||
453 | + c48 &= 0xFFFF; | ||
454 | + return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); | ||
455 | +}; | ||
456 | + | ||
457 | +/** | ||
458 | + * Returns this Long divided by the given one. | ||
459 | + * | ||
460 | + * @method | ||
461 | + * @param {Long} other Long by which to divide. | ||
462 | + * @return {Long} this Long divided by the given one. | ||
463 | + */ | ||
464 | +Long.prototype.div = function(other) { | ||
465 | + if (other.isZero()) { | ||
466 | + throw Error('division by zero'); | ||
467 | + } else if (this.isZero()) { | ||
468 | + return Long.ZERO; | ||
469 | + } | ||
470 | + | ||
471 | + if (this.equals(Long.MIN_VALUE)) { | ||
472 | + if (other.equals(Long.ONE) || | ||
473 | + other.equals(Long.NEG_ONE)) { | ||
474 | + return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE | ||
475 | + } else if (other.equals(Long.MIN_VALUE)) { | ||
476 | + return Long.ONE; | ||
477 | + } else { | ||
478 | + // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. | ||
479 | + var halfThis = this.shiftRight(1); | ||
480 | + var approx = halfThis.div(other).shiftLeft(1); | ||
481 | + if (approx.equals(Long.ZERO)) { | ||
482 | + return other.isNegative() ? Long.ONE : Long.NEG_ONE; | ||
483 | + } else { | ||
484 | + var rem = this.subtract(other.multiply(approx)); | ||
485 | + var result = approx.add(rem.div(other)); | ||
486 | + return result; | ||
487 | + } | ||
488 | + } | ||
489 | + } else if (other.equals(Long.MIN_VALUE)) { | ||
490 | + return Long.ZERO; | ||
491 | + } | ||
492 | + | ||
493 | + if (this.isNegative()) { | ||
494 | + if (other.isNegative()) { | ||
495 | + return this.negate().div(other.negate()); | ||
496 | + } else { | ||
497 | + return this.negate().div(other).negate(); | ||
498 | + } | ||
499 | + } else if (other.isNegative()) { | ||
500 | + return this.div(other.negate()).negate(); | ||
501 | + } | ||
502 | + | ||
503 | + // Repeat the following until the remainder is less than other: find a | ||
504 | + // floating-point that approximates remainder / other *from below*, add this | ||
505 | + // into the result, and subtract it from the remainder. It is critical that | ||
506 | + // the approximate value is less than or equal to the real value so that the | ||
507 | + // remainder never becomes negative. | ||
508 | + var res = Long.ZERO; | ||
509 | + var rem = this; | ||
510 | + while (rem.greaterThanOrEqual(other)) { | ||
511 | + // Approximate the result of division. This may be a little greater or | ||
512 | + // smaller than the actual value. | ||
513 | + var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); | ||
514 | + | ||
515 | + // We will tweak the approximate result by changing it in the 48-th digit or | ||
516 | + // the smallest non-fractional digit, whichever is larger. | ||
517 | + var log2 = Math.ceil(Math.log(approx) / Math.LN2); | ||
518 | + var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); | ||
519 | + | ||
520 | + // Decrease the approximation until it is smaller than the remainder. Note | ||
521 | + // that if it is too large, the product overflows and is negative. | ||
522 | + var approxRes = Long.fromNumber(approx); | ||
523 | + var approxRem = approxRes.multiply(other); | ||
524 | + while (approxRem.isNegative() || approxRem.greaterThan(rem)) { | ||
525 | + approx -= delta; | ||
526 | + approxRes = Long.fromNumber(approx); | ||
527 | + approxRem = approxRes.multiply(other); | ||
528 | + } | ||
529 | + | ||
530 | + // We know the answer can't be zero... and actually, zero would cause | ||
531 | + // infinite recursion since we would make no progress. | ||
532 | + if (approxRes.isZero()) { | ||
533 | + approxRes = Long.ONE; | ||
534 | + } | ||
535 | + | ||
536 | + res = res.add(approxRes); | ||
537 | + rem = rem.subtract(approxRem); | ||
538 | + } | ||
539 | + return res; | ||
540 | +}; | ||
541 | + | ||
542 | +/** | ||
543 | + * Returns this Long modulo the given one. | ||
544 | + * | ||
545 | + * @method | ||
546 | + * @param {Long} other Long by which to mod. | ||
547 | + * @return {Long} this Long modulo the given one. | ||
548 | + */ | ||
549 | +Long.prototype.modulo = function(other) { | ||
550 | + return this.subtract(this.div(other).multiply(other)); | ||
551 | +}; | ||
552 | + | ||
553 | +/** | ||
554 | + * The bitwise-NOT of this value. | ||
555 | + * | ||
556 | + * @method | ||
557 | + * @return {Long} the bitwise-NOT of this value. | ||
558 | + */ | ||
559 | +Long.prototype.not = function() { | ||
560 | + return Long.fromBits(~this.low_, ~this.high_); | ||
561 | +}; | ||
562 | + | ||
563 | +/** | ||
564 | + * Returns the bitwise-AND of this Long and the given one. | ||
565 | + * | ||
566 | + * @method | ||
567 | + * @param {Long} other the Long with which to AND. | ||
568 | + * @return {Long} the bitwise-AND of this and the other. | ||
569 | + */ | ||
570 | +Long.prototype.and = function(other) { | ||
571 | + return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); | ||
572 | +}; | ||
573 | + | ||
574 | +/** | ||
575 | + * Returns the bitwise-OR of this Long and the given one. | ||
576 | + * | ||
577 | + * @method | ||
578 | + * @param {Long} other the Long with which to OR. | ||
579 | + * @return {Long} the bitwise-OR of this and the other. | ||
580 | + */ | ||
581 | +Long.prototype.or = function(other) { | ||
582 | + return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); | ||
583 | +}; | ||
584 | + | ||
585 | +/** | ||
586 | + * Returns the bitwise-XOR of this Long and the given one. | ||
587 | + * | ||
588 | + * @method | ||
589 | + * @param {Long} other the Long with which to XOR. | ||
590 | + * @return {Long} the bitwise-XOR of this and the other. | ||
591 | + */ | ||
592 | +Long.prototype.xor = function(other) { | ||
593 | + return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); | ||
594 | +}; | ||
595 | + | ||
596 | +/** | ||
597 | + * Returns this Long with bits shifted to the left by the given amount. | ||
598 | + * | ||
599 | + * @method | ||
600 | + * @param {number} numBits the number of bits by which to shift. | ||
601 | + * @return {Long} this shifted to the left by the given amount. | ||
602 | + */ | ||
603 | +Long.prototype.shiftLeft = function(numBits) { | ||
604 | + numBits &= 63; | ||
605 | + if (numBits == 0) { | ||
606 | + return this; | ||
607 | + } else { | ||
608 | + var low = this.low_; | ||
609 | + if (numBits < 32) { | ||
610 | + var high = this.high_; | ||
611 | + return Long.fromBits( | ||
612 | + low << numBits, | ||
613 | + (high << numBits) | (low >>> (32 - numBits))); | ||
614 | + } else { | ||
615 | + return Long.fromBits(0, low << (numBits - 32)); | ||
616 | + } | ||
617 | + } | ||
618 | +}; | ||
619 | + | ||
620 | +/** | ||
621 | + * Returns this Long with bits shifted to the right by the given amount. | ||
622 | + * | ||
623 | + * @method | ||
624 | + * @param {number} numBits the number of bits by which to shift. | ||
625 | + * @return {Long} this shifted to the right by the given amount. | ||
626 | + */ | ||
627 | +Long.prototype.shiftRight = function(numBits) { | ||
628 | + numBits &= 63; | ||
629 | + if (numBits == 0) { | ||
630 | + return this; | ||
631 | + } else { | ||
632 | + var high = this.high_; | ||
633 | + if (numBits < 32) { | ||
634 | + var low = this.low_; | ||
635 | + return Long.fromBits( | ||
636 | + (low >>> numBits) | (high << (32 - numBits)), | ||
637 | + high >> numBits); | ||
638 | + } else { | ||
639 | + return Long.fromBits( | ||
640 | + high >> (numBits - 32), | ||
641 | + high >= 0 ? 0 : -1); | ||
642 | + } | ||
643 | + } | ||
644 | +}; | ||
645 | + | ||
646 | +/** | ||
647 | + * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. | ||
648 | + * | ||
649 | + * @method | ||
650 | + * @param {number} numBits the number of bits by which to shift. | ||
651 | + * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. | ||
652 | + */ | ||
653 | +Long.prototype.shiftRightUnsigned = function(numBits) { | ||
654 | + numBits &= 63; | ||
655 | + if (numBits == 0) { | ||
656 | + return this; | ||
657 | + } else { | ||
658 | + var high = this.high_; | ||
659 | + if (numBits < 32) { | ||
660 | + var low = this.low_; | ||
661 | + return Long.fromBits( | ||
662 | + (low >>> numBits) | (high << (32 - numBits)), | ||
663 | + high >>> numBits); | ||
664 | + } else if (numBits == 32) { | ||
665 | + return Long.fromBits(high, 0); | ||
666 | + } else { | ||
667 | + return Long.fromBits(high >>> (numBits - 32), 0); | ||
668 | + } | ||
669 | + } | ||
670 | +}; | ||
671 | + | ||
672 | +/** | ||
673 | + * Returns a Long representing the given (32-bit) integer value. | ||
674 | + * | ||
675 | + * @method | ||
676 | + * @param {number} value the 32-bit integer in question. | ||
677 | + * @return {Long} the corresponding Long value. | ||
678 | + */ | ||
679 | +Long.fromInt = function(value) { | ||
680 | + if (-128 <= value && value < 128) { | ||
681 | + var cachedObj = Long.INT_CACHE_[value]; | ||
682 | + if (cachedObj) { | ||
683 | + return cachedObj; | ||
684 | + } | ||
685 | + } | ||
686 | + | ||
687 | + var obj = new Long(value | 0, value < 0 ? -1 : 0); | ||
688 | + if (-128 <= value && value < 128) { | ||
689 | + Long.INT_CACHE_[value] = obj; | ||
690 | + } | ||
691 | + return obj; | ||
692 | +}; | ||
693 | + | ||
694 | +/** | ||
695 | + * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. | ||
696 | + * | ||
697 | + * @method | ||
698 | + * @param {number} value the number in question. | ||
699 | + * @return {Long} the corresponding Long value. | ||
700 | + */ | ||
701 | +Long.fromNumber = function(value) { | ||
702 | + if (isNaN(value) || !isFinite(value)) { | ||
703 | + return Long.ZERO; | ||
704 | + } else if (value <= -Long.TWO_PWR_63_DBL_) { | ||
705 | + return Long.MIN_VALUE; | ||
706 | + } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { | ||
707 | + return Long.MAX_VALUE; | ||
708 | + } else if (value < 0) { | ||
709 | + return Long.fromNumber(-value).negate(); | ||
710 | + } else { | ||
711 | + return new Long( | ||
712 | + (value % Long.TWO_PWR_32_DBL_) | 0, | ||
713 | + (value / Long.TWO_PWR_32_DBL_) | 0); | ||
714 | + } | ||
715 | +}; | ||
716 | + | ||
717 | +/** | ||
718 | + * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. | ||
719 | + * | ||
720 | + * @method | ||
721 | + * @param {number} lowBits the low 32-bits. | ||
722 | + * @param {number} highBits the high 32-bits. | ||
723 | + * @return {Long} the corresponding Long value. | ||
724 | + */ | ||
725 | +Long.fromBits = function(lowBits, highBits) { | ||
726 | + return new Long(lowBits, highBits); | ||
727 | +}; | ||
728 | + | ||
729 | +/** | ||
730 | + * Returns a Long representation of the given string, written using the given radix. | ||
731 | + * | ||
732 | + * @method | ||
733 | + * @param {string} str the textual representation of the Long. | ||
734 | + * @param {number} opt_radix the radix in which the text is written. | ||
735 | + * @return {Long} the corresponding Long value. | ||
736 | + */ | ||
737 | +Long.fromString = function(str, opt_radix) { | ||
738 | + if (str.length == 0) { | ||
739 | + throw Error('number format error: empty string'); | ||
740 | + } | ||
741 | + | ||
742 | + var radix = opt_radix || 10; | ||
743 | + if (radix < 2 || 36 < radix) { | ||
744 | + throw Error('radix out of range: ' + radix); | ||
745 | + } | ||
746 | + | ||
747 | + if (str.charAt(0) == '-') { | ||
748 | + return Long.fromString(str.substring(1), radix).negate(); | ||
749 | + } else if (str.indexOf('-') >= 0) { | ||
750 | + throw Error('number format error: interior "-" character: ' + str); | ||
751 | + } | ||
752 | + | ||
753 | + // Do several (8) digits each time through the loop, so as to | ||
754 | + // minimize the calls to the very expensive emulated div. | ||
755 | + var radixToPower = Long.fromNumber(Math.pow(radix, 8)); | ||
756 | + | ||
757 | + var result = Long.ZERO; | ||
758 | + for (var i = 0; i < str.length; i += 8) { | ||
759 | + var size = Math.min(8, str.length - i); | ||
760 | + var value = parseInt(str.substring(i, i + size), radix); | ||
761 | + if (size < 8) { | ||
762 | + var power = Long.fromNumber(Math.pow(radix, size)); | ||
763 | + result = result.multiply(power).add(Long.fromNumber(value)); | ||
764 | + } else { | ||
765 | + result = result.multiply(radixToPower); | ||
766 | + result = result.add(Long.fromNumber(value)); | ||
767 | + } | ||
768 | + } | ||
769 | + return result; | ||
770 | +}; | ||
771 | + | ||
772 | +// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the | ||
773 | +// from* methods on which they depend. | ||
774 | + | ||
775 | + | ||
776 | +/** | ||
777 | + * A cache of the Long representations of small integer values. | ||
778 | + * @type {Object} | ||
779 | + * @ignore | ||
780 | + */ | ||
781 | +Long.INT_CACHE_ = {}; | ||
782 | + | ||
783 | +// NOTE: the compiler should inline these constant values below and then remove | ||
784 | +// these variables, so there should be no runtime penalty for these. | ||
785 | + | ||
786 | +/** | ||
787 | + * Number used repeated below in calculations. This must appear before the | ||
788 | + * first call to any from* function below. | ||
789 | + * @type {number} | ||
790 | + * @ignore | ||
791 | + */ | ||
792 | +Long.TWO_PWR_16_DBL_ = 1 << 16; | ||
793 | + | ||
794 | +/** | ||
795 | + * @type {number} | ||
796 | + * @ignore | ||
797 | + */ | ||
798 | +Long.TWO_PWR_24_DBL_ = 1 << 24; | ||
799 | + | ||
800 | +/** | ||
801 | + * @type {number} | ||
802 | + * @ignore | ||
803 | + */ | ||
804 | +Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; | ||
805 | + | ||
806 | +/** | ||
807 | + * @type {number} | ||
808 | + * @ignore | ||
809 | + */ | ||
810 | +Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; | ||
811 | + | ||
812 | +/** | ||
813 | + * @type {number} | ||
814 | + * @ignore | ||
815 | + */ | ||
816 | +Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; | ||
817 | + | ||
818 | +/** | ||
819 | + * @type {number} | ||
820 | + * @ignore | ||
821 | + */ | ||
822 | +Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; | ||
823 | + | ||
824 | +/** | ||
825 | + * @type {number} | ||
826 | + * @ignore | ||
827 | + */ | ||
828 | +Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; | ||
829 | + | ||
830 | +/** @type {Long} */ | ||
831 | +Long.ZERO = Long.fromInt(0); | ||
832 | + | ||
833 | +/** @type {Long} */ | ||
834 | +Long.ONE = Long.fromInt(1); | ||
835 | + | ||
836 | +/** @type {Long} */ | ||
837 | +Long.NEG_ONE = Long.fromInt(-1); | ||
838 | + | ||
839 | +/** @type {Long} */ | ||
840 | +Long.MAX_VALUE = | ||
841 | + Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); | ||
842 | + | ||
843 | +/** @type {Long} */ | ||
844 | +Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); | ||
845 | + | ||
846 | +/** | ||
847 | + * @type {Long} | ||
848 | + * @ignore | ||
849 | + */ | ||
850 | +Long.TWO_PWR_24_ = Long.fromInt(1 << 24); | ||
851 | + | ||
852 | +/** | ||
853 | + * Expose. | ||
854 | + */ | ||
855 | +module.exports = Long; | ||
856 | +module.exports.Long = Long; |
1 | +"use strict" | ||
2 | + | ||
3 | +// We have an ES6 Map available, return the native instance | ||
4 | +if(typeof global.Map !== 'undefined') { | ||
5 | + module.exports = global.Map; | ||
6 | + module.exports.Map = global.Map; | ||
7 | +} else { | ||
8 | + // We will return a polyfill | ||
9 | + var Map = function(array) { | ||
10 | + this._keys = []; | ||
11 | + this._values = {}; | ||
12 | + | ||
13 | + for(var i = 0; i < array.length; i++) { | ||
14 | + if(array[i] == null) continue; // skip null and undefined | ||
15 | + var entry = array[i]; | ||
16 | + var key = entry[0]; | ||
17 | + var value = entry[1]; | ||
18 | + // Add the key to the list of keys in order | ||
19 | + this._keys.push(key); | ||
20 | + // Add the key and value to the values dictionary with a point | ||
21 | + // to the location in the ordered keys list | ||
22 | + this._values[key] = {v: value, i: this._keys.length - 1}; | ||
23 | + } | ||
24 | + } | ||
25 | + | ||
26 | + Map.prototype.clear = function() { | ||
27 | + this._keys = []; | ||
28 | + this._values = {}; | ||
29 | + } | ||
30 | + | ||
31 | + Map.prototype.delete = function(key) { | ||
32 | + var value = this._values[key]; | ||
33 | + if(value == null) return false; | ||
34 | + // Delete entry | ||
35 | + delete this._values[key]; | ||
36 | + // Remove the key from the ordered keys list | ||
37 | + this._keys.splice(value.i, 1); | ||
38 | + return true; | ||
39 | + } | ||
40 | + | ||
41 | + Map.prototype.entries = function() { | ||
42 | + var self = this; | ||
43 | + var index = 0; | ||
44 | + | ||
45 | + return { | ||
46 | + next: function() { | ||
47 | + var key = self._keys[index++]; | ||
48 | + return { | ||
49 | + value: key !== undefined ? [key, self._values[key].v] : undefined, | ||
50 | + done: key !== undefined ? false : true | ||
51 | + } | ||
52 | + } | ||
53 | + }; | ||
54 | + } | ||
55 | + | ||
56 | + Map.prototype.forEach = function(callback, self) { | ||
57 | + self = self || this; | ||
58 | + | ||
59 | + for(var i = 0; i < this._keys.length; i++) { | ||
60 | + var key = this._keys[i]; | ||
61 | + // Call the forEach callback | ||
62 | + callback.call(self, this._values[key].v, key, self); | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + Map.prototype.get = function(key) { | ||
67 | + return this._values[key] ? this._values[key].v : undefined; | ||
68 | + } | ||
69 | + | ||
70 | + Map.prototype.has = function(key) { | ||
71 | + return this._values[key] != null; | ||
72 | + } | ||
73 | + | ||
74 | + Map.prototype.keys = function(key) { | ||
75 | + var self = this; | ||
76 | + var index = 0; | ||
77 | + | ||
78 | + return { | ||
79 | + next: function() { | ||
80 | + var key = self._keys[index++]; | ||
81 | + return { | ||
82 | + value: key !== undefined ? key : undefined, | ||
83 | + done: key !== undefined ? false : true | ||
84 | + } | ||
85 | + } | ||
86 | + }; | ||
87 | + } | ||
88 | + | ||
89 | + Map.prototype.set = function(key, value) { | ||
90 | + if(this._values[key]) { | ||
91 | + this._values[key].v = value; | ||
92 | + return this; | ||
93 | + } | ||
94 | + | ||
95 | + // Add the key to the list of keys in order | ||
96 | + this._keys.push(key); | ||
97 | + // Add the key and value to the values dictionary with a point | ||
98 | + // to the location in the ordered keys list | ||
99 | + this._values[key] = {v: value, i: this._keys.length - 1}; | ||
100 | + return this; | ||
101 | + } | ||
102 | + | ||
103 | + Map.prototype.values = function(key, value) { | ||
104 | + var self = this; | ||
105 | + var index = 0; | ||
106 | + | ||
107 | + return { | ||
108 | + next: function() { | ||
109 | + var key = self._keys[index++]; | ||
110 | + return { | ||
111 | + value: key !== undefined ? self._values[key].v : undefined, | ||
112 | + done: key !== undefined ? false : true | ||
113 | + } | ||
114 | + } | ||
115 | + }; | ||
116 | + } | ||
117 | + | ||
118 | + // Last ismaster | ||
119 | + Object.defineProperty(Map.prototype, 'size', { | ||
120 | + enumerable:true, | ||
121 | + get: function() { return this._keys.length; } | ||
122 | + }); | ||
123 | + | ||
124 | + module.exports = Map; | ||
125 | + module.exports.Map = Map; | ||
126 | +} |
1 | +/** | ||
2 | + * A class representation of the BSON MaxKey type. | ||
3 | + * | ||
4 | + * @class | ||
5 | + * @return {MaxKey} A MaxKey instance | ||
6 | + */ | ||
7 | +function MaxKey() { | ||
8 | + if(!(this instanceof MaxKey)) return new MaxKey(); | ||
9 | + | ||
10 | + this._bsontype = 'MaxKey'; | ||
11 | +} | ||
12 | + | ||
13 | +module.exports = MaxKey; | ||
14 | +module.exports.MaxKey = MaxKey; |
1 | +/** | ||
2 | + * A class representation of the BSON MinKey type. | ||
3 | + * | ||
4 | + * @class | ||
5 | + * @return {MinKey} A MinKey instance | ||
6 | + */ | ||
7 | +function MinKey() { | ||
8 | + if(!(this instanceof MinKey)) return new MinKey(); | ||
9 | + | ||
10 | + this._bsontype = 'MinKey'; | ||
11 | +} | ||
12 | + | ||
13 | +module.exports = MinKey; | ||
14 | +module.exports.MinKey = MinKey; |
1 | +/** | ||
2 | + * Machine id. | ||
3 | + * | ||
4 | + * Create a random 3-byte value (i.e. unique for this | ||
5 | + * process). Other drivers use a md5 of the machine id here, but | ||
6 | + * that would mean an asyc call to gethostname, so we don't bother. | ||
7 | + * @ignore | ||
8 | + */ | ||
9 | +var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); | ||
10 | + | ||
11 | +// Regular expression that checks for hex value | ||
12 | +var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); | ||
13 | +var hasBufferType = false; | ||
14 | + | ||
15 | +// Check if buffer exists | ||
16 | +try { | ||
17 | + if(Buffer && Buffer.from) hasBufferType = true; | ||
18 | +} catch(err) {}; | ||
19 | + | ||
20 | +/** | ||
21 | +* Create a new ObjectID instance | ||
22 | +* | ||
23 | +* @class | ||
24 | +* @param {(string|number)} id Can be a 24 byte hex string, 12 byte binary string or a Number. | ||
25 | +* @property {number} generationTime The generation time of this ObjectId instance | ||
26 | +* @return {ObjectID} instance of ObjectID. | ||
27 | +*/ | ||
28 | +var ObjectID = function ObjectID(id) { | ||
29 | + // Duck-typing to support ObjectId from different npm packages | ||
30 | + if(id instanceof ObjectID) return id; | ||
31 | + if(!(this instanceof ObjectID)) return new ObjectID(id); | ||
32 | + | ||
33 | + this._bsontype = 'ObjectID'; | ||
34 | + | ||
35 | + // The most common usecase (blank id, new objectId instance) | ||
36 | + if(id == null || typeof id == 'number') { | ||
37 | + // Generate a new id | ||
38 | + this.id = this.generate(id); | ||
39 | + // If we are caching the hex string | ||
40 | + if(ObjectID.cacheHexString) this.__id = this.toString('hex'); | ||
41 | + // Return the object | ||
42 | + return; | ||
43 | + } | ||
44 | + | ||
45 | + // Check if the passed in id is valid | ||
46 | + var valid = ObjectID.isValid(id); | ||
47 | + | ||
48 | + // Throw an error if it's not a valid setup | ||
49 | + if(!valid && id != null){ | ||
50 | + throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); | ||
51 | + } else if(valid && typeof id == 'string' && id.length == 24 && hasBufferType) { | ||
52 | + return new ObjectID(new Buffer(id, 'hex')); | ||
53 | + } else if(valid && typeof id == 'string' && id.length == 24) { | ||
54 | + return ObjectID.createFromHexString(id); | ||
55 | + } else if(id != null && id.length === 12) { | ||
56 | + // assume 12 byte string | ||
57 | + this.id = id; | ||
58 | + } else if(id != null && id.toHexString) { | ||
59 | + // Duck-typing to support ObjectId from different npm packages | ||
60 | + return id; | ||
61 | + } else { | ||
62 | + throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); | ||
63 | + } | ||
64 | + | ||
65 | + if(ObjectID.cacheHexString) this.__id = this.toString('hex'); | ||
66 | +}; | ||
67 | + | ||
68 | +// Allow usage of ObjectId as well as ObjectID | ||
69 | +var ObjectId = ObjectID; | ||
70 | + | ||
71 | +// Precomputed hex table enables speedy hex string conversion | ||
72 | +var hexTable = []; | ||
73 | +for (var i = 0; i < 256; i++) { | ||
74 | + hexTable[i] = (i <= 15 ? '0' : '') + i.toString(16); | ||
75 | +} | ||
76 | + | ||
77 | +/** | ||
78 | +* Return the ObjectID id as a 24 byte hex string representation | ||
79 | +* | ||
80 | +* @method | ||
81 | +* @return {string} return the 24 byte hex string representation. | ||
82 | +*/ | ||
83 | +ObjectID.prototype.toHexString = function() { | ||
84 | + if(ObjectID.cacheHexString && this.__id) return this.__id; | ||
85 | + | ||
86 | + var hexString = ''; | ||
87 | + if(!this.id || !this.id.length) { | ||
88 | + throw new Error('invalid ObjectId, ObjectId.id must be either a string or a Buffer, but is [' + JSON.stringify(this.id) + ']'); | ||
89 | + } | ||
90 | + | ||
91 | + if(this.id instanceof _Buffer) { | ||
92 | + hexString = convertToHex(this.id); | ||
93 | + if(ObjectID.cacheHexString) this.__id = hexString; | ||
94 | + return hexString; | ||
95 | + } | ||
96 | + | ||
97 | + for (var i = 0; i < this.id.length; i++) { | ||
98 | + hexString += hexTable[this.id.charCodeAt(i)]; | ||
99 | + } | ||
100 | + | ||
101 | + if(ObjectID.cacheHexString) this.__id = hexString; | ||
102 | + return hexString; | ||
103 | +}; | ||
104 | + | ||
105 | +/** | ||
106 | +* Update the ObjectID index used in generating new ObjectID's on the driver | ||
107 | +* | ||
108 | +* @method | ||
109 | +* @return {number} returns next index value. | ||
110 | +* @ignore | ||
111 | +*/ | ||
112 | +ObjectID.prototype.get_inc = function() { | ||
113 | + return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; | ||
114 | +}; | ||
115 | + | ||
116 | +/** | ||
117 | +* Update the ObjectID index used in generating new ObjectID's on the driver | ||
118 | +* | ||
119 | +* @method | ||
120 | +* @return {number} returns next index value. | ||
121 | +* @ignore | ||
122 | +*/ | ||
123 | +ObjectID.prototype.getInc = function() { | ||
124 | + return this.get_inc(); | ||
125 | +}; | ||
126 | + | ||
127 | +/** | ||
128 | +* Generate a 12 byte id buffer used in ObjectID's | ||
129 | +* | ||
130 | +* @method | ||
131 | +* @param {number} [time] optional parameter allowing to pass in a second based timestamp. | ||
132 | +* @return {Buffer} return the 12 byte id buffer string. | ||
133 | +*/ | ||
134 | +ObjectID.prototype.generate = function(time) { | ||
135 | + if ('number' != typeof time) { | ||
136 | + time = ~~(Date.now()/1000); | ||
137 | + } | ||
138 | + | ||
139 | + // Use pid | ||
140 | + var pid = (typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid) % 0xFFFF; | ||
141 | + var inc = this.get_inc(); | ||
142 | + // Buffer used | ||
143 | + var buffer = new Buffer(12); | ||
144 | + // Encode time | ||
145 | + buffer[3] = time & 0xff; | ||
146 | + buffer[2] = (time >> 8) & 0xff; | ||
147 | + buffer[1] = (time >> 16) & 0xff; | ||
148 | + buffer[0] = (time >> 24) & 0xff; | ||
149 | + // Encode machine | ||
150 | + buffer[6] = MACHINE_ID & 0xff; | ||
151 | + buffer[5] = (MACHINE_ID >> 8) & 0xff; | ||
152 | + buffer[4] = (MACHINE_ID >> 16) & 0xff; | ||
153 | + // Encode pid | ||
154 | + buffer[8] = pid & 0xff; | ||
155 | + buffer[7] = (pid >> 8) & 0xff; | ||
156 | + // Encode index | ||
157 | + buffer[11] = inc & 0xff; | ||
158 | + buffer[10] = (inc >> 8) & 0xff; | ||
159 | + buffer[9] = (inc >> 16) & 0xff; | ||
160 | + // Return the buffer | ||
161 | + return buffer; | ||
162 | +}; | ||
163 | + | ||
164 | +/** | ||
165 | +* Converts the id into a 24 byte hex string for printing | ||
166 | +* | ||
167 | +* @param {String} format The Buffer toString format parameter. | ||
168 | +* @return {String} return the 24 byte hex string representation. | ||
169 | +* @ignore | ||
170 | +*/ | ||
171 | +ObjectID.prototype.toString = function(format) { | ||
172 | + // Is the id a buffer then use the buffer toString method to return the format | ||
173 | + if(this.id && this.id.copy) { | ||
174 | + return this.id.toString(typeof format === 'string' ? format : 'hex'); | ||
175 | + } | ||
176 | + | ||
177 | + // if(this.buffer ) | ||
178 | + return this.toHexString(); | ||
179 | +}; | ||
180 | + | ||
181 | +/** | ||
182 | +* Converts to a string representation of this Id. | ||
183 | +* | ||
184 | +* @return {String} return the 24 byte hex string representation. | ||
185 | +* @ignore | ||
186 | +*/ | ||
187 | +ObjectID.prototype.inspect = ObjectID.prototype.toString; | ||
188 | + | ||
189 | +/** | ||
190 | +* Converts to its JSON representation. | ||
191 | +* | ||
192 | +* @return {String} return the 24 byte hex string representation. | ||
193 | +* @ignore | ||
194 | +*/ | ||
195 | +ObjectID.prototype.toJSON = function() { | ||
196 | + return this.toHexString(); | ||
197 | +}; | ||
198 | + | ||
199 | +/** | ||
200 | +* Compares the equality of this ObjectID with `otherID`. | ||
201 | +* | ||
202 | +* @method | ||
203 | +* @param {object} otherID ObjectID instance to compare against. | ||
204 | +* @return {boolean} the result of comparing two ObjectID's | ||
205 | +*/ | ||
206 | +ObjectID.prototype.equals = function equals (otherId) { | ||
207 | + var id; | ||
208 | + | ||
209 | + if(otherId instanceof ObjectID) { | ||
210 | + return this.toString() == otherId.toString(); | ||
211 | + } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 12 && this.id instanceof _Buffer) { | ||
212 | + return otherId === this.id.toString('binary'); | ||
213 | + } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 24) { | ||
214 | + return otherId.toLowerCase() === this.toHexString(); | ||
215 | + } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 12) { | ||
216 | + return otherId === this.id; | ||
217 | + } else if(otherId != null && (otherId instanceof ObjectID || otherId.toHexString)) { | ||
218 | + return otherId.toHexString() === this.toHexString(); | ||
219 | + } else { | ||
220 | + return false; | ||
221 | + } | ||
222 | +} | ||
223 | + | ||
224 | +/** | ||
225 | +* Returns the generation date (accurate up to the second) that this ID was generated. | ||
226 | +* | ||
227 | +* @method | ||
228 | +* @return {date} the generation date | ||
229 | +*/ | ||
230 | +ObjectID.prototype.getTimestamp = function() { | ||
231 | + var timestamp = new Date(); | ||
232 | + var time = this.id[3] | this.id[2] << 8 | this.id[1] << 16 | this.id[0] << 24; | ||
233 | + timestamp.setTime(Math.floor(time) * 1000); | ||
234 | + return timestamp; | ||
235 | +} | ||
236 | + | ||
237 | +/** | ||
238 | +* @ignore | ||
239 | +*/ | ||
240 | +ObjectID.index = ~~(Math.random() * 0xFFFFFF); | ||
241 | + | ||
242 | +/** | ||
243 | +* @ignore | ||
244 | +*/ | ||
245 | +ObjectID.createPk = function createPk () { | ||
246 | + return new ObjectID(); | ||
247 | +}; | ||
248 | + | ||
249 | +/** | ||
250 | +* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. | ||
251 | +* | ||
252 | +* @method | ||
253 | +* @param {number} time an integer number representing a number of seconds. | ||
254 | +* @return {ObjectID} return the created ObjectID | ||
255 | +*/ | ||
256 | +ObjectID.createFromTime = function createFromTime (time) { | ||
257 | + var buffer = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); | ||
258 | + // Encode time into first 4 bytes | ||
259 | + buffer[3] = time & 0xff; | ||
260 | + buffer[2] = (time >> 8) & 0xff; | ||
261 | + buffer[1] = (time >> 16) & 0xff; | ||
262 | + buffer[0] = (time >> 24) & 0xff; | ||
263 | + // Return the new objectId | ||
264 | + return new ObjectID(buffer); | ||
265 | +}; | ||
266 | + | ||
267 | +// Lookup tables | ||
268 | +var encodeLookup = '0123456789abcdef'.split('') | ||
269 | +var decodeLookup = [] | ||
270 | +var i = 0 | ||
271 | +while (i < 10) decodeLookup[0x30 + i] = i++ | ||
272 | +while (i < 16) decodeLookup[0x41 - 10 + i] = decodeLookup[0x61 - 10 + i] = i++ | ||
273 | + | ||
274 | +var _Buffer = Buffer; | ||
275 | +var convertToHex = function(bytes) { | ||
276 | + return bytes.toString('hex'); | ||
277 | +} | ||
278 | + | ||
279 | +/** | ||
280 | +* Creates an ObjectID from a hex string representation of an ObjectID. | ||
281 | +* | ||
282 | +* @method | ||
283 | +* @param {string} hexString create a ObjectID from a passed in 24 byte hexstring. | ||
284 | +* @return {ObjectID} return the created ObjectID | ||
285 | +*/ | ||
286 | +ObjectID.createFromHexString = function createFromHexString (string) { | ||
287 | + // Throw an error if it's not a valid setup | ||
288 | + if(typeof string === 'undefined' || string != null && string.length != 24) { | ||
289 | + throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); | ||
290 | + } | ||
291 | + | ||
292 | + // Use Buffer.from method if available | ||
293 | + if(hasBufferType) return new ObjectID(new Buffer(string, 'hex')); | ||
294 | + | ||
295 | + // Calculate lengths | ||
296 | + var array = new _Buffer(12); | ||
297 | + var n = 0; | ||
298 | + var i = 0; | ||
299 | + | ||
300 | + while (i < 24) { | ||
301 | + array[n++] = decodeLookup[string.charCodeAt(i++)] << 4 | decodeLookup[string.charCodeAt(i++)] | ||
302 | + } | ||
303 | + | ||
304 | + return new ObjectID(array); | ||
305 | +}; | ||
306 | + | ||
307 | +/** | ||
308 | +* Checks if a value is a valid bson ObjectId | ||
309 | +* | ||
310 | +* @method | ||
311 | +* @return {boolean} return true if the value is a valid bson ObjectId, return false otherwise. | ||
312 | +*/ | ||
313 | +ObjectID.isValid = function isValid(id) { | ||
314 | + if(id == null) return false; | ||
315 | + | ||
316 | + if(typeof id == 'number') { | ||
317 | + return true; | ||
318 | + } | ||
319 | + | ||
320 | + if(typeof id == 'string') { | ||
321 | + return id.length == 12 || (id.length == 24 && checkForHexRegExp.test(id)); | ||
322 | + } | ||
323 | + | ||
324 | + if(id instanceof ObjectID) { | ||
325 | + return true; | ||
326 | + } | ||
327 | + | ||
328 | + if(id instanceof _Buffer) { | ||
329 | + return true; | ||
330 | + } | ||
331 | + | ||
332 | + // Duck-Typing detection of ObjectId like objects | ||
333 | + if(id.toHexString) { | ||
334 | + return id.id.length == 12 || (id.id.length == 24 && checkForHexRegExp.test(id.id)); | ||
335 | + } | ||
336 | + | ||
337 | + return false; | ||
338 | +}; | ||
339 | + | ||
340 | +/** | ||
341 | +* @ignore | ||
342 | +*/ | ||
343 | +Object.defineProperty(ObjectID.prototype, "generationTime", { | ||
344 | + enumerable: true | ||
345 | + , get: function () { | ||
346 | + return this.id[3] | this.id[2] << 8 | this.id[1] << 16 | this.id[0] << 24; | ||
347 | + } | ||
348 | + , set: function (value) { | ||
349 | + // Encode time into first 4 bytes | ||
350 | + this.id[3] = value & 0xff; | ||
351 | + this.id[2] = (value >> 8) & 0xff; | ||
352 | + this.id[1] = (value >> 16) & 0xff; | ||
353 | + this.id[0] = (value >> 24) & 0xff; | ||
354 | + } | ||
355 | +}); | ||
356 | + | ||
357 | +/** | ||
358 | + * Expose. | ||
359 | + */ | ||
360 | +module.exports = ObjectID; | ||
361 | +module.exports.ObjectID = ObjectID; | ||
362 | +module.exports.ObjectId = ObjectID; |
1 | +"use strict" | ||
2 | + | ||
3 | +var writeIEEE754 = require('../float_parser').writeIEEE754 | ||
4 | + , readIEEE754 = require('../float_parser').readIEEE754 | ||
5 | + , Long = require('../long').Long | ||
6 | + , Double = require('../double').Double | ||
7 | + , Timestamp = require('../timestamp').Timestamp | ||
8 | + , ObjectID = require('../objectid').ObjectID | ||
9 | + , Symbol = require('../symbol').Symbol | ||
10 | + , BSONRegExp = require('../regexp').BSONRegExp | ||
11 | + , Code = require('../code').Code | ||
12 | + , Decimal128 = require('../decimal128') | ||
13 | + , MinKey = require('../min_key').MinKey | ||
14 | + , MaxKey = require('../max_key').MaxKey | ||
15 | + , DBRef = require('../db_ref').DBRef | ||
16 | + , Binary = require('../binary').Binary; | ||
17 | + | ||
18 | +// To ensure that 0.4 of node works correctly | ||
19 | +var isDate = function isDate(d) { | ||
20 | + return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; | ||
21 | +} | ||
22 | + | ||
23 | +var calculateObjectSize = function calculateObjectSize(object, serializeFunctions, ignoreUndefined) { | ||
24 | + var totalLength = (4 + 1); | ||
25 | + | ||
26 | + if(Array.isArray(object)) { | ||
27 | + for(var i = 0; i < object.length; i++) { | ||
28 | + totalLength += calculateElement(i.toString(), object[i], serializeFunctions, true, ignoreUndefined) | ||
29 | + } | ||
30 | + } else { | ||
31 | + // If we have toBSON defined, override the current object | ||
32 | + if(object.toBSON) { | ||
33 | + object = object.toBSON(); | ||
34 | + } | ||
35 | + | ||
36 | + // Calculate size | ||
37 | + for(var key in object) { | ||
38 | + totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined) | ||
39 | + } | ||
40 | + } | ||
41 | + | ||
42 | + return totalLength; | ||
43 | +} | ||
44 | + | ||
45 | +/** | ||
46 | + * @ignore | ||
47 | + * @api private | ||
48 | + */ | ||
49 | +function calculateElement(name, value, serializeFunctions, isArray, ignoreUndefined) { | ||
50 | + // If we have toBSON defined, override the current object | ||
51 | + if(value && value.toBSON){ | ||
52 | + value = value.toBSON(); | ||
53 | + } | ||
54 | + | ||
55 | + switch(typeof value) { | ||
56 | + case 'string': | ||
57 | + return 1 + Buffer.byteLength(name, 'utf8') + 1 + 4 + Buffer.byteLength(value, 'utf8') + 1; | ||
58 | + case 'number': | ||
59 | + if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { | ||
60 | + if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit | ||
61 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (4 + 1); | ||
62 | + } else { | ||
63 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (8 + 1); | ||
64 | + } | ||
65 | + } else { // 64 bit | ||
66 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (8 + 1); | ||
67 | + } | ||
68 | + case 'undefined': | ||
69 | + if(isArray || !ignoreUndefined) return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (1); | ||
70 | + return 0; | ||
71 | + case 'boolean': | ||
72 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (1 + 1); | ||
73 | + case 'object': | ||
74 | + if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { | ||
75 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (1); | ||
76 | + } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { | ||
77 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (12 + 1); | ||
78 | + } else if(value instanceof Date || isDate(value)) { | ||
79 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (8 + 1); | ||
80 | + } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { | ||
81 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (1 + 4 + 1) + value.length; | ||
82 | + } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp | ||
83 | + || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { | ||
84 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (8 + 1); | ||
85 | + } else if(value instanceof Decimal128 || value['_bsontype'] == 'Decimal128') { | ||
86 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (16 + 1); | ||
87 | + } else if(value instanceof Code || value['_bsontype'] == 'Code') { | ||
88 | + // Calculate size depending on the availability of a scope | ||
89 | + if(value.scope != null && Object.keys(value.scope).length > 0) { | ||
90 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + 4 + 4 + Buffer.byteLength(value.code.toString(), 'utf8') + 1 + calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined); | ||
91 | + } else { | ||
92 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + 4 + Buffer.byteLength(value.code.toString(), 'utf8') + 1; | ||
93 | + } | ||
94 | + } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { | ||
95 | + // Check what kind of subtype we have | ||
96 | + if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { | ||
97 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (value.position + 1 + 4 + 1 + 4); | ||
98 | + } else { | ||
99 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + (value.position + 1 + 4 + 1); | ||
100 | + } | ||
101 | + } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { | ||
102 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + Buffer.byteLength(value.value, 'utf8') + 4 + 1 + 1; | ||
103 | + } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { | ||
104 | + // Set up correct object for serialization | ||
105 | + var ordered_values = { | ||
106 | + '$ref': value.namespace | ||
107 | + , '$id' : value.oid | ||
108 | + }; | ||
109 | + | ||
110 | + // Add db reference if it exists | ||
111 | + if(null != value.db) { | ||
112 | + ordered_values['$db'] = value.db; | ||
113 | + } | ||
114 | + | ||
115 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + calculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined); | ||
116 | + } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { | ||
117 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + Buffer.byteLength(value.source, 'utf8') + 1 | ||
118 | + + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 | ||
119 | + } else if(value instanceof BSONRegExp || value['_bsontype'] == 'BSONRegExp') { | ||
120 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + Buffer.byteLength(value.pattern, 'utf8') + 1 | ||
121 | + + Buffer.byteLength(value.options, 'utf8') + 1 | ||
122 | + } else { | ||
123 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + calculateObjectSize(value, serializeFunctions, ignoreUndefined) + 1; | ||
124 | + } | ||
125 | + case 'function': | ||
126 | + // WTF for 0.4.X where typeof /someregexp/ === 'function' | ||
127 | + if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { | ||
128 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + Buffer.byteLength(value.source, 'utf8') + 1 | ||
129 | + + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 | ||
130 | + } else { | ||
131 | + if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { | ||
132 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + 4 + 4 + Buffer.byteLength(value.toString(), 'utf8') + 1 + calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined); | ||
133 | + } else if(serializeFunctions) { | ||
134 | + return (name != null ? (Buffer.byteLength(name, 'utf8') + 1) : 0) + 1 + 4 + Buffer.byteLength(value.toString(), 'utf8') + 1; | ||
135 | + } | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + return 0; | ||
140 | +} | ||
141 | + | ||
142 | +var BSON = {}; | ||
143 | + | ||
144 | +// BSON MAX VALUES | ||
145 | +BSON.BSON_INT32_MAX = 0x7FFFFFFF; | ||
146 | +BSON.BSON_INT32_MIN = -0x80000000; | ||
147 | + | ||
148 | +// JS MAX PRECISE VALUES | ||
149 | +BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. | ||
150 | +BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. | ||
151 | + | ||
152 | +module.exports = calculateObjectSize; |
1 | +"use strict" | ||
2 | + | ||
3 | +var readIEEE754 = require('../float_parser').readIEEE754, | ||
4 | + f = require('util').format, | ||
5 | + Long = require('../long').Long, | ||
6 | + Double = require('../double').Double, | ||
7 | + Timestamp = require('../timestamp').Timestamp, | ||
8 | + ObjectID = require('../objectid').ObjectID, | ||
9 | + Symbol = require('../symbol').Symbol, | ||
10 | + Code = require('../code').Code, | ||
11 | + MinKey = require('../min_key').MinKey, | ||
12 | + MaxKey = require('../max_key').MaxKey, | ||
13 | + Decimal128 = require('../decimal128'), | ||
14 | + Int32 = require('../int_32'), | ||
15 | + DBRef = require('../db_ref').DBRef, | ||
16 | + BSONRegExp = require('../regexp').BSONRegExp, | ||
17 | + Binary = require('../binary').Binary; | ||
18 | + | ||
19 | +var deserialize = function(buffer, options, isArray) { | ||
20 | + options = options == null ? {} : options; | ||
21 | + var index = options && options.index ? options.index : 0; | ||
22 | + // Read the document size | ||
23 | + var size = buffer[index] | buffer[index+1] << 8 | buffer[index+2] << 16 | buffer[index+3] << 24; | ||
24 | + | ||
25 | + // Ensure buffer is valid size | ||
26 | + if(size < 5 || buffer.length < size || (size + index) > buffer.length) { | ||
27 | + throw new Error("corrupt bson message"); | ||
28 | + } | ||
29 | + | ||
30 | + // Illegal end value | ||
31 | + if(buffer[index + size - 1] != 0) { | ||
32 | + throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00"); | ||
33 | + } | ||
34 | + | ||
35 | + // Start deserializtion | ||
36 | + return deserializeObject(buffer, index, options, isArray); | ||
37 | +} | ||
38 | + | ||
39 | +var deserializeObject = function(buffer, index, options, isArray) { | ||
40 | + var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; | ||
41 | + var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; | ||
42 | + var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; | ||
43 | + var fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw']; | ||
44 | + | ||
45 | + // Return raw bson buffer instead of parsing it | ||
46 | + var raw = options['raw'] == null ? false : options['raw']; | ||
47 | + | ||
48 | + // Return BSONRegExp objects instead of native regular expressions | ||
49 | + var bsonRegExp = typeof options['bsonRegExp'] == 'boolean' ? options['bsonRegExp'] : false; | ||
50 | + | ||
51 | + // Controls the promotion of values vs wrapper classes | ||
52 | + var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers']; | ||
53 | + var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs']; | ||
54 | + var promoteValues = options['promoteValues'] == null ? true : options['promoteValues']; | ||
55 | + | ||
56 | + // Set the start index | ||
57 | + var startIndex = index; | ||
58 | + | ||
59 | + // Validate that we have at least 4 bytes of buffer | ||
60 | + if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); | ||
61 | + | ||
62 | + // Read the document size | ||
63 | + var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
64 | + | ||
65 | + // Ensure buffer is valid size | ||
66 | + if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); | ||
67 | + | ||
68 | + // Create holding object | ||
69 | + var object = isArray ? [] : {}; | ||
70 | + // Used for arrays to skip having to perform utf8 decoding | ||
71 | + var arrayIndex = 0; | ||
72 | + | ||
73 | + // While we have more left data left keep parsing | ||
74 | + while(true) { | ||
75 | + // Read the type | ||
76 | + var elementType = buffer[index++]; | ||
77 | + // If we get a zero it's the last byte, exit | ||
78 | + if(elementType == 0) { | ||
79 | + break; | ||
80 | + } | ||
81 | + | ||
82 | + // Get the start search index | ||
83 | + var i = index; | ||
84 | + // Locate the end of the c string | ||
85 | + while(buffer[i] !== 0x00 && i < buffer.length) { | ||
86 | + i++ | ||
87 | + } | ||
88 | + | ||
89 | + // If are at the end of the buffer there is a problem with the document | ||
90 | + if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString") | ||
91 | + var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i); | ||
92 | + | ||
93 | + index = i + 1; | ||
94 | + | ||
95 | + if(elementType == BSON.BSON_DATA_STRING) { | ||
96 | + var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
97 | + if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson"); | ||
98 | + object[name] = buffer.toString('utf8', index, index + stringSize - 1); | ||
99 | + index = index + stringSize; | ||
100 | + } else if(elementType == BSON.BSON_DATA_OID) { | ||
101 | + var oid = new Buffer(12); | ||
102 | + buffer.copy(oid, 0, index, index + 12); | ||
103 | + object[name] = new ObjectID(oid); | ||
104 | + index = index + 12; | ||
105 | + } else if(elementType == BSON.BSON_DATA_INT && promoteValues == false) { | ||
106 | + object[name] = new Int32(buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24); | ||
107 | + } else if(elementType == BSON.BSON_DATA_INT) { | ||
108 | + object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
109 | + } else if(elementType == BSON.BSON_DATA_NUMBER && promoteValues == false) { | ||
110 | + object[name] = new Double(buffer.readDoubleLE(index)); | ||
111 | + index = index + 8; | ||
112 | + } else if(elementType == BSON.BSON_DATA_NUMBER) { | ||
113 | + object[name] = buffer.readDoubleLE(index); | ||
114 | + index = index + 8; | ||
115 | + } else if(elementType == BSON.BSON_DATA_DATE) { | ||
116 | + var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
117 | + var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
118 | + object[name] = new Date(new Long(lowBits, highBits).toNumber()); | ||
119 | + } else if(elementType == BSON.BSON_DATA_BOOLEAN) { | ||
120 | + if(buffer[index] != 0 && buffer[index] != 1) throw new Error('illegal boolean type value'); | ||
121 | + object[name] = buffer[index++] == 1; | ||
122 | + } else if(elementType == BSON.BSON_DATA_OBJECT) { | ||
123 | + var _index = index; | ||
124 | + var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; | ||
125 | + if(objectSize <= 0 || objectSize > (buffer.length - index)) throw new Error("bad embedded document length in bson"); | ||
126 | + | ||
127 | + // We have a raw value | ||
128 | + if(raw) { | ||
129 | + object[name] = buffer.slice(index, index + objectSize); | ||
130 | + } else { | ||
131 | + object[name] = deserializeObject(buffer, _index, options, false); | ||
132 | + } | ||
133 | + | ||
134 | + index = index + objectSize; | ||
135 | + } else if(elementType == BSON.BSON_DATA_ARRAY) { | ||
136 | + var _index = index; | ||
137 | + var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; | ||
138 | + var arrayOptions = options; | ||
139 | + | ||
140 | + // Stop index | ||
141 | + var stopIndex = index + objectSize; | ||
142 | + | ||
143 | + // All elements of array to be returned as raw bson | ||
144 | + if(fieldsAsRaw && fieldsAsRaw[name]) { | ||
145 | + arrayOptions = {}; | ||
146 | + for(var n in options) arrayOptions[n] = options[n]; | ||
147 | + arrayOptions['raw'] = true; | ||
148 | + } | ||
149 | + | ||
150 | + object[name] = deserializeObject(buffer, _index, arrayOptions, true); | ||
151 | + index = index + objectSize; | ||
152 | + | ||
153 | + if(buffer[index - 1] != 0) throw new Error('invalid array terminator byte'); | ||
154 | + if(index != stopIndex) throw new Error('corrupted array bson'); | ||
155 | + } else if(elementType == BSON.BSON_DATA_UNDEFINED) { | ||
156 | + object[name] = undefined; | ||
157 | + } else if(elementType == BSON.BSON_DATA_NULL) { | ||
158 | + object[name] = null; | ||
159 | + } else if(elementType == BSON.BSON_DATA_LONG) { | ||
160 | + // Unpack the low and high bits | ||
161 | + var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
162 | + var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
163 | + var long = new Long(lowBits, highBits); | ||
164 | + // Promote the long if possible | ||
165 | + if(promoteLongs && promoteValues == true) { | ||
166 | + object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; | ||
167 | + } else { | ||
168 | + object[name] = long; | ||
169 | + } | ||
170 | + } else if(elementType == BSON.BSON_DATA_DECIMAL128) { | ||
171 | + // Buffer to contain the decimal bytes | ||
172 | + var bytes = new Buffer(16); | ||
173 | + // Copy the next 16 bytes into the bytes buffer | ||
174 | + buffer.copy(bytes, 0, index, index + 16); | ||
175 | + // Update index | ||
176 | + index = index + 16; | ||
177 | + // Assign the new Decimal128 value | ||
178 | + var decimal128 = new Decimal128(bytes); | ||
179 | + // If we have an alternative mapper use that | ||
180 | + object[name] = decimal128.toObject ? decimal128.toObject() : decimal128; | ||
181 | + } else if(elementType == BSON.BSON_DATA_BINARY) { | ||
182 | + var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
183 | + var totalBinarySize = binarySize; | ||
184 | + var subType = buffer[index++]; | ||
185 | + | ||
186 | + // Did we have a negative binary size, throw | ||
187 | + if(binarySize < 0) throw new Error('Negative binary type element size found'); | ||
188 | + | ||
189 | + // Is the length longer than the document | ||
190 | + if(binarySize > buffer.length) throw new Error('Binary type size larger than document size'); | ||
191 | + | ||
192 | + // Decode as raw Buffer object if options specifies it | ||
193 | + if(buffer['slice'] != null) { | ||
194 | + // If we have subtype 2 skip the 4 bytes for the size | ||
195 | + if(subType == Binary.SUBTYPE_BYTE_ARRAY) { | ||
196 | + binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
197 | + if(binarySize < 0) throw new Error('Negative binary type element size found for subtype 0x02'); | ||
198 | + if(binarySize > (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to long binary size'); | ||
199 | + if(binarySize < (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to short binary size'); | ||
200 | + } | ||
201 | + | ||
202 | + if(promoteBuffers && promoteValues) { | ||
203 | + object[name] = buffer.slice(index, index + binarySize); | ||
204 | + } else { | ||
205 | + object[name] = new Binary(buffer.slice(index, index + binarySize), subType); | ||
206 | + } | ||
207 | + } else { | ||
208 | + var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); | ||
209 | + // If we have subtype 2 skip the 4 bytes for the size | ||
210 | + if(subType == Binary.SUBTYPE_BYTE_ARRAY) { | ||
211 | + binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
212 | + if(binarySize < 0) throw new Error('Negative binary type element size found for subtype 0x02'); | ||
213 | + if(binarySize > (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to long binary size'); | ||
214 | + if(binarySize < (totalBinarySize - 4)) throw new Error('Binary type with subtype 0x02 contains to short binary size'); | ||
215 | + } | ||
216 | + | ||
217 | + // Copy the data | ||
218 | + for(var i = 0; i < binarySize; i++) { | ||
219 | + _buffer[i] = buffer[index + i]; | ||
220 | + } | ||
221 | + | ||
222 | + if(promoteBuffers && promoteValues) { | ||
223 | + object[name] = _buffer; | ||
224 | + } else { | ||
225 | + object[name] = new Binary(_buffer, subType); | ||
226 | + } | ||
227 | + } | ||
228 | + | ||
229 | + // Update the index | ||
230 | + index = index + binarySize; | ||
231 | + } else if(elementType == BSON.BSON_DATA_REGEXP && bsonRegExp == false) { | ||
232 | + // Get the start search index | ||
233 | + var i = index; | ||
234 | + // Locate the end of the c string | ||
235 | + while(buffer[i] !== 0x00 && i < buffer.length) { | ||
236 | + i++ | ||
237 | + } | ||
238 | + // If are at the end of the buffer there is a problem with the document | ||
239 | + if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString") | ||
240 | + // Return the C string | ||
241 | + var source = buffer.toString('utf8', index, i); | ||
242 | + // Create the regexp | ||
243 | + index = i + 1; | ||
244 | + | ||
245 | + // Get the start search index | ||
246 | + var i = index; | ||
247 | + // Locate the end of the c string | ||
248 | + while(buffer[i] !== 0x00 && i < buffer.length) { | ||
249 | + i++ | ||
250 | + } | ||
251 | + // If are at the end of the buffer there is a problem with the document | ||
252 | + if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString") | ||
253 | + // Return the C string | ||
254 | + var regExpOptions = buffer.toString('utf8', index, i); | ||
255 | + index = i + 1; | ||
256 | + | ||
257 | + // For each option add the corresponding one for javascript | ||
258 | + var optionsArray = new Array(regExpOptions.length); | ||
259 | + | ||
260 | + // Parse options | ||
261 | + for(var i = 0; i < regExpOptions.length; i++) { | ||
262 | + switch(regExpOptions[i]) { | ||
263 | + case 'm': | ||
264 | + optionsArray[i] = 'm'; | ||
265 | + break; | ||
266 | + case 's': | ||
267 | + optionsArray[i] = 'g'; | ||
268 | + break; | ||
269 | + case 'i': | ||
270 | + optionsArray[i] = 'i'; | ||
271 | + break; | ||
272 | + } | ||
273 | + } | ||
274 | + | ||
275 | + object[name] = new RegExp(source, optionsArray.join('')); | ||
276 | + } else if(elementType == BSON.BSON_DATA_REGEXP && bsonRegExp == true) { | ||
277 | + // Get the start search index | ||
278 | + var i = index; | ||
279 | + // Locate the end of the c string | ||
280 | + while(buffer[i] !== 0x00 && i < buffer.length) { | ||
281 | + i++ | ||
282 | + } | ||
283 | + // If are at the end of the buffer there is a problem with the document | ||
284 | + if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString") | ||
285 | + // Return the C string | ||
286 | + var source = buffer.toString('utf8', index, i); | ||
287 | + index = i + 1; | ||
288 | + | ||
289 | + // Get the start search index | ||
290 | + var i = index; | ||
291 | + // Locate the end of the c string | ||
292 | + while(buffer[i] !== 0x00 && i < buffer.length) { | ||
293 | + i++ | ||
294 | + } | ||
295 | + // If are at the end of the buffer there is a problem with the document | ||
296 | + if(i >= buffer.length) throw new Error("Bad BSON Document: illegal CString") | ||
297 | + // Return the C string | ||
298 | + var regExpOptions = buffer.toString('utf8', index, i); | ||
299 | + index = i + 1; | ||
300 | + | ||
301 | + // Set the object | ||
302 | + object[name] = new BSONRegExp(source, regExpOptions); | ||
303 | + } else if(elementType == BSON.BSON_DATA_SYMBOL) { | ||
304 | + var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
305 | + if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson"); | ||
306 | + object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); | ||
307 | + index = index + stringSize; | ||
308 | + } else if(elementType == BSON.BSON_DATA_TIMESTAMP) { | ||
309 | + var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
310 | + var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
311 | + object[name] = new Timestamp(lowBits, highBits); | ||
312 | + } else if(elementType == BSON.BSON_DATA_MIN_KEY) { | ||
313 | + object[name] = new MinKey(); | ||
314 | + } else if(elementType == BSON.BSON_DATA_MAX_KEY) { | ||
315 | + object[name] = new MaxKey(); | ||
316 | + } else if(elementType == BSON.BSON_DATA_CODE) { | ||
317 | + var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
318 | + if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson"); | ||
319 | + var functionString = buffer.toString('utf8', index, index + stringSize - 1); | ||
320 | + | ||
321 | + // If we are evaluating the functions | ||
322 | + if(evalFunctions) { | ||
323 | + var value = null; | ||
324 | + // If we have cache enabled let's look for the md5 of the function in the cache | ||
325 | + if(cacheFunctions) { | ||
326 | + var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; | ||
327 | + // Got to do this to avoid V8 deoptimizing the call due to finding eval | ||
328 | + object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); | ||
329 | + } else { | ||
330 | + object[name] = isolateEval(functionString); | ||
331 | + } | ||
332 | + } else { | ||
333 | + object[name] = new Code(functionString); | ||
334 | + } | ||
335 | + | ||
336 | + // Update parse index position | ||
337 | + index = index + stringSize; | ||
338 | + } else if(elementType == BSON.BSON_DATA_CODE_W_SCOPE) { | ||
339 | + var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
340 | + | ||
341 | + // Element cannot be shorter than totalSize + stringSize + documentSize + terminator | ||
342 | + if(totalSize < (4 + 4 + 4 + 1)) { | ||
343 | + throw new Error("code_w_scope total size shorter minimum expected length"); | ||
344 | + } | ||
345 | + | ||
346 | + // Get the code string size | ||
347 | + var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
348 | + // Check if we have a valid string | ||
349 | + if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson"); | ||
350 | + | ||
351 | + // Javascript function | ||
352 | + var functionString = buffer.toString('utf8', index, index + stringSize - 1); | ||
353 | + // Update parse index position | ||
354 | + index = index + stringSize; | ||
355 | + // Parse the element | ||
356 | + var _index = index; | ||
357 | + // Decode the size of the object document | ||
358 | + var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; | ||
359 | + // Decode the scope object | ||
360 | + var scopeObject = deserializeObject(buffer, _index, options, false); | ||
361 | + // Adjust the index | ||
362 | + index = index + objectSize; | ||
363 | + | ||
364 | + // Check if field length is to short | ||
365 | + if(totalSize < (4 + 4 + objectSize + stringSize)) { | ||
366 | + throw new Error('code_w_scope total size is to short, truncating scope'); | ||
367 | + } | ||
368 | + | ||
369 | + // Check if totalSize field is to long | ||
370 | + if(totalSize > (4 + 4 + objectSize + stringSize)) { | ||
371 | + throw new Error('code_w_scope total size is to long, clips outer document'); | ||
372 | + } | ||
373 | + | ||
374 | + // If we are evaluating the functions | ||
375 | + if(evalFunctions) { | ||
376 | + // Contains the value we are going to set | ||
377 | + var value = null; | ||
378 | + // If we have cache enabled let's look for the md5 of the function in the cache | ||
379 | + if(cacheFunctions) { | ||
380 | + var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; | ||
381 | + // Got to do this to avoid V8 deoptimizing the call due to finding eval | ||
382 | + object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); | ||
383 | + } else { | ||
384 | + object[name] = isolateEval(functionString); | ||
385 | + } | ||
386 | + | ||
387 | + object[name].scope = scopeObject; | ||
388 | + } else { | ||
389 | + object[name] = new Code(functionString, scopeObject); | ||
390 | + } | ||
391 | + } else if(elementType == BSON.BSON_DATA_DBPOINTER) { | ||
392 | + // Get the code string size | ||
393 | + var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; | ||
394 | + // Check if we have a valid string | ||
395 | + if(stringSize <= 0 || stringSize > (buffer.length - index) || buffer[index + stringSize - 1] != 0) throw new Error("bad string length in bson"); | ||
396 | + // Namespace | ||
397 | + var namespace = buffer.toString('utf8', index, index + stringSize - 1); | ||
398 | + // Update parse index position | ||
399 | + index = index + stringSize; | ||
400 | + | ||
401 | + // Read the oid | ||
402 | + var oidBuffer = new Buffer(12); | ||
403 | + buffer.copy(oidBuffer, 0, index, index + 12); | ||
404 | + var oid = new ObjectID(oidBuffer); | ||
405 | + | ||
406 | + // Update the index | ||
407 | + index = index + 12; | ||
408 | + | ||
409 | + // Split the namespace | ||
410 | + var parts = namespace.split('.'); | ||
411 | + var db = parts.shift(); | ||
412 | + var collection = parts.join('.'); | ||
413 | + // Upgrade to DBRef type | ||
414 | + object[name] = new DBRef(collection, oid, db); | ||
415 | + } else { | ||
416 | + throw new Error("Detected unknown BSON type " + elementType.toString(16) + " for fieldname \"" + name + "\", are you using the latest BSON parser"); | ||
417 | + } | ||
418 | + } | ||
419 | + | ||
420 | + // Check if the deserialization was against a valid array/object | ||
421 | + if(size != (index - startIndex)) { | ||
422 | + if(isArray) throw new Error('corrupt array bson'); | ||
423 | + throw new Error('corrupt object bson'); | ||
424 | + } | ||
425 | + | ||
426 | + // Check if we have a db ref object | ||
427 | + if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); | ||
428 | + return object; | ||
429 | +} | ||
430 | + | ||
431 | +/** | ||
432 | + * Ensure eval is isolated. | ||
433 | + * | ||
434 | + * @ignore | ||
435 | + * @api private | ||
436 | + */ | ||
437 | +var isolateEvalWithHash = function(functionCache, hash, functionString, object) { | ||
438 | + // Contains the value we are going to set | ||
439 | + var value = null; | ||
440 | + | ||
441 | + // Check for cache hit, eval if missing and return cached function | ||
442 | + if(functionCache[hash] == null) { | ||
443 | + eval("value = " + functionString); | ||
444 | + functionCache[hash] = value; | ||
445 | + } | ||
446 | + // Set the object | ||
447 | + return functionCache[hash].bind(object); | ||
448 | +} | ||
449 | + | ||
450 | +/** | ||
451 | + * Ensure eval is isolated. | ||
452 | + * | ||
453 | + * @ignore | ||
454 | + * @api private | ||
455 | + */ | ||
456 | +var isolateEval = function(functionString) { | ||
457 | + // Contains the value we are going to set | ||
458 | + var value = null; | ||
459 | + // Eval the function | ||
460 | + eval("value = " + functionString); | ||
461 | + return value; | ||
462 | +} | ||
463 | + | ||
464 | +var BSON = {}; | ||
465 | + | ||
466 | +/** | ||
467 | + * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 | ||
468 | + * | ||
469 | + * @ignore | ||
470 | + * @api private | ||
471 | + */ | ||
472 | +var functionCache = BSON.functionCache = {}; | ||
473 | + | ||
474 | +/** | ||
475 | + * Number BSON Type | ||
476 | + * | ||
477 | + * @classconstant BSON_DATA_NUMBER | ||
478 | + **/ | ||
479 | +BSON.BSON_DATA_NUMBER = 1; | ||
480 | +/** | ||
481 | + * String BSON Type | ||
482 | + * | ||
483 | + * @classconstant BSON_DATA_STRING | ||
484 | + **/ | ||
485 | +BSON.BSON_DATA_STRING = 2; | ||
486 | +/** | ||
487 | + * Object BSON Type | ||
488 | + * | ||
489 | + * @classconstant BSON_DATA_OBJECT | ||
490 | + **/ | ||
491 | +BSON.BSON_DATA_OBJECT = 3; | ||
492 | +/** | ||
493 | + * Array BSON Type | ||
494 | + * | ||
495 | + * @classconstant BSON_DATA_ARRAY | ||
496 | + **/ | ||
497 | +BSON.BSON_DATA_ARRAY = 4; | ||
498 | +/** | ||
499 | + * Binary BSON Type | ||
500 | + * | ||
501 | + * @classconstant BSON_DATA_BINARY | ||
502 | + **/ | ||
503 | +BSON.BSON_DATA_BINARY = 5; | ||
504 | +/** | ||
505 | + * Binary BSON Type | ||
506 | + * | ||
507 | + * @classconstant BSON_DATA_UNDEFINED | ||
508 | + **/ | ||
509 | +BSON.BSON_DATA_UNDEFINED = 6; | ||
510 | +/** | ||
511 | + * ObjectID BSON Type | ||
512 | + * | ||
513 | + * @classconstant BSON_DATA_OID | ||
514 | + **/ | ||
515 | +BSON.BSON_DATA_OID = 7; | ||
516 | +/** | ||
517 | + * Boolean BSON Type | ||
518 | + * | ||
519 | + * @classconstant BSON_DATA_BOOLEAN | ||
520 | + **/ | ||
521 | +BSON.BSON_DATA_BOOLEAN = 8; | ||
522 | +/** | ||
523 | + * Date BSON Type | ||
524 | + * | ||
525 | + * @classconstant BSON_DATA_DATE | ||
526 | + **/ | ||
527 | +BSON.BSON_DATA_DATE = 9; | ||
528 | +/** | ||
529 | + * null BSON Type | ||
530 | + * | ||
531 | + * @classconstant BSON_DATA_NULL | ||
532 | + **/ | ||
533 | +BSON.BSON_DATA_NULL = 10; | ||
534 | +/** | ||
535 | + * RegExp BSON Type | ||
536 | + * | ||
537 | + * @classconstant BSON_DATA_REGEXP | ||
538 | + **/ | ||
539 | +BSON.BSON_DATA_REGEXP = 11; | ||
540 | +/** | ||
541 | + * Code BSON Type | ||
542 | + * | ||
543 | + * @classconstant BSON_DATA_DBPOINTER | ||
544 | + **/ | ||
545 | +BSON.BSON_DATA_DBPOINTER = 12; | ||
546 | +/** | ||
547 | + * Code BSON Type | ||
548 | + * | ||
549 | + * @classconstant BSON_DATA_CODE | ||
550 | + **/ | ||
551 | +BSON.BSON_DATA_CODE = 13; | ||
552 | +/** | ||
553 | + * Symbol BSON Type | ||
554 | + * | ||
555 | + * @classconstant BSON_DATA_SYMBOL | ||
556 | + **/ | ||
557 | +BSON.BSON_DATA_SYMBOL = 14; | ||
558 | +/** | ||
559 | + * Code with Scope BSON Type | ||
560 | + * | ||
561 | + * @classconstant BSON_DATA_CODE_W_SCOPE | ||
562 | + **/ | ||
563 | +BSON.BSON_DATA_CODE_W_SCOPE = 15; | ||
564 | +/** | ||
565 | + * 32 bit Integer BSON Type | ||
566 | + * | ||
567 | + * @classconstant BSON_DATA_INT | ||
568 | + **/ | ||
569 | +BSON.BSON_DATA_INT = 16; | ||
570 | +/** | ||
571 | + * Timestamp BSON Type | ||
572 | + * | ||
573 | + * @classconstant BSON_DATA_TIMESTAMP | ||
574 | + **/ | ||
575 | +BSON.BSON_DATA_TIMESTAMP = 17; | ||
576 | +/** | ||
577 | + * Long BSON Type | ||
578 | + * | ||
579 | + * @classconstant BSON_DATA_LONG | ||
580 | + **/ | ||
581 | +BSON.BSON_DATA_LONG = 18; | ||
582 | +/** | ||
583 | + * Long BSON Type | ||
584 | + * | ||
585 | + * @classconstant BSON_DATA_DECIMAL128 | ||
586 | + **/ | ||
587 | +BSON.BSON_DATA_DECIMAL128 = 19; | ||
588 | +/** | ||
589 | + * MinKey BSON Type | ||
590 | + * | ||
591 | + * @classconstant BSON_DATA_MIN_KEY | ||
592 | + **/ | ||
593 | +BSON.BSON_DATA_MIN_KEY = 0xff; | ||
594 | +/** | ||
595 | + * MaxKey BSON Type | ||
596 | + * | ||
597 | + * @classconstant BSON_DATA_MAX_KEY | ||
598 | + **/ | ||
599 | +BSON.BSON_DATA_MAX_KEY = 0x7f; | ||
600 | + | ||
601 | +/** | ||
602 | + * Binary Default Type | ||
603 | + * | ||
604 | + * @classconstant BSON_BINARY_SUBTYPE_DEFAULT | ||
605 | + **/ | ||
606 | +BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; | ||
607 | +/** | ||
608 | + * Binary Function Type | ||
609 | + * | ||
610 | + * @classconstant BSON_BINARY_SUBTYPE_FUNCTION | ||
611 | + **/ | ||
612 | +BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; | ||
613 | +/** | ||
614 | + * Binary Byte Array Type | ||
615 | + * | ||
616 | + * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY | ||
617 | + **/ | ||
618 | +BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; | ||
619 | +/** | ||
620 | + * Binary UUID Type | ||
621 | + * | ||
622 | + * @classconstant BSON_BINARY_SUBTYPE_UUID | ||
623 | + **/ | ||
624 | +BSON.BSON_BINARY_SUBTYPE_UUID = 3; | ||
625 | +/** | ||
626 | + * Binary MD5 Type | ||
627 | + * | ||
628 | + * @classconstant BSON_BINARY_SUBTYPE_MD5 | ||
629 | + **/ | ||
630 | +BSON.BSON_BINARY_SUBTYPE_MD5 = 4; | ||
631 | +/** | ||
632 | + * Binary User Defined Type | ||
633 | + * | ||
634 | + * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED | ||
635 | + **/ | ||
636 | +BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; | ||
637 | + | ||
638 | +// BSON MAX VALUES | ||
639 | +BSON.BSON_INT32_MAX = 0x7FFFFFFF; | ||
640 | +BSON.BSON_INT32_MIN = -0x80000000; | ||
641 | + | ||
642 | +BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; | ||
643 | +BSON.BSON_INT64_MIN = -Math.pow(2, 63); | ||
644 | + | ||
645 | +// JS MAX PRECISE VALUES | ||
646 | +BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. | ||
647 | +BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. | ||
648 | + | ||
649 | +// Internal long versions | ||
650 | +var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. | ||
651 | +var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. | ||
652 | + | ||
653 | +module.exports = deserialize |
-
请 注册 或 登录 后发表评论