Add CFX_ByteStringC::CharAt() to avoid c_str() and casts.

Most of the time, we want to operate on chars as if they
were unsigned, but there are a few places where we need
the default (questionably signed) values. Consolidate
the casting in a single place rather than forcing callers
to get a char* ptr.

BUG=pdfium:493

Review-Url: https://codereview.chromium.org/1972053003
diff --git a/core/fpdfapi/fpdf_font/cpdf_font.cpp b/core/fpdfapi/fpdf_font/cpdf_font.cpp
index f143bed..9fb54a8 100644
--- a/core/fpdfapi/fpdf_font/cpdf_font.cpp
+++ b/core/fpdfapi/fpdf_font/cpdf_font.cpp
@@ -149,7 +149,7 @@
 }
 
 int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const {
-  *buf = (FX_CHAR)charcode;
+  *buf = static_cast<FX_CHAR>(charcode);
   return 1;
 }
 
diff --git a/core/fpdfapi/fpdf_font/fpdf_font.cpp b/core/fpdfapi/fpdf_font/fpdf_font.cpp
index dccce56..9f7b127 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font.cpp
+++ b/core/fpdfapi/fpdf_font/fpdf_font.cpp
@@ -139,12 +139,12 @@
   int result = 0;
   if (str[0] == '<') {
     for (int i = 1; i < len && std::isxdigit(str[i]); ++i)
-      result = result * 16 + FXSYS_toHexDigit(str[i]);
+      result = result * 16 + FXSYS_toHexDigit(str.CharAt(i));
     return result;
   }
 
   for (int i = 0; i < len && std::isdigit(str[i]); ++i)
-    result = result * 10 + FXSYS_toDecimalDigit(static_cast<FX_CHAR>(str[i]));
+    result = result * 10 + FXSYS_toDecimalDigit(str.CharAt(i));
 
   return result;
 }
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
index 0397514..1e9252f 100644
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
@@ -87,21 +87,20 @@
 }
 
 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) {
-  int size = bstr.GetLength();
-  const FX_CHAR* pSrc = bstr.c_str();
   if (bstr.Find('#') == -1)
     return bstr;
 
+  int size = bstr.GetLength();
   CFX_ByteString result;
   FX_CHAR* pDestStart = result.GetBuffer(size);
   FX_CHAR* pDest = pDestStart;
   for (int i = 0; i < size; i++) {
-    if (pSrc[i] == '#' && i < size - 2) {
+    if (bstr[i] == '#' && i < size - 2) {
       *pDest++ =
-          FXSYS_toHexDigit(pSrc[i + 1]) * 16 + FXSYS_toHexDigit(pSrc[i + 2]);
+          FXSYS_toHexDigit(bstr[i + 1]) * 16 + FXSYS_toHexDigit(bstr[i + 2]);
       i += 2;
     } else {
-      *pDest++ = pSrc[i];
+      *pDest++ = bstr[i];
     }
   }
   result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart));
diff --git a/core/fxcrt/fx_basic_bstring.cpp b/core/fxcrt/fx_basic_bstring.cpp
index 18e240b..e035dd5 100644
--- a/core/fxcrt/fx_basic_bstring.cpp
+++ b/core/fxcrt/fx_basic_bstring.cpp
@@ -99,9 +99,8 @@
 }
 
 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& stringSrc) {
-  if (!stringSrc.IsEmpty()) {
+  if (!stringSrc.IsEmpty())
     m_pData.Reset(StringData::Create(stringSrc.c_str(), stringSrc.GetLength()));
-  }
 }
 
 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& str1,
diff --git a/core/fxcrt/fx_basic_gcc.cpp b/core/fxcrt/fx_basic_gcc.cpp
index ddbdcd5..a55a486 100644
--- a/core/fxcrt/fx_basic_gcc.cpp
+++ b/core/fxcrt/fx_basic_gcc.cpp
@@ -226,9 +226,8 @@
   int len = 0;
   for (int i = 0; i < wlen; i++) {
     if (wstr[i] < 0x100) {
-      if (buf && len < buflen) {
-        buf[len] = (FX_CHAR)wstr[i];
-      }
+      if (buf && len < buflen)
+        buf[len] = static_cast<FX_CHAR>(wstr[i]);
       len++;
     }
   }
