int OOBase::Environment::get_block(const env_table_t& tabEnv, ScopedArrayPtr<wchar_t>& ptr) { if (tabEnv.empty()) return 0; // Copy and widen to UNICODE typedef SharedPtr<wchar_t> temp_wchar_t; // Sort environment block - UNICODE, no-locale, case-insensitive (from MSDN) struct env_sort { bool operator ()(const OOBase::SharedPtr<wchar_t>& s1, const OOBase::SharedPtr<wchar_t>& s2) const { return (_wcsicmp(s1.get(),s2.get()) < 0); } }; StackAllocator<1024> allocator; Table<temp_wchar_t,temp_wchar_t,env_sort,AllocatorInstance> wenv(env_sort(),allocator); size_t total_size = 0; for (env_table_t::const_iterator i=tabEnv.begin();i;++i) { int err = Win32::utf8_to_wchar_t(i->first.c_str(),ptr); if (!err) { // Include \0 and optionally '=' length size_t len = wcslen(ptr.get()); total_size += len + 1; temp_wchar_t key = make_shared(static_cast<wchar_t*>(allocator.allocate(len+1,alignment_of<wchar_t>::value)),allocator); if (!key) return ERROR_OUTOFMEMORY; wcscpy(key.get(),ptr.get()); err = Win32::utf8_to_wchar_t(i->second.c_str(),ptr); if (!err) { temp_wchar_t value; len = wcslen(ptr.get()); if (len) { total_size += len + 1; value = make_shared(static_cast<wchar_t*>(allocator.allocate(len+1,alignment_of<wchar_t>::value)),allocator); if (!value) return ERROR_OUTOFMEMORY; wcscpy(value.get(),ptr.get()); } if (!wenv.insert(key,value)) return ERROR_OUTOFMEMORY; } } if (err) return err; } // And now copy into one giant block if (!ptr.resize(total_size + 2)) return ERROR_OUTOFMEMORY; wchar_t* pout = ptr.get(); for (Table<temp_wchar_t,temp_wchar_t,env_sort,AllocatorInstance>::iterator i=wenv.begin();i;++i) { const wchar_t* p = i->first.get(); while (*p != L'\0') *pout++ = *p++; p = i->second.get(); if (p && *p != L'\0') { *pout++ = L'='; while (*p != L'\0') *pout++ = *p++; } *pout++ = L'\0'; } // Terminate with \0 *pout++ = L'\0'; *pout++ = L'\0'; return 0; }
stack_tuple( StackAllocator const& stack_alloc_, std::size_t size) : stack_ctx(), stack_alloc( stack_alloc_) { stack_alloc.allocate( stack_ctx, size); }