Utilities for creating, modifying, and managing CFB container structures.
Creates a new empty CFB container that can be populated with files and directories.
/**
* Create new empty CFB container
* @param opts - Optional configuration for the new container
* @returns New empty CFB container ready for file additions
*/
CFB.utils.cfb_new(opts?: any): CFB$Container;Usage Examples:
const CFB = require('cfb');
// Create a new empty container
const cfb = CFB.utils.cfb_new();
console.log('Created container with', cfb.FullPaths.length, 'entries'); // 1 (root)
// Add some content
CFB.utils.cfb_add(cfb, 'Document', Buffer.from('Hello World'));
CFB.utils.cfb_add(cfb, 'Metadata', Buffer.from('Created with CFB'));
// Write to file
CFB.writeFile(cfb, 'my-document.cfb');Adds files or streams to an existing CFB container.
/**
* Add file/stream to CFB container
* @param cfb - Target CFB container
* @param name - Name/path for the new entry
* @param content - File content (Buffer, string, or array)
* @param opts - Optional settings for the addition
* @returns The created CFB entry
*/
CFB.utils.cfb_add(
cfb: CFB$Container,
name: string,
content: any,
opts?: CFB$AddOpts
): CFB$Entry;
interface CFB$AddOpts {
/** Skip existence and safety checks (best for bulk operations) */
unsafe?: boolean;
}Usage Examples:
const CFB = require('cfb');
// Create container and add various content types
const cfb = CFB.utils.cfb_new();
// Add text content
CFB.utils.cfb_add(cfb, 'readme.txt', 'This is a readme file');
// Add binary content
const binaryData = Buffer.from([0x89, 0x50, 0x4E, 0x47]); // PNG header
CFB.utils.cfb_add(cfb, 'image.png', binaryData);
// Add JSON data
const metadata = { title: 'My Document', author: 'John Doe' };
CFB.utils.cfb_add(cfb, 'metadata.json', JSON.stringify(metadata));
// Add with unsafe flag for bulk operations
const bulkData = Array.from({length: 100}, (_, i) => `File ${i} content`);
bulkData.forEach((content, i) => {
CFB.utils.cfb_add(cfb, `bulk/file${i}.txt`, content, { unsafe: true });
});
console.log('Container now has', cfb.FullPaths.length, 'entries');Removes files or streams from a CFB container.
/**
* Delete file from CFB container
* @param cfb - CFB container to modify
* @param name - Name/path of entry to delete
* @returns true if deletion successful, false if entry not found
*/
CFB.utils.cfb_del(cfb: CFB$Container, name: string): boolean;Usage Examples:
const CFB = require('cfb');
// Load existing container
const cfb = CFB.read('document.cfb', { type: 'file' });
// Delete specific files
const deleted = CFB.utils.cfb_del(cfb, 'TempFile');
if (deleted) {
console.log('Successfully deleted TempFile');
} else {
console.log('TempFile not found');
}
// Delete multiple files
const filesToDelete = ['cache.tmp', 'backup.bak', 'old-version.dat'];
filesToDelete.forEach(filename => {
const success = CFB.utils.cfb_del(cfb, filename);
console.log(`Delete ${filename}: ${success ? 'success' : 'not found'}`);
});
// Save modified container
CFB.writeFile(cfb, 'cleaned-document.cfb');Moves or renames files within a CFB container.
/**
* Move/rename file in CFB container
* @param cfb - CFB container to modify
* @param old_name - Current name/path of the entry
* @param new_name - New name/path for the entry
* @returns true if move successful, false if old entry not found
*/
CFB.utils.cfb_mov(cfb: CFB$Container, old_name: string, new_name: string): boolean;Usage Examples:
const CFB = require('cfb');
// Load container
const cfb = CFB.read('document.cfb', { type: 'file' });
// Rename a file
const renamed = CFB.utils.cfb_mov(cfb, 'OldName', 'NewName');
if (renamed) {
console.log('Successfully renamed OldName to NewName');
}
// Move file to different location (if directory structure exists)
CFB.utils.cfb_mov(cfb, 'Document', 'Archive/Document');
// Batch rename with pattern
const entries = cfb.FullPaths.filter(path => path.startsWith('temp_'));
entries.forEach(oldPath => {
const newPath = oldPath.replace('temp_', 'final_');
CFB.utils.cfb_mov(cfb, oldPath, newPath);
});
// Save changes
CFB.writeFile(cfb, 'reorganized-document.cfb');Rebuilds and optimizes a CFB container by removing unused space and reorganizing the structure.
/**
* Garbage collect and rebuild CFB container
* @param cfb - CFB container to optimize
*/
CFB.utils.cfb_gc(cfb: CFB$Container): void;Usage Examples:
const CFB = require('cfb');
// Load container that may have fragmentation
const cfb = CFB.read('large-document.cfb', { type: 'file' });
// Perform many modifications
CFB.utils.cfb_add(cfb, 'NewFile1', 'Content 1');
CFB.utils.cfb_del(cfb, 'OldFile1');
CFB.utils.cfb_add(cfb, 'NewFile2', 'Content 2');
CFB.utils.cfb_del(cfb, 'OldFile2');
console.log('Before GC - Size:', CFB.write(cfb).length, 'bytes');
// Optimize the container
CFB.utils.cfb_gc(cfb);
console.log('After GC - Size:', CFB.write(cfb).length, 'bytes');
// Save optimized container
CFB.writeFile(cfb, 'optimized-document.cfb');The CFB library provides low-level utilities for advanced binary data manipulation.
/**
* Read shift utility for binary data processing
* @param size - Number of bytes to read
* @param t - Optional type specification
* @returns Numeric or string value depending on type
*/
CFB.utils.ReadShift(size: number, t?: string): number | string;
/**
* Field validation utility
* @param hexstr - Hex string to validate
* @param fld - Optional field name for error reporting
*/
CFB.utils.CheckField(hexstr: string, fld?: string): void;
/**
* Prepare blob for processing
* @param blob - Input data to prepare
* @param pos - Optional position offset
* @returns Prepared blob data
*/
CFB.utils.prep_blob(blob: any, pos?: number): CFB$Blob;
/**
* Concatenate buffers/arrays
* @param bufs - Array of buffers to concatenate
* @returns Concatenated result
*/
CFB.utils.bconcat(bufs: any[]): any;Usage Examples:
const CFB = require('cfb');
// Prepare binary data for processing
const rawData = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
const preparedBlob = CFB.utils.prep_blob(rawData);
// Concatenate multiple data sources
const part1 = Buffer.from([0x01, 0x02]);
const part2 = Buffer.from([0x03, 0x04]);
const combined = CFB.utils.bconcat([part1, part2]);
// Validate field data
try {
CFB.utils.CheckField('CAFEBABE', 'MagicNumber');
console.log('Field validation passed');
} catch (error) {
console.log('Field validation failed:', error.message);
}Configure compression support for certain CFB operations.
/**
* Configure zlib instance for compression operations
* @param zlib - zlib implementation to use
*/
CFB.utils.use_zlib(zlib: any): void;
/**
* Raw deflate compression
* @param data - Data to compress
* @returns Compressed data
*/
CFB.utils._deflateRaw(data: any): any;
/**
* Raw inflate decompression
* @param payload - Compressed data to decompress
* @param usz - Uncompressed size hint
* @returns Decompressed data
*/
CFB.utils._inflateRaw(payload: any, usz: number): any;Usage Examples:
const CFB = require('cfb');
const zlib = require('zlib');
// Configure zlib for compression
CFB.utils.use_zlib(zlib);
// Example of working with compressed data (advanced usage)
const largeData = Buffer.alloc(10000, 'A');
try {
const compressed = CFB.utils._deflateRaw(largeData);
console.log('Compressed size:', compressed.length);
const decompressed = CFB.utils._inflateRaw(compressed, largeData.length);
console.log('Decompression successful:', decompressed.length === largeData.length);
} catch (error) {
console.log('Compression operation failed:', error.message);
}Access to CFB format constants for advanced operations.
/**
* CFB format constants
*/
CFB.utils.consts: {
MAXREGSECT: number;
DIFSECT: number;
FATSECT: number;
ENDOFCHAIN: number;
FREESECT: number;
HEADER_SIGNATURE: string;
HEADER_MINOR_VERSION: string;
MAXREGSID: number;
NOSTREAM: number;
HEADER_CLSID: string;
EntryTypes: string[];
};Usage Examples:
const CFB = require('cfb');
// Access CFB constants
const constants = CFB.utils.consts;
console.log('CFB signature:', constants.HEADER_SIGNATURE);
console.log('Entry types:', constants.EntryTypes);
// Use constants for validation or analysis
const cfb = CFB.read('document.cfb', { type: 'file' });
cfb.FileIndex.forEach((entry, index) => {
const typeName = constants.EntryTypes[entry.type] || 'unknown';
console.log(`${cfb.FullPaths[index]}: ${typeName}`);
});Here's a comprehensive example showing the full lifecycle of CFB container manipulation:
const CFB = require('cfb');
const fs = require('fs');
// 1. Create new container
console.log('Creating new CFB container...');
const cfb = CFB.utils.cfb_new();
// 2. Add various types of content
console.log('Adding content...');
CFB.utils.cfb_add(cfb, 'Document/Main', 'This is the main document content');
CFB.utils.cfb_add(cfb, 'Document/Metadata', JSON.stringify({
title: 'My Document',
author: 'John Doe',
created: new Date().toISOString()
}));
// 3. Add binary data
const imageData = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
CFB.utils.cfb_add(cfb, 'Assets/logo.png', imageData);
// 4. Save initial version
CFB.writeFile(cfb, 'document-v1.cfb');
console.log('Saved version 1');
// 5. Make modifications
console.log('Making modifications...');
CFB.utils.cfb_add(cfb, 'Document/Changelog', 'v1.1: Added new features');
CFB.utils.cfb_mov(cfb, 'Assets/logo.png', 'Assets/Images/logo.png');
CFB.utils.cfb_del(cfb, 'Document/Metadata'); // Remove old metadata
// 6. Add new metadata
const newMetadata = {
title: 'My Document',
author: 'John Doe',
version: '1.1',
modified: new Date().toISOString()
};
CFB.utils.cfb_add(cfb, 'Document/Info', JSON.stringify(newMetadata));
// 7. Optimize container
console.log('Optimizing container...');
CFB.utils.cfb_gc(cfb);
// 8. Save final version
CFB.writeFile(cfb, 'document-v2.cfb');
console.log('Saved version 2');
// 9. Verify contents
console.log('Final container contents:');
cfb.FullPaths.forEach((path, index) => {
const entry = cfb.FileIndex[index];
if (entry.type === 2) { // streams only
console.log(`- ${path} (${entry.size} bytes)`);
}
});