示例#1
0
文件: Weather.cpp 项目: anaconda/xbmc
void CWeatherJob::LoadLocalizedToken()
{
  // We load the english strings in to get our tokens
  std::string language = LANGUAGE_DEFAULT;
  std::shared_ptr<CSettingString> languageSetting = std::static_pointer_cast<CSettingString>(CServiceBroker::GetSettings().GetSetting(CSettings::SETTING_LOCALE_LANGUAGE));
  if (languageSetting != NULL)
    language = languageSetting->GetDefault();

  // Try the strings PO file first
  CPODocument PODoc;
  if (PODoc.LoadFile(URIUtils::AddFileToFolder(CLangInfo::GetLanguagePath(language), "strings.po")))
  {
    int counter = 0;

    while (PODoc.GetNextEntry())
    {
      if (PODoc.GetEntryType() != ID_FOUND)
        continue;

      uint32_t id = PODoc.GetEntryID();
      PODoc.ParseEntry(ISSOURCELANG);

      if (id > LOCALIZED_TOKEN_LASTID2) break;
      if ((LOCALIZED_TOKEN_FIRSTID  <= id && id <= LOCALIZED_TOKEN_LASTID)  ||
          (LOCALIZED_TOKEN_FIRSTID2 <= id && id <= LOCALIZED_TOKEN_LASTID2) ||
          (LOCALIZED_TOKEN_FIRSTID3 <= id && id <= LOCALIZED_TOKEN_LASTID3) ||
          (LOCALIZED_TOKEN_FIRSTID4 <= id && id <= LOCALIZED_TOKEN_LASTID4))
      {
        if (!PODoc.GetMsgid().empty())
        {
          m_localizedTokens.insert(make_pair(PODoc.GetMsgid(), id));
          counter++;
        }
      }
    }

    CLog::Log(LOGDEBUG, "POParser: loaded %i weather tokens", counter);
    return;
  }

  CLog::Log(LOGDEBUG,
            "Weather: no PO string file available, to load English tokens, "
            "fallback to strings.xml file");

  // We load the tokens from the strings.xml file
  std::string strLanguagePath = URIUtils::AddFileToFolder(CLangInfo::GetLanguagePath(language), "strings.xml");

  CXBMCTinyXML xmlDoc;
  if (!xmlDoc.LoadFile(strLanguagePath) || !xmlDoc.RootElement())
  {
    CLog::Log(LOGERROR, "Weather: unable to load %s: %s at line %d", strLanguagePath.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow());
    return;
  }

  TiXmlElement* pRootElement = xmlDoc.RootElement();
  if (pRootElement->ValueStr() != "strings")
    return;

  const TiXmlElement *pChild = pRootElement->FirstChildElement();
  while (pChild)
  {
    std::string strValue = pChild->ValueStr();
    if (strValue == "string")
    { // Load new style language file with id as attribute
      const char* attrId = pChild->Attribute("id");
      if (attrId && !pChild->NoChildren())
      {
        int id = atoi(attrId);
        if ((LOCALIZED_TOKEN_FIRSTID  <= id && id <= LOCALIZED_TOKEN_LASTID)  ||
            (LOCALIZED_TOKEN_FIRSTID2 <= id && id <= LOCALIZED_TOKEN_LASTID2) ||
            (LOCALIZED_TOKEN_FIRSTID3 <= id && id <= LOCALIZED_TOKEN_LASTID3) ||
            (LOCALIZED_TOKEN_FIRSTID4 <= id && id <= LOCALIZED_TOKEN_LASTID4))
        {
          std::string utf8Label(pChild->FirstChild()->ValueStr());
          if (!utf8Label.empty())
            m_localizedTokens.insert(make_pair(utf8Label, id));
        }
      }
    }
    pChild = pChild->NextSiblingElement();
  }
}
示例#2
0
文件: TestPOUtils.cpp 项目: A600/xbmc
TEST(TestPOUtils, General)
{
  CPODocument a;

  EXPECT_TRUE(a.LoadFile(XBMC_REF_FILE_PATH("/language/Spanish/strings.po")));

  EXPECT_TRUE(a.GetNextEntry());
  EXPECT_EQ(ID_FOUND, a.GetEntryType());
  EXPECT_EQ((uint32_t)0, a.GetEntryID());
  a.ParseEntry(false);
  EXPECT_STREQ("", a.GetMsgctxt().c_str());
  EXPECT_STREQ("Programs", a.GetMsgid().c_str());
  EXPECT_STREQ("Programas", a.GetMsgstr().c_str());
  EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());

  EXPECT_TRUE(a.GetNextEntry());
  EXPECT_EQ(ID_FOUND, a.GetEntryType());
  EXPECT_EQ((uint32_t)1, a.GetEntryID());
  a.ParseEntry(false);
  EXPECT_STREQ("", a.GetMsgctxt().c_str());
  EXPECT_STREQ("Pictures", a.GetMsgid().c_str());
  EXPECT_STREQ("Imágenes", a.GetMsgstr().c_str());
  EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());

  EXPECT_TRUE(a.GetNextEntry());
  EXPECT_EQ(ID_FOUND, a.GetEntryType());
  EXPECT_EQ((uint32_t)2, a.GetEntryID());
  a.ParseEntry(false);
  EXPECT_STREQ("", a.GetMsgctxt().c_str());
  EXPECT_STREQ("Music", a.GetMsgid().c_str());
  EXPECT_STREQ("Música", a.GetMsgstr().c_str());
  EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());
}
示例#3
0
/*! \brief Tries to load ids and strings from a strings.po file to the `strings` map.
 * It should only be called from the LoadStr2Mem function to have a fallback.
 \param pathname The directory name, where we look for the strings file.
 \param strings [out] The resulting strings map.
 \param encoding Encoding of the strings. For PO files we only use utf-8.
 \param offset An offset value to place strings from the id value.
 \param bSourceLanguage If we are loading the source English strings.po.
 \return false if no strings.po file was loaded.
 */
