Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  BufferReader.h   Sprache: C

 
/* 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 BUFFER_READER_H_
#define BUFFER_READER_H_

#include <string.h>
#include "mozilla/EndianUtils.h"
#include "nscore.h"
#include "nsTArray.h"
#include "MediaData.h"
#include "MediaSpan.h"
#include "mozilla/Logging.h"
#include "mozilla/Result.h"

namespace mozilla {

extern mozilla::LazyLogModule gMP4MetadataLog;

class MOZ_RAII BufferReader {
 public:
  BufferReader() : mPtr(nullptr), mRemaining(0), mLength(0) {}
  BufferReader(const uint8_t* aData, size_t aSize)
      : mPtr(aData), mRemaining(aSize), mLength(aSize) {}
  template <size_t S>
  explicit BufferReader(const AutoTArray<uint8_t, S>& aData)
      : mPtr(aData.Elements()),
        mRemaining(aData.Length()),
        mLength(aData.Length()) {}
  explicit BufferReader(const nsTArray<uint8_t>& aData)
      : mPtr(aData.Elements()),
        mRemaining(aData.Length()),
        mLength(aData.Length()) {}
  explicit BufferReader(const mozilla::MediaByteBuffer* aData)
      : mPtr(aData->Elements()),
        mRemaining(aData->Length()),
        mLength(aData->Length()) {}
  explicit BufferReader(const mozilla::MediaSpan& aData)
      : mPtr(aData.Elements()),
        mRemaining(aData.Length()),
        mLength(aData.Length()) {}
  explicit BufferReader(const Span<const uint8_t>& aData)
      : mPtr(aData.Elements()),
        mRemaining(aData.Length()),
        mLength(aData.Length()) {}

  void SetData(const nsTArray<uint8_t>& aData) {
    MOZ_ASSERT(!mPtr && !mRemaining);
    mPtr = aData.Elements();
    mRemaining = aData.Length();
    mLength = mRemaining;
  }

  ~BufferReader() = default;

  size_t Offset() const { return mLength - mRemaining; }

  size_t Remaining() const { return mRemaining; }

  mozilla::Result<uint8_t, nsresult> ReadU8() {
    auto ptr = Read(1);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return *ptr;
  }

  mozilla::Result<uint16_t, nsresult> ReadU16() {
    auto ptr = Read(2);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readUint16(ptr);
  }

  mozilla::Result<int16_t, nsresult> ReadLE16() {
    auto ptr = Read(2);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::LittleEndian::readInt16(ptr);
  }

  mozilla::Result<uint32_t, nsresult> ReadU24() {
    auto ptr = Read(3);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
  }

  mozilla::Result<int32_t, nsresult> Read24() {
    return ReadU24().map([](uint32_t x) { return (int32_t)x; });
  }

  mozilla::Result<int32_t, nsresult> ReadLE24() {
    auto ptr = Read(3);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]);
    if (result & 0x00800000u) {
      result -= 0x1000000;
    }
    return result;
  }

  mozilla::Result<uint32_t, nsresult> ReadU32() {
    auto ptr = Read(4);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readUint32(ptr);
  }

  mozilla::Result<int32_t, nsresult> Read32() {
    auto ptr = Read(4);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readInt32(ptr);
  }

  mozilla::Result<uint32_t, nsresult> ReadLEU32() {
    auto ptr = Read(4);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::LittleEndian::readUint32(ptr);
  }

  mozilla::Result<uint64_t, nsresult> ReadU64() {
    auto ptr = Read(8);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readUint64(ptr);
  }

  mozilla::Result<int64_t, nsresult> Read64() {
    auto ptr = Read(8);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readInt64(ptr);
  }

  const uint8_t* Read(size_t aCount) {
    if (aCount > mRemaining) {
      mPtr += mRemaining;
      mRemaining = 0;
      return nullptr;
    }
    mRemaining -= aCount;

    const uint8_t* result = mPtr;
    mPtr += aCount;

    return result;
  }

  const uint8_t* Rewind(size_t aCount) {
    MOZ_ASSERT(aCount <= Offset());
    size_t rewind = Offset();
    if (aCount < rewind) {
      rewind = aCount;
    }
    mRemaining += rewind;
    mPtr -= rewind;
    return mPtr;
  }

  mozilla::Result<uint8_t, nsresult> PeekU8() const {
    auto ptr = Peek(1);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return *ptr;
  }

  mozilla::Result<uint16_t, nsresult> PeekU16() const {
    auto ptr = Peek(2);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readUint16(ptr);
  }

  mozilla::Result<uint32_t, nsresult> PeekU24() const {
    auto ptr = Peek(3);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
  }

  mozilla::Result<int32_t, nsresult> Peek24() const {
    return PeekU24().map([](uint32_t x) { return (int32_t)x; });
  }

  mozilla::Result<uint32_t, nsresult> PeekU32() {
    auto ptr = Peek(4);
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return mozilla::BigEndian::readUint32(ptr);
  }

  const uint8_t* Peek(size_t aCount) const {
    if (aCount > mRemaining) {
      return nullptr;
    }
    return mPtr;
  }

  const uint8_t* Seek(size_t aOffset) {
    if (aOffset >= mLength) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure, offset: %zu", __func__, aOffset));
      return nullptr;
    }

    mPtr = mPtr - Offset() + aOffset;
    mRemaining = mLength - aOffset;
    return mPtr;
  }

  const uint8_t* Reset() {
    mPtr -= Offset();
    mRemaining = mLength;
    return mPtr;
  }

  uint32_t Align() const { return 4 - ((intptr_t)mPtr & 3); }

  template <typename T>
  bool CanReadType() const {
    return mRemaining >= sizeof(T);
  }

  template <typename T>
  T ReadType() {
    auto ptr = Read(sizeof(T));
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return 0;
    }
    // handle unaligned accesses by memcpying
    T ret;
    memcpy(&ret, ptr, sizeof(T));
    return ret;
  }

  template <typename T>
  [[nodiscard]] bool ReadArray(nsTArray<T>& aDest, size_t aLength) {
    auto ptr = Read(aLength * sizeof(T));
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return false;
    }

    aDest.Clear();
    aDest.AppendElements(reinterpret_cast<const T*>(ptr), aLength);
    return true;
  }

  template <typename T>
  [[nodiscard]] bool ReadArray(FallibleTArray<T>& aDest, size_t aLength) {
    auto ptr = Read(aLength * sizeof(T));
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return false;
    }

    aDest.Clear();
    if (!aDest.SetCapacity(aLength, mozilla::fallible)) {
      return false;
    }
    MOZ_ALWAYS_TRUE(aDest.AppendElements(reinterpret_cast<const T*>(ptr),
                                         aLength, mozilla::fallible));
    return true;
  }

  template <typename T>
  mozilla::Result<Span<const T>, nsresult> ReadSpan(size_t aLength) {
    auto ptr = Read(aLength * sizeof(T));
    if (!ptr) {
      MOZ_LOG(gMP4MetadataLog, mozilla::LogLevel::Error,
              ("%s: failure", __func__));
      return mozilla::Err(NS_ERROR_FAILURE);
    }
    return Span(reinterpret_cast<const T*>(ptr), aLength);
  }

 private:
  const uint8_t* mPtr;
  size_t mRemaining;
  size_t mLength;
};

}  // namespace mozilla

#endif

Messung V0.5
C=95 H=91 G=92

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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 und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge