@native-to-anchor/buffer-layout
Version:
Buffer layout utilities for Solana programs.
193 lines • 6.07 kB
JavaScript
import BN from "bn.js";
import { Layout, blob, u32, struct, offset, seq, u8, } from "@solana/buffer-layout";
export { blob, f32, f64, Layout, s16 as i16, s32 as i32, s8 as i8, seq, struct, u16, u32, u8, union, } from "@solana/buffer-layout";
export { bool, decimal, publicKey } from "@solana/buffer-layout-utils";
export function u64(property) {
return new BNLayout(8, false, property);
}
export function i64(property) {
return new BNLayout(8, true, property);
}
export function u128(property) {
return new BNLayout(16, false, property);
}
export function i128(property) {
return new BNLayout(16, true, property);
}
class BNLayout extends Layout {
constructor(span, signed, property) {
super(span, property);
this.blob = blob(span);
this.signed = signed;
}
encode(src, b, offset = 0) {
if (this.signed) {
src = src.toTwos(this.span * 8);
}
return this.blob.encode(src.toArrayLike(Buffer, "le", this.span), b, offset);
}
decode(b, offset = 0) {
const num = new BN(this.blob.decode(b, offset), 10, "le");
if (this.signed) {
return num.fromTwos(this.span * 8).clone();
}
return num;
}
}
export function option(layout, property) {
return new OptionLayout(layout, property);
}
class OptionLayout extends Layout {
constructor(layout, property) {
super(-1, property);
this.layout = layout;
this.discriminator = u8();
}
encode(src, b, offset = 0) {
if (src === null || src === undefined) {
return this.discriminator.encode(0, b, offset);
}
this.discriminator.encode(1, b, offset);
return (this.discriminator.span +
this.layout.encode(src, b, offset + this.discriminator.span));
}
decode(b, offset = 0) {
const discriminator = this.discriminator.decode(b, offset);
if (discriminator === 0) {
return null;
}
else if (discriminator === 1) {
return this.layout.decode(b, offset + this.discriminator.span);
}
throw new Error("Invalid option " + this.layout.property);
}
getSpan(b, offset = 0) {
const discriminator = this.discriminator.decode(b, offset);
if (discriminator === 0) {
return 1;
}
else if (discriminator === 1) {
return this.layout.getSpan(b, offset + 1) + 1;
}
throw new Error("Invalid option " + this.property);
}
}
export function coption(layout, property) {
return new COptionLayout(layout, property);
}
class COptionLayout extends Layout {
constructor(layout, property) {
super(-1, property);
this.layout = layout;
this.discriminator = u32();
}
encode(src, b, offset = 0) {
if (src === null || src === undefined) {
return this.layout.span + this.discriminator.encode(0, b, offset);
}
this.discriminator.encode(1, b, offset);
return (this.discriminator.span +
this.layout.encode(src, b, offset + this.discriminator.span));
}
decode(b, offset = 0) {
const discriminator = this.discriminator.decode(b, offset);
if (discriminator === 0) {
return null;
}
else if (discriminator === 1) {
return this.layout.decode(b, offset + this.discriminator.span);
}
throw new Error("Invalid coption " + this.layout.property);
}
getSpan(b, offset = 0) {
return (this.discriminator.span +
this.layout.getSpan(b, offset + this.discriminator.span));
}
}
export function vec(layout, property) {
return new VecLayout(layout, property);
}
class VecLayout extends Layout {
constructor(layout, property) {
super(-1, property);
this.layout = struct([
u32("length"),
// @ts-ignore
seq(layout, offset(u32(), -4), "src"),
], property);
}
encode(src, b, offset = 0) {
const data = {
src,
};
return this.layout.encode(data, b, offset);
}
decode(b, offset = 0) {
const data = this.layout.decode(b, offset);
return data.src;
}
getSpan(b, offset = 0) {
return this.layout.getSpan(b, offset);
}
}
export function bytes(property) {
return new BytesLayout(property);
}
class BytesLayout extends Layout {
constructor(property) {
super(-1, property);
this.layout = struct([
u32("length"),
// @ts-ignore
blob(offset(u32(), -4), "src"),
], this.property);
}
encode(src, b, offset = 0) {
if (src === null || src === undefined) {
return this.layout.span;
}
const data = {
src,
};
return this.layout.encode(data, b, offset);
}
decode(b, offset = 0) {
const data = this.layout.decode(b, offset);
return data.src;
}
getSpan(b, offset = 0) {
return (u32().span +
new BN(new Uint8Array(b).slice(offset, offset + 4), 10, "le").toNumber());
}
}
export function utf8Str(property) {
return new Utf8StringLayout(property);
}
class Utf8StringLayout extends Layout {
constructor(property) {
super(-1, property);
this.layout = struct([
u32("length"),
// @ts-ignore
blob(offset(u32(), -4), "src"),
], this.property);
}
encode(src, b, offset = 0) {
if (src === null || src === undefined) {
return this.layout.span;
}
const data = {
src: Buffer.from(src, "utf8"),
};
return this.layout.encode(data, b, offset);
}
decode(b, offset = 0) {
const data = this.layout.decode(b, offset);
return data.src.toString();
}
getSpan(b, offset = 0) {
return (u32().span +
new BN(new Uint8Array(b).slice(offset, offset + 4), 10, "le").toNumber());
}
}
//# sourceMappingURL=index.js.map