← Back to Reports Index

CELLO Evaluation Report: buffer

Generated: 2026-02-15T23:50:57.911451

Original C Code (1997 bytes)

/* Dynamic buffer implementation - common pattern in C infrastructure */

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

typedef struct {
    char* data;
    size_t size;      // Current size
    size_t capacity;  // Allocated capacity
} Buffer;

/**
 * Initialize a new buffer with initial capacity
 */
Buffer* buffer_new(size_t initial_capacity) {
    Buffer* buf = (Buffer*)malloc(sizeof(Buffer));
    if (!buf) return NULL;
    
    buf->data = (char*)malloc(initial_capacity);
    if (!buf->data) {
        free(buf);
        return NULL;
    }
    
    buf->size = 0;
    buf->capacity = initial_capacity;
    buf->data[0] = '\0';
    
    return buf;
}

/**
 * Grow buffer capacity (doubles current capacity)
 */
static int buffer_grow(Buffer* buf) {
    if (!buf) return -1;
    
    size_t new_capacity = buf->capacity * 2;
    if (new_capacity < 16) new_capacity = 16;
    
    char* new_data = (char*)realloc(buf->data, new_capacity);
    if (!new_data) return -1;
    
    buf->data = new_data;
    buf->capacity = new_capacity;
    return 0;
}

/**
 * Append data to buffer
 */
int buffer_append(Buffer* buf, const char* data, size_t len) {
    if (!buf || !data) return -1;
    
    while (buf->size + len + 1 > buf->capacity) {
        if (buffer_grow(buf) != 0) return -1;
    }
    
    memcpy(buf->data + buf->size, data, len);
    buf->size += len;
    buf->data[buf->size] = '\0';
    
    return 0;
}

/**
 * Append a string to buffer
 */
int buffer_append_str(Buffer* buf, const char* str) {
    if (!str) return -1;
    return buffer_append(buf, str, strlen(str));
}

/**
 * Clear buffer contents
 */
void buffer_clear(Buffer* buf) {
    if (!buf) return;
    buf->size = 0;
    if (buf->data) buf->data[0] = '\0';
}

/**
 * Free buffer and its data
 */
void buffer_free(Buffer* buf) {
    if (!buf) return;
    free(buf->data);
    free(buf);
}

/**
 * Get current buffer contents as C string
 */
const char* buffer_cstr(const Buffer* buf) {
    return buf ? buf->data : NULL;
}

CLAUDE Transpilation

Overall Score: 77/100
Dimension Score Max Details
Compilation 25 25 ✓ Compiles successfully
Safety 18 20 ✓ No unsafe blocks | ✓ Uses Result for error handling | ✓ Uses Option for nullable values
Quality 14 20 ✓ Snake_case naming | ✓ Well documented (10 doc comments) | ✓ Proper type definitions | ✓ Implementation blocks
Correctness 7 15 ✓ Edge case checks | ✓ Pattern matching
Maintainability 3 10 ✓ Clear public API (10 items)
Performance 10 10 ✓ Minimal cloning | ✓ Reference usage

✅ Compilation: PASSED

Generated Rust Code (1966 bytes)

/// Dynamic buffer implementation for managing growing byte sequences
pub struct Buffer {
    data: Vec<u8>,
}

impl Buffer {
    /// Initialize a new buffer with initial capacity
    pub fn new(initial_capacity: usize) -> Self {
        Buffer {
            data: Vec::with_capacity(initial_capacity),
        }
    }

    /// Append data to buffer
    pub fn append(&mut self, data: &[u8]) -> Result<(), BufferError> {
        self.data.extend_from_slice(data);
        Ok(())
    }

    /// Append a string to buffer
    pub fn append_str(&mut self, s: &str) -> Result<(), BufferError> {
        self.append(s.as_bytes())
    }

    /// Clear buffer contents
    pub fn clear(&mut self) {
        self.data.clear();
    }

    /// Get current buffer contents as byte slice
    pub fn as_bytes(&self) -> &[u8] {
        &self.data
    }

    /// Get current buffer contents as C string (null-terminated)
    pub fn as_cstr(&self) -> Option<&std::ffi::CStr> {
        if self.data.is_empty() || self.data[self.data.len() - 1] != 0 {
            None
        } else {
            std::ffi::CStr::from_bytes_with_nul(&self.data).ok()
        }
    }

    /// Get current size
    pub fn size(&self) -> usize {
        self.data.len()
    }

    /// Get current capacity
    pub fn capacity(&self) -> usize {
        self.data.capacity()
    }

