Skip to content
This repository
Browse code

Add reading/writing of C integers to buffers

  • Loading branch information...
commit 9812e31e8ba43be9c50d07f83cbf459427a5d877 1 parent 8a03cf7
Robert Mustacchi rmustacc authored ry committed
195 doc/api/buffers.markdown
Source Rendered
@@ -168,3 +168,198 @@ from the original Buffer.
168 168
169 169 // abc
170 170 // !bc
  171 +
  172 +### buffer.readUInt8(offset, endian)
  173 +
  174 +Reads an unsigned 8 bit integer from the buffer at the specified offset. Endian
  175 +must be either 'big' or 'little' and specifies what endian ordering to read the
  176 +bytes from the buffer in.
  177 +
  178 +Example:
  179 +
  180 + var buf = new Buffer(4);
  181 +
  182 + buf[0] = 0x3;
  183 + buf[1] = 0x4;
  184 + buf[2] = 0x23;
  185 + buf[3] = 0x42;
  186 +
  187 + for (ii = 0; ii < buf.length; ii++) {
  188 + console.log(buf.readUInt8(ii, 'big');
  189 + console.log(buf.readUInt8(ii, 'little');
  190 + }
  191 +
  192 + // 0x3
  193 + // 0x3
  194 + // 0x4
  195 + // 0x4
  196 + // 0x23
  197 + // 0x23
  198 + // 0x42
  199 + // 0x42
  200 +
  201 +### buffer.readUInt16(offset, endian)
  202 +
  203 +Reads an unsigned 16 bit integer from the buffer at the specified offset. Endian
  204 +must be either 'big' or 'little' and specifies what endian ordering to read the
  205 +bytes from the buffer in.
  206 +
  207 +Example:
  208 +
  209 + var buf = new Buffer(4);
  210 +
  211 + buf[0] = 0x3;
  212 + buf[1] = 0x4;
  213 + buf[2] = 0x23;
  214 + buf[3] = 0x42;
  215 +
  216 + console.log(buf.readUInt16(0, 'big');
  217 + console.log(buf.readUInt16(0, 'little');
  218 + console.log(buf.readUInt16(1, 'big');
  219 + console.log(buf.readUInt16(1, 'little');
  220 + console.log(buf.readUInt16(2, 'big');
  221 + console.log(buf.readUInt16(2, 'little');
  222 +
  223 + // 0x0304
  224 + // 0x0403
  225 + // 0x0423
  226 + // 0x2304
  227 + // 0x2342
  228 + // 0x4223
  229 +
  230 +### buffer.readUInt32(offset, endian)
  231 +
  232 +Reads an unsigned 32 bit integer from the buffer at the specified offset. Endian
  233 +must be either 'big' or 'little' and specifies what endian ordering to read the
  234 +bytes from the buffer in.
  235 +
  236 +Example:
  237 +
  238 + var buf = new Buffer(4);
  239 +
  240 + buf[0] = 0x3;
  241 + buf[1] = 0x4;
  242 + buf[2] = 0x23;
  243 + buf[3] = 0x42;
  244 +
  245 + console.log(buf.readUInt32(0, 'big');
  246 + console.log(buf.readUInt32(0, 'little');
  247 +
  248 + // 0x03042342
  249 + // 0x42230403
  250 +
  251 +### buffer.readInt8(offset, endian)
  252 +
  253 +Reads a signed 8 bit integer from the buffer at the specified offset. Endian
  254 +must be either 'big' or 'little' and specifies what endian ordering to read the
  255 +bytes from the buffer in.
  256 +
  257 +Works as `buffer.readUInt8`, except buffer contents are treated as twos
  258 +complement signed values.
  259 +
  260 +### buffer.readInt16(offset, endian)
  261 +
  262 +Reads a signed 16 bit integer from the buffer at the specified offset. Endian
  263 +must be either 'big' or 'little' and specifies what endian ordering to read the
  264 +bytes from the buffer in.
  265 +
  266 +Works as `buffer.readUInt16`, except buffer contents are treated as twos
  267 +complement signed values.
  268 +
  269 +### buffer.readInt32(offset, endian)
  270 +
  271 +Reads a signed 32 bit integer from the buffer at the specified offset. Endian
  272 +must be either 'big' or 'little' and specifies what endian ordering to read the
  273 +bytes from the buffer in.
  274 +
  275 +Works as `buffer.readUInt32`, except buffer contents are treated as twos
  276 +complement signed values.
  277 +
  278 +### buffer.writeUInt8(value, offset, endian)
  279 +
  280 +Writes `value` to the buffer at the specified offset with specified endian
  281 +format. Note, `value` must be a valid 8 bit unsigned integer.
  282 +
  283 +Example:
  284 +
  285 + var buf = new Buffer(4);
  286 + buf.writeUInt8(0x3, 0, 'big');
  287 + buf.writeUInt8(0x4, 1, 'big');
  288 + buf.writeUInt8(0x23, 2, 'big');
  289 + buf.writeUInt8(0x42, 3, 'big');
  290 +
  291 + console.log(buf);
  292 +
  293 + buf.writeUInt8(0x3, 0, 'little');
  294 + buf.writeUInt8(0x4, 1, 'little');
  295 + buf.writeUInt8(0x23, 2, 'little');
  296 + buf.writeUInt8(0x42, 3, 'little');
  297 +
  298 + console.log(buf);
  299 +
  300 + // <Buffer 03 04 23 42>
  301 + // <Buffer 03 04 23 42>
  302 +
  303 +### buffer.writeUInt16(value, offset, endian)
  304 +
  305 +Writes `value` to the buffer at the specified offset with specified endian
  306 +format. Note, `value` must be a valid 16 bit unsigned integer.
  307 +
  308 +Example:
  309 +
  310 + var buf = new Buffer(4);
  311 + buf.writeUInt16(0xdead, 0, 'big');
  312 + buf.writeUInt16(0xbeef, 2, 'big');
  313 +
  314 + console.log(buf);
  315 +
  316 + buf.writeUInt16(0xdead, 0, 'little');
  317 + buf.writeUInt16(0xbeef, 2, 'little');
  318 +
  319 + console.log(buf);
  320 +
  321 + // <Buffer de ad be ef>
  322 + // <Buffer ad de ef be>
  323 +
  324 +### buffer.writeUInt32(value, offset, endian)
  325 +
  326 +Writes `value` to the buffer at the specified offset with specified endian
  327 +format. Note, `value` must be a valid 32 bit unsigned integer.
  328 +
  329 +Example:
  330 +
  331 + var buf = new Buffer(4);
  332 + buf.writeUInt32(0xfeedface, 0, 'big');
  333 +
  334 + console.log(buf);
  335 +
  336 + buf.writeUInt32(0xfeedface, 0, 'little');
  337 +
  338 + console.log(buf);
  339 +
  340 + // <Buffer fe ed fa ce>
  341 + // <Buffer ce fa ed fe>
  342 +
  343 +### buffer.writeInt8(value, offset, endian)
  344 +
  345 +Writes `value` to the buffer at the specified offset with specified endian
  346 +format. Note, `value` must be a valid 16 bit signed integer.
  347 +
  348 +Works as `buffer.writeUInt8`, except value is written out as a two's complement
  349 +signed integer into `buffer`.
  350 +
  351 +### buffer.writeInt16(value, offset, endian)
  352 +
  353 +Writes `value` to the buffer at the specified offset with specified endian
  354 +format. Note, `value` must be a valid 16 bit unsigned integer.
  355 +
  356 +Works as `buffer.writeUInt16`, except value is written out as a two's complement
  357 +signed integer into `buffer`.
  358 +
  359 +### buffer.writeInt32(value, offset, endian)
  360 +
  361 +Writes `value` to the buffer at the specified offset with specified endian
  362 +format. Note, `value` must be a valid 16 bit signed integer.
  363 +
  364 +Works as `buffer.writeUInt832, except value is written out as a two's complement
  365 +signed integer into `buffer`.
448 lib/buffer.js
@@ -20,6 +20,7 @@
20 20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 21
22 22 var SlowBuffer = process.binding('buffer').SlowBuffer;
  23 +var assert = require('assert');
23 24
24 25
25 26 function toHex(n) {
@@ -45,7 +46,7 @@ SlowBuffer.prototype.hexSlice = function(start, end) {
45 46 if (!end || end < 0 || end > len) end = len;
46 47
47 48 var out = '';
48   - for (var i = start; i < end; i ++) {
  49 + for (var i = start; i < end; i++) {
49 50 out += toHex(this[i]);
50 51 }
51 52 return out;
@@ -98,13 +99,13 @@ SlowBuffer.prototype.hexWrite = function(string, offset) {
98 99 if (len % 2) {
99 100 throw new Error('Invalid hex string');
100 101 }
101   - for (var i = 0; i < len / 2; i ++) {
  102 + for (var i = 0; i < len / 2; i++) {
102 103 var byte = parseInt(string.substr(i * 2, 2), 16);
103 104 if (isNaN(byte)) throw new Error('Invalid hex string');
104 105 this[offset + i] = byte;
105 106 }
106 107 return i;
107   -}
  108 +};
108 109
109 110
110 111 SlowBuffer.prototype.write = function(string, offset, encoding) {
@@ -449,3 +450,444 @@ Buffer.prototype.asciiWrite = function(string, offset) {
449 450 return this.write(string, offset, 'ascii');
450 451 };
451 452
  453 +Buffer.prototype.readUInt8 = function(offset, endian) {
  454 + var buffer = this;
  455 +
  456 + assert.ok(endian !== undefined && endian !== null,
  457 + 'missing endian');
  458 +
  459 + assert.ok(endian == 'big' || endian == 'little',
  460 + 'bad endian value');
  461 +
  462 + assert.ok(offset !== undefined && offset !== null,
  463 + 'missing offset');
  464 +
  465 + assert.ok(offset < buffer.length,
  466 + 'Trying to read beyond buffer length');
  467 +
  468 + return buffer[offset];
  469 +};
  470 +
  471 +
  472 +Buffer.prototype.readUInt16 = function(offset, endian) {
  473 + var val = 0;
  474 + var buffer = this;
  475 +
  476 + assert.ok(endian !== undefined && endian !== null,
  477 + 'missing endian');
  478 +
  479 + assert.ok(endian == 'big' || endian == 'little',
  480 + 'bad endian value');
  481 +
  482 + assert.ok(offset !== undefined && offset !== null,
  483 + 'missing offset');
  484 +
  485 + assert.ok(offset + 1 < buffer.length,
  486 + 'Trying to read beyond buffer length');
  487 +
  488 + if (endian == 'big') {
  489 + val = buffer[offset] << 8;
  490 + val |= buffer[offset + 1];
  491 + } else {
  492 + val = buffer[offset];
  493 + val |= buffer[offset + 1] << 8;
  494 + }
  495 +
  496 + return val;
  497 +};
  498 +
  499 +
  500 +Buffer.prototype.readUInt32 = function(offset, endian) {
  501 + var val = 0;
  502 + var buffer = this;
  503 +
  504 + assert.ok(endian !== undefined && endian !== null,
  505 + 'missing endian');
  506 +
  507 + assert.ok(endian == 'big' || endian == 'little',
  508 + 'bad endian value');
  509 +
  510 + assert.ok(offset !== undefined && offset !== null,
  511 + 'missing offset');
  512 +
  513 + assert.ok(offset + 3 < buffer.length,
  514 + 'Trying to read beyond buffer length');
  515 +
  516 + if (endian == 'big') {
  517 + val = buffer[offset + 1] << 16;
  518 + val |= buffer[offset + 2] << 8;
  519 + val |= buffer[offset + 3];
  520 + val = val + (buffer[offset] << 24 >>> 0);
  521 + } else {
  522 + val = buffer[offset + 2] << 16;
  523 + val |= buffer[offset + 1] << 8;
  524 + val |= buffer[offset];
  525 + val = val + (buffer[offset + 3] << 24 >>> 0);
  526 + }
  527 +
  528 + return val;
  529 +};
  530 +
  531 +
  532 +/*
  533 + * Signed integer types, yay team! A reminder on how two's complement actually
  534 + * works. The first bit is the signed bit, i.e. tells us whether or not the
  535 + * number should be positive or negative. If the two's complement value is
  536 + * positive, then we're done, as it's equivalent to the unsigned representation.
  537 + *
  538 + * Now if the number is positive, you're pretty much done, you can just leverage
  539 + * the unsigned translations and return those. Unfortunately, negative numbers
  540 + * aren't quite that straightforward.
  541 + *
  542 + * At first glance, one might be inclined to use the traditional formula to
  543 + * translate binary numbers between the positive and negative values in two's
  544 + * complement. (Though it doesn't quite work for the most negative value)
  545 + * Mainly:
  546 + * - invert all the bits
  547 + * - add one to the result
  548 + *
  549 + * Of course, this doesn't quite work in Javascript. Take for example the value
  550 + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
  551 + * course, Javascript will do the following:
  552 + *
  553 + * > ~0xff80
  554 + * -65409
  555 + *
  556 + * Whoh there, Javascript, that's not quite right. But wait, according to
  557 + * Javascript that's perfectly correct. When Javascript ends up seeing the
  558 + * constant 0xff80, it has no notion that it is actually a signed number. It
  559 + * assumes that we've input the unsigned value 0xff80. Thus, when it does the
  560 + * binary negation, it casts it into a signed value, (positive 0xff80). Then
  561 + * when you perform binary negation on that, it turns it into a negative number.
  562 + *
  563 + * Instead, we're going to have to use the following general formula, that works
  564 + * in a rather Javascript friendly way. I'm glad we don't support this kind of
  565 + * weird numbering scheme in the kernel.
  566 + *
  567 + * (BIT-MAX - (unsigned)val + 1) * -1
  568 + *
  569 + * The astute observer, may think that this doesn't make sense for 8-bit numbers
  570 + * (really it isn't necessary for them). However, when you get 16-bit numbers,
  571 + * you do. Let's go back to our prior example and see how this will look:
  572 + *
  573 + * (0xffff - 0xff80 + 1) * -1
  574 + * (0x007f + 1) * -1
  575 + * (0x0080) * -1
  576 + */
  577 +Buffer.prototype.readInt8 = function(offset, endian) {
  578 + var buffer = this;
  579 + var neg;
  580 +
  581 + assert.ok(endian !== undefined && endian !== null,
  582 + 'missing endian');
  583 +
  584 + assert.ok(endian == 'big' || endian == 'little',
  585 + 'bad endian value');
  586 +
  587 + assert.ok(offset !== undefined && offset !== null,
  588 + 'missing offset');
  589 +
  590 + assert.ok(offset < buffer.length,
  591 + 'Trying to read beyond buffer length');
  592 +
  593 + neg = buffer[offset] & 0x80;
  594 + if (!neg) {
  595 + return (buffer[offset]);
  596 + }
  597 +
  598 + return ((0xff - buffer[offset] + 1) * -1);
  599 +};
  600 +
  601 +
  602 +Buffer.prototype.readInt16 = function(offset, endian) {
  603 + var buffer = this;
  604 + var neg;
  605 +
  606 + assert.ok(endian !== undefined && endian !== null,
  607 + 'missing endian');
  608 +
  609 + assert.ok(endian == 'big' || endian == 'little',
  610 + 'bad endian value');
  611 +
  612 + assert.ok(offset !== undefined && offset !== null,
  613 + 'missing offset');
  614 +
  615 + assert.ok(offset + 1 < buffer.length,
  616 + 'Trying to read beyond buffer length');
  617 +
  618 + val = buffer.readUInt16(offset, endian);
  619 + neg = val & 0x8000;
  620 + if (!neg) {
  621 + return val;
  622 + }
  623 +
  624 + return (0xffff - val + 1) * -1;
  625 +};
  626 +
  627 +
  628 +Buffer.prototype.readInt32 = function(offset, endian) {
  629 + var buffer = this;
  630 + var neg;
  631 +
  632 + assert.ok(endian !== undefined && endian !== null,
  633 + 'missing endian');
  634 +
  635 + assert.ok(endian == 'big' || endian == 'little',
  636 + 'bad endian value');
  637 +
  638 + assert.ok(offset !== undefined && offset !== null,
  639 + 'missing offset');
  640 +
  641 + assert.ok(offset + 3 < buffer.length,
  642 + 'Trying to read beyond buffer length');
  643 +
  644 + val = buffer.readUInt32(offset, endian);
  645 + neg = val & 0x80000000;
  646 + if (!neg) {
  647 + return (val);
  648 + }
  649 +
  650 + return (0xffffffff - val + 1) * -1;
  651 +};
  652 +
  653 +
  654 +/*
  655 + * We have to make sure that the value is a valid integer. This means that it is
  656 + * non-negative. It has no fractional component and that it does not exceed the
  657 + * maximum allowed value.
  658 + *
  659 + * value The number to check for validity
  660 + *
  661 + * max The maximum value
  662 + */
  663 +function verifuint(value, max) {
  664 + assert.ok(typeof (value) == 'number',
  665 + 'cannot write a non-number as a number');
  666 +
  667 + assert.ok(value >= 0,
  668 + 'specified a negative value for writing an unsigned value');
  669 +
  670 + assert.ok(value <= max, 'value is larger than maximum value for type');
  671 +
  672 + assert.ok(Math.floor(value) === value, 'value has a fractional component');
  673 +}
  674 +
  675 +
  676 +Buffer.prototype.writeUInt8 = function(value, offset, endian) {
  677 + var buffer = this;
  678 +
  679 + assert.ok(value !== undefined && value !== null,
  680 + 'missing value');
  681 +
  682 + assert.ok(endian !== undefined && endian !== null,
  683 + 'missing endian');
  684 +
  685 + assert.ok(endian == 'big' || endian == 'little',
  686 + 'bad endian value');
  687 +
  688 + assert.ok(offset !== undefined && offset !== null,
  689 + 'missing offset');
  690 +
  691 + assert.ok(offset < buffer.length,
  692 + 'trying to read beyond buffer length');
  693 +
  694 + verifuint(value, 0xff);
  695 + buffer[offset] = value;
  696 +};
  697 +
  698 +
  699 +Buffer.prototype.writeUInt16 = function(value, offset, endian) {
  700 + var buffer = this;
  701 +
  702 + assert.ok(value !== undefined && value !== null,
  703 + 'missing value');
  704 +
  705 + assert.ok(endian !== undefined && endian !== null,
  706 + 'missing endian');
  707 +
  708 + assert.ok(endian == 'big' || endian == 'little',
  709 + 'bad endian value');
  710 +
  711 + assert.ok(offset !== undefined && offset !== null,
  712 + 'missing offset');
  713 +
  714 + assert.ok(offset + 1 < buffer.length,
  715 + 'trying to read beyond buffer length');
  716 +
  717 + verifuint(value, 0xffff);
  718 +
  719 + if (endian == 'big') {
  720 + buffer[offset] = (value & 0xff00) >>> 8;
  721 + buffer[offset + 1] = value & 0x00ff;
  722 + } else {
  723 + buffer[offset + 1] = (value & 0xff00) >>> 8;
  724 + buffer[offset] = value & 0x00ff;
  725 + }
  726 +};
  727 +
  728 +
  729 +Buffer.prototype.writeUInt32 = function(value, offset, endian) {
  730 + var buffer = this;
  731 +
  732 + assert.ok(value !== undefined && value !== null,
  733 + 'missing value');
  734 +
  735 + assert.ok(endian !== undefined && endian !== null,
  736 + 'missing endian');
  737 +
  738 + assert.ok(endian == 'big' || endian == 'little',
  739 + 'bad endian value');
  740 +
  741 + assert.ok(offset !== undefined && offset !== null,
  742 + 'missing offset');
  743 +
  744 + assert.ok(offset + 3 < buffer.length,
  745 + 'trying to read beyond buffer length');
  746 +
  747 + verifuint(value, 0xffffffff);
  748 + if (endian == 'big') {
  749 + buffer[offset] = (value >>> 24) & 0xff;
  750 + buffer[offset + 1] = (value >>> 16) & 0xff;
  751 + buffer[offset + 2] = (value >>> 8) & 0xff;
  752 + buffer[offset + 3] = value & 0xff;
  753 + } else {
  754 + buffer[offset + 3] = (value >>> 24) & 0xff;
  755 + buffer[offset + 2] = (value >>> 16) & 0xff;
  756 + buffer[offset + 1] = (value >>> 8) & 0xff;
  757 + buffer[offset] = value & 0xff;
  758 + }
  759 +};
  760 +
  761 +
  762 +/*
  763 + * We now move onto our friends in the signed number category. Unlike unsigned
  764 + * numbers, we're going to have to worry a bit more about how we put values into
  765 + * arrays. Since we are only worrying about signed 32-bit values, we're in
  766 + * slightly better shape. Unfortunately, we really can't do our favorite binary
  767 + * & in this system. It really seems to do the wrong thing. For example:
  768 + *
  769 + * > -32 & 0xff
  770 + * 224
  771 + *
  772 + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
  773 + * this aren't treated as a signed number. Ultimately a bad thing.
  774 + *
  775 + * What we're going to want to do is basically create the unsigned equivalent of
  776 + * our representation and pass that off to the wuint* functions. To do that
  777 + * we're going to do the following:
  778 + *
  779 + * - if the value is positive
  780 + * we can pass it directly off to the equivalent wuint
  781 + * - if the value is negative
  782 + * we do the following computation:
  783 + * mb + val + 1, where
  784 + * mb is the maximum unsigned value in that byte size
  785 + * val is the Javascript negative integer
  786 + *
  787 + *
  788 + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
  789 + * you do out the computations:
  790 + *
  791 + * 0xffff - 128 + 1
  792 + * 0xffff - 127
  793 + * 0xff80
  794 + *
  795 + * You can then encode this value as the signed version. This is really rather
  796 + * hacky, but it should work and get the job done which is our goal here.
  797 + */
  798 +
  799 +/*
  800 + * A series of checks to make sure we actually have a signed 32-bit number
  801 + */
  802 +function verifsint(value, max, min) {
  803 + assert.ok(typeof (value) == 'number',
  804 + 'cannot write a non-number as a number');
  805 +
  806 + assert.ok(value <= max, 'value larger than maximum allowed value');
  807 +
  808 + assert.ok(value >= min, 'value smaller than minimum allowed value');
  809 +
  810 + assert.ok(Math.floor(value) === value, 'value has a fractional component');
  811 +}
  812 +
  813 +Buffer.prototype.writeInt8 = function(value, offset, endian) {
  814 + var buffer = this;
  815 +
  816 + assert.ok(value !== undefined && value !== null,
  817 + 'missing value');
  818 +
  819 + assert.ok(endian !== undefined && endian !== null,
  820 + 'missing endian');
  821 +
  822 + assert.ok(endian == 'big' || endian == 'little',
  823 + 'bad endian value');
  824 +
  825 + assert.ok(offset !== undefined && offset !== null,
  826 + 'missing offset');
  827 +
  828 + assert.ok(offset < buffer.length,
  829 + 'Trying to read beyond buffer length');
  830 +
  831 + verifsint(value, 0x7f, -0xf0);
  832 +
  833 + if (value >= 0) {
  834 + buffer.writeUInt8(value, offset, endian);
  835 + } else {
  836 + buffer.writeUInt8(0xff + value + 1, offset, endian);
  837 + }
  838 +};
  839 +
  840 +
  841 +Buffer.prototype.writeInt16 = function(value, offset, endian) {
  842 + var buffer = this;
  843 +
  844 + assert.ok(value !== undefined && value !== null,
  845 + 'missing value');
  846 +
  847 + assert.ok(endian !== undefined && endian !== null,
  848 + 'missing endian');
  849 +
  850 + assert.ok(endian == 'big' || endian == 'little',
  851 + 'bad endian value');
  852 +
  853 + assert.ok(offset !== undefined && offset !== null,
  854 + 'missing offset');
  855 +
  856 + assert.ok(offset + 1 < buffer.length,
  857 + 'Trying to read beyond buffer length');
  858 +
  859 + verifsint(value, 0x7fff, -0xf000);
  860 +
  861 + if (value >= 0) {
  862 + buffer.writeUInt16(value, offset, endian);
  863 + } else {
  864 + buffer.writeUInt16(0xffff + value + 1, offset, endian);
  865 + }
  866 +};
  867 +
  868 +
  869 +Buffer.prototype.writeInt32 = function(value, offset, endian) {
  870 + var buffer = this;
  871 +
  872 + assert.ok(value !== undefined && value !== null,
  873 + 'missing value');
  874 +
  875 + assert.ok(endian !== undefined && endian !== null,
  876 + 'missing endian');
  877 +
  878 + assert.ok(endian == 'big' || endian == 'little',
  879 + 'bad endian value');
  880 +
  881 + assert.ok(offset !== undefined && offset !== null,
  882 + 'missing offset');
  883 +
  884 + assert.ok(offset + 3 < buffer.length,
  885 + 'Trying to read beyond buffer length');
  886 +
  887 + verifsint(value, 0x7fffffff, -0xf0000000);
  888 + if (value >= 0) {
  889 + buffer.writeUInt32(value, offset, endian);
  890 + } else {
  891 + buffer.writeUInt32(0xffffffff + value + 1, offset, endian);
  892 + }
  893 +};
100 test/simple/test-readint.js
... ... @@ -0,0 +1,100 @@
  1 +/*
  2 + * Tests to verify we're reading in signed integers correctly
  3 + */
  4 +var ASSERT = require('assert');
  5 +
  6 +/*
  7 + * Test 8 bit signed integers
  8 + */
  9 +function test8() {
  10 + var data = new Buffer(4);
  11 +
  12 + data[0] = 0x23;
  13 + ASSERT.equal(0x23, data.readInt8(0, 'big'));
  14 + ASSERT.equal(0x23, data.readInt8(0, 'little'));
  15 +
  16 + data[0] = 0xff;
  17 + ASSERT.equal(-1, data.readInt8(0, 'big'));
  18 + ASSERT.equal(-1, data.readInt8(0, 'little'));
  19 +
  20 + data[0] = 0x87;
  21 + data[1] = 0xab;
  22 + data[2] = 0x7c;
  23 + data[3] = 0xef;
  24 + ASSERT.equal(-121, data.readInt8(0, 'big'));
  25 + ASSERT.equal(-85, data.readInt8(1, 'big'));
  26 + ASSERT.equal(124, data.readInt8(2, 'big'));
  27 + ASSERT.equal(-17, data.readInt8(3, 'big'));
  28 + ASSERT.equal(-121, data.readInt8(0, 'little'));
  29 + ASSERT.equal(-85, data.readInt8(1, 'little'));
  30 + ASSERT.equal(124, data.readInt8(2, 'little'));
  31 + ASSERT.equal(-17, data.readInt8(3, 'little'));
  32 +}
  33 +
  34 +
  35 +function test16() {
  36 + var buffer = new Buffer(6);
  37 + buffer[0] = 0x16;
  38 + buffer[1] = 0x79;
  39 + ASSERT.equal(0x1679, buffer.readInt16(0, 'big'));
  40 + ASSERT.equal(0x7916, buffer.readInt16(0, 'little'));
  41 +
  42 + buffer[0] = 0xff;
  43 + buffer[1] = 0x80;
  44 + ASSERT.equal(-128, buffer.readInt16(0, 'big'));
  45 + ASSERT.equal(-32513, buffer.readInt16(0, 'little'));
  46 +
  47 + /* test offset with weenix */
  48 + buffer[0] = 0x77;
  49 + buffer[1] = 0x65;
  50 + buffer[2] = 0x65;
  51 + buffer[3] = 0x6e;
  52 + buffer[4] = 0x69;
  53 + buffer[5] = 0x78;
  54 + ASSERT.equal(0x7765, buffer.readInt16(0, 'big'));
  55 + ASSERT.equal(0x6565, buffer.readInt16(1, 'big'));
  56 + ASSERT.equal(0x656e, buffer.readInt16(2, 'big'));
  57 + ASSERT.equal(0x6e69, buffer.readInt16(3, 'big'));
  58 + ASSERT.equal(0x6978, buffer.readInt16(4, 'big'));
  59 + ASSERT.equal(0x6577, buffer.readInt16(0, 'little'));
  60 + ASSERT.equal(0x6565, buffer.readInt16(1, 'little'));
  61 + ASSERT.equal(0x6e65, buffer.readInt16(2, 'little'));
  62 + ASSERT.equal(0x696e, buffer.readInt16(3, 'little'));
  63 + ASSERT.equal(0x7869, buffer.readInt16(4, 'little'));
  64 +}
  65 +
  66 +
  67 +function test32() {
  68 + var buffer = new Buffer(6);
  69 + buffer[0] = 0x43;
  70 + buffer[1] = 0x53;
  71 + buffer[2] = 0x16;
  72 + buffer[3] = 0x79;
  73 + ASSERT.equal(0x43531679, buffer.readInt32(0, 'big'));
  74 + ASSERT.equal(0x79165343, buffer.readInt32(0, 'little'));
  75 +
  76 + buffer[0] = 0xff;
  77 + buffer[1] = 0xfe;
  78 + buffer[2] = 0xef;
  79 + buffer[3] = 0xfa;
  80 + ASSERT.equal(-69638, buffer.readInt32(0, 'big'));
  81 + ASSERT.equal(-84934913, buffer.readInt32(0, 'little'));
  82 +
  83 + buffer[0] = 0x42;
  84 + buffer[1] = 0xc3;
  85 + buffer[2] = 0x95;
  86 + buffer[3] = 0xa9;
  87 + buffer[4] = 0x36;
  88 + buffer[5] = 0x17;
  89 + ASSERT.equal(0x42c395a9, buffer.readInt32(0, 'big'));
  90 + ASSERT.equal(-1013601994, buffer.readInt32(1, 'big'));
  91 + ASSERT.equal(-1784072681, buffer.readInt32(2, 'big'));
  92 + ASSERT.equal(-1449802942, buffer.readInt32(0, 'little'));
  93 + ASSERT.equal(917083587, buffer.readInt32(1, 'little'));
  94 + ASSERT.equal(389458325, buffer.readInt32(2, 'little'));
  95 +}
  96 +
  97 +
  98 +test8();
  99 +test16();
  100 +test32();
94 test/simple/test-readuint.js
... ... @@ -0,0 +1,94 @@
  1 +/*
  2 + * A battery of tests to help us read a series of uints
  3 + */
  4 +
  5 +var ASSERT = require('assert');
  6 +
  7 +/*
  8 + * We need to check the following things:
  9 + * - We are correctly resolving big endian (doesn't mean anything for 8 bit)
  10 + * - Correctly resolving little endian (doesn't mean anything for 8 bit)
  11 + * - Correctly using the offsets
  12 + * - Correctly interpreting values that are beyond the signed range as unsigned
  13 + */
  14 +function test8() {
  15 + var data = new Buffer(4);
  16 + data[0] = 23;
  17 + data[1] = 23;
  18 + data[2] = 23;
  19 + data[3] = 23;
  20 + ASSERT.equal(23, data.readUInt8(0, 'big'));
  21 + ASSERT.equal(23, data.readUInt8(0, 'little'));
  22 + ASSERT.equal(23, data.readUInt8(1, 'big'));
  23 + ASSERT.equal(23, data.readUInt8(1, 'little'));
  24 + ASSERT.equal(23, data.readUInt8(2, 'big'));
  25 + ASSERT.equal(23, data.readUInt8(2, 'little'));
  26 + ASSERT.equal(23, data.readUInt8(3, 'big'));
  27 + ASSERT.equal(23, data.readUInt8(3, 'little'));
  28 + data[0] = 255; /* If it became a signed int, would be -1 */
  29 + ASSERT.equal(255, data.readUInt8(0, 'big'));
  30 + ASSERT.equal(255, data.readUInt8(0, 'little'));
  31 +}
  32 +
  33 +
  34 +/*
  35 + * Test 16 bit unsigned integers. We need to verify the same set as 8 bit, only
  36 + * now some of the issues actually matter:
  37 + * - We are correctly resolving big endian
  38 + * - Correctly resolving little endian
  39 + * - Correctly using the offsets
  40 + * - Correctly interpreting values that are beyond the signed range as unsigned
  41 + */
  42 +function test16() {
  43 + var data = new Buffer(4);
  44 +
  45 + data[0] = 0;
  46 + data[1] = 0x23;
  47 + data[2] = 0x42;
  48 + data[3] = 0x3f;
  49 +
  50 + ASSERT.equal(0x23, data.readUInt16(0, 'big'));
  51 + ASSERT.equal(0x2342, data.readUInt16(1, 'big'));
  52 + ASSERT.equal(0x423f, data.readUInt16(2, 'big'));
  53 +
  54 + ASSERT.equal(0x2300, data.readUInt16(0, 'little'));
  55 + ASSERT.equal(0x4223, data.readUInt16(1, 'little'));
  56 + ASSERT.equal(0x3f42, data.readUInt16(2, 'little'));
  57 +
  58 + data[0] = 0xfe;
  59 + data[1] = 0xfe;
  60 +
  61 + ASSERT.equal(0xfefe, data.readUInt16(0, 'big'));
  62 + ASSERT.equal(0xfefe, data.readUInt16(0, 'little'));
  63 +}
  64 +
  65 +
  66 +/*
  67 + * Test 32 bit unsigned integers. We need to verify the same set as 8 bit, only
  68 + * now some of the issues actually matter:
  69 + * - We are correctly resolving big endian
  70 + * - Correctly using the offsets
  71 + * - Correctly interpreting values that are beyond the signed range as unsigned
  72 + */
  73 +function test32() {
  74 + var data = new Buffer(8);
  75 + data[0] = 0x32;
  76 + data[1] = 0x65;
  77 + data[2] = 0x42;
  78 + data[3] = 0x56;
  79 + data[4] = 0x23;
  80 + data[5] = 0xff;
  81 +
  82 + ASSERT.equal(0x32654256, data.readUInt32(0, 'big'));
  83 + ASSERT.equal(0x65425623, data.readUInt32(1, 'big'));
  84 + ASSERT.equal(0x425623ff, data.readUInt32(2, 'big'));
  85 +
  86 + ASSERT.equal(0x56426532, data.readUInt32(0, 'little'));
  87 + ASSERT.equal(0x23564265, data.readUInt32(1, 'little'));
  88 + ASSERT.equal(0xff235642, data.readUInt32(2, 'little'));
  89 +}
  90 +
  91 +
  92 +test8();
  93 +test16();
  94 +test32();
91 test/simple/test-writeint.js
... ... @@ -0,0 +1,91 @@
  1 +/*
  2 + * Tests to verify we're writing signed integers correctly
  3 + */
  4 +var ASSERT = require('assert');
  5 +
  6 +function test8() {
  7 + var buffer = new Buffer(4);
  8 + buffer.writeInt8(0x23, 0, 'big');
  9 + buffer.writeInt8(0x23, 1, 'little');
  10 + buffer.writeInt8(-5, 2, 'big');
  11 + buffer.writeInt8(-5, 3, 'little');
  12 +
  13 + ASSERT.equal(0x23, buffer[0]);
  14 + ASSERT.equal(0x23, buffer[1]);
  15 + ASSERT.equal(0xfb, buffer[2]);
  16 + ASSERT.equal(0xfb, buffer[3]);
  17 +
  18 + /* Make sure we handle truncation correctly */
  19 + ASSERT.throws(function() {
  20 + buffer.writeInt8(0xabc, 0, 'big');
  21 + });
  22 + ASSERT.throws(function() {
  23 + buffer.writeInt8(0xabc, 0, 'little');
  24 + });
  25 +}
  26 +
  27 +
  28 +function test16() {
  29 + var buffer = new Buffer(6);
  30 + buffer.writeInt16(0x0023, 0, 'big');
  31 + buffer.writeInt16(0x0023, 2, 'little');
  32 + ASSERT.equal(0x00, buffer[0]);
  33 + ASSERT.equal(0x23, buffer[1]);
  34 + ASSERT.equal(0x23, buffer[2]);
  35 + ASSERT.equal(0x00, buffer[3]);
  36 + buffer.writeInt16(-5, 0, 'big');
  37 + buffer.writeInt16(-5, 2, 'little');
  38 + ASSERT.equal(0xff, buffer[0]);
  39 + ASSERT.equal(0xfb, buffer[1]);
  40 + ASSERT.equal(0xfb, buffer[2]);
  41 + ASSERT.equal(0xff, buffer[3]);
  42 +
  43 + buffer.writeInt16(-1679, 1, 'big');
  44 + buffer.writeInt16(-1679, 3, 'little');
  45 + ASSERT.equal(0xf9, buffer[1]);
  46 + ASSERT.equal(0x71, buffer[2]);
  47 + ASSERT.equal(0x71, buffer[3]);
  48 + ASSERT.equal(0xf9, buffer[4]);
  49 +}
  50 +
  51 +
  52 +function test32() {
  53 + var buffer = new Buffer(8);
  54 + buffer.writeInt32(0x23, 0, 'big');
  55 + buffer.writeInt32(0x23, 4, 'little');
  56 + ASSERT.equal(0x00, buffer[0]);
  57 + ASSERT.equal(0x00, buffer[1]);
  58 + ASSERT.equal(0x00, buffer[2]);
  59 + ASSERT.equal(0x23, buffer[3]);
  60 + ASSERT.equal(0x23, buffer[4]);
  61 + ASSERT.equal(0x00, buffer[5]);
  62 + ASSERT.equal(0x00, buffer[6]);
  63 + ASSERT.equal(0x00, buffer[7]);
  64 +
  65 + buffer.writeInt32(-5, 0, 'big');
  66 + buffer.writeInt32(-5, 4, 'little');
  67 + ASSERT.equal(0xff, buffer[0]);
  68 + ASSERT.equal(0xff, buffer[1]);
  69 + ASSERT.equal(0xff, buffer[2]);
  70 + ASSERT.equal(0xfb, buffer[3]);
  71 + ASSERT.equal(0xfb, buffer[4]);
  72 + ASSERT.equal(0xff, buffer[5]);
  73 + ASSERT.equal(0xff, buffer[6]);
  74 + ASSERT.equal(0xff, buffer[7]);
  75 +
  76 + buffer.writeInt32(-805306713, 0, 'big');
  77 + buffer.writeInt32(-805306713, 4, 'little');
  78 + ASSERT.equal(0xcf, buffer[0]);
  79 + ASSERT.equal(0xff, buffer[1]);
  80 + ASSERT.equal(0xfe, buffer[2]);
  81 + ASSERT.equal(0xa7, buffer[3]);
  82 + ASSERT.equal(0xa7, buffer[4]);
  83 + ASSERT.equal(0xfe, buffer[5]);
  84 + ASSERT.equal(0xff, buffer[6]);
  85 + ASSERT.equal(0xcf, buffer[7]);
  86 +}
  87 +
  88 +
  89 +test8();
  90 +test16();
  91 +test32();
118 test/simple/test-writeuint.js
... ... @@ -0,0 +1,118 @@
  1 +/*
  2 + * A battery of tests to help us read a series of uints
  3 + */
  4 +var ASSERT = require('assert');
  5 +
  6 +/*
  7 + * We need to check the following things:
  8 + * - We are correctly resolving big endian (doesn't mean anything for 8 bit)
  9 + * - Correctly resolving little endian (doesn't mean anything for 8 bit)
  10 + * - Correctly using the offsets
  11 + * - Correctly interpreting values that are beyond the signed range as unsigned
  12 + */
  13 +function test8() {
  14 + var data = new Buffer(4);
  15 + data.writeUInt8(23, 0, 'big');
  16 + data.writeUInt8(23, 1, 'big');
  17 + data.writeUInt8(23, 2, 'big');
  18 + data.writeUInt8(23, 3, 'big');
  19 + ASSERT.equal(23, data[0]);
  20 + ASSERT.equal(23, data[1]);
  21 + ASSERT.equal(23, data[2]);
  22 + ASSERT.equal(23, data[3]);
  23 + data.writeUInt8(23, 0, 'little');
  24 + data.writeUInt8(23, 1, 'little');
  25 + data.writeUInt8(23, 2, 'little');
  26 + data.writeUInt8(23, 3, 'little');
  27 + ASSERT.equal(23, data[0]);
  28 + ASSERT.equal(23, data[1]);
  29 + ASSERT.equal(23, data[2]);
  30 + ASSERT.equal(23, data[3]);
  31 + data.writeUInt8(255, 0, 'big');
  32 + ASSERT.equal(255, data[0]);
  33 + data.writeUInt8(255, 0, 'little');
  34 + ASSERT.equal(255, data[0]);
  35 +}
  36 +
  37 +
  38 +function test16() {
  39 + var value = 0x2343;
  40 + var data = new Buffer(4);
  41 + data.writeUInt16(value, 0, 'big');
  42 + ASSERT.equal(0x23, data[0]);
  43 + ASSERT.equal(0x43, data[1]);
  44 + data.writeUInt16(value, 1, 'big');
  45 + ASSERT.equal(0x23, data[1]);
  46 + ASSERT.equal(0x43, data[2]);
  47 + data.writeUInt16(value, 2, 'big');
  48 + ASSERT.equal(0x23, data[2]);
  49 + ASSERT.equal(0x43, data[3]);
  50 +
  51 + data.writeUInt16(value, 0, 'little');
  52 + ASSERT.equal(0x23, data[1]);
  53 + ASSERT.equal(0x43, data[0]);
  54 +
  55 + data.writeUInt16(value, 1, 'little');
  56 + ASSERT.equal(0x23, data[2]);
  57 + ASSERT.equal(0x43, data[1]);
  58 +
  59 + data.writeUInt16(value, 2, 'little');
  60 + ASSERT.equal(0x23, data[3]);
  61 + ASSERT.equal(0x43, data[2]);
  62 +
  63 + value = 0xff80;
  64 + data.writeUInt16(value, 0, 'little');
  65 + ASSERT.equal(0xff, data[1]);
  66 + ASSERT.equal(0x80, data[0]);
  67 +
  68 + data.writeUInt16(value, 0, 'big');
  69 + ASSERT.equal(0xff, data[0]);
  70 + ASSERT.equal(0x80, data[1]);
  71 +}
  72 +
  73 +
  74 +function test32() {
  75 + var data = new Buffer(6);
  76 + var value = 0xe7f90a6d;
  77 +
  78 + data.writeUInt32(value, 0, 'big');
  79 + ASSERT.equal(0xe7, data[0]);
  80 + ASSERT.equal(0xf9, data[1]);
  81 + ASSERT.equal(0x0a, data[2]);
  82 + ASSERT.equal(0x6d, data[3]);
  83 +
  84 + data.writeUInt32(value, 1, 'big');
  85 + ASSERT.equal(0xe7, data[1]);
  86 + ASSERT.equal(0xf9, data[2]);
  87 + ASSERT.equal(0x0a, data[3]);
  88 + ASSERT.equal(0x6d, data[4]);
  89 +
  90 + data.writeUInt32(value, 2, 'big');
  91 + ASSERT.equal(0xe7, data[2]);
  92 + ASSERT.equal(0xf9, data[3]);
  93 + ASSERT.equal(0x0a, data[4]);
  94 + ASSERT.equal(0x6d, data[5]);
  95 +
  96 + data.writeUInt32(value, 0, 'little');
  97 + ASSERT.equal(0xe7, data[3]);
  98 + ASSERT.equal(0xf9, data[2]);
  99 + ASSERT.equal(0x0a, data[1]);
  100 + ASSERT.equal(0x6d, data[0]);
  101 +
  102 + data.writeUInt32(value, 1, 'little');
  103 + ASSERT.equal(0xe7, data[4]);
  104 + ASSERT.equal(0xf9, data[3]);
  105 + ASSERT.equal(0x0a, data[2]);
  106 + ASSERT.equal(0x6d, data[1]);
  107 +
  108 + data.writeUInt32(value, 2, 'little');
  109 + ASSERT.equal(0xe7, data[5]);
  110 + ASSERT.equal(0xf9, data[4]);
  111 + ASSERT.equal(0x0a, data[3]);
  112 + ASSERT.equal(0x6d, data[2]);
  113 +}
  114 +
  115 +
  116 +test8();
  117 +test16();
  118 +test32();

0 comments on commit 9812e31

Please sign in to comment.
Something went wrong with that request. Please try again.