Generated: 2026-02-16T12:12:34.564677
/* 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;
}
| 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
/// Dynamic buffer implementation for managing growable byte arrays
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 C string (null-terminated)
pub fn as_cstr(&self) -> Option<&std::ffi::CStr> {
if self.data.is_empty() || self.data.last() != Some(&0) {
return None;
}
std::ffi::CStr::from_bytes_with_nul(&self.data).ok()
}
/// Get current buffer contents as byte slice
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
/// Get current buffer contents as string slice if valid UTF-8
pub fn as_str(&self) -> Result<&str, std::str::Utf8Error> {
std::str::from_utf8(&self.data)
}
/// Get current size of buffer
pub fn size(&self) -> usize {
self.data.len()
}
/// Get current capacity of buffer
pub fn capacity(&self) -> usize {
self.data.capacity()
}
}
impl Default for Buffer {
fn default() -> Self {
Self::new(0)
}
}
#[derive(Debug, Clone, Copy, 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 {}
| Dimension | Score | Max | Details |
|---|---|---|---|
| Compilation | 25 | 25 | ✓ Compiles successfully |
| Safety | 2 | 20 | ✗ Heavy unsafe usage (7 blocks) | ✓ Uses Result for error handling | ⚠ Uses raw pointers |
| Quality | 20 | 20 | ✓ Snake_case naming | ✓ Well documented (9 doc comments) | ✓ Uses ? operator | ✓ Functional programming patterns | ✓ 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
use std::alloc::{alloc, dealloc, realloc, Layout};
use std::ffi::{CStr, CString, NulError};
use std::os::raw::c_char;
use std::ptr;
use std::str;
/// Represents a dynamic buffer.
pub struct Buffer {
data: *mut c_char,
size: usize,
capacity: usize,
}
impl Buffer {
/// Initializes a new buffer with an initial capacity.
pub fn new(initial_capacity: usize) -> Result<Self, &'static str> {
let layout = Layout::array::<c_char>(initial_capacity).map_err(|_| "Invalid capacity")?;
let data = unsafe { alloc(layout) as *mut c_char };
if data.is_null() {
return Err("Failed to allocate buffer");
}
unsafe {
data.write(0 as c_char); // Null terminate
}
Ok(Buffer {
data,
size: 0,
capacity: initial_capacity,
})
}
/// Grows the buffer capacity (doubles current capacity, but at least 16).
fn grow(&mut self) -> Result<(), &'static str> {
let new_capacity = std::cmp::max(self.capacity * 2, 16);
let old_layout = Layout::array::<c_char>(self.capacity).map_err(|_| "Invalid capacity")?;
let new_layout = Layout::array::<c_char>(new_capacity).map_err(|_| "Invalid capacity")?;
let new_data = unsafe {
realloc(self.data as *mut u8, old_layout, new_capacity) as *mut c_char
};
if new_data.is_null() {
return Err("Failed to reallocate 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() as *const c_char,
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, str: &str) -> Result<(), &'static str> {
self.append(str.as_bytes())
}
/// Clears the buffer 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) -> *const c_char {
self.data as *const c_char
}
/// Returns the current buffer contents as a Rust String.
pub fn to_string(&self) -> Result<String, str::Utf8Error> {
let c_str = unsafe { CStr::from_ptr(self.c_str()) };
c_str.to_str().map(|s| s.to_string())
}
}
impl Drop for Buffer {
/// Frees the buffer and its data.
fn drop(&mut self) {
if !self.data.is_null() {
let layout = Layout::array::<c_char>(self.capacity).unwrap();
unsafe {
dealloc(self.data as *mut u8, layout);
}
self.data = ptr::null_mut();
self.size = 0;
self.capacity = 0;
}
}
}
| Model | Total | Compilation | Safety | Quality | Correctness | Maintainability | Performance |
|---|---|---|---|---|---|---|---|
| CLAUDE | 77/100 | 25/25 | 18/20 | 14/20 | 7/15 | 3/10 | 10/10 |
| GEMINI | 66/100 | 25/25 | 2/20 | 20/20 | 4/15 | 5/10 | 10/10 |
CELLO evaluates transpilation quality across 6 dimensions:
Total possible score: 100 points