Skip to content

Instantly share code, notes, and snippets.

@TooTallNate
Last active June 3, 2022 13:26
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save TooTallNate/80ac2d94b950216a2705 to your computer and use it in GitHub Desktop.
Save TooTallNate/80ac2d94b950216a2705 to your computer and use it in GitHub Desktop.
Fixed length "Buffer" type, for use in `ref-struct` type definitions.
var ref = require('ref');
module.exports = BufferType;
/**
* Fixed length "Buffer" type, for use in Struct type definitions.
*
* Optionally setting the `encoding` param will force to call
* `toString(encoding)` on the buffer returning a String instead.
*/
function BufferType (length, encoding) {
if (!(this instanceof BufferType)) return new BufferType(length);
this.size = length | 0;
this.encoding = encoding || null;
}
BufferType.prototype = Object.create(ref.types.byte, {
constructor: {
value: BufferType,
enumerable: false,
writable: true,
configurable: true
}
});
BufferType.prototype.get = function (buffer, offset) {
var buf = buffer.slice(offset, offset + this.size);
if (this.encoding !== null) {
buf = buf.toString(this.encoding);
}
return buf;
};
BufferType.prototype.set = function (buffer, offset, value) {
if ('string' === typeof value || Array.isArray(value)) {
value = new Buffer(value, this.encoding);
} else if (!Buffer.isBuffer(value)) {
throw new TypeError('Buffer instance expected');
}
if (value.length > this.size) {
throw new Error('Buffer given is ' + value.length + ' bytes, but only '
+ this.size + ' bytes available');
}
value.copy(buffer, offset);
};
@zacharyabresch
Copy link

This is awesome and I've been using it a lot. I have one question ... it seems like when I use this to encode or decode strings I get a bunch of crud that wasn't in the original strings. Here's some sample data from my tests:

  1) Devices #get #get('inputs') should return the list of audio inputs:

      AssertionError: expected [ Array(2) ] to deeply equal [ Array(2) ]
      + expected - actual

       [
         {
           "deviceFlags": 7
           "deviceId": 1
      -    "deviceName": "Input One\u00018�\u0002\u0004\u0001\u0004\u0001��\u0002\u0004\u0001؏\u0002\u0004\u0001\u0001\u0003prototype\u0018-\u0005\u0001\u0001�\u0003\u0002\u0001\u0001\u0013\u000b\u0001\u0001X�\u0002\u0004\u0001\t\u0001\u0006����9\u0005\u0001\u0001�$\u0001����\u0001Ȕ\u0002\u0004\u0001\u0001\u0018�\u0002\u0004\u0001�<\u0005\u0001\u0001~\u001b\u0001��������\u0001��\u0002\u0004\u0001"
      -    "deviceUID": "1234abcd�\u0002\u0004\u0001x-\u0005\u0001\u0001�\u0005\u0001����\u0004 ������\u0002\u0004\u0001�\u0001x1\u0005\u0001\u0001s8�\u0002\u0004\u0001(�\u0002\u0004\u0001\u0018\u0013\u000b\u0001\u0001(�\u0002\u0004\u0001\u0018�\u0002\u0004\u0001\u0003\u0004�\u0001\u0001\u0001\u0001\u0001x-\u0005\u0001\u0001����\u0018\u0001����\u0004\u0004������\u0002\u0004\u0001����\u0001 .\u0005\u0001\u0001"
      -    "manufacturerName": "Apple\u0001�����\u0001\u0001ؕ\u0002\u0004\u0001��\u0002\u0004\u0001\u0001����\u0001h5\u0005\u0001\u0001����\u0001\u0010�\u0002\u0004\u0001\u00180\u0005\u0001\u0001�\u0001\u0001'��\u0002\u0004\u0001\u0001\u0001\u0001�\u0002\u0004\u0001��\u0002\u0004\u0001resolve\u0018-\u0005\u0001\u0001\b�\u0003\u0002\u0001\u0001�\u0002\u0004\u0001Ȗ\u0002\u0004\u0001\u0007\u0012�}\u000e9x-\u0005\u0001\u0001�����\u0001"
      +    "deviceName": "Input One"
      +    "deviceUID": "1234abcd"
      +    "manufacturerName": "Apple"
         }
         {
           "deviceFlags": 7
           "deviceId": 2
      -    "deviceName": "Input Two�\u0002\u0004\u0001�x-\u0005\u0001\u0001�7\u0001����\u0004\u0004������\u0002\u0004\u0001�\u0001��\u0002\u0004\u0001\u0004\u0001��\u0002\u0004\u0001�������\u0002\u0004\u0001 �\u0002\u0004\u0001./resolve.js\u0001\u0018-\u0005\u0001\u0001\u0010�\u0003\u0002\u0001\u0001��\u0002\u0004\u0001\f\u0001V��(\u0001�9\u0005\u0001\u0001�:\u0001����\u0010�\u0002\u0004\u0001\u0001��\u0002\u0004\u0001"
      -    "deviceUID": "1234abcde<\u0005\u0001\u0001�1\u0001����\u0002����8�\u0002\u0004\u0001p�\u0002\u0004\u0001�\u0019\u0001x-\u0005\u0001\u0001�\b\u0001����\u0004����ؘ\u0002\u0004\u0001�x1\u0005\u0001\u0001���\u0002\u0004\u0001(�\u0002\u0004\u0001\u0018\u0013\u000b\u0001\u0001(�\u0002\u0004\u0001Ж\u0002\u0004\u0001\u0002�����\u0001\u0001"
      -    "manufacturerName": "Microsoft���.\u0001����\u0004\u0004����ؘ\u0002\u0004\u0001����\u0001 .\u0005\u0001\u0001����*\u0001�����\u0001\u0005 �\u0002\u0004\u0001(�\u0002\u0004\u0001\u0001����\u0001h5\u0005\u0001\u0001����\u0001X�\u0002\u0004\u0001\u00180\u0005\u0001\u0001�\u0001=\b�\u0002\u0004\u0001\u0001\u0001\u0001�\u0002\u0004\u0001(�\u0002\u0004\u0001appRootPath�\u0001"
      +    "deviceName": "Input Two"
      +    "deviceUID": "1234abcde"
      +    "manufacturerName": "Microsoft"
         }
       ]

