double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType) { double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay()); double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds); double localTimeResult = (day * WTF::msPerDay) + ms; double localToUTCTimeOffset = inputTimeType == LocalTime ? localTimeOffset(vm, localTimeResult, inputTimeType).offset : 0; return localTimeResult - localToUTCTimeOffset; }
double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) { double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay()); double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds); double result = (day * WTF::msPerDay) + ms; if (!inputIsUTC) { // convert to UTC double utcOffset = getUTCOffset(exec); result -= utcOffset; result -= getDSTOffset(exec, result, utcOffset); } return result; }
PassRefPtr<SharedBuffer> MHTMLArchive::generateMHTMLData(Page* page) { Vector<PageSerializer::Resource> resources; PageSerializer pageSerializer(&resources); pageSerializer.serialize(page); String boundary = generateRandomBoundary(); String endOfResourceBoundary = makeString("--", boundary, "\r\n"); GregorianDateTime now; now.setToCurrentLocalTime(); String dateString = makeRFC2822DateString(now.weekDay(), now.monthDay(), now.month(), now.year(), now.hour(), now.minute(), now.second(), now.utcOffset() / 60); StringBuilder stringBuilder; stringBuilder.append("From: <Saved by WebKit>\r\n"); stringBuilder.append("Subject: "); // We replace non ASCII characters with '?' characters to match IE's behavior. stringBuilder.append(replaceNonPrintableCharacters(page->mainFrame().document()->title())); stringBuilder.append("\r\nDate: "); stringBuilder.append(dateString); stringBuilder.append("\r\nMIME-Version: 1.0\r\n"); stringBuilder.append("Content-Type: multipart/related;\r\n"); stringBuilder.append("\ttype=\""); stringBuilder.append(page->mainFrame().document()->suggestedMIMEType()); stringBuilder.append("\";\r\n"); stringBuilder.append("\tboundary=\""); stringBuilder.append(boundary); stringBuilder.append("\"\r\n\r\n"); // We use utf8() below instead of ascii() as ascii() replaces CRLFs with ?? (we still only have put ASCII characters in it). ASSERT(stringBuilder.toString().containsOnlyASCII()); CString asciiString = stringBuilder.toString().utf8(); RefPtr<SharedBuffer> mhtmlData = SharedBuffer::create(); mhtmlData->append(asciiString.data(), asciiString.length()); for (auto& resource : resources) { stringBuilder.clear(); stringBuilder.append(endOfResourceBoundary); stringBuilder.append("Content-Type: "); stringBuilder.append(resource.mimeType); const char* contentEncoding = nullptr; if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) || MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType)) contentEncoding = quotedPrintable; else contentEncoding = base64; stringBuilder.append("\r\nContent-Transfer-Encoding: "); stringBuilder.append(contentEncoding); stringBuilder.append("\r\nContent-Location: "); stringBuilder.append(resource.url); stringBuilder.append("\r\n\r\n"); asciiString = stringBuilder.toString().utf8(); mhtmlData->append(asciiString.data(), asciiString.length()); // FIXME: ideally we would encode the content as a stream without having to fetch it all. const char* data = resource.data->data(); size_t dataLength = resource.data->size(); Vector<char> encodedData; if (!strcmp(contentEncoding, quotedPrintable)) { quotedPrintableEncode(data, dataLength, encodedData); mhtmlData->append(encodedData.data(), encodedData.size()); mhtmlData->append("\r\n", 2); } else { ASSERT(!strcmp(contentEncoding, base64)); // We are not specifying insertLFs = true below as it would cut the lines with LFs and MHTML requires CRLFs. base64Encode(data, dataLength, encodedData); const size_t maximumLineLength = 76; size_t index = 0; size_t encodedDataLength = encodedData.size(); do { size_t lineLength = std::min(encodedDataLength - index, maximumLineLength); mhtmlData->append(encodedData.data() + index, lineLength); mhtmlData->append("\r\n", 2); index += maximumLineLength; } while (index < encodedDataLength); } } asciiString = makeString("--", boundary, "--\r\n").utf8(); mhtmlData->append(asciiString.data(), asciiString.length()); return mhtmlData.release(); }