diff --git a/Bakeneko/Bakeneko.vcxproj b/Bakeneko/Bakeneko.vcxproj
index 7c2094c..8018076 100644
--- a/Bakeneko/Bakeneko.vcxproj
+++ b/Bakeneko/Bakeneko.vcxproj
@@ -47,7 +47,7 @@
false
- true
+ false
@@ -72,6 +72,7 @@
WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
MultiThreaded
true
+ None
Windows
diff --git a/Bakeneko/bakeneko/api/jisho.cpp b/Bakeneko/bakeneko/api/jisho.cpp
index 2ca6b2e..fa74eb0 100644
--- a/Bakeneko/bakeneko/api/jisho.cpp
+++ b/Bakeneko/bakeneko/api/jisho.cpp
@@ -41,19 +41,29 @@ std::string JishoData::toString() {
return dataString;
}
-JishoData JishoAPI::lookUp(std::string const& word) {
- JSONBlob json = m_json.parse(m_http.get(word));
-
- //@TODO: JSON 1:n data
- JishoData data;
- data.word = json.get(1, (std::string)"japanese", (std::string)"word");
- data.fields.push_back( json.get(1, (std::string)"japanese", (std::string)"reading") );
- data.fields.push_back( utf::fromUTF32To8( jp::addRuby( utf::fromUTF8to32(data.word), utf::fromUTF8to32(data.fields[0]) ) ) );
- data.fields.push_back( json.get(1, (std::string)"parts_of_speech") );
- data.fields.push_back( json.get(1, (std::string)"english_definitions") );
- //@TODO: additional fields...
-
- return data;
+std::vector JishoAPI::lookUp(std::string const& word) {
+ std::vector result;
+ std::vector relevant = { 1 };
+
+ JSONBlob json = m_json.parse(m_http.get(word));
+
+ //@TODO: Let user decide what fields + which results to grab
+ if (json.m_commonIdx.size() != 0)
+ relevant = json.m_commonIdx;
+
+ for (int i : relevant) {
+ JishoData jishoData;
+ jishoData.word = json.get(i, API_KEY_JP, API_ELEM_WORD, AccessMode::First);
+ jishoData.fields.push_back(json.get(i, API_KEY_JP, API_ELEM_READ, AccessMode::First));
+ jishoData.fields.push_back(utf::fromUTF32To8(jp::addRuby(utf::fromUTF8to32(jishoData.word), utf::fromUTF8to32(jishoData.fields[0]))));
+ jishoData.fields.push_back(json.get(i, API_KEY_POS, AccessMode::First));
+ jishoData.fields.push_back(json.get(i, API_KEY_ENG));
+ //@TODO: additional fields...
+
+ result.push_back(jishoData.toData());
+ }
+
+ return result;
}
}; // namespace bakeneko
\ No newline at end of file
diff --git a/Bakeneko/bakeneko/api/jisho.h b/Bakeneko/bakeneko/api/jisho.h
index faef361..19983eb 100644
--- a/Bakeneko/bakeneko/api/jisho.h
+++ b/Bakeneko/bakeneko/api/jisho.h
@@ -25,12 +25,18 @@
#include "json.h"
#include "../data/data.h"
-const std::string API_HOSTNAME = "jisho.org";
-const std::string API_PATH = "/api/v1/search/words?keyword=";
+const std::string API_HOSTNAME = "jisho.org";
+const std::string API_PATH = "/api/v1/search/words?keyword=";
+
+const std::string API_KEY_JP = "japanese";
+const std::string API_ELEM_WORD = "word";
+const std::string API_ELEM_READ = "reading";
+const std::string API_KEY_POS = "parts_of_speech";
+const std::string API_KEY_ENG = "english_definitions";
namespace bakeneko {
-class JishoData {
+class JishoData {
public:
std::string word = "";
std::vector fields;
@@ -47,7 +53,7 @@ class JishoAPI {
JishoAPI(){ m_http.init(API_HOSTNAME, API_PATH); };
~JishoAPI() { };
- JishoData lookUp(std::string const& word);
+ std::vector lookUp(std::string const& word);
private:
JSONParserLite m_json;
diff --git a/Bakeneko/bakeneko/api/json.cpp b/Bakeneko/bakeneko/api/json.cpp
index d38ea9b..84f4c2b 100644
--- a/Bakeneko/bakeneko/api/json.cpp
+++ b/Bakeneko/bakeneko/api/json.cpp
@@ -20,39 +20,81 @@
#include "json.h"
#include
+#include
#include
+#include "..\util\unicode.h"
namespace bakeneko{
void JSONBlob::add(int index, std::string const& key, std::string value) {
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
+ value.erase(std::remove(value.begin(), value.end(), '\t'), value.end());
+ value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
+ value.erase(std::remove(value.begin(), value.end(), '\r'), value.end());
+
m_data[index][key].push_back(value);
}
- std::string JSONBlob::get(int pos, std::string const& key, std::string const& elem) {
+ std::string JSONBlob::get(int pos, std::string const& key, std::string const& elem, AccessMode mode, int item) {
+ if (mode == AccessMode::Exact && item == NULL) return ""; //usage error
+
if (m_data.find(pos) != m_data.end()) {
if (m_data.at(pos).find(key) != m_data.at(pos).end()) {
- return findElem(m_data.at(pos).at(key)[0], elem);
+ return findElem(m_data.at(pos).at(key)[0], elem, mode, item);
}
}
return "";
}
- std::string JSONBlob::get(int pos, std::string const& key) {
+ std::string JSONBlob::get(int pos, std::string const& key, AccessMode mode, int item) {
+ if (mode == AccessMode::Exact && item == NULL) return ""; //usage error
+
if (m_data.find(pos) != m_data.end()) {
if (m_data.at(pos).find(key) != m_data.at(pos).end()) {
- return m_data.at(pos).at(key)[0];
+ switch (mode) {
+ case AccessMode::First:
+ item = 1;
+ //intentional fallthrough
+
+ case AccessMode::Exact:
+ if (item > m_data.at(pos).at(key).size()) {
+ return "";
+ } else {
+ return m_data.at(pos).at(key)[item - 1];
+ }
+
+ case AccessMode::All:
+ if (m_data.at(pos).at(key).size() == 1) {
+ return m_data.at(pos).at(key)[0];
+ } else {
+ static std::string br = utf::fromWidetoUTF8(L"
");
+ std::ostringstream os;
+
+ for (int i = 0; i < m_data.at(pos).at(key).size(); ++i) {
+ os << m_data.at(pos).at(key)[i];
+ if (i != m_data.at(pos).at(key).size() - 1)
+ os << br;
+ }
+ return os.str();
+ }
+ }
}
}
return "";
}
- std::string JSONBlob::findElem(std::string jsonStr, std::string elem) {
- if (elem == "") return jsonStr;
+ std::string JSONBlob::findElem(std::string jsonStr, std::string elem, AccessMode mode, int item) {
+ if (elem == "") return jsonStr;
+ if (mode == AccessMode::All) return ""; //not required right now
+ if (mode == AccessMode::Exact && item == NULL) return ""; //usage error
+ if (mode == AccessMode::First) item = 1;
std::regex rgx(elem + ":([^,]+),?");
std::smatch match;
+ int counter = 0;
+
while (std::regex_search(jsonStr, match, rgx)) {
- return match[1];
+ counter++;
+ if (item == counter) return match[1];
}
return "";
@@ -63,31 +105,37 @@ namespace bakeneko{
const std::string is_common = "{\"is_common\":";
const std::regex rgx("\"(\\w+)\":\\[([^\\[\\]]+)\\]");
- int begin = 0;
- int end = 0;
- int dataCounter = 0;
+ int begin = 0;
+ int end = 0;
+ int dataCounter = 0;
+ std::string common = "";
JSONBlob blob;
- while (1) {
+ for (;;) {
std::string data = "";
std::smatch match;
if (end > begin) begin = end;
if (begin == 0) {
- //find first word
+ //find first result
begin = json.find(is_common, begin);
if (begin == std::string::npos) break;
}
- //find next word
+ //find next result
end = json.find(is_common, begin + is_common.length());
if (end == std::string::npos) end = json.length();
if (end <= begin) break; //EOS
- //only extract common words for now
- if (json.substr(begin+is_common.length(),4) != "true") continue;
+ //optimistically increment dataCounter
+ dataCounter++;
+
+ //index common results
+ if (json.substr(begin + is_common.length(), 4) == "true") {
+ blob.m_commonIdx.push_back(dataCounter);
+ }
data.assign(json, begin, end - begin);
@@ -95,9 +143,6 @@ namespace bakeneko{
data.erase(std::remove(data.begin(), data.end(), '{'), data.end());
data.erase(std::remove(data.begin(), data.end(), '}'), data.end());
- //optimistically increment dataCounter
- dataCounter++;
-
//add data from non-empty JSON arrays to blob
while(std::regex_search(data, match, rgx)) {
blob.add(dataCounter, match[1], match[2]);
diff --git a/Bakeneko/bakeneko/api/json.h b/Bakeneko/bakeneko/api/json.h
index 85f6b90..92860a1 100644
--- a/Bakeneko/bakeneko/api/json.h
+++ b/Bakeneko/bakeneko/api/json.h
@@ -26,18 +26,21 @@
#include