summaryrefslogtreecommitdiffstats
path: root/ipc/hal/DaemonSocketPDUHelpers.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/hal/DaemonSocketPDUHelpers.h')
-rw-r--r--ipc/hal/DaemonSocketPDUHelpers.h1283
1 files changed, 0 insertions, 1283 deletions
diff --git a/ipc/hal/DaemonSocketPDUHelpers.h b/ipc/hal/DaemonSocketPDUHelpers.h
deleted file mode 100644
index 38a848e46..000000000
--- a/ipc/hal/DaemonSocketPDUHelpers.h
+++ /dev/null
@@ -1,1283 +0,0 @@
-/* -*- 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/. */
-
-#ifndef mozilla_ipc_DaemonSocketPDUHelpers_h
-#define mozilla_ipc_DaemonSocketPDUHelpers_h
-
-#include <stdint.h>
-#include "mozilla/ipc/DaemonSocketPDU.h"
-#include "mozilla/UniquePtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace ipc {
-
-struct DaemonSocketPDUHeader {
- DaemonSocketPDUHeader()
- : mService(0x00)
- , mOpcode(0x00)
- , mLength(0x00)
- { }
-
- DaemonSocketPDUHeader(uint8_t aService, uint8_t aOpcode, uint16_t aLength)
- : mService(aService)
- , mOpcode(aOpcode)
- , mLength(aLength)
- { }
-
- uint8_t mService;
- uint8_t mOpcode;
- uint16_t mLength;
-};
-
-namespace DaemonSocketPDUHelpers {
-
-//
-// Logging
-//
-// The HAL IPC logging macros below print clear error messages for
-// failed IPC operations. Use |MOZ_HAL_IPC_CONVERT_WARN_IF|,
-// |MOZ_HAL_IPC_PACK_WARN_IF| and |MOZ_HAL_IPC_UNPACK_WARN_IF| to
-// test for failures when processing PDUs.
-//
-// All macros accept the test condition as their first argument, and
-// additional type information: the convert macro takes the input and
-// output types, the pack macro takes the input type, and the unpack
-// macro takes output type. All macros return the result of the test
-// condition. If the test fails (i.e., the condition is true), they
-// output a warning to the log.
-//
-// Don't call the functions in the detail namespace. They are helpers
-// and not for general use.
-//
-
-namespace detail {
-
-void
-LogProtocolError(const char*, ...);
-
-inline bool
-ConvertWarnIfImpl(const char* aFile, unsigned long aLine,
- bool aCondition, const char* aExpr, const char* aIn,
- const char* aOut)
-{
- if (MOZ_UNLIKELY(aCondition)) {
- LogProtocolError("%s:%d: Convert('%s' to '%s') failed: %s",
- aFile, aLine, aIn, aOut, aExpr);
- }
- return aCondition;
-}
-
-inline bool
-PackWarnIfImpl(const char* aFile, unsigned long aLine,
- bool aCondition, const char* aExpr, const char* aIn)
-{
- if (MOZ_UNLIKELY(aCondition)) {
- LogProtocolError("%s:%d: Pack('%s') failed: %s",
- aFile, aLine, aIn, aExpr);
- }
- return aCondition;
-}
-
-inline bool
-UnpackWarnIfImpl(const char* aFile, unsigned long aLine,
- bool aCondition, const char* aExpr, const char* aOut)
-{
- if (MOZ_UNLIKELY(aCondition)) {
- LogProtocolError("%s:%d: Unpack('%s') failed: %s",
- aFile, aLine, aOut, aExpr);
- }
- return aCondition;
-}
-
-} // namespace detail
-
-#define MOZ_HAL_IPC_CONVERT_WARN_IF(condition, in, out) \
- ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
- ConvertWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in, #out)
-
-#define MOZ_HAL_IPC_PACK_WARN_IF(condition, in) \
- ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
- PackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in)
-
-#define MOZ_HAL_IPC_UNPACK_WARN_IF(condition, out) \
- ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
- UnpackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #out)
-
-//
-// Conversion
-//
-// PDUs can only store primitive data types, such as integers or
-// byte arrays. Gecko often uses more complex data types, such as
-// enumators or stuctures. Conversion functions convert between
-// primitive data and internal Gecko's data types during a PDU's
-// packing and unpacking.
-//
-
-nsresult
-Convert(bool aIn, uint8_t& aOut);
-
-nsresult
-Convert(bool aIn, int32_t& aOut);
-
-nsresult
-Convert(int aIn, uint8_t& aOut);
-
-nsresult
-Convert(int aIn, int16_t& aOut);
-
-nsresult
-Convert(int aIn, int32_t& aOut);
-
-nsresult
-Convert(uint8_t aIn, bool& aOut);
-
-nsresult
-Convert(uint8_t aIn, char& aOut);
-
-nsresult
-Convert(uint8_t aIn, int& aOut);
-
-nsresult
-Convert(uint8_t aIn, unsigned long& aOut);
-
-nsresult
-Convert(uint32_t aIn, int& aOut);
-
-nsresult
-Convert(uint32_t aIn, uint8_t& aOut);
-
-nsresult
-Convert(size_t aIn, uint16_t& aOut);
-
-//
-// Packing
-//
-
-// introduce link errors on non-handled data types
-template <typename T>
-nsresult
-PackPDU(T aIn, DaemonSocketPDU& aPDU);
-
-nsresult
-PackPDU(bool aIn, DaemonSocketPDU& aPDU);
-
-inline nsresult
-PackPDU(uint8_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(uint16_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(int32_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(uint32_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(int64_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(uint64_t aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(float aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-inline nsresult
-PackPDU(double aIn, DaemonSocketPDU& aPDU)
-{
- return aPDU.Write(aIn);
-}
-
-nsresult
-PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU);
-
-/* |PackConversion| is a helper for packing converted values. Pass
- * an instance of this structure to |PackPDU| to convert a value from
- * the input type to the output type and and write it to the PDU.
- */
-template<typename Tin, typename Tout>
-struct PackConversion {
- PackConversion(const Tin& aIn)
- : mIn(aIn)
- { }
-
- const Tin& mIn;
-};
-
-template<typename Tin, typename Tout>
-inline nsresult
-PackPDU(const PackConversion<Tin, Tout>& aIn, DaemonSocketPDU& aPDU)
-{
- Tout out;
-
- nsresult rv = Convert(aIn.mIn, out);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(out, aPDU);
-}
-
-/* |PackArray| is a helper for packing arrays. Pass an instance
- * of this structure as the first argument to |PackPDU| to pack
- * an array. The array's maximum default length is 255 elements.
- */
-template <typename T>
-struct PackArray
-{
- PackArray(const T* aData, size_t aLength)
- : mData(aData)
- , mLength(aLength)
- { }
-
- const T* mData;
- size_t mLength;
-};
-
-/* This implementation of |PackPDU| packs the length of an array
- * and the elements of the array one-by-one.
- */
-template<typename T>
-inline nsresult
-PackPDU(const PackArray<T>& aIn, DaemonSocketPDU& aPDU)
-{
- for (size_t i = 0; i < aIn.mLength; ++i) {
- nsresult rv = PackPDU(aIn.mData[i], aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-template<>
-inline nsresult
-PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, DaemonSocketPDU& aPDU)
-{
- /* Write raw bytes in one pass */
- return aPDU.Write(aIn.mData, aIn.mLength);
-}
-
-template<>
-inline nsresult
-PackPDU<char>(const PackArray<char>& aIn, DaemonSocketPDU& aPDU)
-{
- /* Write raw bytes in one pass */
- return aPDU.Write(aIn.mData, aIn.mLength);
-}
-
-/* |PackCString0| is a helper for packing 0-terminated C string,
- * including the \0 character. Pass an instance of this structure
- * as the first argument to |PackPDU| to pack a string.
- */
-struct PackCString0
-{
- PackCString0(const nsCString& aString)
- : mString(aString)
- { }
-
- const nsCString& mString;
-};
-
-/* This implementation of |PackPDU| packs a 0-terminated C string.
- */
-inline nsresult
-PackPDU(const PackCString0& aIn, DaemonSocketPDU& aPDU)
-{
- return PackPDU(
- PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()),
- aIn.mString.Length() + 1), aPDU);
-}
-
-/* |PackReversed| is a helper for packing data in reversed order. Pass an
- * instance of this structure as the first argument to |PackPDU| to pack data
- * in reversed order.
- */
-template<typename T>
-struct PackReversed
-{
- PackReversed(const T& aValue)
- : mValue(aValue)
- { }
-
- const T& mValue;
-};
-
-/* No general rules to pack data in reversed order. Signal a link error if the
- * type |T| of |PackReversed| is not defined explicitly.
- */
-template<typename T>
-nsresult
-PackPDU(const PackReversed<T>& aIn, DaemonSocketPDU& aPDU);
-
-/* This implementation of |PackPDU| packs elements in |PackArray| in reversed
- * order. (ex. reversed GATT UUID, see bug 1171866)
- */
-template<typename U>
-inline nsresult
-PackPDU(const PackReversed<PackArray<U>>& aIn, DaemonSocketPDU& aPDU)
-{
- for (size_t i = 0; i < aIn.mValue.mLength; ++i) {
- nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-/* |PackArray<PackReversed<U>>| is a helper for packing data of each element in
- * the reversed order. Pass an instance of this structure as the first argument
- * to |PackPDU| to pack data of each array element in the reversed order.
- *
- * Unlike |PackReversed<PackArray<U>>| which packed array elements in the
- * reversed order, here we use |PackReversed<U>| to pack data of each element
- * of |PackArray| in the reversed order.
- */
-template<typename U>
-struct PackArray<PackReversed<U>>
-{
- PackArray(const U* aData, size_t aLength)
- : mData(aData)
- , mLength(aLength)
- { }
-
- const U* mData;
- size_t mLength;
-};
-
-/* This implementation of |PackPDU| packs data of each element in |PackArray|
- * in the reversed order. (ex. reversed GATT UUID, see bug 1171866)
- */
-template<typename U>
-inline nsresult
-PackPDU(const PackArray<PackReversed<U>>& aIn, DaemonSocketPDU& aPDU)
-{
- for (size_t i = 0; i < aIn.mLength; ++i) {
- nsresult rv = PackPDU(PackReversed<U>(aIn.mData[i]), aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-template <typename T1, typename T2>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn2, aPDU);
-}
-
-template <typename T1, typename T2, typename T3>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn3, aPDU);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4,
- DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn4, aPDU);
-}
-
-template <typename T1, typename T2, typename T3,
- typename T4, typename T5>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- const T4& aIn4, const T5& aIn5,
- DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn4, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn5, aPDU);
-}
-
-template <typename T1, typename T2, typename T3,
- typename T4, typename T5, typename T6>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- const T4& aIn4, const T5& aIn5, const T6& aIn6,
- DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn4, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn5, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn6, aPDU);
-}
-
-template <typename T1, typename T2, typename T3,
- typename T4, typename T5, typename T6,
- typename T7>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- const T4& aIn4, const T5& aIn5, const T6& aIn6,
- const T7& aIn7, DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn4, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn5, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn6, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn7, aPDU);
-}
-
-template <typename T1, typename T2, typename T3,
- typename T4, typename T5, typename T6,
- typename T7, typename T8>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- const T4& aIn4, const T5& aIn5, const T6& aIn6,
- const T7& aIn7, const T8& aIn8, DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn4, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn5, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn6, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn7, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn8, aPDU);
-}
-
-template <typename T1, typename T2, typename T3,
- typename T4, typename T5, typename T6,
- typename T7, typename T8, typename T9,
- typename T10, typename T11, typename T12,
- typename T13>
-inline nsresult
-PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
- const T4& aIn4, const T5& aIn5, const T6& aIn6,
- const T7& aIn7, const T8& aIn8, const T9& aIn9,
- const T10& aIn10, const T11& aIn11, const T12& aIn12,
- const T13& aIn13, DaemonSocketPDU& aPDU)
-{
- nsresult rv = PackPDU(aIn1, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn2, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn3, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn4, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn5, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn6, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn7, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn8, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn9, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn10, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn11, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = PackPDU(aIn12, aPDU);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return PackPDU(aIn13, aPDU);
-}
-
-//
-// Unpacking
-//
-
-// introduce link errors on non-handled data types
-template <typename T>
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, T& aOut);
-
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut);
-
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, char& aOut);
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, int8_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, uint8_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, uint16_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, int32_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, uint32_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, int64_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, uint64_t& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, float& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, double& aOut)
-{
- return aPDU.Read(aOut);
-}
-
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, DaemonSocketPDUHeader& aOut)
-{
- nsresult rv = UnpackPDU(aPDU, aOut.mService);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(aPDU, aOut.mOpcode);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return UnpackPDU(aPDU, aOut.mLength);
-}
-
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut);
-
-/* |UnpackCString0| is a helper for unpacking 0-terminated C string,
- * including the \0 character. Pass an instance of this structure
- * as the first argument to |UnpackPDU| to unpack a string.
- */
-struct UnpackCString0
-{
- UnpackCString0(nsCString& aString)
- : mString(&aString)
- { }
-
- nsCString* mString; // non-null by construction
-};
-
-/* This implementation of |UnpackPDU| unpacks a 0-terminated C string.
- */
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut);
-
-/* |UnpackString0| is a helper for unpacking 0-terminated C string,
- * including the \0 character. Pass an instance of this structure
- * as the first argument to |UnpackPDU| to unpack a C string and convert
- * it to wide-character encoding.
- */
-struct UnpackString0
-{
- UnpackString0(nsString& aString)
- : mString(&aString)
- { }
-
- nsString* mString; // non-null by construction
-};
-
-/* This implementation of |UnpackPDU| unpacks a 0-terminated C string
- * and converts it to wide-character encoding.
- */
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut);
-
-/* |UnpackConversion| is a helper for convering unpacked values. Pass
- * an instance of this structure to |UnpackPDU| to read a value from
- * the PDU in the input type and convert it to the output type.
- */
-template<typename Tin, typename Tout>
-struct UnpackConversion {
- UnpackConversion(Tout& aOut)
- : mOut(aOut)
- { }
-
- Tout& mOut;
-};
-
-template<typename Tin, typename Tout>
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut)
-{
- Tin in;
- nsresult rv = UnpackPDU(aPDU, in);
- if (NS_FAILED(rv)) {
- return rv;
- }
- return Convert(in, aOut.mOut);
-}
-
-/* |UnpackArray| is a helper for unpacking arrays. Pass an instance
- * of this structure as the second argument to |UnpackPDU| to unpack
- * an array.
- */
-template <typename T>
-struct UnpackArray
-{
- UnpackArray(T* aData, size_t aLength)
- : mData(aData)
- , mLength(aLength)
- { }
-
- UnpackArray(UniquePtr<T[]>& aData, size_t aLength)
- : mData(nullptr)
- , mLength(aLength)
- {
- aData.reset(new T[mLength]);
- mData = aData.get();
- }
-
- UnpackArray(UniquePtr<T>& aData, size_t aSize, size_t aElemSize)
- : mData(nullptr)
- , mLength(aSize / aElemSize)
- {
- aData.reset(new T[mLength]);
- mData = aData.get();
- }
-
- T* mData;
- size_t mLength;
-};
-
-template<typename T>
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackArray<T>& aOut)
-{
- for (size_t i = 0; i < aOut.mLength; ++i) {
- nsresult rv = UnpackPDU(aPDU, aOut.mData[i]);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-template<typename T>
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, UnpackArray<T>& aOut)
-{
- for (size_t i = 0; i < aOut.mLength; ++i) {
- nsresult rv = UnpackPDU(aPDU, aOut.mData[i]);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-template<>
-inline nsresult
-UnpackPDU<uint8_t>(DaemonSocketPDU& aPDU, const UnpackArray<uint8_t>& aOut)
-{
- /* Read raw bytes in one pass */
- return aPDU.Read(aOut.mData, aOut.mLength);
-}
-
-template<typename T>
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, nsTArray<T>& aOut)
-{
- for (typename nsTArray<T>::size_type i = 0; i < aOut.Length(); ++i) {
- nsresult rv = UnpackPDU(aPDU, aOut[i]);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an
- * instance of this structure as the second argument to |UnpackPDU| to unpack
- * data in reversed order.
- */
-template<typename T>
-struct UnpackReversed
-{
- UnpackReversed(T& aValue)
- : mValue(&aValue)
- { }
-
- UnpackReversed(T&& aValue)
- : mValue(&aValue)
- { }
-
- T* mValue;
-};
-
-/* No general rules to unpack data in reversed order. Signal a link error if
- * the type |T| of |UnpackReversed| is not defined explicitly.
- */
-template<typename T>
-nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<T>& aOut);
-
-template<typename U>
-inline nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut)
-{
- for (size_t i = 0; i < aOut.mValue->mLength; ++i) {
- nsresult rv = UnpackPDU(aPDU,
- aOut.mValue->mData[aOut.mValue->mLength - i - 1]);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- return NS_OK;
-}
-
-//
-// Init operators
-//
-
-//
-// Below are general-purpose init operators for Bluetooth. The classes
-// of type |ConstantInitOp[1..3]| initialize results or notifications
-// with constant values.
-//
-
-template <typename T1>
-class ConstantInitOp1 final
-{
-public:
- ConstantInitOp1(const T1& aArg1)
- : mArg1(aArg1)
- { }
-
- nsresult operator () (T1& aArg1) const
- {
- aArg1 = mArg1;
-
- return NS_OK;
- }
-
-private:
- const T1& mArg1;
-};
-
-template <typename T1, typename T2>
-class ConstantInitOp2 final
-{
-public:
- ConstantInitOp2(const T1& aArg1, const T2& aArg2)
- : mArg1(aArg1)
- , mArg2(aArg2)
- { }
-
- nsresult operator () (T1& aArg1, T2& aArg2) const
- {
- aArg1 = mArg1;
- aArg2 = mArg2;
-
- return NS_OK;
- }
-
-private:
- const T1& mArg1;
- const T2& mArg2;
-};
-
-template <typename T1, typename T2, typename T3>
-class ConstantInitOp3 final
-{
-public:
- ConstantInitOp3(const T1& aArg1, const T2& aArg2, const T3& aArg3)
- : mArg1(aArg1)
- , mArg2(aArg2)
- , mArg3(aArg3)
- { }
-
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
- {
- aArg1 = mArg1;
- aArg2 = mArg2;
- aArg3 = mArg3;
-
- return NS_OK;
- }
-
-private:
- const T1& mArg1;
- const T2& mArg2;
- const T3& mArg3;
-};
-
-// |PDUInitOP| provides functionality for init operators that unpack PDUs.
-class PDUInitOp
-{
-protected:
- PDUInitOp(DaemonSocketPDU& aPDU)
- : mPDU(&aPDU)
- { }
-
- DaemonSocketPDU& GetPDU() const
- {
- return *mPDU; // cannot be nullptr
- }
-
- void WarnAboutTrailingData() const;
-
-private:
- DaemonSocketPDU* mPDU; // Hold pointer to allow for constant instances
-};
-
-// |UnpackPDUInitOp| is a general-purpose init operator for all variants
-// of |DaemonResultRunnable| and |DaemonNotificationRunnable|. The call
-// operators of |UnpackPDUInitOp| unpack a PDU into the supplied
-// arguments.
-class UnpackPDUInitOp final : private PDUInitOp
-{
-public:
- UnpackPDUInitOp(DaemonSocketPDU& aPDU)
- : PDUInitOp(aPDU)
- { }
-
- nsresult operator () () const
- {
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1>
- nsresult operator () (T1& aArg1) const
- {
- nsresult rv = UnpackPDU(GetPDU(), aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2>
- nsresult operator () (T1& aArg1, T2& aArg2) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
- T5& aArg5) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg5);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
- T5& aArg5, T6& aArg6) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg5);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg6);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
- T5& aArg5, T6& aArg6, T7& aArg7) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg5);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg6);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg7);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
- T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg5);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg6);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg7);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg8);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
- nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
- T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8,
- T9& aArg9) const
- {
- DaemonSocketPDU& pdu = GetPDU();
-
- nsresult rv = UnpackPDU(pdu, aArg1);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg2);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg3);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg4);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg5);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg6);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg7);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg8);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = UnpackPDU(pdu, aArg9);
- if (NS_FAILED(rv)) {
- return rv;
- }
- WarnAboutTrailingData();
- return NS_OK;
- }
-};
-
-} // namespace DaemonSocketPDUHelpers
-
-} // namespace ipc
-} // namespace mozilla
-
-#endif // mozilla_ipc_DaemonSocketPDUHelpers_h