jadtfmt 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+