diff --git a/core/fxcrt/fx_basic_util.cpp b/core/fxcrt/fx_basic_util.cpp
index f691856..abb2b94 100644
--- a/core/fxcrt/fx_basic_util.cpp
+++ b/core/fxcrt/fx_basic_util.cpp
@@ -97,19 +97,19 @@
 void FX_atonum(const CFX_ByteStringC& strc, FX_BOOL& bInteger, void* pData) {
   if (strc.Find('.') == -1) {
     bInteger = TRUE;
-    int cc = 0, integer = 0;
-    const FX_CHAR* str = strc.c_str();
-    int len = strc.GetLength();
-    FX_BOOL bNegative = FALSE;
-    if (str[0] == '+') {
+    int cc = 0;
+    int integer = 0;
+    FX_STRSIZE len = strc.GetLength();
+    bool bNegative = false;
+    if (strc[0] == '+') {
       cc++;
-    } else if (str[0] == '-') {
-      bNegative = TRUE;
+    } else if (strc[0] == '-') {
+      bNegative = true;
       cc++;
     }
-    while (cc < len && std::isdigit(str[cc])) {
+    while (cc < len && std::isdigit(strc[cc])) {
       // TODO(dsinclair): This is not the right way to handle overflow.
-      integer = integer * 10 + FXSYS_toDecimalDigit(str[cc]);
+      integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
       if (integer < 0)
         break;
       cc++;
@@ -124,31 +124,30 @@
   }
 }
 FX_FLOAT FX_atof(const CFX_ByteStringC& strc) {
-  if (strc.GetLength() == 0) {
+  if (strc.IsEmpty())
     return 0.0;
-  }
+
   int cc = 0;
-  FX_BOOL bNegative = FALSE;
-  const FX_CHAR* str = strc.c_str();
+  bool bNegative = false;
   int len = strc.GetLength();
-  if (str[0] == '+') {
+  if (strc[0] == '+') {
     cc++;
-  } else if (str[0] == '-') {
+  } else if (strc[0] == '-') {
     bNegative = TRUE;
     cc++;
   }
   while (cc < len) {
-    if (str[cc] != '+' && str[cc] != '-') {
+    if (strc[cc] != '+' && strc[cc] != '-') {
       break;
     }
     cc++;
   }
   FX_FLOAT value = 0;
   while (cc < len) {
-    if (str[cc] == '.') {
+    if (strc[cc] == '.') {
       break;
     }
-    value = value * 10 + FXSYS_toDecimalDigit(str[cc]);
+    value = value * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
     cc++;
   }
   static const FX_FLOAT fraction_scales[] = {
@@ -156,14 +155,13 @@
       0.00001f,     0.000001f,     0.0000001f,    0.00000001f,
       0.000000001f, 0.0000000001f, 0.00000000001f};
   int scale = 0;
-  if (cc < len && str[cc] == '.') {
+  if (cc < len && strc[cc] == '.') {
     cc++;
     while (cc < len) {
-      value += fraction_scales[scale] * FXSYS_toDecimalDigit(str[cc]);
+      value += fraction_scales[scale] * FXSYS_toDecimalDigit(strc.CharAt(cc));
       scale++;
-      if (scale == sizeof fraction_scales / sizeof(FX_FLOAT)) {
+      if (scale == FX_ArraySize(fraction_scales))
         break;
-      }
       cc++;
     }
   }
diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp
index 0b55fc9..315e33f 100644
--- a/core/fxcrt/fx_extension.cpp
+++ b/core/fxcrt/fx_extension.cpp
@@ -219,17 +219,13 @@
 }
 
 uint32_t FX_HashCode_GetA(const CFX_ByteStringC& str, bool bIgnoreCase) {
-  const FX_CHAR* pStr = str.c_str();
-  const FX_CHAR* pStrEnd = pStr + str.GetLength();
   uint32_t dwHashCode = 0;
   if (bIgnoreCase) {
-    while (pStr < pStrEnd) {
-      dwHashCode = 31 * dwHashCode + FXSYS_tolower(*pStr++);
-    }
+    for (FX_STRSIZE i = 0; i < str.GetLength(); ++i)
+      dwHashCode = 31 * dwHashCode + FXSYS_tolower(str.CharAt(i));
   } else {
-    while (pStr < pStrEnd) {
-      dwHashCode = 31 * dwHashCode + *pStr++;
-    }
+    for (FX_STRSIZE i = 0; i < str.GetLength(); ++i)
+      dwHashCode = 31 * dwHashCode + str.CharAt(i);
   }
   return dwHashCode;
 }
diff --git a/core/fxcrt/fx_xml_composer.cpp b/core/fxcrt/fx_xml_composer.cpp
index 576ff95..1bad069 100644
--- a/core/fxcrt/fx_xml_composer.cpp
+++ b/core/fxcrt/fx_xml_composer.cpp
@@ -11,24 +11,18 @@
 void FX_XML_SplitQualifiedName(const CFX_ByteStringC& bsFullName,
                                CFX_ByteStringC& bsSpace,
                                CFX_ByteStringC& bsName) {
-  if (bsFullName.IsEmpty()) {
+  if (bsFullName.IsEmpty())
     return;
-  }
-  int32_t iStart = 0;
-  for (; iStart < bsFullName.GetLength(); iStart++) {
-    if (bsFullName.GetAt(iStart) == ':') {
-      break;
-    }
-  }
-  if (iStart >= bsFullName.GetLength()) {
+
+  FX_STRSIZE iStart = bsFullName.Find(':');
+  if (iStart == -1) {
     bsName = bsFullName;
   } else {
-    bsSpace = CFX_ByteStringC(bsFullName.c_str(), iStart);
-    iStart++;
-    bsName = CFX_ByteStringC(bsFullName.c_str() + iStart,
-                             bsFullName.GetLength() - iStart);
+    bsSpace = bsFullName.Mid(0, iStart);
+    bsName = bsFullName.Mid(iStart + 1);
   }
 }
+
 void CXML_Element::SetTag(const CFX_ByteStringC& qSpace,
                           const CFX_ByteStringC& tagname) {
   m_QSpaceName = qSpace;
diff --git a/core/fxcrt/include/fx_string.h b/core/fxcrt/include/fx_string.h
index 8c1a617..617e02e 100644
--- a/core/fxcrt/include/fx_string.h
+++ b/core/fxcrt/include/fx_string.h
@@ -94,6 +94,9 @@
   bool IsEmpty() const { return m_Length == 0; }
 
   uint8_t GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
+  FX_CHAR CharAt(FX_STRSIZE index) const {
+    return static_cast<FX_CHAR>(m_Ptr[index]);
+  }
 
   FX_STRSIZE Find(FX_CHAR ch) const {
     const uint8_t* found =
diff --git a/xfa/fee/fde_txtedtengine.cpp b/xfa/fee/fde_txtedtengine.cpp
index dfbf02e..71f5102 100644
--- a/xfa/fee/fde_txtedtengine.cpp
+++ b/xfa/fee/fde_txtedtengine.cpp
@@ -1603,9 +1603,9 @@
 
 IFDE_TxtEdtDoRecord* IFDE_TxtEdtDoRecord::Create(
     const CFX_ByteStringC& bsDoRecord) {
-  const FX_CHAR* lpBuf = bsDoRecord.c_str();
-  int32_t nType = *((int32_t*)lpBuf);
-  switch (nType) {
+  const uint32_t* lpBuf =
+      reinterpret_cast<const uint32_t*>(bsDoRecord.raw_str());
+  switch (*lpBuf) {
     case FDE_TXTEDT_DORECORD_INS:
       return new CFDE_TxtEdtDoRecord_Insert(bsDoRecord);
     case FDE_TXTEDT_DORECORD_DEL:
@@ -1669,9 +1669,7 @@
 }
 void CFDE_TxtEdtDoRecord_Insert::Deserialize(
     const CFX_ByteStringC& bsDoRecord) {
-  CFX_ArchiveLoader ArchiveLoader(
-      reinterpret_cast<const uint8_t*>(bsDoRecord.c_str()),
-      bsDoRecord.GetLength());
+  CFX_ArchiveLoader ArchiveLoader(bsDoRecord.raw_str(), bsDoRecord.GetLength());
   int32_t nType = 0;
   ArchiveLoader >> nType;
   ASSERT(nType == FDE_TXTEDT_DORECORD_INS);
@@ -1746,9 +1744,7 @@
 }
 void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize(
     const CFX_ByteStringC& bsDoRecord) {
-  CFX_ArchiveLoader ArchiveLoader(
-      reinterpret_cast<const uint8_t*>(bsDoRecord.c_str()),
-      bsDoRecord.GetLength());
+  CFX_ArchiveLoader ArchiveLoader(bsDoRecord.raw_str(), bsDoRecord.GetLength());
   int32_t nType = 0;
   ArchiveLoader >> nType;
   ASSERT(nType == FDE_TXTEDT_DORECORD_DEL);
diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp
index 88a52b9..53c5a84 100644
--- a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp
+++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp
@@ -36,9 +36,9 @@
     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
 const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::TEXT_SHIFT3_SET_CHARS[] = {
-    '\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',         'J',
-    'K',  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',         'U',
-    'V',  'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (FX_CHAR)127};
+    '\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+    'K',  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
+    'V',  'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127};
 const int32_t CBC_DataMatrixDecodedBitStreamParser::PAD_ENCODE = 0;
 const int32_t CBC_DataMatrixDecodedBitStreamParser::ASCII_ENCODE = 1;
 const int32_t CBC_DataMatrixDecodedBitStreamParser::C40_ENCODE = 2;