comparison dwtx/dwtxhelper/mangoicu/UNumberFormat.d @ 89:040da1cb0d76

Add a local copy of the mango ICU binding to work out the utf8 usability. Will hopefully go back into mango.
author Frank Benoit <benoit@tionex.de>
date Sun, 22 Jun 2008 22:57:31 +0200
parents
children 11e8159caf7a
comparison
equal deleted inserted replaced
88:cd18fa3b71f1 89:040da1cb0d76
1 /*******************************************************************************
2
3 @file UNumberFormat.d
4
5 Copyright (c) 2004 Kris Bell
6
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for damages
9 of any kind arising from the use of this software.
10
11 Permission is hereby granted to anyone to use this software for any
12 purpose, including commercial applications, and to alter it and/or
13 redistribute it freely, subject to the following restrictions:
14
15 1. The origin of this software must not be misrepresented; you must
16 not claim that you wrote the original software. If you use this
17 software in a product, an acknowledgment within documentation of
18 said product would be appreciated but is not required.
19
20 2. Altered source versions must be plainly marked as such, and must
21 not be misrepresented as being the original software.
22
23 3. This notice may not be removed or altered from any distribution
24 of the source.
25
26 4. Derivative works are permitted, but they must carry this notice
27 in full and credit the original source.
28
29
30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
32
33 @version Initial version, November 2004
34 @author Kris
35
36 Note that this package and documentation is built around the ICU
37 project (http://oss.software.ibm.com/icu/). Below is the license
38 statement as specified by that software:
39
40
41 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
43
44 ICU License - ICU 1.8.1 and later
45
46 COPYRIGHT AND PERMISSION NOTICE
47
48 Copyright (c) 1995-2003 International Business Machines Corporation and
49 others.
50
51 All rights reserved.
52
53 Permission is hereby granted, free of charge, to any person obtaining a
54 copy of this software and associated documentation files (the
55 "Software"), to deal in the Software without restriction, including
56 without limitation the rights to use, copy, modify, merge, publish,
57 distribute, and/or sell copies of the Software, and to permit persons
58 to whom the Software is furnished to do so, provided that the above
59 copyright notice(s) and this permission notice appear in all copies of
60 the Software and that both the above copyright notice(s) and this
61 permission notice appear in supporting documentation.
62
63 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
64 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
65 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
66 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
68 INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
69 FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
70 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
71 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
72
73 Except as contained in this notice, the name of a copyright holder
74 shall not be used in advertising or otherwise to promote the sale, use
75 or other dealings in this Software without prior written authorization
76 of the copyright holder.
77
78 ----------------------------------------------------------------------
79
80 All trademarks and registered trademarks mentioned herein are the
81 property of their respective owners.
82
83 *******************************************************************************/
84
85 module dwtx.dwthelper.mangoicu.UNumberFormat;
86
87 private import dwtx.dwthelper.mangoicu.ICU,
88 dwtx.dwthelper.mangoicu.UString;
89
90 public import dwtx.dwthelper.mangoicu.ULocale;
91
92 /*******************************************************************************
93
94 *******************************************************************************/
95
96 class UDecimalFormat : UCommonFormat
97 {
98 /***********************************************************************
99
100 ***********************************************************************/
101
102 this (inout ULocale locale)
103 {
104 super (Style.Decimal, null, locale);
105 }
106
107 /***********************************************************************
108
109 Set the pattern for a UDecimalFormat
110
111 ***********************************************************************/
112
113 void setPattern (UText pattern, bool localized)
114 {
115 Error e;
116
117 unum_applyPattern (handle, localized, pattern.get.ptr, pattern.length, null, e);
118 testError (e, "failed to set numeric pattern");
119 }
120 }
121
122
123 /*******************************************************************************
124
125 *******************************************************************************/
126
127 class UCurrencyFormat : UCommonFormat
128 {
129 /***********************************************************************
130
131 ***********************************************************************/
132
133 this (inout ULocale locale)
134 {
135 super (Style.Currency, null, locale);
136 }
137 }
138
139
140 /*******************************************************************************
141
142 *******************************************************************************/
143
144 class UPercentFormat : UCommonFormat
145 {
146 /***********************************************************************
147
148 ***********************************************************************/
149
150 this (inout ULocale locale)
151 {
152 super (Style.Percent, null, locale);
153 }
154 }
155
156
157 /*******************************************************************************
158
159 *******************************************************************************/
160
161 class UScientificFormat : UCommonFormat
162 {
163 /***********************************************************************
164
165 ***********************************************************************/
166
167 this (inout ULocale locale)
168 {
169 super (Style.Scientific, null, locale);
170 }
171 }
172
173
174 /*******************************************************************************
175
176 *******************************************************************************/
177
178 class USpelloutFormat : UCommonFormat
179 {
180 /***********************************************************************
181
182 ***********************************************************************/
183
184 this (inout ULocale locale)
185 {
186 super (Style.Spellout, null, locale);
187 }
188 }
189
190
191 /*******************************************************************************
192
193 *******************************************************************************/
194
195 class UDurationFormat : UCommonFormat
196 {
197 /***********************************************************************
198
199 ***********************************************************************/
200
201 this (inout ULocale locale)
202 {
203 super (Style.Duration, null, locale);
204 }
205 }
206
207
208 /*******************************************************************************
209
210 *******************************************************************************/
211
212 class URuleBasedFormat : UNumberFormat
213 {
214 /***********************************************************************
215
216 ***********************************************************************/
217
218 this (inout ULocale locale)
219 {
220 super (Style.RuleBased, null, locale);
221 }
222
223 /***********************************************************************
224
225 ***********************************************************************/
226
227 void setLenientParse (bool yes)
228 {
229 unum_setAttribute (handle, Attribute.LenientParse, yes);
230 }
231
232
233 /***********************************************************************
234
235 ***********************************************************************/
236
237 bool isLenientParse ()
238 {
239 return unum_getAttribute (handle, Attribute.LenientParse) != 0;
240 }
241 }
242
243
244 /*******************************************************************************
245
246 *******************************************************************************/
247
248 private class UCommonFormat : UNumberFormat
249 {
250 /***********************************************************************
251
252 ***********************************************************************/
253
254 this (Style style, char[] pattern, inout ULocale locale)
255 {
256 super (style, pattern, locale);
257 }
258
259 /***********************************************************************
260
261 Return true if this format will parse numbers as integers
262 only
263
264 ***********************************************************************/
265
266 bool isParseIntegerOnly ()
267 {
268 return unum_getAttribute (handle, Attribute.ParseIntOnly) != 0;
269 }
270
271 /***********************************************************************
272
273 Returns true if grouping is used in this format.
274
275 ***********************************************************************/
276
277 bool isGroupingUsed ()
278 {
279 return unum_getAttribute (handle, Attribute.GroupingUsed) != 0;
280 }
281
282 /***********************************************************************
283
284 Always show decimal point?
285
286 ***********************************************************************/
287
288 bool isDecimalSeparatorAlwaysShown ()
289 {
290 return unum_getAttribute (handle, Attribute.DecimalAlwaysShown) != 0;
291 }
292
293 /***********************************************************************
294
295 Sets whether or not numbers should be parsed as integers
296 only
297
298 ***********************************************************************/
299
300 void setParseIntegerOnly (bool yes)
301 {
302 unum_setAttribute (handle, Attribute.ParseIntOnly, yes);
303 }
304
305 /***********************************************************************
306
307 Set whether or not grouping will be used in this format.
308
309 ***********************************************************************/
310
311 void setGroupingUsed (bool yes)
312 {
313 unum_setAttribute (handle, Attribute.GroupingUsed, yes);
314 }
315
316 /***********************************************************************
317
318 Always show decimal point.
319
320 ***********************************************************************/
321
322 void setDecimalSeparatorAlwaysShown (bool yes)
323 {
324 unum_setAttribute (handle, Attribute.DecimalAlwaysShown, yes);
325 }
326
327 /***********************************************************************
328
329 Sets the maximum number of digits allowed in the integer
330 portion of a number.
331
332 ***********************************************************************/
333
334 void setMaxIntegerDigits (uint x)
335 {
336 unum_setAttribute (handle, Attribute.MaxIntegerDigits, x);
337 }
338
339 /***********************************************************************
340
341 Sets the minimum number of digits allowed in the integer
342 portion of a number.
343
344 ***********************************************************************/
345
346 void setMinIntegerDigits (uint x)
347 {
348 unum_setAttribute (handle, Attribute.MinIntegerDigits, x);
349 }
350
351 /***********************************************************************
352
353 Integer digits displayed
354
355 ***********************************************************************/
356
357 void setIntegerDigits (uint x)
358 {
359 unum_setAttribute (handle, Attribute.IntegerDigits, x);
360 }
361
362 /***********************************************************************
363
364 Sets the maximum number of digits allowed in the fraction
365 portion of a number.
366
367 ***********************************************************************/
368
369 void setMaxFractionDigits (uint x)
370 {
371 unum_setAttribute (handle, Attribute.MaxFractionDigits, x);
372 }
373
374 /***********************************************************************
375
376 Sets the minimum number of digits allowed in the fraction
377 portion of a number.
378
379 ***********************************************************************/
380
381 void setMinFractionDigits (uint x)
382 {
383 unum_setAttribute (handle, Attribute.MinFractionDigits, x);
384 }
385
386 /***********************************************************************
387
388 Fraction digits.
389
390 ***********************************************************************/
391
392 void setFractionDigits (uint x)
393 {
394 unum_setAttribute (handle, Attribute.FractionDigits, x);
395 }
396
397 /***********************************************************************
398
399 ***********************************************************************/
400
401 void setMultiplier (uint x)
402 {
403 unum_setAttribute (handle, Attribute.Multiplier, x);
404 }
405
406 /***********************************************************************
407
408 ***********************************************************************/
409
410 void setGroupingSize (uint x)
411 {
412 unum_setAttribute (handle, Attribute.GroupingSize, x);
413 }
414
415 /***********************************************************************
416
417 ***********************************************************************/
418
419 void setRoundingMode (Rounding x)
420 {
421 unum_setAttribute (handle, Attribute.RoundingMode, x);
422 }
423
424 /***********************************************************************
425
426 ***********************************************************************/
427
428 void setRoundingIncrement (uint x)
429 {
430 unum_setAttribute (handle, Attribute.RoundingIncrement, x);
431 }
432
433 /***********************************************************************
434
435 The width to which the output of format() is padded
436
437 ***********************************************************************/
438
439 void setFormatWidth (uint x)
440 {
441 unum_setAttribute (handle, Attribute.FormatWidth, x);
442 }
443
444 /***********************************************************************
445
446 The position at which padding will take place.
447
448 ***********************************************************************/
449
450 void setPaddingPosition (Pad x)
451 {
452 unum_setAttribute (handle, Attribute.PaddingPosition, x);
453 }
454
455 /***********************************************************************
456
457 ***********************************************************************/
458
459 void setSecondaryGroupingSize (uint x)
460 {
461 unum_setAttribute (handle, Attribute.SecondaryGroupingSize, x);
462 }
463
464 /***********************************************************************
465
466 ***********************************************************************/
467
468 void setSignificantDigitsUsed (uint x)
469 {
470 unum_setAttribute (handle, Attribute.SignificantDigitsUsed, x);
471 }
472
473 /***********************************************************************
474
475 ***********************************************************************/
476
477 void setMinSignificantDigits (uint x)
478 {
479 unum_setAttribute (handle, Attribute.MinSignificantDigits, x);
480 }
481
482 /***********************************************************************
483
484 ***********************************************************************/
485
486 void setMaxSignificantDigits (uint x)
487 {
488 unum_setAttribute (handle, Attribute.MaxSignificantDigits, x);
489 }
490
491
492 /***********************************************************************
493
494 Returns the maximum number of digits allowed in the integer
495 portion of a number.
496
497 ***********************************************************************/
498
499 uint getMaxIntegerDigits ()
500 {
501 return unum_getAttribute (handle, Attribute.MaxIntegerDigits);
502 }
503
504 /***********************************************************************
505
506 Returns the minimum number of digits allowed in the integer
507 portion of a number.
508
509 ***********************************************************************/
510
511 uint getMinIntegerDigits ()
512 {
513 return unum_getAttribute (handle, Attribute.MinIntegerDigits);
514 }
515
516 /***********************************************************************
517
518 ***********************************************************************/
519
520 uint getIntegerDigits ()
521 {
522 return unum_getAttribute (handle, Attribute.IntegerDigits);
523 }
524
525 /***********************************************************************
526
527 Returns the maximum number of digits allowed in the fraction
528 portion of a number.
529
530 ***********************************************************************/
531
532 uint getMaxFractionDigits ()
533 {
534 return unum_getAttribute (handle, Attribute.MaxFractionDigits);
535 }
536
537 /***********************************************************************
538
539 ***********************************************************************/
540
541 uint getMinFractionDigits ()
542 {
543 return unum_getAttribute (handle, Attribute.MinFractionDigits);
544 }
545
546 /***********************************************************************
547
548 ***********************************************************************/
549
550 uint getFractionDigits ()
551 {
552 return unum_getAttribute (handle, Attribute.FractionDigits);
553 }
554
555 /***********************************************************************
556
557 ***********************************************************************/
558
559 uint getMultiplier ()
560 {
561 return unum_getAttribute (handle, Attribute.Multiplier);
562 }
563
564 /***********************************************************************
565
566 ***********************************************************************/
567
568 uint getGroupingSize ()
569 {
570 return unum_getAttribute (handle, Attribute.GroupingSize);
571 }
572
573 /***********************************************************************
574
575 ***********************************************************************/
576
577 Rounding getRoundingMode ()
578 {
579 return cast(Rounding) unum_getAttribute (handle, Attribute.RoundingMode);
580 }
581
582 /***********************************************************************
583
584 ***********************************************************************/
585
586 uint getRoundingIncrement ()
587 {
588 return unum_getAttribute (handle, Attribute.RoundingIncrement);
589 }
590
591 /***********************************************************************
592
593 ***********************************************************************/
594
595 uint getFormatWidth ()
596 {
597 return unum_getAttribute (handle, Attribute.FormatWidth);
598 }
599
600 /***********************************************************************
601
602 ***********************************************************************/
603
604 Pad getPaddingPosition ()
605 {
606 return cast(Pad) unum_getAttribute (handle, Attribute.PaddingPosition);
607 }
608
609 /***********************************************************************
610
611 ***********************************************************************/
612
613 uint getSecondaryGroupingSize ()
614 {
615 return unum_getAttribute (handle, Attribute.SecondaryGroupingSize);
616 }
617
618 /***********************************************************************
619
620 ***********************************************************************/
621
622 uint getSignificantDigitsUsed ()
623 {
624 return unum_getAttribute (handle, Attribute.SignificantDigitsUsed);
625 }
626
627 /***********************************************************************
628
629 ***********************************************************************/
630
631 uint getMinSignificantDigits ()
632 {
633 return unum_getAttribute (handle, Attribute.MinSignificantDigits);
634 }
635
636 /***********************************************************************
637
638 ***********************************************************************/
639
640 uint getMaxSignificantDigits ()
641 {
642 return unum_getAttribute (handle, Attribute.MaxSignificantDigits);
643 }
644
645 /***********************************************************************
646
647 ***********************************************************************/
648
649 void getPattern (UString dst, bool localize)
650 {
651 uint fmat (wchar* result, uint len, inout Error e)
652 {
653 return unum_toPattern (handle, localize, result, len, e);
654 }
655
656 dst.format (&fmat, "failed to retrieve numeric format pattern");
657 }
658 }
659
660
661 /*******************************************************************************
662
663 UNumberFormat provides functions for formatting and parsing
664 a number. Also provides methods for determining which locales have
665 number formats, and what their names are.
666
667 UNumberFormat helps you to format and parse numbers for any locale.
668 Your code can be completely independent of the locale conventions
669 for decimal points, thousands-separators, or even the particular
670 decimal digits used, or whether the number format is even decimal.
671 There are different number format styles like decimal, currency,
672 percent and spellout
673
674 See <A HREF="http://oss.software.ibm.com/icu/apiref/unum_8h.html">
675 this page</A> for full details.
676
677 *******************************************************************************/
678
679 class UNumberFormat : ICU
680 {
681 package Handle handle;
682
683 typedef void* UFieldPos;
684 typedef void* ParseError;
685
686
687 public enum Rounding
688 {
689 Ceiling,
690 Floor,
691 Down,
692 Up,
693 HalfEven,
694 HalfDown,
695 HalfUp
696 };
697
698 public enum Pad
699 {
700 BeforePrefix,
701 AfterPrefix,
702 BeforeSuffix,
703 AfterSuffix
704 };
705
706 public enum Style
707 {
708 PatternDecimal,
709 Decimal,
710 Currency,
711 Percent,
712 Scientific,
713 Spellout,
714 Ordinal,
715 Duration,
716 RuleBased,
717 Default = Decimal,
718 Ignore = PatternDecimal
719 };
720
721 private enum Attribute
722 {
723 ParseIntOnly,
724 GroupingUsed,
725 DecimalAlwaysShown,
726 MaxIntegerDigits,
727 MinIntegerDigits,
728 IntegerDigits,
729 MaxFractionDigits,
730 MinFractionDigits,
731 FractionDigits,
732 Multiplier,
733 GroupingSize,
734 RoundingMode,
735 RoundingIncrement,
736 FormatWidth,
737 PaddingPosition,
738 SecondaryGroupingSize,
739 SignificantDigitsUsed,
740 MinSignificantDigits,
741 MaxSignificantDigits,
742 LenientParse
743 };
744
745 private enum Symbol
746 {
747 DecimalSeparator,
748 GroupingSeparator,
749 PatternSeparator,
750 Percent,
751 ZeroDigit,
752 Digit,
753 MinusSign,
754 PlusSign,
755 Currency,
756 IntlCurrency,
757 MonetarySeparator,
758 Exponential,
759 Permill,
760 PadEscape,
761 Infinity,
762 Nan,
763 SignificantDigit,
764 FormatSymbolCount
765 };
766
767 /***********************************************************************
768
769 ***********************************************************************/
770
771 this (Style style, char[] pattern, inout ULocale locale)
772 {
773 Error e;
774
775 handle = unum_open (style, pattern.ptr, pattern.length, toString(locale.name), null, e);
776 testError (e, "failed to create NumberFormat");
777 }
778
779 /***********************************************************************
780
781 ***********************************************************************/
782
783 ~this ()
784 {
785 unum_close (handle);
786 }
787
788 /***********************************************************************
789
790 ***********************************************************************/
791
792 void format (UString dst, int number, UFieldPos p = null)
793 {
794 uint fmat (wchar* result, uint len, inout Error e)
795 {
796 return unum_format (handle, number, result, len, p, e);
797 }
798
799 dst.format (&fmat, "int format failed");
800 }
801
802 /***********************************************************************
803
804 ***********************************************************************/
805
806 void format (UString dst, long number, UFieldPos p = null)
807 {
808 uint fmat (wchar* result, uint len, inout Error e)
809 {
810 return unum_formatInt64 (handle, number, result, len, p, e);
811 }
812
813 dst.format (&fmat, "int64 format failed");
814 }
815
816 /***********************************************************************
817
818 ***********************************************************************/
819
820 void format (UString dst, double number, UFieldPos p = null)
821 {
822 uint fmat (wchar* result, uint len, inout Error e)
823 {
824 return unum_formatDouble (handle, number, result, len, p, e);
825 }
826
827 dst.format (&fmat, "double format failed");
828 }
829
830 /***********************************************************************
831
832 ***********************************************************************/
833
834 int parseInteger (UText src, uint* index=null)
835 {
836 Error e;
837
838 return unum_parse (handle, src.content.ptr, src.len, index, e);
839 }
840
841 /***********************************************************************
842
843 ***********************************************************************/
844
845 long parseLong (UText src, uint* index=null)
846 {
847 Error e;
848
849 return unum_parseInt64 (handle, src.content.ptr, src.len, index, e);
850 }
851
852 /***********************************************************************
853
854 ***********************************************************************/
855
856 double parseDouble (UText src, uint* index=null)
857 {
858 Error e;
859
860 return unum_parseDouble (handle, src.content.ptr, src.len, index, e);
861 }
862
863
864
865 /***********************************************************************
866
867 Bind the ICU functions from a shared library. This is
868 complicated by the issues regarding D and DLLs on the
869 Windows platform
870
871 ***********************************************************************/
872
873 private static void* library;
874
875 /***********************************************************************
876
877 ***********************************************************************/
878
879 private static extern (C)
880 {
881 Handle function (uint, char*, uint, char*, ParseError, inout Error) unum_open;
882 void function (Handle) unum_close;
883 int function (Handle, int, wchar*, uint, UFieldPos, inout Error) unum_format;
884 int function (Handle, long, wchar*, uint, UFieldPos, inout Error) unum_formatInt64;
885 int function (Handle, double, wchar*, uint, UFieldPos, inout Error) unum_formatDouble;
886 int function (Handle, wchar*, uint, uint*, inout Error) unum_parse;
887 long function (Handle, wchar*, uint, uint*, inout Error) unum_parseInt64;
888 double function (Handle, wchar*, uint, uint*, inout Error) unum_parseDouble;
889 int function (Handle, uint) unum_getAttribute;
890 void function (Handle, uint, uint) unum_setAttribute;
891 uint function (Handle, byte, wchar*, uint, inout Error) unum_toPattern;
892 void function (Handle, byte, wchar*, uint, ParseError, inout Error) unum_applyPattern;
893 }
894
895 /***********************************************************************
896
897 ***********************************************************************/
898
899 static FunctionLoader.Bind[] targets =
900 [
901 {cast(void**) &unum_open, "unum_open"},
902 {cast(void**) &unum_close, "unum_close"},
903 {cast(void**) &unum_format, "unum_format"},
904 {cast(void**) &unum_formatInt64 "unum_formatInt64"},
905 {cast(void**) &unum_formatDouble "unum_formatDouble"},
906 {cast(void**) &unum_parse, "unum_parse"},
907 {cast(void**) &unum_parseInt64 "unum_parseInt64"},
908 {cast(void**) &unum_parseDouble "unum_parseDouble"},
909 {cast(void**) &unum_getAttribute "unum_getAttribute"},
910 {cast(void**) &unum_setAttribute "unum_setAttribute"},
911 {cast(void**) &unum_toPattern "unum_toPattern"},
912 ];
913
914 /***********************************************************************
915
916 ***********************************************************************/
917
918 static this ()
919 {
920 library = FunctionLoader.bind (icuin, targets);
921 }
922
923 /***********************************************************************
924
925 ***********************************************************************/
926
927 static ~this ()
928 {
929 FunctionLoader.unbind (library);
930 }
931 }
932
933
934