Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/io/nsUnicharInputStream.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsUnicharInputStream.h"
8
#include "nsIInputStream.h"
9
#include "nsIServiceManager.h"
10
#include "nsString.h"
11
#include "nsTArray.h"
12
#include "nsAutoPtr.h"
13
#include "nsCRT.h"
14
#include "nsStreamUtils.h"
15
#include "nsConverterInputStream.h"
16
#include "mozilla/Attributes.h"
17
#include <fcntl.h>
18
#if defined(XP_WIN)
19
#include <io.h>
20
#else
21
#include <unistd.h>
22
#endif
23
24
0
#define STRING_BUFFER_SIZE 8192
25
26
class StringUnicharInputStream final : public nsIUnicharInputStream
27
{
28
public:
29
  explicit StringUnicharInputStream(const nsAString& aString) :
30
0
    mString(aString), mPos(0), mLen(aString.Length()) { }
31
32
  NS_DECL_ISUPPORTS
33
  NS_DECL_NSIUNICHARINPUTSTREAM
34
35
  nsString mString;
36
  uint32_t mPos;
37
  uint32_t mLen;
38
39
private:
40
0
  ~StringUnicharInputStream() { }
41
};
42
43
NS_IMETHODIMP
44
StringUnicharInputStream::Read(char16_t* aBuf,
45
                               uint32_t aCount,
46
                               uint32_t* aReadCount)
47
0
{
48
0
  if (mPos >= mLen) {
49
0
    *aReadCount = 0;
50
0
    return NS_OK;
51
0
  }
52
0
  nsAString::const_iterator iter;
53
0
  mString.BeginReading(iter);
54
0
  const char16_t* us = iter.get();
55
0
  uint32_t amount = mLen - mPos;
56
0
  if (amount > aCount) {
57
0
    amount = aCount;
58
0
  }
59
0
  memcpy(aBuf, us + mPos, sizeof(char16_t) * amount);
60
0
  mPos += amount;
61
0
  *aReadCount = amount;
62
0
  return NS_OK;
63
0
}
64
65
NS_IMETHODIMP
66
StringUnicharInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter,
67
                                       void* aClosure,
68
                                       uint32_t aCount, uint32_t* aReadCount)
69
0
{
70
0
  uint32_t bytesWritten;
71
0
  uint32_t totalBytesWritten = 0;
72
0
73
0
  nsresult rv;
74
0
  aCount = XPCOM_MIN(mString.Length() - mPos, aCount);
75
0
76
0
  nsAString::const_iterator iter;
77
0
  mString.BeginReading(iter);
78
0
79
0
  while (aCount) {
80
0
    rv = aWriter(this, aClosure, iter.get() + mPos,
81
0
                 totalBytesWritten, aCount, &bytesWritten);
82
0
83
0
    if (NS_FAILED(rv)) {
84
0
      // don't propagate errors to the caller
85
0
      break;
86
0
    }
87
0
88
0
    aCount -= bytesWritten;
89
0
    totalBytesWritten += bytesWritten;
90
0
    mPos += bytesWritten;
91
0
  }
92
0
93
0
  *aReadCount = totalBytesWritten;
94
0
95
0
  return NS_OK;
96
0
}
97
98
NS_IMETHODIMP
99
StringUnicharInputStream::ReadString(uint32_t aCount, nsAString& aString,
100
                                     uint32_t* aReadCount)
101
0
{
102
0
  if (mPos >= mLen) {
103
0
    *aReadCount = 0;
104
0
    return NS_OK;
105
0
  }
106
0
  uint32_t amount = mLen - mPos;
107
0
  if (amount > aCount) {
108
0
    amount = aCount;
109
0
  }
110
0
  aString = Substring(mString, mPos, amount);
111
0
  mPos += amount;
112
0
  *aReadCount = amount;
113
0
  return NS_OK;
114
0
}
115
116
nsresult
117
StringUnicharInputStream::Close()
118
0
{
119
0
  mPos = mLen;
120
0
  return NS_OK;
121
0
}
122
123
NS_IMPL_ISUPPORTS(StringUnicharInputStream, nsIUnicharInputStream)
124
125
//----------------------------------------------------------------------
126
127
nsresult
128
NS_NewUnicharInputStream(nsIInputStream* aStreamToWrap,
129
                         nsIUnicharInputStream** aResult)
130
0
{
131
0
  *aResult = nullptr;
132
0
133
0
  // Create converter input stream
134
0
  RefPtr<nsConverterInputStream> it = new nsConverterInputStream();
135
0
  nsresult rv =
136
0
    it->Init(aStreamToWrap,
137
0
             "UTF-8",
138
0
             STRING_BUFFER_SIZE,
139
0
             nsIConverterInputStream::ERRORS_ARE_FATAL);
140
0
  if (NS_FAILED(rv)) {
141
0
    return rv;
142
0
  }
143
0
144
0
  it.forget(aResult);
145
0
  return NS_OK;
146
0
}