source: webkit/trunk/JavaScriptCore/kjs/ustring.cpp@ 36263

Last change on this file since 36263 was 36263, checked in by [email protected], 17 years ago

2008-09-07 Cameron Zwarich <[email protected]>

Reviewed by Maciej Stachowiak.

Bug 20704: Replace the KJS namespace
<https://bugs.webkit.org/show_bug.cgi?id=20704>

Rename the KJS namespace to JSC. There are still some uses of KJS in
preprocessor macros and comments, but these will also be changed some
time in the near future. There are also some uses in the names of JNI
functions, but I will check if these are safe to change as well.

JavaScriptCore:

  • API/APICast.h: (toJS): (toRef): (toGlobalRef):
  • API/JSBase.cpp:
  • API/JSCallbackConstructor.cpp:
  • API/JSCallbackConstructor.h:
  • API/JSCallbackFunction.cpp:
  • API/JSCallbackFunction.h:
  • API/JSCallbackObject.cpp:
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h:
  • API/JSClassRef.cpp: (OpaqueJSClass::staticValues): (OpaqueJSClass::staticFunctions):
  • API/JSClassRef.h:
  • API/JSContextRef.cpp:
  • API/JSObjectRef.cpp:
  • API/JSProfilerPrivate.cpp:
  • API/JSStringRef.cpp:
  • API/JSValueRef.cpp: (JSValueGetType):
  • API/OpaqueJSString.cpp:
  • API/OpaqueJSString.h:
  • JavaScriptCore.Debug.exp:
  • JavaScriptCore.base.exp:
  • VM/CTI.cpp: (JSC::):
  • VM/CTI.h:
  • VM/CodeBlock.cpp:
  • VM/CodeBlock.h:
  • VM/CodeGenerator.cpp:
  • VM/CodeGenerator.h:
  • VM/ExceptionHelpers.cpp:
  • VM/ExceptionHelpers.h:
  • VM/Instruction.h:
  • VM/JSPropertyNameIterator.cpp:
  • VM/JSPropertyNameIterator.h:
  • VM/LabelID.h:
  • VM/Machine.cpp:
  • VM/Machine.h:
  • VM/Opcode.cpp:
  • VM/Opcode.h:
  • VM/Register.h: (WTF::):
  • VM/RegisterFile.cpp:
  • VM/RegisterFile.h:
  • VM/RegisterID.h: (WTF::):
  • VM/SamplingTool.cpp:
  • VM/SamplingTool.h:
  • VM/SegmentedVector.h:
  • kjs/ArgList.cpp:
  • kjs/ArgList.h:
  • kjs/Arguments.cpp:
  • kjs/Arguments.h:
  • kjs/ArrayConstructor.cpp:
  • kjs/ArrayConstructor.h:
  • kjs/ArrayPrototype.cpp:
  • kjs/ArrayPrototype.h:
  • kjs/BatchedTransitionOptimizer.h:
  • kjs/BooleanConstructor.cpp:
  • kjs/BooleanConstructor.h:
  • kjs/BooleanObject.cpp:
  • kjs/BooleanObject.h:
  • kjs/BooleanPrototype.cpp:
  • kjs/BooleanPrototype.h:
  • kjs/CallData.cpp:
  • kjs/CallData.h:
  • kjs/ClassInfo.h:
  • kjs/CommonIdentifiers.cpp:
  • kjs/CommonIdentifiers.h:
  • kjs/ConstructData.cpp:
  • kjs/ConstructData.h:
  • kjs/DateConstructor.cpp:
  • kjs/DateConstructor.h:
  • kjs/DateInstance.cpp: (JSC::DateInstance::msToGregorianDateTime):
  • kjs/DateInstance.h:
  • kjs/DateMath.cpp:
  • kjs/DateMath.h:
  • kjs/DatePrototype.cpp:
  • kjs/DatePrototype.h:
  • kjs/DebuggerCallFrame.cpp:
  • kjs/DebuggerCallFrame.h:
  • kjs/Error.cpp:
  • kjs/Error.h:
  • kjs/ErrorConstructor.cpp:
  • kjs/ErrorConstructor.h:
  • kjs/ErrorInstance.cpp:
  • kjs/ErrorInstance.h:
  • kjs/ErrorPrototype.cpp:
  • kjs/ErrorPrototype.h:
  • kjs/ExecState.cpp:
  • kjs/ExecState.h:
  • kjs/FunctionConstructor.cpp:
  • kjs/FunctionConstructor.h:
  • kjs/FunctionPrototype.cpp:
  • kjs/FunctionPrototype.h:
  • kjs/GetterSetter.cpp:
  • kjs/GetterSetter.h:
  • kjs/GlobalEvalFunction.cpp:
  • kjs/GlobalEvalFunction.h:
  • kjs/IndexToNameMap.cpp:
  • kjs/IndexToNameMap.h:
  • kjs/InitializeThreading.cpp:
  • kjs/InitializeThreading.h:
  • kjs/InternalFunction.cpp:
  • kjs/InternalFunction.h: (JSC::InternalFunction::InternalFunction):
  • kjs/JSActivation.cpp:
  • kjs/JSActivation.h:
  • kjs/JSArray.cpp:
  • kjs/JSArray.h:
  • kjs/JSCell.cpp:
  • kjs/JSCell.h:
  • kjs/JSFunction.cpp:
  • kjs/JSFunction.h: (JSC::JSFunction::JSFunction):
  • kjs/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • kjs/JSGlobalData.h:
  • kjs/JSGlobalObject.cpp:
  • kjs/JSGlobalObject.h:
  • kjs/JSGlobalObjectFunctions.cpp:
  • kjs/JSGlobalObjectFunctions.h:
  • kjs/JSImmediate.cpp:
  • kjs/JSImmediate.h:
  • kjs/JSLock.cpp:
  • kjs/JSLock.h:
  • kjs/JSNotAnObject.cpp:
  • kjs/JSNotAnObject.h:
  • kjs/JSNumberCell.cpp:
  • kjs/JSNumberCell.h:
  • kjs/JSObject.cpp:
  • kjs/JSObject.h:
  • kjs/JSStaticScopeObject.cpp:
  • kjs/JSStaticScopeObject.h:
  • kjs/JSString.cpp:
  • kjs/JSString.h:
  • kjs/JSType.h:
  • kjs/JSValue.cpp:
  • kjs/JSValue.h:
  • kjs/JSVariableObject.cpp:
  • kjs/JSVariableObject.h:
  • kjs/JSWrapperObject.cpp:
  • kjs/JSWrapperObject.h:
  • kjs/LabelStack.cpp:
  • kjs/LabelStack.h:
  • kjs/MathObject.cpp:
  • kjs/MathObject.h:
  • kjs/NativeErrorConstructor.cpp:
  • kjs/NativeErrorConstructor.h:
  • kjs/NativeErrorPrototype.cpp:
  • kjs/NativeErrorPrototype.h:
  • kjs/NodeInfo.h:
  • kjs/NumberConstructor.cpp:
  • kjs/NumberConstructor.h:
  • kjs/NumberObject.cpp:
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp:
  • kjs/NumberPrototype.h:
  • kjs/ObjectConstructor.cpp:
  • kjs/ObjectConstructor.h:
  • kjs/ObjectPrototype.cpp:
  • kjs/ObjectPrototype.h:
  • kjs/Parser.cpp:
  • kjs/Parser.h:
  • kjs/PropertyMap.cpp: (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger):
  • kjs/PropertyMap.h:
  • kjs/PropertyNameArray.cpp:
  • kjs/PropertyNameArray.h:
  • kjs/PropertySlot.cpp:
  • kjs/PropertySlot.h:
  • kjs/PrototypeFunction.cpp:
  • kjs/PrototypeFunction.h:
  • kjs/PutPropertySlot.h:
  • kjs/RegExpConstructor.cpp:
  • kjs/RegExpConstructor.h:
  • kjs/RegExpObject.cpp:
  • kjs/RegExpObject.h:
  • kjs/RegExpPrototype.cpp:
  • kjs/RegExpPrototype.h:
  • kjs/ScopeChain.cpp:
  • kjs/ScopeChain.h:
  • kjs/ScopeChainMark.h:
  • kjs/Shell.cpp: (jscmain):
  • kjs/SmallStrings.cpp:
  • kjs/SmallStrings.h:
  • kjs/SourceProvider.h:
  • kjs/SourceRange.h:
  • kjs/StringConstructor.cpp:
  • kjs/StringConstructor.h:
  • kjs/StringObject.cpp:
  • kjs/StringObject.h:
  • kjs/StringObjectThatMasqueradesAsUndefined.h:
  • kjs/StringPrototype.cpp:
  • kjs/StringPrototype.h:
  • kjs/StructureID.cpp:
  • kjs/StructureID.h:
  • kjs/SymbolTable.h:
  • kjs/collector.cpp:
  • kjs/collector.h:
  • kjs/completion.h:
  • kjs/create_hash_table:
  • kjs/debugger.cpp:
  • kjs/debugger.h:
  • kjs/dtoa.cpp:
  • kjs/dtoa.h:
  • kjs/grammar.y:
  • kjs/identifier.cpp:
  • kjs/identifier.h: (JSC::Identifier::equal):
  • kjs/interpreter.cpp:
  • kjs/interpreter.h:
  • kjs/lexer.cpp: (JSC::Lexer::Lexer): (JSC::Lexer::clear): (JSC::Lexer::makeIdentifier):
  • kjs/lexer.h:
  • kjs/lookup.cpp:
  • kjs/lookup.h:
  • kjs/nodes.cpp:
  • kjs/nodes.h:
  • kjs/nodes2string.cpp:
  • kjs/operations.cpp:
  • kjs/operations.h:
  • kjs/protect.h:
  • kjs/regexp.cpp:
  • kjs/regexp.h:
  • kjs/ustring.cpp:
  • kjs/ustring.h: (JSC::operator!=): (JSC::IdentifierRepHash::hash): (WTF::):
  • masm/MacroAssembler.h:
  • masm/MacroAssemblerWin.cpp:
  • masm/X86Assembler.h:
  • pcre/pcre_exec.cpp:
  • profiler/CallIdentifier.h: (WTF::):
  • profiler/HeavyProfile.cpp:
  • profiler/HeavyProfile.h:
  • profiler/Profile.cpp:
  • profiler/Profile.h:
  • profiler/ProfileGenerator.cpp:
  • profiler/ProfileGenerator.h:
  • profiler/ProfileNode.cpp:
  • profiler/ProfileNode.h:
  • profiler/Profiler.cpp:
  • profiler/Profiler.h:
  • profiler/TreeProfile.cpp:
  • profiler/TreeProfile.h:
  • wrec/WREC.cpp:
  • wrec/WREC.h:
  • wtf/AVLTree.h:

