#AppendBuffer datatype

1 messages · Page 1 of 1 (latest)

bold forum
#

(zig noob here)
Am I doing something wrong with this code ?
It is just a "string" that grows with the append function.
I am having issues finding simple code snippets in the wild.

const AppendBuffer = struct {
  allocator: Allocator,
  buffer: ?[]u8 = null,

  fn init(allocator: Allocator) AppendBuffer {
    return AppendBuffer {
      .allocator = allocator,
    };
  }

  fn append(self: *AppendBuffer, new: []const u8 ) !void {
    if(self.buffer==null){
      self.buffer = try self.allocator.alloc(u8, new.len);
      std.mem.copy(u8, self.buffer.?, new);
    }
    else {
      const len = self.buffer.?.len;
      self.buffer = try self.allocator.realloc(self.buffer.?, self.buffer.?.len+new.len); 
      std.mem.copy(u8, self.buffer.?[len..self.buffer.?.len], new);
    }
  }

  fn deinit(self: *AppendBuffer) void {
    if(self.buffer != null) self.allocator.free(self.buffer.?);
  }
};
olive snow
#

The code seems fine. I don't see any errors in there.
However there are some things you could simplify:

  1. If you initialize your buffer to a zero-length slice like
  buffer: []u8 = &[0]u8{},

then you can remove all the ifs:

  fn append(self: *AppendBuffer, new: []const u8 ) !void {
    self.buffer = try self.allocator.realloc(self.buffer.?, self.buffer.?.len+new.len); 
    std.mem.copy(u8, self.buffer.?[len..self.buffer.?.len], new);
  }

  fn deinit(self: *AppendBuffer) void {
    self.allocator.free(self.buffer.?);
  }

This works because free() and realloc() just ignore zero-length slices.

  1. Why are you even making this yourself? You could use std.ArrayList(u8). It comes with appendSlice which does exactly what you want.