00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <nds.h>
00021 #include <stdio.h>
00022 #include <malloc.h>
00023 #include <fat.h>
00024 #include <unistd.h>
00025
00026 #include "efs_lib.h"
00027
00028 #include <string>
00029 #include <vector>
00030 #include <cstring>
00031 #include <cstdlib>
00032
00033 #include "utf8.h"
00034
00035 #include "definitions.h"
00036 #include "card.h"
00037 #include "xmlparser.h"
00038
00039 using std::string;
00040
00041 XMLParser::XMLParser()
00042 {
00043 file_ = NULL;
00044 }
00045
00046 void XMLParser::Init(const string& file_path)
00047 {
00048 if (file_)
00049 {
00050 if (file_path == file_path_)
00051
00052 fseek(file_, 0L, SEEK_SET);
00053 else
00054 {
00055 fclose(file_);
00056 file_ = fopen(file_path.c_str(),"rb");
00057 }
00058 }
00059 else
00060 file_ = fopen(file_path.c_str(),"rb");
00061
00062 file_path_= file_path;
00063 char buff [BUFFER_SIZE];
00064 if (file_ && !feof(file_))
00065 {
00066 fgets(buff, BUFFER_SIZE, file_);
00067 string buffer(buff);
00068 if (buffer.compare("<?xml version=\"1.0\"?>"))
00069 {
00070 xml_version_ = "1.0";
00071 if (!feof(file_)){
00072 fgets(buff, BUFFER_SIZE, file_);
00073 int position = 0;
00074 if (find("<package", buff, position))
00075 {
00076 package_name_ = attribute_value ("name", buff, position);
00077 package_records_ = atoi(attribute_value("records", buff, position).c_str());
00078 package_format_ = attribute_value ("format", buff, position);
00079 package_license_ = attribute_value ("license", buff, position);
00080
00081 file_cursor_ = new fpos_t [package_records_];
00082 int auxpos = 0;
00083 if (find("kanji", package_format_.c_str(), auxpos))
00084 file_format_ = XML_KANJI;
00085 if (find("vocabulary", package_format_.c_str(), auxpos))
00086 file_format_ = XML_VOCABULARY;
00087 if (file_format_ == XML_KANJI)
00088 {
00089 grade_ = new std::vector<int> [MAX_GRADE];
00090 strokes_ = new std::vector<int> [MAX_STROKES];
00091 q_grade_min_ = q_grade_max_ = q_strokes_min_ = q_strokes_max_ = 0;
00092 }
00093 GenerateIndexes();
00094 }
00095
00096 }
00097
00098 }
00099
00100 }
00101
00102 }
00103
00104 Card XMLParser::card (unsigned index, unsigned grade_min, unsigned grade_max,
00105 unsigned strokes_min, unsigned strokes_max)
00106 {
00107 Card read_card;
00108 int file_index = GetIndex(index, grade_min, grade_max, strokes_min, strokes_max);
00109 if (file_index && file_index <= package_records_)
00110 {
00111 char buff [BUFFER_SIZE];
00112 fpos_t fposition = file_cursor_[file_index-1];
00113 fsetpos(file_, &fposition);
00114
00115
00116 fgets(buff, BUFFER_SIZE, file_);
00117
00118 int position = 0;
00119
00120 read_card.Init(file_index,
00121 attribute_value(" symbol",buff, position),
00122 attribute_value(" reading",buff, position),
00123 attribute_value(" reading2",buff, position),
00124 attribute_value(" translation",buff, position),
00125 attribute_value(" example_symbol",buff, position),
00126 attribute_value(" example_reading",buff, position),
00127 attribute_value(" example_translation",buff, position)
00128 );
00129 }
00130
00131 return read_card;
00132 }
00133
00134 int XMLParser::package_records () const
00135 {
00136 return package_records_;
00137 }
00138
00139 int XMLParser::QueryResultSize (unsigned grade_min, unsigned grade_max,
00140 unsigned strokes_min, unsigned strokes_max)
00141 {
00142 QueryResult(grade_min, grade_max, strokes_min, strokes_max);
00143
00144 return query_result_.size();
00145 }
00146
00147 string XMLParser::attribute_value(const char* name, const char* buffer,
00148 int& position)
00149 {
00150 string result;
00151 if (find(name, buffer, position))
00152 {
00153 position += strlen(name);
00154 int start = position + 2;
00155
00156 for (position += 2; buffer[position] != '\"' && buffer[position] != '\0'
00157 && position < BUFFER_SIZE; ++position);
00158 if (buffer[position] == '\"')
00159 {
00160
00161 result = string(buffer+start, position-start);
00162 }
00163 }
00164
00165 ++position;
00166
00167 return result;
00168 }
00169
00170 void XMLParser::GenerateIndexes()
00171 {
00172 char buff [BUFFER_SIZE];
00173 fseek(file_, 0L, SEEK_SET);
00174 fgets(buff, BUFFER_SIZE, file_);
00175 fgets(buff, BUFFER_SIZE, file_);
00176 for (int i = 0; i < package_records_ && !feof(file_); ++i)
00177 {
00178 fpos_t position;
00179 int auxpos = 0;
00180 fgetpos(file_, &position);
00181 fgets(buff, BUFFER_SIZE, file_);
00182 file_cursor_[i] = position;
00183 if (file_format_ == XML_KANJI)
00184 {
00185 grade_[atoi(attribute_value(" grade", buff, auxpos).c_str())-1].
00186 push_back(i);
00187 strokes_[atoi(attribute_value(" strokes", buff, auxpos).c_str())-1].
00188 push_back(i);
00189 }
00190 }
00191 }
00192
00193 unsigned XMLParser::GetIndex(unsigned index, unsigned grade_min,
00194 unsigned grade_max, unsigned strokes_min,
00195 unsigned strokes_max)
00196 {
00197 unsigned final_index;
00198 if (file_format_ == XML_KANJI)
00199 {
00200 QueryResult(grade_min, grade_max, strokes_min, strokes_max);
00201
00202 --index;
00203 if (index < query_result_.size())
00204 final_index = query_result_[index]+1;
00205 else
00206 final_index = 0;
00207 }
00208 else
00209 final_index = index;
00210
00211 return final_index;
00212 }
00213
00214 void XMLParser::QueryResult (unsigned grade_min, unsigned grade_max,
00215 unsigned strokes_min, unsigned strokes_max)
00216 {
00217
00218
00219 if (grade_min != q_grade_min_ || grade_max != q_grade_max_ ||
00220 strokes_min != q_strokes_min_ || strokes_max != q_strokes_max_)
00221 {
00222 q_grade_min_ = grade_min, q_grade_max_ = grade_max;
00223 q_strokes_min_ = strokes_min, q_strokes_max_ = strokes_max;
00224 query_result_.clear();
00225 --grade_min;
00226 --strokes_min;
00227 for (unsigned i = grade_min; i < grade_max; ++i)
00228 for (unsigned j = strokes_min; j < strokes_max; ++j)
00229 for (unsigned k = 0; k < grade_[i].size(); ++k)
00230 {
00231 unsigned l = 0;
00232 for (; l < strokes_[j].size() &&
00233 strokes_[j][l] != grade_[i][k]; ++l);
00234
00235 if (l < strokes_[j].size())
00236 query_result_.push_back(grade_[i][k]);
00237 }
00238 }
00239 }
00240
00241 XMLParser::~XMLParser ()
00242 {
00243 fclose(file_);
00244 }
00245