Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/root2dex/src/byte-range-source.ts is written in an unsupported language. File is not indexed.

0001 /**
0002  * A ROOT source built from nothing but "give me bytes [pos, pos+len)".
0003  *
0004  * `PodioEventFile` already handles local files and http(s) URLs directly. This
0005  * is the seam for everything else: an XRootD proxy endpoint, a service worker
0006  * cache, a test double that counts how much was read. Implement
0007  * `ByteRangeReader` and hand the result to `PodioEventFile.open` /
0008  * `Root2DexConverter.open`.
0009  *
0010  * Implement the optional `readRanges` when the transport can answer several
0011  * ranges in one round trip - JSROOT asks for all the baskets of one entry at
0012  * once, and a proxy that batches them turns an event into a single request.
0013  */
0014 
0015 import { FileProxy } from 'jsroot/io';
0016 import type { RootSource } from './podio-file';
0017 
0018 /** What a byte-range transport has to provide. */
0019 export interface ByteRangeReader {
0020   /** File name, used for messages and for JSROOT's file-name checks. */
0021   readonly name: string;
0022   /** Total size in bytes; JSROOT seeks relative to it. */
0023   readonly size: number;
0024   /** Reads one range. */
0025   readRange(position: number, length: number): Promise<ArrayBuffer | DataView>;
0026   /** Optional batched form: all ranges of one request in one round trip. */
0027   readRanges?(ranges: Array<[position: number, length: number]>): Promise<DataView[]>;
0028   close?(): void;
0029 }
0030 
0031 function toDataView(data: ArrayBuffer | DataView): DataView {
0032   return data instanceof DataView ? data : new DataView(data);
0033 }
0034 
0035 /**
0036  * Wraps a `ByteRangeReader` into the object JSROOT's `openFile` accepts.
0037  *
0038  * `FileProxy` is a JSROOT base class and `openFile` checks the instance type,
0039  * so the subclass is created here rather than declared at module scope.
0040  */
0041 export function createByteRangeSource(reader: ByteRangeReader): RootSource {
0042   class ReaderProxy extends FileProxy {
0043     async openFile(): Promise<boolean> {
0044       return true;
0045     }
0046     getFileName(): string {
0047       return reader.name;
0048     }
0049     getFileSize(): number {
0050       return reader.size;
0051     }
0052     async readBuffer(position: number, length: number): Promise<DataView> {
0053       return toDataView(await reader.readRange(position, length));
0054     }
0055     closeFile(): void {
0056       reader.close?.();
0057     }
0058   }
0059 
0060   const proxy = new ReaderProxy() as ReaderProxy & {
0061     readBuffers?: (place: number[]) => Promise<DataView[]>;
0062   };
0063 
0064   if (reader.readRanges) {
0065     // JSROOT passes places as a flat [pos, len, pos, len, ...] array
0066     proxy.readBuffers = async (place: number[]) => {
0067       const ranges: Array<[number, number]> = [];
0068       for (let i = 0; i < place.length; i += 2) ranges.push([place[i], place[i + 1]]);
0069       return reader.readRanges!(ranges);
0070     };
0071   }
0072 
0073   return proxy;
0074 }