1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2005 Takuro Ashie
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "scim_anthy_style_file.h"
22 using namespace scim_anthy;
24 const int MAX_LINE_LENGTH = 4096;
27 escape (const String &str)
31 for (unsigned int i = 0; i < dest.size (); i++) {
32 if (dest[i] == '#' || // for comment
33 dest[i] == '\\' || // for backslash itself
34 dest[i] == '=' || // for separatort
35 dest[i] == '[' || dest[i] == ']' || // for section
36 dest[i] == ',' || // for array
37 dest[i] == ' ' || dest[i] == '\t') // for space
39 dest.insert (i, "\\");
48 unescape (const String &str)
52 for (unsigned int i = 0; i < dest.size (); i++) {
53 if (dest[i] == '\\') {
55 if (i < dest.size () && dest[i] == '\\')
63 StyleLine::StyleLine (StyleFile *style_file, String line)
64 : m_style_file (style_file),
66 m_type (SCIM_ANTHY_STYLE_LINE_UNKNOWN)
70 StyleLine::StyleLine (StyleFile *style_file, String key, String value)
71 : m_style_file (style_file),
72 m_line (escape (key) + String ("=")),
73 m_type (SCIM_ANTHY_STYLE_LINE_KEY)
78 StyleLine::StyleLine (StyleFile *style_file, String key,
79 std::vector<String> &value)
80 : m_style_file (style_file),
81 m_line (escape (key) + String("=")),
82 m_type (SCIM_ANTHY_STYLE_LINE_KEY)
84 set_value_array (value);
87 StyleLine::~StyleLine ()
92 StyleLine::get_type (void)
94 if (m_type != SCIM_ANTHY_STYLE_LINE_UNKNOWN)
97 unsigned int spos, epos;
99 spos < m_line.length () && isspace (m_line[spos]);
101 if (m_line.length() > 0) {
102 for (epos = m_line.length () - 1;
103 epos >= 0 && isspace (m_line[epos]);
109 if (m_line.length() == 0 || spos >= m_line.length()) {
110 m_type = SCIM_ANTHY_STYLE_LINE_SPACE;
113 } else if (m_line[spos] == '#') {
114 m_type = SCIM_ANTHY_STYLE_LINE_COMMENT;
117 } else if (m_line[spos] == '[' && m_line[epos] == ']') {
118 m_type = SCIM_ANTHY_STYLE_LINE_SECTION;
122 m_type = SCIM_ANTHY_STYLE_LINE_KEY;
127 StyleLine::get_section (String §ion)
129 if (get_type () != SCIM_ANTHY_STYLE_LINE_SECTION)
132 unsigned int spos, epos;
134 spos < m_line.length () && isspace (m_line[spos]);
136 for (epos = m_line.length () - 1;
137 epos >= 0 && isspace (m_line[epos]);
142 section = m_line.substr (spos, epos - spos);
150 StyleLine::get_key (String &key)
152 if (get_type () != SCIM_ANTHY_STYLE_LINE_KEY)
155 unsigned int spos, epos;
157 spos < m_line.length () && isspace (m_line[spos]);
161 epos < m_line.length ();
164 if (m_line[epos] == '\\') {
168 if (m_line[epos] == '=') {
174 epos >= spos && isspace (m_line[epos]);
176 if (!isspace(m_line[epos]))
179 if (spos >= 0 && spos < epos && epos <= m_line.length ()) {
180 key = unescape (m_line.substr (spos, epos - spos));
188 get_value_position (String &str)
192 spos < str.length ();
195 if (str[spos] == '\\') {
199 if (str[spos] == '=') {
203 if (spos >= str.length ())
208 spos < str.length () && isspace(str[spos]);
215 StyleLine::get_value (String &value)
217 if (get_type () != SCIM_ANTHY_STYLE_LINE_KEY)
220 unsigned int spos = get_value_position (m_line);
221 unsigned int epos = m_line.length ();
223 value = unescape (m_line.substr (spos, epos - spos));
229 StyleLine::set_value (String value)
233 m_line = escape (key) + String ("=") + escape (value);
237 StyleLine::get_value_array (std::vector<String> &value)
239 if (get_type () != SCIM_ANTHY_STYLE_LINE_KEY)
242 unsigned int spos = get_value_position (m_line);
243 unsigned int epos = m_line.length ();
245 unsigned int head_of_element = spos;
246 for (unsigned int i = spos; i <= epos; i++) {
247 if (i < epos && m_line[i] == '\\') {
252 if (i == epos || m_line[i] == ',') {
254 if (head_of_element == epos)
257 str = unescape (m_line.substr (head_of_element,
258 i - head_of_element));
259 value.push_back (str);
260 head_of_element = i + 1;
268 StyleLine::set_value_array (std::vector<String> &value)
273 m_line = escape (key) + String ("=");
274 for (unsigned int i = 0; i < value.size (); i++) {
277 m_line += escape (value[i]);
282 StyleFile::StyleFile ()
284 setup_default_entries ();
287 StyleFile::~StyleFile ()
292 StyleFile::load (const char *filename)
295 setup_default_entries ();
296 m_filename = filename;
298 std::ifstream in_file (filename);
304 m_sections.push_back (StyleLines ());
305 StyleLines *section = &m_sections[0];
306 unsigned int section_id = 0;
308 char buf[MAX_LINE_LENGTH];
310 in_file.getline (buf, MAX_LINE_LENGTH);
315 m_iconv.convert (dest, buf);
316 StyleLine line (this, utf8_wcstombs (dest));
317 StyleLineType type = line.get_type ();
319 if (type == SCIM_ANTHY_STYLE_LINE_SECTION) {
320 m_sections.push_back (StyleLines ());
321 section = &m_sections.back();
325 section->push_back (line);
327 if (section_id == 0) {
330 if (key == "FormatVersion") {
331 line.get_value (m_format_version);
333 } else if (key == "Encoding") {
334 line.get_value (m_encoding);
335 bool success = m_iconv.set_encoding (m_encoding);
337 m_iconv.set_encoding ("UTF-8");
339 } else if (key == "Title") {
340 line.get_value (m_title);
342 } else if (key == "Version") {
343 line.get_value (m_version);
346 } while (!in_file.eof ());
350 m_filename = filename;
356 StyleFile::save (const char *filename)
358 std::ofstream out_file (filename);
362 StyleSections::iterator it;
363 for (it = m_sections.begin (); it != m_sections.end (); it++) {
364 StyleLines::iterator lit;
365 for (lit = it->begin (); lit != it->end (); lit++) {
367 lit->get_line (line);
368 m_iconv.convert (dest, utf8_mbstowcs (line));
369 out_file << dest.c_str () << std::endl;
375 m_filename = filename;
381 StyleFile::clear (void)
383 m_filename = String ();
384 m_format_version = String ();
385 m_encoding = String ();
387 m_version = String ();
392 StyleFile::get_encoding (void)
398 StyleFile::get_title (void)
404 StyleFile::get_file_name (void)
410 StyleFile::get_string (String &value, String section, String key)
412 StyleSections::iterator it;
413 for (it = m_sections.begin (); it != m_sections.end (); it++) {
414 if (it->size () <= 0)
418 (*it)[0].get_section (s);
423 StyleLines::iterator lit;
424 for (lit = it->begin (); lit != it->end (); lit++) {
427 lit->get_value (value);
437 StyleFile::get_string (WideString &value, String section, String key)
440 bool success = get_string (str, section, key);
443 value = utf8_mbstowcs (str);
448 StyleFile::get_string_array (std::vector<String> &value,
449 String section, String key)
451 StyleLines *lines = find_section (section);
456 StyleLines::iterator lit;
457 for (lit = lines->begin (); lit != lines->end (); lit++) {
461 lit->get_value_array (value);
470 StyleFile::get_string_array (std::vector<WideString> &value,
471 String section, String key)
473 std::vector<String> array;
474 bool success = get_string_array (array, section, key);
478 std::vector<String>::iterator it;
479 for (it = array.begin (); it != array.end (); it++)
480 value.push_back (utf8_mbstowcs (*it));
485 StyleFile::set_string (String section, String key, String value)
487 StyleLines *lines = find_section (section);
490 StyleLines::iterator lit, last = lines->begin () + 1;
491 for (lit = last; lit != lines->end (); lit++) {
492 StyleLineType type = lit->get_type ();
493 if (type != SCIM_ANTHY_STYLE_LINE_SPACE)
499 // replace existing entry
500 if (k.length () > 0 && k == key) {
501 lit->set_value (value);
506 // append new entry if no mathced entry exists.
507 lines->insert (last, StyleLine (this, key, value));
510 StyleLines &newsec = append_new_section (section);
513 newsec.push_back (StyleLine (this, key, value));
518 StyleFile::set_string (String section, String key, WideString value)
520 set_string (section, key, utf8_wcstombs (value));
524 StyleFile::set_string_array (String section, String key,
525 std::vector<String> &value)
527 StyleLines *lines = find_section (section);
530 StyleLines::iterator lit, last = lines->begin () + 1;
531 for (lit = last; lit != lines->end (); lit++) {
532 StyleLineType type = lit->get_type ();
533 if (type != SCIM_ANTHY_STYLE_LINE_SPACE)
539 // replace existing entry
540 if (k.length () > 0 && k == key) {
541 lit->set_value_array (value);
546 // append new entry if no mathced entry exists.
547 lines->insert (last + 1, StyleLine (this, key, value));
550 StyleLines &newsec = append_new_section (section);
553 newsec.push_back (StyleLine (this, key, value));
558 StyleFile::set_string_array (String section, String key,
559 std::vector<WideString> &value)
561 std::vector<String> array;
562 std::vector<WideString>::iterator it;
563 for (it = value.begin (); it != value.end (); it++)
564 array.push_back (utf8_wcstombs (*it));
565 set_string_array (section, key, array);
569 StyleFile::get_section_list (StyleSections §ions)
571 sections = m_sections;
576 StyleFile::get_entry_list (StyleLines &lines, String section)
578 StyleSections::iterator it;
579 for (it = m_sections.begin (); it != m_sections.end (); it++) {
580 if (it->size () <= 0)
584 (*it)[0].get_section (s);
595 StyleFile::get_key_list (std::vector<String> &keys, String section)
597 StyleLines *lines = find_section (section);
601 StyleLines::iterator lit;
602 for (lit = lines->begin (); lit != lines->end (); lit++) {
603 if (lit->get_type () != SCIM_ANTHY_STYLE_LINE_KEY)
608 keys.push_back (key);
614 StyleFile::delete_key (String section, String key)
616 StyleLines *lines = find_section (section);
621 StyleLines::iterator lit;
622 for (lit = lines->begin (); lit != lines->end (); lit++) {
633 StyleFile::delete_section (String section)
635 StyleSections::iterator it;
636 for (it = m_sections.begin (); it != m_sections.end (); it++) {
637 if (it->size () <= 0)
640 StyleLines::iterator lit;
642 (*it)[0].get_section (s);
644 m_sections.erase (it);
651 StyleFile::get_key2kana_table (String section)
653 Key2KanaTable *table = NULL;
655 std::vector<String> keys;
656 bool success = get_key_list (keys, section);
658 table = new Key2KanaTable (utf8_mbstowcs (get_title ()));
659 std::vector<String>::iterator it;
660 for (it = keys.begin (); it != keys.end (); it++) {
661 std::vector<String> array;
662 get_string_array (array, section, *it);
663 table->append_rule (*it, array);
671 StyleFile::setup_default_entries (void)
673 m_encoding = "UTF-8";
674 m_title = "User defined";
675 m_iconv.set_encoding (m_encoding);
676 m_sections.push_back (StyleLines ());
678 m_sections.push_back (StyleLines ());
679 StyleLines &newsec = m_sections.back ();
680 String str = String ("Encoding") + String ("=") + escape (m_encoding);
681 newsec.push_back (StyleLine (this, str.c_str ()));
682 str = String ("Title") + String ("=") + escape (m_title);
683 newsec.push_back (StyleLine (this, str.c_str ()));
687 StyleFile::find_section (const String §ion)
690 StyleSections::iterator it;
691 for (it = m_sections.begin (); it != m_sections.end (); it++) {
692 if (it->size () <= 0)
696 (*it)[0].get_section (s);
706 StyleFile::append_new_section (const String §ion)
708 // append space before new section
709 if (!m_sections.empty()) {
710 StyleLines &sec = m_sections.back ();
712 sec.back().get_type() != SCIM_ANTHY_STYLE_LINE_SPACE)
714 sec.push_back (StyleLine (this, ""));
719 // append new section
721 m_sections.push_back (StyleLines ());
722 StyleLines &newsec = m_sections.back ();
725 String str = String ("[") + String (section) + String ("]");
726 newsec.push_back (StyleLine (this, str.c_str ()));