|
22 | 22 | import io.deephaven.javascript.proto.dhinternal.io.deephaven_core.proto.ticket_pb.Ticket; |
23 | 23 | import io.deephaven.javascript.proto.dhinternal.io.deephaven_core.proto.ticket_pb.TypedTicket; |
24 | 24 | import io.deephaven.web.client.api.Callbacks; |
| 25 | +import io.deephaven.web.client.api.JsProtobufUtils; |
25 | 26 | import io.deephaven.web.client.api.event.Event; |
26 | 27 | import io.deephaven.web.client.api.WorkerConnection; |
27 | 28 | import io.deephaven.web.client.api.event.HasEventHandling; |
@@ -81,7 +82,7 @@ private static Promise<FlightInfo> fetchPluginFlightInfo(WorkerConnection connec |
81 | 82 | Uint8Array innerRequestBytes = fetchRequest.serializeBinary(); |
82 | 83 |
|
83 | 84 | // Wrap in google.protobuf.Any with the proper typeUrl |
84 | | - Uint8Array anyWrappedBytes = wrapInAny( |
| 85 | + Uint8Array anyWrappedBytes = JsProtobufUtils.wrapInAny( |
85 | 86 | "type.googleapis.com/io.deephaven.proto.backplane.grpc.RemoteFileSourcePluginFetchRequest", |
86 | 87 | innerRequestBytes); |
87 | 88 |
|
@@ -317,165 +318,4 @@ public void respond(@JsNullable Object content) { |
317 | 318 | sendClientRequest(clientRequest); |
318 | 319 | } |
319 | 320 | } |
320 | | - |
321 | | - /** |
322 | | - * Calculates the total size needed for a protobuf length-delimited field. |
323 | | - * <p> |
324 | | - * A length-delimited field consists of: |
325 | | - * <ul> |
326 | | - * <li>Tag (field number + wire type) encoded as a varint</li> |
327 | | - * <li>Length of the data encoded as a varint</li> |
328 | | - * <li>The actual data bytes</li> |
329 | | - * </ul> |
330 | | - * |
331 | | - * @param tag the protobuf field tag (field number << 3 | wire type) |
332 | | - * @param dataLength the length of the data in bytes |
333 | | - * @return the total number of bytes needed for this field |
334 | | - */ |
335 | | - private static int calculateFieldSize(int tag, int dataLength) { |
336 | | - return sizeOfVarint(tag) + sizeOfVarint(dataLength) + dataLength; |
337 | | - } |
338 | | - |
339 | | - /** |
340 | | - * Calculates how many bytes a varint encoding will require for the given value. |
341 | | - * <p> |
342 | | - * Protobuf uses varint encoding where each byte stores 7 bits of data (the 8th bit is |
343 | | - * a continuation flag). This means: |
344 | | - * <ul> |
345 | | - * <li>1 byte: 0 to 127 (2^7 - 1)</li> |
346 | | - * <li>2 bytes: 128 to 16,383 (2^14 - 1)</li> |
347 | | - * <li>3 bytes: 16,384 to 2,097,151 (2^21 - 1)</li> |
348 | | - * <li>4 bytes: 2,097,152 to 268,435,455 (2^28 - 1)</li> |
349 | | - * <li>5 bytes: 268,435,456 to 4,294,967,295 (2^35 - 1, max unsigned 32-bit)</li> |
350 | | - * <li>10 bytes: negative numbers (due to sign extension)</li> |
351 | | - * </ul> |
352 | | - * |
353 | | - * @param value the integer value to encode |
354 | | - * @return the number of bytes required to encode the value as a varint |
355 | | - */ |
356 | | - private static int sizeOfVarint(int value) { |
357 | | - if (value < 0) |
358 | | - return 10; // Negative numbers use sign extension, always 10 bytes |
359 | | - if (value < 128) // 2^7 |
360 | | - return 1; |
361 | | - if (value < 16384) // 2^14 |
362 | | - return 2; |
363 | | - if (value < 2097152) // 2^21 |
364 | | - return 3; |
365 | | - if (value < 268435456) // 2^28 |
366 | | - return 4; |
367 | | - return 5; // 2^35 (max for positive 32-bit int) |
368 | | - } |
369 | | - |
370 | | - /** |
371 | | - * Wraps a protobuf message in a google.protobuf.Any message. |
372 | | - * <p> |
373 | | - * The google.protobuf.Any message has two fields: |
374 | | - * <ul> |
375 | | - * <li>Field 1: type_url (string) - identifies the type of message contained</li> |
376 | | - * <li>Field 2: value (bytes) - the actual serialized message</li> |
377 | | - * </ul> |
378 | | - * <p> |
379 | | - * This method manually encodes the Any message in protobuf binary format since the client-side |
380 | | - * JavaScript protobuf library doesn't provide Any.pack() like the server-side Java library does. |
381 | | - * |
382 | | - * @param typeUrl the type URL for the message (e.g., "type.googleapis.com/package.MessageName") |
383 | | - * @param messageBytes the serialized protobuf message bytes |
384 | | - * @return the serialized Any message containing the wrapped message |
385 | | - */ |
386 | | - private static Uint8Array wrapInAny(String typeUrl, Uint8Array messageBytes) { |
387 | | - // Protobuf tag constants for google.protobuf.Any message fields |
388 | | - // Tag format: (field_number << 3) | wire_type |
389 | | - // wire_type=2 means length-delimited (for strings/bytes) |
390 | | - final int TYPE_URL_TAG = 10; // (1 << 3) | 2 = field 1, wire type 2 |
391 | | - final int VALUE_TAG = 18; // (2 << 3) | 2 = field 2, wire type 2 |
392 | | - |
393 | | - // Encode the type_url string to UTF-8 bytes |
394 | | - TextEncoder textEncoder = new TextEncoder(); |
395 | | - Uint8Array typeUrlBytes = textEncoder.encode(typeUrl); |
396 | | - |
397 | | - // Calculate sizes for protobuf binary encoding |
398 | | - int typeUrlFieldSize = calculateFieldSize(TYPE_URL_TAG, typeUrlBytes.length); |
399 | | - int valueFieldSize = calculateFieldSize(VALUE_TAG, messageBytes.length); |
400 | | - |
401 | | - // Allocate buffer for the complete Any message |
402 | | - int totalSize = typeUrlFieldSize + valueFieldSize; |
403 | | - Uint8Array result = new Uint8Array(totalSize); |
404 | | - int pos = 0; |
405 | | - |
406 | | - // Write field 1 (type_url) in protobuf binary format |
407 | | - pos = writeField(result, pos, TYPE_URL_TAG, typeUrlBytes); |
408 | | - |
409 | | - // Write field 2 (value) in protobuf binary format |
410 | | - writeField(result, pos, VALUE_TAG, messageBytes); |
411 | | - |
412 | | - return result; |
413 | | - } |
414 | | - |
415 | | - /** |
416 | | - * Writes a complete protobuf length-delimited field to the buffer. |
417 | | - * <p> |
418 | | - * A length-delimited field consists of: |
419 | | - * <ul> |
420 | | - * <li>Tag (field number + wire type) encoded as a varint</li> |
421 | | - * <li>Length of the data encoded as a varint</li> |
422 | | - * <li>The actual data bytes</li> |
423 | | - * </ul> |
424 | | - * |
425 | | - * @param buffer the buffer to write to |
426 | | - * @param pos the starting position in the buffer |
427 | | - * @param tag the protobuf field tag |
428 | | - * @param data the data bytes to write |
429 | | - * @return the new position after writing the complete field |
430 | | - */ |
431 | | - private static int writeField(Uint8Array buffer, int pos, int tag, Uint8Array data) { |
432 | | - // Write tag and length |
433 | | - pos = writeVarint(buffer, pos, tag); |
434 | | - pos = writeVarint(buffer, pos, data.length); |
435 | | - // Write data bytes |
436 | | - for (int i = 0; i < data.length; i++) { |
437 | | - buffer.setAt(pos++, data.getAt(i)); |
438 | | - } |
439 | | - return pos; |
440 | | - } |
441 | | - |
442 | | - |
443 | | - /** |
444 | | - * Writes a value to the buffer as a protobuf varint (variable-length integer). |
445 | | - * <p> |
446 | | - * Varint encoding works by: |
447 | | - * <ol> |
448 | | - * <li>Taking the lowest 7 bits of the value</li> |
449 | | - * <li>Setting the 8th bit to 1 if more bytes follow (continuation flag)</li> |
450 | | - * <li>Writing the byte to the buffer</li> |
451 | | - * <li>Shifting the value right by 7 bits</li> |
452 | | - * <li>Repeating until the value is less than 128</li> |
453 | | - * <li>Writing the final byte without the continuation flag (8th bit = 0)</li> |
454 | | - * </ol> |
455 | | - * <p> |
456 | | - * Example: encoding 300 |
457 | | - * <ul> |
458 | | - * <li>300 in binary: 100101100</li> |
459 | | - * <li>First byte: (300 & 0x7F) | 0x80 = 0b00101100 | 0b10000000 = 172 (0xAC)</li> |
460 | | - * <li>Shift: 300 >>> 7 = 2</li> |
461 | | - * <li>Second byte: 2 (no continuation flag)</li> |
462 | | - * <li>Result: [172, 2]</li> |
463 | | - * </ul> |
464 | | - * |
465 | | - * @param buffer the buffer to write to |
466 | | - * @param pos the starting position in the buffer |
467 | | - * @param value the value to encode |
468 | | - * @return the new position after writing |
469 | | - */ |
470 | | - private static int writeVarint(Uint8Array buffer, int pos, int value) { |
471 | | - while (value >= 128) { |
472 | | - // Extract lowest 7 bits and set continuation flag (8th bit = 1) |
473 | | - buffer.setAt(pos++, (double) ((value & 0x7F) | 0x80)); |
474 | | - // Shift right by 7 to process next chunk |
475 | | - value >>>= 7; // Unsigned right shift to handle large positive values |
476 | | - } |
477 | | - // Write final byte (no continuation flag, 8th bit = 0) |
478 | | - buffer.setAt(pos++, (double) value); |
479 | | - return pos; |
480 | | - } |
481 | 321 | } |
0 commit comments