Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/mfbt/tests/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 12 kB image not shown  

Quelle  TestBufferList.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 9; 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 is included first to ensure it doesn't implicitly depend on anything
// else.
#include "mozilla/BufferList.h"

// It would be nice if we could use the InfallibleAllocPolicy from mozalloc,
// but MFBT cannot use mozalloc.
class InfallibleAllocPolicy {
 public:
  template <typename T>
  T* pod_malloc(size_t aNumElems) {
    if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
      MOZ_CRASH("TestBufferList.cpp: overflow");
    }
    T* rv = static_cast<T*>(malloc(aNumElems * sizeof(T)));
    if (!rv) {
      MOZ_CRASH("TestBufferList.cpp: out of memory");
    }
    return rv;
  }

  template <typename T>
  void free_(T* aPtr, size_t aNumElems = 0) {
    free(aPtr);
  }

  void reportAllocOverflow() const {}

  bool checkSimulatedOOM() const { return true; }
};

typedef mozilla::BufferList<InfallibleAllocPolicy> BufferList;

int main(void) {
  const size_t kInitialSize = 16;
  const size_t kInitialCapacity = 24;
  const size_t kStandardCapacity = 32;

  BufferList bl(kInitialSize, kInitialCapacity, kStandardCapacity);

  memset(bl.Start(), 0x0c, kInitialSize);
  MOZ_RELEASE_ASSERT(bl.Size() == kInitialSize);

  // Simple iteration and access.

  BufferList::IterImpl iter(bl.Iter());
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == kInitialSize);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(kInitialSize));
  MOZ_RELEASE_ASSERT(!iter.HasRoomFor(kInitialSize + 1));
  MOZ_RELEASE_ASSERT(!iter.HasRoomFor(size_t(-1)));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0c);
  MOZ_RELEASE_ASSERT(!iter.Done());

  iter.Advance(bl, 4);
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == kInitialSize - 4);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(kInitialSize - 4));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0c);
  MOZ_RELEASE_ASSERT(!iter.Done());

  iter.Advance(bl, 11);
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == kInitialSize - 4 - 11);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(kInitialSize - 4 - 11));
  MOZ_RELEASE_ASSERT(!iter.HasRoomFor(kInitialSize - 4 - 11 + 1));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0c);
  MOZ_RELEASE_ASSERT(!iter.Done());

  iter.Advance(bl, kInitialSize - 4 - 11);
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == 0);
  MOZ_RELEASE_ASSERT(!iter.HasRoomFor(1));
  MOZ_RELEASE_ASSERT(iter.Done());

  // Writing to the buffer.

  const size_t kSmallWrite = 16;

  char toWrite[kSmallWrite];
  memset(toWrite, 0x0a, kSmallWrite);
  MOZ_ALWAYS_TRUE(bl.WriteBytes(toWrite, kSmallWrite));

  MOZ_RELEASE_ASSERT(bl.Size() == kInitialSize + kSmallWrite);

  iter = bl.Iter();
  iter.Advance(bl, kInitialSize);
  MOZ_RELEASE_ASSERT(!iter.Done());
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() ==
                     kInitialCapacity - kInitialSize);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(kInitialCapacity - kInitialSize));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0a);

  // AdvanceAcrossSegments.

  iter = bl.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl, kInitialCapacity - 4));
  MOZ_RELEASE_ASSERT(!iter.Done());
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == 4);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(4));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0a);

  iter = bl.Iter();
  MOZ_RELEASE_ASSERT(
      iter.AdvanceAcrossSegments(bl, kInitialSize + kSmallWrite - 4));
  MOZ_RELEASE_ASSERT(!iter.Done());
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == 4);
  MOZ_RELEASE_ASSERT(iter.HasRoomFor(4));
  MOZ_RELEASE_ASSERT(*iter.Data() == 0x0a);

  MOZ_RELEASE_ASSERT(
      bl.Iter().AdvanceAcrossSegments(bl, kInitialSize + kSmallWrite - 1));
  MOZ_RELEASE_ASSERT(
      bl.Iter().AdvanceAcrossSegments(bl, kInitialSize + kSmallWrite));
  MOZ_RELEASE_ASSERT(
      !bl.Iter().AdvanceAcrossSegments(bl, kInitialSize + kSmallWrite + 1));
  MOZ_RELEASE_ASSERT(!bl.Iter().AdvanceAcrossSegments(bl, size_t(-1)));

  // Reading non-contiguous bytes.

  char toRead[kSmallWrite];
  iter = bl.Iter();
  iter.Advance(bl, kInitialSize);
  bl.ReadBytes(iter, toRead, kSmallWrite);
  MOZ_RELEASE_ASSERT(memcmp(toRead, toWrite, kSmallWrite) == 0);
  MOZ_RELEASE_ASSERT(iter.Done());

  // Make sure reading up to the end of a segment advances the iter to the next
  // segment.
  iter = bl.Iter();
  bl.ReadBytes(iter, toRead, kInitialSize);
  MOZ_RELEASE_ASSERT(!iter.Done());
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() ==
                     kInitialCapacity - kInitialSize);

  const size_t kBigWrite = 1024;

  char* toWriteBig = static_cast<char*>(malloc(kBigWrite));
  for (unsigned i = 0; i < kBigWrite; i++) {
    toWriteBig[i] = i % 37;
  }
  MOZ_ALWAYS_TRUE(bl.WriteBytes(toWriteBig, kBigWrite));

  char* toReadBig = static_cast<char*>(malloc(kBigWrite));
  iter = bl.Iter();
  MOZ_RELEASE_ASSERT(
      iter.AdvanceAcrossSegments(bl, kInitialSize + kSmallWrite));
  bl.ReadBytes(iter, toReadBig, kBigWrite);
  MOZ_RELEASE_ASSERT(memcmp(toReadBig, toWriteBig, kBigWrite) == 0);
  MOZ_RELEASE_ASSERT(iter.Done());

  free(toReadBig);
  free(toWriteBig);

  // Currently bl contains these segments:
  // #0: offset 0, [0x0c]*16 + [0x0a]*8, size 24
  // #1: offset 24, [0x0a]*8 + [i%37 for i in 0..24], size 32
  // #2: offset 56, [i%37 for i in 24..56, size 32
  // ...
  // #32: offset 1016, [i%37 for i in 984..1016], size 32
  // #33: offset 1048, [i%37 for i in 1016..1024], size 8

  static size_t kTotalSize = kInitialSize + kSmallWrite + kBigWrite;

  MOZ_RELEASE_ASSERT(bl.Size() == kTotalSize);

  static size_t kLastSegmentSize =
      (kTotalSize - kInitialCapacity) % kStandardCapacity;

  iter = bl.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(
      bl, kTotalSize - kLastSegmentSize - kStandardCapacity));
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == kStandardCapacity);
  iter.Advance(bl, kStandardCapacity);
  MOZ_RELEASE_ASSERT(iter.RemainingInSegment() == kLastSegmentSize);
  MOZ_RELEASE_ASSERT(
      unsigned(*iter.Data()) ==
      (kTotalSize - kLastSegmentSize - kInitialSize - kSmallWrite) % 37);

  // Clear.

  bl.Clear();
  MOZ_RELEASE_ASSERT(bl.Size() == 0);
  MOZ_RELEASE_ASSERT(bl.Iter().Done());

  // Move assignment.

  const size_t kSmallCapacity = 8;

  BufferList bl2(0, kSmallCapacity, kSmallCapacity);
  MOZ_ALWAYS_TRUE(bl2.WriteBytes(toWrite, kSmallWrite));
  MOZ_ALWAYS_TRUE(bl2.WriteBytes(toWrite, kSmallWrite));
  MOZ_ALWAYS_TRUE(bl2.WriteBytes(toWrite, kSmallWrite));

  bl = std::move(bl2);
  MOZ_RELEASE_ASSERT(bl2.Size() == 0);
  MOZ_RELEASE_ASSERT(bl2.Iter().Done());

  iter = bl.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl, kSmallWrite * 3));
  MOZ_RELEASE_ASSERT(iter.Done());

  // MoveFallible

  bool success;
  bl2 = bl.MoveFallible<InfallibleAllocPolicy>(&success);
  MOZ_RELEASE_ASSERT(success);
  MOZ_RELEASE_ASSERT(bl.Size() == 0);
  MOZ_RELEASE_ASSERT(bl.Iter().Done());
  MOZ_RELEASE_ASSERT(bl2.Size() == kSmallWrite * 3);

  iter = bl2.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl2, kSmallWrite * 3));
  MOZ_RELEASE_ASSERT(iter.Done());

  bl = bl2.MoveFallible<InfallibleAllocPolicy>(&success);

  // Borrowing.

  const size_t kBorrowStart = 4;
  const size_t kBorrowSize = 24;

  iter = bl.Iter();
  iter.Advance(bl, kBorrowStart);
  bl2 = bl.Borrow<InfallibleAllocPolicy>(iter, kBorrowSize, &success);
  MOZ_RELEASE_ASSERT(success);
  MOZ_RELEASE_ASSERT(bl2.Size() == kBorrowSize);

  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(
      bl, kSmallWrite * 3 - kBorrowSize - kBorrowStart));
  MOZ_RELEASE_ASSERT(iter.Done());

  iter = bl2.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl2, kBorrowSize));
  MOZ_RELEASE_ASSERT(iter.Done());

  BufferList::IterImpl iter1(bl.Iter()), iter2(bl2.Iter());
  iter1.Advance(bl, kBorrowStart);
  MOZ_RELEASE_ASSERT(iter1.Data() == iter2.Data());
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl, kBorrowSize - 5));
  MOZ_RELEASE_ASSERT(iter2.AdvanceAcrossSegments(bl2, kBorrowSize - 5));
  MOZ_RELEASE_ASSERT(iter1.Data() == iter2.Data());

  // RangeLength.

  BufferList bl12(0, 0, 8);
  MOZ_ALWAYS_TRUE(bl12.WriteBytes("abcdefgh", 8));
  MOZ_ALWAYS_TRUE(bl12.WriteBytes("12345678", 8));

  // |iter| is at position 0 (1st segment).
  iter = bl12.Iter();
  iter1 = bl12.Iter();
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 0);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 4);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 8);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 12);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 3));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 15);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(iter1.Done());

  // |iter| is at position 1 (1st segment).
  iter = bl12.Iter();
  iter1 = bl12.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 0);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 4);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 8);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 12);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 2));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 14);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(iter1.Done());

  // |iter| is at position 8 (2nd segment).
  iter = bl12.Iter();
  iter1 = bl12.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl12, 8));
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 8));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 0);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 4);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 3));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 7);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(iter1.Done());

  // |iter| is at position 9 (2nd segment).
  iter = bl12.Iter();
  iter1 = bl12.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl12, 9));
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 9));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 0);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 4));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 4);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 2));
  MOZ_RELEASE_ASSERT(bl12.RangeLength(iter, iter1) == 6);
  MOZ_RELEASE_ASSERT(iter1.AdvanceAcrossSegments(bl12, 1));
  MOZ_RELEASE_ASSERT(iter1.Done());

  BufferList bl13(0, 0, 8);
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("abcdefgh", 8));
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("12345678", 8));
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("ABCDEFGH", 8));
  MOZ_RELEASE_ASSERT(bl13.Size() == 24);

  // At segment border
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl13, 8));
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 16);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 8);

  // Restore state
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("12345678", 8));
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("ABCDEFGH", 8));
  MOZ_RELEASE_ASSERT(bl13.Size() == 24);

  // Before segment border
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl13, 7));
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 17);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 7);

  // Restore state
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("h", 1));
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("12345678", 8));
  MOZ_ALWAYS_TRUE(bl13.WriteBytes("ABCDEFGH", 8));
  MOZ_RELEASE_ASSERT(bl13.Size() == 24);

  // In last segment
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl13, 20));
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 4);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 20);

  // No-op truncate
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 0);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 20);

  // No-op truncate with fresh iterator
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl13, 20));
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 0);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 20);

  // Truncate at start of buffer
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 20);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 0);

  // No-op truncate at start of buffer
  iter = bl13.Iter();
  MOZ_RELEASE_ASSERT(bl13.Truncate(iter) == 0);
  MOZ_RELEASE_ASSERT(iter.Done());
  MOZ_RELEASE_ASSERT(bl13.Size() == 0);

  return 0;
}

96%


¤ Dauer der Verarbeitung: 0.18 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 ist noch experimentell.