Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/accessible/atk/DOMtoATK.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=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 "DOMtoATK.h"
8
#include "nsUTF8Utils.h"
9
10
namespace mozilla {
11
namespace a11y {
12
13
namespace DOMtoATK {
14
15
void
16
AddBOMs(nsACString& aDest, const nsACString& aSource)
17
0
{
18
0
  uint32_t destlength = 0;
19
0
20
0
  // First compute how much room we will need.
21
0
  for (uint32_t srci = 0; srci < aSource.Length(); ) {
22
0
    int bytes = UTF8traits::bytes(aSource[srci]);
23
0
    if (bytes >= 4) {
24
0
      // Non-BMP character, will add a BOM after it.
25
0
      destlength += 3;
26
0
    }
27
0
    // Skip whole character encoding.
28
0
    srci += bytes;
29
0
    destlength += bytes;
30
0
  }
31
0
32
0
  uint32_t desti = 0; // Index within aDest.
33
0
34
0
  // Add BOMs after non-BMP characters.
35
0
  aDest.SetLength(destlength);
36
0
  for (uint32_t srci = 0; srci < aSource.Length(); ) {
37
0
    uint32_t bytes = UTF8traits::bytes(aSource[srci]);
38
0
39
0
    MOZ_ASSERT(bytes <= aSource.Length() - srci, "We should have the whole sequence");
40
0
41
0
    // Copy whole sequence.
42
0
    aDest.Replace(desti, bytes, Substring(aSource, srci, bytes));
43
0
    desti += bytes;
44
0
    srci += bytes;
45
0
46
0
    if (bytes >= 4) {
47
0
      // More than 4 bytes in UTF-8 encoding exactly means more than 16 encoded
48
0
      // bits.  This is thus a non-BMP character which needed a surrogate
49
0
      // pair to get encoded in UTF-16, add a BOM after it.
50
0
51
0
      // And add a BOM after it.
52
0
      aDest.Replace(desti, 3, "\xEF\xBB\xBF");
53
0
      desti += 3;
54
0
    }
55
0
  }
56
0
  MOZ_ASSERT(desti == destlength, "Incoherency between computed length"
57
0
                                  "and actually translated length");
58
0
}
59
60
void
61
ATKStringConverterHelper::AdjustOffsets(gint* aStartOffset, gint* aEndOffset,
62
                                        gint count)
63
0
{
64
0
  MOZ_ASSERT(!mAdjusted, "DOMtoATK::ATKStringConverterHelper::AdjustOffsets needs to be called only once");
65
0
66
0
  if (*aStartOffset > 0) {
67
0
    (*aStartOffset)--;
68
0
    mStartShifted = true;
69
0
  }
70
0
71
0
  if (*aEndOffset != -1 && *aEndOffset < count) {
72
0
    (*aEndOffset)++;
73
0
    mEndShifted = true;
74
0
  }
75
0
76
#ifdef DEBUG
77
  mAdjusted = true;
78
#endif
79
}
80
81
gchar*
82
ATKStringConverterHelper::FinishUTF16toUTF8(nsCString& aStr)
83
0
{
84
0
  int skip = 0;
85
0
86
0
  if (mStartShifted) {
87
0
    // AdjustOffsets added a leading character.
88
0
89
0
    MOZ_ASSERT(aStr.Length() > 0, "There should be a leading character");
90
0
    MOZ_ASSERT(static_cast<int>(aStr.Length()) >= UTF8traits::bytes(aStr.CharAt(0)),
91
0
               "The leading character should be complete");
92
0
93
0
    // drop first character
94
0
    skip = UTF8traits::bytes(aStr.CharAt(0));
95
0
  }
96
0
97
0
  if (mEndShifted) {
98
0
    // AdjustOffsets added a trailing character.
99
0
100
0
    MOZ_ASSERT(aStr.Length() > 0, "There should be a trailing character");
101
0
102
0
    int trail = -1;
103
0
    // Find beginning of last character.
104
0
    for (trail = aStr.Length() - 1; trail >= 0; trail--) {
105
0
      if (!UTF8traits::isInSeq(aStr.CharAt(trail))) {
106
0
        break;
107
0
      }
108
0
    }
109
0
    MOZ_ASSERT(trail >= 0,
110
0
               "There should be at least a whole trailing character");
111
0
    MOZ_ASSERT(trail + UTF8traits::bytes(aStr.CharAt(trail)) == static_cast<int>(aStr.Length()),
112
0
               "The trailing character should be complete");
113
0
114
0
    // Drop the last character.
115
0
    aStr.Truncate(trail);
116
0
  }
117
0
118
0
  // copy and return, libspi will free it
119
0
  return g_strdup(aStr.get() + skip);
120
0
}
121
122
gchar*
123
ATKStringConverterHelper::ConvertAdjusted(const nsAString& aStr)
124
0
{
125
0
  MOZ_ASSERT(mAdjusted, "DOMtoATK::ATKStringConverterHelper::AdjustOffsets needs to be called before ATKStringConverterHelper::ConvertAdjusted");
126
0
127
0
  NS_ConvertUTF16toUTF8 cautoStr(aStr);
128
0
  if (!cautoStr.get()) {
129
0
    return nullptr;
130
0
  }
131
0
132
0
  nsAutoCString cautoStrBOMs;
133
0
  AddBOMs(cautoStrBOMs, cautoStr);
134
0
  return FinishUTF16toUTF8(cautoStrBOMs);
135
0
}
136
137
gchar*
138
Convert(const nsAString& aStr)
139
0
{
140
0
  NS_ConvertUTF16toUTF8 cautoStr(aStr);
141
0
  if (!cautoStr.get()) {
142
0
    return nullptr;
143
0
  }
144
0
145
0
  nsAutoCString cautoStrBOMs;
146
0
  AddBOMs(cautoStrBOMs, cautoStr);
147
0
  return g_strdup(cautoStrBOMs.get());
148
0
}
149
150
void
151
ConvertTexttoAsterisks(nsAString& aString)
152
0
{
153
0
  for (uint32_t i = 0; i < aString.Length(); i++) {
154
0
    aString.ReplaceLiteral(i, 1, u"*");
155
0
  }
156
0
}
157
158
}
159
160
} // namespace a11y
161
} // namespace mozilla