static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding) { mxwriter *This = impl_from_IMXWriter( iface ); xml_encoding enc; HRESULT hr; TRACE("(%p)->(%s)\n", This, debugstr_w(encoding)); enc = parse_encoding_name(encoding); if (enc == XmlEncoding_Unknown) { FIXME("unsupported encoding %s\n", debugstr_w(encoding)); return E_INVALIDARG; } hr = flush_output_buffer(This); if (FAILED(hr)) return hr; SysReAllocString(&This->encoding, encoding); This->xml_enc = enc; TRACE("got encoding %d\n", This->xml_enc); reset_output_buffer(This); return S_OK; }
static HRESULT WINAPI mxwriter_saxcontent_endDocument(ISAXContentHandler *iface) { mxwriter *This = impl_from_ISAXContentHandler( iface ); TRACE("(%p)\n", This); This->prop_changed = FALSE; return flush_output_buffer(This); }
/* Reads the specified number of bytes into a the supplied buffer, returning * the number actually read. */ static MVMint64 read_bytes(MVMThreadContext *tc, MVMOSHandle *h, char **buf_out, MVMint64 bytes) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; char *buf = MVM_malloc(bytes); unsigned int interval_id = MVM_telemetry_interval_start(tc, "syncfile.read_to_buffer"); MVMint32 bytes_read; #ifdef _WIN32 /* Can only perform relatively small reads from a Windows console; * trying to do larger ones gives back ENOMEM, most likely due to * limitations of the Windows console subsystem. */ if (bytes > 16387 && _isatty(data->fd)) bytes = 16387; #endif flush_output_buffer(tc, data); MVM_gc_mark_thread_blocked(tc); if ((bytes_read = read(data->fd, buf, bytes)) == -1) { int save_errno = errno; MVM_free(buf); MVM_gc_mark_thread_unblocked(tc); MVM_exception_throw_adhoc(tc, "Reading from filehandle failed: %s", strerror(save_errno)); } *buf_out = buf; MVM_gc_mark_thread_unblocked(tc); MVM_telemetry_interval_annotate(bytes_read, interval_id, "read this many bytes"); MVM_telemetry_interval_stop(tc, interval_id, "syncfile.read_to_buffer"); data->byte_position += bytes_read; if (bytes_read == 0 && bytes != 0) data->eof_reported = 1; return bytes_read; }
void write_bin_files(void) { lan_blk_t *lbp; token_t *ttab; int ntab; int i; get_tokentable(&ttab, &ntab); for (lbp = lanblockhead; lbp; lbp = lbp->next) { char *cptr = NULL; for (i = 0; i < ntab; i++) { if (ttab[i].type == tok_language && ttab[i].token == lbp->lan) { if (ttab[i].alias) cptr = dup_u2c(WMC_DEFAULT_CODEPAGE, ttab[i].alias); break; } } if(!cptr) internal_error(__FILE__, __LINE__, "Filename vanished for language 0x%0x\n", lbp->lan); init_output_buffer(); output_bin_data( lbp ); cptr = xrealloc( cptr, strlen(cptr) + 5 ); strcat( cptr, ".bin" ); flush_output_buffer( cptr ); free(cptr); } }
/* Seek to the specified position in the file. */ static void seek(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 offset, MVMint64 whence) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; if (!data->seekable) MVM_exception_throw_adhoc(tc, "It is not possible to seek this kind of handle"); flush_output_buffer(tc, data); if (MVM_platform_lseek(data->fd, offset, whence) == -1) MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno); }
/* Flushes the file handle. */ static void flush(MVMThreadContext *tc, MVMOSHandle *h, MVMint32 sync){ MVMIOFileData *data = (MVMIOFileData *)h->body.data; flush_output_buffer(tc, data); if (sync) { if (MVM_platform_fsync(data->fd) == -1) { /* If this is something that can't be flushed, we let that pass. */ if (errno != EROFS && errno != EINVAL) MVM_exception_throw_adhoc(tc, "Failed to flush filehandle: %s", strerror(errno)); } } }
/* Get current position in the file. */ static MVMint64 mvm_tell(MVMThreadContext *tc, MVMOSHandle *h) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; flush_output_buffer(tc, data); if (data->seekable) { MVMint64 r; if ((r = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1) MVM_exception_throw_adhoc(tc, "Failed to tell in filehandle: %d", errno); return r; } else { return data->byte_position; } }
int flush_rle(rle_state * s, io_buffer * output) { if (s->run_length != 0) { if(s->run_length < s->huffman_length[s->running_digit]) { huffman_put_symbol(&s->huffman[s->running_digit], output, s->run_length); } else { huffman_put_symbol(&s->huffman[s->running_digit], output, s->huffman_length[s->running_digit]); io_buffer_put(output, s->run_length, 24); } } return flush_output_buffer(output); }
/* Closes the file. */ static MVMint64 closefh(MVMThreadContext *tc, MVMOSHandle *h) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; if (data->fd != -1) { int r; flush_output_buffer(tc, data); MVM_free(data->output_buffer); data->output_buffer = NULL; r = close(data->fd); data->fd = -1; if (r == -1) MVM_exception_throw_adhoc(tc, "Failed to close filehandle: %s", strerror(errno)); } return 0; }
void write_res_file( const char *name ) { lan_blk_t *lbp; int i, j; init_output_buffer(); put_dword( 0 ); /* ResSize */ put_dword( 32 ); /* HeaderSize */ put_word( 0xffff ); /* ResType */ put_word( 0x0000 ); put_word( 0xffff ); /* ResName */ put_word( 0x0000 ); put_dword( 0 ); /* DataVersion */ put_word( 0 ); /* Memory options */ put_word( 0 ); /* Language */ put_dword( 0 ); /* Version */ put_dword( 0 ); /* Characteristics */ for (lbp = lanblockhead; lbp; lbp = lbp->next) { unsigned int data_size = 4 * (lbp->nblk * 3 + 1); unsigned int header_size = 5 * sizeof(unsigned int) + 6 * sizeof(unsigned short); for (i = 0; i < lbp->nblk; i++) { block_t *blk = &lbp->blks[i]; for (j = 0; j < blk->nmsg; j++) data_size += 4 + ((blk->msgs[j]->len * 2 + 3) & ~3); } put_dword( data_size ); /* ResSize */ put_dword( header_size ); /* HeaderSize */ put_word( 0xffff ); /* ResType */ put_word( 0x000b /*RT_MESSAGETABLE*/ ); put_word( 0xffff ); /* ResName */ put_word( 0x0001 ); align_output( 4 ); put_dword( 0 ); /* DataVersion */ put_word( 0x30 ); /* Memory options */ put_word( lbp->lan ); /* Language */ put_dword( lbp->version ); /* Version */ put_dword( 0 ); /* Characteristics */ output_bin_data( lbp ); } flush_output_buffer( name ); }
/* Sets the output buffer size; if <= 0, means no buffering. Flushes any * existing buffer before changing. */ static void set_buffer_size(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 size) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; /* Flush and clear up any existing output buffer. */ flush_output_buffer(tc, data); MVM_free(data->output_buffer); /* Set up new buffer if needed. */ if (size > 0) { data->output_buffer_size = size; data->output_buffer = MVM_malloc(size); } else { data->output_buffer_size = 0; data->output_buffer = NULL; } }
static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest) { mxwriter *This = impl_from_IMXWriter( iface ); HRESULT hr; TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest)); hr = flush_output_buffer(This); if (FAILED(hr)) return hr; switch (V_VT(&dest)) { case VT_EMPTY: { if (This->dest) IStream_Release(This->dest); This->dest = NULL; reset_output_buffer(This); break; } case VT_UNKNOWN: { IStream *stream; hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream); if (hr == S_OK) { /* Recreate the output buffer to make sure it's using the correct encoding. */ reset_output_buffer(This); if (This->dest) IStream_Release(This->dest); This->dest = stream; break; } FIXME("unhandled interface type for VT_UNKNOWN destination\n"); return E_NOTIMPL; } default: FIXME("unhandled destination type %s\n", debugstr_variant(&dest)); return E_NOTIMPL; } return S_OK; }
/* Writes the specified bytes to the file handle. */ static MVMint64 write_bytes(MVMThreadContext *tc, MVMOSHandle *h, char *buf, MVMint64 bytes) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; if (data->output_buffer_size && data->known_writable) { /* If we can't fit it on the end of the buffer, flush the buffer. */ if (data->output_buffer_used + bytes > data->output_buffer_size) flush_output_buffer(tc, data); /* If we can fit it in the buffer now, memcpy it there, and we're * done. */ if (bytes < data->output_buffer_size) { memcpy(data->output_buffer + data->output_buffer_used, buf, bytes); data->output_buffer_used += bytes; return bytes; } } perform_write(tc, data, buf, bytes); return bytes; }
static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest) { mxwriter *This = impl_from_IMXWriter( iface ); TRACE("(%p)->(%p)\n", This, dest); if (!This->dest) { HRESULT hr = flush_output_buffer(This); if (FAILED(hr)) return hr; V_VT(dest) = VT_BSTR; V_BSTR(dest) = SysAllocString((WCHAR*)This->buffer->utf16.data); return S_OK; } else FIXME("not implemented when stream is set up\n"); return E_NOTIMPL; }
static ULONG WINAPI mxwriter_Release(IMXWriter *iface) { mxwriter *This = impl_from_IMXWriter( iface ); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(%d)\n", This, ref); if(!ref) { /* Windows flushes the buffer when the interface is destroyed. */ flush_output_buffer(This); free_output_buffer(This->buffer); if (This->dest) IStream_Release(This->dest); SysFreeString(This->version); SysFreeString(This->encoding); SysFreeString(This->element); release_dispex(&This->dispex); heap_free(This); } return ref; }
/******************************************************************* * output_fake_module * * Build a fake binary module from a spec file. */ void output_fake_module( DLLSPEC *spec ) { static const unsigned char dll_code_section[] = { 0x31, 0xc0, /* xor %eax,%eax */ 0xc2, 0x0c, 0x00 }; /* ret $12 */ static const unsigned char exe_code_section[] = { 0xb8, 0x01, 0x00, 0x00, 0x00, /* movl $1,%eax */ 0xc2, 0x04, 0x00 }; /* ret $4 */ static const char fakedll_signature[] = "Wine placeholder DLL"; const unsigned int page_size = get_page_size(); const unsigned int section_align = page_size; const unsigned int file_align = 0x200; const unsigned int reloc_size = 8; const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15; const unsigned int nb_sections = 2 + (spec->nb_resources != 0); const unsigned int text_size = (spec->characteristics & IMAGE_FILE_DLL) ? sizeof(dll_code_section) : sizeof(exe_code_section); unsigned char *resources; unsigned int resources_size; unsigned int image_size = 3 * section_align; resolve_imports( spec ); output_bin_resources( spec, 3 * section_align ); resources = output_buffer; resources_size = output_buffer_pos; if (resources_size) image_size += (resources_size + section_align - 1) & ~(section_align - 1); init_output_buffer(); put_word( 0x5a4d ); /* e_magic */ put_word( 0x40 ); /* e_cblp */ put_word( 0x01 ); /* e_cp */ put_word( 0 ); /* e_crlc */ put_word( lfanew / 16 ); /* e_cparhdr */ put_word( 0x0000 ); /* e_minalloc */ put_word( 0xffff ); /* e_maxalloc */ put_word( 0x0000 ); /* e_ss */ put_word( 0x00b8 ); /* e_sp */ put_word( 0 ); /* e_csum */ put_word( 0 ); /* e_ip */ put_word( 0 ); /* e_cs */ put_word( lfanew ); /* e_lfarlc */ put_word( 0 ); /* e_ovno */ put_dword( 0 ); /* e_res */ put_dword( 0 ); put_word( 0 ); /* e_oemid */ put_word( 0 ); /* e_oeminfo */ put_dword( 0 ); /* e_res2 */ put_dword( 0 ); put_dword( 0 ); put_dword( 0 ); put_dword( 0 ); put_dword( lfanew ); put_data( fakedll_signature, sizeof(fakedll_signature) ); align_output( 16 ); put_dword( 0x4550 ); /* Signature */ switch(target_cpu) { case CPU_x86: put_word( IMAGE_FILE_MACHINE_I386 ); break; case CPU_x86_64: put_word( IMAGE_FILE_MACHINE_AMD64 ); break; case CPU_POWERPC: put_word( IMAGE_FILE_MACHINE_POWERPC ); break; case CPU_SPARC: put_word( IMAGE_FILE_MACHINE_SPARC ); break; case CPU_ARM: put_word( IMAGE_FILE_MACHINE_ARMV7 ); break; } put_word( nb_sections ); /* NumberOfSections */ put_dword( 0 ); /* TimeDateStamp */ put_dword( 0 ); /* PointerToSymbolTable */ put_dword( 0 ); /* NumberOfSymbols */ put_word( get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); /* SizeOfOptionalHeader */ put_word( spec->characteristics ); /* Characteristics */ put_word( get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); /* Magic */ put_byte( 0 ); /* MajorLinkerVersion */ put_byte( 0 ); /* MinorLinkerVersion */ put_dword( text_size ); /* SizeOfCode */ put_dword( 0 ); /* SizeOfInitializedData */ put_dword( 0 ); /* SizeOfUninitializedData */ put_dword( section_align ); /* AddressOfEntryPoint */ put_dword( section_align ); /* BaseOfCode */ if (get_ptr_size() == 4) put_dword( 0 ); /* BaseOfData */ put_pword( 0x10000000 ); /* ImageBase */ put_dword( section_align ); /* SectionAlignment */ put_dword( file_align ); /* FileAlignment */ put_word( 1 ); /* MajorOperatingSystemVersion */ put_word( 0 ); /* MinorOperatingSystemVersion */ put_word( 0 ); /* MajorImageVersion */ put_word( 0 ); /* MinorImageVersion */ put_word( spec->subsystem_major ); /* MajorSubsystemVersion */ put_word( spec->subsystem_minor ); /* MinorSubsystemVersion */ put_dword( 0 ); /* Win32VersionValue */ put_dword( image_size ); /* SizeOfImage */ put_dword( file_align ); /* SizeOfHeaders */ put_dword( 0 ); /* CheckSum */ put_word( spec->subsystem ); /* Subsystem */ put_word( spec->dll_characteristics ); /* DllCharacteristics */ put_pword( (spec->stack_size ? spec->stack_size : 1024) * 1024 ); /* SizeOfStackReserve */ put_pword( page_size ); /* SizeOfStackCommit */ put_pword( (spec->heap_size ? spec->heap_size : 1024) * 1024 ); /* SizeOfHeapReserve */ put_pword( page_size ); /* SizeOfHeapCommit */ put_dword( 0 ); /* LoaderFlags */ put_dword( 16 ); /* NumberOfRvaAndSizes */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ if (resources_size) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */ { put_dword( 3 * section_align ); put_dword( resources_size ); } else { put_dword( 0 ); put_dword( 0 ); } put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] */ put_dword( 2 * section_align ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] */ put_dword( reloc_size ); put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] */ put_dword( 0 ); put_dword( 0 ); /* DataDirectory[15] */ /* .text section */ put_data( ".text\0\0", 8 ); /* Name */ put_dword( section_align ); /* VirtualSize */ put_dword( section_align ); /* VirtualAddress */ put_dword( text_size ); /* SizeOfRawData */ put_dword( file_align ); /* PointerToRawData */ put_dword( 0 ); /* PointerToRelocations */ put_dword( 0 ); /* PointerToLinenumbers */ put_word( 0 ); /* NumberOfRelocations */ put_word( 0 ); /* NumberOfLinenumbers */ put_dword( 0x60000020 /* CNT_CODE|MEM_EXECUTE|MEM_READ */ ); /* Characteristics */ /* .reloc section */ put_data( ".reloc\0", 8 ); /* Name */ put_dword( section_align ); /* VirtualSize */ put_dword( 2 * section_align );/* VirtualAddress */ put_dword( reloc_size ); /* SizeOfRawData */ put_dword( 2 * file_align ); /* PointerToRawData */ put_dword( 0 ); /* PointerToRelocations */ put_dword( 0 ); /* PointerToLinenumbers */ put_word( 0 ); /* NumberOfRelocations */ put_word( 0 ); /* NumberOfLinenumbers */ put_dword( 0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ ); /* Characteristics */ /* .rsrc section */ if (resources_size) { put_data( ".rsrc\0\0", 8 ); /* Name */ put_dword( (resources_size + section_align - 1) & ~(section_align - 1) ); /* VirtualSize */ put_dword( 3 * section_align );/* VirtualAddress */ put_dword( resources_size ); /* SizeOfRawData */ put_dword( 3 * file_align ); /* PointerToRawData */ put_dword( 0 ); /* PointerToRelocations */ put_dword( 0 ); /* PointerToLinenumbers */ put_word( 0 ); /* NumberOfRelocations */ put_word( 0 ); /* NumberOfLinenumbers */ put_dword( 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ ); /* Characteristics */ } /* .text contents */ align_output( file_align ); if (spec->characteristics & IMAGE_FILE_DLL) put_data( dll_code_section, sizeof(dll_code_section) ); else put_data( exe_code_section, sizeof(exe_code_section) ); /* .reloc contents */ align_output( file_align ); put_dword( 0 ); /* VirtualAddress */ put_dword( 0 ); /* SizeOfBlock */ /* .rsrc contents */ if (resources_size) { align_output( file_align ); put_data( resources, resources_size ); } flush_output_buffer(); }
/******************************************************************* * output_fake_module16 * * Create a fake 16-bit binary module. */ void output_fake_module16( DLLSPEC *spec ) { static const unsigned char code_segment[] = { 0x90, 0xc3 }; static const unsigned char data_segment[16] = { 0 }; static const char fakedll_signature[] = "Wine placeholder DLL"; const unsigned int cseg = 2; const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15; const unsigned int segtab = lfanew + 0x40; unsigned int i, rsrctab, restab, namelen, modtab, imptab, enttab, cbenttab, codeseg, dataseg, rsrcdata; init_output_buffer(); rsrctab = lfanew; restab = segtab + 8 * cseg; if (spec->nb_resources) { output_bin_res16_directory( spec, 0 ); align_output( 2 ); rsrctab = restab; restab += output_buffer_pos; free( output_buffer ); init_output_buffer(); } namelen = strlen( spec->dll_name ); modtab = restab + ((namelen + 3) & ~1); imptab = modtab; enttab = modtab + 2; cbenttab = 1; codeseg = (enttab + cbenttab + 1) & ~1; dataseg = codeseg + sizeof(code_segment); rsrcdata = dataseg + sizeof(data_segment); init_output_buffer(); put_word( 0x5a4d ); /* e_magic */ put_word( 0x40 ); /* e_cblp */ put_word( 0x01 ); /* e_cp */ put_word( 0 ); /* e_crlc */ put_word( lfanew / 16 ); /* e_cparhdr */ put_word( 0x0000 ); /* e_minalloc */ put_word( 0xffff ); /* e_maxalloc */ put_word( 0x0000 ); /* e_ss */ put_word( 0x00b8 ); /* e_sp */ put_word( 0 ); /* e_csum */ put_word( 0 ); /* e_ip */ put_word( 0 ); /* e_cs */ put_word( lfanew ); /* e_lfarlc */ put_word( 0 ); /* e_ovno */ put_dword( 0 ); /* e_res */ put_dword( 0 ); put_word( 0 ); /* e_oemid */ put_word( 0 ); /* e_oeminfo */ put_dword( 0 ); /* e_res2 */ put_dword( 0 ); put_dword( 0 ); put_dword( 0 ); put_dword( 0 ); put_dword( lfanew ); put_data( fakedll_signature, sizeof(fakedll_signature) ); align_output( 16 ); put_word( 0x454e ); /* ne_magic */ put_byte( 0 ); /* ne_ver */ put_byte( 0 ); /* ne_rev */ put_word( enttab - lfanew ); /* ne_enttab */ put_word( cbenttab ); /* ne_cbenttab */ put_dword( 0 ); /* ne_crc */ put_word( NE_FFLAGS_SINGLEDATA | /* ne_flags */ ((spec->characteristics & IMAGE_FILE_DLL) ? NE_FFLAGS_LIBMODULE : 0) ); put_word( 2 ); /* ne_autodata */ put_word( spec->heap_size ); /* ne_heap */ put_word( 0 ); /* ne_stack */ put_word( 0 ); put_word( 0 ); /* ne_csip */ put_word( 0 ); put_word( 2 ); /* ne_sssp */ put_word( cseg ); /* ne_cseg */ put_word( 0 ); /* ne_cmod */ put_word( 0 ); /* ne_cbnrestab */ put_word( segtab - lfanew ); /* ne_segtab */ put_word( rsrctab - lfanew ); /* ne_rsrctab */ put_word( restab - lfanew ); /* ne_restab */ put_word( modtab - lfanew ); /* ne_modtab */ put_word( imptab - lfanew ); /* ne_imptab */ put_dword( 0 ); /* ne_nrestab */ put_word( 0 ); /* ne_cmovent */ put_word( 0 ); /* ne_align */ put_word( 0 ); /* ne_cres */ put_byte( 2 /*NE_OSFLAGS_WINDOWS*/ ); /* ne_exetyp */ put_byte( 8 /*NE_AFLAGS_FASTLOAD*/ ); /* ne_flagsothers */ put_word( 0 ); /* ne_pretthunks */ put_word( 0 ); /* ne_psegrefbytes */ put_word( 0 ); /* ne_swaparea */ put_word( 0 ); /* ne_expver */ /* segment table */ put_word( codeseg ); put_word( sizeof(code_segment) ); put_word( 0x2000 /* NE_SEGFLAGS_32BIT */ ); put_word( sizeof(code_segment) ); put_word( dataseg ); put_word( sizeof(data_segment) ); put_word( 0x0001 /* NE_SEGFLAGS_DATA */ ); put_word( sizeof(data_segment) ); /* resource directory */ if (spec->nb_resources) { output_bin_res16_directory( spec, rsrcdata ); align_output( 2 ); } /* resident names table */ put_byte( namelen ); for (i = 0; i < namelen; i++) put_byte( toupper(spec->dll_name[i]) ); put_byte( 0 ); align_output( 2 ); /* imported names table */ put_word( 0 ); /* entry table */ put_byte( 0 ); align_output( 2 ); /* code segment */ put_data( code_segment, sizeof(code_segment) ); /* data segment */ put_data( data_segment, sizeof(data_segment) ); /* resource data */ output_bin_res16_data( spec ); flush_output_buffer(); }
static HRESULT WINAPI mxwriter_flush(IMXWriter *iface) { mxwriter *This = impl_from_IMXWriter( iface ); TRACE("(%p)\n", This); return flush_output_buffer(This); }
/* output the resources into a .o file */ void output_res_o_file( DLLSPEC *spec ) { unsigned int i; char *res_file = NULL; int fd; struct strarray *args; if (!spec->nb_resources) fatal_error( "--resources mode needs at least one resource file as input\n" ); if (!output_file_name) fatal_error( "No output file name specified\n" ); qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res ); remove_duplicate_resources( spec ); byte_swapped = 0; init_output_buffer(); put_dword( 0 ); /* ResSize */ put_dword( 32 ); /* HeaderSize */ put_word( 0xffff ); /* ResType */ put_word( 0x0000 ); put_word( 0xffff ); /* ResName */ put_word( 0x0000 ); put_dword( 0 ); /* DataVersion */ put_word( 0 ); /* Memory options */ put_word( 0 ); /* Language */ put_dword( 0 ); /* Version */ put_dword( 0 ); /* Characteristics */ for (i = 0; i < spec->nb_resources; i++) { unsigned int header_size = get_resource_header_size( &spec->resources[i] ); put_dword( spec->resources[i].data_size ); put_dword( (header_size + 3) & ~3 ); put_string( &spec->resources[i].type ); put_string( &spec->resources[i].name ); align_output( 4 ); put_dword( 0 ); put_word( spec->resources[i].mem_options ); put_word( spec->resources[i].lang ); put_dword( spec->resources[i].version ); put_dword( 0 ); put_data( spec->resources[i].data, spec->resources[i].data_size ); align_output( 4 ); } /* if the output file name is a .res too, don't run the results through windres */ if (strendswith( output_file_name, ".res")) { flush_output_buffer(); return; } res_file = get_temp_file_name( output_file_name, ".res" ); if ((fd = open( res_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600 )) == -1) fatal_error( "Cannot create %s\n", res_file ); if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos) fatal_error( "Error writing to %s\n", res_file ); close( fd ); free( output_buffer ); args = find_tool( "windres", NULL ); strarray_add( args, "-i", res_file, "-o", output_file_name, NULL ); spawn( args ); strarray_free( args ); output_file_name = NULL; /* so we don't try to assemble it */ }
/* output the resources into a .o file */ void output_res_o_file( DLLSPEC *spec ) { unsigned int i; char *res_file = NULL; int fd, err; if (!spec->nb_resources) fatal_error( "--resources mode needs at least one resource file as input\n" ); if (!output_file_name) fatal_error( "No output file name specified\n" ); byte_swapped = 0; init_output_buffer(); put_dword( 0 ); /* ResSize */ put_dword( 32 ); /* HeaderSize */ put_word( 0xffff ); /* ResType */ put_word( 0x0000 ); put_word( 0xffff ); /* ResName */ put_word( 0x0000 ); put_dword( 0 ); /* DataVersion */ put_word( 0 ); /* Memory options */ put_word( 0 ); /* Language */ put_dword( 0 ); /* Version */ put_dword( 0 ); /* Characteristics */ for (i = 0; i < spec->nb_resources; i++) { unsigned int header_size = get_resource_header_size( &spec->resources[i] ); put_dword( spec->resources[i].data_size ); put_dword( (header_size + 3) & ~3 ); put_string( &spec->resources[i].type ); put_string( &spec->resources[i].name ); align_output( 4 ); put_dword( 0 ); put_word( spec->resources[i].mem_options ); put_word( spec->resources[i].lang ); put_dword( 0 ); put_dword( 0 ); put_data( spec->resources[i].data, spec->resources[i].data_size ); align_output( 4 ); } /* if the output file name is a .res too, don't run the results through windres */ if (strendswith( output_file_name, ".res")) { flush_output_buffer(); return; } res_file = get_temp_file_name( output_file_name, ".res" ); if ((fd = open( res_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600 )) == -1) fatal_error( "Cannot create %s\n", res_file ); if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos) fatal_error( "Error writing to %s\n", res_file ); close( fd ); free( output_buffer ); if (res_file) { char *prog = find_tool( "windres", NULL ); char *cmd = xmalloc( strlen(prog) + strlen(res_file) + strlen(output_file_name) + 9 ); sprintf( cmd, "%s -i %s -o %s", prog, res_file, output_file_name ); if (verbose) fprintf( stderr, "%s\n", cmd ); err = system( cmd ); if (err) fatal_error( "%s failed with status %d\n", prog, err ); free( cmd ); free( prog ); } output_file_name = NULL; /* so we don't try to assemble it */ }
/** * Write one or more arrays with the same IO decomposition to the * file. * * This funciton is similar to PIOc_write_darray(), but allows the * caller to use their own data buffering (instead of using the * buffering implemented in PIOc_write_darray()). * * When the user calls PIOc_write_darray() one or more times, then * PIO_write_darray_multi() will be called when the buffer is flushed. * * Internally, this function will: * <ul> * <li>Find info about file, decomposition, and variable. * <li>Do a special flush for pnetcdf if needed. * <li>Allocates a buffer big enough to hold all the data in the * multi-buffer, for all tasks. * <li>Calls rearrange_comp2io() to move data from compute to IO * tasks. * <li>For parallel iotypes (pnetcdf and netCDF-4 parallel) call * pio_write_darray_multi_nc(). * <li>For serial iotypes (netcdf classic and netCDF-4 serial) call * write_darray_multi_serial(). * <li>For subset rearranger, create holegrid to write missing * data. Then call pio_write_darray_multi_nc() or * write_darray_multi_serial() to write the holegrid. * <li>Special buffer flush for pnetcdf. * </ul> * * @param ncid identifies the netCDF file. * @param varids an array of length nvars containing the variable ids to * be written. * @param ioid the I/O description ID as passed back by * PIOc_InitDecomp(). * @param nvars the number of variables to be written with this * call. * @param arraylen the length of the array to be written. This is the * length of the distrubited array. That is, the length of the portion * of the data that is on the processor. The same arraylen is used for * all variables in the call. * @param array pointer to the data to be written. This is a pointer * to an array of arrays with the distributed portion of the array * that is on this processor. There are nvars arrays of data, and each * array of data contains one record worth of data for that variable. * @param frame an array of length nvars with the frame or record * dimension for each of the nvars variables in IOBUF. NULL if this * iodesc contains non-record vars. * @param fillvalue pointer an array (of length nvars) of pointers to * the fill value to be used for missing data. * @param flushtodisk non-zero to cause buffers to be flushed to disk. * @return 0 for success, error code otherwise. * @ingroup PIO_write_darray * @author Jim Edwards, Ed Hartnett */ int PIOc_write_darray_multi(int ncid, const int *varids, int ioid, int nvars, PIO_Offset arraylen, void *array, const int *frame, void **fillvalue, bool flushtodisk) { iosystem_desc_t *ios; /* Pointer to io system information. */ file_desc_t *file; /* Pointer to file information. */ io_desc_t *iodesc; /* Pointer to IO description information. */ int rlen; /* Total data buffer size. */ var_desc_t *vdesc0; /* First entry in array of var_desc structure for each var. */ int fndims; /* Number of dims in the var in the file. */ int mpierr = MPI_SUCCESS, mpierr2; /* Return code from MPI function calls. */ int ierr; /* Return code. */ /* Get the file info. */ if ((ierr = pio_get_file(ncid, &file))) return pio_err(NULL, NULL, PIO_EBADID, __FILE__, __LINE__); ios = file->iosystem; /* Check inputs. */ if (nvars <= 0 || !varids) return pio_err(ios, file, PIO_EINVAL, __FILE__, __LINE__); LOG((1, "PIOc_write_darray_multi ncid = %d ioid = %d nvars = %d arraylen = %ld " "flushtodisk = %d", ncid, ioid, nvars, arraylen, flushtodisk)); /* Check that we can write to this file. */ if (!file->writable) return pio_err(ios, file, PIO_EPERM, __FILE__, __LINE__); /* Get iodesc. */ if (!(iodesc = pio_get_iodesc_from_id(ioid))) return pio_err(ios, file, PIO_EBADID, __FILE__, __LINE__); pioassert(iodesc->rearranger == PIO_REARR_BOX || iodesc->rearranger == PIO_REARR_SUBSET, "unknown rearranger", __FILE__, __LINE__); /* Check the types of all the vars. They must match the type of * the decomposition. */ for (int v = 0; v < nvars; v++) { var_desc_t *vdesc; if ((ierr = get_var_desc(varids[v], &file->varlist, &vdesc))) return pio_err(ios, file, ierr, __FILE__, __LINE__); if (vdesc->pio_type != iodesc->piotype) return pio_err(ios, file, PIO_EINVAL, __FILE__, __LINE__); } /* Get a pointer to the variable info for the first variable. */ if ((ierr = get_var_desc(varids[0], &file->varlist, &vdesc0))) return pio_err(ios, file, ierr, __FILE__, __LINE__); /* Run these on all tasks if async is not in use, but only on * non-IO tasks if async is in use. */ if (!ios->async || !ios->ioproc) { /* Get the number of dims for this var. */ LOG((3, "about to call PIOc_inq_varndims varids[0] = %d", varids[0])); if ((ierr = PIOc_inq_varndims(file->pio_ncid, varids[0], &fndims))) return check_netcdf(file, ierr, __FILE__, __LINE__); LOG((3, "called PIOc_inq_varndims varids[0] = %d fndims = %d", varids[0], fndims)); } /* If async is in use, and this is not an IO task, bcast the parameters. */ if (ios->async) { if (!ios->ioproc) { int msg = PIO_MSG_WRITEDARRAYMULTI; char frame_present = frame ? true : false; /* Is frame non-NULL? */ char fillvalue_present = fillvalue ? true : false; /* Is fillvalue non-NULL? */ int flushtodisk_int = flushtodisk; /* Need this to be int not boolean. */ if (ios->compmaster == MPI_ROOT) mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); /* Send the function parameters and associated informaiton * to the msg handler. */ if (!mpierr) mpierr = MPI_Bcast(&ncid, 1, MPI_INT, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&nvars, 1, MPI_INT, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast((void *)varids, nvars, MPI_INT, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&ioid, 1, MPI_INT, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&arraylen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(array, arraylen * iodesc->piotype_size, MPI_CHAR, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&frame_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); if (!mpierr && frame_present) mpierr = MPI_Bcast((void *)frame, nvars, MPI_INT, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&fillvalue_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); if (!mpierr && fillvalue_present) mpierr = MPI_Bcast((void *)fillvalue, nvars * iodesc->piotype_size, MPI_CHAR, ios->compmaster, ios->intercomm); if (!mpierr) mpierr = MPI_Bcast(&flushtodisk_int, 1, MPI_INT, ios->compmaster, ios->intercomm); LOG((2, "PIOc_write_darray_multi file->pio_ncid = %d nvars = %d ioid = %d arraylen = %d " "frame_present = %d fillvalue_present = %d flushtodisk = %d", file->pio_ncid, nvars, ioid, arraylen, frame_present, fillvalue_present, flushtodisk)); } /* Handle MPI errors. */ if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->comproot, ios->my_comm))) return check_mpi(file, mpierr2, __FILE__, __LINE__); if (mpierr) return check_mpi(file, mpierr, __FILE__, __LINE__); /* Share results known only on computation tasks with IO tasks. */ if ((mpierr = MPI_Bcast(&fndims, 1, MPI_INT, ios->comproot, ios->my_comm))) check_mpi(file, mpierr, __FILE__, __LINE__); LOG((3, "shared fndims = %d", fndims)); } /* if the buffer is already in use in pnetcdf we need to flush first */ if (file->iotype == PIO_IOTYPE_PNETCDF && file->iobuf) if ((ierr = flush_output_buffer(file, 1, 0))) return pio_err(ios, file, ierr, __FILE__, __LINE__); pioassert(!file->iobuf, "buffer overwrite",__FILE__, __LINE__); /* Determine total size of aggregated data (all vars/records). * For netcdf serial writes we collect the data on io nodes and * then move that data one node at a time to the io master node * and write (or read). The buffer size on io task 0 must be as * large as the largest used to accommodate this serial io * method. */ rlen = 0; if (iodesc->llen > 0) rlen = iodesc->maxiobuflen * nvars; /* Allocate iobuf. */ if (rlen > 0) { /* Allocate memory for the buffer for all vars/records. */ if (!(file->iobuf = bget(iodesc->mpitype_size * (size_t)rlen))) return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__); LOG((3, "allocated %lld bytes for variable buffer", (size_t)rlen * iodesc->mpitype_size)); /* If fill values are desired, and we're using the BOX * rearranger, insert fill values. */ if (iodesc->needsfill && iodesc->rearranger == PIO_REARR_BOX) { LOG((3, "inerting fill values iodesc->maxiobuflen = %d", iodesc->maxiobuflen)); for (int nv = 0; nv < nvars; nv++) for (int i = 0; i < iodesc->maxiobuflen; i++) memcpy(&((char *)file->iobuf)[iodesc->mpitype_size * (i + nv * iodesc->maxiobuflen)], &((char *)fillvalue)[nv * iodesc->mpitype_size], iodesc->mpitype_size); } } else if (file->iotype == PIO_IOTYPE_PNETCDF && ios->ioproc) { /* this assures that iobuf is allocated on all iotasks thus assuring that the flush_output_buffer call above is called collectively (from all iotasks) */ if (!(file->iobuf = bget(1))) return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__); LOG((3, "allocated token for variable buffer")); } /* Move data from compute to IO tasks. */ if ((ierr = rearrange_comp2io(ios, iodesc, array, file->iobuf, nvars))) return pio_err(ios, file, ierr, __FILE__, __LINE__); /* Write the darray based on the iotype. */ LOG((2, "about to write darray for iotype = %d", file->iotype)); switch (file->iotype) { case PIO_IOTYPE_NETCDF4P: case PIO_IOTYPE_PNETCDF: if ((ierr = write_darray_multi_par(file, nvars, fndims, varids, iodesc, DARRAY_DATA, frame))) return pio_err(ios, file, ierr, __FILE__, __LINE__); break; case PIO_IOTYPE_NETCDF4C: case PIO_IOTYPE_NETCDF: if ((ierr = write_darray_multi_serial(file, nvars, fndims, varids, iodesc, DARRAY_DATA, frame))) return pio_err(ios, file, ierr, __FILE__, __LINE__); break; default: return pio_err(NULL, NULL, PIO_EBADIOTYPE, __FILE__, __LINE__); } /* For PNETCDF the iobuf is freed in flush_output_buffer() */ if (file->iotype != PIO_IOTYPE_PNETCDF) { /* Release resources. */ if (file->iobuf) { LOG((3,"freeing variable buffer in pio_darray")); brel(file->iobuf); file->iobuf = NULL; } } /* The box rearranger will always have data (it could be fill * data) to fill the entire array - that is the aggregate start * and count values will completely describe one unlimited * dimension unit of the array. For the subset method this is not * necessarily the case, areas of missing data may never be * written. In order to make sure that these areas are given the * missing value a 'holegrid' is used to describe the missing * points. This is generally faster than the netcdf method of * filling the entire array with missing values before overwriting * those values later. */ if (iodesc->rearranger == PIO_REARR_SUBSET && iodesc->needsfill) { LOG((2, "nvars = %d holegridsize = %ld iodesc->needsfill = %d\n", nvars, iodesc->holegridsize, iodesc->needsfill)); pioassert(!vdesc0->fillbuf, "buffer overwrite",__FILE__, __LINE__); /* Get a buffer. */ if (ios->io_rank == 0) vdesc0->fillbuf = bget(iodesc->maxholegridsize * iodesc->mpitype_size * nvars); else if (iodesc->holegridsize > 0) vdesc0->fillbuf = bget(iodesc->holegridsize * iodesc->mpitype_size * nvars); /* copying the fill value into the data buffer for the box * rearranger. This will be overwritten with data where * provided. */ for (int nv = 0; nv < nvars; nv++) for (int i = 0; i < iodesc->holegridsize; i++) memcpy(&((char *)vdesc0->fillbuf)[iodesc->mpitype_size * (i + nv * iodesc->holegridsize)], &((char *)fillvalue)[iodesc->mpitype_size * nv], iodesc->mpitype_size); /* Write the darray based on the iotype. */ switch (file->iotype) { case PIO_IOTYPE_PNETCDF: case PIO_IOTYPE_NETCDF4P: if ((ierr = write_darray_multi_par(file, nvars, fndims, varids, iodesc, DARRAY_FILL, frame))) return pio_err(ios, file, ierr, __FILE__, __LINE__); break; case PIO_IOTYPE_NETCDF4C: case PIO_IOTYPE_NETCDF: if ((ierr = write_darray_multi_serial(file, nvars, fndims, varids, iodesc, DARRAY_FILL, frame))) return pio_err(ios, file, ierr, __FILE__, __LINE__); break; default: return pio_err(ios, file, PIO_EBADIOTYPE, __FILE__, __LINE__); } /* For PNETCDF fillbuf is freed in flush_output_buffer() */ if (file->iotype != PIO_IOTYPE_PNETCDF) { /* Free resources. */ if (vdesc0->fillbuf) { brel(vdesc0->fillbuf); vdesc0->fillbuf = NULL; } } } /* Flush data to disk for pnetcdf. */ if (ios->ioproc && file->iotype == PIO_IOTYPE_PNETCDF) if ((ierr = flush_output_buffer(file, flushtodisk, 0))) return pio_err(ios, file, ierr, __FILE__, __LINE__); return PIO_NOERR; }
/// /// PIO interface to nc_function /// /// This routine is called collectively by all tasks in the communicator ios.union_comm. /// /// Refer to the <A HREF="http://www.unidata.ucar.edu/software/netcdf/docs/netcdf_documentation.html"> netcdf documentation. </A> /// int PIO_function() { int ierr; int msg; int mpierr; iosystem_desc_t *ios; file_desc_t *file; var_desc_t *vdesc; PIO_Offset usage; int *request; ierr = PIO_NOERR; file = pio_get_file_from_id(ncid); if(file == NULL) return PIO_EBADID; ios = file->iosystem; msg = 0; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); } if(ios->ioproc){ switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 case PIO_IOTYPE_NETCDF4P: ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); ierr = nc_function(); break; case PIO_IOTYPE_NETCDF4C: #endif case PIO_IOTYPE_NETCDF: if(ios->io_rank==0){ ierr = nc_function(); } break; #endif #ifdef _PNETCDF case PIO_IOTYPE_PNETCDF: vdesc = file->varlist + varid; if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ vdesc->request = realloc(vdesc->request, sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); } request = vdesc->request+vdesc->nreqs; if(ios->io_rank==0){ ierr = ncmpi_function(); }else{ *request = PIO_REQ_NULL; } vdesc->nreqs++; flush_output_buffer(file, false, 0); break; #endif default: ierr = iotype_error(file->iotype,__FILE__,__LINE__); } } ierr = check_netcdf(file, ierr, __FILE__,__LINE__); return ierr; }
void flush() { flush_output_buffer(); }
void possibly_flush_output_buffer() { if (m_output_buffer.committed() > max_buffer_size_for_flush) { flush_output_buffer(); } }
/** * @name PIOc_sync */ int PIOc_sync (int ncid) { int ierr; int msg; int mpierr; iosystem_desc_t *ios; file_desc_t *file; wmulti_buffer *wmb, *twmb; ierr = PIO_NOERR; file = pio_get_file_from_id(ncid); if(file == NULL) return PIO_EBADID; ios = file->iosystem; msg = PIO_MSG_SYNC; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); } if((file->mode & PIO_WRITE)){ // cn_buffer_report( *ios, true); wmb = &(file->buffer); while(wmb != NULL){ // printf("%s %d %d %d\n",__FILE__,__LINE__,wmb->ioid, wmb->validvars); if(wmb->validvars>0){ flush_buffer(ncid, wmb, true); } twmb = wmb; wmb = wmb->next; if(twmb == &(file->buffer)){ twmb->ioid=-1; twmb->next=NULL; }else{ brel(twmb); } } flush_output_buffer(file, true, 0); if(ios->ioproc){ switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 case PIO_IOTYPE_NETCDF4P: ierr = nc_sync(file->fh);; break; case PIO_IOTYPE_NETCDF4C: #endif case PIO_IOTYPE_NETCDF: if(ios->io_rank==0){ ierr = nc_sync(file->fh);; } break; #endif #ifdef _PNETCDF case PIO_IOTYPE_PNETCDF: ierr = ncmpi_sync(file->fh);; break; #endif default: ierr = iotype_error(file->iotype,__FILE__,__LINE__); } } ierr = check_netcdf(file, ierr, __FILE__,__LINE__); } return ierr; }