Skip to content

Commit 35254ee

Browse files
committed
support multiple encoders
1 parent d397193 commit 35254ee

File tree

1 file changed

+55
-12
lines changed

1 file changed

+55
-12
lines changed

src/viewer/App.tsx

+55-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ import classNames from 'classnames';
55
import './App.scss';
66
import {ObjectInspector} from 'react-inspector';
77
import {Frame} from 'rsocket-types';
8-
import {deserializeFrame, deserializeFrameWithLength, FLAGS, FRAME_TYPES, printFrame, Utf8Encoders} from "rsocket-core";
8+
import {
9+
BufferEncoders,
10+
deserializeFrame,
11+
deserializeFrameWithLength,
12+
FLAGS,
13+
FRAME_TYPES,
14+
printFrame,
15+
Utf8Encoders
16+
} from "rsocket-core";
17+
import {Encoders} from "rsocket-core/RSocketEncoding";
918

1019
function getRSocketType(type) {
1120
for (const [name, code] of Object.entries(FRAME_TYPES)) {
@@ -59,8 +68,8 @@ function base64ToArrayBuffer(base64: string) {
5968
return bytes;
6069
}
6170

62-
const FrameEntry = ({frame, selected, onClick}: {frame: WsFrame, selected: boolean, onClick: MouseEventHandler}) => {
63-
const rsocketFrame = tryDecodeFrame(frame.payload)
71+
const FrameEntry = ({frame, selected, onClick}: { frame: WsFrame, selected: boolean, onClick: MouseEventHandler }) => {
72+
const rsocketFrame = tryDeserializeFrame(frame.payload)
6473
const frameName = rsocketFrame
6574
? <span className="name">{shortFrame(rsocketFrame)}</span>
6675
: <span className="name">{frame.text != null ? "Text Frame" : "Binary Frame"}</span>
@@ -120,10 +129,14 @@ class RSocketFrame extends React.Component<RSocketFrameProps, any> {
120129
jsonMeta = undefined;
121130
}
122131
const dataField = jsonData
123-
? <div><hr/>Data<br/><ObjectInspector data={jsonData}/></div>
132+
? <div>
133+
<hr/>
134+
Data<br/><ObjectInspector data={jsonData}/></div>
124135
: <div/>
125136
const jsonField = jsonMeta
126-
? <div><hr/>Metadata<br/><ObjectInspector data={jsonMeta}/></div>
137+
? <div>
138+
<hr/>
139+
Metadata<br/><ObjectInspector data={jsonMeta}/></div>
127140
: <div/>
128141
return (
129142
<div>
@@ -180,19 +193,47 @@ const TextViewer = ({data}) => (
180193
</div>
181194
);
182195

183-
function tryDecodeFrame(data: string): Frame | undefined {
196+
// Could
197+
let cachedEncoders: Encoders<any> = Utf8Encoders
198+
let cachedLengthPrefixedFrames: boolean = false;
199+
200+
function tryDeserializeFrameWith(data: string, buffer: Buffer, lengthPrefixedFrames, encoders: Encoders<any>) {
184201
try {
185-
let lengthPrefixedFrames = false;
186-
const buffer = base64ToArrayBuffer(data);
187202
return lengthPrefixedFrames
188-
? deserializeFrameWithLength(buffer, Utf8Encoders)
189-
: deserializeFrame(buffer, Utf8Encoders);
203+
? deserializeFrameWithLength(buffer, encoders)
204+
: deserializeFrame(buffer, encoders);
190205
} catch (e) {
191206
// console.error("failed to decode frame", e)
192207
return undefined;
193208
}
194209
}
195210

211+
function tryDeserializeFrame(data: string): Frame | undefined {
212+
const buffer = base64ToArrayBuffer(data)
213+
let frame: Frame | undefined;
214+
// fast path
215+
frame = tryDeserializeFrameWith(data, buffer, cachedLengthPrefixedFrames, cachedEncoders);
216+
if (frame) {
217+
return frame;
218+
}
219+
// slow path
220+
let attempts: [Encoders<any>, boolean][] = [
221+
[Utf8Encoders, false],
222+
[Utf8Encoders, true],
223+
[BufferEncoders, false],
224+
[BufferEncoders, true],
225+
];
226+
for (let [encoders, lengthPrefixedFrames] of attempts) {
227+
frame = tryDeserializeFrameWith(data, buffer, lengthPrefixedFrames, encoders);
228+
if (frame) {
229+
cachedEncoders = encoders;
230+
cachedLengthPrefixedFrames = lengthPrefixedFrames;
231+
return frame;
232+
}
233+
}
234+
return undefined;
235+
}
236+
196237
const RSocketViewer = ({frame, data}) => {
197238
try {
198239
return (
@@ -219,10 +260,12 @@ class FrameView extends React.Component<{ wsFrame: WsFrame }, { panel?: string }
219260

220261
render() {
221262
const {wsFrame} = this.props;
222-
const rsocketFrame = tryDecodeFrame(wsFrame.payload)
263+
const rsocketFrame = tryDeserializeFrame(wsFrame.payload)
223264
const panel = rsocketFrame
224265
? <RSocketViewer frame={rsocketFrame} data={wsFrame.payload}/>
225-
: <TextViewer data={wsFrame.text}/>;
266+
: wsFrame.text
267+
? <TextViewer data={wsFrame.text}/>
268+
: <TextViewer data={wsFrame.binary}/>;
226269
return (
227270
<div className="FrameView">
228271
{panel}

0 commit comments

Comments
 (0)