michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/TextEncoder.h" michael@0: #include "mozilla/dom/EncodingUtils.h" michael@0: #include "nsContentUtils.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: void michael@0: TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv) michael@0: { michael@0: nsAutoString label(aEncoding); michael@0: EncodingUtils::TrimSpaceCharacters(label); michael@0: michael@0: // Let encoding be the result of getting an encoding from label. michael@0: // If encoding is failure, or is none of utf-8, utf-16, and utf-16be, michael@0: // throw a TypeError. michael@0: if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) { michael@0: aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label); michael@0: return; michael@0: } michael@0: michael@0: if (!mEncoding.EqualsLiteral("UTF-8") && michael@0: !mEncoding.EqualsLiteral("UTF-16LE") && michael@0: !mEncoding.EqualsLiteral("UTF-16BE")) { michael@0: aRv.ThrowTypeError(MSG_DOM_ENCODING_NOT_UTF); michael@0: return; michael@0: } michael@0: michael@0: // Create an encoder object for mEncoding. michael@0: mEncoder = EncodingUtils::EncoderForEncoding(mEncoding); michael@0: } michael@0: michael@0: void michael@0: TextEncoder::Encode(JSContext* aCx, michael@0: JS::Handle aObj, michael@0: const nsAString& aString, michael@0: const bool aStream, michael@0: JS::MutableHandle aRetval, michael@0: ErrorResult& aRv) michael@0: { michael@0: // Run the steps of the encoding algorithm. michael@0: int32_t srcLen = aString.Length(); michael@0: int32_t maxLen; michael@0: const char16_t* data = PromiseFlatString(aString).get(); michael@0: nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen); michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: return; michael@0: } michael@0: // Need a fallible allocator because the caller may be a content michael@0: // and the content can specify the length of the string. michael@0: static const fallible_t fallible = fallible_t(); michael@0: nsAutoArrayPtr buf(new (fallible) char[maxLen + 1]); michael@0: if (!buf) { michael@0: aRv.Throw(NS_ERROR_OUT_OF_MEMORY); michael@0: return; michael@0: } michael@0: michael@0: int32_t dstLen = maxLen; michael@0: rv = mEncoder->Convert(data, &srcLen, buf, &dstLen); michael@0: michael@0: // If the internal streaming flag is not set, then reset michael@0: // the encoding algorithm state to the default values for encoding. michael@0: if (!aStream) { michael@0: int32_t finishLen = maxLen - dstLen; michael@0: rv = mEncoder->Finish(buf + dstLen, &finishLen); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: dstLen += finishLen; michael@0: } michael@0: } michael@0: michael@0: JSObject* outView = nullptr; michael@0: if (NS_SUCCEEDED(rv)) { michael@0: buf[dstLen] = '\0'; michael@0: JSAutoCompartment ac(aCx, aObj); michael@0: outView = Uint8Array::Create(aCx, dstLen, michael@0: reinterpret_cast(buf.get())); michael@0: if (!outView) { michael@0: aRv.Throw(NS_ERROR_OUT_OF_MEMORY); michael@0: return; michael@0: } michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) { michael@0: aRv.Throw(rv); michael@0: } michael@0: aRetval.set(outView); michael@0: } michael@0: michael@0: void michael@0: TextEncoder::GetEncoding(nsAString& aEncoding) michael@0: { michael@0: CopyASCIItoUTF16(mEncoding, aEncoding); michael@0: nsContentUtils::ASCIIToLower(aEncoding); michael@0: } michael@0: michael@0: } // dom michael@0: } // mozilla