]> git.vomp.tv Git - vompserver.git/commitdiff
New I18n system: server code
authorMark Calderbank <mark@vomp.tv>
Thu, 6 Dec 2007 13:58:34 +0000 (13:58 +0000)
committerMark Calderbank <mark@vomp.tv>
Thu, 6 Dec 2007 13:58:34 +0000 (13:58 +0000)
Makefile
i18n.c [new file with mode: 0644]
i18n.h [new file with mode: 0644]
mvpclient.c
mvpclient.h

index 659d4e92d6621441dfcbd9427ee9c09cf87f3452..fda7d9e1860c8fcabdb7cbf7b666c0e989d3c0ec 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
 ### The object files (add further files here):
 
-OBJS = $(PLUGIN).o dsock.o mvpserver.o udpreplier.o bootpd.o tftpd.o mvpclient.o tcp.o \
+OBJS = $(PLUGIN).o dsock.o mvpserver.o udpreplier.o bootpd.o tftpd.o i18n.o mvpclient.o tcp.o \
                    ringbuffer.o mvprelay.o \
                    recplayer.o config.o log.o thread.o mvpreceiver.o tftpclient.o \
                    media.o responsepacket.o
diff --git a/i18n.c b/i18n.c
new file mode 100644 (file)
index 0000000..7621b40
--- /dev/null
+++ b/i18n.c
@@ -0,0 +1,134 @@
+/*
+    Copyright 2007 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "i18n.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <glob.h>
+
+using namespace std;
+
+I18n::I18n(char* tconfigDir)
+{
+  configDir = tconfigDir;
+}
+
+void I18n::findLanguages(void)
+{
+  glob_t globbuf;
+  char line[1000];
+
+  CodeList.clear();
+  FileList.clear();
+  
+  string l10nGlob = configDir;
+  l10nGlob += "/l10n/*";
+  glob(l10nGlob.c_str(), 0, NULL, &globbuf);
+  for (unsigned int i=0; i < globbuf.gl_pathc; i++)
+  {
+    FILE *f = fopen(globbuf.gl_pathv[i], "r");
+    if (f)
+    {
+      while (fgets(line, 1000, f) && strncmp(line, "l10n-vomp:", 10) == 0)
+      {
+        string langline = line;
+        string code, name;
+
+        string::size_type pos_start, pos_end;
+        pos_start = langline.find_first_not_of(" \t\r\n", 10);
+        if (pos_start == string::npos) break;
+        pos_end = langline.find_first_of(" \t", pos_start);
+        if (pos_end == string::npos) break;
+        code = langline.substr(pos_start, pos_end - pos_start);
+        pos_start = langline.find_first_not_of(" \t\r\n", pos_end);
+        if (pos_start == string::npos) break;
+        pos_end = langline.find_last_not_of(" \t\r\n");
+        name = langline.substr(pos_start, pos_end + 1 - pos_start);
+        CodeList[code] = name;
+        FileList.insert(lang_file(code, globbuf.gl_pathv[i]));
+      }
+      fclose(f);
+    }
+  }
+  globfree(&globbuf);
+}
+
+I18n::trans_table I18n::getLanguageContent(const string code)
+{
+  trans_table Translations;
+  if (CodeList.count(code) == 0) return Translations;
+  LanguageCode = code;
+
+  pair<lang_file_list::const_iterator, lang_file_list::const_iterator> range;
+  range = FileList.equal_range(code);
+  lang_file_list::const_iterator iter;
+  for (iter = range.first; iter != range.second; ++iter)
+  {
+    FILE *f;
+    char line[1000];
+    string key; 
+    f = fopen((*iter).second.c_str(), "r");
+    if (f)
+    {
+      while (fgets(line, 1000, f))
+      {
+        int linetype = 0;
+       string::size_type offset = 0;
+        string fileline = line;
+        if (fileline.compare(0, 2, "x:") == 0)
+        { // New key to be translated
+          linetype = 1; offset = 2;
+        }
+        if (fileline.compare(0, code.size() + 1, code + ":") == 0)
+        { // Translation for previous key
+          if (key.empty()) continue; // Translation without preceding key
+          linetype = 2; offset = code.size() + 1;
+        }
+        if (linetype != 0)
+        {
+          string::size_type start, end;
+         start = fileline.find_first_not_of(" \t\r\n",offset);
+          if (start == string::npos)
+         {
+           if (linetype == 2) Translations[key].clear();
+           continue;
+         }
+          end = fileline.find_last_not_of(" \t\r\n");
+          string text = fileline.substr(start, end + 1 - start);
+         if (text.length() > 1) // Strip quotes if at both ends
+         {
+           if (text[0] == '"' && text[text.length()-1] == '"')
+             text = text.substr(1, text.length()-2);
+         }
+          if (linetype == 1) key = text;
+          if (linetype == 2) Translations[key] = text;
+        }
+      }
+      fclose(f);
+    }
+  }
+  return Translations;
+}
+
+const I18n::lang_code_list& I18n::getLanguageList(void)
+{
+  return CodeList;
+}
diff --git a/i18n.h b/i18n.h
new file mode 100644 (file)
index 0000000..109c336
--- /dev/null
+++ b/i18n.h
@@ -0,0 +1,49 @@
+/*
+    Copyright 2007 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef I18N_H
+#define I18N_H
+
+#include <string>
+#include <map>
+
+class I18n
+{
+  public:
+    I18n(char* tconfigDir);
+    typedef std::map<std::string,std::string> lang_code_list;
+    typedef std::pair<std::string,std::string> lang_code;
+    typedef std::map<std::string,std::string> trans_table;
+    typedef std::pair<std::string,std::string> trans_entry;
+
+    void findLanguages(void);
+    trans_table getLanguageContent(const std::string code);
+    const lang_code_list& getLanguageList(void);
+
+  private:
+    char* configDir;
+    std::string LanguageCode;
+    lang_code_list CodeList;
+
+    typedef std::multimap<std::string,std::string> lang_file_list;
+    typedef std::pair<std::string,std::string> lang_file;
+    lang_file_list FileList; 
+};
+#endif
index d366e51e1ccc2f9ec41589cfc8ddc154846e8ffb..17fced939e7921d09cb6415cdcab1bb72984872e 100644 (file)
@@ -30,7 +30,7 @@ int MVPClient::nr_clients = 0;
 
 
 MVPClient::MVPClient(Config* cfgBase, char* tconfigDir, int tsocket)
- : tcp(tsocket)
+ : tcp(tsocket), i18n(tconfigDir)
 {
 #ifndef VOMPSTANDALONE
   lp = NULL;
@@ -41,6 +41,7 @@ MVPClient::MVPClient(Config* cfgBase, char* tconfigDir, int tsocket)
   log = Log::getInstance();
   loggedIn = false;
   configDir = tconfigDir;
+  log->log("Client", Log::DEBUG, "Config dir: %s", configDir);
   baseConfig = cfgBase;
   incClients();
 }
@@ -383,6 +384,12 @@ void MVPClient::run2()
       case 32:
         result = processGetImageBlock(data, extraDataLength, rp);
         break;
+      case 33:
+        result = processGetLanguageList(data, extraDataLength, rp);
+        break;
+      case 34:
+        result = processGetLanguageContent(data, extraDataLength, rp);
+        break;
     }
 
     if (data) free(data);
@@ -1836,6 +1843,46 @@ int MVPClient::processGetImageBlock(UCHAR* data, int length, ResponsePacket* rp)
 }
 
 
+int MVPClient::processGetLanguageList(UCHAR* data, int length, ResponsePacket* rp)
+{
+  i18n.findLanguages();
+  const I18n::lang_code_list& languages = i18n.getLanguageList();
+  std::string result;
+  I18n::lang_code_list::const_iterator iter;
+  for (iter = languages.begin(); iter != languages.end(); ++iter)
+  {
+    rp->addString(iter->first.c_str());
+    rp->addString(iter->second.c_str());
+  }
+  rp->finalise();
+  tcp.sendPacket(rp->getPtr(), rp->getLen());
+  delete rp;
+  return 1;
+}
+
+int MVPClient::processGetLanguageContent(UCHAR* data, int length, ResponsePacket* rp)
+{
+  if (length <= 0) return 0;
+  std::string code, result;
+  code.assign((char*)data, length - 1);
+  i18n.findLanguages();
+  I18n::trans_table texts = i18n.getLanguageContent(code);
+  I18n::trans_table::const_iterator iter;
+  for (iter = texts.begin(); iter != texts.end(); ++iter)
+  {
+    rp->addString(iter->first.c_str());
+    rp->addString(iter->second.c_str());
+  }
+  rp->finalise();
+  tcp.sendPacket(rp->getPtr(), rp->getLen());
+  delete rp;
+  return 1;
+}
+
+
+
+
+
 
 
 
index 8afdf4fd3ce9dee9965fa16180b68a9a969a1bef..9ef5c84471d6f79a33114de545913558162c943c 100644 (file)
@@ -43,6 +43,7 @@
 #include "tcp.h"
 #include "config.h"
 #include "media.h"
+#include "i18n.h"
 
 class ResponsePacket;
 
@@ -65,6 +66,7 @@ class MVPClient
     TCP tcp;
     Config config;
     Config* baseConfig;
+    I18n i18n;
     bool loggedIn;
     char* configDir;
     FILE* imageFile;
@@ -103,6 +105,8 @@ class MVPClient
     int processGetMediaList(UCHAR* data, int length, ResponsePacket* rp);
     int processGetPicture(UCHAR* data, int length, ResponsePacket* rp);
     int processGetImageBlock(UCHAR* data, int length, ResponsePacket* rp);
+    int processGetLanguageList(UCHAR* data, int length, ResponsePacket* rp);
+    int processGetLanguageContent(UCHAR* data, int length, ResponsePacket* rp);
 
     void incClients();
     void decClients();