DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (409f3966645a)

VCS Links

Line Code
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "DOMtoATK.h"
#include "nsUTF8Utils.h"

namespace mozilla {
namespace a11y {

namespace DOMtoATK {

void
AddBOMs(nsACString& aDest, const nsACString& aSource)
{
  uint32_t destlength = 0;

  // First compute how much room we will need.
  for (uint32_t srci = 0; srci < aSource.Length(); ) {
    int bytes = UTF8traits::bytes(aSource[srci]);
    if (bytes >= 4) {
      // Non-BMP character, will add a BOM after it.
      destlength += 3;
    }
    // Skip whole character encoding.
    srci += bytes;
    destlength += bytes;
  }

  uint32_t desti = 0; // Index within aDest.

  // Add BOMs after non-BMP characters.
  aDest.SetLength(destlength);
  for (uint32_t srci = 0; srci < aSource.Length(); ) {
    uint32_t bytes = UTF8traits::bytes(aSource[srci]);

    MOZ_ASSERT(bytes <= aSource.Length() - srci, "We should have the whole sequence");

    // Copy whole sequence.
    aDest.Replace(desti, bytes, Substring(aSource, srci, bytes));
    desti += bytes;
    srci += bytes;

    if (bytes >= 4) {
      // More than 4 bytes in UTF-8 encoding exactly means more than 16 encoded
      // bits.  This is thus a non-BMP character which needed a surrogate
      // pair to get encoded in UTF-16, add a BOM after it.

      // And add a BOM after it.
      aDest.Replace(desti, 3, "\xEF\xBB\xBF");
      desti += 3;
    }
  }
  MOZ_ASSERT(desti == destlength, "Incoherency between computed length"
                                  "and actually translated length");
}

void
ATKStringConverterHelper::AdjustOffsets(gint* aStartOffset, gint* aEndOffset,
                                        gint count)
{
  MOZ_ASSERT(!mAdjusted, "DOMtoATK::ATKStringConverterHelper::AdjustOffsets needs to be called only once");

  if (*aStartOffset > 0) {
    (*aStartOffset)--;
    mStartShifted = true;
  }

  if (*aEndOffset != -1 && *aEndOffset < count) {
    (*aEndOffset)++;
    mEndShifted = true;
  }

#ifdef DEBUG
  mAdjusted = true;
#endif
}

gchar*
ATKStringConverterHelper::FinishUTF16toUTF8(nsCString& aStr)
{
  int skip = 0;

  if (mStartShifted) {
    // AdjustOffsets added a leading character.

    MOZ_ASSERT(aStr.Length() > 0, "There should be a leading character");
    MOZ_ASSERT(static_cast<int>(aStr.Length()) >= UTF8traits::bytes(aStr.CharAt(0)),
               "The leading character should be complete");

    // drop first character
    skip = UTF8traits::bytes(aStr.CharAt(0));
  }

  if (mEndShifted) {
    // AdjustOffsets added a trailing character.

    MOZ_ASSERT(aStr.Length() > 0, "There should be a trailing character");

    int trail = -1;
    // Find beginning of last character.
    for (trail = aStr.Length() - 1; trail >= 0; trail--) {
      if (!UTF8traits::isInSeq(aStr.CharAt(trail))) {
        break;
      }
    }
    MOZ_ASSERT(trail >= 0,
               "There should be at least a whole trailing character");
    MOZ_ASSERT(trail + UTF8traits::bytes(aStr.CharAt(trail)) == static_cast<int>(aStr.Length()),
               "The trailing character should be complete");

    // Drop the last character.
    aStr.Truncate(trail);
  }

  // copy and return, libspi will free it
  return g_strdup(aStr.get() + skip);
}

gchar*
ATKStringConverterHelper::ConvertAdjusted(const nsAString& aStr)
{
  MOZ_ASSERT(mAdjusted, "DOMtoATK::ATKStringConverterHelper::AdjustOffsets needs to be called before ATKStringConverterHelper::ConvertAdjusted");

  NS_ConvertUTF16toUTF8 cautoStr(aStr);
  if (!cautoStr.get()) {
    return nullptr;
  }

  nsAutoCString cautoStrBOMs;
  AddBOMs(cautoStrBOMs, cautoStr);
  return FinishUTF16toUTF8(cautoStrBOMs);
}

gchar*
Convert(const nsAString& aStr)
{
  NS_ConvertUTF16toUTF8 cautoStr(aStr);
  if (!cautoStr.get()) {
    return nullptr;
  }

  nsAutoCString cautoStrBOMs;
  AddBOMs(cautoStrBOMs, cautoStr);
  return g_strdup(cautoStrBOMs.get());
}

void
ConvertTexttoAsterisks(nsAString& aString)
{
  for (uint32_t i = 0; i < aString.Length(); i++) {
    aString.ReplaceLiteral(i, 1, u"*");
  }
}

}

} // namespace a11y
} // namespace mozilla