source: node_modules/pg-protocol/src/buffer-writer.ts@ 6c7cfa6

main
Last change on this file since 6c7cfa6 was 62b2964, checked in by Klimentina Efremova <klimentina08642@…>, 2 weeks ago

Project Handcraft Marketplace

  • Property mode set to 100644
File size: 3.4 KB
Line 
1//binary data writer tuned for encoding binary specific to the postgres binary protocol
2
3export class Writer {
4 private buffer: Buffer
5 private offset: number = 5
6 private headerPosition: number = 0
7 constructor(private size = 256) {
8 this.buffer = Buffer.allocUnsafe(size)
9 }
10
11 private ensure(size: number): void {
12 const remaining = this.buffer.length - this.offset
13 if (remaining < size) {
14 const oldBuffer = this.buffer
15 // exponential growth factor of around ~ 1.5
16 // https://stackoverflow.com/questions/2269063/buffer-growth-strategy
17 const newSize = oldBuffer.length + (oldBuffer.length >> 1) + size
18 this.buffer = Buffer.allocUnsafe(newSize)
19 oldBuffer.copy(this.buffer)
20 }
21 }
22
23 public addInt32(num: number): Writer {
24 this.ensure(4)
25 this.buffer[this.offset++] = (num >>> 24) & 0xff
26 this.buffer[this.offset++] = (num >>> 16) & 0xff
27 this.buffer[this.offset++] = (num >>> 8) & 0xff
28 this.buffer[this.offset++] = (num >>> 0) & 0xff
29 return this
30 }
31
32 public addInt16(num: number): Writer {
33 this.ensure(2)
34 this.buffer[this.offset++] = (num >>> 8) & 0xff
35 this.buffer[this.offset++] = (num >>> 0) & 0xff
36 return this
37 }
38
39 public addCString(string: string): Writer {
40 if (!string) {
41 this.ensure(1)
42 } else {
43 const len = Buffer.byteLength(string)
44 this.ensure(len + 1) // +1 for null terminator
45 this.buffer.write(string, this.offset, 'utf-8')
46 this.offset += len
47 }
48
49 this.buffer[this.offset++] = 0 // null terminator
50 return this
51 }
52
53 public addString(string: string = ''): Writer {
54 const len = Buffer.byteLength(string)
55 this.ensure(len)
56 this.buffer.write(string, this.offset)
57 this.offset += len
58 return this
59 }
60
61 // Write an Int32 byte-length prefix immediately followed by the string's UTF-8
62 // bytes. Postgres' Bind wire format prefixes every parameter with its length,
63 // and doing it in one method computes Buffer.byteLength ONCE — the previous
64 // `addInt32(Buffer.byteLength(s)).addString(s)` pairing scanned the string
65 // three times (byteLength for the prefix, byteLength again inside addString,
66 // then the encode), which is costly for large text parameters.
67 public addInt32PrefixedString(string: string): Writer {
68 const len = Buffer.byteLength(string)
69 this.ensure(4 + len)
70 const buffer = this.buffer
71 let offset = this.offset
72 buffer[offset++] = (len >>> 24) & 0xff
73 buffer[offset++] = (len >>> 16) & 0xff
74 buffer[offset++] = (len >>> 8) & 0xff
75 buffer[offset++] = (len >>> 0) & 0xff
76 buffer.write(string, offset, 'utf-8')
77 this.offset = offset + len
78 return this
79 }
80
81 public add(otherBuffer: Buffer): Writer {
82 this.ensure(otherBuffer.length)
83 otherBuffer.copy(this.buffer, this.offset)
84 this.offset += otherBuffer.length
85 return this
86 }
87
88 private join(code?: number): Buffer {
89 if (code) {
90 this.buffer[this.headerPosition] = code
91 //length is everything in this packet minus the code
92 const length = this.offset - (this.headerPosition + 1)
93 this.buffer.writeInt32BE(length, this.headerPosition + 1)
94 }
95 return this.buffer.slice(code ? 0 : 5, this.offset)
96 }
97
98 public flush(code?: number): Buffer {
99 const result = this.join(code)
100 this.offset = 5
101 this.headerPosition = 0
102 this.buffer = Buffer.allocUnsafe(this.size)
103 return result
104 }
105
106 public clear(): void {
107 this.offset = 5
108 this.headerPosition = 0
109 }
110}
Note: See TracBrowser for help on using the repository browser.