EncodedJSValue JSC_HOST_CALL COMMethodCall::call(ExecState* execState) { COMMethodCall* callee = jsCast<COMMethodCall*>(execState->callee()); if (execState->argumentCount() != callee->_parameterCells.size()) { // TODO: error CRASH(); } COMInterop* interop = jsCast<GlobalObject*>(execState->lexicalGlobalObject())->interop(); size_t numberOfABIParameters = callee->_parameterCells.size() + (callee->_isVoid ? 1 : 2); HRESULT hr; Microsoft::WRL::ComPtr<IUnknown> self; hr = interop->wrap(execState->thisValue(), callee->_methodInterface, self.GetAddressOf()); void** vtable = *reinterpret_cast<void***>(self.Get()); void* fn = vtable[callee->_methodIndex]; WTF::Vector<void*> arguments; arguments.reserveCapacity(numberOfABIParameters); IUnknown* thisValue = self.Get(); arguments.append(&thisValue); for (int i = 0; i < callee->_parameterCells.size(); i++) { JSCell* type = callee->_parameterCells[i].get(); void* buffer = _alloca(std::max(sizeof(ffi_arg), callee->_parameterTypes[i + 1]->size)); getFFIMethodTable(type)->marshalJSToNative(type, execState, execState->uncheckedArgument(i), buffer); arguments.append(buffer); } void* returnBuffer = nullptr; if (!callee->_isVoid) { returnBuffer = _alloca(std::max(sizeof(ffi_arg), callee->_parameterTypes[numberOfABIParameters - 1]->size)); arguments.append(&returnBuffer); } ffi_call(&callee->_cif, FFI_FN(fn), &hr, arguments.data()); JSValue jsResult; if (!SUCCEEDED(hr)) { _com_error error(hr, nullptr); jsResult = execState->vm().throwException(execState, createError(execState, error.ErrorMessage())); } else if (!callee->_isVoid) { JSCell* returnType = callee->_returnType.get(); jsResult = getFFIMethodTable(returnType)->marshalNativeToJS(returnType, execState, returnBuffer); } else { jsResult = jsUndefined(); } return JSValue::encode(jsResult); }
static void write_string(WTF::Vector<char>& v, const WebCore::String& str) { unsigned strLen = str.length(); // Only do work if the string has data. if (strLen) { // Determine how much to grow the vector. Use the worst case for utf8 to // avoid reading the string twice. Add sizeof(unsigned) to hold the // string length in utf8. unsigned vectorLen = v.size() + sizeof(unsigned); unsigned length = (strLen << 2) + vectorLen; // Grow the vector. This will change the value of v.size() but we // remember the original size above. v.grow(length); // Grab the position to write to. char* data = v.begin() + vectorLen; // Write the actual string int l = SkUTF16_ToUTF8(str.characters(), strLen, data); LOGV("Writing string %d %.*s", l, l, data); // Go back and write the utf8 length. Subtract sizeof(unsigned) from // data to get the position to write the length. memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); // Shrink the internal state of the vector so we match what was // actually written. v.shrink(vectorLen + l); } else v.append((char*)&strLen, sizeof(unsigned)); }
void SpellCheckerClientImpl::checkGrammarOfString(const String& text, WTF::Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength) { if (badGrammarLocation) *badGrammarLocation = -1; if (badGrammarLength) *badGrammarLength = 0; if (!m_webView->spellCheckClient()) return; WebVector<WebTextCheckingResult> webResults; m_webView->spellCheckClient()->checkTextOfParagraph(text, WebTextCheckingTypeGrammar, &webResults); if (!webResults.size()) return; // Convert a list of WebTextCheckingResults to a list of GrammarDetails. If // the converted vector of GrammarDetails has grammar errors, we set // badGrammarLocation and badGrammarLength to tell WebKit that the input // text has grammar errors. for (size_t i = 0; i < webResults.size(); ++i) { if (webResults[i].decoration == WebTextDecorationTypeGrammar) { GrammarDetail detail; detail.location = webResults[i].location; detail.length = webResults[i].length; detail.userDescription = webResults[i].replacement; details.append(detail); } } if (!details.size()) return; if (badGrammarLocation) *badGrammarLocation = 0; if (badGrammarLength) *badGrammarLength = text.length(); }
bool parseSuboriginHeader(const String& header, Suborigin* suborigin, WTF::Vector<String>& messages) { Vector<String> headers; header.split(',', true, headers); if (headers.size() > 1) messages.append("Multiple Suborigin headers found. Ignoring all but the first."); Vector<UChar> characters; headers[0].appendTo(characters); const UChar* position = characters.data(); const UChar* end = position + characters.size(); skipWhile<UChar, isASCIISpace>(position, end); String name; position = parseSuboriginName(position, end, name, messages); if (!position) return false; suborigin->setName(name); while (position < end) { skipWhile<UChar, isASCIISpace>(position, end); if (position == end) return true; String optionName; position = parseSuboriginPolicyOption(position, end, optionName, messages); if (!position) { suborigin->clear(); return false; } Suborigin::SuboriginPolicyOptions option = getSuboriginPolicyOptionFromString(optionName); if (option == Suborigin::SuboriginPolicyOptions::None) messages.append("Ignoring unknown suborigin policy option " + optionName + "."); else suborigin->addPolicyOption(option); } return true; }
void FileChooserPrivate::chooseFiles(const String* str, int items) { WTF::Vector<WebCore::String> ws; for (int i=0; i<items; i++) { ws.append(str[i]); } m_webcore->chooseFiles(ws); }
TEST(FontDescriptionTest, TestHashCollision) { FontWeight weights[] = { FontWeight100, FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900, }; FontStretch stretches[] { FontStretchUltraCondensed, FontStretchExtraCondensed, FontStretchCondensed, FontStretchSemiCondensed, FontStretchNormal, FontStretchSemiExpanded, FontStretchExpanded, FontStretchExtraExpanded, FontStretchUltraExpanded }; FontStyle styles[] = { FontStyleNormal, FontStyleOblique, FontStyleItalic }; FontVariant variants[] = { FontVariantNormal, FontVariantSmallCaps }; FontDescription source; WTF::Vector<unsigned> hashes; for (size_t i = 0; i < WTF_ARRAY_LENGTH(weights); i++) { source.setWeight(weights[i]); for (size_t j = 0; j < WTF_ARRAY_LENGTH(stretches); j++) { source.setStretch(stretches[j]); for (size_t k = 0; k < WTF_ARRAY_LENGTH(styles); k++) { source.setStyle(styles[k]); for (size_t m = 0; m < WTF_ARRAY_LENGTH(variants); m++) { source.setVariant(variants[m]); unsigned hash = source.styleHashWithoutFamilyList(); ASSERT_FALSE(hashes.contains(hash)); hashes.append(hash); } } } } }
WTF::Vector <BackingStoreClient*> BackingStoreClient::children() const { WTF::Vector<BackingStoreClient*> children; for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { BlackBerry::WebKit::BackingStoreClient* client = m_webPage->d->backingStoreClientForFrame(child); if (client) children.append(client); } return children; }
static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item) { // Original url write_string(v, item->originalURLString()); // Url write_string(v, item->urlString()); // Title write_string(v, item->title()); // Form content type write_string(v, item->formContentType()); // Form data const WebCore::FormData* formData = item->formData(); if (formData) { write_string(v, formData->flattenToString()); // save the identifier as it is not included in the flatten data int64_t id = formData->identifier(); v.append((char*)&id, sizeof(int64_t)); } else write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. // Target write_string(v, item->target()); AndroidWebHistoryBridge* bridge = item->bridge(); LOG_ASSERT(bridge, "We should have a bridge here!"); // Screen scale const int scale = bridge->scale(); LOGV("Writing scale %d", scale); v.append((char*)&scale, sizeof(int)); const int screenWidthScale = bridge->screenWidthScale(); LOGV("Writing screen width scale %d", screenWidthScale); v.append((char*)&screenWidthScale, sizeof(int)); // Document state const WTF::Vector<WebCore::String>& docState = item->documentState(); WTF::Vector<WebCore::String>::const_iterator end = docState.end(); unsigned stateSize = docState.size(); LOGV("Writing docState %d", stateSize); v.append((char*)&stateSize, sizeof(unsigned)); for (WTF::Vector<WebCore::String>::const_iterator i = docState.begin(); i != end; ++i) { write_string(v, *i); } // Is target item LOGV("Writing isTargetItem %d", item->isTargetItem()); v.append((char)item->isTargetItem()); // Children count unsigned childCount = item->children().size(); LOGV("Writing childCount %d", childCount); v.append((char*)&childCount, sizeof(unsigned)); }
void JavaBridge::UpdatePluginDirectories(JNIEnv* env, jobject obj, jobjectArray array, jboolean reload) { WTF::Vector<WTF::String> directories; int count = env->GetArrayLength(array); for (int i = 0; i < count; i++) { jstring dir = (jstring) env->GetObjectArrayElement(array, i); directories.append(jstringToWtfString(env, dir)); env->DeleteLocalRef(dir); } checkException(env); WebCore::PluginDatabase *pluginDatabase = WebCore::PluginDatabase::installedPlugins(); pluginDatabase->setPluginDirectories(directories); // refreshPlugins() should refresh both PluginDatabase and Page's PluginData WebCore::Page::refreshPlugins(reload); }
WTF::Vector<WebCore::String>JavaBridge::getSupportedKeyStrengthList() { WTF::Vector<WebCore::String> list; JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), mGetKeyStrengthList); int count = env->GetArrayLength(array); for (int i = 0; i < count; ++i) { jstring keyStrength = (jstring) env->GetObjectArrayElement(array, i); list.append(to_string(env, keyStrength)); env->DeleteLocalRef(keyStrength); } env->DeleteLocalRef(array); checkException(env); return list; }
// ReverseBidi is a trimmed-down version of GraphicsContext::drawBidiText() void ReverseBidi(UChar* chars, int len) { using namespace WTF::Unicode; WTF::Vector<UChar> result; result.reserveCapacity(len); TextRun run(chars, len); BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs(); bidiResolver.setStatus(BidiStatus(LeftToRight, LeftToRight, LeftToRight, BidiContext::create(0, LeftToRight, false))); bidiResolver.setPosition(TextRunIterator(&run, 0)); bidiResolver.createBidiRunsForLine(TextRunIterator(&run, len)); if (!bidiRuns.runCount()) return; BidiCharacterRun* bidiRun = bidiRuns.firstRun(); while (bidiRun) { int bidiStart = bidiRun->start(); int bidiStop = bidiRun->stop(); int size = result.size(); int bidiCount = bidiStop - bidiStart; result.append(chars + bidiStart, bidiCount); if (bidiRun->level() % 2) { UChar* start = &result[size]; UChar* end = start + bidiCount; // reverse the order of any RTL substrings while (start < end) { UChar temp = *start; *start++ = *--end; *end = temp; } start = &result[size]; end = start + bidiCount - 1; // if the RTL substring had a surrogate pair, restore its order while (start < end) { UChar trail = *start++; if (!U16_IS_SURROGATE(trail)) continue; start[-1] = *start; // lead *start++ = trail; } } bidiRun = bidiRun->next(); } bidiRuns.deleteRuns(); memcpy(chars, &result[0], len * sizeof(UChar)); }
WTF::Vector<WebCore::String> JavaBridge::getPluginDirectories() { WTF::Vector<WebCore::String> directories; JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = getRealObject(env, mJavaObject); jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), mGetPluginDirectories); int count = env->GetArrayLength(array); for (int i = 0; i < count; i++) { jstring dir = (jstring) env->GetObjectArrayElement(array, i); directories.append(to_string(env, dir)); env->DeleteLocalRef(dir); } env->DeleteLocalRef(array); checkException(env); return directories; }
void EditorClient::getGuessesForWord(const String& word, WTF::Vector<String>& guesses) { GSList* langs = webkit_web_settings_get_spell_languages(m_webView); guesses.clear(); for (; langs; langs = langs->next) { size_t numberOfSuggestions; size_t i; SpellLanguage* lang = static_cast<SpellLanguage*>(langs->data); gchar** suggestions = enchant_dict_suggest(lang->speller, word.utf8().data(), -1, &numberOfSuggestions); for (i = 0; i < numberOfSuggestions && i < 10; i++) guesses.append(String::fromUTF8(suggestions[i])); if (numberOfSuggestions > 0) enchant_dict_free_suggestions(lang->speller, suggestions); } }
void TilesManager::paintedSurfacesCleanup(GLWebViewState* state) { // PaintedSurfaces are created by LayerAndroid with a refcount of 1, // and just transferred to new (corresponding) layers when a new layer tree // is received. // PaintedSurface also keep a reference on the Layer it currently has, so // when we unref the tree of layer, those layers with a PaintedSurface will // still be around if we do nothing. // Here, if the surface does not have any associated layer, it means that we // received a new layer tree without a corresponding layer (i.e. a layer // using a texture has been removed by webkit). // In that case, we remove the PaintedSurface from our list, and unref it. // If the surface does have a layer, but the GLWebViewState associated to // that layer is different from the one passed in parameter, it means we can // also remove the surface (and we also remove/unref any layer that surface // has). We do this when we deallocate GLWebViewState (i.e. the webview has // been destroyed) and also when we switch to a page without // composited layers. WTF::Vector<PaintedSurface*> collect; for (unsigned int i = 0; i < m_paintedSurfaces.size(); i++) { PaintedSurface* surface = m_paintedSurfaces[i]; Layer* drawing = surface->drawingLayer(); Layer* painting = surface->paintingLayer(); XLOG("considering PS %p, drawing %p, painting %p", surface, drawing, painting); bool drawingMatchesState = state && drawing && (drawing->state() == state); bool paintingMatchesState = state && painting && (painting->state() == state); if ((!painting && !drawing) || drawingMatchesState || paintingMatchesState) { XLOG("trying to remove PS %p, painting %p, drawing %p, DMS %d, PMS %d", surface, painting, drawing, drawingMatchesState, paintingMatchesState); collect.append(surface); } } for (unsigned int i = 0; i < collect.size(); i++) { PaintedSurface* surface = collect[i]; m_paintedSurfaces.remove(m_paintedSurfaces.find(surface)); SkSafeUnref(surface); } }
void EditorClient::getGuessesForWord(const String& word, WTF::Vector<String>& guesses) { GSList* dicts = webkit_web_settings_get_enchant_dicts(m_webView); guesses.clear(); for (; dicts; dicts = dicts->next) { size_t numberOfSuggestions; size_t i; EnchantDict* dict = static_cast<EnchantDict*>(dicts->data); gchar** suggestions = enchant_dict_suggest(dict, word.utf8().data(), -1, &numberOfSuggestions); for (i = 0; i < numberOfSuggestions && i < 10; i++) guesses.append(String::fromUTF8(suggestions[i])); if (numberOfSuggestions > 0) enchant_dict_free_suggestions(dict, suggestions); } }
void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount, WTF::Vector<TileTexture*>& textures, bool deallocateGLTextures) { const unsigned int max = textures.size(); int dealloc = 0; WTF::Vector<int> discardedIndex; for (unsigned int i = 0; i < max; i++) { TextureOwner* owner = textures[i]->owner(); if (!owner || owner->drawCount() < sparedDrawCount) { if (deallocateGLTextures) { // deallocate textures' gl memory textures[i]->discardGLTexture(); discardedIndex.append(i); } else if (owner) { // simply detach textures from owner static_cast<Tile*>(owner)->discardTextures(); } dealloc++; } } bool base = textures == m_textures; // Clean up the vector of TileTextures and reset the max texture count. if (discardedIndex.size()) { android::Mutex::Autolock lock(m_texturesLock); for (int i = discardedIndex.size() - 1; i >= 0; i--) textures.remove(discardedIndex[i]); int remainedTextureNumber = textures.size(); int* countPtr = base ? &m_currentTextureCount : &m_currentLayerTextureCount; if (remainedTextureNumber < *countPtr) { ALOGV("reset currentTextureCount for %s tiles from %d to %d", base ? "base" : "layer", *countPtr, remainedTextureNumber); *countPtr = remainedTextureNumber; } } ALOGV("Discarded %d %s textures (out of %d %s tiles)", dealloc, (deallocateGLTextures ? "gl" : ""), max, base ? "base" : "layer"); }
static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) { LOG_ASSERT(frame, "Close needs a valid Frame pointer!"); WebCore::Frame* pFrame = (WebCore::Frame*)frame; WebCore::BackForwardList* list = pFrame->page()->backForwardList(); RefPtr<WebCore::HistoryItem> current = list->currentItem(); // Remove each item instead of using close(). close() is intended to be used // right before the list is deleted. WebCore::HistoryItemVector& entries = list->entries(); int size = entries.size(); for (int i = size - 1; i >= 0; --i) list->removeItem(entries[i].get()); // Add the current item back to the list. if (current) { current->setBridge(0); // addItem will update the children to match the newly created bridge list->addItem(current); /* * The Grand Prix site uses anchor navigations to change the display. * WebKit tries to be smart and not load child frames that have the * same history urls during an anchor navigation. This means that the * current history item stored in the child frame's loader does not * match the item found in the history tree. If we remove all the * entries in the back/foward list, we have to restore the entire tree * or else a HistoryItem might have a deleted parent. * * In order to restore the history tree correctly, we have to look up * all the frames first and then look up the history item. We do this * because the history item in the tree may be null at this point. * Unfortunately, a HistoryItem can only search its immediately * children so we do a breadth-first rebuild of the tree. */ // Keep a small list of child frames to traverse. WTF::Vector<WebCore::Frame*> frameQueue; // Fix the top-level item. pFrame->loader()->history()->setCurrentItem(current.get()); WebCore::Frame* child = pFrame->tree()->firstChild(); // Remember the parent history item so we can search for a child item. RefPtr<WebCore::HistoryItem> parent = current; while (child) { // Use the old history item since the current one may have a // deleted parent. WebCore::HistoryItem* item = parent->childItemWithTarget(child->tree()->name()); child->loader()->history()->setCurrentItem(item); // Append the first child to the queue if it exists. If there is no // item, then we do not need to traverse the children since there // will be no parent history item. WebCore::Frame* firstChild; if (item && (firstChild = child->tree()->firstChild())) frameQueue.append(firstChild); child = child->tree()->nextSibling(); // If we don't have a sibling for this frame and the queue isn't // empty, use the next entry in the queue. if (!child && !frameQueue.isEmpty()) { child = frameQueue.at(0); frameQueue.remove(0); // Figure out the parent history item used when searching for // the history item to use. parent = child->tree()->parent()->loader()->history()->currentItem(); } } } }
static bool read_item_recursive(WebCore::HistoryItem* newItem, const char** pData, int length) { if (!pData || length < HISTORY_MIN_SIZE) return false; const WebCore::TextEncoding& e = WebCore::UTF8Encoding(); const char* data = *pData; const char* end = data + length; int sizeofUnsigned = (int)sizeof(unsigned); // Read the original url // Read the expected length of the string. int l; memcpy(&l, data, sizeofUnsigned); // Increment data pointer by the size of an unsigned int. data += sizeofUnsigned; if (l) { LOGV("Original url %d %.*s", l, l, data); // If we have a length, check if that length exceeds the data length // and return null if there is not enough data. if (data + l < end) newItem->setOriginalURLString(e.decode(data, l)); else return false; // Increment the data pointer by the length of the string. data += l; } // Check if we have enough data left to continue. if (end - data < sizeofUnsigned) return false; // Read the url memcpy(&l, data, sizeofUnsigned); data += sizeofUnsigned; if (l) { LOGV("Url %d %.*s", l, l, data); if (data + l < end) newItem->setURLString(e.decode(data, l)); else return false; data += l; } if (end - data < sizeofUnsigned) return false; // Read the title memcpy(&l, data, sizeofUnsigned); data += sizeofUnsigned; if (l) { LOGV("Title %d %.*s", l, l, data); if (data + l < end) newItem->setTitle(e.decode(data, l)); else return false; data += l; } if (end - data < sizeofUnsigned) return false; // Generate a new ResourceRequest object for populating form information. WebCore::String formContentType; WTF::PassRefPtr<WebCore::FormData> formData = NULL; // Read the form content type memcpy(&l, data, sizeofUnsigned); data += sizeofUnsigned; if (l) { LOGV("Content type %d %.*s", l, l, data); if (data + l < end) formContentType = e.decode(data, l); else return false; data += l; } if (end - data < sizeofUnsigned) return false; // Read the form data memcpy(&l, data, sizeofUnsigned); data += sizeofUnsigned; if (l) { LOGV("Form data %d %.*s", l, l, data); if (data + l < end) formData = WebCore::FormData::create(data, l); else return false; data += l; // Read the identifier { int64_t id; int size = (int)sizeof(int64_t); memcpy(&id, data, size); data += size; if (id) formData->setIdentifier(id); } } if (end - data < sizeofUnsigned) return false; // Set up the form info if (formData != NULL) { WebCore::ResourceRequest r; r.setHTTPMethod("POST"); r.setHTTPContentType(formContentType); r.setHTTPBody(formData); newItem->setFormInfoFromRequest(r); } // Read the target memcpy(&l, data, sizeofUnsigned); data += sizeofUnsigned; if (l) { LOGV("Target %d %.*s", l, l, data); if (data + l < end) newItem->setTarget(e.decode(data, l)); else return false; data += l; } if (end - data < sizeofUnsigned) return false; AndroidWebHistoryBridge* bridge = newItem->bridge(); LOG_ASSERT(bridge, "There should be a bridge object during inflate"); // Read the screen scale memcpy(&l, data, sizeofUnsigned); LOGV("Screen scale %d", l); bridge->setScale(l); data += sizeofUnsigned; memcpy(&l, data, sizeofUnsigned); LOGV("Screen width scale %d", l); bridge->setScreenWidthScale(l); data += sizeofUnsigned; if (end - data < sizeofUnsigned) return false; // Read the document state memcpy(&l, data, sizeofUnsigned); LOGV("Document state %d", l); data += sizeofUnsigned; if (l) { // Check if we have enough data to at least parse the sizes of each // document state string. if (data + l * sizeofUnsigned >= end) return false; // Create a new vector and reserve enough space for the document state. WTF::Vector<WebCore::String> docState; docState.reserveCapacity(l); while (l--) { // Check each time if we have enough to parse the length of the next // string. if (end - data < sizeofUnsigned) return false; int strLen; memcpy(&strLen, data, sizeofUnsigned); data += sizeofUnsigned; if (data + strLen < end) docState.append(e.decode(data, strLen)); else return false; LOGV("\t\t%d %.*s", strLen, strLen, data); data += strLen; } newItem->setDocumentState(docState); } // Check if we have enough to read the next byte if (data >= end) return false; // Read is target item // Cast the value to unsigned char in order to make a negative value larger // than 1. A value that is not 0 or 1 is a failure. unsigned char c = (unsigned char)data[0]; if (c > 1) return false; LOGV("Target item %d", c); newItem->setIsTargetItem((bool)c); data++; if (end - data < sizeofUnsigned) return false; // Read the child count memcpy(&l, data, sizeofUnsigned); LOGV("Child count %d", l); data += sizeofUnsigned; *pData = data; if (l) { // Check if we have the minimum amount need to parse l children. if (data + l * HISTORY_MIN_SIZE >= end) return false; while (l--) { // No need to check the length each time because read_item_recursive // will return null if there isn't enough data left to parse. WTF::PassRefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create(); // Set a bridge that will not call into java. child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge))); // Read the child item. if (!read_item_recursive(child.get(), pData, end - data)) { child.clear(); return false; } child->bridge()->setActive(); newItem->addChildItem(child); } } return true; }
static void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item) { // Original url writeString(vector, item->originalURLString()); // Url writeString(vector, item->urlString()); // Title writeString(vector, item->title()); // Form content type writeString(vector, item->formContentType()); // Form data const WebCore::FormData* formData = item->formData(); if (formData) { // write a flag means formData is not null. unsigned flag = FLAG_NOT_NULL; vector.append((char*)&flag, sizeof(unsigned)); //LOGD("Writing Form data if {} Tag"); /*guoxiaolei 20120827 end>*/ writeString(vector, formData->flattenToString()); // save the identifier as it is not included in the flatten data int64_t id = formData->identifier(); //LOGD("Writing the identifier %d ", id); /*guoxiaolei 20120827 end>*/ vector.append((char*)&id, sizeof(int64_t)); } else{ //LOGD("Writing Form data else {} Tag"); //write_string(v, WTF::String()); // Empty constructor does not allocate a buffer. // write a flag means formData is null. unsigned flag = FLAG_IS_NULL; vector.append((char*)&flag, sizeof(unsigned)); } /*guoxiaolei 20120827 end>*/ // Target writeString(vector, item->target()); AndroidWebHistoryBridge* bridge = item->bridge(); ALOG_ASSERT(bridge, "We should have a bridge here!"); // Screen scale const float scale = bridge->scale(); ALOGV("Writing scale %f", scale); vector.append((char*)&scale, sizeof(float)); const float textWrapScale = bridge->textWrapScale(); ALOGV("Writing text wrap scale %f", textWrapScale); vector.append((char*)&textWrapScale, sizeof(float)); // Scroll position. const int scrollX = item->scrollPoint().x(); vector.append((char*)&scrollX, sizeof(int)); const int scrollY = item->scrollPoint().y(); vector.append((char*)&scrollY, sizeof(int)); // Document state const WTF::Vector<WTF::String>& docState = item->documentState(); WTF::Vector<WTF::String>::const_iterator end = docState.end(); unsigned stateSize = docState.size(); ALOGV("Writing docState %d", stateSize); vector.append((char*)&stateSize, sizeof(unsigned)); for (WTF::Vector<WTF::String>::const_iterator i = docState.begin(); i != end; ++i) { writeString(vector, *i); } // Is target item ALOGV("Writing isTargetItem %d", item->isTargetItem()); vector.append((char)item->isTargetItem()); // Children count unsigned childCount = item->children().size(); ALOGV("Writing childCount %d", childCount); vector.append((char*)&childCount, sizeof(unsigned)); }
void FrameLoaderClientAndroid::dispatchDidFailProvisionalLoad(const ResourceError& error) { ASSERT(m_frame); // Ignore ErrorInterrupted since it is due to a policy interruption. This // is caused by a decision to download the main resource rather than // display it. if (error.errorCode() == InternalErrorInterrupted || error.errorCode() == InternalErrorCancelled) { // If we decided to download the main resource or if the user cancelled // it, make sure we report that the load is done. didFinishLoad(); return; } AssetManager* am = globalAssetManager(); // Check to see if the error code was not generated internally WebCore::PlatformBridge::rawResId id = WebCore::PlatformBridge::NoDomain; if ((error.errorCode() == ErrorFile || error.errorCode() == ErrorFileNotFound) && (!error.localizedDescription().isEmpty())) { id = WebCore::PlatformBridge::LoadError; } String filename = m_webFrame->getRawResourceFilename(id); if (filename.isEmpty()) return; // Grab the error page from the asset manager Asset* a = am->openNonAsset( filename.utf8().data(), Asset::ACCESS_BUFFER); if (!a) return; // Take the failing url and encode html entities so javascript urls are not // executed. CString failingUrl = error.failingURL().utf8(); WTF::Vector<char> url; int len = failingUrl.length(); const char* data = failingUrl.data(); for (int i = 0; i < len; i++) { char c = data[i]; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) url.append(c); else { char buf[16]; int res = sprintf(buf, "&#%d;", c); buf[res] = 0; url.append(buf, res); } } // Replace all occurances of %s with the failing url. String s = UTF8Encoding().decode((const char*)a->getBuffer(false), a->getLength()); // samsung shkim // \frameworks\base\core\res\res\raw-XX\nodomain.html or loaderror.html // These error pages does not have <viewport> tag, it is loaded as low zoom scale if( s.contains( "viewport" ) == false ) s = s.replace( "<head>", "<head> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\"/>" ); s = s.replace("%s", String(url.data(), url.size())); // Replace all occurances of %e with the error text s = s.replace("%e", error.localizedDescription()); // Create the request and the substitute data and tell the FrameLoader to // load with the replacement data. // use KURL(const char*) as KURL(const String& url) can trigger ASSERT for // invalidate URL string. loadDataIntoFrame(m_frame, KURL(ParsedURLString, data), error.failingURL(), s); // Delete the asset. delete a; }
static bool readItemRecursive(WebCore::HistoryItem* newItem, const char** pData, int length) { if (!pData || length < HISTORY_MIN_SIZE) { ALOGW("readItemRecursive() bad params; pData=%p length=%d", pData, length); return false; } const char* data = *pData; const char* end = data + length; String content; // Read the original url if (readString(data, end, content, "Original url")) newItem->setOriginalURLString(content); else return false; // Read the url if (readString(data, end, content, "Url")) newItem->setURLString(content); else return false; // Read the title if (readString(data, end, content, "Title")) newItem->setTitle(content); else return false; // Generate a new ResourceRequest object for populating form information. // Read the form content type WTF::String formContentType; if (!readString(data, end, formContentType, "Content type")) return false; // Read the form data size unsigned formDataSize; if (!readUnsigned(data, end, formDataSize, "Form data size")) return false; // Read the form data WTF::RefPtr<WebCore::FormData> formData; if (formDataSize) { ALOGV("Reading Form data %d %.*s", formDataSize, formDataSize, data); if ((end < data) || ((size_t)(end - data) < formDataSize)) { ALOGW("\tNot enough data to read form data; returning"); return false; } formData = WebCore::FormData::create(data, formDataSize); data += formDataSize; // Read the identifier int64_t id; if (!readInt64(data, end, id, "Form id")) return false; if (id) formData->setIdentifier(id); } // Set up the form info if (formData != NULL) { WebCore::ResourceRequest r; r.setHTTPMethod("POST"); r.setHTTPContentType(formContentType); r.setHTTPBody(formData); newItem->setFormInfoFromRequest(r); } // Read the target if (readString(data, end, content, "Target")) newItem->setTarget(content); else return false; AndroidWebHistoryBridge* bridge = newItem->bridge(); ALOG_ASSERT(bridge, "There should be a bridge object during inflate"); // Read the screen scale float fValue; if (readFloat(data, end, fValue, "Screen scale")) bridge->setScale(fValue); else return false; // Read the text wrap scale if (readFloat(data, end, fValue, "Text wrap scale")) bridge->setTextWrapScale(fValue); else return false; // Read scroll position. int scrollX; if (!readInt(data, end, scrollX, "Scroll pos x")) return false; int scrollY; if (!readInt(data, end, scrollY, "Scroll pos y")) return false; newItem->setScrollPoint(IntPoint(scrollX, scrollY)); // Read the document state unsigned docStateCount; if (!readUnsigned(data, end, docStateCount, "Doc state count")) return false; if (docStateCount) { // Create a new vector and reserve enough space for the document state. WTF::Vector<WTF::String> docState; docState.reserveCapacity(docStateCount); while (docStateCount--) { // Read a document state string if (readString(data, end, content, "Document state")) docState.append(content); else return false; } newItem->setDocumentState(docState); } // Read is target item bool c; if (readBool(data, end, c, "Target item")) newItem->setIsTargetItem(c); else return false; // Read the child count unsigned count; if (!readUnsigned(data, end, count, "Child count")) return false; *pData = data; if (count) { while (count--) { // No need to check the length each time because read_item_recursive // will return null if there isn't enough data left to parse. WTF::RefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create(); // Set a bridge that will not call into java. child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge))); // Read the child item. if (!readItemRecursive(child.get(), pData, end - data)) return false; child->bridge()->setActive(); newItem->addChildItem(child); } } return true; }