static bool types_to_remote_types(char * const p_types[], uint4 p_type_count, char**& r_rtypes) { char **t_rtypes; if (!MCMemoryNewArray(p_type_count * 2, t_rtypes)) return false; for(uint32_t i = 0; i < p_type_count; i++) { uint32_t t_part_count; char **t_parts; if (MCCStringSplit(p_types[i], '|', t_parts, t_part_count)) { if (t_part_count > 0) { MCCStringClone(t_parts[0], t_rtypes[i * 2]); if (t_part_count > 1) MCCStringClone(t_parts[1], t_rtypes[i * 2 + 1]); } MCCStringArrayFree(t_parts, t_part_count); } } r_rtypes = t_rtypes; return true; }
// Should be removed when 'combine by row' and 'combine by column' only differs by the delimiter used, // not by the way the array is handled - any index is fine for combine by row void MCArraysExecCombineByRow(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef &r_string) { MCAutoListRef t_list; MCListCreateMutable(ctxt . GetRowDelimiter(), &t_list); uindex_t t_count = MCArrayGetCount(p_array); combine_array_t t_lisctxt; bool t_success; t_lisctxt . elements = nil; t_lisctxt . index = 0; t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { MCArrayApply(p_array, list_array_elements, &t_lisctxt); qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_array_element); for (int i = 0; i < t_count && t_success; ++i) { MCAutoStringRef t_string; if (ctxt . ConvertToString(t_lisctxt . elements[i] . value, &t_string)) t_success = MCListAppend(*t_list, *t_string); else t_success = false; } MCMemoryDeleteArray(t_lisctxt . elements); } if (t_success && MCListCopyAsString(*t_list, r_string)) return; ctxt . Throw(); }
static bool __MCValueRehashUniqueValues(index_t p_new_item_count) { // Get the current capacity index. uindex_t t_new_capacity_idx; t_new_capacity_idx = s_unique_value_capacity_idx; if (p_new_item_count != 0) { // If we are shrinking we just shrink down to the level needed by the currently // used buckets. if (p_new_item_count < 0) p_new_item_count = 0; // Work out the smallest possible capacity greater than the requested capacity. uindex_t t_new_capacity_req; t_new_capacity_req = s_unique_value_count + p_new_item_count; for(t_new_capacity_idx = 0; t_new_capacity_idx < 64; t_new_capacity_idx++) if (t_new_capacity_req <= __kMCValueHashTableCapacities[t_new_capacity_idx]) break; } // Fetch the old capacity and table. uindex_t t_old_capacity; __MCUniqueValueBucket *t_old_buckets; t_old_capacity = __kMCValueHashTableSizes[s_unique_value_capacity_idx]; t_old_buckets = s_unique_values; // Create the new table. uindex_t t_new_capacity; __MCUniqueValueBucket *t_new_buckets; t_new_capacity = __kMCValueHashTableSizes[t_new_capacity_idx]; if (!MCMemoryNewArray(t_new_capacity, t_new_buckets)) return false; // Update the vars. s_unique_value_capacity_idx = t_new_capacity_idx; s_unique_values = t_new_buckets; // Now rehash the values from the old table. for(uindex_t i = 0; i < t_old_capacity; i++) { if (t_old_buckets[i] . value != UINTPTR_MIN && t_old_buckets[i] . value != UINTPTR_MAX) { uindex_t t_target_slot; t_target_slot = __MCValueFindUniqueValueBucketAfterRehash((__MCValue *)t_old_buckets[i] . value, t_old_buckets[i] . hash); // This assertion should never trigger - something is very wrong if it does! MCAssert(t_target_slot != UINDEX_MAX); s_unique_values[t_target_slot] . hash = t_old_buckets[i] . hash; s_unique_values[t_target_slot] . value = t_old_buckets[i] . value; } } // Delete the old table. MCMemoryDeleteArray(t_old_buckets); // We are done! return true; }
void MCArraysExecCombine(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef p_element_delimiter, MCStringRef p_key_delimiter, MCStringRef& r_string) { bool t_success; t_success = true; uindex_t t_count; t_count = MCArrayGetCount(p_array); MCAutoStringRef t_string; if (t_success) t_success = MCStringCreateMutable(0, &t_string); combine_array_t t_lisctxt; t_lisctxt . elements = nil; if (t_success) t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { t_lisctxt . index = 0; MCArrayApply(p_array, list_array_elements, &t_lisctxt); qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_array_element); for(uindex_t i = 0; i < t_count; i++) { MCAutoStringRef t_value_as_string; t_success = ctxt . ConvertToString(t_lisctxt . elements[i] . value, &t_value_as_string); if (!t_success) break; t_success = (p_key_delimiter == nil || (MCStringAppend(*t_string, MCNameGetString(t_lisctxt . elements[i] . key)) && MCStringAppend(*t_string, p_key_delimiter)))&& MCStringAppend(*t_string, *t_value_as_string) && (i == t_count - 1 || MCStringAppend(*t_string, p_element_delimiter)); if (!t_success) break; } } if (t_success) t_success = MCStringCopy(*t_string, r_string); MCMemoryDeleteArray(t_lisctxt . elements); if (t_success) return; // Throw the current error code (since last library call returned false). ctxt . Throw(); }
bool MCResampledImageRep::LoadImageFrames(MCBitmapFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied) { uindex_t t_src_width, t_src_height; if (!m_source->GetGeometry(t_src_width, t_src_height)) return false; bool t_success = true; MCBitmapFrame *t_frames = nil; uindex_t t_frame_count = 0; t_frame_count = m_source->GetFrameCount(); // IM-2013-07-03: [[ Bug 11018 ]] fail here if the source has no frames t_success = t_frame_count != 0; if (t_success) t_success = MCMemoryNewArray(t_frame_count, t_frames); MCGFloat t_scale; t_scale = MCMax(m_target_width / (float)t_src_width, m_target_height / (float)t_src_height); for (uindex_t i = 0; t_success && i < t_frame_count; i++) { MCBitmapFrame *t_src_frame = nil; t_success = m_source->LockBitmapFrame(i, t_scale, t_src_frame); if (t_success) { t_frames[i].duration = t_src_frame->duration; t_success = MCImageScaleBitmap(t_src_frame->image, m_target_width, m_target_height, INTERPOLATION_BICUBIC, t_frames[i].image); if (t_success) MCImageFlipBitmapInPlace(t_frames[i].image, m_h_flip, m_v_flip); } m_source->UnlockBitmapFrame(i, t_src_frame); } if (t_success) { r_frames = t_frames; r_frame_count = t_frame_count; r_frames_premultiplied = false; } else MCImageFreeFrames(t_frames, t_frame_count); return t_success; }
bool rle_true_encode(const uint4 *sptr, uint4 ssize, uint1 *&dptr, uint4 &dsize) { uint4 osize = ssize + (ssize / 127); uint1 *destptr = nil; if (!MCMemoryNewArray(osize, destptr)) return false; const uint4 *eptr = sptr + ssize / sizeof(uint4); dsize = 0; uint2 run; do { run = 1; if (sptr < (eptr - 1) && *sptr == *(sptr + 1)) { uint4 pixel = *sptr; while (++sptr < eptr && *sptr == pixel && run < 127) run++; destptr[dsize++] = run | 0x80; swap_uint4(&pixel); memcpy(&destptr[dsize], &pixel, sizeof(uint4)); dsize += sizeof(uint4); } else { while (++sptr < (eptr - 1) && *sptr != *(sptr + 1) && run < 127) run++; destptr[dsize++] = (uint1)run; uint2 bytes = run * sizeof(uint4); memcpy(&destptr[dsize], sptr - run, bytes); uint4 *startptr = (uint32_t*)&destptr[dsize]; while (run--) swap_uint4(startptr++); dsize += bytes; } } while (sptr < eptr); if (!MCMemoryReallocate(destptr, dsize, dptr)) { MCMemoryDeleteArray(destptr); return false; } return true; }
static bool WindowsGetModuleFileNameEx(HANDLE p_process, HMODULE p_module, MCStringRef& r_path) { bool t_success; t_success = true; // For some unfathomable reason, it is not possible find out how big a // buffer you might need for a module file name. Instead we loop until // we are sure we have the whole thing. WCHAR *t_path; uint32_t t_path_length; t_path_length = 0; t_path = nil; while(t_success) { t_path_length += 256; MCMemoryDeleteArray(t_path); if (t_success) t_success = MCMemoryNewArray(t_path_length, t_path); DWORD t_result; t_result = 0; if (t_success) { // If the buffer is too small, the result will equal the input // buffer size. t_result = GetModuleFileNameExW(p_process, p_module, t_path, t_path_length); if (t_result == 0) t_success = false; else if (t_result == t_path_length) continue; } if (t_success) break; } if (t_success) t_success = MCStringCreateWithWString(t_path, r_path); MCMemoryDeleteArray(t_path); return t_success; }
bool MCWin32QueryActCtxSettings(const unichar_t *p_settings_name, unichar_t *&r_value) { bool t_success; t_success = true; BOOL t_result; SIZE_T t_size; unichar_t *t_buffer; t_buffer = NULL; uint32_t t_buffer_size; t_buffer_size = 0; t_success = MCWin32QueryActCtxSettingsW(t_result, 0, NULL, NULL, p_settings_name, NULL, 0, &t_size); if (t_success) { DWORD t_error; t_error = GetLastError(); t_success = t_result != FALSE; t_success = t_result == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER; } if (t_success) { t_buffer_size = t_size; t_success = MCMemoryNewArray(t_buffer_size, t_buffer); } if (t_success) t_success = MCWin32QueryActCtxSettingsW(t_result, 0, NULL, NULL, p_settings_name, t_buffer, t_buffer_size, &t_size); if (t_success) t_success = t_result != FALSE; if (t_success) r_value = t_buffer; else MCMemoryDeleteArray(t_buffer); return t_success; }
bool __MCValueInitialize(void) { if (!MCMemoryNewArray(kMCValueTypeCodeList + 1, s_value_pools)) return false; if (!__MCValueCreate(kMCValueTypeCodeNull, kMCNull)) return false; if (!__MCValueCreate(kMCValueTypeCodeBoolean, kMCTrue)) return false; if (!__MCValueCreate(kMCValueTypeCodeBoolean, kMCFalse)) return false; if (!__MCValueRehashUniqueValues(1)) return false; return true; }
// IM-2014-01-29: [[ HiDPI ]] Refactored to handle display info caching in MCUIDC superclass bool MCScreenDC::device_getdisplays(bool p_effective, MCDisplay * &r_displays, uint32_t &r_display_count) { // NOTE: this code assumes that there is only one GdkScreen! GdkScreen *t_screen; t_screen = gdk_display_get_default_screen(dpy); // Get the number of monitors attached to this screen gint t_monitor_count; t_monitor_count = gdk_screen_get_n_monitors(t_screen); // Allocate the list of monitors MCDisplay *t_displays; MCMemoryNewArray(t_monitor_count, t_displays); // Get the geometry of each monitor for (gint i = 0; i < t_monitor_count; i++) { GdkRectangle t_rect; gdk_screen_get_monitor_geometry(t_screen, i, &t_rect); MCRectangle t_mc_rect; t_mc_rect = MCRectangleMake(t_rect.x, t_rect.y, t_rect.width, t_rect.height); t_displays[i].index = i; t_displays[i].pixel_scale = 1.0; t_displays[i].viewport = t_displays[i].workarea = t_mc_rect; } if (t_monitor_count == 1) { apply_workarea(t_displays, t_monitor_count) || apply_partial_struts(t_displays, t_monitor_count); } else { apply_partial_struts(t_displays, t_monitor_count); } // All done r_displays = t_displays; r_display_count = t_monitor_count; return true; }
bool MCSessionReadIndex(MCSessionIndexRef p_index) { bool t_success = true; t_success = read_uint32(p_index->file, p_index->session_count); if (t_success) t_success = MCMemoryNewArray(p_index->session_count, p_index->session); for (uint32_t i = 0; t_success && i < p_index->session_count; i++) { t_success = MCMemoryNew(p_index->session[i]); if (t_success) t_success = read_cstring(p_index->file, p_index->session[i]->id) && read_cstring(p_index->file, p_index->session[i]->ip) && read_cstring(p_index->file, p_index->session[i]->filename) && read_real64(p_index->file, p_index->session[i]->expires); } return t_success; }
bool MCCompressedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied) { bool t_success = true; MCImageFrame *t_frame = nil; t_success = MCMemoryNewArray(1, t_frame); if (t_success) t_success = MCImageDecompressRLE(m_compressed, t_frame->image); if (t_success) { t_frame->density = 1.0; r_frames = t_frame; r_frame_count = 1; r_frames_premultiplied = false; } else MCImageFreeFrames(t_frame, 1); return t_success; }
// decode image data to a series of frames, ignoring all the other bits & pieces bool MCImageDecode(IO_handle p_stream, MCImageFrame *&r_frames, uindex_t &r_frame_count) { bool t_success = true; MCImageFrame *t_frames = nil; uindex_t t_frame_count = 0; MCImageBitmap *t_bitmap = nil; MCImageCompressedBitmap *t_compressed = nil; MCPoint t_hotspot; char *t_name = nil; if (t_success) t_success = MCImageImport(p_stream, nil, t_hotspot, t_name, t_compressed, t_bitmap); if (t_success) { if (t_compressed != nil) t_success = MCImageDecompress(t_compressed, r_frames, r_frame_count); else { t_success = MCMemoryNewArray(1, r_frames); if (t_success) { r_frames[0].image = t_bitmap; t_bitmap = nil; r_frame_count = 1; } } } MCImageFreeCompressedBitmap(t_compressed); MCImageFreeBitmap(t_bitmap); MCCStringFree(t_name); return t_success; }
bool MCEventQueuePostImeCompose(MCStack *p_stack, bool p_enabled, uint32_t p_offset, const uint16_t *p_chars, uint32_t p_char_count) { uint16_t *t_new_chars; if (!MCMemoryNewArray(p_char_count, t_new_chars)) return false; MCEvent *t_event; if (!MCEventQueuePost(kMCEventTypeImeCompose, t_event)) { MCMemoryDeleteArray(t_new_chars); return false; } t_event -> ime . stack = p_stack; t_event -> ime . compose . enabled = p_enabled; t_event -> ime . compose . offset = p_offset; t_event -> ime . compose . chars = t_new_chars; t_event -> ime . compose . char_count = p_char_count; MCMemoryCopy(t_new_chars, p_chars, sizeof(uint16_t) * p_char_count); return true; }
bool MCGCacheTableCreate(uindex_t p_size, uindex_t p_max_occupancy, uindex_t p_max_bytes, MCGCacheTableRef &r_cache_table) { bool t_success; t_success = true; __MCGCacheTable *t_cache_table; t_cache_table = NULL; if (t_success) t_success = MCMemoryNew(t_cache_table); __MCGCacheTableEntry *t_pairs; t_pairs = NULL; if (t_success) t_success = MCMemoryNewArray(p_size, t_pairs); if (t_success) { t_cache_table -> total_buckets = p_size; t_cache_table -> used_buckets = 0; t_cache_table -> max_occupancy = p_max_occupancy; t_cache_table -> max_bytes = p_max_bytes; t_cache_table -> bytes_used = sizeof(__MCGCacheTable) + sizeof(__MCGCacheTableEntry) * p_size; t_cache_table -> pairs = t_pairs; t_success = p_max_bytes > t_cache_table -> bytes_used; } if (t_success) r_cache_table = t_cache_table; else { MCMemoryDeleteArray(t_pairs); MCMemoryDelete(t_cache_table); } return t_success; }
bool MCScreenDC::listprinters(MCStringRef& r_printers) { MCAutoListRef t_list; if (!MCListCreateMutable('\n', &t_list)) return false; DWORD t_flags; DWORD t_level; t_flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS; t_level = 4; DWORD t_printer_count; DWORD t_bytes_needed; t_printer_count = 0; t_bytes_needed = 0; if (EnumPrintersW(t_flags, NULL, t_level, NULL, 0, &t_bytes_needed, &t_printer_count) != 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { MCAutoPointer<byte_t> t_printers; if (!MCMemoryNewArray(t_bytes_needed, &t_printers)) return false; if (EnumPrintersW(t_flags, NULL, t_level, (LPBYTE)*t_printers, t_bytes_needed, &t_bytes_needed, &t_printer_count) != 0) { for(uint4 i = 0; i < t_printer_count; ++i) { MCAutoStringRef t_printer_name; if (!MCStringCreateWithWString(((PRINTER_INFO_4W *)*t_printers)[i] . pPrinterName, &t_printer_name)) return false; if (!MCListAppend(*t_list, *t_printer_name)) return false; } } } return MCListCopyAsString(*t_list, r_printers); }
bool MCEncodedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied) { bool t_success = true; // IM-2013-02-18 - switching this back to using MCImageImport as we need to // determine the compression type for m_compression IO_handle t_stream = nil; IO_handle t_mask_stream = nil; MCImageCompressedBitmap *t_compressed = nil; MCImageBitmap *t_bitmap = nil; MCPoint t_hotspot = {1, 1}; char *t_name = nil; t_success = GetDataStream(t_stream) && MCImageImport(t_stream, t_mask_stream, t_hotspot, t_name, t_compressed, t_bitmap); if (t_stream != nil) MCS_close(t_stream); MCImageFrame *t_frames; t_frames = nil; uindex_t t_frame_count; t_frame_count = 0; if (t_success) { if (t_compressed != nil) t_success = MCImageDecompress(t_compressed, t_frames, t_frame_count); else { t_success = MCMemoryNewArray(1, t_frames); if (t_success) { t_frames[0].image = t_bitmap; t_frames[0].density = 1.0; t_bitmap = nil; t_frame_count = 1; } } } if (t_success) { m_width = t_frames[0].image->width; m_height = t_frames[0].image->height; if (t_compressed != nil) m_compression = t_compressed->compression; m_have_geometry = true; r_frames = t_frames; r_frame_count = t_frame_count; r_frames_premultiplied = false; } MCCStringFree(t_name); MCImageFreeBitmap(t_bitmap); MCImageFreeCompressedBitmap(t_compressed); return t_success; }
IO_stat MCLogicalFontTableLoad(IO_handle p_stream) { // Delete any existing font table. MCLogicalFontTableFinish(); // Keep track of any IO errors. IO_stat t_stat; t_stat = IO_NORMAL; // Read the number of entries. uint2 t_count; if (t_stat == IO_NORMAL) t_stat = IO_read_uint2(&t_count, p_stream); // Allocate an array big enough to hold all of them. if (t_stat == IO_NORMAL) if (!MCMemoryNewArray(t_count, s_logical_font_table)) t_stat = IO_ERROR; if (t_stat == IO_NORMAL) { // The size and capacity of the table are equal to the count. s_logical_font_table_size = s_logical_font_table_capacity = t_count; // Iterate t_count times to load each entry in. for(uint32_t i = 0; i < t_count && t_stat == IO_NORMAL; i++) { char *t_textfont; uint2 t_textsize, t_textstyle; t_textfont = nil; // Read in the textSize, textStyle and (original) textFont props. t_stat = IO_read_uint2(&t_textsize, p_stream); if (t_stat == IO_NORMAL) t_stat = IO_read_uint2(&t_textstyle, p_stream); if (t_stat == IO_NORMAL) t_stat = IO_read_string(t_textfont, p_stream); // Now convert the textFont string into a name, splitting off the // lang tag (if any). MCNameRef t_textfont_name; bool t_is_unicode; if (t_stat == IO_NORMAL) { // MW-2012-02-17: [[ Bug ]] It seems possible for the textFont string // to be empty in some cases - so handle this case carefully. const char *t_textfont_tag; if (t_textfont != nil) { t_textfont_tag = strchr(t_textfont, ','); if (t_textfont_tag == nil) { t_textfont_tag = t_textfont + strlen(t_textfont); t_is_unicode = false; } else t_is_unicode = true; } else { t_textfont_tag = nil; t_is_unicode = false; } if (!MCNameCreateWithOldString(MCString(t_textfont, t_textfont_tag - t_textfont), t_textfont_name)) t_stat = IO_ERROR; } // Set the appropriate table entry. if (t_stat == IO_NORMAL) MCLogicalFontTableSetEntry(i, t_textfont_name, t_textstyle, t_textsize, t_is_unicode); // Cleanup the (temporary) original textFont string. delete t_textfont; } } return t_stat; }
// This method reads a stack from the given stream. The stack is set to // have parent MCDispatch, and filename MCcmd. It is designed to be used // for embedded stacks/deployed stacks/revlet stacks. IO_stat MCDispatch::readstartupstack(IO_handle stream, MCStack*& r_stack) { char version[8]; uint1 charset, type; char *newsf; if (readheader(stream, version) != IO_NORMAL || IO_read_uint1(&charset, stream) != IO_NORMAL || IO_read_uint1(&type, stream) != IO_NORMAL || IO_read_string(newsf, stream) != IO_NORMAL) return IO_ERROR; // MW-2008-10-20: [[ ParentScripts ]] Set the boolean flag that tells us whether // parentscript resolution is required to false. s_loaded_parent_script_reference = false; MCtranslatechars = charset != CHARSET; delete newsf; // stackfiles is obsolete MCStack *t_stack = nil; /* UNCHECKED */ MCStackSecurityCreateStack(t_stack); t_stack -> setparent(this); // MM-2013-10-30: [[ Bug 11333 ]] Set the filename of android mainstack to apk/mainstack (previously was just apk). // This solves relative file path referencing issues. #ifdef TARGET_SUBPLATFORM_ANDROID char *t_filename; /* UNCHECKED */ MCMemoryNewArray(MCCStringLength(MCcmd) + 11, t_filename); MCCStringFormat(t_filename, "%s/mainstack", MCcmd); t_stack -> setfilename(t_filename); #else t_stack -> setfilename(strclone(MCcmd)); #endif if (IO_read_uint1(&type, stream) != IO_NORMAL || type != OT_STACK && type != OT_ENCRYPT_STACK || t_stack->load(stream, version, type) != IO_NORMAL) { delete t_stack; return IO_ERROR; } if (t_stack->load_substacks(stream, version) != IO_NORMAL || IO_read_uint1(&type, stream) != IO_NORMAL || type != OT_END) { delete t_stack; return IO_ERROR; } // We are reading the startup stack, so this becomes the root of the // stack list. stacks = t_stack; r_stack = t_stack; #ifndef _MOBILE // Make sure parent script references are up to date. if (s_loaded_parent_script_reference) t_stack -> resolveparentscripts(); #else // Mark the stack as needed parentscript resolution. This is done after // aux stacks have been loaded. if (s_loaded_parent_script_reference) t_stack -> setextendedstate(True, ECS_USES_PARENTSCRIPTS); #endif return IO_NORMAL; }
Exec_stat MCIdeDmgBuild::exec(MCExecPoint& ep) { Exec_stat t_stat; t_stat = ES_NORMAL; // Clear the result as we return an error there MCresult -> clear(); ///////// if (t_stat == ES_NORMAL) t_stat = m_items -> eval(ep); if (t_stat == ES_NORMAL && ep . getformat() != VF_ARRAY) t_stat = ES_ERROR; MCVariableArray *t_array; if (t_stat == ES_NORMAL) { t_array = ep . getarray() -> get_array(); if (!t_array -> issequence()) t_stat = ES_ERROR; } MCDeployDmgItem *t_items; uint32_t t_item_count; t_items = nil; t_item_count = 0; if (t_stat == ES_NORMAL) { if (MCMemoryNewArray(t_array -> getnfilled(), t_items)) t_item_count = t_array -> getnfilled(); else t_stat = ES_ERROR; } MCExecPoint ep2(ep); if (t_stat == ES_NORMAL) for(uint32_t i = 0; i < t_item_count && t_stat == ES_NORMAL; i++) { MCHashentry *t_element; t_element = t_array -> lookupindex(i + 1, False); if (t_element == nil) t_stat = ES_ERROR; if (t_stat == ES_NORMAL) t_stat = t_element -> value . fetch(ep2); MCVariableValue *t_item_array; if (t_stat == ES_NORMAL) { t_item_array = ep2 . getarray(); if (t_item_array == nil) t_stat = ES_ERROR; } if (t_stat == ES_NORMAL) { t_stat = t_item_array -> fetch_element(ep2, "type"); if (t_stat == ES_NORMAL) { if (ep2 . getsvalue() == "folder") t_items[i] . is_folder = true; else if (ep2 . getsvalue() == "file") t_items[i] . is_folder = false; else t_stat = ES_ERROR; } } if (t_stat == ES_NORMAL) t_stat = fetch_uint32(ep2, t_item_array, "parent", t_items[i] . parent); if (t_stat == ES_NORMAL) t_stat = fetch_cstring(ep2, t_item_array, "name", t_items[i] . name); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "owner_id", t_items[i] . owner_id); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "group_id", t_items[i] . group_id); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "file_mode", t_items[i] . file_mode); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "create_date", t_items[i] . create_date); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "content_mod_date", t_items[i] . content_mod_date); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "attribute_mod_date", t_items[i] . attribute_mod_date); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "access_date", t_items[i] . access_date); if (t_stat == ES_NORMAL) t_stat = fetch_opt_uint32(ep2, t_item_array, "backup_date", t_items[i] . backup_date); } ///////// if (t_stat == ES_NORMAL) t_stat = m_filename -> eval(ep); if (t_stat == ES_NORMAL) { MCDeployDmgParameters t_params; t_params . items = t_items; t_params . item_count = t_item_count; t_params . output = (char *)ep . getcstring(); if (!MCDeployDmgBuild(t_params)) t_stat = ES_ERROR; } //////// for(uint32_t i = 0; i < t_item_count; i++) MCCStringFree(t_items[i] . name); MCMemoryDeleteArray(t_items); return ES_NORMAL; }
// This method constructs and then writes out a capsule to the given output file. // The capsule contents is derived from the deploy parameters structure. // The offset in the file after writing is returned in x_offset. bool MCDeployWriteCapsule(const MCDeployParameters& p_params, MCDeployFileRef p_output, uint32_t& x_offset) { bool t_success; t_success = true; // Open the stackfile. MCDeployFileRef t_stackfile; t_stackfile = NULL; if (t_success && !MCDeployFileOpen(p_params . stackfile, "rb", t_stackfile)) t_success = MCDeployThrow(kMCDeployErrorNoStackfile); // Open the spill file, if required MCDeployFileRef t_spill; t_spill = NULL; if (t_success && p_params . spill != nil && !MCDeployFileOpen(p_params . spill, "wb+", t_spill)) t_success = MCDeployThrow(kMCDeployErrorNoSpill); // First create our deployment capsule MCDeployCapsuleRef t_capsule; t_capsule = nil; if (t_success) t_success = MCDeployCapsuleCreate(t_capsule); // Next, the first thing to do is to add the the header section. if (t_success) t_success = MCDeployWriteCapsuleDefineStandaloneSections(p_params, t_capsule); // Add any redirects if (t_success) for(uint32_t i = 0; i < p_params . redirect_count && t_success; i++) t_success = MCDeployCapsuleDefine(t_capsule, kMCCapsuleSectionTypeRedirect, p_params . redirects[i], MCCStringLength(p_params . redirects[i]) + 1); // Now we add the main stack if (t_success) t_success = MCDeployCapsuleDefineFromFile(t_capsule, kMCCapsuleSectionTypeStack, t_stackfile); // Now we add the auxillary stackfiles, if any MCDeployFileRef *t_aux_stackfiles; t_aux_stackfiles = nil; if (t_success) t_success = MCMemoryNewArray(p_params . auxillary_stackfile_count, t_aux_stackfiles); if (t_success) for(uint32_t i = 0; i < p_params . auxillary_stackfile_count && t_success; i++) { if (t_success && !MCDeployFileOpen(p_params . auxillary_stackfiles[i], "rb", t_aux_stackfiles[i])) t_success = MCDeployThrow(kMCDeployErrorNoAuxStackfile); if (t_success) t_success = MCDeployCapsuleDefineFromFile(t_capsule, kMCCapsuleSectionTypeAuxillaryStack, t_aux_stackfiles[i]); } // Now add the externals, if any if (t_success) for(uint32_t i = 0; i < p_params . external_count && t_success; i++) t_success = MCDeployCapsuleDefine(t_capsule, kMCCapsuleSectionTypeExternal, p_params . externals[i], MCCStringLength(p_params . externals[i]) + 1); // Now add the startup script, if any. if (t_success && p_params . startup_script != nil) t_success = MCDeployCapsuleDefine(t_capsule, kMCCapsuleSectionTypeStartupScript, p_params . startup_script, MCCStringLength(p_params . startup_script) + 1); // Now a digest if (t_success) t_success = MCDeployCapsuleChecksum(t_capsule); // Finally the epilogue if (t_success) t_success = MCDeployCapsuleDefine(t_capsule, kMCCapsuleSectionTypeEpilogue, nil, 0); // Now we write it if (t_success) t_success = MCDeployCapsuleGenerate(t_capsule, p_output, t_spill, x_offset); MCDeployCapsuleDestroy(t_capsule); for(uint32_t i = 0; i < p_params . auxillary_stackfile_count; i++) MCDeployFileClose(t_aux_stackfiles[i]); MCMemoryDeleteArray(t_aux_stackfiles); MCDeployFileClose(t_spill); MCDeployFileClose(t_stackfile); return t_success; }
bool MCSystemPickOption(const_cstring_array_t **p_expression, const_int32_array_t *p_indexes, uint32_t p_expression_cnt, const_int32_array_t *&r_result, bool p_use_checkmark, bool p_use_picker, bool p_use_cancel, bool p_use_done, bool &r_canceled, MCRectangle p_button_rect) { MCLog("indexes: (%p) {length = %d, element[0] = %d}", p_indexes, p_indexes ? p_indexes->length : 0, p_indexes && p_indexes->length > 0 ? p_indexes->elements[0] : 0); // multi-pick list not supported if (p_expression_cnt != 1) return false; bool t_success = true; // convert cstring array to java list of strings JNIEnv *t_env = MCJavaGetThreadEnv(); jobject t_joptionlist = nil; const char *t_title = nil; bool t_has_selection = false; uint32_t t_selected_index = 0; t_success = MCJavaInitList(t_env, t_joptionlist); if (t_success) { for (uint32_t i = 0; t_success && i < p_expression[0]->length; i++) { MCString t_string(p_expression[0]->elements[i]); t_success = MCJavaListAppendString(t_env, t_joptionlist, &t_string); } } if (t_success) { t_has_selection = (p_indexes != nil && p_indexes->length != 0); if (t_has_selection) t_selected_index = p_indexes->elements[0]; MCLog("selected index: %d", t_selected_index); s_in_popup_dialog = true; s_dialog_result = kMCDialogResultUnknown; MCAndroidEngineRemoteCall("showListPicker", "vlsbibbb", nil, t_joptionlist, t_title, t_has_selection, t_selected_index, p_use_checkmark, p_use_cancel, p_use_done); while (s_in_popup_dialog) MCscreen->wait(60.0, True, True); if (s_dialog_result == kMCDialogResultError) t_success = false; r_canceled = s_dialog_result == kMCDialogResultCanceled; if (!r_canceled) { t_success = MCMemoryNew(r_result) && MCMemoryNewArray(1, r_result->elements); if (t_success) { r_result->length = 1; r_result->elements[0] = s_selected_index + 1; } } } if (t_joptionlist != nil) MCJavaFreeList(t_env, t_joptionlist); return t_success; }
bool MCTextLayout(const unichar_t *p_chars, uint32_t p_char_count, MCFontStruct *p_font, MCTextLayoutCallback p_callback, void *p_context) { bool t_success; t_success = true; // The state structure we use to record the list of runs and the dc we use // for processing. MCTextLayoutState self; MCMemoryClear(&self, sizeof(MCTextLayoutState)); if (t_success) { self . dc = CreateCompatibleDC(nil); if (self . dc == nil) t_success = false; } // Fetch a layout font for the provided HFONT. if (t_success) t_success = MCTextLayoutFontFromHFONT(p_font -> fid, self . primary_font); // First thing we need to do is itemize the input string. The ScriptItemize // function splits up the chars into runs, each run being potentially // processed differently by Uniscribe. // Unfortunately, there is no way to predict for an arbitrary string how // many items might be generated, nor is the ScriptItemize function // incremental, thus we must loop with an every increasing buffer until // we have enough room. SCRIPT_ITEM *t_items; uint32_t t_item_limit, t_item_count; SCRIPT_STATE t_script_state; SCRIPT_CONTROL t_script_control; t_items = nil; t_item_limit = 0; t_item_count = 0; MCMemoryClear(&t_script_state, sizeof(SCRIPT_STATE)); MCMemoryClear(&t_script_control, sizeof(SCRIPT_CONTROL)); while(t_success) { // Increase the item array by 32 each time if (t_success) t_success = MCMemoryResizeArray(t_item_limit + 32, t_items, t_item_limit); // Attempt to itemize HRESULT t_result; if (t_success) { t_result = ScriptItemize(p_chars, p_char_count, t_item_limit, &t_script_control, &t_script_state, t_items, (int *)&t_item_count); if (t_result != S_OK && t_result != E_OUTOFMEMORY) t_success = false; } if (t_success && t_result == S_OK) break; } // Next we loop through the items one by one, processing them as we go, this // process is slightly recursive - LayoutItem may recurse to fill in any // 'holes' caused by glyphs not in the primary font. for(uint32_t i = 0; i < t_item_count && t_success; i++) t_success = MCTextLayoutStyleItem( self, t_items[i] . a, p_chars + t_items[i] . iCharPos, t_items[i + 1] . iCharPos - t_items[i] . iCharPos, self . primary_font); // At this point we should have an array of runs to render. First though we // need to compute the visual to logical mapping. uint8_t *t_levels; int *t_map; t_levels = nil; t_map = nil; if (t_success) t_success = MCMemoryNewArray(self . run_count, t_levels) && MCMemoryNewArray(self . run_count, t_map); // Work out the run mapping, but only if we have runs to map! if (t_success && self . run_count > 0) { for(uint32_t i = 0; i < self . run_count; i++) t_levels[i] = self . runs[i] . embedding_level; if (ScriptLayout(self . run_count, t_levels, t_map, nil) != S_OK) t_success = false; } // Now we have the mapping we loop through the runs in the correct order // dispatching them to the callback. if (t_success && p_callback != nil) { double t_x; t_x = 0.0; for(uint32_t i = 0; i < self . run_count && t_success; i++) { MCTextLayoutRun *t_run; t_run = &self . runs[t_map[i]]; // Allocate a temporary array for the glyph structures MCTextLayoutGlyph *t_glyphs; t_glyphs = nil; if (t_success) t_success = MCMemoryNewArray(t_run -> glyph_count, t_glyphs); if (t_success) { // Compute the position for each glyph, keeping a running // total of the advance width. for(uint32_t i = 0; i < t_run -> glyph_count; i++) { t_glyphs[i] . index = t_run -> glyphs[i]; t_glyphs[i] . x = t_x + t_run -> goffsets[i] . du; t_glyphs[i] . y = t_run -> goffsets[i] . dv; t_x += t_run -> advances[i]; } // Dispatch the span to the callback. MCTextLayoutSpan t_span; t_span . chars = t_run -> chars; t_span . clusters = t_run -> clusters; t_span . char_count = t_run -> char_count; t_span . glyphs = t_glyphs; t_span . glyph_count = t_run -> glyph_count; t_span . font = t_run -> font -> handle; t_success = p_callback(p_context, &t_span); } // Free the temporary array. MCMemoryDeleteArray(t_glyphs); } } // Free all the arrays and other resources that have been allocated. MCMemoryDeleteArray(t_map); MCMemoryDeleteArray(t_levels); for(uint32_t i = 0; i < self . run_count; i++) { MCMemoryDeallocate(self . runs[i] . chars); MCMemoryDeallocate(self . runs[i] . clusters); MCMemoryDeallocate(self . runs[i] . glyphs); MCMemoryDeallocate(self . runs[i] . advances); MCMemoryDeallocate(self . runs[i] . goffsets); } MCMemoryDeleteArray(self . runs); MCMemoryDeleteArray(t_items); if (self . dc != nil) DeleteDC(self . dc); return t_success; }
// SN-2014-09-01: [[ Bug 13297 ]] Combining by column deserves its own function as it is too // different from combining by row void MCArraysExecCombineByColumn(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef &r_string) { MCStringRef t_row_delimiter, t_col_delimiter; t_row_delimiter = ctxt . GetRowDelimiter(); t_col_delimiter = ctxt . GetColumnDelimiter(); MCAutoListRef t_list; MCListCreateMutable(t_row_delimiter, &t_list); uindex_t t_count = MCArrayGetCount(p_array); combine_int_indexed_array_t t_lisctxt; bool t_success; t_lisctxt . elements = nil; t_lisctxt . index = 0; t_lisctxt . converter = &ctxt; t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { if (MCArrayApply(p_array, list_int_indexed_array_elements, &t_lisctxt)) { bool t_valid_keys; qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_int_indexed_elements); // Combine by row/column is only valid if all the indices are consecutive numbers // Otherwise, an empty string is returned - no error index_t t_last_index; t_valid_keys = true; t_last_index = 0; for (int i = 0; i < t_count && t_valid_keys; ++i) { if (!t_last_index) t_last_index = t_lisctxt . elements[i] . key; else t_valid_keys = ++t_last_index == t_lisctxt . elements[i] . key; } if (t_valid_keys) { // SN-2014-09-01: [[ Bug 13297 ]] // We need to store the converted strings in a array, to be able to iterate through the elements by one row-delimitated // at a time MCStringRef* t_strings; uindex_t *t_next_row_indices; t_strings = NULL; t_next_row_indices = NULL; /* UNCHECKED */ MCMemoryNewArray(t_count, t_strings); // MCMemoryNewArray initialises all t_next_row_indices elements to 0. /* UNCHECKED */ MCMemoryNewArray(t_count, t_next_row_indices); for (int i = 0; i < t_count && t_success; ++i) { if (t_lisctxt . elements[i] . key == 0) // The index 0 is ignored continue; t_success = ctxt . ConvertToString(t_lisctxt . elements[i] . value, t_strings[i]); } // SN-2014-09-01: [[ Bug 13297 ]] Added a missed part in column-combining: // only combining row-by-row the array elements. if (t_success) { uindex_t t_elements_over; t_elements_over = 0; // We iterate as long as one element still has uncombined rows while (t_success && t_elements_over != t_count) { MCAutoListRef t_row; t_success = MCListCreateMutable(t_col_delimiter, &t_row); t_elements_over = 0; // Iterate through all the elements of the array for (int i = 0; i < t_count && t_success; ++i) { // Only consider this element if it has any uncombined rows remaining if (t_next_row_indices[i] < MCStringGetLength(t_strings[i])) { MCRange t_cell_range; if (MCStringFind(t_strings[i], MCRangeMake(t_next_row_indices[i], UINDEX_MAX), t_row_delimiter, ctxt.GetStringComparisonType(), &t_cell_range)) { // We found a row delimiter, so we stop the copy range before it and update the next index from which to look t_success = MCListAppendSubstring(*t_row, t_strings[i], MCRangeMake(t_next_row_indices[i], t_cell_range . offset - t_next_row_indices[i])); t_next_row_indices[i] = t_cell_range . offset + t_cell_range . length; } else { // No row delimiter: we copy the remaining part of the string and mark the element // as wholly combined by setting the next index to the length of the element t_success = MCListAppendSubstring(*t_row, t_strings[i], MCRangeMake(t_next_row_indices[i], UINDEX_MAX)); t_next_row_indices[i] = MCStringGetLength(t_strings[i]); } } else { // Everything has been combined in this element t_elements_over++; MCListAppend(*t_row, kMCEmptyString); } } // One more row has been combined - doing it anyway mimics the previous behaviour of having an empty row // added in the end when combining by columns if (t_elements_over != t_count) MCListAppend(*t_list, *t_row); } } MCMemoryDeleteArray(t_next_row_indices); MCMemoryDeleteArray(t_strings); } } MCMemoryDeleteArray(t_lisctxt . elements); } if (t_success && MCListCopyAsString(*t_list, r_string)) return; ctxt . Throw(); }
static bool MCRegistryListValues(HKEY p_root, const char *p_key, MCRegistryListValuesCallback p_callback, void *p_context) { bool t_success; t_success = true; // Attempt to open the given key. HKEY t_handle; t_handle = nil; if (t_success) if (RegOpenKeyExA(p_root, p_key, 0, KEY_QUERY_VALUE, &t_handle) != ERROR_SUCCESS) t_success = false; // Next determine the maximum length of the value names. DWORD t_max_name_length; if (t_success) if (RegQueryInfoKeyA(t_handle, nil, nil, nil, nil, nil, nil, nil, &t_max_name_length, nil, nil, nil) != ERROR_SUCCESS) t_success = false; // Allocate a buffer big enough for the name char *t_name_buffer; t_name_buffer = nil; if (t_success) t_success = MCMemoryNewArray(t_max_name_length + 1, t_name_buffer); if (t_success) { DWORD t_index; t_index = 0; while(t_success) { DWORD t_name_length, t_value_length; t_name_length = t_max_name_length + 1; t_value_length = 0; LSTATUS t_result; if (t_success) { t_result = RegEnumValueA(t_handle, t_index, t_name_buffer, &t_name_length, nil, nil, nil, &t_value_length); if (t_result == ERROR_NO_MORE_ITEMS) break; if (t_result != ERROR_SUCCESS) t_success = false; } void *t_value_buffer; t_value_buffer = nil; if (t_success) t_success = MCMemoryAllocate(t_value_length, t_value_buffer); DWORD t_type; if (t_success) { t_name_length = t_max_name_length + 1; if (RegEnumValueA(t_handle, t_index, t_name_buffer, &t_name_length, nil, &t_type, (LPBYTE)t_value_buffer, &t_value_length) != ERROR_SUCCESS) t_success = false; } if (t_success && p_callback != nil) p_callback(p_context, t_name_buffer, t_type, t_value_buffer, t_value_length); MCMemoryDeallocate(t_value_buffer); t_index++; } } MCMemoryDeleteArray(t_name_buffer); if (t_handle != nil) RegCloseKey(t_handle); return t_success; }
static int CALLBACK MCTextLayoutStyleItemCallback(HDC p_dc, HANDLETABLE *p_handles, const ENHMETARECORD *p_record, int p_object_count, LPARAM p_context) { // This method assumes that the order of the TextOut records is in logical // order - i.e. no reversing for right-to-left text. This should be a valid // assumption to make since each SCRIPT_ITEM is rendered individually and // each such item is either all LTR or all RTL. // Additionally, it assumes that all printable chars (i.e. non-control) in // the analysed string will be part of some ExtTextOut record, even if the // suggested font (with linking) doesn't contain the characters. // Finally, it assumes that errant records which should not be rendered cause // a reference point advance of 0. MCTextLayoutStyleItemContext *context; context = (MCTextLayoutStyleItemContext *)p_context; bool t_success; t_success = true; bool t_flush; t_flush = false; int32_t t_new_pending_x; uint32_t t_new_pending_char_count; unichar_t *t_new_pending_chars; MCTextLayoutFont *t_new_pending_font; t_new_pending_x = 0; t_new_pending_char_count = 0; t_new_pending_chars = nil; t_new_pending_font = nil; switch(p_record -> iType) { case EMR_EXTCREATEFONTINDIRECTW: { EMREXTCREATEFONTINDIRECTW *t_record; t_record = (EMREXTCREATEFONTINDIRECTW *)p_record; // Attempt to create the font with the given info. p_handles -> objectHandle[t_record -> ihFont] = CreateFontIndirectW(&t_record -> elfw . elfLogFont); if (p_handles -> objectHandle[t_record -> ihFont] == nil) t_success = false; } break; case EMR_SELECTOBJECT: { EMRSELECTOBJECT *t_record; t_record = (EMRSELECTOBJECT *)p_record; // If the object being selected is a font, update our current font. if (GetObjectType(p_handles -> objectHandle[t_record -> ihObject]) == OBJ_FONT) t_success = MCTextLayoutFontFromHFONT((HFONT)p_handles -> objectHandle[t_record -> ihObject], context -> current_font); } break; case EMR_DELETEOBJECT: { EMRDELETEOBJECT *t_record; t_record = (EMRDELETEOBJECT *)p_record; // If the object being deleted is our current font, reset selection // to nil. if (p_handles -> objectHandle[t_record -> ihObject] == context -> current_font) context -> current_font = context -> primary_font; DeleteObject(p_handles -> objectHandle[t_record -> ihObject]); p_handles -> objectHandle[t_record -> ihObject] = nil; } break; case EMR_EXTTEXTOUTW: { EMREXTTEXTOUTW *t_record; t_record = (EMREXTTEXTOUTW *)p_record; unichar_t *t_run_chars; uint32_t t_run_char_count; t_run_chars = (unichar_t *)((char *)p_record + t_record -> emrtext . offString); t_run_char_count = t_record -> emrtext . nChars; if (t_run_char_count > 0) { if (MCMemoryNewArray(t_run_char_count, t_new_pending_chars)) { t_flush = true; t_new_pending_x = t_record -> emrtext . ptlReference . x; t_new_pending_font = context -> current_font; t_new_pending_char_count = t_run_char_count; MCMemoryCopy(t_new_pending_chars, t_run_chars, t_new_pending_char_count * sizeof(uint16_t)); } else t_success = false; } } break; case EMR_EOF: t_new_pending_x = MAXINT4; t_flush = true; break; } if (t_success && t_flush) { if (context -> pending_chars != nil && t_new_pending_x != context -> pending_x) t_success = MCTextLayoutLinkItem(*(context -> state), context -> analysis, context -> pending_chars, context -> pending_char_count, context -> pending_font); MCMemoryDeleteArray(context -> pending_chars); context -> pending_chars = t_new_pending_chars; context -> pending_char_count = t_new_pending_char_count; context -> pending_font = t_new_pending_font; context -> pending_x = t_new_pending_x; } if (!t_success) MCMemoryDeleteArray(context -> pending_chars); return t_success; }
static bool bsdiffmain(MCBsDiffInputStream *p_old_file, MCBsDiffInputStream *p_new_file, MCBsDiffOutputStream *p_patch_file) { u_char *old,*newp; off_t oldsize,newsize; off_t *I,*V; off_t scan,pos,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens; off_t i; off_t dblen,eblen; u_char *db,*eb; // if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); bool t_success; t_success = true; V = NULL; /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ /*if(((fd=open(argv[1],O_RDONLY,0))<0) || ((oldsize=lseek(fd,0,SEEK_END))==-1) || ((old=malloc(oldsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,old,oldsize)!=oldsize) || (close(fd)==-1)) err(1,"%s",argv[1]);*/ if (t_success) { uint32_t t_size; t_success = p_old_file -> Measure(t_size); oldsize = (signed)t_size; } if (t_success) t_success = MCMemoryNewArray(oldsize + 1, old); if (t_success) t_success = p_old_file -> ReadBytes(old, oldsize); /*if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) || ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL);*/ if (t_success) t_success = MCMemoryNewArray(oldsize + 1, I); if (t_success) t_success = MCMemoryNewArray(oldsize + 1, V); if (t_success) qsufsort(I,V,old,oldsize); /*free(V);*/ MCMemoryDeleteArray(V); /* Allocate newsize+1 bytes instead of newsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ /*if(((fd=open(argv[2],O_RDONLY,0))<0) || ((newsize=lseek(fd,0,SEEK_END))==-1) || ((newp=malloc(newsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,newp,newsize)!=newsize) || (close(fd)==-1)) err(1,"%s",argv[2]);*/ if (t_success) { uint32_t t_size; t_success = p_new_file -> Measure(t_size); newsize = (signed)t_size; } if (t_success) t_success = MCMemoryNewArray(newsize + 1, newp); if (t_success) t_success = p_new_file -> ReadBytes(newp, newsize); /*if(((db=malloc(newsize+1))==NULL) || ((eb=malloc(newsize+1))==NULL)) err(1,NULL);*/ if (t_success) t_success = MCMemoryNewArray(newsize + 1, db); if (t_success) t_success = MCMemoryNewArray(newsize + 1, eb); dblen=0; eblen=0; /* Create the patch file */ /*if ((pf = fopen(argv[3], "w")) == NULL) err(1, "%s", argv[3]);*/ /* Header is 0 8 "BSDIFF40" 8 8 length of bzip2ed ctrl block 16 8 length of bzip2ed diff block 24 8 length of new file */ /* File is 0 32 Header 32 ?? Bzip2ed ctrl block ?? ?? Bzip2ed diff block ?? ?? Bzip2ed extra block */ /*memcpy(header,"BSDIFF40",8); offtout(0, header + 8); offtout(0, header + 16); offtout(newsize, header + 24); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", argv[3]);*/ uint32_t t_control_size, t_diff_size, t_extra_size; t_control_size = 0; t_diff_size = 0; t_extra_size = 0; if (t_success) t_success = p_patch_file -> WriteInt32(t_control_size) && p_patch_file -> WriteInt32(t_diff_size) && p_patch_file -> WriteInt32(t_extra_size) && p_patch_file -> WriteInt32(newsize); /* Compute the differences, writing ctrl as we go */ /*if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);*/ scan=0;len=0; lastscan=0;lastpos=0;lastoffset=0; while(t_success && scan<newsize) { oldscore=0; for(scsc=scan+=len;scan<newsize;scan++) { len=search(I,old,oldsize,newp+scan,newsize-scan, 0,oldsize,&pos); for(;scsc<scan+len;scsc++) if((scsc+lastoffset<oldsize) && (old[scsc+lastoffset] == newp[scsc])) oldscore++; if(((len==oldscore) && (len!=0)) || (len>oldscore+8)) break; if((scan+lastoffset<oldsize) && (old[scan+lastoffset] == newp[scan])) oldscore--; }; if((len!=oldscore) || (scan==newsize)) { s=0;Sf=0;lenf=0; for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) { if(old[lastpos+i]==newp[lastscan+i]) s++; i++; if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; }; }; lenb=0; if(scan<newsize) { s=0;Sb=0; for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) { if(old[pos-i]==newp[scan-i]) s++; if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; }; }; if(lastscan+lenf>scan-lenb) { overlap=(lastscan+lenf)-(scan-lenb); s=0;Ss=0;lens=0; for(i=0;i<overlap;i++) { if(newp[lastscan+lenf-overlap+i]== old[lastpos+lenf-overlap+i]) s++; if(newp[scan-lenb+i]== old[pos-lenb+i]) s--; if(s>Ss) { Ss=s; lens=i+1; }; }; lenf+=lens-overlap; lenb-=lens; }; for(i=0;i<lenf;i++) db[dblen+i]=newp[lastscan+i]-old[lastpos+i]; for(i=0;i<(scan-lenb)-(lastscan+lenf);i++) eb[eblen+i]=newp[lastscan+lenf+i]; dblen+=lenf; eblen+=(scan-lenb)-(lastscan+lenf); /*offtout(lenf,buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); offtout((scan-lenb)-(lastscan+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); offtout((pos-lenb)-(lastpos+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);*/ if (t_success) t_success = p_patch_file -> WriteInt32(lenf) && p_patch_file -> WriteInt32((scan-lenb)-(lastscan+lenf)) && p_patch_file -> WriteInt32((pos-lenb)-(lastpos+lenf)); if (t_success) t_control_size += 12; lastscan=scan-lenb; lastpos=pos-lenb; lastoffset=pos-scan; }; }; /*BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);*/ /* Compute size of compressed ctrl data */ /*if ((len = ftello(pf)) == -1) err(1, "ftello"); offtout(len-32, header + 8);*/ /* Write compressed diff data */ /*if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, db, dblen); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);*/ if (t_success) t_success = p_patch_file -> WriteBytes(db, dblen); if (t_success) t_diff_size = dblen; /* Compute size of compressed diff data */ /*if ((newsize = ftello(pf)) == -1) err(1, "ftello"); offtout(newsize - len, header + 16);*/ /* Write compressed extra data */ /*if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, eb, eblen); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);*/ if (t_success) t_success = p_patch_file -> WriteBytes(eb, eblen); if (t_success) t_extra_size = eblen; /* Seek to the beginning, write the header, and close the file */ /*if (fseeko(pf, 0, SEEK_SET)) err(1, "fseeko"); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", argv[3]); if (fclose(pf)) err(1, "fclose");*/ if (t_success) t_success = p_patch_file -> Rewind() && p_patch_file -> WriteInt32(t_control_size) && p_patch_file -> WriteInt32(t_diff_size) && p_patch_file -> WriteInt32(t_extra_size) && p_patch_file -> Rewind(); /* Free the memory we used */ /*free(db); free(eb); free(I); free(old); free(new);*/ MCMemoryDeleteArray(db); MCMemoryDeleteArray(eb); MCMemoryDeleteArray(I); MCMemoryDeleteArray(old); MCMemoryDeleteArray(newp); return t_success; }
static bool MCTextLayoutLinkItem(MCTextLayoutState& self, SCRIPT_ANALYSIS p_analysis, const unichar_t *p_chars, uint32_t p_char_count, MCTextLayoutFont *p_font) { bool t_success; t_success = true; // If the font is not linked, we can move directly to shaping if (p_font -> linking == nil) return MCTextLayoutShapeItem(self, p_analysis, p_chars, p_char_count, p_font, nil); // Otherwise we need to split up the run further into font ranges resulting // from font linking. Unfortunately, this is more complex than just looking // up each UTF-16 codepoint in the fonts support since we need to handle // combining cases and surrogates. // Make an array to hold cached text layout fonts, we get these as needed. MCTextLayoutFont **t_fonts; t_fonts = nil; if (t_success) t_success = MCMemoryNewArray(p_font -> linking -> entry_count + 1, t_fonts); // The first entry in the array is always the font we start with. if (t_success) t_fonts[0] = p_font; // We shape cluster by cluster, so determine the cluster boundaries using // ScriptBreak. SCRIPT_LOGATTR *t_breaks; t_breaks = nil; if (t_success) t_success = MCMemoryNewArray(p_char_count, t_breaks); if (t_success) if (ScriptBreak(p_chars, p_char_count, &p_analysis, t_breaks) != S_OK) t_success = false; // Now loop cluster by cluster, determining the font of each one. Note that // we can't use the results of shaping individual clusters to build up the // glyphs of the item since adjacent clusters may interact. For example, in // Sylfaen 'f' and 'i' and elide to form a proper 'fi' ligature. if (t_success) { MCTextLayoutFont *t_span_font; uint32_t t_span_start, t_span_finish; t_span_start = t_span_finish = 0; t_span_font = nil; while(t_success && t_span_finish < p_char_count) { // Compute bounds of next cluster uint32_t t_cluster_start, t_cluster_finish; t_cluster_start = t_span_finish; t_cluster_finish = t_cluster_start + 1; while(t_cluster_finish < p_char_count && !t_breaks[t_cluster_finish] . fCharStop) t_cluster_finish++; // Now try to shape the cluster in each font successively. MCTextLayoutFont *t_cluster_font; t_cluster_font = nil; for(uint32_t i = 0; i < p_font -> linking -> entry_count + 1 && t_success; i++) { // Get the font, if it doesn't already exist if (t_fonts[i] == nil) t_success = MCTextLayoutFontWithLink(p_font, &p_font -> linking -> entries[i - 1], t_fonts[i]); // Now try to shape the cluster with it bool t_shaped; if (t_success) t_success = MCTextLayoutShapeItem(self, p_analysis, p_chars + t_cluster_start, t_cluster_finish - t_cluster_start, t_fonts[i], &t_shaped); // If the shaping was successful we are done if (t_success && t_shaped) { t_cluster_font = t_fonts[i]; break; } } // If the cluster's font is not the same as the span's font then we // have a run to shape. if (t_success && t_cluster_font != t_span_font) { if (t_span_start != t_span_finish) t_success = MCTextLayoutShapeItem(self, p_analysis, p_chars + t_span_start, t_span_finish - t_span_start, t_span_font, nil); // The next span starts where the previous one finishes and has // the font of the cluster we just shaped. if (t_success) { t_span_start = t_span_finish; t_span_font = t_cluster_font; } } // End of span is end of cluster t_span_finish = t_cluster_finish; } // Shape the trailing span if (t_success) t_success = MCTextLayoutShapeItem(self, p_analysis, p_chars + t_span_start, t_span_finish - t_span_start, t_span_font, nil); } MCMemoryDeleteArray(t_breaks); MCMemoryDeleteArray(t_fonts); return t_success; }
bool MCImageEncodePNG(MCImageIndexedBitmap *p_indexed, IO_handle p_stream, uindex_t &r_bytes_written) { bool t_success = true; MCPNGWriteContext t_context; t_context.stream = p_stream; t_context.byte_count = 0; png_structp t_png_ptr = nil; png_infop t_info_ptr = nil; png_color *t_png_palette = nil; png_byte *t_png_transparency = nil; png_bytep t_data_ptr = nil; uindex_t t_stride = 0; /*init png stuff*/ if (t_success) { t_success = nil != (t_png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL)); } if (t_success) t_success = nil != (t_info_ptr = png_create_info_struct(t_png_ptr)); /*in case of png error*/ if (setjmp(png_jmpbuf(t_png_ptr))) t_success = false; if (t_success) png_set_write_fn(t_png_ptr,(png_voidp)&t_context,fakewrite,fakeflush); if (t_success) { png_set_IHDR(t_png_ptr, t_info_ptr, p_indexed->width, p_indexed->height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_gAMA(t_png_ptr, t_info_ptr, 1/MCgamma); } if (t_success) t_success = MCMemoryNewArray(p_indexed->palette_size, t_png_palette); /*create palette for 8 bit*/ if (t_success) { for (uindex_t i = 0; i < p_indexed->palette_size ; i++) { t_png_palette[i].red = p_indexed->palette[i].red >> 8; t_png_palette[i].green = p_indexed->palette[i].green >> 8; t_png_palette[i].blue = p_indexed->palette[i].blue >> 8; } png_set_PLTE(t_png_ptr, t_info_ptr, t_png_palette, p_indexed->palette_size); } if (MCImageIndexedBitmapHasTransparency(p_indexed)) { if (t_success) t_success = MCMemoryAllocate(p_indexed->palette_size, t_png_transparency); if (t_success) { memset(t_png_transparency, 0xFF, p_indexed->palette_size); t_png_transparency[p_indexed->transparent_index] = 0x00; png_set_tRNS(t_png_ptr, t_info_ptr, t_png_transparency, p_indexed->palette_size, NULL); } } if (t_success) png_write_info(t_png_ptr, t_info_ptr); if (t_success) { t_data_ptr = (png_bytep)p_indexed->data; t_stride = p_indexed->stride; } if (t_success) { for (uindex_t i = 0; i < p_indexed->height; i++) { png_write_row(t_png_ptr, t_data_ptr); t_data_ptr += t_stride; } } if (t_success) png_write_end(t_png_ptr, t_info_ptr); if (t_png_ptr != nil) png_destroy_write_struct(&t_png_ptr, &t_info_ptr); if (t_png_palette != nil) MCMemoryDeleteArray(t_png_palette); if (t_png_transparency != nil) MCMemoryDeallocate(t_png_transparency); if (t_success) r_bytes_written = t_context.byte_count; return t_success; }
bool MCTransformedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count) { uindex_t t_target_width, t_target_height; if (!GetGeometry(t_target_width, t_target_height)) return false; bool t_success = true; MCImageFrame *t_frames = nil; uindex_t t_frame_count = 0; t_frame_count = m_source->GetFrameCount(); t_success = MCMemoryNewArray(t_frame_count, t_frames); for (uindex_t i = 0; t_success && i < t_frame_count; i++) { MCImageFrame *t_src_frame = nil; t_success = m_source->LockImageFrame(i, t_src_frame); if (t_success) { t_frames[i].duration = t_src_frame->duration; if (m_angle != 0) { // rotate MCImageBitmap *t_bitmap = nil; MCImageBitmap *t_rotated = nil; t_success = MCImageCopyBitmap(t_src_frame->image, t_bitmap); if (t_success) { MCImageBitmapPremultiply(t_bitmap); t_success = MCImageRotateBitmap(t_bitmap, m_angle, m_quality, 0x0, t_rotated); } MCImageFreeBitmap(t_bitmap); bool t_scaled = false; if (t_success && (t_rotated->width != t_target_width || t_rotated->height != t_target_height)) { MCImageBitmap *t_sbitmap = nil; t_success = MCImageScaleBitmap(t_rotated, t_target_width, t_target_height, m_quality, t_sbitmap); MCImageFreeBitmap(t_rotated); t_rotated = t_sbitmap; t_scaled = true; } if (t_success) { if (t_scaled && (m_quality == INTERPOLATION_BICUBIC)) MCImageBitmapUnpremultiplyChecking(t_rotated); else MCImageBitmapUnpremultiply(t_rotated); t_frames[i].image = t_rotated; } else MCImageFreeBitmap(t_rotated); } else { // resize if (t_src_frame->image->width == t_target_width && t_src_frame->image->height == t_target_height) t_success = MCImageCopyBitmap(t_src_frame->image, t_frames[i].image); else t_success = MCImageScaleBitmap(t_src_frame->image, t_target_width, t_target_height, m_quality, t_frames[i].image); } } m_source->UnlockImageFrame(i, t_src_frame); } if (t_success) { r_frames = t_frames; r_frame_count = t_frame_count; } else MCImageFreeFrames(t_frames, t_frame_count); return t_success; }