Skip to content

Commit

Permalink
PR #386: Use Buffer instead of string concatenation for huge XML su…
Browse files Browse the repository at this point in the history
…pport.
  • Loading branch information
agerasimov authored and jjhbw committed Sep 25, 2024
1 parent 3afd74b commit e1032d9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ async function createReport(

logger.debug('Converting report to XML...');
const reportXml = buildXml(report1, xmlOptions);
if (_probe === 'XML') return reportXml;
if (_probe === 'XML') return reportXml.toString('utf-8');
logger.debug('Writing report...');
zipSetText(zip, `${TEMPLATE_PATH}/${mainDocument}`, reportXml);

Expand Down Expand Up @@ -478,7 +478,7 @@ const processImages = async (
logger.debug(`Writing image ${imageId} (${imgName})...`);
const imgPath = `${TEMPLATE_PATH}/media/${imgName}`;
if (typeof imgData === 'string') {
zipSetBase64(zip, imgPath, imgData);
zipSetBase64(zip, imgPath, Buffer.from(imgData));
} else {
zipSetBinary(zip, imgPath, imgData);
}
Expand Down Expand Up @@ -550,7 +550,7 @@ const processHtmls = async (
logger.debug(`Writing html ${htmlId} (${htmlName})...`);
const htmlPath = `${TEMPLATE_PATH}/${htmlName}`;
htmlFiles.push(`/${htmlPath}`);
zipSetText(zip, htmlPath, htmlData);
zipSetText(zip, htmlPath, Buffer.from(htmlData));
addChild(
rels,
newNonTextNode('Relationship', {
Expand Down
27 changes: 21 additions & 6 deletions src/xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,16 @@ type XmlOptions = {
};

const buildXml = (node: Node, options: XmlOptions, indent: string = '') => {
let xml = indent.length
const xml = indent.length
? ''
: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
if (node._fTextNode) xml += sanitizeText(node._text, options);

let xmlBuffer = Buffer.from(xml, 'utf-8');
if (node._fTextNode)
xmlBuffer = Buffer.concat([
xmlBuffer,
Buffer.from(sanitizeText(node._text, options)),
]);
else {
let attrs = '';
const nodeAttrs = node._attrs;
Expand All @@ -66,18 +72,27 @@ const buildXml = (node: Node, options: XmlOptions, indent: string = '') => {
});
const fHasChildren = node._children.length > 0;
const suffix = fHasChildren ? '' : '/';
xml += `\n${indent}<${node._tag}${attrs}${suffix}>`;
xmlBuffer = Buffer.concat([
xmlBuffer,
Buffer.from(`\n${indent}<${node._tag}${attrs}${suffix}>`),
]);
let fLastChildIsNode = false;
node._children.forEach(child => {
xml += buildXml(child, options, `${indent} `);
xmlBuffer = Buffer.concat([
xmlBuffer,
buildXml(child, options, `${indent} `),
]);
fLastChildIsNode = !child._fTextNode;
});
if (fHasChildren) {
const indent2 = fLastChildIsNode ? `\n${indent}` : '';
xml += `${indent2}</${node._tag}>`;
xmlBuffer = Buffer.concat([
xmlBuffer,
Buffer.from(`${indent2}</${node._tag}>`),
]);
}
}
return xml;
return xmlBuffer;
};

const sanitizeText = (str: string, options: XmlOptions) => {
Expand Down
6 changes: 3 additions & 3 deletions src/zip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ const zipGetText = (zip: JSZip, filename: string) => {
return file_in_zip.async('text');
};

const zipSetText = (zip: JSZip, filename: string, data: string) =>
zip.file(filename, data);
const zipSetText = (zip: JSZip, filename: string, data: Buffer) =>
zip.file(filename, data, { binary: false });
const zipSetBinary = (zip: JSZip, filename: string, data: ArrayBuffer) =>
zip.file(filename, data, { binary: true });
const zipSetBase64 = (zip: JSZip, filename: string, data: string) =>
const zipSetBase64 = (zip: JSZip, filename: string, data: Buffer) =>
zip.file(filename, data, { base64: true });
const zipSave = (zip: JSZip) =>
zip.generateAsync({
Expand Down

0 comments on commit e1032d9

Please sign in to comment.