d_define_method(stream, seek)(struct s_object *self, off_t offset, enum e_stream_seek whence, off_t *moved) { d_using(stream); int whence_local = SEEK_SET; off_t moved_local; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { switch (whence) { case e_stream_seek_begin: whence_local = SEEK_SET; break; case e_stream_seek_current: whence_local = SEEK_CUR; break; case e_stream_seek_end: whence_local = SEEK_END; break; default: d_throw(v_exception_malformed, "malformed whence format exception"); } moved_local = lseek(stream_attributes->descriptor, offset, whence_local); if (moved) *moved = moved_local; } else d_throw(v_exception_closed, "read in a closed stream exception"); return self; }
d_define_method(fonts, add_font)(struct s_object *self, unsigned int id, struct s_object *stream, int size) { d_using(fonts); struct s_stream_attributes *stream_attributes = d_cast(stream, stream); char buffer[d_string_buffer_size]; SDL_RWops *font_block; if (fonts_attributes->fonts[id].font) { TTF_CloseFont(fonts_attributes->fonts[id].font); munmap(fonts_attributes->fonts[id].font_block, fonts_attributes->fonts[id].file_stats.st_size); } fstat(stream_attributes->descriptor, &(fonts_attributes->fonts[id].file_stats)); if ((fonts_attributes->fonts[id].font_block = mmap(NULL, fonts_attributes->fonts[id].file_stats.st_size, PROT_READ, MAP_SHARED, stream_attributes->descriptor, 0)) != MAP_FAILED) { font_block = SDL_RWFromMem(fonts_attributes->fonts[id].font_block, fonts_attributes->fonts[id].file_stats.st_size); if (!(fonts_attributes->fonts[id].font = TTF_OpenFontRW(font_block, d_true, size))) { munmap(fonts_attributes->fonts[id].font_block, fonts_attributes->fonts[id].file_stats.st_size); snprintf(buffer, d_string_buffer_size, "ungenerable TTF for font %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_ttf, buffer); } } else { snprintf(buffer, d_string_buffer_size, "wrong type for file %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_wrong_type, buffer); } return self; }
struct s_object *f_track_new_channel(struct s_object *self, struct s_object *stream, int channel) { struct s_track_attributes *attributes = p_track_alloc(self); struct s_stream_attributes *stream_attributes = d_cast(stream, stream); char *memblock, buffer[d_string_buffer_size]; struct stat file_stats; SDL_RWops *tracked_block; if (attributes->chunk) Mix_FreeChunk(attributes->chunk); fstat(stream_attributes->descriptor, &file_stats); if ((memblock = mmap(NULL, file_stats.st_size, PROT_READ, MAP_SHARED, stream_attributes->descriptor, 0)) != MAP_FAILED) { tracked_block = SDL_RWFromMem(memblock, file_stats.st_size); if ((attributes->chunk = Mix_LoadWAV_RW(tracked_block, d_true))) { if ((attributes->channel = channel) == d_track_auto_channel) attributes->auto_channel = d_true; attributes->next_channel = channel; attributes->volume = d_track_default_volume; } else { snprintf(buffer, d_string_buffer_size, "unable to retrieve information for track %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_chunk, buffer); } munmap(memblock, file_stats.st_size); } else { snprintf(buffer, d_string_buffer_size, "wrong type for file %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_wrong_type, buffer); } return self; }
struct s_object *f_stream_new_file(struct s_object *self, struct s_object *string_name, const char *action, int permission) { struct s_stream_attributes *attributes = p_stream_alloc(self); char buffer[d_string_buffer_size]; attributes->string_name = d_retain(string_name); attributes->parameters = -1; switch(action[0]) { case 'r': case 'R': attributes->parameters = d_stream_flag_read; if ((action[1] == 'w') || (action[1] == 'W')) attributes->parameters = d_stream_flag_write_read; break; case 'w': case 'W': attributes->parameters = d_stream_flag_truncate; if ((action[1] == 'a') || (action[1] == 'A')) attributes->parameters = d_stream_flag_append; } if (attributes->parameters != -1) { if ((attributes->descriptor = open(d_string_cstring(attributes->string_name), attributes->parameters, permission)) > -1) attributes->flags = e_stream_flag_opened; else { snprintf(buffer, d_string_buffer_size, "unreachable file %s exception", d_string_cstring(attributes->string_name)); d_throw(v_exception_unreachable, buffer); } } else d_throw(v_exception_malformed, "malformed action format"); return self; }
d_define_method(label, update_texture)(struct s_object *self, TTF_Font *font, struct s_object *environment) { d_using(label); char buffer[d_string_buffer_size]; int width, height; struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_uiable_attributes *uiable_attributes = d_cast(self, uiable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); TTF_Font *current_font; SDL_Surface *unoptimized_surface; SDL_Color white = { 255, 255, 255, 255 }; if (label_attributes->image) { SDL_DestroyTexture(label_attributes->image); label_attributes->image = NULL; } if ((current_font = font) || (current_font = label_attributes->last_font)) { label_attributes->last_font = current_font; if (f_string_strlen(label_attributes->string_content) > 0) { if ((unoptimized_surface = TTF_RenderText_Blended(current_font, label_attributes->string_content, white))) { label_attributes->image = SDL_CreateTextureFromSurface(environment_attributes->renderer, unoptimized_surface); if (SDL_QueryTexture(label_attributes->image, NULL, NULL, &width, &height) == 0) { label_attributes->string_width = width; label_attributes->string_height = height; if (label_attributes->format == e_label_background_format_adaptable) { label_attributes->last_width = width + (uiable_attributes->border_w * 2.0); label_attributes->last_height = height + (uiable_attributes->border_h * 2.0); } d_call(&(drawable_attributes->point_dimension), m_point_set_x, (double)label_attributes->last_width); d_call(&(drawable_attributes->point_dimension), m_point_set_y, (double)label_attributes->last_height); if (label_attributes->last_blend != e_drawable_blend_undefined) d_call(self, m_drawable_set_blend, label_attributes->last_blend); d_call(self, m_drawable_set_maskRGB, (unsigned int)label_attributes->last_mask_R, (unsigned int)label_attributes->last_mask_G, (unsigned int)label_attributes->last_mask_B); d_call(self, m_drawable_set_maskA, (unsigned int)label_attributes->last_mask_A); } else { snprintf(buffer, d_string_buffer_size, "unable to retrieve informations for label \"%s\" exception", label_attributes->string_content); d_throw(v_exception_texture, buffer); } SDL_FreeSurface(unoptimized_surface); } else { snprintf(buffer, d_string_buffer_size, "ungenerable texture for label \"%s\" exception", label_attributes->string_content); d_throw(v_exception_texture, buffer); } } } else { snprintf(buffer, d_string_buffer_size, "ungenerable texture for label \"%s\" with missing font exception", label_attributes->string_content); d_throw(v_exception_texture, buffer); } d_call(self, m_emitter_raise, v_uiable_signals[e_uiable_signal_content_changed]); return self; }
d_define_method(stream, read)(struct s_object *self, unsigned char *buffer, size_t size, size_t *readed) { d_using(stream); size_t readed_local; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { if (((stream_attributes->parameters&O_RDWR) == O_RDWR) || ((stream_attributes->parameters&O_RDONLY) == O_RDONLY)) { readed_local = read(stream_attributes->descriptor, buffer, size); if (readed) *readed = readed_local; } else d_throw(v_exception_unsupported, "read in a write-only stream exception"); } else d_throw(v_exception_closed, "read in a closed stream exception"); return self; }
d_define_method(stream, write)(struct s_object *self, unsigned char *raw, size_t size, size_t *written) { d_using(stream); size_t written_local; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { if (((stream_attributes->parameters&O_RDWR) == O_RDWR) || ((stream_attributes->parameters&O_WRONLY) == O_WRONLY)) { written_local = write(stream_attributes->descriptor, raw, size); if (written) *written = written_local; } else d_throw(v_exception_unsupported, "write in a read-only stream exception"); } else d_throw(v_exception_closed, "write in a closed stream exception"); return self; }
void p_dictionary_delete(struct o_object *object) { struct o_dictionary *local_object; struct o_array *keys; struct o_object *key; struct s_hash_bucket current; size_t index; if ((local_object = d_object_kind(object, dictionary))) { if ((keys = local_object->m_keys(local_object))) { for (index = 0; index < keys->size; index++) if ((key = keys->m_get(keys, index))) { f_hash_delete(local_object->table, key, ¤t); if (current.kind != e_hash_kind_empty) { if (current.key) d_release(current.key); if (current.value) d_release(current.value); memset(¤t, 0, sizeof(struct s_hash_bucket)); } } d_release(keys); } f_hash_destroy(&(local_object->table)); } else d_throw(v_exception_kind, "object is not an instance of o_dictionary"); }
d_define_method(stream, size)(struct s_object *self, size_t *size) { d_using(stream); off_t offset, current_offset; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { if (((stream_attributes->parameters&O_RDWR) == O_RDWR) || ((stream_attributes->parameters&O_RDONLY) == O_RDONLY)) { d_call(self, m_stream_seek, 0, e_stream_seek_current, ¤t_offset); d_call(self, m_stream_seek, 0, e_stream_seek_begin, NULL); d_call(self, m_stream_seek, 0, e_stream_seek_end, &offset); if (size) *size = (size_t)offset; d_call(self, m_stream_seek, current_offset, e_stream_seek_begin); } else d_throw(v_exception_unsupported, "read in a write-only stream exception"); } else d_throw(v_exception_closed, "read in a closed stream exception"); return self; }
d_define_method(label, set_content)(struct s_object *self, struct s_object *string_content, TTF_Font *font, struct s_object *environment) { d_using(label); struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); char buffer[d_string_buffer_size]; int width, height; SDL_Surface *unoptimized_surface; SDL_Color white = { 255, 255, 255, 255 }; if (label_attributes->string_content) d_delete(label_attributes->string_content); label_attributes->string_content = d_retain(string_content); if (label_attributes->image) SDL_DestroyTexture(label_attributes->image); if ((unoptimized_surface = TTF_RenderText_Blended(font, d_string_cstring(string_content), white))) { label_attributes->image = SDL_CreateTextureFromSurface(environment_attributes->renderer, unoptimized_surface); if (SDL_QueryTexture(label_attributes->image, NULL, NULL, &width, &height) == 0) { d_call(&(drawable_attributes->point_dimension), m_point_set_x, (double)width); d_call(&(drawable_attributes->point_dimension), m_point_set_y, (double)height); d_call(&(drawable_attributes->point_center), m_point_set_x, (double)(width/2.0)); d_call(&(drawable_attributes->point_center), m_point_set_y, (double)(height/2.0)); if (label_attributes->last_blend != e_drawable_blend_undefined) d_call(self, m_drawable_set_blend, label_attributes->last_blend); d_call(self, m_drawable_set_maskRGB, (unsigned int)label_attributes->last_mask_R, (unsigned int)label_attributes->last_mask_G, (unsigned int)label_attributes->last_mask_B); d_call(self, m_drawable_set_maskA, (unsigned int)label_attributes->last_mask_A); } else { snprintf(buffer, d_string_buffer_size, "unable to retrieve informations for label \"%s\" exception", d_string_cstring(string_content)); d_throw(v_exception_texture, buffer); } SDL_FreeSurface(unoptimized_surface); } else { snprintf(buffer, d_string_buffer_size, "ungenerable texture for label \"%s\" exception", d_string_cstring(string_content)); d_throw(v_exception_texture, buffer); } return self; }
struct s_object *f_bitmap_new(struct s_object *self, struct s_object *stream, struct s_object *environment) { struct s_bitmap_attributes *attributes = p_bitmap_alloc(self); struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_stream_attributes *stream_attributes = d_cast(stream, stream); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); char *memblock, buffer[d_string_buffer_size]; struct stat file_stats; int width, height; SDL_RWops *surfaced_block; SDL_Surface *unoptimized_surface; fstat(stream_attributes->descriptor, &file_stats); if ((memblock = mmap(NULL, file_stats.st_size, PROT_READ, MAP_SHARED, stream_attributes->descriptor, 0)) != MAP_FAILED) { surfaced_block = SDL_RWFromMem(memblock, file_stats.st_size); if ((unoptimized_surface = IMG_Load_RW(surfaced_block, d_true))) { attributes->image = SDL_CreateTextureFromSurface(environment_attributes->renderer, unoptimized_surface); if (SDL_QueryTexture(attributes->image, NULL, NULL, &width, &height) == 0) { d_call(&(drawable_attributes->point_dimension), m_point_set_x, (double)width); d_call(&(drawable_attributes->point_dimension), m_point_set_y, (double)height); d_call(&(drawable_attributes->point_center), m_point_set_x, (double)(width/2.0)); d_call(&(drawable_attributes->point_center), m_point_set_y, (double)(height/2.0)); } else { snprintf(buffer, d_string_buffer_size, "unable to retrieve informations for bitmap %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_texture, buffer); } } else { snprintf(buffer, d_string_buffer_size, "ungenerable texture for bitmap %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_texture, buffer); } SDL_FreeSurface(unoptimized_surface); munmap(memblock, file_stats.st_size); } else { snprintf(buffer, d_string_buffer_size, "wrong type for file %s exception", d_string_cstring(stream_attributes->string_name)); d_throw(v_exception_wrong_type, buffer); } return self; }
const struct s_method *p_object_recall(const char *file, int line, struct s_object *object, const char *symbol, const char *type) { struct s_virtual_table *singleton; char buffer[d_string_buffer_size]; struct s_method_cache swap_cache; const struct s_method *result = NULL; int index; if ((object->cache_calls.first.type == type) && (object->cache_calls.first.entry->symbol == symbol)) result = object->cache_calls.first.entry; else if ((object->cache_calls.second.type == type) && (object->cache_calls.second.entry->symbol == symbol)) { swap_cache = object->cache_calls.first; object->cache_calls.first = object->cache_calls.second; object->cache_calls.second = swap_cache; result = object->cache_calls.first.entry; } else { d_reverse_foreach(&(object->virtual_tables), singleton, struct s_virtual_table) { if ((type == v_undefined_type) || (type == singleton->type)) for (index = 0; singleton->virtual_table[index].symbol; ++index) if (singleton->virtual_table[index].symbol == symbol) { object->cache_calls.second = object->cache_calls.first; object->cache_calls.first.type = type; object->cache_calls.first.entry = &(singleton->virtual_table[index]); result = object->cache_calls.first.entry; } if (result) break; } } if (result) { if ((result->flag == e_flag_private) && (result->file != file)) { snprintf(buffer, d_string_buffer_size, "method '%s' is private and you are out of context (%s, %d)", symbol, file, line); d_throw(v_exception_private_method, buffer); } } else { snprintf(buffer, d_string_buffer_size, "symbol '%s' is undefined or it is a member of another class (%s, %d)", symbol, file, line); d_throw(v_exception_undefined_method, buffer); } return result; }
struct s_object *f_stream_new_temporary(struct s_object *self, struct s_object *string_name) { struct s_stream_attributes *attributes = p_stream_alloc(self); char file_name[] = "magrathea_XXXXXX.tmp"; attributes->string_name = d_retain(string_name); attributes->parameters = d_stream_flag_write_read; /* (from man): [...] the last six characters of template must be "XXXXXX" and these are replaced with a string that makes the filename unique. * Since it will be modified, template must not be a string constant, but should be declared as a character array. */ if ((attributes->descriptor = mkstemp(file_name)) >= 0) attributes->flags = (e_stream_flag_temporary|e_stream_flag_opened); else d_throw(v_exception_unreachable, "unreachable temporary file exception"); return self; }
d_define_method(stream, read_string)(struct s_object *self, struct s_object *string_supplied, size_t size) { d_using(stream); struct s_string_attributes *string_attributes = NULL; char character, buffer[d_stream_block_size]; size_t readed_local = 0; int tail = d_true; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { if (((stream_attributes->parameters&O_RDWR) == O_RDWR) || ((stream_attributes->parameters&O_RDONLY) == O_RDONLY)) { while ((readed_local < size) && (read(stream_attributes->descriptor, &character, 1) > 0)) { tail = d_false; if ((character != '\n') && (character != '\0')) buffer[readed_local++] = character; else break; } if (!tail) { buffer[readed_local] = '\0'; if (!string_supplied) { string_supplied = f_string_new_size(d_new(string), buffer, (readed_local + 1)); } else { string_attributes = d_cast(string_supplied, string); if (string_attributes->size < (readed_local + 1)) { string_attributes->content = d_realloc(string_attributes->content, (readed_local + 1)); string_attributes->length = (readed_local + 1); } strncpy(string_attributes->content, buffer, readed_local); string_attributes->content[readed_local] = '\0'; string_attributes->length = readed_local; } } else string_supplied = NULL; } else d_throw(v_exception_unsupported, "read in a write-only stream exception"); } else d_throw(v_exception_closed, "read in a closed stream exception"); return string_supplied; }
d_define_method(stream, lock)(struct s_object *self, int lock) { d_using(stream); int flags; if ((stream_attributes->flags&e_stream_flag_opened) == e_stream_flag_opened) { flags = fcntl(stream_attributes->descriptor, F_GETFL); if (lock) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (stream_attributes->parameters != flags) if (fcntl(stream_attributes->descriptor, F_SETFL, flags) != -1) stream_attributes->parameters = flags; } else d_throw(v_exception_closed, "read in a closed stream exception"); return self; }
char *p_dictionary_string(struct o_object *object, char *data, size_t size) { struct o_dictionary *local_object; struct o_array *keys; struct o_object *key, *value; char *pointer = data, *next; size_t index, written = 0; if ((local_object = d_object_kind(object, dictionary))) { if (written < size) { *pointer = '{'; if ((++written) < size) pointer++; } if ((keys = local_object->m_keys(local_object))) { for (index = 0; index < keys->size; index++) if ((key = keys->m_get(keys, index))) { next = key->s_delegate.m_string(key, pointer, (size-written)); written += (next-pointer); pointer = next; if (written < size) { *pointer = ':'; if ((++written) < size) { pointer++; if ((value = f_hash_get(local_object->table, key))) { next = value->s_delegate.m_string(value, pointer, (size-written)); written += (next-pointer); pointer = next; if (written < size) { *pointer = ','; if ((++written) < size) pointer++; } } } } } d_release(keys); } if (written < size) { *pointer = '}'; if ((++written) < size) pointer++; } *pointer = '\0'; } else d_throw(v_exception_kind, "object is not an instance of o_dictionary"); return pointer; }
struct o_object *p_dictionary_clone(struct o_object *object) { struct o_dictionary *result = NULL, *local_object; struct o_array *keys; struct o_object *key; size_t index; if ((local_object = d_object_kind(object, dictionary))) { result = (struct o_dictionary *)p_object_clone(object); result->table = NULL; f_hash_init(&(result->table), p_dictionary_compare_hooker, p_dictionary_hash_hooker); if ((keys = local_object->m_keys(local_object))) { for (index = 0; index < keys->size; index++) { key = keys->m_get(keys, index); result->m_insert(result, key, f_hash_get(local_object->table, key)); } d_release(keys); } } else d_throw(v_exception_kind, "object is not an instance of o_dictionary"); return (o_object *)result; }
void check (int l, int r) { if (r < l) d_throw(v_exception_range, "wrong range specified"); }