WebCore:

  • WebCore.base.exp:
  • bindings/js/GCController.cpp:
  • bindings/js/JSAttrCustom.cpp:
  • bindings/js/JSAudioConstructor.cpp:
  • bindings/js/JSAudioConstructor.h: (WebCore::JSAudioConstructor::classInfo):
  • bindings/js/JSCSSRuleCustom.cpp:
  • bindings/js/JSCSSStyleDeclarationCustom.cpp:
  • bindings/js/JSCSSValueCustom.cpp:
  • bindings/js/JSCanvasPixelArrayCustom.cpp:
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:
  • bindings/js/JSClipboardCustom.cpp:
  • bindings/js/JSConsoleCustom.cpp:
  • bindings/js/JSCustomSQLStatementCallback.cpp: (WebCore::JSCustomSQLStatementCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementCallback.h: (WebCore::JSCustomSQLStatementCallback::create):
  • bindings/js/JSCustomSQLStatementErrorCallback.cpp: (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementErrorCallback.h: (WebCore::JSCustomSQLStatementErrorCallback::create):
  • bindings/js/JSCustomSQLTransactionCallback.cpp: (WebCore::JSCustomSQLTransactionCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionCallback.h: (WebCore::JSCustomSQLTransactionCallback::create):
  • bindings/js/JSCustomSQLTransactionErrorCallback.cpp: (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionErrorCallback.h: (WebCore::JSCustomSQLTransactionErrorCallback::create):
  • bindings/js/JSCustomVoidCallback.cpp: (WebCore::JSCustomVoidCallback::handleEvent):
  • bindings/js/JSCustomVoidCallback.h: (WebCore::JSCustomVoidCallback::create):
  • bindings/js/JSCustomXPathNSResolver.cpp: (WebCore::JSCustomXPathNSResolver::create):
  • bindings/js/JSCustomXPathNSResolver.h:
  • bindings/js/JSDOMApplicationCacheCustom.cpp: (WebCore::JSDOMApplicationCache::dispatchEvent):
  • bindings/js/JSDOMBinding.cpp: (WebCore::jsOwnedStringOrNull):
  • bindings/js/JSDOMBinding.h: (WebCore::DOMObject::DOMObject): (WebCore::cacheDOMObject): (WebCore::cacheSVGDOMObject): (WebCore::DOMExceptionTranslator::DOMExceptionTranslator): (WebCore::toJS):
  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSDOMWindowBase.h: (WebCore::JSDOMWindowBase::classInfo): (WebCore::JSDOMWindowBase::d):
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::getPropertyAttributes):
  • bindings/js/JSDOMWindowCustom.h: (WebCore::asJSDOMWindow): (WebCore::JSDOMWindow::customGetOwnPropertySlot): (WebCore::JSDOMWindow::customPut): (WebCore::JSDOMWindowBase::allowsAccessFrom): (WebCore::JSDOMWindowBase::allowsAccessFromNoErrorMessage):
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::getPropertyAttributes):
  • bindings/js/JSDOMWindowShell.h: (WebCore::JSDOMWindowShell::classInfo):
  • bindings/js/JSDatabaseCustom.cpp:
  • bindings/js/JSDocumentCustom.cpp:
  • bindings/js/JSDocumentFragmentCustom.cpp:
  • bindings/js/JSElementCustom.cpp:
  • bindings/js/JSEventCustom.cpp:
  • bindings/js/JSEventListener.cpp:
  • bindings/js/JSEventListener.h: (WebCore::JSUnprotectedEventListener::create): (WebCore::JSEventListener::create):
  • bindings/js/JSEventTargetBase.cpp:
  • bindings/js/JSEventTargetBase.h: (WebCore::JSEventTargetBase::getValueProperty): (WebCore::JSEventTargetBase::putValueProperty): (WebCore::JSEventTargetBase::getOwnPropertySlot): (WebCore::JSEventTargetBase::put): (WebCore::JSEventTargetPrototype::JSEventTargetPrototype): (WebCore::JSEventTargetPrototype::self): (WebCore::JSEventTargetPrototype::getOwnPropertySlot): (WebCore::JSEventTargetPrototype::classInfo):
  • bindings/js/JSEventTargetNode.cpp:
  • bindings/js/JSEventTargetNode.h: (WebCore::JSEventTargetNode::getOwnPropertySlot): (WebCore::JSEventTargetNode::getValueProperty): (WebCore::JSEventTargetNode::put): (WebCore::JSEventTargetNode::putValueProperty):
  • bindings/js/JSHTMLAllCollection.h: (WebCore::JSHTMLAllCollection::JSHTMLAllCollection): (WebCore::JSHTMLAllCollection::toBoolean):
  • bindings/js/JSHTMLAppletElementCustom.cpp:
  • bindings/js/JSHTMLCollectionCustom.cpp:
  • bindings/js/JSHTMLDocumentCustom.cpp:
  • bindings/js/JSHTMLElementCustom.cpp:
  • bindings/js/JSHTMLEmbedElementCustom.cpp:
  • bindings/js/JSHTMLFormElementCustom.cpp:
  • bindings/js/JSHTMLFrameElementCustom.cpp:
  • bindings/js/JSHTMLFrameSetElementCustom.cpp:
  • bindings/js/JSHTMLIFrameElementCustom.cpp:
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::JSHTMLInputElementBase): (WebCore::JSHTMLInputElementBase::getOwnPropertySlot):
  • bindings/js/JSHTMLInputElementBase.h: (WebCore::JSHTMLInputElementBase::classInfo):
  • bindings/js/JSHTMLObjectElementCustom.cpp:
  • bindings/js/JSHTMLOptionElementConstructor.cpp:
  • bindings/js/JSHTMLOptionElementConstructor.h: (WebCore::JSHTMLOptionElementConstructor::classInfo):
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp:
  • bindings/js/JSHTMLSelectElementCustom.cpp: (WebCore::selectIndexSetter): (WebCore::JSHTMLSelectElement::indexSetter):
  • bindings/js/JSHTMLSelectElementCustom.h:
  • bindings/js/JSHistoryCustom.cpp:
  • bindings/js/JSImageConstructor.cpp:
  • bindings/js/JSImageConstructor.h: (WebCore::JSImageConstructor::classInfo):
  • bindings/js/JSInspectedObjectWrapper.cpp:
  • bindings/js/JSInspectedObjectWrapper.h: (WebCore::JSInspectedObjectWrapper::wrapOutgoingValue): (WebCore::JSInspectedObjectWrapper::classInfo):
  • bindings/js/JSInspectorCallbackWrapper.cpp:
  • bindings/js/JSInspectorCallbackWrapper.h: (WebCore::JSInspectorCallbackWrapper::classInfo): (WebCore::JSInspectorCallbackWrapper::wrapOutgoingValue):
  • bindings/js/JSJavaScriptCallFrameCustom.cpp:
  • bindings/js/JSLocationCustom.cpp:
  • bindings/js/JSMimeTypeArrayCustom.cpp:
  • bindings/js/JSNSResolver.cpp:
  • bindings/js/JSNSResolver.h: (WebCore::JSNSResolver::create):
  • bindings/js/JSNamedNodeMapCustom.cpp:
  • bindings/js/JSNamedNodesCollection.cpp: (WebCore::JSNamedNodesCollection::JSNamedNodesCollection):
  • bindings/js/JSNamedNodesCollection.h: (WebCore::JSNamedNodesCollection::classInfo):
  • bindings/js/JSNavigatorCustom.cpp:
  • bindings/js/JSNodeCustom.cpp:
  • bindings/js/JSNodeFilterCondition.cpp: (WebCore::JSNodeFilterCondition::acceptNode):
  • bindings/js/JSNodeFilterCondition.h: (WebCore::JSNodeFilterCondition::create):
  • bindings/js/JSNodeFilterCustom.cpp:
  • bindings/js/JSNodeIteratorCustom.cpp:
  • bindings/js/JSNodeListCustom.cpp:
  • bindings/js/JSPluginArrayCustom.cpp:
  • bindings/js/JSPluginCustom.cpp:
  • bindings/js/JSPluginElementFunctions.cpp: (WebCore::getRuntimeObject):
  • bindings/js/JSPluginElementFunctions.h:
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::construct): (WebCore::JSQuarantinedObjectWrapper::call):
  • bindings/js/JSQuarantinedObjectWrapper.h: (WebCore::JSQuarantinedObjectWrapper::unwrappedObject): (WebCore::JSQuarantinedObjectWrapper::unwrappedGlobalObject): (WebCore::JSQuarantinedObjectWrapper::className):
  • bindings/js/JSRGBColor.cpp:
  • bindings/js/JSRGBColor.h: (WebCore::JSRGBColor::classInfo):
  • bindings/js/JSSQLResultSetRowListCustom.cpp:
  • bindings/js/JSSQLTransactionCustom.cpp:
  • bindings/js/JSSVGLazyEventListener.cpp:
  • bindings/js/JSSVGLazyEventListener.h:
  • bindings/js/JSSVGLengthCustom.cpp:
  • bindings/js/JSSVGMatrixCustom.cpp: (WebCore::JSSVGMatrix::inverse): (WebCore::JSSVGMatrix::rotateFromVector):
  • bindings/js/JSSVGPathSegCustom.cpp:
  • bindings/js/JSSVGPathSegListCustom.cpp: (WebCore::JSSVGPathSegList::initialize): (WebCore::JSSVGPathSegList::getItem): (WebCore::JSSVGPathSegList::insertItemBefore): (WebCore::JSSVGPathSegList::replaceItem): (WebCore::JSSVGPathSegList::removeItem): (WebCore::JSSVGPathSegList::appendItem):
  • bindings/js/JSSVGPointListCustom.cpp:
  • bindings/js/JSSVGTransformListCustom.cpp:
  • bindings/js/JSStorageCustom.cpp:
  • bindings/js/JSStyleSheetCustom.cpp:
  • bindings/js/JSStyleSheetListCustom.cpp:
  • bindings/js/JSTextCustom.cpp:
  • bindings/js/JSTreeWalkerCustom.cpp:
  • bindings/js/JSXMLHttpRequestConstructor.cpp:
  • bindings/js/JSXMLHttpRequestConstructor.h: (WebCore::JSXMLHttpRequestConstructor::classInfo):
  • bindings/js/JSXMLHttpRequestCustom.cpp:
  • bindings/js/JSXMLHttpRequestUploadCustom.cpp:
  • bindings/js/JSXSLTProcessorConstructor.cpp:
  • bindings/js/JSXSLTProcessorConstructor.h: (WebCore::JSXSLTProcessorConstructor::classInfo):
  • bindings/js/JSXSLTProcessorCustom.cpp:
  • bindings/js/ScheduledAction.cpp:
  • bindings/js/ScheduledAction.h:
  • bindings/js/ScriptController.cpp: (WebCore::ScriptController::attachDebugger): (WebCore::ScriptController::windowScriptNPObject):
  • bindings/js/ScriptController.h:
  • bindings/js/ScriptControllerGtk.cpp: (WebCore::ScriptController::createScriptInstanceForWidget):
  • bindings/js/ScriptControllerMac.mm: (WebCore::ScriptController::createScriptInstanceForWidget): (WebCore::ScriptController::windowScriptObject): (WebCore::ScriptController::clearPlatformScriptObjects): (WebCore::updateRenderingForBindings): (WebCore::ScriptController::initJavaJSBindings):
  • bindings/js/ScriptControllerQt.cpp: (WebCore::ScriptController::createScriptInstanceForWidget):
  • bindings/js/ScriptControllerWin.cpp: (WebCore::ScriptController::createScriptInstanceForWidget):
  • bindings/js/ScriptControllerWx.cpp: (WebCore::ScriptController::createScriptInstanceForWidget):
  • bindings/js/StringSourceProvider.h: (WebCore::StringSourceProvider::getRange):
  • bindings/objc/DOM.mm: (-[DOMNode JSC::Bindings::]):
  • bindings/objc/DOMInternal.h:
  • bindings/objc/DOMInternal.mm: (-[WebScriptObject _initializeScriptDOMNodeImp]):
  • bindings/objc/DOMUtility.mm: (JSC::createDOMWrapper): (WebCore::createDOMWrapper):
  • bindings/objc/WebScriptObject.mm: (WebCore::createJSWrapper): (-[WebScriptObject _initWithJSObject:JSC::originRootObject:JSC::Bindings::rootObject:JSC::Bindings::]):
  • bindings/objc/WebScriptObjectPrivate.h:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp:
  • bridge/NP_jsobject.h:
  • bridge/c/c_class.cpp:
  • bridge/c/c_class.h:
  • bridge/c/c_instance.cpp:
  • bridge/c/c_instance.h:
  • bridge/c/c_runtime.cpp:
  • bridge/c/c_runtime.h:
  • bridge/c/c_utility.cpp:
  • bridge/c/c_utility.h:
  • bridge/jni/jni_class.cpp:
  • bridge/jni/jni_class.h:
  • bridge/jni/jni_instance.cpp:
  • bridge/jni/jni_instance.h:
  • bridge/jni/jni_jsobject.h:
  • bridge/jni/jni_jsobject.mm: (JavaJSObject::call): (JavaJSObject::convertJObjectToValue):
  • bridge/jni/jni_objc.mm: (JSC::Bindings::dispatchJNICall):
  • bridge/jni/jni_runtime.cpp:
  • bridge/jni/jni_runtime.h:
  • bridge/jni/jni_utility.cpp:
  • bridge/jni/jni_utility.h:
  • bridge/npruntime.cpp: (_NPN_GetStringIdentifier):
  • bridge/objc/WebScriptObject.h:
  • bridge/objc/objc_class.h:
  • bridge/objc/objc_class.mm:
  • bridge/objc/objc_instance.h:
  • bridge/objc/objc_instance.mm:
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm:
  • bridge/objc/objc_utility.h:
  • bridge/objc/objc_utility.mm:
  • bridge/qt/qt_class.cpp:
  • bridge/qt/qt_class.h:
  • bridge/qt/qt_instance.cpp:
  • bridge/qt/qt_instance.h:
  • bridge/qt/qt_runtime.cpp: (JSC::Bindings::convertQVariantToValue): (JSC::Bindings::):
  • bridge/qt/qt_runtime.h:
  • bridge/runtime.cpp:
  • bridge/runtime.h:
  • bridge/runtime_array.cpp:
  • bridge/runtime_array.h:
  • bridge/runtime_method.cpp:
  • bridge/runtime_method.h:
  • bridge/runtime_object.cpp:
  • bridge/runtime_object.h:
  • bridge/runtime_root.cpp: (JSC::Bindings::RootObject::invalidate): (JSC::Bindings::RootObject::gcProtect): (JSC::Bindings::RootObject::gcUnprotect):
  • bridge/runtime_root.h:
  • bridge/testbindings.cpp:
  • bridge/testbindings.mm:
  • bridge/testqtbindings.cpp:
  • dom/Document.cpp: (WebCore::Document::~Document):
  • dom/NSResolver.h:
  • dom/Node.cpp: (WebCore::Node::setDocument): (WebCore::ResolveNamespaceFunctor::ResolveNamespaceFunctor): (WebCore::resolveNamespacesForSelector): (WebCore::Node::querySelector): (WebCore::Node::querySelectorAll):
  • dom/Node.h:
  • dom/NodeFilter.cpp:
  • dom/NodeFilter.h:
  • dom/NodeFilterCondition.cpp:
  • dom/NodeFilterCondition.h:
  • dom/NodeIterator.cpp:
  • dom/NodeIterator.h:
  • dom/Traversal.cpp:
  • dom/Traversal.h:
  • dom/TreeWalker.cpp:
  • dom/TreeWalker.h:
  • dom/make_names.pl:
  • history/CachedPage.cpp:
  • history/CachedPage.h:
  • html/HTMLPlugInElement.cpp: (WebCore::HTMLPlugInElement::getInstance):
  • html/HTMLPlugInElement.h:
  • loader/FrameLoader.cpp:
  • loader/FrameLoader.h:
  • loader/icon/IconDatabase.cpp: (WebCore::iconDatabase):
  • page/Console.cpp:
  • page/Console.h:
  • page/InspectorController.cpp: (WebCore::XMLHttpRequestResource::XMLHttpRequestResource): (WebCore::XMLHttpRequestResource::~XMLHttpRequestResource): (WebCore::InspectorResource::setXMLHttpRequestProperties): (WebCore::InspectorResource::sourceString): (WebCore::getResourceDocumentNode): (WebCore::search): (WebCore::InspectorController::focusNode): (WebCore::InspectorController::inspectedWindowScriptObjectCleared): (WebCore::InspectorController::addDatabaseScriptResource): (WebCore::InspectorController::resourceRetrievedByXMLHttpRequest):
  • page/InspectorController.h: (WebCore::InspectorController::profiles):
  • page/JavaScriptCallFrame.cpp: (WebCore::JavaScriptCallFrame::scopeChain):
  • page/JavaScriptCallFrame.h: (WebCore::JavaScriptCallFrame::create): (WebCore::JavaScriptCallFrame::update):
  • page/JavaScriptDebugListener.h:
  • page/JavaScriptDebugServer.cpp: (WebCore::dispatchDidParseSource):
  • page/JavaScriptDebugServer.h:
  • page/JavaScriptProfile.cpp:
  • page/JavaScriptProfile.h:
  • page/JavaScriptProfileNode.cpp: (WebCore::getTotalTime): (WebCore::getSelfTime): (WebCore::getTotalPercent): (WebCore::getSelfPercent): (WebCore::getNumberOfCalls): (WebCore::getChildren): (WebCore::getVisible):
  • page/JavaScriptProfileNode.h:
  • page/Page.cpp: (WebCore::Page::setDebuggerForAllPages): (WebCore::Page::setDebugger):
  • page/Page.h: (WebCore::Page::debugger):
  • page/mac/FrameMac.mm:
  • platform/KURL.h: (WebCore::KURL::operator JSC::UString):
  • platform/text/AtomicString.cpp: (WebCore::AtomicString::add): (WebCore::AtomicString::find):
  • platform/text/AtomicString.h: (WebCore::AtomicString::AtomicString):
  • platform/text/PlatformString.h:
  • platform/text/String.cpp: (WebCore::charactersToDouble):
  • platform/win/BString.cpp:
  • platform/win/BString.h:
  • plugins/MimeTypeArray.h:
  • plugins/Plugin.h:
  • plugins/PluginArray.h:
  • plugins/PluginView.cpp: (WebCore::PluginView::start): (WebCore::PluginView::performRequest): (WebCore::PluginView::bindingInstance):
  • plugins/PluginView.h:
  • plugins/gtk/PluginViewGtk.cpp: (WebCore::PluginView::paint): (WebCore::PluginView::handleKeyboardEvent): (WebCore::PluginView::handleMouseEvent): (WebCore::PluginView::setNPWindowRect): (WebCore::PluginView::stop): (WebCore::PluginView::init):
  • plugins/qt/PluginViewQt.cpp: (WebCore::PluginView::setNPWindowRect): (WebCore::PluginView::stop): (WebCore::PluginView::init):
  • plugins/win/PluginViewWin.cpp: (WebCore::PluginView::dispatchNPEvent): (WebCore::PluginView::handleKeyboardEvent): (WebCore::PluginView::handleMouseEvent): (WebCore::PluginView::setNPWindowRect): (WebCore::PluginView::stop):
  • storage/Database.cpp: (WebCore::Database::Database):
  • xml/XMLHttpRequest.cpp: (WebCore::XMLHttpRequest::responseText): (WebCore::XMLHttpRequest::loadRequestAsynchronously): (WebCore::XMLHttpRequest::clearResponse): (WebCore::XMLHttpRequest::dropProtection): (WebCore::XMLHttpRequest::didFinishLoading): (WebCore::XMLHttpRequest::didReceiveData):
  • xml/XMLHttpRequest.h:

