Quellcode-Bibliothek nsBinaryStream.cpp
Sprache: C
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * This file contains implementations of the nsIBinaryInputStream and * nsIBinaryOutputStream interfaces. Together, these interfaces allows reading * and writing of primitive data types (integers, floating-point values, * booleans, etc.) to a stream in a binary, untagged, fixed-endianness format. * This might be used, for example, to implement network protocols or to * produce architecture-neutral binary disk files, i.e. ones that can be read * and written by both big-endian and little-endian platforms. Output is * written in big-endian order (high-order byte first), as this is traditional * network order. * * @See nsIBinaryInputStream * @See nsIBinaryOutputStream
*/ #include <algorithm> #include <string.h>
// when forwarding ReadSegments to mInputStream, we need to make sure // 'this' is being passed to the writer each time. To do this, we need // a thunking function which keeps the real input stream around.
// mInputStream might give us short reads, so deal with that.
uint32_t bytesRead; do {
nsresult rv = mInputStream->ReadSegments(ReadSegmentForwardingThunk,
&thunkClosure, aCount, &bytesRead);
if (rv == NS_BASE_STREAM_WOULD_BLOCK && thunkClosure.mBytesRead != 0) { // We already read some data. Return it. break;
}
if (bytesRead != length) { return NS_ERROR_FAILURE;
}
return NS_OK;
}
// sometimes, WriteSegmentToString will be handed an odd-number of // bytes, which means we only have half of the last char16_t struct WriteStringClosure {
char16_t* mWriteCursor; bool mHasCarryoverByte; char mCarryoverByte;
};
// there are a few cases we have to account for here: // * even length buffer, no carryover - easy, just append // * odd length buffer, no carryover - the last byte needs to be saved // for carryover // * odd length buffer, with carryover - first byte needs to be used // with the carryover byte, and // the rest of the even length // buffer is appended as normal // * even length buffer, with carryover - the first byte needs to be // used with the previous carryover byte. // this gives you an odd length buffer, // so you have to save the last byte for // the next carryover
// same version of the above, but with correct casting and endian swapping static nsresult WriteSegmentToString(nsIInputStream* aStream, void* aClosure, constchar* aFromSegment,
uint32_t aToOffset, uint32_t aCount,
uint32_t* aWriteCount) {
MOZ_ASSERT(aCount > 0, "Why are we being told to write 0 bytes?");
static_assert(sizeof(char16_t) == 2, "We can't handle other sizes!");
// we're always going to consume the whole buffer no matter what // happens, so take care of that right now.. that allows us to // tweak aCount later. Do NOT move this!
*aWriteCount = aCount;
// if the last Write had an odd-number of bytes read, then if (closure->mHasCarryoverByte) { // re-create the two-byte sequence we want to work with char bytes[2] = {closure->mCarryoverByte, *aFromSegment};
*cursor = *(char16_t*)bytes; // Now the little endianness dance
mozilla::NativeEndian::swapToBigEndianInPlace(cursor, 1);
++cursor;
// now skip past the first byte of the buffer.. code from here // can assume normal operations, but should not assume aCount // is relative to the ORIGINAL buffer
++aFromSegment;
--aCount;
closure->mHasCarryoverByte = false;
}
// this array is possibly unaligned... be careful how we access it! const char16_t* unicodeSegment = reinterpret_cast<const char16_t*>(aFromSegment);
// calculate number of full characters in segment (aCount could be odd!)
uint32_t segmentLength = aCount / sizeof(char16_t);
// copy all data into our aligned buffer. byte swap if necessary. // cursor may be unaligned, so we cannot use copyAndSwapToBigEndian directly
memcpy(cursor, unicodeSegment, segmentLength * sizeof(char16_t));
char16_t* end = cursor + segmentLength;
mozilla::NativeEndian::swapToBigEndianInPlace(cursor, segmentLength);
closure->mWriteCursor = end;
// remember this is the modifed aCount and aFromSegment, // so that will take into account the fact that we might have // skipped the first byte in the buffer if (aCount % sizeof(char16_t) != 0) { // we must have had a carryover byte, that we'll need the next // time around
closure->mCarryoverByte = aFromSegment[aCount - 1];
closure->mHasCarryoverByte = true;
}
rv = Read32(&length); if (NS_FAILED(rv)) { return rv;
}
if (length == 0) {
aString.Truncate(); return NS_OK;
}
// pre-allocate output buffer, and get direct access to buffer... if (!aString.SetLength(length, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY;
}
rv = ReadID(&iid); if (NS_WARN_IF(NS_FAILED(rv))) { return rv;
}
// HACK: Intercept old (pre-gecko6) nsIURI IID, and replace with // the updated IID, so that we're QI'ing to an actual interface. // (As soon as we drop support for upgrading from pre-gecko6, we can // remove this chunk.) staticconst nsIID oldURIiid = {
0x7a22cc0,
0xce5,
0x11d3,
{0x93, 0x31, 0x0, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
// Hack around bug 1508939 // The old CSP serialization can't be handled cleanly when // it's embedded in an old style principal staticconst nsIID oldCSPiid = {
0xb3c4c0ae,
0xbd5e,
0x4cad,
{0x87, 0xe0, 0x8d, 0x21, 0x0d, 0xbb, 0x3f, 0x9f}}; if (iid.Equals(oldCSPiid)) { return NS_ERROR_FAILURE;
} // END HACK
// HACK: Service workers store resource security info on disk in the dom // Cache API. When the uuid of the nsIX509Cert interface changes // these serialized objects cannot be loaded any more. This hack // works around this issue.
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.34Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.