static bool LoadPO(const std::string &filename, std::map<uint32_t, LocStr>& strings,
    std::string &encoding, uint32_t offset = 0 , bool bSourceLanguage = false)
{
  CPODocument PODoc;
  if (!PODoc.LoadFile(filename))
    return false;

  int counter = 0;

  while ((PODoc.GetNextEntry()))
  {
    uint32_t id;
    if (PODoc.GetEntryType() == ID_FOUND)
    {
      bool bStrInMem = strings.find((id = PODoc.GetEntryID()) + offset) != strings.end();
      PODoc.ParseEntry(bSourceLanguage);

      if (bSourceLanguage && !PODoc.GetMsgid().empty())
      {
        if (bStrInMem && (strings[id + offset].strOriginal.empty() ||
                          PODoc.GetMsgid() == strings[id + offset].strOriginal))
          continue;
        else if (bStrInMem)
          CLog::Log(LOGDEBUG,
              "POParser: id:%i was recently re-used in the English string file, which is not yet "
                  "changed in the translated file. Using the English string instead", id);
        strings[id + offset].strTranslated = PODoc.GetMsgid();
        counter++;
      }
      else if (!bSourceLanguage && !bStrInMem && !PODoc.GetMsgstr().empty())
      {
        strings[id + offset].strTranslated = PODoc.GetMsgstr();
        strings[id + offset].strOriginal = PODoc.GetMsgid();
        counter++;
      }
    }
    else if (PODoc.GetEntryType() == MSGID_FOUND)
    {
      // TODO: implement reading of non-id based string entries from the PO files.
      // These entries would go into a separate memory map, using hash codes for fast look-up.
      // With this memory map we can implement using gettext(), ngettext(), pgettext() calls,
      // so that we don't have to use new IDs for new strings. Even we can start converting
      // the ID based calls to normal gettext calls.
    }
    else if (PODoc.GetEntryType() == MSGID_PLURAL_FOUND)
    {
      // TODO: implement reading of non-id based pluralized string entries from the PO files.
      // We can store the pluralforms for each language, in the langinfo.xml files.
    }
  }

  CLog::Log(LOGDEBUG, "LocalizeStrings: loaded %i strings from file %s", counter, filename.c_str());
  return true;
}
示例#4
0
bool CLocalizeStrings::LoadPO(const CStdString &filename, CStdString &encoding,
                              uint32_t offset /* = 0 */, bool bSourceLanguage)
{
  CPODocument PODoc;
  if (!PODoc.LoadFile(filename))
    return false;

  int counter = 0;

  while ((PODoc.GetNextEntry()))
  {
    uint32_t id;
    if (PODoc.GetEntryType() == ID_FOUND &&
        m_strings.find((id = PODoc.GetEntryID()) + offset) == m_strings.end())
    {
      PODoc.ParseEntry(bSourceLanguage);
      if (bSourceLanguage)
      {
        if (!PODoc.GetMsgid().empty())
        {
          m_strings[id + offset] = PODoc.GetMsgid();
          counter++;
        }
      }
      else
      {
        if (!PODoc.GetMsgstr().empty())
        {
          m_strings[id + offset] = PODoc.GetMsgstr();
          counter++;
        }
      }
    }
    else if (PODoc.GetEntryType() == MSGID_FOUND)
    {
      // TODO: implement reading of non-id based string entries from the PO files.
      // These entries would go into a separate memory map, using hash codes for fast look-up.
      // With this memory map we can implement using gettext(), ngettext(), pgettext() calls,
      // so that we don't have to use new IDs for new strings. Even we can start converting
      // the ID based calls to normal gettext calls.
    }
    else if (PODoc.GetEntryType() == MSGID_PLURAL_FOUND)
    {
      // TODO: implement reading of non-id based pluralized string entries from the PO files.
      // We can store the pluralforms for each language, in the langinfo.xml files.
    }
  }

  CLog::Log(LOGDEBUG, "POParser: loaded %i strings from file %s", counter, filename.c_str());
  return true;
}
示例#5
0
void CWeatherJob::LoadLocalizedToken()
{
  // We load the english strings in to get our tokens

  // Try the strings PO file first
  CPODocument PODoc;
  if (PODoc.LoadFile("special://xbmc/language/English/strings.po"))
  {
    int counter = 0;

    while (PODoc.GetNextEntry())
    {
      if (PODoc.GetEntryType() != ID_FOUND)
        continue;

      uint32_t id = PODoc.GetEntryID();
      PODoc.ParseEntry(ISSOURCELANG);

      if (id > LOCALIZED_TOKEN_LASTID2) break;
      if ((LOCALIZED_TOKEN_FIRSTID  <= id && id <= LOCALIZED_TOKEN_LASTID)  ||
          (LOCALIZED_TOKEN_FIRSTID2 <= id && id <= LOCALIZED_TOKEN_LASTID2) ||
          (LOCALIZED_TOKEN_FIRSTID3 <= id && id <= LOCALIZED_TOKEN_LASTID3) ||
          (LOCALIZED_TOKEN_FIRSTID4 <= id && id <= LOCALIZED_TOKEN_LASTID4))
      {
        if (!PODoc.GetMsgid().empty())
        {
          m_localizedTokens.insert(make_pair(PODoc.GetMsgid(), id));
          counter++;
        }
      }
    }

    CLog::Log(LOGDEBUG, "POParser: loaded %i weather tokens", counter);
    return;
  }

  CLog::Log(LOGDEBUG,
            "Weather: no PO string file available, to load English tokens, "
            "fallback to strings.xml file");

  // We load the tokens from the strings.xml file
  CStdString strLanguagePath = "special://xbmc/language/English/strings.xml";

  CXBMCTinyXML xmlDoc;
  if (!xmlDoc.LoadFile(strLanguagePath) || !xmlDoc.RootElement())
  {
    CLog::Log(LOGERROR, "Weather: unable to load %s: %s at line %d", strLanguagePath.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow());
    return;
  }

  CStdString strEncoding;
  XMLUtils::GetEncoding(&xmlDoc, strEncoding);

  TiXmlElement* pRootElement = xmlDoc.RootElement();
  if (pRootElement->Value() != CStdString("strings"))
    return;

  const TiXmlElement *pChild = pRootElement->FirstChildElement();
  while (pChild)
  {
    CStdString strValue = pChild->Value();
    if (strValue == "string")
    { // Load new style language file with id as attribute
      const char* attrId = pChild->Attribute("id");
      if (attrId && !pChild->NoChildren())
      {
        int id = atoi(attrId);
        if ((LOCALIZED_TOKEN_FIRSTID  <= id && id <= LOCALIZED_TOKEN_LASTID)  ||
            (LOCALIZED_TOKEN_FIRSTID2 <= id && id <= LOCALIZED_TOKEN_LASTID2) ||
            (LOCALIZED_TOKEN_FIRSTID3 <= id && id <= LOCALIZED_TOKEN_LASTID3) ||
            (LOCALIZED_TOKEN_FIRSTID4 <= id && id <= LOCALIZED_TOKEN_LASTID4))
        {
          CStdString utf8Label;
          if (strEncoding.IsEmpty()) // Is language file utf8?
            utf8Label=pChild->FirstChild()->Value();
          else
            g_charsetConverter.stringCharsetToUtf8(strEncoding, pChild->FirstChild()->Value(), utf8Label);

          if (!utf8Label.IsEmpty())
            m_localizedTokens.insert(make_pair(utf8Label, id));
        }
      }
    }
    pChild = pChild->NextSiblingElement();
  }
}