-
Notifications
You must be signed in to change notification settings - Fork 4k
ARROW-6317: [JS] Implement IPC message format alignment changes #5225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,11 @@ export class MessageReader implements IterableIterator<Message> { | |
| public next(): IteratorResult<Message> { | ||
| let r; | ||
| if ((r = this.readMetadataLength()).done) { return ITERATOR_DONE; } | ||
| // ARROW-6313: If the first 4 bytes are continuation indicator (-1), read | ||
| // the next 4 for the 32-bit metadata length. Otherwise, assume this is a | ||
| // pre-v0.15 message, where the first 4 bytes are the metadata length. | ||
| if ((r.value === -1) && | ||
| (r = this.readMetadataLength()).done) { return ITERATOR_DONE; } | ||
| if ((r = this.readMetadata(r.value)).done) { return ITERATOR_DONE; } | ||
| return (<any> r) as IteratorResult<Message>; | ||
| } | ||
|
|
@@ -76,8 +81,8 @@ export class MessageReader implements IterableIterator<Message> { | |
| protected readMetadataLength(): IteratorResult<number> { | ||
| const buf = this.source.read(PADDING); | ||
| const bb = buf && new ByteBuffer(buf); | ||
| const len = +(bb && bb.readInt32(0))!; | ||
| return { done: len <= 0, value: len }; | ||
| const len = bb && bb.readInt32(0) || 0; | ||
| return { done: len === 0, value: len }; | ||
| } | ||
| protected readMetadata(metadataLength: number): IteratorResult<Message> { | ||
| const buf = this.source.read(metadataLength); | ||
|
|
@@ -104,6 +109,11 @@ export class AsyncMessageReader implements AsyncIterableIterator<Message> { | |
| public async next(): Promise<IteratorResult<Message>> { | ||
| let r; | ||
| if ((r = await this.readMetadataLength()).done) { return ITERATOR_DONE; } | ||
| // ARROW-6313: If the first 4 bytes are continuation indicator (-1), read | ||
| // the next 4 for the 32-bit metadata length. Otherwise, assume this is a | ||
| // pre-v0.15 message, where the first 4 bytes are the metadata length. | ||
| if ((r.value === -1) && | ||
| (r = await this.readMetadataLength()).done) { return ITERATOR_DONE; } | ||
|
||
| if ((r = await this.readMetadata(r.value)).done) { return ITERATOR_DONE; } | ||
| return (<any> r) as IteratorResult<Message>; | ||
| } | ||
|
|
@@ -140,8 +150,8 @@ export class AsyncMessageReader implements AsyncIterableIterator<Message> { | |
| protected async readMetadataLength(): Promise<IteratorResult<number>> { | ||
| const buf = await this.source.read(PADDING); | ||
| const bb = buf && new ByteBuffer(buf); | ||
| const len = +(bb && bb.readInt32(0))!; | ||
| return { done: len <= 0, value: len }; | ||
| const len = bb && bb.readInt32(0) || 0; | ||
| return { done: len === 0, value: len }; | ||
| } | ||
| protected async readMetadata(metadataLength: number): Promise<IteratorResult<Message>> { | ||
| const buf = await this.source.read(metadataLength); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have some kind of assertion somewhere that verifies length > 0? What happens if a corrupt file has that value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s effectively handled in the subsequent call. We use the length read here as the number of bytes to consume from the stream, which should be the flatbuffer metadata.
If the length is incorrect, the flatbuffer metadata created from the buffer will be empty. If the length is too long, the stream will read as many bytes as it can, and close automatically. Both cases are interpreted by the stream reader as bad input, and ignored.