summaryrefslogtreecommitdiffstats
path: root/xpcom/tests/gtest/TestStorageStream.cpp
blob: a49d6f6bcababf82d660ab1dfa234ac7cd16c5f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* -*- 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/. */

#include <stdlib.h>
#include "gtest/gtest.h"
#include "Helpers.h"
#include "nsCOMPtr.h"
#include "nsICloneableInputStream.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIStorageStream.h"
#include "nsTArray.h"

namespace {

void
WriteData(nsIOutputStream* aOut, nsTArray<char>& aData, uint32_t aNumBytes,
          nsACString& aDataWritten)
{
  uint32_t n;
  nsresult rv = aOut->Write(aData.Elements(), aNumBytes, &n);
  EXPECT_TRUE(NS_SUCCEEDED(rv));
  aDataWritten.Append(aData.Elements(), aNumBytes);
}

} // namespace

TEST(StorageStreams, Main)
{
  // generate some test data we will write in 4k chunks to the stream
  nsTArray<char> kData;
  testing::CreateData(4096, kData);

  // track how much data was written so we can compare at the end
  nsAutoCString dataWritten;

  nsresult rv;
  nsCOMPtr<nsIStorageStream> stor;

  rv = NS_NewStorageStream(kData.Length(), UINT32_MAX, getter_AddRefs(stor));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  nsCOMPtr<nsIOutputStream> out;
  rv = stor->GetOutputStream(0, getter_AddRefs(out));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  WriteData(out, kData, kData.Length(), dataWritten);
  WriteData(out, kData, kData.Length(), dataWritten);

  rv = out->Close();
  EXPECT_TRUE(NS_SUCCEEDED(rv));
  out = nullptr;

  nsCOMPtr<nsIInputStream> in;
  rv = stor->NewInputStream(0, getter_AddRefs(in));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(in);
  ASSERT_TRUE(cloneable != nullptr);
  ASSERT_TRUE(cloneable->GetCloneable());

  nsCOMPtr<nsIInputStream> clone;
  rv = cloneable->Clone(getter_AddRefs(clone));

  testing::ConsumeAndValidateStream(in, dataWritten);
  testing::ConsumeAndValidateStream(clone, dataWritten);
  in = nullptr;
  clone = nullptr;

  // now, write 3 more full 4k segments + 11 bytes, starting at 8192
  // total written equals 20491 bytes

  rv = stor->GetOutputStream(dataWritten.Length(), getter_AddRefs(out));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  WriteData(out, kData, kData.Length(), dataWritten);
  WriteData(out, kData, kData.Length(), dataWritten);
  WriteData(out, kData, kData.Length(), dataWritten);
  WriteData(out, kData, 11, dataWritten);

  rv = out->Close();
  EXPECT_TRUE(NS_SUCCEEDED(rv));
  out = nullptr;

  // now, read all
  rv = stor->NewInputStream(0, getter_AddRefs(in));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  testing::ConsumeAndValidateStream(in, dataWritten);
  in = nullptr;
}

TEST(StorageStreams, EarlyInputStream)
{
  // generate some test data we will write in 4k chunks to the stream
  nsTArray<char> kData;
  testing::CreateData(4096, kData);

  // track how much data was written so we can compare at the end
  nsAutoCString dataWritten;

  nsresult rv;
  nsCOMPtr<nsIStorageStream> stor;

  rv = NS_NewStorageStream(kData.Length(), UINT32_MAX, getter_AddRefs(stor));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  // Get input stream before writing data into the output stream
  nsCOMPtr<nsIInputStream> in;
  rv = stor->NewInputStream(0, getter_AddRefs(in));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  // Write data to output stream
  nsCOMPtr<nsIOutputStream> out;
  rv = stor->GetOutputStream(0, getter_AddRefs(out));
  EXPECT_TRUE(NS_SUCCEEDED(rv));

  WriteData(out, kData, kData.Length(), dataWritten);
  WriteData(out, kData, kData.Length(), dataWritten);

  rv = out->Close();
  EXPECT_TRUE(NS_SUCCEEDED(rv));
  out = nullptr;

  // Should be able to consume input stream
  testing::ConsumeAndValidateStream(in, dataWritten);
  in = nullptr;
}