WebKit/gtk:

  • webkit/webkitprivate.cpp: (webkit_init):

WebKit/mac:

  • Misc/WebCoreStatistics.mm:
  • Plugins/WebBaseNetscapePluginStream.mm: (-[WebBaseNetscapePluginStream wantsAllStreams]):
  • Plugins/WebBaseNetscapePluginView.mm: (-[WebBaseNetscapePluginView sendEvent:isDrawRect:]): (-[WebBaseNetscapePluginView setWindowIfNecessary]): (-[WebBaseNetscapePluginView start]): (-[WebBaseNetscapePluginView createPluginScriptableObject]): (-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]): (-[WebBaseNetscapePluginView webFrame:didFinishLoadWithReason:]): (-[WebBaseNetscapePluginView loadPluginRequest:]): (-[WebBaseNetscapePluginView _printedPluginBitmap]):
  • Plugins/WebPluginController.mm: (+[WebPluginController plugInViewWithArguments:fromPluginPackage:]): (-[WebPluginController startAllPlugins]): (-[WebPluginController stopAllPlugins]): (-[WebPluginController addPlugin:]): (-[WebPluginController destroyPlugin:]): (-[WebPluginController destroyAllPlugins]):
  • WebView/WebFrame.mm:
  • WebView/WebScriptDebugDelegate.mm:
  • WebView/WebScriptDebugger.h:
  • WebView/WebScriptDebugger.mm:
  • WebView/WebView.mm: (-[WebViewPrivate init]):

