@inweb/viewer-three
Version:
JavaScript library for rendering CAD and BIM files in a browser using Three.js
106 lines (89 loc) • 3.45 kB
text/typescript
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
// All rights reserved.
//
// This software and its documentation and related materials are owned by
// the Alliance. The software may only be incorporated into application
// programs owned by members of the Alliance, subject to a signed
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable
// trade secrets of the Alliance and its suppliers. The software is also
// protected by copyright law and international treaty provisions. Application
// programs incorporating this software must include the following statement
// with their copyright notices:
//
// This application incorporates Open Design Alliance software pursuant to a
// license agreement with Open Design Alliance.
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
// All rights reserved.
//
// By use of this software, its documentation or related materials, you
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////
class FetchError extends Error {
public status: number;
constructor(status: number, message: string) {
super(message);
this.name = "FetchError";
this.status = status;
}
}
export interface Range {
offset: number;
length: number;
}
export class RangesLoader {
private requestHeader: HeadersInit;
private withCredentials: boolean;
private abortSignal: AbortSignal | undefined;
constructor() {
this.requestHeader = {};
this.withCredentials = false;
this.abortSignal = undefined;
}
setRequestHeader(requestHeader: HeadersInit) {
this.requestHeader = requestHeader;
}
setWithCredentials(withCredentials: boolean) {
this.withCredentials = withCredentials;
}
setAbortSignal(abortSignal: AbortSignal) {
this.abortSignal = abortSignal;
}
async load(url: string, ranges: Range[]): Promise<ArrayBuffer> {
const init: RequestInit = {
headers: {
...this.requestHeader,
Range: "bytes=" + ranges.map((x) => `${x.offset}-${x.offset + x.length - 1}`).join(","),
},
credentials: this.withCredentials ? "include" : "same-origin",
signal: this.abortSignal,
};
const response = await fetch(url, init);
if (!response.ok) {
throw new FetchError(response.status, `Failed to fetch "${url}", status ${response.status}`);
}
if (response.status !== 206) {
const arrayBuffer = await response.arrayBuffer();
return this.extractRanges(arrayBuffer, ranges);
}
return response.arrayBuffer();
}
// ===================== AI-CODE-START ======================
// Source: Claude Sonnet 4.5
// Date: 2025-28-10
// Reviewer: roman.mochalov@opendesign.com
// Issue: CLOUD-5933
extractRanges(arrayBuffer: ArrayBuffer, ranges: Range[]): ArrayBuffer {
const totalLength = ranges.reduce((sum, range) => sum + range.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const range of ranges) {
const chunk = new Uint8Array(arrayBuffer, range.offset, range.length);
result.set(chunk, offset);
offset += range.length;
}
return result.buffer;
}
// ===================== AI-CODE-END ======================
}