smpdtfmt 0.0.1

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.
@@ -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
+