Task 052: .B File Format

Task 052: .B File Format

The ".B" file extension is ambiguous and not associated with a single, well-defined file format with clear specifications. Based on available information, the ".B" extension is linked to multiple uses, such as BASIC source code, Grand Theft Auto III (GTA3) saved game files, BuRg3r definition files, and others, but none provide a standardized specification with intrinsic file system properties. Since no universal ".B" file format specification exists, I’ll assume a hypothetical ".B" file format for this task to fulfill the requirements. This hypothetical format will be a simple binary format with a defined structure, as this is a common approach for custom file formats.

Hypothetical .B File Format Specification

For the purpose of this task, let’s define the ".B" file format as a binary file with the following structure:

  • Header (8 bytes):
  • Magic Number (4 bytes): ASCII "BFRM" (identifies the file as a .B file).
  • Version (4 bytes): 32-bit integer representing the format version (e.g., 1).
  • Metadata Section:
  • File Size (4 bytes): 32-bit integer indicating total file size in bytes.
  • Creation Timestamp (8 bytes): 64-bit integer (Unix epoch time in seconds).
  • Author Name (32 bytes): UTF-8 encoded string, padded with null bytes if shorter.
  • Data Section:
  • Data Length (4 bytes): 32-bit integer indicating the length of the data payload.
  • Data Payload (variable length): Raw binary data.

Intrinsic File System Properties:

  1. File Extension: .B
  2. File Size: Total size in bytes, stored in the metadata section.
  3. Creation Timestamp: Unix epoch time when the file was created.
  4. Author Name: UTF-8 string (up to 32 characters) identifying the file’s author.
  5. Data Length: Size of the data payload in bytes.
  6. Data Payload: The actual content stored in the file.

Below are implementations in Python, Java, JavaScript, and C to handle this hypothetical .B file format, including reading, writing, and printing the properties.


1. List of Properties Intrinsic to the .B File Format

  • File Extension: .B (identifies the file type).
  • File Size: Total size of the file in bytes (stored in metadata).
  • Creation Timestamp: 64-bit Unix epoch time of file creation.
  • Author Name: UTF-8 string (up to 32 characters) for the author.
  • Data Length: Length of the data payload in bytes.
  • Data Payload: Variable-length binary data.

2. Python Class for .B File Format

import struct
import time

class BFile:
    def __init__(self, filename):
        self.filename = filename
        self.magic = b"BFRM"
        self.version = 1
        self.file_size = 0
        self.creation_timestamp = 0
        self.author_name = ""
        self.data_length = 0
        self.data_payload = b""

    def read(self):
        try:
            with open(self.filename, "rb") as f:
                # Read header
                header = f.read(8)
                if len(header) != 8:
                    raise ValueError("Invalid file size")
                magic, self.version = struct.unpack(">4sI", header)
                if magic != self.magic:
                    raise ValueError("Invalid .B file: incorrect magic number")

                # Read metadata
                metadata = f.read(44)  # 4 + 8 + 32
                if len(metadata) != 44:
                    raise ValueError("Invalid metadata section")
                self.file_size, self.creation_timestamp = struct.unpack(">IQ", metadata[:12])
                self.author_name = metadata[12:44].decode("utf-8").rstrip("\x00")

                # Read data section
                self.data_length = struct.unpack(">I", f.read(4))[0]
                self.data_payload = f.read(self.data_length)
                if len(self.data_payload) != self.data_length:
                    raise ValueError("Incomplete data payload")
        except Exception as e:
            print(f"Error reading .B file: {e}")

    def write(self, author_name, data_payload):
        try:
            with open(self.filename, "wb") as f:
                # Write header
                f.write(struct.pack(">4sI", self.magic, self.version))

                # Write metadata
                self.creation_timestamp = int(time.time())
                self.author_name = author_name[:32].ljust(32, "\x00")
                self.data_payload = data_payload.encode() if isinstance(data_payload, str) else data_payload
                self.data_length = len(self.data_payload)
                self.file_size = 8 + 44 + 4 + self.data_length
                f.write(struct.pack(">IQ", self.file_size, self.creation_timestamp))
                f.write(self.author_name.encode("utf-8")[:32])

                # Write data section
                f.write(struct.pack(">I", self.data_length))
                f.write(self.data_payload)
        except Exception as e:
            print(f"Error writing .B file: {e}")

    def print_properties(self):
        print(f"File Extension: .B")
        print(f"File Size: {self.file_size} bytes")
        print(f"Creation Timestamp: {self.creation_timestamp}")
        print(f"Author Name: {self.author_name}")
        print(f"Data Length: {self.data_length} bytes")
        print(f"Data Payload: {self.data_payload[:100]}")  # Truncate for readability

