jadtfmt 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/extconf.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ if have_header('unicode/calendar.h') and have_header('unicode/smpdtfmt.h') and ( have_library('icuin') or have_library('icui18n') ) and have_library('icuuc')
4
+ create_makefile('jadtfmt')
5
+ end
data/ext/jadtfmt.c ADDED
@@ -0,0 +1,198 @@
1
+ /* */
2
+ #ifdef _WIN32
3
+ __declspec(dllexport) void Init_jadtfmt();
4
+ #endif
5
+
6
+ #include <string.h>
7
+
8
+ #ifndef _WIN32
9
+ #include <alloca.h>
10
+ #else
11
+ #include <malloc.h>
12
+ #endif
13
+
14
+ #include "ruby.h"
15
+ #include "jadtfmt.h"
16
+ #include "jadtfmt_icu.h"
17
+
18
+ #define VERSION "0.0.2"
19
+
20
+ #define DEFAULT_INT(n) (NIL_P(n) ? 0 : NUM2INT(n))
21
+
22
+ static VALUE JapaneseDateFormat;
23
+ static VALUE pph_E, pph_N, pph_n, pph_E_pattern, pph_N_pattern, pph_n_pattern;
24
+
25
+ /* */
26
+ static VALUE jadtfmt_initialize(int argc, VALUE *argv, VALUE self) {
27
+ struct jadtfmt *p;
28
+ VALUE pattern, kcode;
29
+ char *s_pattern = NULL;
30
+ int i_pattern_len = 0;
31
+ const char *s_kcode;
32
+ char *s_codepage;
33
+
34
+ rb_scan_args(argc, argv, "02", &pattern, &kcode);
35
+
36
+ if (!NIL_P(pattern)) {
37
+ Check_Type(pattern, T_STRING);
38
+ s_pattern = StringValuePtr(pattern);
39
+ i_pattern_len = RSTRING(pattern)->len;
40
+ }
41
+
42
+ if (!NIL_P(kcode)) {
43
+ Check_Type(kcode, T_STRING);
44
+ s_kcode = (RSTRING(kcode)->len > 0) ? StringValuePtr(kcode) : "UTF8";
45
+ } else {
46
+ s_kcode = rb_get_kcode();
47
+ }
48
+
49
+ switch (s_kcode[0]) {
50
+ case 'S': case 's': s_codepage = "Shift_JIS"; break;
51
+ case 'E': case 'e': s_codepage = "EUC-JP"; break;
52
+ case 'U': case 'u': s_codepage = "UTF-8"; break;
53
+ default: s_codepage = "UTF-8"; break;
54
+ }
55
+
56
+ Data_Get_Struct(self, struct jadtfmt, p);
57
+ p->fmt = jadtfmt_icu_new(s_pattern, s_codepage);
58
+ p->pattern_len = i_pattern_len;
59
+ p->codepage = s_codepage;
60
+
61
+ return Qnil;
62
+ }
63
+
64
+ /* */
65
+ static VALUE jadtfmt_format(VALUE self, VALUE src) {
66
+ struct jadtfmt *p;
67
+ VALUE year, month, day, hour, min, sec;
68
+ char *buf;
69
+
70
+ if (!rb_obj_is_instance_of(src, rb_cTime)) {
71
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(src)));
72
+ }
73
+
74
+ year = rb_funcall(src, rb_intern("year"), 0);
75
+ month = rb_funcall(src, rb_intern("month"), 0);
76
+ day = rb_funcall(src, rb_intern("day"), 0);
77
+ hour = rb_funcall(src, rb_intern("hour"), 0);
78
+ min = rb_funcall(src, rb_intern("min"), 0);
79
+ sec = rb_funcall(src, rb_intern("sec"), 0);
80
+
81
+ Data_Get_Struct(self, struct jadtfmt, p);
82
+
83
+ if (p->pattern_len > 0) {
84
+ int len = p->pattern_len * 3 + 16;
85
+ buf = alloca(len);
86
+ memset(buf, 0, len);
87
+ } else {
88
+ rb_raise(rb_eRuntimeError, "pattern is not set");
89
+ }
90
+
91
+ jadtfmt_icu_format(p->fmt, NUM2INT(year), NUM2INT(month), NUM2INT(day), NUM2INT(hour), NUM2INT(min), NUM2INT(sec), p->codepage, buf);
92
+
93
+ return rb_str_new2(buf);
94
+ }
95
+
96
+ /* */
97
+ static VALUE jadtfmt_format_attrs(int argc, VALUE *argv, VALUE self) {
98
+ struct jadtfmt *p;
99
+ VALUE year, month, day, hour, min, sec;
100
+ char *buf;
101
+
102
+ rb_scan_args(argc, argv, "15", &year, &month, &day, &hour, &min, &sec);
103
+
104
+ Data_Get_Struct(self, struct jadtfmt, p);
105
+
106
+ if (p->pattern_len > 0) {
107
+ int len = p->pattern_len * 3 + 16;
108
+ buf = alloca(len);
109
+ memset(buf, 0, len);
110
+ } else {
111
+ rb_raise(rb_eRuntimeError, "pattern is not set");
112
+ }
113
+
114
+ jadtfmt_icu_format(p->fmt, NUM2INT(year), DEFAULT_INT(month), DEFAULT_INT(day), DEFAULT_INT(hour), DEFAULT_INT(min), DEFAULT_INT(sec), p->codepage, buf);
115
+
116
+ return rb_str_new2(buf);
117
+ }
118
+
119
+ /* */
120
+ static VALUE jadtfmt_apply_pattern(VALUE self, VALUE pattern) {
121
+ struct jadtfmt *p;
122
+
123
+ Check_Type(pattern, T_STRING);
124
+ Data_Get_Struct(self, struct jadtfmt, p);
125
+ jadtfmt_icu_apply_pattern(p->fmt, StringValuePtr(pattern), p->codepage);
126
+ p->pattern_len = RSTRING(pattern)->len;
127
+
128
+ return Qnil;
129
+ }
130
+
131
+ /* */
132
+ static VALUE jadtfmt_Time_jadtfmt(VALUE self, VALUE pattern) {
133
+ VALUE jadtfmt = rb_funcall(JapaneseDateFormat, rb_intern("new"), 1, pattern);
134
+ return rb_funcall(jadtfmt, rb_intern("format"), 1, self);
135
+ }
136
+
137
+ /* */
138
+ static VALUE jadtfmt_Time_jastrftime(VALUE self, VALUE format) {
139
+ VALUE jadtfmt, replace;
140
+
141
+ Check_Type(format, T_STRING);
142
+ jadtfmt = rb_funcall(JapaneseDateFormat, rb_intern("new"), 0);
143
+
144
+ if (rb_funcall(format, rb_intern("include?"), 1, pph_E)) {
145
+ rb_funcall(jadtfmt, rb_intern("apply_pattern"), 1, pph_E_pattern);
146
+ replace = rb_funcall(jadtfmt, rb_intern("format"), 1, self);
147
+ format = rb_funcall(format, rb_intern("gsub"), 2, pph_E, replace);
148
+ }
149
+
150
+ if (rb_funcall(format, rb_intern("include?"), 1, pph_N)) {
151
+ rb_funcall(jadtfmt, rb_intern("apply_pattern"), 1, pph_N_pattern);
152
+ replace = rb_funcall(jadtfmt, rb_intern("format"), 1, self);
153
+ format = rb_funcall(format, rb_intern("gsub"), 2, pph_N, replace);
154
+ }
155
+
156
+ if (rb_funcall(format, rb_intern("include?"), 1, pph_n)) {
157
+ rb_funcall(jadtfmt, rb_intern("apply_pattern"), 1, pph_n_pattern);
158
+ replace = rb_funcall(jadtfmt, rb_intern("format"), 1, self);
159
+ format = rb_funcall(format, rb_intern("gsub"), 2, pph_n, replace);
160
+ }
161
+
162
+ return rb_funcall(self, rb_intern("strftime"), 1, format);
163
+ }
164
+
165
+ static void jadtfmt_free(struct jadtfmt *p) {
166
+ jadtfmt_icu_delete(p->fmt);
167
+ xfree(p);
168
+ }
169
+
170
+ static VALUE jadtfmt_alloc(VALUE klass) {
171
+ struct jadtfmt *p = ALLOC(struct jadtfmt);
172
+
173
+ p->fmt = NULL;
174
+ p->pattern_len = 0;
175
+ p->codepage = NULL;
176
+
177
+ return Data_Wrap_Struct(klass, 0, jadtfmt_free, p);
178
+ }
179
+
180
+ void Init_jadtfmt() {
181
+ JapaneseDateFormat = rb_define_class("JapaneseDateFormat", rb_cObject);
182
+ rb_define_const(JapaneseDateFormat, "VERSION", rb_str_new2(VERSION));
183
+ rb_define_alloc_func(JapaneseDateFormat, jadtfmt_alloc);
184
+ rb_define_private_method(JapaneseDateFormat, "initialize", jadtfmt_initialize, -1);
185
+ rb_define_method(JapaneseDateFormat, "format", jadtfmt_format, 1);
186
+ rb_define_method(JapaneseDateFormat, "format_attrs", jadtfmt_format_attrs, -1);
187
+ rb_define_method(JapaneseDateFormat, "apply_pattern", jadtfmt_apply_pattern, 1);
188
+
189
+ rb_define_method(rb_cTime, "jadtfmt", jadtfmt_Time_jadtfmt, 1);
190
+ rb_define_method(rb_cTime, "jastrftime", jadtfmt_Time_jastrftime, 1);
191
+
192
+ pph_E = rb_str_new2("%E");
193
+ pph_N = rb_str_new2("%N");
194
+ pph_n = rb_str_new2("%n");
195
+ pph_E_pattern = rb_str_new2("G");
196
+ pph_N_pattern = rb_str_new2("yy");
197
+ pph_n_pattern = rb_str_new2("y");
198
+ }
data/ext/jadtfmt.h ADDED
@@ -0,0 +1,10 @@
1
+ #ifndef __JADTFMT_H__
2
+ #define __JADTFMT_H__
3
+
4
+ struct jadtfmt {
5
+ void *fmt;
6
+ int pattern_len;
7
+ char *codepage;
8
+ };
9
+
10
+ #endif
@@ -0,0 +1,76 @@
1
+ #include <string>
2
+ #include <iostream>
3
+ #include "unicode/calendar.h"
4
+ #include "unicode/smpdtfmt.h"
5
+
6
+ #include "ruby.h"
7
+
8
+ #define JADTFMT_LOCALE "ja_JP_TRADITIONAL"
9
+ #define RAISE_ICU_ERRER(s) do { rb_raise(rb_eRuntimeError, u_errorName(s)); } while(0)
10
+ #define Chack_ICU_ERROR(s) do { if (U_FAILURE(s)) { RAISE_ICU_ERRER(s); } } while(0)
11
+
12
+ extern "C" {
13
+ void *jadtfmt_icu_new(const char *pattern, const char *codepage);
14
+ void jadtfmt_icu_delete(void *p);
15
+ void jadtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst);
16
+ void jadtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage);
17
+ }
18
+
19
+ void *jadtfmt_icu_new(const char *pattern, const char *codepage) {
20
+ UErrorCode status = U_ZERO_ERROR;
21
+ SimpleDateFormat *fmt;
22
+ Calendar *cal;
23
+
24
+ if (pattern) {
25
+ fmt = new SimpleDateFormat(UnicodeString(pattern), status);
26
+ } else {
27
+ fmt = new SimpleDateFormat(status);
28
+ }
29
+
30
+ if (U_FAILURE(status)) {
31
+ delete fmt;
32
+ RAISE_ICU_ERRER(status);
33
+ }
34
+
35
+ cal = Calendar::createInstance(JADTFMT_LOCALE, status);
36
+
37
+ if (U_FAILURE(status)) {
38
+ delete cal;
39
+ delete fmt;
40
+ RAISE_ICU_ERRER(status);
41
+ }
42
+
43
+ fmt->adoptCalendar(cal);
44
+
45
+ return fmt;
46
+ }
47
+
48
+ void jadtfmt_icu_delete(void *p) {
49
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
50
+ delete fmt;
51
+ }
52
+
53
+ void jadtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst) {
54
+ UErrorCode status = U_ZERO_ERROR;
55
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
56
+ Calendar *cal = Calendar::createInstance(JADTFMT_LOCALE, status);
57
+ Chack_ICU_ERROR(status);
58
+
59
+ cal->set(year - 1988, month - 1, date, hour, minute, second);
60
+ UDate now = cal->getTime(status);
61
+ Chack_ICU_ERROR(status);
62
+
63
+ UnicodeString buf;
64
+ fmt->format(now, buf);
65
+
66
+ std::string conv(buf.extract(0, buf.length(), 0, codepage), '\0');
67
+ buf.extract(0, buf.length(), &conv[0], codepage);
68
+ memcpy(dst, conv.c_str(), conv.size());
69
+
70
+ delete cal;
71
+ }
72
+
73
+ void jadtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage) {
74
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
75
+ fmt->applyPattern(UnicodeString(pattern, codepage));
76
+ }
data/ext/jadtfmt_icu.h ADDED
@@ -0,0 +1,9 @@
1
+ #ifndef __JADTFMT_ICU_H__
2
+ #define __JADTFMT_ICU_H__
3
+
4
+ void *jadtfmt_icu_new(const char *pattern, const char *codepage);
5
+ void jadtfmt_icu_delete(void *p);
6
+ void jadtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst);
7
+ void jadtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage);
8
+
9
+ #endif
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jadtfmt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - winebarrel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-17 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: sgwr_dts@yahoo.co.jp
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - ext/jadtfmt.c
24
+ files:
25
+ - ext/jadtfmt.c
26
+ - ext/jadtfmt.h
27
+ - ext/jadtfmt_icu.cpp
28
+ - ext/jadtfmt_icu.h
29
+ - ext/extconf.rb
30
+ has_rdoc: true
31
+ homepage: http://rua.rubyforge.org
32
+ post_install_message:
33
+ rdoc_options:
34
+ - --title
35
+ - JapaneseDateFormat - formatting a Time to the japanese time string using ICU.
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project: jadtfmt
53
+ rubygems_version: 1.0.1
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: formatting a Time to the japanese time string using ICU.
57
+ test_files: []
58
+