Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Int } from "./int";
import { UnsignedInt } from "./unsigned-int";
import {calculatePadding, slicePadding} from "./util";
import isString from "lodash/isString";
import isArray from "lodash/isArray";
import includeIoMixin from './io-mixin';

export class String {
Expand All @@ -21,7 +22,11 @@ export class String {
let padding = calculatePadding(length);
let result = io.slice(length);
slicePadding(io, padding);
return result.buffer().toString('utf8');
return result.buffer();
}

readString(io) {
return this.read(io).toString('utf8');
}

write(value, io) {
Expand All @@ -31,20 +36,26 @@ export class String {
`max allows is ${this._maxLength}`);
}

if(!isString(value)) {
throw new Error(`XDR Write Error: ${value} is not a string,`);
let buffer;
if (isString(value)) {
buffer = Buffer.from(value, 'utf8');
} else {
buffer = Buffer.from(value);
}
let buffer = Buffer.from(value, 'utf8');

Int.write(buffer.length, io);
io.writeBufferPadded(buffer);
}

isValid(value) {
if (!isString(value)) {
let buffer;
if (isString(value)) {
buffer = Buffer.from(value, 'utf8');
} else if (isArray(value) || Buffer.isBuffer(value)) {
buffer = Buffer.from(value);
} else {
return false;
}
let buffer = Buffer.from(value, 'utf8');
return buffer.length <= this._maxLength;
}
}
Expand Down
54 changes: 47 additions & 7 deletions test/unit/string_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ let subject = new XDR.String(4);
describe('String#read', function() {

it('decodes correctly', function() {
expect(read([0x00,0x00,0x00,0x00])).to.eql("");
expect(read([0x00,0x00,0x00,0x01,0x41,0x00,0x00,0x00])).to.eql("A");
expect(read([0x00,0x00,0x00,0x03,0xe4,0xb8,0x89,0x00])).to.eql("三");
expect(read([0x00,0x00,0x00,0x02,0x41,0x41,0x00,0x00])).to.eql("AA");
expect(read([0x00,0x00,0x00,0x00]).toString('utf8')).to.eql("");
expect(read([0x00,0x00,0x00,0x01,0x41,0x00,0x00,0x00]).toString('utf8')).to.eql("A");
expect(read([0x00,0x00,0x00,0x03,0xe4,0xb8,0x89,0x00]).toString('utf8')).to.eql("三");
expect(read([0x00,0x00,0x00,0x02,0x41,0x41,0x00,0x00]).toString('utf8')).to.eql("AA");
});

it('decodes correctly to string', function() {
expect(readString([0x00,0x00,0x00,0x00])).to.eql("");
expect(readString([0x00,0x00,0x00,0x01,0x41,0x00,0x00,0x00])).to.eql("A");
expect(readString([0x00,0x00,0x00,0x03,0xe4,0xb8,0x89,0x00])).to.eql("三");
expect(readString([0x00,0x00,0x00,0x02,0x41,0x41,0x00,0x00])).to.eql("AA");
});

it('decodes non-utf-8 correctly', function() {
let val = read([0x00,0x00,0x00,0x01,0xd1,0x00,0x00,0x00])
expect(val[0]).to.eql(0xd1);
})

it("throws a read error when the encoded length is greater than the allowed max", function() {
expect(() => read([0x00,0x00,0x00,0x05,0x41,0x41,0x41,0x41,0x41])).to.throw(/read error/i);
});
Expand All @@ -26,17 +38,30 @@ describe('String#read', function() {
let io = new Cursor(bytes);
return subject.read(io);
}

function readString(bytes) {
let io = new Cursor(bytes);
return subject.readString(io);
}
});

describe('String#write', function() {

it('encodes correctly', function() {
it('encodes string correctly', function() {
expect(write("")).to.eql([0x00,0x00,0x00,0x00]);
expect(write("三")).to.eql([0x00,0x00,0x00,0x03,0xe4,0xb8,0x89,0x00]);
expect(write("A")).to.eql([0x00,0x00,0x00,0x01,0x41,0x00,0x00,0x00]);
expect(write("AA")).to.eql([0x00,0x00,0x00,0x02,0x41,0x41,0x00,0x00]);
});

it('encodes non-utf-8 correctly', function() {
expect(write([0xd1])).to.eql([0x00,0x00,0x00,0x01,0xd1,0x00,0x00,0x00]);
});

it('encodes non-utf-8 correctly (buffer)', function() {
expect(write(Buffer.from([0xd1]))).to.eql([0x00,0x00,0x00,0x01,0xd1,0x00,0x00,0x00]);
});

function write(value) {
let io = new Cursor(8);
subject.write(value, io);
Expand All @@ -51,15 +76,30 @@ describe('String#isValid', function() {
expect(subject.isValid("aa")).to.be.true;
});

it('returns true for arrays of the correct length', function() {
expect(subject.isValid([0x01])).to.be.true;
});

it('returns true for buffers of the correct length', function() {
expect(subject.isValid(Buffer.from([0x01]))).to.be.true;
});

it('returns false for strings that are too large', function() {
expect(subject.isValid("aaaaa")).to.be.false;
});

it('returns false for non string', function() {
it('returns false for arrays that are too large', function() {
expect(subject.isValid([0x01, 0x01, 0x01, 0x01, 0x01])).to.be.false;
});

it('returns false for buffers that are too large', function() {
expect(subject.isValid(Buffer.from([0x01, 0x01, 0x01, 0x01, 0x01]))).to.be.false;
});

it('returns false for non string/array/buffer', function() {
expect(subject.isValid(true)).to.be.false;
expect(subject.isValid(null)).to.be.false;
expect(subject.isValid(3)).to.be.false;
expect(subject.isValid([0])).to.be.false;
});
});

Expand Down