# Example usage
if __name__ == "__main__":
    bfile = BFile("example.b")
    bfile.write("John Doe", "Sample data for .B file")
    bfile.read()
    bfile.print_properties()

3. Java Class for .B File Format

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class BFile {
    private String filename;
    private final byte[] magic = "BFRM".getBytes();
    private int version = 1;
    private int fileSize = 0;
    private long creationTimestamp = 0;
    private String authorName = "";
    private int dataLength = 0;
    private byte[] dataPayload = new byte[0];

    public BFile(String filename) {
        this.filename = filename;
    }

    public void read() {
        try (DataInputStream dis = new DataInputStream(new FileInputStream(filename))) {
            // Read header
            byte[] header = new byte[8];
            dis.readFully(header);
            byte[] magicRead = Arrays.copyOfRange(header, 0, 4);
            if (!Arrays.equals(magicRead, magic)) {
                throw new IOException("Invalid .B file: incorrect magic number");
            }
            version = dis.readInt();

            // Read metadata
            fileSize = dis.readInt();
            creationTimestamp = dis.readLong();
            byte[] authorBytes = new byte[32];
            dis.readFully(authorBytes);
            authorName = new String(authorBytes, StandardCharsets.UTF_8).trim();

            // Read data section
            dataLength = dis.readInt();
            dataPayload = new byte[dataLength];
            dis.readFully(dataPayload);
        } catch (IOException e) {
            System.err.println("Error reading .B file: " + e.getMessage());
        }
    }

    public void write(String authorName, byte[] dataPayload) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(filename))) {
            // Write header
            dos.write(magic);
            dos.writeInt(version);

            // Write metadata
            creationTimestamp = System.currentTimeMillis() / 1000;
            this.authorName = authorName.length() > 32 ? authorName.substring(0, 32) : authorName;
            this.dataPayload = dataPayload;
            dataLength = dataPayload.length;
            fileSize = 8 + 44 + 4 + dataLength;
            dos.writeInt(fileSize);
            dos.writeLong(creationTimestamp);
            byte[] authorBytes = this.authorName.getBytes(StandardCharsets.UTF_8);
            byte[] paddedAuthor = Arrays.copyOf(authorBytes, 32);
            dos.write(paddedAuthor);

            // Write data section
            dos.writeInt(dataLength);
            dos.write(dataPayload);
        } catch (IOException e) {
            System.err.println("Error writing .B file: " + e.getMessage());
        }
    }

    public void printProperties() {
        System.out.println("File Extension: .B");
        System.out.println("File Size: " + fileSize + " bytes");
        System.out.println("Creation Timestamp: " + creationTimestamp);
        System.out.println("Author Name: " + authorName);
        System.out.println("Data Length: " + dataLength + " bytes");
        System.out.println("Data Payload: " + new String(dataPayload, StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        BFile bfile = new BFile("example.b");
        bfile.write("John Doe", "Sample data for .B file".getBytes());
        bfile.read();
        bfile.printProperties();
    }
}

4. JavaScript Class for .B File Format

const fs = require('fs').promises;

class BFile {
    constructor(filename) {
        this.filename = filename;
        this.magic = Buffer.from('BFRM');
        this.version = 1;
        this.fileSize = 0;
        this.creationTimestamp = 0;
        this.authorName = '';
        this.dataLength = 0;
        this.dataPayload = Buffer.alloc(0);
    }

    async read() {
        try {
            const data = await fs.readFile(this.filename);
            const buffer = Buffer.from(data);

            // Read header
            if (buffer.length < 8) throw new Error('Invalid file size');
            const magic = buffer.slice(0, 4);
            if (!magic.equals(this.magic)) throw new Error('Invalid .B file: incorrect magic number');
            this.version = buffer.readUInt32BE(4);

            // Read metadata
            if (buffer.length < 52) throw new Error('Invalid metadata section');
            this.fileSize = buffer.readUInt32BE(8);
            this.creationTimestamp = Number(buffer.readBigUInt64BE(12));
            this.authorName = buffer.slice(20, 52).toString('utf8').replace(/\x00/g, '');

            // Read data section
            this.dataLength = buffer.readUInt32BE(52);
            this.dataPayload = buffer.slice(56, 56 + this.dataLength);
            if (this.dataPayload.length !== this.dataLength) throw new Error('Incomplete data payload');
        } catch (e) {
            console.error(`Error reading .B file: ${e.message}`);
        }
    }

    async write(authorName, dataPayload) {
        try {
            const buffer = Buffer.alloc(56 + dataPayload.length);
            // Write header
            this.magic.copy(buffer, 0);
            buffer.writeUInt32BE(this.version, 4);

            // Write metadata
            this.creationTimestamp = Math.floor(Date.now() / 1000);
            this.authorName = authorName.slice(0, 32).padEnd(32, '\x00');
            this.dataPayload = Buffer.isBuffer(dataPayload) ? dataPayload : Buffer.from(dataPayload);
            this.dataLength = this.dataPayload.length;
            this.fileSize = 8 + 44 + 4 + this.dataLength;
            buffer.writeUInt32BE(this.fileSize, 8);
            buffer.writeBigUInt64BE(BigInt(this.creationTimestamp), 12);
            Buffer.from(this.authorName, 'utf8').copy(buffer, 20);

            // Write data section
            buffer.writeUInt32BE(this.dataLength, 52);
            this.dataPayload.copy(buffer, 56);

            await fs.writeFile(this.filename, buffer);
        } catch (e) {
            console.error(`Error writing .B file: ${e.message}`);
        }
    }

    printProperties() {
        console.log('File Extension: .B');
        console.log(`File Size: ${this.fileSize} bytes`);
        console.log(`Creation Timestamp: ${this.creationTimestamp}`);
        console.log(`Author Name: ${this.authorName}`);
        console.log(`Data Length: ${this.dataLength} bytes`);
        console.log(`Data Payload: ${this.dataPayload.toString('utf8')}`);
    }
}

// Example usage
(async () => {
    const bfile = new BFile('example.b');
    await bfile.write('John Doe', 'Sample data for .B file');
    await bfile.read();
    bfile.printProperties();
})();

5. C Class for .B File Format

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define AUTHOR_NAME_SIZE 32

typedef struct {
    char* filename;
    char magic[4];
    unsigned int version;
    unsigned int file_size;
    unsigned long long creation_timestamp;
    char author_name[AUTHOR_NAME_SIZE];
    unsigned int data_length;
    unsigned char* data_payload;
} BFile;

void bfile_init(BFile* bfile, const char* filename) {
    bfile->filename = strdup(filename);
    memcpy(bfile->magic, "BFRM", 4);
    bfile->version = 1;
    bfile->file_size = 0;
    bfile->creation_timestamp = 0;
    memset(bfile->author_name, 0, AUTHOR_NAME_SIZE);
    bfile->data_length = 0;
    bfile->data_payload = NULL;
}

void bfile_free(BFile* bfile) {
    free(bfile->filename);
    free(bfile->data_payload);
}

int bfile_read(BFile* bfile) {
    FILE* fp = fopen(bfile->filename, "rb");
    if (!fp) {
        printf("Error opening file: %s\n", bfile->filename);
        return 1;
    }

    // Read header
    char magic[4];
    if (fread(magic, 1, 4, fp) != 4 || memcmp(magic, bfile->magic, 4) != 0) {
        printf("Invalid .B file: incorrect magic number\n");
        fclose(fp);
        return 1;
    }
    if (fread(&bfile->version, sizeof(unsigned int), 1, fp) != 1) {
        printf("Error reading version\n");
        fclose(fp);
        return 1;
    }

    // Read metadata
    if (fread(&bfile->file_size, sizeof(unsigned int), 1, fp) != 1 ||
        fread(&bfile->creation_timestamp, sizeof(unsigned long long), 1, fp) != 1 ||
        fread(bfile->author_name, 1, AUTHOR_NAME_SIZE, fp) != AUTHOR_NAME_SIZE) {
        printf("Error reading metadata\n");
        fclose(fp);
        return 1;
    }
    bfile->author_name[AUTHOR_NAME_SIZE - 1] = '\0';

    // Read data section
    if (fread(&bfile->data_length, sizeof(unsigned int), 1, fp) != 1) {
        printf("Error reading data length\n");
        fclose(fp);
        return 1;
    }
    bfile->data_payload = malloc(bfile->data_length);
    if (!bfile->data_payload || fread(bfile->data_payload, 1, bfile->data_length, fp) != bfile->data_length) {
        printf("Error reading data payload\n");
        free(bfile->data_payload);
        fclose(fp);
        return 1;
    }

    fclose(fp);
    return 0;
}

int bfile_write(BFile* bfile, const char* author_name, const unsigned char* data_payload, unsigned int data_length) {
    FILE* fp = fopen(bfile->filename, "wb");
    if (!fp) {
        printf("Error opening file: %s\n", bfile->filename);
        return 1;
    }

    // Write header
    fwrite(bfile->magic, 1, 4, fp);
    fwrite(&bfile->version, sizeof(unsigned int), 1, fp);

    // Write metadata
    bfile->creation_timestamp = (unsigned long long)time(NULL);
    bfile->data_length = data_length;
    bfile->file_size = 8 + 44 + 4 + data_length;
    strncpy(bfile->author_name, author_name, AUTHOR_NAME_SIZE);
    bfile->author_name[AUTHOR_NAME_SIZE - 1] = '\0';
    fwrite(&bfile->file_size, sizeof(unsigned int), 1, fp);
    fwrite(&bfile->creation_timestamp, sizeof(unsigned long long), 1, fp);
    fwrite(bfile->author_name, 1, AUTHOR_NAME_SIZE, fp);

    // Write data section
    fwrite(&bfile->data_length, sizeof(unsigned int), 1, fp);
    bfile->data_payload = malloc(data_length);
    memcpy(bfile->data_payload, data_payload, data_length);
    fwrite(bfile->data_payload, 1, data_length, fp);

    fclose(fp);
    return 0;
}

void bfile_print_properties(BFile* bfile) {
    printf("File Extension: .B\n");
    printf("File Size: %u bytes\n", bfile->file_size);
    printf("Creation Timestamp: %llu\n", bfile->creation_timestamp);
    printf("Author Name: %s\n", bfile->author_name);
    printf("Data Length: %u bytes\n", bfile->data_length);
    printf("Data Payload: %.*s\n", bfile->data_length, bfile->data_payload);
}

int main() {
    BFile bfile;
    bfile_init(&bfile, "example.b");
    const char* data = "Sample data for .B file";
    bfile_write(&bfile, "John Doe", (unsigned char*)data, strlen(data));
    bfile_read(&bfile);
    bfile_print_properties(&bfile);
    bfile_free(&bfile);
    return 0;
}

Notes

  • Assumption: Since no standard .B file format exists, I created a hypothetical binary format with a clear structure to demonstrate reading, writing, and printing properties.
  • Error Handling: Each implementation includes basic error handling for file operations and format validation.
  • Cross-Language Consistency: All classes follow the same structure and logic, adapted to language-specific conventions (e.g., struct in C, Buffer in JavaScript).
  • File System Properties: The properties listed are intrinsic to the hypothetical format and stored within the file itself, not relying on external file system metadata.
  • Usage: Each class includes example usage to write a file, read it back, and print the properties.

If you have a specific .B file format in mind (e.g., related to BASIC, GTA3, or another context), please provide more details, and I can tailor the implementations accordingly.