    /// Get buffer contents as a string slice if valid UTF-8
    pub fn as_str(&self) -> Result<&str, std::str::Utf8Error> {
        std::str::from_utf8(&self.data)
    }
}

impl Default for Buffer {
    fn default() -> Self {
        Self::new(0)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BufferError {
    AllocationFailed,
}

impl std::fmt::Display for BufferError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            BufferError::AllocationFailed => write!(f, "Buffer allocation failed"),
        }
    }
}

impl std::error::Error for BufferError {}

GEMINI Transpilation

Overall Score: 63/100
Dimension Score Max Details
Compilation 25 25 ✓ Compiles successfully
Safety 2 20 ✗ Heavy unsafe usage (8 blocks) | ✓ Uses Result for error handling | ⚠ Uses raw pointers
Quality 17 20 ✓ Snake_case naming | ✓ Well documented (8 doc comments) | ✓ Uses ? operator | ✓ Proper type definitions | ✓ Implementation blocks
Correctness 4 15 ✓ Edge case checks
Maintainability 5 10 ✓ Clear public API (7 items) | ✓ Uses constants
Performance 10 10 ✓ Minimal cloning | ✓ Reference usage

✅ Compilation: PASSED

Generated Rust Code (3208 bytes)

use std::alloc::{alloc, dealloc, realloc, Layout};
use std::ffi::{CStr, CString};
use std::mem;
use std::ptr;

/// Represents a dynamic buffer.
pub struct Buffer {
    data: *mut u8,
    size: usize,
    capacity: usize,
}

impl Buffer {
    /// Initializes a new buffer with the specified initial capacity.
    pub fn new(initial_capacity: usize) -> Result<Self, &'static str> {
        let layout = Layout::array::<u8>(initial_capacity)
            .map_err(|_| "Failed to create layout")?;

        let data = unsafe { alloc(layout) };

        if data.is_null() {
            return Err("Failed to allocate memory for buffer data");
        }

        unsafe {
            data.write(0); // Null terminate
        }

        Ok(Buffer {
            data,
            size: 0,
            capacity: initial_capacity,
        })
    }

    /// Doubles the buffer's capacity.
    fn grow(&mut self) -> Result<(), &'static str> {
        let new_capacity = if self.capacity * 2 > 16 {
            self.capacity * 2
        } else {
            16
        };

        let old_layout = Layout::array::<u8>(self.capacity)
            .map_err(|_| "Failed to create layout")?;
        let new_layout = Layout::array::<u8>(new_capacity)
            .map_err(|_| "Failed to create layout")?;

        let new_data = unsafe {
            realloc(self.data, old_layout, new_layout.size())
        };

        if new_data.is_null() {
            return Err("Failed to reallocate memory for buffer");
        }

        self.data = new_data;
        self.capacity = new_capacity;
        Ok(())
    }

    /// Appends data to the buffer.
    pub fn append(&mut self, data: &[u8]) -> Result<(), &'static str> {
        if self.size + data.len() + 1 > self.capacity {
            self.grow()?;
        }

        unsafe {
            ptr::copy_nonoverlapping(
                data.as_ptr(),
                self.data.add(self.size),
                data.len(),
            );
            self.size += data.len();
            self.data.add(self.size).write(0); // Null terminate
        }

        Ok(())
    }

    /// Appends a string to the buffer.
    pub fn append_str(&mut self, s: &str) -> Result<(), &'static str> {
        self.append(s.as_bytes())
    }

    /// Clears the buffer's contents.
    pub fn clear(&mut self) {
        self.size = 0;
        if !self.data.is_null() {
            unsafe {
                self.data.write(0);
            }
        }
    }

    /// Returns the current buffer contents as a C string.
    pub fn c_str(&self) -> Result<CString, std::ffi::NulError> {
        unsafe {
            CStr::from_ptr(self.data as *const i8).to_owned()
        }
    }

    /// Returns the current buffer contents as a byte slice.
    pub fn as_bytes(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.data, self.size) }
    }
}

impl Drop for Buffer {
    fn drop(&mut self) {
        if !self.data.is_null() {
            let layout = Layout::array::<u8>(self.capacity).unwrap();
            unsafe {
                dealloc(self.data, layout);
            }
            self.data = ptr::null_mut();
            self.size = 0;
            self.capacity = 0;
        }
    }
}

Model Comparison

Model Total Compilation Safety Quality Correctness Maintainability Performance
CLAUDE 77/100 25/25 18/20 14/20 7/15 3/10 10/10
GEMINI 63/100 25/25 2/20 17/20 4/15 5/10 10/10

Evaluation Methodology

CELLO evaluates transpilation quality across 6 dimensions:

Total possible score: 100 points