smpdtfmt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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('smpdtfmt')
5
+ end
@@ -0,0 +1,212 @@
1
+ /* */
2
+ #ifdef _WIN32
3
+ __declspec(dllexport) void Init_smpdtfmt();
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 "smpdtfmt.h"
16
+ #include "smpdtfmt_icu.h"
17
+
18
+ #define VERSION "0.0.1"
19
+
20
+ #define DEFAULT_INT(n) (NIL_P(n) ? 0 : NUM2INT(n))
21
+
22
+ static VALUE rb_cSimpleDateFormat;
23
+
24
+ /* */
25
+ static VALUE smpdtfmt_initialize(int argc, VALUE *argv, VALUE self) {
26
+ struct smpdtfmt *p;
27
+ VALUE pattern, kcode;
28
+ char *s_pattern = NULL;
29
+ int i_pattern_len = 0;
30
+ const char *s_kcode;
31
+ char *s_codepage;
32
+
33
+ rb_scan_args(argc, argv, "02", &pattern, &kcode);
34
+
35
+ if (!NIL_P(pattern)) {
36
+ Check_Type(pattern, T_STRING);
37
+ s_pattern = StringValuePtr(pattern);
38
+ i_pattern_len = RSTRING(pattern)->len;
39
+ }
40
+
41
+ if (!NIL_P(kcode)) {
42
+ Check_Type(kcode, T_STRING);
43
+ s_kcode = (RSTRING(kcode)->len > 0) ? StringValuePtr(kcode) : "UTF8";
44
+ } else {
45
+ s_kcode = rb_get_kcode();
46
+ }
47
+
48
+ switch (s_kcode[0]) {
49
+ case 'S': case 's': s_codepage = "Shift_JIS"; break;
50
+ case 'E': case 'e': s_codepage = "EUC-JP"; break;
51
+ case 'U': case 'u': s_codepage = "UTF-8"; break;
52
+ default: s_codepage = "UTF-8"; break;
53
+ }
54
+
55
+ Data_Get_Struct(self, struct smpdtfmt, p);
56
+ p->fmt = smpdtfmt_icu_new(s_pattern, s_codepage);
57
+ p->pattern_len = i_pattern_len;
58
+ p->codepage = s_codepage;
59
+
60
+ return Qnil;
61
+ }
62
+
63
+ /* */
64
+ static VALUE smpdtfmt_format(VALUE self, VALUE src) {
65
+ struct smpdtfmt *p;
66
+ VALUE year, month, day, hour, min, sec;
67
+ char *buf;
68
+
69
+ if (!rb_obj_is_instance_of(src, rb_cTime)) {
70
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(src)));
71
+ }
72
+
73
+ year = rb_funcall(src, rb_intern("year"), 0);
74
+ month = rb_funcall(src, rb_intern("month"), 0);
75
+ day = rb_funcall(src, rb_intern("day"), 0);
76
+ hour = rb_funcall(src, rb_intern("hour"), 0);
77
+ min = rb_funcall(src, rb_intern("min"), 0);
78
+ sec = rb_funcall(src, rb_intern("sec"), 0);
79
+
80
+ Data_Get_Struct(self, struct smpdtfmt, p);
81
+
82
+ if (p->pattern_len > 0) {
83
+ int len = p->pattern_len * 3 + 16;
84
+ buf = alloca(len);
85
+ memset(buf, 0, len);
86
+ } else {
87
+ rb_raise(rb_eRuntimeError, "pattern is not set");
88
+ }
89
+
90
+ smpdtfmt_icu_format(p->fmt, NUM2INT(year), NUM2INT(month), NUM2INT(day), NUM2INT(hour), NUM2INT(min), NUM2INT(sec), p->codepage, buf);
91
+
92
+ return rb_str_new2(buf);
93
+ }
94
+
95
+ /* */
96
+ static VALUE smpdtfmt_format_attrs(int argc, VALUE *argv, VALUE self) {
97
+ struct smpdtfmt *p;
98
+ VALUE year, month, day, hour, min, sec;
99
+ char *buf;
100
+
101
+ rb_scan_args(argc, argv, "15", &year, &month, &day, &hour, &min, &sec);
102
+
103
+ Data_Get_Struct(self, struct smpdtfmt, p);
104
+
105
+ if (p->pattern_len > 0) {
106
+ int len = p->pattern_len * 3 + 16;
107
+ buf = alloca(len);
108
+ memset(buf, 0, len);
109
+ } else {
110
+ rb_raise(rb_eRuntimeError, "pattern is not set");
111
+ }
112
+
113
+ smpdtfmt_icu_format(p->fmt, NUM2INT(year), DEFAULT_INT(month), DEFAULT_INT(day), DEFAULT_INT(hour), DEFAULT_INT(min), DEFAULT_INT(sec), p->codepage, buf);
114
+
115
+ return rb_str_new2(buf);
116
+ }
117
+
118
+ /* */
119
+ static VALUE smpdtfmt_parse(VALUE self, VALUE text) {
120
+ struct smpdtfmt *p;
121
+ int year, month, day, hour, min, sec;
122
+
123
+ Check_Type(text, T_STRING);
124
+ Data_Get_Struct(self, struct smpdtfmt, p);
125
+ smpdtfmt_icu_parse(p->fmt, StringValuePtr(text), p->codepage, &year, &month, &day, &hour, &min, &sec);
126
+
127
+ return rb_funcall(rb_cTime, rb_intern("mktime"), 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
128
+ }
129
+
130
+ /* */
131
+ static VALUE smpdtfmt_apply_pattern(VALUE self, VALUE pattern) {
132
+ struct smpdtfmt *p;
133
+
134
+ Check_Type(pattern, T_STRING);
135
+ Data_Get_Struct(self, struct smpdtfmt, p);
136
+ smpdtfmt_icu_apply_pattern(p->fmt, StringValuePtr(pattern), p->codepage);
137
+ p->pattern_len = RSTRING(pattern)->len;
138
+
139
+ return Qnil;
140
+ }
141
+
142
+ /* */
143
+ static VALUE smpdtfmt_set_lenient(VALUE self, VALUE lenient) {
144
+ struct smpdtfmt *p;
145
+ int i_lenient;
146
+
147
+ switch (TYPE(lenient)) {
148
+ case T_TRUE: i_lenient = 1; break;
149
+ case T_FALSE: i_lenient = 0; break;
150
+ default:
151
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected TrueClass or FalseClass)", CLASS_OF(lenient));
152
+ break;
153
+ }
154
+
155
+ Data_Get_Struct(self, struct smpdtfmt, p);
156
+ smpdtfmt_icu_set_lenient(p->fmt, i_lenient);
157
+
158
+ return Qnil;
159
+ }
160
+
161
+ /* */
162
+ static VALUE smpdtfmt_Time_dtfmt(VALUE self, VALUE pattern) {
163
+ VALUE smpdtfmt = rb_funcall(rb_cSimpleDateFormat, rb_intern("new"), 1, pattern);
164
+ return rb_funcall(smpdtfmt, rb_intern("format"), 1, self);
165
+ }
166
+
167
+ /* */
168
+ static VALUE smpdtfmt_Time_icuparse(int argc, VALUE *argv, VALUE self) {
169
+ VALUE smpdtfmt, pattern, text, lenient;
170
+
171
+ rb_scan_args(argc, argv, "21", &pattern, &text, &lenient);
172
+ Check_Type(pattern, T_STRING);
173
+
174
+ if (NIL_P(lenient)) {
175
+ lenient = Qtrue;
176
+ }
177
+
178
+ smpdtfmt = rb_funcall(rb_cSimpleDateFormat, rb_intern("new"), 1, pattern);
179
+ rb_funcall(smpdtfmt, rb_intern("lenient="), 1, lenient);
180
+
181
+ return rb_funcall(smpdtfmt, rb_intern("parse"), 1, text);
182
+ }
183
+
184
+ static void smpdtfmt_free(struct smpdtfmt *p) {
185
+ smpdtfmt_icu_delete(p->fmt);
186
+ xfree(p);
187
+ }
188
+
189
+ static VALUE smpdtfmt_alloc(VALUE klass) {
190
+ struct smpdtfmt *p = ALLOC(struct smpdtfmt);
191
+
192
+ p->fmt = NULL;
193
+ p->pattern_len = 0;
194
+ p->codepage = NULL;
195
+
196
+ return Data_Wrap_Struct(klass, 0, smpdtfmt_free, p);
197
+ }
198
+
199
+ void Init_smpdtfmt() {
200
+ rb_cSimpleDateFormat = rb_define_class("SimpleDateFormat", rb_cObject);
201
+ rb_define_const(rb_cSimpleDateFormat, "VERSION", rb_str_new2(VERSION));
202
+ rb_define_alloc_func(rb_cSimpleDateFormat, smpdtfmt_alloc);
203
+ rb_define_private_method(rb_cSimpleDateFormat, "initialize", smpdtfmt_initialize, -1);
204
+ rb_define_method(rb_cSimpleDateFormat, "format", smpdtfmt_format, 1);
205
+ rb_define_method(rb_cSimpleDateFormat, "format_attrs", smpdtfmt_format_attrs, -1);
206
+ rb_define_method(rb_cSimpleDateFormat, "parse", smpdtfmt_parse, 1);
207
+ rb_define_method(rb_cSimpleDateFormat, "apply_pattern", smpdtfmt_apply_pattern, 1);
208
+ rb_define_method(rb_cSimpleDateFormat, "lenient=", smpdtfmt_set_lenient, 1);
209
+
210
+ rb_define_method(rb_cTime, "dtfmt", smpdtfmt_Time_dtfmt, 1);
211
+ rb_define_singleton_method(rb_cTime, "icuparse", smpdtfmt_Time_icuparse, -1);
212
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef __JADTFMT_H__
2
+ #define __JADTFMT_H__
3
+
4
+ struct smpdtfmt {
5
+ void *fmt;
6
+ int pattern_len;
7
+ char *codepage;
8
+ };
9
+
10
+ #endif
@@ -0,0 +1,99 @@
1
+ #include <string>
2
+ #include <iostream>
3
+ #include "unicode/calendar.h"
4
+ #include "unicode/smpdtfmt.h"
5
+
6
+ #include "ruby.h"
7
+
8
+ #define RAISE_ICU_ERRER(s) do { rb_raise(rb_eRuntimeError, u_errorName(s)); } while(0)
9
+ #define Chack_ICU_ERROR(s) do { if (U_FAILURE(s)) { RAISE_ICU_ERRER(s); } } while(0)
10
+
11
+ extern "C" {
12
+ void *smpdtfmt_icu_new(const char *pattern, const char *codepage);
13
+ void smpdtfmt_icu_delete(void *p);
14
+ void smpdtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst);
15
+ void smpdtfmt_icu_parse(void *p, const char *text, const char *codepage, int *year, int *month, int *date, int *hour, int *minute, int *second);
16
+ void smpdtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage);
17
+ void smpdtfmt_icu_set_lenient(void *p, int lenient);
18
+ }
19
+
20
+ void *smpdtfmt_icu_new(const char *pattern, const char *codepage) {
21
+ UErrorCode status = U_ZERO_ERROR;
22
+ SimpleDateFormat *fmt;
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
+ return fmt;
36
+ }
37
+
38
+ void smpdtfmt_icu_delete(void *p) {
39
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
40
+ delete fmt;
41
+ }
42
+
43
+ void smpdtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst) {
44
+ UErrorCode status = U_ZERO_ERROR;
45
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
46
+ Calendar *cal = Calendar::createInstance(status);
47
+ Chack_ICU_ERROR(status);
48
+
49
+ cal->set(year, month - 1, date, hour, minute, second);
50
+ UDate now = cal->getTime(status);
51
+ Chack_ICU_ERROR(status);
52
+
53
+ UnicodeString buf;
54
+ fmt->format(now, buf);
55
+
56
+ std::string conv(buf.extract(0, buf.length(), 0, codepage), '\0');
57
+ buf.extract(0, buf.length(), &conv[0], codepage);
58
+ memcpy(dst, conv.c_str(), conv.size());
59
+
60
+ delete cal;
61
+ }
62
+
63
+ void smpdtfmt_icu_parse(void *p, const char *text, const char *codepage, int *year, int *month, int *date, int *hour, int *minute, int *second) {
64
+ UErrorCode status = U_ZERO_ERROR;
65
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
66
+ Calendar *cal = Calendar::createInstance(status);
67
+ Chack_ICU_ERROR(status);
68
+
69
+ UDate parsed = fmt->parse(UnicodeString(text, codepage), status);
70
+ Chack_ICU_ERROR(status);
71
+
72
+ cal->setTime(parsed, status);
73
+ Chack_ICU_ERROR(status);
74
+
75
+ *year = cal->get(UCAL_YEAR, status);
76
+ Chack_ICU_ERROR(status);
77
+ *month = cal->get(UCAL_MONTH, status) + 1;
78
+ Chack_ICU_ERROR(status);
79
+ *date = cal->get(UCAL_DATE, status);
80
+ Chack_ICU_ERROR(status);
81
+ *hour = cal->get(UCAL_HOUR_OF_DAY, status);
82
+ Chack_ICU_ERROR(status);
83
+ *minute = cal->get(UCAL_MINUTE, status);
84
+ Chack_ICU_ERROR(status);
85
+ *second = cal->get(UCAL_SECOND, status);
86
+ Chack_ICU_ERROR(status);
87
+
88
+ delete cal;
89
+ }
90
+
91
+ void smpdtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage) {
92
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
93
+ fmt->applyPattern(UnicodeString(pattern, codepage));
94
+ }
95
+
96
+ void smpdtfmt_icu_set_lenient(void *p, int lenient) {
97
+ SimpleDateFormat *fmt = static_cast<SimpleDateFormat *>(p);
98
+ fmt->setLenient(static_cast<UBool>(lenient));
99
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef __JADTFMT_ICU_H__
2
+ #define __JADTFMT_ICU_H__
3
+
4
+ void *smpdtfmt_icu_new(const char *pattern, const char *codepage);
5
+ void smpdtfmt_icu_delete(void *p);
6
+ void smpdtfmt_icu_format(void *p, int year, int month, int date, int hour, int minute, int second, const char *codepage, char *dst);
7
+ void smpdtfmt_icu_parse(void *p, const char *text, const char *codepage, int *year, int *month, int *date, int *hour, int *minute, int *second);
8
+ void smpdtfmt_icu_apply_pattern(void *p, const char *pattern, const char *codepage);
9
+ void smpdtfmt_icu_set_lenient(void *p, int lenient);
10
+
11
+ #endif
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smpdtfmt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - winebarrel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-19 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/smpdtfmt.c
24
+ files:
25
+ - ext/smpdtfmt.c
26
+ - ext/smpdtfmt.h
27
+ - ext/smpdtfmt_icu.cpp
28
+ - ext/smpdtfmt_icu.h
29
+ - ext/extconf.rb
30
+ has_rdoc: true
31
+ homepage: http://smpdtfmt.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: smpdtfmt
53
+ rubygems_version: 1.1.1
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: formatting a Time to the japanese time string using ICU.
57
+ test_files: []
58
+