Hi,
Hernán Morales Durand <hernan.morales(a)gmail.com> wrote:
>Is there any serializer (Fuel/StOMP/Ma object
>serialization/BOSS/SRP/SIXX??) which let me attach an external
>compressor/decompressor for specific Strings to the
>serialization/deserialization process?
Mariano Martinez Peck <marianopeck(a)gmail.com> wrote:
> I think StOMP should support this as well:
> http://stomp.smalltalk-users.jp/home/how-to-use-stomp/hook-methods
Yes. StOMP does support such kind of custom serialization.
Pattern 1: Using Memento.
StOMP has two basic hook methods (stompWriteValue/stompReadValue).
With a memento pattern, you can customize
serialization/deserialization behavior easily.
SpecificString>> stompWriteValue
^ StringCompressedMemento on: self
StringCompressedMemento>> stompReadValue
^ SpecificString on: self uncompressToString
SpecificString is a mere wrapper class (holding original string). And
StringCompressedMemento should implement compress/uncompress logic.
Pattern 2: Subclassing Writer/Reader
Pattern 1 is usable, but it is basically suitable for pointer objects.
For String-like objects, defining a new String wrapper and Memento is
overwhelming. You can also subclass StompWriter/Reader for adding
custom serialization/deserialization behaviors.
MyStompWriter>>writeString: aString
(self isSpecificString: aString) ifTrue: [^super writeString: (self
compressString: aString)].
^ super writeString: string
MyStompReader>>readByteString
| rawString |
rawString := self basicReadObject asString.
^ (self isCompressedString: rawString)
ifTrue: [self uncompressString: rawString]
ifFalse: [rawString]
You have to add some marking headers to the original string for
determining it should be compressed/uncompressed. (Yes. this is a
little awkward, but works well).
I've attached working sample codes. So please see for details.
Best regards,
--
[:masashi | ^umezawa]
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.638.mcz
==================== Summary ====================
Name: Kernel-nice.638
Author: nice
Time: 15 October 2011, 12:01:04.127 am
UUID: 83cd4ee4-8be1-410e-9663-dcbd2e6f07b9
Ancestors: Kernel-nice.637
Cheaper #mightBeASquare (only test expensive lowBit where necessary).
Remove powers of 2 before performing sqrtFloor on a large integer.
=============== Diff against Kernel-nice.637 ===============
Item was changed:
----- Method: LargePositiveInteger>>mightBeASquare (in category 'mathematical functions') -----
mightBeASquare
"In base 16, a square number can end only with 0,1,4 or 9 and
- in case 0, only 0,1,4,9 can precede it,
- in case 4, only even numbers can precede it.
See http://en.wikipedia.org/wiki/Square_number
So, in hex, the last byte must be one of:
00
10
40
90
x1
e4
x9
where x is any hex digit and e is any even digit
Also, the receiver must be an aven power of two."
| lsb |
lsb := self digitAt: 1.
+ ^(lsb = 0 and: [ self lowBit odd ]) "00 (and even power of 2)"
+ or: [ lsb = 16r40 "40"
+ or: [ (lsb bitAnd: 16r7) = 1 "any|1 or any|9"
+ or: [ (lsb bitAnd: 16r1F) = 4 "even|4"
+ or: [ (lsb bitAnd: 16r7F) = 16 ]]]] "10 or 90"!
- ^((lsb bitAnd: 7) = 1 "any|1 or any|9"
- or: [(lsb bitAnd: 31) = 4 "even|4"
- or: [(lsb bitAnd: 127) = 16 "10 or 90"
- or: [(lsb bitAnd: 191) = 0]]]) "00 or 40"
- and: [self lowBit odd] "even power of 2"!
Item was added:
+ ----- Method: LargePositiveInteger>>sqrtFloor (in category 'mathematical functions') -----
+ sqrtFloor
+ "Return the integer part of the square root of self"
+
+ | powerOfTwo |
+ (powerOfTwo := self lowBit - 1 // 2) > 1
+ ifFalse: [^super sqrtFloor].
+ ^(self bitShift: -2 * powerOfTwo) sqrtFloor bitShift: powerOfTwo!
Thanks for reviewing and integrating all this, Nicolas! And for fixing
ScaledDecimal, that is not included in Cuis.
Note that the check for being an even power of two (great idea BTW) is
implicit in most of the tests already done, so this is enough:
...
Also, the receiver must be an aven power of two.
This needs additional testing in the 00 suffix,
as it implied in all the other conditions"
| lsb |
lsb := self digitAt: 1.
^(lsb = 0 and: [ self lowBit odd ]) "00 (and even power of 2)"
or: [ lsb = 16r40 "40"
or: [ (lsb bitAnd: 16r7) = 1 "any|1 or any|9"
or: [ (lsb bitAnd: 16r1F) = 4 "even|4"
or: [ (lsb bitAnd: 16r7F) = 16 ]]]] "10 or 90"
Cheers,
Juan Vuletich
commits(a)source.squeak.org wrote:
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-nice.637.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-nice.637
> Author: nice
> Time: 14 October 2011, 10:28:53.269 pm
> UUID: 90981f89-5348-4bf9-8981-4cc51da6bc29
> Ancestors: Kernel-nice.636
>
> Implement ScaledDecimal>>nthRoot:
> #mightBeASquare now verifies whether the receiver is an even power of two.
>
> =============== Diff against Kernel-nice.636 ===============
>
> ...
>
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.637.mcz
==================== Summary ====================
Name: Kernel-nice.637
Author: nice
Time: 14 October 2011, 10:28:53.269 pm
UUID: 90981f89-5348-4bf9-8981-4cc51da6bc29
Ancestors: Kernel-nice.636
Implement ScaledDecimal>>nthRoot:
#mightBeASquare now verifies whether the receiver is an even power of two.
=============== Diff against Kernel-nice.636 ===============
Item was changed:
----- Method: Integer>>sqrt (in category 'mathematical functions') -----
sqrt
"Answer the square root of the receiver."
| selfAsFloat floatResult guess |
selfAsFloat := self asFloat.
floatResult := selfAsFloat sqrt.
floatResult isInfinite ifFalse: [
guess := floatResult truncated.
"If got an exact answer, answer it. Otherwise answer float approximate answer."
guess squared = self
ifTrue: [ ^ guess ]].
"In this case, maybe it failed because we are such a big integer that the Float method becomes
inexact, even if we are a whole square number. So, try the slower but more general method"
selfAsFloat >= Float maxExactInteger asFloat squared
ifTrue: [
guess := self sqrtFloor.
+ guess squared = self ifTrue: [
- guess * guess = self ifTrue: [
^guess ]].
"We need an approximate result"
^floatResult!
Item was changed:
----- Method: LargePositiveInteger>>mightBeASquare (in category 'mathematical functions') -----
mightBeASquare
"In base 16, a square number can end only with 0,1,4 or 9 and
- in case 0, only 0,1,4,9 can precede it,
- in case 4, only even numbers can precede it.
See http://en.wikipedia.org/wiki/Square_number
So, in hex, the last byte must be one of:
00
10
40
90
x1
e4
x9
where x is any hex digit and e is any even digit
+ Also, the receiver must be an aven power of two."
+ | lsb |
+ lsb := self digitAt: 1.
+ ^((lsb bitAnd: 7) = 1 "any|1 or any|9"
+ or: [(lsb bitAnd: 31) = 4 "even|4"
+ or: [(lsb bitAnd: 127) = 16 "10 or 90"
+ or: [(lsb bitAnd: 191) = 0]]]) "00 or 40"
+ and: [self lowBit odd] "even power of 2"!
- "
- | lsb |
- lsb := self digitAt: 1.
- ^((lsb bitAnd: 7) = 1 "any|1 or any|9"
- or: [(lsb bitAnd: 31) = 4 "even|4"
- or: [(lsb bitAnd: 127) = 16 "10 or 90"
- or: [(lsb bitAnd: 191) = 0]]]) "00 or 40"!
Item was added:
+ ----- Method: ScaledDecimal>>nthRoot: (in category 'mathematical functions') -----
+ nthRoot: anInteger
+ "Answer the nth root of the receiver.
+ Preserve receiver class and scale if answer is exact.
+ Otherwise, answer a Float to denote inexactness."
+ | nthRoot |
+ nthRoot := self asFraction nthRoot: anInteger.
+ ^nthRoot isFloat
+ ifTrue: [nthRoot]
+ ifFalse: [nthRoot asScaledDecimal: scale]!
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.636.mcz
==================== Summary ====================
Name: Kernel-nice.636
Author: nice
Time: 14 October 2011, 10:05:36.672 pm
UUID: 87b3aaea-65b6-4ebf-8855-ef8f27bcb0c3
Ancestors: Kernel-nice.635
Fix ScaledDecimal which didn't work anymore, and let it be exact when possible.
=============== Diff against Kernel-nice.635 ===============
Item was added:
+ ----- Method: ScaledDecimal>>sqrt (in category 'mathematical functions') -----
+ sqrt
+ "Answer the square root of the receiver.
+ Preserve receiver class and scale if answer is exact.
+ Otherwise, answer a Float to denote inexactness."
+ | squareRoot |
+ squareRoot := self asFraction sqrt.
+ ^squareRoot isFloat
+ ifTrue: [squareRoot]
+ ifFalse: [squareRoot asScaledDecimal: scale]!