static void S_flush(OutStream *self, OutStreamIVARS *ivars) { UNUSED_VAR(self); if (ivars->file_handle == NULL) { THROW(ERR, "Can't write to a closed OutStream for %o", ivars->path); } if (!FH_Write(ivars->file_handle, ivars->buf, ivars->buf_pos)) { RETHROW(INCREF(Err_get_error())); } ivars->buf_start += ivars->buf_pos; ivars->buf_pos = 0; }
void OutStream_Destroy_IMP(OutStream *self) { OutStreamIVARS *const ivars = OutStream_IVARS(self); if (ivars->file_handle != NULL) { // Inlined flush, ignoring errors. if (ivars->buf_pos) { FH_Write(ivars->file_handle, ivars->buf, ivars->buf_pos); } DECREF(ivars->file_handle); } DECREF(ivars->path); FREEMEM(ivars->buf); SUPER_DESTROY(self, OUTSTREAM); }
static void test_spew_and_slurp(TestBatch *batch) { Obj *dump = S_make_dump(); Folder *folder = (Folder*)RAMFolder_new(NULL); CharBuf *foo = (CharBuf*)ZCB_WRAP_STR("foo", 3); bool_t result = Json_spew_json(dump, folder, foo); TEST_TRUE(batch, result, "spew_json returns true on success"); TEST_TRUE(batch, Folder_Exists(folder, foo), "spew_json wrote file"); Obj *got = Json_slurp_json(folder, foo); TEST_TRUE(batch, got && Obj_Equals(dump, got), "Round trip through spew_json and slurp_json"); DECREF(got); Err_set_error(NULL); result = Json_spew_json(dump, folder, foo); TEST_FALSE(batch, result, "Can't spew_json when file exists"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed spew_json sets Err_error"); Err_set_error(NULL); CharBuf *bar = (CharBuf*)ZCB_WRAP_STR("bar", 3); got = Json_slurp_json(folder, bar); TEST_TRUE(batch, got == NULL, "slurp_json returns NULL when file doesn't exist"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed slurp_json sets Err_error"); CharBuf *boffo = (CharBuf*)ZCB_WRAP_STR("boffo", 5); FileHandle *fh = Folder_Open_FileHandle(folder, boffo, FH_CREATE | FH_WRITE_ONLY); FH_Write(fh, "garbage", 7); DECREF(fh); Err_set_error(NULL); got = Json_slurp_json(folder, boffo); TEST_TRUE(batch, got == NULL, "slurp_json returns NULL when file doesn't contain valid JSON"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed slurp_json sets Err_error"); DECREF(got); DECREF(dump); DECREF(folder); }
static void test_Slurp_File(TestBatch *batch) { Folder *folder = (Folder*)RAMFolder_new(NULL); FileHandle *fh = Folder_Open_FileHandle(folder, &foo, FH_CREATE | FH_WRITE_ONLY); ByteBuf *contents; FH_Write(fh, "stuff", 5); FH_Close(fh); DECREF(fh); contents = Folder_Slurp_File(folder, &foo); TEST_TRUE(batch, BB_Equals_Bytes(contents, "stuff", 5), "Slurp_File"); DECREF(contents); DECREF(folder); }
static CFISH_INLINE void SI_write_bytes(OutStream *self, OutStreamIVARS *ivars, const void *bytes, size_t len) { // If this data is larger than the buffer size, flush and write. if (len >= IO_STREAM_BUF_SIZE) { S_flush(self, ivars); if (!FH_Write(ivars->file_handle, bytes, len)) { RETHROW(INCREF(Err_get_error())); } ivars->buf_start += len; } // If there's not enough room in the buffer, flush then add. else if (ivars->buf_pos + len >= IO_STREAM_BUF_SIZE) { S_flush(self, ivars); memcpy((ivars->buf + ivars->buf_pos), bytes, len); ivars->buf_pos += len; } // If there's room, just add these bytes to the buffer. else { memcpy((ivars->buf + ivars->buf_pos), bytes, len); ivars->buf_pos += len; } }