Here's some supporting code:

      const expectedInputs = {
        pDevices: [
          {
            deviceId: 1,
            deviceFlags: 7,
            deviceName: 'Input One',
            deviceUID: '1234abcd',
            manufacturerName: 'Apple',
          },
          {
            deviceId: 2,
            deviceFlags: 7,
            deviceName: 'Input Two',
            deviceUID: '1234abcde',
            manufacturerName: 'Microsoft',
          },
        ],
        nNumberDevices: 2,
      };

      const expectedStruct = new AUDIO_OS_DEVICES(expectedInputs);
      const FAKE_DATA = ref.alloc(AUDIO_OS_DEVICES, expectedStruct);

and the Struct definition:

const AUDIO_OS_DEVICE = StructType({
  deviceId: ref.types.int,
  deviceFlags: ref.types.int,
  deviceName: FixedBuffer(AUDIO_OS_DEVICE_NAME_MAX_LEN),
  deviceUID: FixedBuffer(AUDIO_OS_DEVICE_UID_MAX_LEN),
  manufacturerName: FixedBuffer(AUDIO_OS_DEVICE_MANUFACTURER_MAX_LEN),
});

const AUDIO_OS_DEVICES = StructType({
  nNumberDevices: ref.types.int,
  pDevices: RefArray(AUDIO_OS_DEVICE),
});

Any ideas on what could be causing this?

@zacharyabresch
Copy link

I just realized the source changed from whenever I copied this last.

@zacharyabresch
Copy link

Well, I added the missing code that brought the encoding into the mix. I'm now creating like this: FixedBuffer(AUDIO_OS_DEVICE_NAME_MAX_LEN, 'utf8') but still seeing all the extra junk in the strings.

@zacharyabresch
Copy link

Any thoughts?

@nanchen
Copy link

nanchen commented Jul 9, 2018

Hi zacharyabresch,

I use the piece of code below, at least I got '\u0000's attached to the end of useful characters, then I guess it shouldn't be too hard to trim the useful part.

headings":["heading 0000000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"]

    const rowData = new T.RowData({row_id:0});
    var property0 = Buffer.alloc(32);
    Buffer.from("row 0 propety 0 aaaaa").copy(property0);
    rowData.property0 = property0;

struct definition:
const RowData = refStruct({
row_id: 'int',
key: 'long',
property0: refBufferType(ROW_STRING_MAX_LEN),
property1: refBufferType(ROW_STRING_MAX_LEN),
property2: refBufferType(ROW_STRING_MAX_LEN),
property3: refBufferType(ROW_STRING_MAX_LEN)
});

@YOSSTM
Copy link

YOSSTM commented Jun 3, 2022

I need the same class but typescript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment