Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

buffer.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*!
  2. * Module dependencies.
  3. */
  4. 'use strict';
  5. const Binary = require('../driver').get().Binary;
  6. const utils = require('../utils');
  7. const Buffer = require('safe-buffer').Buffer;
  8. // Yes this is weird. See https://github.com/feross/safe-buffer/pull/23
  9. const proto = Buffer.from('').constructor.prototype;
  10. /**
  11. * Mongoose Buffer constructor.
  12. *
  13. * Values always have to be passed to the constructor to initialize.
  14. *
  15. * @param {Buffer} value
  16. * @param {String} encode
  17. * @param {Number} offset
  18. * @api private
  19. * @inherits Buffer
  20. * @see http://bit.ly/f6CnZU
  21. */
  22. function MongooseBuffer(value, encode, offset) {
  23. const length = arguments.length;
  24. let val;
  25. if (length === 0 || arguments[0] === null || arguments[0] === undefined) {
  26. val = 0;
  27. } else {
  28. val = value;
  29. }
  30. let encoding;
  31. let path;
  32. let doc;
  33. if (Array.isArray(encode)) {
  34. // internal casting
  35. path = encode[0];
  36. doc = encode[1];
  37. } else {
  38. encoding = encode;
  39. }
  40. let buf;
  41. if (typeof val === 'number' || val instanceof Number) {
  42. buf = Buffer.alloc(val);
  43. } else { // string, array or object { type: 'Buffer', data: [...] }
  44. buf = Buffer.from(val, encoding, offset);
  45. }
  46. utils.decorate(buf, MongooseBuffer.mixin);
  47. buf.isMongooseBuffer = true;
  48. // make sure these internal props don't show up in Object.keys()
  49. buf[MongooseBuffer.pathSymbol] = path;
  50. buf[parentSymbol] = doc;
  51. buf._subtype = 0;
  52. return buf;
  53. }
  54. const pathSymbol = Symbol.for('mongoose#Buffer#_path');
  55. const parentSymbol = Symbol.for('mongoose#Buffer#_parent');
  56. MongooseBuffer.pathSymbol = pathSymbol;
  57. /*!
  58. * Inherit from Buffer.
  59. */
  60. MongooseBuffer.mixin = {
  61. /**
  62. * Default subtype for the Binary representing this Buffer
  63. *
  64. * @api private
  65. * @property _subtype
  66. * @receiver MongooseBuffer
  67. */
  68. _subtype: undefined,
  69. /**
  70. * Marks this buffer as modified.
  71. *
  72. * @api private
  73. * @method _markModified
  74. * @receiver MongooseBuffer
  75. */
  76. _markModified: function() {
  77. const parent = this[parentSymbol];
  78. if (parent) {
  79. parent.markModified(this[MongooseBuffer.pathSymbol]);
  80. }
  81. return this;
  82. },
  83. /**
  84. * Writes the buffer.
  85. *
  86. * @api public
  87. * @method write
  88. * @receiver MongooseBuffer
  89. */
  90. write: function() {
  91. const written = proto.write.apply(this, arguments);
  92. if (written > 0) {
  93. this._markModified();
  94. }
  95. return written;
  96. },
  97. /**
  98. * Copies the buffer.
  99. *
  100. * ####Note:
  101. *
  102. * `Buffer#copy` does not mark `target` as modified so you must copy from a `MongooseBuffer` for it to work as expected. This is a work around since `copy` modifies the target, not this.
  103. *
  104. * @return {Number} The number of bytes copied.
  105. * @param {Buffer} target
  106. * @method copy
  107. * @receiver MongooseBuffer
  108. */
  109. copy: function(target) {
  110. const ret = proto.copy.apply(this, arguments);
  111. if (target && target.isMongooseBuffer) {
  112. target._markModified();
  113. }
  114. return ret;
  115. }
  116. };
  117. /*!
  118. * Compile other Buffer methods marking this buffer as modified.
  119. */
  120. (
  121. // node < 0.5
  122. ('writeUInt8 writeUInt16 writeUInt32 writeInt8 writeInt16 writeInt32 ' +
  123. 'writeFloat writeDouble fill ' +
  124. 'utf8Write binaryWrite asciiWrite set ' +
  125. // node >= 0.5
  126. 'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
  127. 'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' + 'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE')
  128. ).split(' ').forEach(function(method) {
  129. if (!proto[method]) {
  130. return;
  131. }
  132. MongooseBuffer.mixin[method] = function() {
  133. const ret = proto[method].apply(this, arguments);
  134. this._markModified();
  135. return ret;
  136. };
  137. });
  138. /**
  139. * Converts this buffer to its Binary type representation.
  140. *
  141. * ####SubTypes:
  142. *
  143. * var bson = require('bson')
  144. * bson.BSON_BINARY_SUBTYPE_DEFAULT
  145. * bson.BSON_BINARY_SUBTYPE_FUNCTION
  146. * bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
  147. * bson.BSON_BINARY_SUBTYPE_UUID
  148. * bson.BSON_BINARY_SUBTYPE_MD5
  149. * bson.BSON_BINARY_SUBTYPE_USER_DEFINED
  150. *
  151. * doc.buffer.toObject(bson.BSON_BINARY_SUBTYPE_USER_DEFINED);
  152. *
  153. * @see http://bsonspec.org/#/specification
  154. * @param {Hex} [subtype]
  155. * @return {Binary}
  156. * @api public
  157. * @method toObject
  158. * @receiver MongooseBuffer
  159. */
  160. MongooseBuffer.mixin.toObject = function(options) {
  161. const subtype = typeof options === 'number'
  162. ? options
  163. : (this._subtype || 0);
  164. return new Binary(Buffer.from(this), subtype);
  165. };
  166. /**
  167. * Converts this buffer for storage in MongoDB, including subtype
  168. *
  169. * @return {Binary}
  170. * @api public
  171. * @method toBSON
  172. * @receiver MongooseBuffer
  173. */
  174. MongooseBuffer.mixin.toBSON = function() {
  175. return new Binary(this, this._subtype || 0);
  176. };
  177. /**
  178. * Determines if this buffer is equals to `other` buffer
  179. *
  180. * @param {Buffer} other
  181. * @return {Boolean}
  182. * @method equals
  183. * @receiver MongooseBuffer
  184. */
  185. MongooseBuffer.mixin.equals = function(other) {
  186. if (!Buffer.isBuffer(other)) {
  187. return false;
  188. }
  189. if (this.length !== other.length) {
  190. return false;
  191. }
  192. for (let i = 0; i < this.length; ++i) {
  193. if (this[i] !== other[i]) {
  194. return false;
  195. }
  196. }
  197. return true;
  198. };
  199. /**
  200. * Sets the subtype option and marks the buffer modified.
  201. *
  202. * ####SubTypes:
  203. *
  204. * var bson = require('bson')
  205. * bson.BSON_BINARY_SUBTYPE_DEFAULT
  206. * bson.BSON_BINARY_SUBTYPE_FUNCTION
  207. * bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
  208. * bson.BSON_BINARY_SUBTYPE_UUID
  209. * bson.BSON_BINARY_SUBTYPE_MD5
  210. * bson.BSON_BINARY_SUBTYPE_USER_DEFINED
  211. *
  212. * doc.buffer.subtype(bson.BSON_BINARY_SUBTYPE_UUID);
  213. *
  214. * @see http://bsonspec.org/#/specification
  215. * @param {Hex} subtype
  216. * @api public
  217. * @method subtype
  218. * @receiver MongooseBuffer
  219. */
  220. MongooseBuffer.mixin.subtype = function(subtype) {
  221. if (typeof subtype !== 'number') {
  222. throw new TypeError('Invalid subtype. Expected a number');
  223. }
  224. if (this._subtype !== subtype) {
  225. this._markModified();
  226. }
  227. this._subtype = subtype;
  228. };
  229. /*!
  230. * Module exports.
  231. */
  232. MongooseBuffer.Binary = Binary;
  233. module.exports = MongooseBuffer;