WebKit/qt:


  • Api/qwebframe.cpp: (QWebFrame::addToJavaScriptWindowObject): (QWebFrame::evaluateJavaScript):

WebKit/win:

  • WebCoreStatistics.cpp:
  • WebJavaScriptCollector.cpp:
  • WebScriptCallFrame.cpp: (WebScriptCallFrame::jsValueToString):
  • WebScriptCallFrame.h: (WebScriptCallFrame::state):
  • WebView.cpp: (WebView::WebView): (WebView::stringByEvaluatingJavaScriptFromString):

WebKit/wx:

  • WebFrame.cpp: (wxWebFrame::RunScript):
  • Property svn:eol-style set to native
File size: 39.5 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Cameron Zwarich ([email protected])
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "ustring.h"
25
26#include "JSGlobalObjectFunctions.h"
27#include "collector.h"
28#include "dtoa.h"
29#include "identifier.h"
30#include "operations.h"
31#include <ctype.h>
32#include <float.h>
33#include <limits.h>
34#include <math.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <wtf/ASCIICType.h>
38#include <wtf/Assertions.h>
39#include <wtf/MathExtras.h>
40#include <wtf/Vector.h>
41#include <wtf/unicode/UTF8.h>
42
43#if HAVE(STRING_H)
44#include <string.h>
45#endif
46#if HAVE(STRINGS_H)
47#include <strings.h>
48#endif
49
50using namespace WTF;
51using namespace WTF::Unicode;
52using namespace std;
53
54// This can be tuned differently per platform by putting platform #ifs right here.
55// If you don't define this macro at all, then copyChars will just call directly
56// to memcpy.
57#define USTRING_COPY_CHARS_INLINE_CUTOFF 20
58
59namespace JSC {
60
61extern const double NaN;
62extern const double Inf;
63
64static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); }
65static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); }
66
67static inline UChar* allocChars(size_t length)
68{
69 ASSERT(length);
70 if (length > maxUChars())
71 return 0;
72 return static_cast<UChar*>(tryFastMalloc(sizeof(UChar) * length));
73}
74
75static inline UChar* reallocChars(UChar* buffer, size_t length)
76{
77 ASSERT(length);
78 if (length > maxUChars())
79 return 0;
80 return static_cast<UChar*>(tryFastRealloc(buffer, sizeof(UChar) * length));
81}
82
83static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
84{
85#ifdef USTRING_COPY_CHARS_INLINE_CUTOFF
86 if (numCharacters <= USTRING_COPY_CHARS_INLINE_CUTOFF) {
87 for (unsigned i = 0; i < numCharacters; ++i)
88 destination[i] = source[i];
89 return;
90 }
91#endif
92 memcpy(destination, source, numCharacters * sizeof(UChar));
93}
94
95COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes)
96
97CString::CString(const char* c)
98 : m_length(strlen(c))
99 , m_data(new char[m_length + 1])
100{
101 memcpy(m_data, c, m_length + 1);
102}
103
104CString::CString(const char* c, size_t length)
105 : m_length(length)
106 , m_data(new char[length + 1])
107{
108 memcpy(m_data, c, m_length);
109 m_data[m_length] = 0;
110}
111
112CString::CString(const CString& b)
113{
114 m_length = b.m_length;
115 if (b.m_data) {
116 m_data = new char[m_length + 1];
117 memcpy(m_data, b.m_data, m_length + 1);
118 } else
119 m_data = 0;
120}
121
122CString::~CString()
123{
124 delete [] m_data;
125}
126
127CString CString::adopt(char* c, size_t length)
128{
129 CString s;
130 s.m_data = c;
131 s.m_length = length;
132 return s;
133}
134
135CString& CString::append(const CString& t)
136{
137 char* n;
138 n = new char[m_length + t.m_length + 1];
139 if (m_length)
140 memcpy(n, m_data, m_length);
141 if (t.m_length)
142 memcpy(n + m_length, t.m_data, t.m_length);
143 m_length += t.m_length;
144 n[m_length] = 0;
145
146 delete [] m_data;
147 m_data = n;
148
149 return *this;
150}
151
152CString& CString::operator=(const char* c)
153{
154 if (m_data)
155 delete [] m_data;
156 m_length = strlen(c);
157 m_data = new char[m_length + 1];
158 memcpy(m_data, c, m_length + 1);
159
160 return *this;
161}
162
163CString& CString::operator=(const CString& str)
164{
165 if (this == &str)
166 return *this;
167
168 if (m_data)
169 delete [] m_data;
170 m_length = str.m_length;
171 if (str.m_data) {
172 m_data = new char[m_length + 1];
173 memcpy(m_data, str.m_data, m_length + 1);
174 } else
175 m_data = 0;
176
177 return *this;
178}
179
180bool operator==(const CString& c1, const CString& c2)
181{
182 size_t len = c1.size();
183 return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
184}
185
186// These static strings are immutable, except for rc, whose initial value is chosen to
187// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
188static UChar sharedEmptyChar;
189UString::Rep UString::Rep::null = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::null, 0, 0, 0, 0, 0, 0 };
190UString::Rep UString::Rep::empty = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 };
191
192static char* statBuffer = 0; // Only used for debugging via UString::ascii().
193
194PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
195{
196 UChar* copyD = static_cast<UChar*>(fastMalloc(l * sizeof(UChar)));
197 copyChars(copyD, d, l);
198 return create(copyD, l);
199}
200
201PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
202{
203 Rep* r = new Rep;
204 r->offset = 0;
205 r->len = l;
206 r->rc = 1;
207 r->_hash = 0;
208 r->m_identifierTable = 0;
209 r->baseString = r;
210 r->reportedCost = 0;
211 r->buf = d;
212 r->usedCapacity = l;
213 r->capacity = l;
214 r->usedPreCapacity = 0;
215 r->preCapacity = 0;
216
217 r->checkConsistency();
218
219 // steal the single reference this Rep was created with
220 return adoptRef(r);
221}
222
223PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
224{
225 ASSERT(base);
226 base->checkConsistency();
227
228 int baseOffset = base->offset;
229
230 base = base->baseString;
231
232 ASSERT(-(offset + baseOffset) <= base->usedPreCapacity);
233 ASSERT(offset + baseOffset + length <= base->usedCapacity);
234
235 Rep* r = new Rep;
236 r->offset = baseOffset + offset;
237 r->len = length;
238 r->rc = 1;
239 r->_hash = 0;
240 r->m_identifierTable = 0;
241 r->baseString = base.releaseRef();
242 r->reportedCost = 0;
243 r->buf = 0;
244 r->usedCapacity = 0;
245 r->capacity = 0;
246 r->usedPreCapacity = 0;
247 r->preCapacity = 0;
248
249 r->checkConsistency();
250
251 // steal the single reference this Rep was created with
252 return adoptRef(r);
253}
254
255PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
256{
257 if (!string)
258 return &UString::Rep::null;
259
260 size_t length = strlen(string);
261 Vector<UChar, 1024> buffer(length);
262 UChar* p = buffer.data();
263 if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
264 return &UString::Rep::null;
265
266 return UString::Rep::createCopying(buffer.data(), p - buffer.data());
267}
268
269void UString::Rep::destroy()
270{
271 checkConsistency();
272
273 // Static null and empty strings can never be destroyed, but we cannot rely on
274 // reference counting, because ref/deref are not thread-safe.
275 if (!isStatic()) {
276 if (identifierTable())
277 Identifier::remove(this);
278 if (baseString == this)
279 fastFree(buf);
280 else
281 baseString->deref();
282
283 delete this;
284 }
285}
286
287// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
288// or anything like that.
289const unsigned PHI = 0x9e3779b9U;
290
291// Paul Hsieh's SuperFastHash
292// http://www.azillionmonkeys.com/qed/hash.html
293unsigned UString::Rep::computeHash(const UChar* s, int len)
294{
295 unsigned l = len;
296 uint32_t hash = PHI;
297 uint32_t tmp;
298
299 int rem = l & 1;
300 l >>= 1;
301
302 // Main loop
303 for (; l > 0; l--) {
304 hash += s[0];
305 tmp = (s[1] << 11) ^ hash;
306 hash = (hash << 16) ^ tmp;
307 s += 2;
308 hash += hash >> 11;
309 }
310
311 // Handle end case
312 if (rem) {
313 hash += s[0];
314 hash ^= hash << 11;
315 hash += hash >> 17;
316 }
317
318 // Force "avalanching" of final 127 bits
319 hash ^= hash << 3;
320 hash += hash >> 5;
321 hash ^= hash << 2;
322 hash += hash >> 15;
323 hash ^= hash << 10;
324
325 // this avoids ever returning a hash code of 0, since that is used to
326 // signal "hash not computed yet", using a value that is likely to be
327 // effectively the same as 0 when the low bits are masked
328 if (hash == 0)
329 hash = 0x80000000;
330
331 return hash;
332}
333
334// Paul Hsieh's SuperFastHash
335// http://www.azillionmonkeys.com/qed/hash.html
336unsigned UString::Rep::computeHash(const char* s, int l)
337{
338 // This hash is designed to work on 16-bit chunks at a time. But since the normal case
339 // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
340 // were 16-bit chunks, which should give matching results
341
342 uint32_t hash = PHI;
343 uint32_t tmp;
344
345 size_t rem = l & 1;
346 l >>= 1;
347
348 // Main loop
349 for (; l > 0; l--) {
350 hash += static_cast<unsigned char>(s[0]);
351 tmp = (static_cast<unsigned char>(s[1]) << 11) ^ hash;
352 hash = (hash << 16) ^ tmp;
353 s += 2;
354 hash += hash >> 11;
355 }
356
357 // Handle end case
358 if (rem) {
359 hash += static_cast<unsigned char>(s[0]);
360 hash ^= hash << 11;
361 hash += hash >> 17;
362 }
363
364 // Force "avalanching" of final 127 bits
365 hash ^= hash << 3;
366 hash += hash >> 5;
367 hash ^= hash << 2;
368 hash += hash >> 15;
369 hash ^= hash << 10;
370
371 // this avoids ever returning a hash code of 0, since that is used to
372 // signal "hash not computed yet", using a value that is likely to be
373 // effectively the same as 0 when the low bits are masked
374 if (hash == 0)
375 hash = 0x80000000;
376
377 return hash;
378}
379
380#ifndef NDEBUG
381void UString::Rep::checkConsistency() const
382{
383 // Only base strings have non-zero shared data.
384 if (this != baseString) {
385 ASSERT(!buf);
386 ASSERT(!usedCapacity);
387 ASSERT(!capacity);
388 ASSERT(!usedPreCapacity);
389 ASSERT(!preCapacity);
390 }
391
392 // There is no recursion for base strings.
393 ASSERT(baseString == baseString->baseString);
394
395 if (isStatic()) {
396 // There are only two static strings: null and empty.
397 ASSERT(!len);
398
399 // Static strings cannot get in identifier tables, because they are globally shared.
400 ASSERT(!identifierTable());
401 }
402
403 // The string fits in buffer.
404 ASSERT(baseString->usedPreCapacity <= baseString->preCapacity);
405 ASSERT(baseString->usedCapacity <= baseString->capacity);
406 ASSERT(-offset <= baseString->usedPreCapacity);
407 ASSERT(offset + len <= baseString->usedCapacity);
408}
409#endif
410
411// put these early so they can be inlined
412inline size_t UString::expandedSize(size_t size, size_t otherSize)
413{
414 // Do the size calculation in two parts, returning overflowIndicator if
415 // we overflow the maximum value that we can handle.
416
417 if (size > maxUChars())
418 return overflowIndicator();
419
420 size_t expandedSize = ((size + 10) / 10 * 11) + 1;
421 if (maxUChars() - expandedSize < otherSize)
422 return overflowIndicator();
423
424 return expandedSize + otherSize;
425}
426
427inline int UString::usedCapacity() const
428{
429 return m_rep->baseString->usedCapacity;
430}
431
432inline int UString::usedPreCapacity() const
433{
434 return m_rep->baseString->usedPreCapacity;
435}
436
437void UString::expandCapacity(int requiredLength)
438{
439 m_rep->checkConsistency();
440
441 Rep* r = m_rep->baseString;
442
443 if (requiredLength > r->capacity) {
444 size_t newCapacity = expandedSize(requiredLength, r->preCapacity);
445 UChar* oldBuf = r->buf;
446 r->buf = reallocChars(r->buf, newCapacity);
447 if (!r->buf) {
448 r->buf = oldBuf;
449 makeNull();
450 return;
451 }
452 r->capacity = newCapacity - r->preCapacity;
453 }
454 if (requiredLength > r->usedCapacity)
455 r->usedCapacity = requiredLength;
456
457 m_rep->checkConsistency();
458}
459
460void UString::expandPreCapacity(int requiredPreCap)
461{
462 m_rep->checkConsistency();
463
464 Rep* r = m_rep->baseString;
465
466 if (requiredPreCap > r->preCapacity) {
467 size_t newCapacity = expandedSize(requiredPreCap, r->capacity);
468 int delta = newCapacity - r->capacity - r->preCapacity;
469
470 UChar* newBuf = allocChars(newCapacity);
471 if (!newBuf) {
472 makeNull();
473 return;
474 }
475 copyChars(newBuf + delta, r->buf, r->capacity + r->preCapacity);
476 fastFree(r->buf);
477 r->buf = newBuf;
478
479 r->preCapacity = newCapacity - r->capacity;
480 }
481 if (requiredPreCap > r->usedPreCapacity)
482 r->usedPreCapacity = requiredPreCap;
483
484 m_rep->checkConsistency();
485}
486
487UString::UString(const char* c)
488{
489 if (!c) {
490 m_rep = &Rep::null;
491 return;
492 }
493
494 if (!c[0]) {
495 m_rep = &Rep::empty;
496 return;
497 }
498
499 size_t length = strlen(c);
500 UChar* d = allocChars(length);
501 if (!d)
502 makeNull();
503 else {
504 for (size_t i = 0; i < length; i++)
505 d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
506 m_rep = Rep::create(d, static_cast<int>(length));
507 }
508}
509
510UString::UString(const UChar* c, int length)
511{
512 if (length == 0)
513 m_rep = &Rep::empty;
514 else
515 m_rep = Rep::createCopying(c, length);
516}
517
518UString::UString(UChar* c, int length, bool copy)
519{
520 if (length == 0)
521 m_rep = &Rep::empty;
522 else if (copy)
523 m_rep = Rep::createCopying(c, length);
524 else
525 m_rep = Rep::create(c, length);
526}
527
528UString::UString(const Vector<UChar>& buffer)
529{
530 if (!buffer.size())
531 m_rep = &Rep::empty;
532 else
533 m_rep = Rep::createCopying(buffer.data(), buffer.size());
534}
535
536PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
537{
538 a->checkConsistency();
539 b->checkConsistency();
540
541 int aSize = a->size();
542 int aOffset = a->offset;
543 int bSize = b->size();
544 int bOffset = b->offset;
545 int length = aSize + bSize;
546
547 // possible cases:
548
549 // a is empty
550 if (aSize == 0)
551 return b;
552 // b is empty
553 if (bSize == 0)
554 return a;
555
556 if (bSize == 1 && aOffset + aSize == a->baseString->usedCapacity && aOffset + length <= a->baseString->capacity) {
557 // b is a single character (common fast case)
558 a->baseString->usedCapacity = aOffset + length;
559 a->data()[aSize] = b->data()[0];
560 return UString::Rep::create(a, 0, length);
561 }
562
563 if (aOffset + aSize == a->baseString->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize &&
564 (-bOffset != b->baseString->usedPreCapacity || aSize >= bSize)) {
565 // - a reaches the end of its buffer so it qualifies for shared append
566 // - also, it's at least a quarter the length of b - appending to a much shorter
567 // string does more harm than good
568 // - however, if b qualifies for prepend and is longer than a, we'd rather prepend
569 UString x(a);
570 x.expandCapacity(aOffset + length);
571 if (!a->data() || !x.data())
572 return 0;
573 copyChars(a->data() + aSize, b->data(), bSize);
574 PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length);
575
576 a->checkConsistency();
577 b->checkConsistency();
578 result->checkConsistency();
579
580 return result;
581 }
582
583 if (-bOffset == b->baseString->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
584 // - b reaches the beginning of its buffer so it qualifies for shared prepend
585 // - also, it's at least a quarter the length of a - prepending to a much shorter
586 // string does more harm than good
587 UString y(b);
588 y.expandPreCapacity(-bOffset + aSize);
589 if (!b->data() || !y.data())
590 return 0;
591 copyChars(b->data() - aSize, a->data(), aSize);
592 PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length);
593
594 a->checkConsistency();
595 b->checkConsistency();
596 result->checkConsistency();
597
598 return result;
599 }
600
601 // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
602 size_t newCapacity = UString::expandedSize(length, 0);
603 UChar* d = allocChars(newCapacity);
604 if (!d)
605 return 0;
606 copyChars(d, a->data(), aSize);
607 copyChars(d + aSize, b->data(), bSize);
608 PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
609 result->capacity = newCapacity;
610
611 a->checkConsistency();
612 b->checkConsistency();
613 result->checkConsistency();
614
615 return result;
616}
617
618const UString& UString::null()
619{
620 static UString* n = new UString; // Should be called from main thread at least once to be safely initialized.
621 return *n;
622}
623
624UString UString::from(int i)
625{
626 UChar buf[1 + sizeof(i) * 3];
627 UChar* end = buf + sizeof(buf) / sizeof(UChar);
628 UChar* p = end;
629
630 if (i == 0)
631 *--p = '0';
632 else if (i == INT_MIN) {
633 char minBuf[1 + sizeof(i) * 3];
634 sprintf(minBuf, "%d", INT_MIN);
635 return UString(minBuf);
636 } else {
637 bool negative = false;
638 if (i < 0) {
639 negative = true;
640 i = -i;
641 }
642 while (i) {
643 *--p = static_cast<unsigned short>((i % 10) + '0');
644 i /= 10;
645 }
646 if (negative)
647 *--p = '-';
648 }
649
650 return UString(p, static_cast<int>(end - p));
651}
652
653UString UString::from(unsigned int u)
654{
655 UChar buf[sizeof(u) * 3];
656 UChar* end = buf + sizeof(buf) / sizeof(UChar);
657 UChar* p = end;
658
659 if (u == 0)
660 *--p = '0';
661 else {
662 while (u) {
663 *--p = static_cast<unsigned short>((u % 10) + '0');
664 u /= 10;
665 }
666 }
667
668 return UString(p, static_cast<int>(end - p));
669}
670
671UString UString::from(long l)
672{
673 UChar buf[1 + sizeof(l) * 3];
674 UChar* end = buf + sizeof(buf) / sizeof(UChar);
675 UChar* p = end;
676
677 if (l == 0)
678 *--p = '0';
679 else if (l == LONG_MIN) {
680 char minBuf[1 + sizeof(l) * 3];
681 sprintf(minBuf, "%ld", LONG_MIN);
682 return UString(minBuf);
683 } else {
684 bool negative = false;
685 if (l < 0) {
686 negative = true;
687 l = -l;
688 }
689 while (l) {
690 *--p = static_cast<unsigned short>((l % 10) + '0');
691 l /= 10;
692 }
693 if (negative)
694 *--p = '-';
695 }
696
697 return UString(p, static_cast<int>(end - p));
698}
699
700UString UString::from(double d)
701{
702 // avoid ever printing -NaN, in JS conceptually there is only one NaN value
703 if (isnan(d))
704 return "NaN";
705
706 char buf[80];
707 int decimalPoint;
708 int sign;
709
710 char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
711 int length = static_cast<int>(strlen(result));
712
713 int i = 0;
714 if (sign)
715 buf[i++] = '-';
716
717 if (decimalPoint <= 0 && decimalPoint > -6) {
718 buf[i++] = '0';
719 buf[i++] = '.';
720 for (int j = decimalPoint; j < 0; j++)
721 buf[i++] = '0';
722 strcpy(buf + i, result);
723 } else if (decimalPoint <= 21 && decimalPoint > 0) {
724 if (length <= decimalPoint) {
725 strcpy(buf + i, result);
726 i += length;
727 for (int j = 0; j < decimalPoint - length; j++)
728 buf[i++] = '0';
729 buf[i] = '\0';
730 } else {
731 strncpy(buf + i, result, decimalPoint);
732 i += decimalPoint;
733 buf[i++] = '.';
734 strcpy(buf + i, result + decimalPoint);
735 }
736 } else if (result[0] < '0' || result[0] > '9')
737 strcpy(buf + i, result);
738 else {
739 buf[i++] = result[0];
740 if (length > 1) {
741 buf[i++] = '.';
742 strcpy(buf + i, result + 1);
743 i += length - 1;
744 }
745
746 buf[i++] = 'e';
747 buf[i++] = (decimalPoint >= 0) ? '+' : '-';
748 // decimalPoint can't be more than 3 digits decimal given the
749 // nature of float representation
750 int exponential = decimalPoint - 1;
751 if (exponential < 0)
752 exponential = -exponential;
753 if (exponential >= 100)
754 buf[i++] = static_cast<char>('0' + exponential / 100);
755 if (exponential >= 10)
756 buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
757 buf[i++] = static_cast<char>('0' + exponential % 10);
758 buf[i++] = '\0';
759 }
760
761 freedtoa(result);
762
763 return UString(buf);
764}
765
766UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
767{
768 m_rep->checkConsistency();
769
770 if (rangeCount == 1 && separatorCount == 0) {
771 int thisSize = size();
772 int position = substringRanges[0].position;
773 int length = substringRanges[0].length;
774 if (position <= 0 && length >= thisSize)
775 return *this;
776 return UString::Rep::create(m_rep, max(0, position), min(thisSize, length));
777 }
778
779 int totalLength = 0;
780 for (int i = 0; i < rangeCount; i++)
781 totalLength += substringRanges[i].length;
782 for (int i = 0; i < separatorCount; i++)
783 totalLength += separators[i].size();
784
785 if (totalLength == 0)
786 return "";
787
788 UChar* buffer = allocChars(totalLength);
789 if (!buffer)
790 return null();
791
792 int maxCount = max(rangeCount, separatorCount);
793 int bufferPos = 0;
794 for (int i = 0; i < maxCount; i++) {
795 if (i < rangeCount) {
796 copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
797 bufferPos += substringRanges[i].length;
798 }
799 if (i < separatorCount) {
800 copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
801 bufferPos += separators[i].size();
802 }
803 }
804
805 return UString::Rep::create(buffer, totalLength);
806}
807
808UString& UString::append(const UString &t)
809{
810 m_rep->checkConsistency();
811 t.rep()->checkConsistency();
812
813 int thisSize = size();
814 int thisOffset = m_rep->offset;
815 int tSize = t.size();
816 int length = thisSize + tSize;
817
818 // possible cases:
819 if (thisSize == 0) {
820 // this is empty
821 *this = t;
822 } else if (tSize == 0) {
823 // t is empty
824 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
825 // this is direct and has refcount of 1 (so we can just alter it directly)
826 expandCapacity(thisOffset + length);
827 if (data()) {
828 copyChars(m_rep->data() + thisSize, t.data(), tSize);
829 m_rep->len = length;
830 m_rep->_hash = 0;
831 }
832 } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) {
833 // this reaches the end of the buffer - extend it if it's long enough to append to
834 expandCapacity(thisOffset + length);
835 if (data()) {
836 copyChars(m_rep->data() + thisSize, t.data(), tSize);
837 m_rep = Rep::create(m_rep, 0, length);
838 }
839 } else {
840 // this is shared with someone using more capacity, gotta make a whole new string
841 size_t newCapacity = expandedSize(length, 0);
842 UChar* d = allocChars(newCapacity);
843 if (!d)
844 makeNull();
845 else {
846 copyChars(d, data(), thisSize);
847 copyChars(d + thisSize, t.data(), tSize);
848 m_rep = Rep::create(d, length);
849 m_rep->capacity = newCapacity;
850 }
851 }
852
853 m_rep->checkConsistency();
854 t.rep()->checkConsistency();
855
856 return *this;
857}
858
859UString& UString::append(const UChar* tData, int tSize)
860{
861 m_rep->checkConsistency();
862
863 int thisSize = size();
864 int thisOffset = m_rep->offset;
865 int length = thisSize + tSize;
866
867 // possible cases:
868 if (tSize == 0) {
869 // t is empty
870 } else if (thisSize == 0) {
871 // this is empty
872 m_rep = Rep::createCopying(tData, tSize);
873 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
874 // this is direct and has refcount of 1 (so we can just alter it directly)
875 expandCapacity(thisOffset + length);
876 if (data()) {
877 copyChars(m_rep->data() + thisSize, tData, tSize);
878 m_rep->len = length;
879 m_rep->_hash = 0;
880 }
881 } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) {
882 // this reaches the end of the buffer - extend it if it's long enough to append to
883 expandCapacity(thisOffset + length);
884 if (data()) {
885 copyChars(m_rep->data() + thisSize, tData, tSize);
886 m_rep = Rep::create(m_rep, 0, length);
887 }
888 } else {
889 // this is shared with someone using more capacity, gotta make a whole new string
890 size_t newCapacity = expandedSize(length, 0);
891 UChar* d = allocChars(newCapacity);
892 if (!d)
893 makeNull();
894 else {
895 copyChars(d, data(), thisSize);
896 copyChars(d + thisSize, tData, tSize);
897 m_rep = Rep::create(d, length);
898 m_rep->capacity = newCapacity;
899 }
900 }
901
902 m_rep->checkConsistency();
903
904 return *this;
905}
906
907UString& UString::append(const char* t)
908{
909 m_rep->checkConsistency();
910
911 int thisSize = size();
912 int thisOffset = m_rep->offset;
913 int tSize = static_cast<int>(strlen(t));
914 int length = thisSize + tSize;
915
916 // possible cases:
917 if (thisSize == 0) {
918 // this is empty
919 *this = t;
920 } else if (tSize == 0) {
921 // t is empty, we'll just return *this below.
922 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
923 // this is direct and has refcount of 1 (so we can just alter it directly)
924 expandCapacity(thisOffset + length);
925 UChar* d = m_rep->data();
926 if (d) {
927 for (int i = 0; i < tSize; ++i)
928 d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
929 m_rep->len = length;
930 m_rep->_hash = 0;
931 }
932 } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) {
933 // this string reaches the end of the buffer - extend it
934 expandCapacity(thisOffset + length);
935 UChar* d = m_rep->data();
936 if (d) {
937 for (int i = 0; i < tSize; ++i)
938 d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
939 m_rep = Rep::create(m_rep, 0, length);
940 }
941 } else {
942 // this is shared with someone using more capacity, gotta make a whole new string
943 size_t newCapacity = expandedSize(length, 0);
944 UChar* d = allocChars(newCapacity);
945 if (!d)
946 makeNull();
947 else {
948 copyChars(d, data(), thisSize);
949 for (int i = 0; i < tSize; ++i)
950 d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
951 m_rep = Rep::create(d, length);
952 m_rep->capacity = newCapacity;
953 }
954 }
955
956 m_rep->checkConsistency();
957
958 return *this;
959}
960
961UString& UString::append(UChar c)
962{
963 m_rep->checkConsistency();
964
965 int thisOffset = m_rep->offset;
966 int length = size();
967
968 // possible cases:
969 if (length == 0) {
970 // this is empty - must make a new m_rep because we don't want to pollute the shared empty one
971 size_t newCapacity = expandedSize(1, 0);
972 UChar* d = allocChars(newCapacity);
973 if (!d)
974 makeNull();
975 else {
976 d[0] = c;
977 m_rep = Rep::create(d, 1);
978 m_rep->capacity = newCapacity;
979 }
980 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
981 // this is direct and has refcount of 1 (so we can just alter it directly)
982 expandCapacity(thisOffset + length + 1);
983 UChar* d = m_rep->data();
984 if (d) {
985 d[length] = c;
986 m_rep->len = length + 1;
987 m_rep->_hash = 0;
988 }
989 } else if (thisOffset + length == usedCapacity() && length >= minShareSize) {
990 // this reaches the end of the string - extend it and share
991 expandCapacity(thisOffset + length + 1);
992 UChar* d = m_rep->data();
993 if (d) {
994 d[length] = c;
995 m_rep = Rep::create(m_rep, 0, length + 1);
996 }
997 } else {
998 // this is shared with someone using more capacity, gotta make a whole new string
999 size_t newCapacity = expandedSize(length + 1, 0);
1000 UChar* d = allocChars(newCapacity);
1001 if (!d)
1002 makeNull();
1003 else {
1004 copyChars(d, data(), length);
1005 d[length] = c;
1006 m_rep = Rep::create(d, length + 1);
1007 m_rep->capacity = newCapacity;
1008 }
1009 }
1010
1011 m_rep->checkConsistency();
1012
1013 return *this;
1014}
1015
1016bool UString::getCString(CStringBuffer& buffer) const
1017{
1018 int length = size();
1019 int neededSize = length + 1;
1020 buffer.resize(neededSize);
1021 char* buf = buffer.data();
1022
1023 UChar ored = 0;
1024 const UChar* p = data();
1025 char* q = buf;
1026 const UChar* limit = p + length;
1027 while (p != limit) {
1028 UChar c = p[0];
1029 ored |= c;
1030 *q = static_cast<char>(c);
1031 ++p;
1032 ++q;
1033 }
1034 *q = '\0';
1035
1036 return !(ored & 0xFF00);
1037}
1038
1039char* UString::ascii() const
1040{
1041 int length = size();
1042 int neededSize = length + 1;
1043 delete[] statBuffer;
1044 statBuffer = new char[neededSize];
1045
1046 const UChar* p = data();
1047 char* q = statBuffer;
1048 const UChar* limit = p + length;
1049 while (p != limit) {
1050 *q = static_cast<char>(p[0]);
1051 ++p;
1052 ++q;
1053 }
1054 *q = '\0';
1055
1056 return statBuffer;
1057}
1058
1059UString& UString::operator=(const char* c)
1060{
1061 if (!c) {
1062 m_rep = &Rep::null;
1063 return *this;
1064 }
1065
1066 if (!c[0]) {
1067 m_rep = &Rep::empty;
1068 return *this;
1069 }
1070
1071 int l = static_cast<int>(strlen(c));
1072 UChar* d;
1073 if (m_rep->rc == 1 && l <= m_rep->capacity && m_rep->baseIsSelf() && m_rep->offset == 0 && m_rep->preCapacity == 0) {
1074 d = m_rep->buf;
1075 m_rep->_hash = 0;
1076 m_rep->len = l;
1077 } else {
1078 d = allocChars(l);
1079 if (!d) {
1080 makeNull();
1081 return *this;
1082 }
1083 m_rep = Rep::create(d, l);
1084 }
1085 for (int i = 0; i < l; i++)
1086 d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
1087
1088 return *this;
1089}
1090
1091bool UString::is8Bit() const
1092{
1093 const UChar* u = data();
1094 const UChar* limit = u + size();
1095 while (u < limit) {
1096 if (u[0] > 0xFF)
1097 return false;
1098 ++u;
1099 }
1100
1101 return true;
1102}
1103
1104UChar UString::operator[](int pos) const
1105{
1106 if (pos >= size())
1107 return '\0';
1108 return data()[pos];
1109}
1110
1111double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
1112{
1113 if (size() == 1) {
1114 UChar c = data()[0];
1115 if (isASCIIDigit(c))
1116 return c - '0';
1117 if (isASCIISpace(c) && tolerateEmptyString)
1118 return 0;
1119 return NaN;
1120 }
1121
1122 // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
1123 // after the number, so this is too strict a check.
1124 CStringBuffer s;
1125 if (!getCString(s))
1126 return NaN;
1127 const char* c = s.data();
1128
1129 // skip leading white space
1130 while (isASCIISpace(*c))
1131 c++;
1132
1133 // empty string ?
1134 if (*c == '\0')
1135 return tolerateEmptyString ? 0.0 : NaN;
1136
1137 double d;
1138
1139 // hex number ?
1140 if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) {
1141 const char* firstDigitPosition = c + 2;
1142 c++;
1143 d = 0.0;
1144 while (*(++c)) {
1145 if (*c >= '0' && *c <= '9')
1146 d = d * 16.0 + *c - '0';
1147 else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
1148 d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
1149 else
1150 break;
1151 }
1152
1153 if (d >= mantissaOverflowLowerBound)
1154 d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16);
1155 } else {
1156 // regular number ?
1157 char* end;
1158 d = strtod(c, &end);
1159 if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {
1160 c = end;
1161 } else {
1162 double sign = 1.0;
1163
1164 if (*c == '+')
1165 c++;
1166 else if (*c == '-') {
1167 sign = -1.0;
1168 c++;
1169 }
1170
1171 // We used strtod() to do the conversion. However, strtod() handles
1172 // infinite values slightly differently than JavaScript in that it
1173 // converts the string "inf" with any capitalization to infinity,
1174 // whereas the ECMA spec requires that it be converted to NaN.
1175
1176 if (c[0] == 'I' && c[1] == 'n' && c[2] == 'f' && c[3] == 'i' && c[4] == 'n' && c[5] == 'i' && c[6] == 't' && c[7] == 'y') {
1177 d = sign * Inf;
1178 c += 8;
1179 } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i')
1180 c = end;
1181 else
1182 return NaN;
1183 }
1184 }
1185
1186 // allow trailing white space
1187 while (isASCIISpace(*c))
1188 c++;
1189 // don't allow anything after - unless tolerant=true
1190 if (!tolerateTrailingJunk && *c != '\0')
1191 d = NaN;
1192
1193 return d;
1194}
1195
1196double UString::toDouble(bool tolerateTrailingJunk) const
1197{
1198 return toDouble(tolerateTrailingJunk, true);
1199}
1200
1201double UString::toDouble() const
1202{
1203 return toDouble(false, true);
1204}
1205
1206uint32_t UString::toUInt32(bool* ok) const
1207{
1208 double d = toDouble();
1209 bool b = true;
1210
1211 if (d != static_cast<uint32_t>(d)) {
1212 b = false;
1213 d = 0;
1214 }
1215
1216 if (ok)
1217 *ok = b;
1218
1219 return static_cast<uint32_t>(d);
1220}
1221
1222uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
1223{
1224 double d = toDouble(false, tolerateEmptyString);
1225 bool b = true;
1226
1227 if (d != static_cast<uint32_t>(d)) {
1228 b = false;
1229 d = 0;
1230 }
1231
1232 if (ok)
1233 *ok = b;
1234
1235 return static_cast<uint32_t>(d);
1236}
1237
1238uint32_t UString::toStrictUInt32(bool* ok) const
1239{
1240 if (ok)
1241 *ok = false;
1242
1243 // Empty string is not OK.
1244 int len = m_rep->len;
1245 if (len == 0)
1246 return 0;
1247 const UChar* p = m_rep->data();
1248 unsigned short c = p[0];
1249
1250 // If the first digit is 0, only 0 itself is OK.
1251 if (c == '0') {
1252 if (len == 1 && ok)
1253 *ok = true;
1254 return 0;
1255 }
1256
1257 // Convert to UInt32, checking for overflow.
1258 uint32_t i = 0;
1259 while (1) {
1260 // Process character, turning it into a digit.
1261 if (c < '0' || c > '9')
1262 return 0;
1263 const unsigned d = c - '0';
1264
1265 // Multiply by 10, checking for overflow out of 32 bits.
1266 if (i > 0xFFFFFFFFU / 10)
1267 return 0;
1268 i *= 10;
1269
1270 // Add in the digit, checking for overflow out of 32 bits.
1271 const unsigned max = 0xFFFFFFFFU - d;
1272 if (i > max)
1273 return 0;
1274 i += d;
1275
1276 // Handle end of string.
1277 if (--len == 0) {
1278 if (ok)
1279 *ok = true;
1280 return i;
1281 }
1282
1283 // Get next character.
1284 c = *(++p);
1285 }
1286}
1287
1288int UString::find(const UString& f, int pos) const
1289{
1290 int sz = size();
1291 int fsz = f.size();
1292 if (sz < fsz)
1293 return -1;
1294 if (pos < 0)
1295 pos = 0;
1296 if (fsz == 0)
1297 return pos;
1298 const UChar* end = data() + sz - fsz;
1299 int fsizeminusone = (fsz - 1) * sizeof(UChar);
1300 const UChar* fdata = f.data();
1301 unsigned short fchar = fdata[0];
1302 ++fdata;
1303 for (const UChar* c = data() + pos; c <= end; c++) {
1304 if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
1305 return static_cast<int>(c - data());
1306 }
1307
1308 return -1;
1309}
1310
1311int UString::find(UChar ch, int pos) const
1312{
1313 if (pos < 0)
1314 pos = 0;
1315 const UChar* end = data() + size();
1316 for (const UChar* c = data() + pos; c < end; c++) {
1317 if (*c == ch)
1318 return static_cast<int>(c - data());
1319 }
1320
1321 return -1;
1322}
1323
1324int UString::rfind(const UString& f, int pos) const
1325{
1326 int sz = size();
1327 int fsz = f.size();
1328 if (sz < fsz)
1329 return -1;
1330 if (pos < 0)
1331 pos = 0;
1332 if (pos > sz - fsz)
1333 pos = sz - fsz;
1334 if (fsz == 0)
1335 return pos;
1336 int fsizeminusone = (fsz - 1) * sizeof(UChar);
1337 const UChar* fdata = f.data();
1338 for (const UChar* c = data() + pos; c >= data(); c--) {
1339 if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
1340 return static_cast<int>(c - data());
1341 }
1342
1343 return -1;
1344}
1345
1346int UString::rfind(UChar ch, int pos) const
1347{
1348 if (isEmpty())
1349 return -1;
1350 if (pos + 1 >= size())
1351 pos = size() - 1;
1352 for (const UChar* c = data() + pos; c >= data(); c--) {
1353 if (*c == ch)
1354 return static_cast<int>(c - data());
1355 }
1356
1357 return -1;
1358}
1359
1360UString UString::substr(int pos, int len) const
1361{
1362 int s = size();
1363
1364 if (pos < 0)
1365 pos = 0;
1366 else if (pos >= s)
1367 pos = s;
1368 if (len < 0)
1369 len = s;
1370 if (pos + len >= s)
1371 len = s - pos;
1372
1373 if (pos == 0 && len == s)
1374 return *this;
1375
1376 return UString(Rep::create(m_rep, pos, len));
1377}
1378
1379bool operator==(const UString& s1, const UString& s2)
1380{
1381 int size = s1.size();
1382 switch (size) {
1383 case 0:
1384 return !s2.size();
1385 case 1:
1386 return s2.size() == 1 && s1.data()[0] == s2.data()[0];
1387 default:
1388 return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
1389 }
1390}
1391
1392bool operator==(const UString& s1, const char *s2)
1393{
1394 if (s2 == 0)
1395 return s1.isEmpty();
1396
1397 const UChar* u = s1.data();
1398 const UChar* uend = u + s1.size();
1399 while (u != uend && *s2) {
1400 if (u[0] != (unsigned char)*s2)
1401 return false;
1402 s2++;
1403 u++;
1404 }
1405
1406 return u == uend && *s2 == 0;
1407}
1408
1409bool operator<(const UString& s1, const UString& s2)
1410{
1411 const int l1 = s1.size();
1412 const int l2 = s2.size();
1413 const int lmin = l1 < l2 ? l1 : l2;
1414 const UChar* c1 = s1.data();
1415 const UChar* c2 = s2.data();
1416 int l = 0;
1417 while (l < lmin && *c1 == *c2) {
1418 c1++;
1419 c2++;
1420 l++;
1421 }
1422 if (l < lmin)
1423 return (c1[0] < c2[0]);
1424
1425 return (l1 < l2);
1426}
1427
1428bool operator>(const UString& s1, const UString& s2)
1429{
1430 const int l1 = s1.size();
1431 const int l2 = s2.size();
1432 const int lmin = l1 < l2 ? l1 : l2;
1433 const UChar* c1 = s1.data();
1434 const UChar* c2 = s2.data();
1435 int l = 0;
1436 while (l < lmin && *c1 == *c2) {
1437 c1++;
1438 c2++;
1439 l++;
1440 }
1441 if (l < lmin)
1442 return (c1[0] > c2[0]);
1443
1444 return (l1 > l2);
1445}
1446
1447int compare(const UString& s1, const UString& s2)
1448{
1449 const int l1 = s1.size();
1450 const int l2 = s2.size();
1451 const int lmin = l1 < l2 ? l1 : l2;
1452 const UChar* c1 = s1.data();
1453 const UChar* c2 = s2.data();
1454 int l = 0;
1455 while (l < lmin && *c1 == *c2) {
1456 c1++;
1457 c2++;
1458 l++;
1459 }
1460
1461 if (l < lmin)
1462 return (c1[0] > c2[0]) ? 1 : -1;
1463
1464 if (l1 == l2)
1465 return 0;
1466
1467 return (l1 > l2) ? 1 : -1;
1468}
1469
1470bool equal(const UString::Rep* r, const UString::Rep* b)
1471{
1472 int length = r->len;
1473 if (length != b->len)
1474 return false;
1475 const UChar* d = r->data();
1476 const UChar* s = b->data();
1477 for (int i = 0; i != length; ++i) {
1478 if (d[i] != s[i])
1479 return false;
1480 }
1481 return true;
1482}
1483
1484CString UString::UTF8String(bool strict) const
1485{
1486 // Allocate a buffer big enough to hold all the characters.
1487 const int length = size();
1488 Vector<char, 1024> buffer(length * 3);
1489
1490 // Convert to runs of 8-bit characters.
1491 char* p = buffer.data();
1492 const UChar* d = reinterpret_cast<const UChar*>(&data()[0]);
1493 ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), strict);
1494 if (result != conversionOK)
1495 return CString();
1496
1497 return CString(buffer.data(), p - buffer.data());
1498}
1499
1500// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
1501NEVER_INLINE void UString::makeNull()
1502{
1503 m_rep = &Rep::null;
1504}
1505
1506// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
1507NEVER_INLINE UString::Rep* UString::nullRep()
1508{
1509 return &Rep::null;
1510}
1511
1512} // namespace JSC
Note: See TracBrowser for help on using the repository browser.