34 #ifndef __MOFILEREADER_SINGLE_INCLUDE_H_INCLUDED__
35 #define __MOFILEREADER_SINGLE_INCLUDE_H_INCLUDED__
38 #pragma warning(disable : 4267)
53 #define MO_PATHSEP std::string("\\")
55 #define MO_PATHSEP std::string("/")
62 #ifndef MO_BEGIN_NAMESPACE
63 #define MO_BEGIN_NAMESPACE \
70 #ifndef MO_END_NAMESPACE
71 #define MO_END_NAMESPACE }
166 background-color: black;
173 background-color: orange;
352 std::stringstream stream(data);
368 std::ifstream stream(filename, std::ios_base::binary | std::ios_base::in);
369 if (!stream.is_open())
371 m_error = std::string(
"Cannot open File ") + std::string(filename);
405 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
414 m_error =
"The Magic Number does not match in all cases!";
420 m_error =
"Magic Number is reversed. We do not support this yet!";
433 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
437 TransPairInfo.push_back(_str);
449 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
460 int orLength = TransPairInfo[i].m_orLength + 1;
461 int trLength = TransPairInfo[i].m_trLength + 1;
463 int orOffset = TransPairInfo[i].m_orOffset;
464 int trOffset = TransPairInfo[i].m_trOffset;
467 char *original =
new char[orLength];
468 memset(original, 0,
sizeof(
char) * orLength);
470 stream.seekg(orOffset);
471 stream.read(original, orLength);
475 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
480 char *translation =
new char[trLength];
481 memset(translation, 0,
sizeof(
char) * trLength);
483 stream.seekg(trOffset);
484 stream.read(translation, trLength);
488 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
492 std::string original_str = original;
493 std::string translation_str = translation;
497 if (ctxSeparator == std::string::npos)
499 m_lookup[original_str] = translation_str;
507 m_lookup_context[original_str.substr(0, ctxSeparator)]
508 [original_str.substr(ctxSeparator + 1, original_str.length())] = translation_str;
513 m_error =
"Stream bad during reading. The .mo-file seems to be invalid or has bad descriptions!";
520 delete[] translation;
533 if (m_lookup.empty())
return id;
534 auto iterator = m_lookup.find(
id);
536 return iterator == m_lookup.end() ? id : iterator->second;
547 if (m_lookup_context.empty())
return id;
548 auto iterator = m_lookup_context.find(context);
550 if (iterator == m_lookup_context.end())
return id;
551 auto iterator2 = iterator->second.find(
id);
553 return iterator2 == iterator->second.end() ? id : iterator2->second;
566 m_lookup_context.clear();
596 unsigned int pos = infile.find_last_of(
MO_PATHSEP);
597 if (pos != std::string::npos) { fname = infile.substr(pos + 1, infile.length()); }
604 std::string htmlfile(filename);
605 if (htmlfile.empty()) { htmlfile = infile + std::string(
".html"); }
608 std::ofstream stream(htmlfile.c_str());
609 if (stream.is_open())
611 stream << R
"(<!DOCTYPE HTML PUBLIC "- //W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">)"
613 stream << "<html><head><style type=\"text/css\">\n" << std::endl;
614 stream << css << std::endl;
615 stream <<
"</style>" << std::endl;
616 stream << R
"(<meta http-equiv="content-type" content="text/html; charset=utf-8">)" << std::endl;
617 stream << "<title>Dump of " << fname <<
"</title></head>" << std::endl;
618 stream <<
"<body>" << std::endl;
619 stream <<
"<center>" << std::endl;
620 stream <<
"<h1>" << fname <<
"</h1>" << std::endl;
621 stream << R
"(<table border="1"><th colspan="2">Project Info</th>)" << std::endl;
623 std::stringstream parsee;
624 parsee << reader.Lookup("");
626 while (!parsee.eof())
629 parsee.getline(buffer, 1024);
633 reader.GetPoEditorString(buffer, name, value);
634 if (!(name.empty() || value.empty()))
636 stream <<
"<tr><td>" << name <<
"</td><td>" << value <<
"</td></tr>" << std::endl;
639 stream <<
"</table>" << std::endl;
640 stream <<
"<hr noshade/>" << std::endl;
643 stream << R
"(<table border="1"><th colspan="2">Content</th>)" << std::endl;
644 for (
const auto &it : reader.m_lookup)
646 if (!it.first.empty())
648 stream <<
"<tr><td>" << it.first <<
"</td><td>" << it.second <<
"</td></tr>" << std::endl;
651 stream <<
"</table><br/>" << std::endl;
654 for (
const auto &it : reader.m_lookup_context)
656 stream << R
"(<table border="1"><th colspan="2">)" << it.first << "</th>" << std::endl;
657 for (
const auto &its : it.second)
659 stream <<
"<tr><td>" << its.first <<
"</td><td>" << its.second <<
"</td></tr>" << std::endl;
661 stream <<
"</table><br/>" << std::endl;
664 stream <<
"</center>" << std::endl;
665 stream <<
"<div class=\"copyleft\">File generated by <a href=\"https://github.com/AnotherFoxGuy/MofileReader\" "
666 "target=\"_blank\">moFileReaderSDK</a></div>"
668 stream <<
"</body></html>" << std::endl;
689 unsigned long b0 = (in >> 0) & 0xff;
690 unsigned long b1 = (in >> 8) & 0xff;
691 unsigned long b2 = (in >> 16) & 0xff;
692 unsigned long b3 = (in >> 24) & 0xff;
694 return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
705 static void MakeHtmlConform(std::string &_inout)
707 std::string temp = _inout;
708 for (
unsigned int i = 0; i < temp.length(); i++)
710 if (temp[i] ==
'>') { _inout.replace(i, 1,
")"); }
711 if (temp[i] ==
'<') { _inout.replace(i, 1,
"("); }
716 bool GetPoEditorString(
const char *_buffer, std::string &_name, std::string &_value)
718 std::string line(_buffer);
719 size_t first = line.find_first_of(
':');
721 if (first != std::string::npos)
723 _name = line.substr(0, first);
724 _value = line.substr(first + 1, line.length());
727 MakeHtmlConform(_value);
728 MakeHtmlConform(_name);
740 static void Trim(std::string &_in)
742 while (_in[0] ==
' ')
744 _in = _in.substr(1, _in.length());
746 while (_in[_in.length()] ==
' ')
748 _in = _in.substr(0, _in.length() - 1);
753 #ifndef MO_NO_CONVENIENCE_CLASS
790 return theoneandonly;
808 inline std::string
_(
const char *
id)
835 #if defined(_MSC_VER)
836 #pragma warning(default : 4251)
This class is a gettext-replacement.
unsigned long SwapBytes(unsigned long in)
Swap the endianness of a 4 byte WORD.
static const unsigned int MagicNumber
The Magic Number describes the endianess of bytes on the system.
const std::string & GetErrorDescription() const
Returns the Error Description.
std::string Lookup(const char *id) const
Returns the searched translation or returns the input.
eErrorCode ReadFile(const char *filename)
Reads a .mo-file.
static eErrorCode ExportAsHTML(const std::string &infile, const std::string &filename="", const std::string &css=g_css)
Exports the whole content of the .mo-File as .html.
static const unsigned int MagicReversed
If the Magic Number is Reversed, we need to swap the bytes.
moFileReader::eErrorCode ParseData(const std::string &data)
Reads a .mo-file.
eErrorCode
The possible errorcodes for methods of this class.
@ EC_ERROR
Indicates an error.
@ EC_FILENOTFOUND
The given File was not found.
@ EC_MAGICNUMBER_NOMATCH
The magic number did not match.
@ EC_TABLEEMPTY
Empty Lookup-Table (returned by ExportAsHTML())
@ EC_MAGICNUMBER_REVERSED
The magic number is reversed.
@ EC_FILEINVALID
The file is invalid.
@ EC_SUCCESS
Indicated success.
std::map< std::string, std::string > moLookupList
Type for the map which holds the translation-pairs later.
std::string LookupWithContext(const char *context, const char *id) const
Returns the searched translation or returns the input, restricted to the context given by context....
std::map< std::string, moLookupList > moContextLookupList
Type for the 2D map which holds the translation-pairs later.
unsigned int GetNumStrings() const
Returns the Number of Entries in our Lookup-Table.
eErrorCode ReadStream(T &stream)
Reads data from a stream.
std::string m_error
Keeps the last error as String.
static const char ContextSeparator
The character that is used to separate context strings.
void ClearTable()
Empties the Lookup-Table.
static moFileReaderSingleton & GetInstance()
Singleton-Accessor.
#define MO_BEGIN_NAMESPACE
void moFileClearTable()
Resets the Lookup-Table.
moFileReader::eErrorCode moReadMoFile(const char *_filename)
Reads the .mo-File.
std::string moFileGetErrorDescription()
Returns the last known error as string or an empty class.
MO_BEGIN_NAMESPACE const std::string g_css
std::string _(const char *id)
Looks for the spec. string to translate.
int moFileGetNumStrings()
Returns the number of entries loaded from the .mo-File.
Describes the "Header" of a .mo-File.
int m_offsetTranslation
Offset of the Table of the Translated Strings.
std::deque< moTranslationPairInformation > moTranslationPairList
Type for the list of all Translation-Pair-Descriptions.
int m_numStrings
Number of Strings in the .mo-file.
int m_offsetHashtable
The Offset of the Hashtable.
int m_sizeHashtable
Size of 1 Entry in the Hashtable.
int m_fileVersion
The File Version, 0 atm according to the manpage.
int m_offsetOriginal
Offset of the Table of the Original Strings.
bool m_reversed
Tells you if the bytes are reversed.
int m_magicNumber
The Magic Number, compare it to g_MagicNumber.
moTranslationPairList m_translationPairInformation
A list containing offset and length of the strings in the file.