From 80f7c54e4d14e4762714c6b26e1dcd994f2f0727 Mon Sep 17 00:00:00 2001 From: gfx Date: Wed, 22 Sep 2010 15:25:08 +0900 Subject: [PATCH 01/19] perl: make scopes --- perl/xs-src/unpack.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index 20b345f..95b5910 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -31,6 +31,7 @@ typedef struct { #define msgpack_unpack_user unpack_user void init_Data__MessagePack_unpack(pTHX_ bool const cloning) { + // booleans are load on demand (lazy load). if(!cloning) { MY_CXT_INIT; MY_CXT.msgpack_true = NULL; @@ -52,11 +53,17 @@ static SV* load_bool(pTHX_ const char* const name) { CV* const cv = get_cv(name, GV_ADD); dSP; + ENTER; + SAVETMPS; PUSHMARK(SP); call_sv((SV*)cv, G_SCALAR); SPAGAIN; SV* const sv = newSVsv(POPs); PUTBACK; + FREETMPS; + LEAVE; + assert(sv); + assert(sv_isobject(sv)); return sv; } From 68b6fa46e61490c3f5fdca71b3e1dc90ebb4a02d Mon Sep 17 00:00:00 2001 From: gfx Date: Wed, 22 Sep 2010 15:28:14 +0900 Subject: [PATCH 02/19] perl: add tests for boolean values --- perl/t/13_booleans.t | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 perl/t/13_booleans.t diff --git a/perl/t/13_booleans.t b/perl/t/13_booleans.t new file mode 100755 index 0000000..1ecbe64 --- /dev/null +++ b/perl/t/13_booleans.t @@ -0,0 +1,12 @@ +#!perl -w +use strict; +use Test::More tests => 6; +use Data::MessagePack; + +ok defined(Data::MessagePack::true()), 'true (1)'; +ok defined(Data::MessagePack::true()), 'true (2)'; +ok Data::MessagePack::true(), 'true is true'; + +ok defined(Data::MessagePack::false()), 'false (1)'; +ok defined(Data::MessagePack::false()), 'false (2)'; +ok !Data::MessagePack::false(), 'false is false'; From 0a8a6ed168dfd9338c2e97fd6b87b88ef39644ef Mon Sep 17 00:00:00 2001 From: gfx Date: Wed, 22 Sep 2010 15:59:21 +0900 Subject: [PATCH 03/19] perl: cleanup PP --- perl/lib/Data/MessagePack/PP.pm | 54 +++++++++++++++------------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 8234b49..5dccc0b 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -1,20 +1,17 @@ package Data::MessagePack::PP; use 5.008001; use strict; +use warnings; +no warnings 'recursion'; + use Carp (); +use B (); # See also # http://redmine.msgpack.org/projects/msgpack/wiki/FormatSpec # http://cpansearch.perl.org/src/YAPPO/Data-Model-0.00006/lib/Data/Model/Driver/Memcached.pm # http://frox25.no-ip.org/~mtve/wiki/MessagePack.html : reference to using CORE::pack, CORE::unpack - -package - Data::MessagePack; - -use strict; -use B (); - BEGIN { my $unpack_int64_slow; my $unpack_uint64_slow; @@ -120,6 +117,18 @@ BEGIN { *unpack_int64 = $unpack_int64_slow || sub { return unpack( 'q>', substr( $_[0], $_[1], 8 ) ); }; *unpack_uint64 = $unpack_uint64_slow || sub { return unpack( 'Q>', substr( $_[0], $_[1], 8 ) ); }; } + + # fixin package symbols + no warnings 'once'; + sub pack :method; + sub unpack :method; + *Data::MessagePack::pack = \&pack; + *Data::MessagePack::unpack = \&unpack; + + @Data::MessagePack::Unpacker::ISA = qw(Data::MessagePack::PP::Unpacker); + + *true = \&Data::MessagePack::true; + *false = \&Data::MessagePack::false; } sub _unexpected { @@ -130,10 +139,7 @@ sub _unexpected { # PACK # -{ - no warnings 'recursion'; - - our $_max_depth; +our $_max_depth; sub pack :method { Carp::croak('Usage: Data::MessagePack->pack($dat [,$max_depth])') if @_ < 2; @@ -238,20 +244,19 @@ sub _pack { } -} # PACK - - # # UNPACK # -{ - - my $p; # position variables for speed. +my $p; # position variables for speed. sub unpack :method { $p = 0; # init - _unpack( $_[1] ); + my $data = _unpack( $_[1] ); + if($p < length($_[1])) { + Carp::croak("Data::MessagePack->unpack: extra bytes"); + } + return $data; } @@ -383,17 +388,12 @@ sub _unpack { } -} # UNPACK - - # # Data::MessagePack::Unpacker # package - Data::MessagePack::Unpacker; - -use strict; + Data::MessagePack::PP::Unpacker; sub new { bless { pos => 0 }, shift; @@ -404,10 +404,6 @@ sub execute_limit { execute( @_ ); } - -{ - my $p; - sub execute { my ( $self, $data, $offset, $limit ) = @_; $offset ||= 0; @@ -542,8 +538,6 @@ sub _count { return 0; } -} # execute - sub data { return Data::MessagePack->unpack( substr($_[0]->{ data }, 0, $_[0]->{pos}) ); From 3d905a7a4fe437433dd0746d9864928ec8f464b9 Mon Sep 17 00:00:00 2001 From: gfx Date: Wed, 22 Sep 2010 16:14:55 +0900 Subject: [PATCH 04/19] perl: add tests for 'extra bytes' exceptions --- perl/t/14_invalid_data.t | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 perl/t/14_invalid_data.t diff --git a/perl/t/14_invalid_data.t b/perl/t/14_invalid_data.t new file mode 100755 index 0000000..f534485 --- /dev/null +++ b/perl/t/14_invalid_data.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Data::MessagePack; +use Test::More; +use t::Util; + +my $nil = Data::MessagePack->pack(undef); + +my @data = do 't/data.pl'; +while(my($dump, $data) = splice @data, 0, 2) { + my $s = Data::MessagePack->pack($data); + eval { + Data::MessagePack->unpack($s . $nil); + }; + like $@, qr/extra bytes/, "dump $dump"; +} + +done_testing; From 142493076a7a268bdb38f02b06ac5bc34a0f3004 Mon Sep 17 00:00:00 2001 From: tanakh Date: Thu, 23 Sep 2010 00:04:34 +0900 Subject: [PATCH 05/19] haskell: TH support and refactoring --- haskell/msgpack.cabal | 10 +- haskell/src/Data/MessagePack.hs | 35 +-- haskell/src/Data/MessagePack/Derive.hs | 74 ++++++ haskell/src/Data/MessagePack/Iteratee.hs | 4 +- haskell/src/Data/MessagePack/Object.hs | 235 +++++++++++++++--- .../src/Data/MessagePack/{Put.hs => Pack.hs} | 78 +++--- .../Data/MessagePack/{Parser.hs => Unpack.hs} | 112 ++++++--- haskell/test/UserData.hs | 19 ++ 8 files changed, 422 insertions(+), 145 deletions(-) create mode 100644 haskell/src/Data/MessagePack/Derive.hs rename haskell/src/Data/MessagePack/{Put.hs => Pack.hs} (66%) rename haskell/src/Data/MessagePack/{Parser.hs => Unpack.hs} (70%) create mode 100644 haskell/test/UserData.hs diff --git a/haskell/msgpack.cabal b/haskell/msgpack.cabal index ccdb2f7..9c67bdc 100644 --- a/haskell/msgpack.cabal +++ b/haskell/msgpack.cabal @@ -1,5 +1,5 @@ Name: msgpack -Version: 0.3.1.1 +Version: 0.4.0 Synopsis: A Haskell binding to MessagePack Description: A Haskell binding to MessagePack @@ -25,17 +25,19 @@ Library attoparsec >= 0.8.1 && < 0.8.2, binary >= 0.5.0 && < 0.5.1, data-binary-ieee754 >= 0.4 && < 0.5, - deepseq >= 1.1 && <1.2 + deepseq >= 1.1 && <1.2, + template-haskell >= 2.4 && < 2.5 Ghc-options: -Wall Hs-source-dirs: src Exposed-modules: Data.MessagePack + Data.MessagePack.Pack + Data.MessagePack.Unpack Data.MessagePack.Object - Data.MessagePack.Put - Data.MessagePack.Parser Data.MessagePack.Iteratee + Data.MessagePack.Derive Source-repository head Type: git diff --git a/haskell/src/Data/MessagePack.hs b/haskell/src/Data/MessagePack.hs index 7137589..b71190d 100644 --- a/haskell/src/Data/MessagePack.hs +++ b/haskell/src/Data/MessagePack.hs @@ -13,14 +13,11 @@ -------------------------------------------------------------------- module Data.MessagePack( + module Data.MessagePack.Pack, + module Data.MessagePack.Unpack, module Data.MessagePack.Object, - module Data.MessagePack.Put, - module Data.MessagePack.Parser, module Data.MessagePack.Iteratee, - - -- * Simple functions of Pack and Unpack - pack, - unpack, + module Data.MessagePack.Derive, -- * Pack functions packToString, @@ -44,38 +41,18 @@ import qualified Data.Attoparsec as A import Data.Binary.Put import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L -import Data.Functor.Identity import qualified Data.Iteratee as I import System.IO +import Data.MessagePack.Pack +import Data.MessagePack.Unpack import Data.MessagePack.Object -import Data.MessagePack.Put -import Data.MessagePack.Parser import Data.MessagePack.Iteratee +import Data.MessagePack.Derive bufferSize :: Int bufferSize = 4 * 1024 -class IsByteString s where - toBS :: s -> B.ByteString - -instance IsByteString B.ByteString where - toBS = id - -instance IsByteString L.ByteString where - toBS = B.concat . L.toChunks - --- | Pack Haskell data to MessagePack string. -pack :: ObjectPut a => a -> L.ByteString -pack = packToString . put - --- | Unpack MessagePack string to Haskell data. -unpack :: (ObjectGet a, IsByteString s) => s -> a -unpack bs = - runIdentity $ I.run $ I.joinIM $ I.enumPure1Chunk (toBS bs) getI - --- TODO: tryUnpack - -- | Pack to ByteString. packToString :: Put -> L.ByteString packToString = runPut diff --git a/haskell/src/Data/MessagePack/Derive.hs b/haskell/src/Data/MessagePack/Derive.hs new file mode 100644 index 0000000..cfdb658 --- /dev/null +++ b/haskell/src/Data/MessagePack/Derive.hs @@ -0,0 +1,74 @@ +{-# Language TemplateHaskell #-} + +module Data.MessagePack.Derive ( + derivePack, + deriveUnpack, + deriveObject, + ) where + +import Control.Applicative +import Language.Haskell.TH + +import Data.MessagePack.Pack +import Data.MessagePack.Unpack + +deriveUnpack :: Name -> Q [Dec] +deriveUnpack typName = do + TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + + return + [ InstanceD [] (AppT (ConT ''Unpackable) (ConT name)) + [ FunD 'get [Clause [] (NormalB $ ch $ map body cons) []] + ]] + + where + body (NormalC conName elms) = + DoE + [ BindS (tupOrList $ map VarP names) (VarE 'get) + , NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] + where + names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms + + tupOrList ls + | length ls <= 1 = ListP ls + | otherwise = TupP ls + + ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f) + +derivePack :: Name -> Q [Dec] +derivePack typName = do + TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + + return + [ InstanceD [] (AppT (ConT ''Packable) (ConT name)) + [ FunD 'put (map body cons) + ]] + + where + body (NormalC conName elms) = + Clause + [ ConP conName $ map VarP names ] + (NormalB $ AppE (VarE 'put) $ tupOrList $ map VarE names) [] + where + names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms + + tupOrList ls + | length ls <= 1 = ListE ls + | otherwise = TupE ls + +deriveObject :: Name -> Q [Dec] +deriveObject typName = do + g <- derivePack typName + p <- deriveUnpack typName + {- + TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + let o = InstanceD [] (AppT (ConT ''OBJECT) (ConT name)) + [ FunD 'toObject (map toObjectBody cons) ] + -} + return $ g ++ p -- ++ [o] +{- + where + toObjectBody (NormalC conName elms) = + Clause + [ ConP conP +-} diff --git a/haskell/src/Data/MessagePack/Iteratee.hs b/haskell/src/Data/MessagePack/Iteratee.hs index 4258cf6..6bc0898 100644 --- a/haskell/src/Data/MessagePack/Iteratee.hs +++ b/haskell/src/Data/MessagePack/Iteratee.hs @@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.Iteratee as I import System.IO -import Data.MessagePack.Parser +import Data.MessagePack.Unpack -- | Deserialize a value -getI :: (Monad m, ObjectGet a) => I.Iteratee B.ByteString m a +getI :: (Monad m, Unpackable a) => I.Iteratee B.ByteString m a getI = parserToIteratee get -- | Enumerator diff --git a/haskell/src/Data/MessagePack/Object.hs b/haskell/src/Data/MessagePack/Object.hs index 87f24bd..5111ebb 100644 --- a/haskell/src/Data/MessagePack/Object.hs +++ b/haskell/src/Data/MessagePack/Object.hs @@ -1,6 +1,7 @@ {-# Language TypeSynonymInstances #-} {-# Language FlexibleInstances #-} {-# Language OverlappingInstances #-} +{-# Language IncoherentInstances #-} {-# Language DeriveDataTypeable #-} -------------------------------------------------------------------- @@ -23,16 +24,21 @@ module Data.MessagePack.Object( -- * Serialization to and from Object OBJECT(..), - Result, + -- Result, ) where import Control.DeepSeq +import Control.Exception import Control.Monad import Control.Monad.Trans.Error () +import qualified Data.Attoparsec as A import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as C8 import Data.Typeable +import Data.MessagePack.Pack +import Data.MessagePack.Unpack + -- | Object Representation of MessagePack data. data Object = ObjectNil @@ -55,70 +61,241 @@ instance NFData Object where ObjectArray a -> rnf a ObjectMap m -> rnf m +instance Unpackable Object where + get = + A.choice + [ liftM ObjectInteger get + , liftM (\() -> ObjectNil) get + , liftM ObjectBool get + , liftM ObjectDouble get + , liftM ObjectRAW get + , liftM ObjectArray get + , liftM ObjectMap get + ] + +instance Packable Object where + put obj = + case obj of + ObjectInteger n -> + put n + ObjectNil -> + put () + ObjectBool b -> + put b + ObjectDouble d -> + put d + ObjectRAW raw -> + put raw + ObjectArray arr -> + put arr + ObjectMap m -> + put m + -- | The class of types serializable to and from MessagePack object -class OBJECT a where +class (Unpackable a, Packable a) => OBJECT a where -- | Encode a value to MessagePack object toObject :: a -> Object + toObject = unpack . pack + -- | Decode a value from MessagePack object - fromObject :: Object -> Result a + fromObject :: Object -> a + fromObject a = + case tryFromObject a of + Left err -> + throw $ UnpackError err + Right ret -> + ret --- | A type for parser results -type Result a = Either String a + -- | Decode a value from MessagePack object + tryFromObject :: Object -> Either String a + tryFromObject = tryUnpack . pack instance OBJECT Object where toObject = id - fromObject = Right + tryFromObject = Right -fromObjectError :: String -fromObjectError = "fromObject: cannot cast" +tryFromObjectError :: Either String a +tryFromObjectError = Left "tryFromObject: cannot cast" instance OBJECT () where toObject = const ObjectNil - fromObject ObjectNil = Right () - fromObject _ = Left fromObjectError + tryFromObject ObjectNil = Right () + tryFromObject _ = tryFromObjectError instance OBJECT Int where toObject = ObjectInteger - fromObject (ObjectInteger n) = Right n - fromObject _ = Left fromObjectError + tryFromObject (ObjectInteger n) = Right n + tryFromObject _ = tryFromObjectError instance OBJECT Bool where toObject = ObjectBool - fromObject (ObjectBool b) = Right b - fromObject _ = Left fromObjectError + tryFromObject (ObjectBool b) = Right b + tryFromObject _ = tryFromObjectError instance OBJECT Double where toObject = ObjectDouble - fromObject (ObjectDouble d) = Right d - fromObject _ = Left fromObjectError + tryFromObject (ObjectDouble d) = Right d + tryFromObject _ = tryFromObjectError instance OBJECT B.ByteString where toObject = ObjectRAW - fromObject (ObjectRAW bs) = Right bs - fromObject _ = Left fromObjectError + tryFromObject (ObjectRAW bs) = Right bs + tryFromObject _ = tryFromObjectError instance OBJECT String where toObject = toObject . C8.pack - fromObject obj = liftM C8.unpack $ fromObject obj + tryFromObject obj = liftM C8.unpack $ tryFromObject obj instance OBJECT a => OBJECT [a] where toObject = ObjectArray . map toObject - fromObject (ObjectArray arr) = - mapM fromObject arr - fromObject _ = - Left fromObjectError + tryFromObject (ObjectArray arr) = + mapM tryFromObject arr + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2) => OBJECT (a1, a2) where + toObject (a1, a2) = ObjectArray [toObject a1, toObject a2] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + return (v1, v2) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3) => OBJECT (a1, a2, a3) where + toObject (a1, a2, a3) = ObjectArray [toObject a1, toObject a2, toObject a3] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + return (v1, v2, v3) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4) => OBJECT (a1, a2, a3, a4) where + toObject (a1, a2, a3, a4) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + return (v1, v2, v3, v4) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5) => OBJECT (a1, a2, a3, a4, a5) where + toObject (a1, a2, a3, a4, a5) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4, o5] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + v5 <- tryFromObject o5 + return (v1, v2, v3, v4, v5) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6) => OBJECT (a1, a2, a3, a4, a5, a6) where + toObject (a1, a2, a3, a4, a5, a6) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4, o5, o6] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + v5 <- tryFromObject o5 + v6 <- tryFromObject o6 + return (v1, v2, v3, v4, v5, v6) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7) => OBJECT (a1, a2, a3, a4, a5, a6, a7) where + toObject (a1, a2, a3, a4, a5, a6, a7) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4, o5, o6, o7] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + v5 <- tryFromObject o5 + v6 <- tryFromObject o6 + v7 <- tryFromObject o7 + return (v1, v2, v3, v4, v5, v6, v7) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7, OBJECT a8) => OBJECT (a1, a2, a3, a4, a5, a6, a7, a8) where + toObject (a1, a2, a3, a4, a5, a6, a7, a8) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7, toObject a8] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4, o5, o6, o7, o8] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + v5 <- tryFromObject o5 + v6 <- tryFromObject o6 + v7 <- tryFromObject o7 + v8 <- tryFromObject o8 + return (v1, v2, v3, v4, v5, v6, v7, v8) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError + +instance (OBJECT a1, OBJECT a2, OBJECT a3, OBJECT a4, OBJECT a5, OBJECT a6, OBJECT a7, OBJECT a8, OBJECT a9) => OBJECT (a1, a2, a3, a4, a5, a6, a7, a8, a9) where + toObject (a1, a2, a3, a4, a5, a6, a7, a8, a9) = ObjectArray [toObject a1, toObject a2, toObject a3, toObject a4, toObject a5, toObject a6, toObject a7, toObject a8, toObject a9] + tryFromObject (ObjectArray arr) = + case arr of + [o1, o2, o3, o4, o5, o6, o7, o8, o9] -> do + v1 <- tryFromObject o1 + v2 <- tryFromObject o2 + v3 <- tryFromObject o3 + v4 <- tryFromObject o4 + v5 <- tryFromObject o5 + v6 <- tryFromObject o6 + v7 <- tryFromObject o7 + v8 <- tryFromObject o8 + v9 <- tryFromObject o9 + return (v1, v2, v3, v4, v5, v6, v7, v8, v9) + _ -> + tryFromObjectError + tryFromObject _ = + tryFromObjectError instance (OBJECT a, OBJECT b) => OBJECT [(a, b)] where toObject = ObjectMap . map (\(a, b) -> (toObject a, toObject b)) - fromObject (ObjectMap mem) = do - mapM (\(a, b) -> liftM2 (,) (fromObject a) (fromObject b)) mem - fromObject _ = - Left fromObjectError + tryFromObject (ObjectMap mem) = do + mapM (\(a, b) -> liftM2 (,) (tryFromObject a) (tryFromObject b)) mem + tryFromObject _ = + tryFromObjectError instance OBJECT a => OBJECT (Maybe a) where toObject (Just a) = toObject a toObject Nothing = ObjectNil - fromObject ObjectNil = return Nothing - fromObject obj = liftM Just $ fromObject obj + tryFromObject ObjectNil = return Nothing + tryFromObject obj = liftM Just $ tryFromObject obj diff --git a/haskell/src/Data/MessagePack/Put.hs b/haskell/src/Data/MessagePack/Pack.hs similarity index 66% rename from haskell/src/Data/MessagePack/Put.hs rename to haskell/src/Data/MessagePack/Pack.hs index 24ec305..16243ad 100644 --- a/haskell/src/Data/MessagePack/Put.hs +++ b/haskell/src/Data/MessagePack/Pack.hs @@ -5,7 +5,7 @@ -------------------------------------------------------------------- -- | --- Module : Data.MessagePack.Put +-- Module : Data.MessagePack.Pack -- Copyright : (c) Hideyuki Tanaka, 2009-2010 -- License : BSD3 -- @@ -13,13 +13,15 @@ -- Stability : experimental -- Portability: portable -- --- MessagePack Serializer using @Data.Binary.Put@ +-- MessagePack Serializer using @Data.Binary.Pack@ -- -------------------------------------------------------------------- -module Data.MessagePack.Put( +module Data.MessagePack.Pack ( -- * Serializable class - ObjectPut(..), + Packable(..), + -- * Simple function to pack a Haskell value + pack, ) where import Data.Binary.Put @@ -30,32 +32,16 @@ import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as L import qualified Data.Vector as V -import Data.MessagePack.Object - -- | Serializable class -class ObjectPut a where +class Packable a where -- | Serialize a value put :: a -> Put -instance ObjectPut Object where - put obj = - case obj of - ObjectInteger n -> - put n - ObjectNil -> - put () - ObjectBool b -> - put b - ObjectDouble d -> - put d - ObjectRAW raw -> - put raw - ObjectArray arr -> - put arr - ObjectMap m -> - put m +-- | Pack Haskell data to MessagePack string. +pack :: Packable a => a -> L.ByteString +pack = runPut . put -instance ObjectPut Int where +instance Packable Int where put n = case n of _ | n >= 0 && n <= 127 -> @@ -87,26 +73,26 @@ instance ObjectPut Int where putWord8 0xD3 putWord64be $ fromIntegral n -instance ObjectPut () where +instance Packable () where put _ = putWord8 0xC0 -instance ObjectPut Bool where +instance Packable Bool where put True = putWord8 0xC3 put False = putWord8 0xC2 -instance ObjectPut Double where +instance Packable Double where put d = do putWord8 0xCB putFloat64be d -instance ObjectPut String where +instance Packable String where put = putString length (putByteString . B8.pack) -instance ObjectPut B.ByteString where +instance Packable B.ByteString where put = putString B.length putByteString -instance ObjectPut L.ByteString where +instance Packable L.ByteString where put = putString (fromIntegral . L.length) putLazyByteString putString :: (s -> Int) -> (s -> Put) -> s -> Put @@ -122,41 +108,41 @@ putString lf pf str = do putWord32be $ fromIntegral len pf str -instance ObjectPut a => ObjectPut [a] where +instance Packable a => Packable [a] where put = putArray length (mapM_ put) -instance ObjectPut a => ObjectPut (V.Vector a) where +instance Packable a => Packable (V.Vector a) where put = putArray V.length (V.mapM_ put) -instance (ObjectPut a1, ObjectPut a2) => ObjectPut (a1, a2) where +instance (Packable a1, Packable a2) => Packable (a1, a2) where put = putArray (const 2) f where f (a1, a2) = put a1 >> put a2 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3) => ObjectPut (a1, a2, a3) where +instance (Packable a1, Packable a2, Packable a3) => Packable (a1, a2, a3) where put = putArray (const 3) f where f (a1, a2, a3) = put a1 >> put a2 >> put a3 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4) => ObjectPut (a1, a2, a3, a4) where +instance (Packable a1, Packable a2, Packable a3, Packable a4) => Packable (a1, a2, a3, a4) where put = putArray (const 4) f where f (a1, a2, a3, a4) = put a1 >> put a2 >> put a3 >> put a4 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5) => ObjectPut (a1, a2, a3, a4, a5) where +instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5) => Packable (a1, a2, a3, a4, a5) where put = putArray (const 5) f where f (a1, a2, a3, a4, a5) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6) => ObjectPut (a1, a2, a3, a4, a5, a6) where +instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6) => Packable (a1, a2, a3, a4, a5, a6) where put = putArray (const 6) f where f (a1, a2, a3, a4, a5, a6) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7) => ObjectPut (a1, a2, a3, a4, a5, a6, a7) where +instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7) => Packable (a1, a2, a3, a4, a5, a6, a7) where put = putArray (const 7) f where f (a1, a2, a3, a4, a5, a6, a7) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8) where +instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7, Packable a8) => Packable (a1, a2, a3, a4, a5, a6, a7, a8) where put = putArray (const 8) f where f (a1, a2, a3, a4, a5, a6, a7, a8) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8 -instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8, ObjectPut a9) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8, a9) where +instance (Packable a1, Packable a2, Packable a3, Packable a4, Packable a5, Packable a6, Packable a7, Packable a8, Packable a9) => Packable (a1, a2, a3, a4, a5, a6, a7, a8, a9) where put = putArray (const 9) f where f (a1, a2, a3, a4, a5, a6, a7, a8, a9) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8 >> put a9 @@ -173,13 +159,13 @@ putArray lf pf arr = do putWord32be $ fromIntegral len pf arr -instance (ObjectPut k, ObjectPut v) => ObjectPut [(k, v)] where +instance (Packable k, Packable v) => Packable [(k, v)] where put = putMap length (mapM_ putPair) -instance (ObjectPut k, ObjectPut v) => ObjectPut (V.Vector (k, v)) where +instance (Packable k, Packable v) => Packable (V.Vector (k, v)) where put = putMap V.length (V.mapM_ putPair) -putPair :: (ObjectPut a, ObjectPut b) => (a, b) -> Put +putPair :: (Packable a, Packable b) => (a, b) -> Put putPair (a, b) = put a >> put b putMap :: (a -> Int) -> (a -> Put) -> a -> Put @@ -194,3 +180,7 @@ putMap lf pf m = do putWord8 0xDF putWord32be $ fromIntegral len pf m + +instance Packable a => Packable (Maybe a) where + put Nothing = put () + put (Just a) = put a diff --git a/haskell/src/Data/MessagePack/Parser.hs b/haskell/src/Data/MessagePack/Unpack.hs similarity index 70% rename from haskell/src/Data/MessagePack/Parser.hs rename to haskell/src/Data/MessagePack/Unpack.hs index 200ad96..a0d618e 100644 --- a/haskell/src/Data/MessagePack/Parser.hs +++ b/haskell/src/Data/MessagePack/Unpack.hs @@ -2,10 +2,11 @@ {-# Language IncoherentInstances #-} {-# Language OverlappingInstances #-} {-# Language TypeSynonymInstances #-} +{-# Language DeriveDataTypeable #-} -------------------------------------------------------------------- -- | --- Module : Data.MessagePack.Parser +-- Module : Data.MessagePack.Unpack -- Copyright : (c) Hideyuki Tanaka, 2009-2010 -- License : BSD3 -- @@ -17,11 +18,19 @@ -- -------------------------------------------------------------------- -module Data.MessagePack.Parser( +module Data.MessagePack.Unpack( -- * MessagePack deserializer - ObjectGet(..), + Unpackable(..), + -- * Simple function to unpack a Haskell value + unpack, + tryUnpack, + -- * Unpack exception + UnpackError(..), + -- * ByteString utils + IsByteString(..), ) where +import Control.Exception import Control.Monad import qualified Data.Attoparsec as A import Data.Binary.Get @@ -31,30 +40,53 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as L import Data.Int +import Data.Typeable import qualified Data.Vector as V import Data.Word import Text.Printf -import Data.MessagePack.Object - -- | Deserializable class -class ObjectGet a where +class Unpackable a where -- | Deserialize a value get :: A.Parser a -instance ObjectGet Object where - get = - A.choice - [ liftM ObjectInteger get - , liftM (\() -> ObjectNil) get - , liftM ObjectBool get - , liftM ObjectDouble get - , liftM ObjectRAW get - , liftM ObjectArray get - , liftM ObjectMap get - ] +class IsByteString s where + toBS :: s -> B.ByteString -instance ObjectGet Int where +instance IsByteString B.ByteString where + toBS = id + +instance IsByteString L.ByteString where + toBS = B.concat . L.toChunks + +-- | The exception of unpack +data UnpackError = + UnpackError String + deriving (Show, Typeable) + +instance Exception UnpackError + +-- | Unpack MessagePack string to Haskell data. +unpack :: (Unpackable a, IsByteString s) => s -> a +unpack bs = + case tryUnpack bs of + Left err -> + throw $ UnpackError err + Right ret -> + ret + +-- | Unpack MessagePack string to Haskell data. +tryUnpack :: (Unpackable a, IsByteString s) => s -> Either String a +tryUnpack bs = + case A.parse get (toBS bs) of + A.Fail _ _ err -> + Left err + A.Partial _ -> + Left "not enough input" + A.Done _ ret -> + Right ret + +instance Unpackable Int where get = do c <- A.anyWord8 case c of @@ -81,7 +113,7 @@ instance ObjectGet Int where _ -> fail $ printf "invlid integer tag: 0x%02X" c -instance ObjectGet () where +instance Unpackable () where get = do c <- A.anyWord8 case c of @@ -90,7 +122,7 @@ instance ObjectGet () where _ -> fail $ printf "invlid nil tag: 0x%02X" c -instance ObjectGet Bool where +instance Unpackable Bool where get = do c <- A.anyWord8 case c of @@ -101,7 +133,7 @@ instance ObjectGet Bool where _ -> fail $ printf "invlid bool tag: 0x%02X" c -instance ObjectGet Double where +instance Unpackable Double where get = do c <- A.anyWord8 case c of @@ -112,13 +144,13 @@ instance ObjectGet Double where _ -> fail $ printf "invlid double tag: 0x%02X" c -instance ObjectGet String where +instance Unpackable String where get = parseString (\n -> return . B8.unpack =<< A.take n) -instance ObjectGet B.ByteString where +instance Unpackable B.ByteString where get = parseString A.take -instance ObjectGet L.ByteString where +instance Unpackable L.ByteString where get = parseString (\n -> do bs <- A.take n; return $ L.fromChunks [bs]) parseString :: (Int -> A.Parser a) -> A.Parser a @@ -134,48 +166,48 @@ parseString aget = do _ -> fail $ printf "invlid raw tag: 0x%02X" c -instance ObjectGet a => ObjectGet [a] where +instance Unpackable a => Unpackable [a] where get = parseArray (flip replicateM get) -instance ObjectGet a => ObjectGet (V.Vector a) where +instance Unpackable a => Unpackable (V.Vector a) where get = parseArray (flip V.replicateM get) -instance (ObjectGet a1, ObjectGet a2) => ObjectGet (a1, a2) where +instance (Unpackable a1, Unpackable a2) => Unpackable (a1, a2) where get = parseArray f where f 2 = get >>= \a1 -> get >>= \a2 -> return (a1, a2) f n = fail $ printf "wrong tupple size: expected 2 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3) => ObjectGet (a1, a2, a3) where +instance (Unpackable a1, Unpackable a2, Unpackable a3) => Unpackable (a1, a2, a3) where get = parseArray f where f 3 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> return (a1, a2, a3) f n = fail $ printf "wrong tupple size: expected 3 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4) => ObjectGet (a1, a2, a3, a4) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4) => Unpackable (a1, a2, a3, a4) where get = parseArray f where f 4 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> return (a1, a2, a3, a4) f n = fail $ printf "wrong tupple size: expected 4 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5) => ObjectGet (a1, a2, a3, a4, a5) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5) => Unpackable (a1, a2, a3, a4, a5) where get = parseArray f where f 5 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> return (a1, a2, a3, a4, a5) f n = fail $ printf "wrong tupple size: expected 5 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6) => ObjectGet (a1, a2, a3, a4, a5, a6) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6) => Unpackable (a1, a2, a3, a4, a5, a6) where get = parseArray f where f 6 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> return (a1, a2, a3, a4, a5, a6) f n = fail $ printf "wrong tupple size: expected 6 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7) => ObjectGet (a1, a2, a3, a4, a5, a6, a7) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7) => Unpackable (a1, a2, a3, a4, a5, a6, a7) where get = parseArray f where f 7 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> return (a1, a2, a3, a4, a5, a6, a7) f n = fail $ printf "wrong tupple size: expected 7 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7, Unpackable a8) => Unpackable (a1, a2, a3, a4, a5, a6, a7, a8) where get = parseArray f where f 8 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> return (a1, a2, a3, a4, a5, a6, a7, a8) f n = fail $ printf "wrong tupple size: expected 8 but got " n -instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8, ObjectGet a9) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8, a9) where +instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5, Unpackable a6, Unpackable a7, Unpackable a8, Unpackable a9) => Unpackable (a1, a2, a3, a4, a5, a6, a7, a8, a9) where get = parseArray f where f 9 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> get >>= \a9 -> return (a1, a2, a3, a4, a5, a6, a7, a8, a9) f n = fail $ printf "wrong tupple size: expected 9 but got " n @@ -193,13 +225,13 @@ parseArray aget = do _ -> fail $ printf "invlid array tag: 0x%02X" c -instance (ObjectGet k, ObjectGet v) => ObjectGet [(k, v)] where +instance (Unpackable k, Unpackable v) => Unpackable [(k, v)] where get = parseMap (flip replicateM parsePair) -instance (ObjectGet k, ObjectGet v) => ObjectGet (V.Vector (k, v)) where +instance (Unpackable k, Unpackable v) => Unpackable (V.Vector (k, v)) where get = parseMap (flip V.replicateM parsePair) -parsePair :: (ObjectGet k, ObjectGet v) => A.Parser (k, v) +parsePair :: (Unpackable k, Unpackable v) => A.Parser (k, v) parsePair = do a <- get b <- get @@ -218,6 +250,12 @@ parseMap aget = do _ -> fail $ printf "invlid map tag: 0x%02X" c +instance Unpackable a => Unpackable (Maybe a) where + get = + A.choice + [ liftM Just get + , liftM (\() -> Nothing) get ] + parseUint16 :: A.Parser Word16 parseUint16 = do b0 <- A.anyWord8 diff --git a/haskell/test/UserData.hs b/haskell/test/UserData.hs new file mode 100644 index 0000000..8aced13 --- /dev/null +++ b/haskell/test/UserData.hs @@ -0,0 +1,19 @@ +{-# Language TemplateHaskell #-} + +import Data.MessagePack +import Data.MessagePack.Derive + +data T + = A Int String + | B Double + deriving (Show) + +$(deriveObject ''T) + +main = do + let bs = pack $ A 123 "hoge" + print bs + print (unpack bs :: T) + let cs = pack $ B 3.14 + print cs + print (unpack cs :: T) From 13b6708a099c1e3a6f498f9f4899b6b139c112d4 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Thu, 23 Sep 2010 15:24:12 +0900 Subject: [PATCH 06/19] java: append a code for generating a messageConvert method to annotation-utilities --- .../util/annotation/PackUnpackUtil.java | 882 ++++++++++++++++-- .../annotation/TestMessagePackUnpackable.java | 243 ++++- 2 files changed, 1045 insertions(+), 80 deletions(-) diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java index 5238444..a337ff9 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java @@ -11,6 +11,7 @@ import java.lang.reflect.ParameterizedType; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,6 +26,7 @@ import javassist.CtNewMethod; import javassist.NotFoundException; import org.msgpack.MessageConvertable; +import org.msgpack.MessagePackObject; import org.msgpack.MessagePackable; import org.msgpack.MessageTypeException; import org.msgpack.MessageUnpackable; @@ -43,37 +45,6 @@ public class PackUnpackUtil { static final String KEYWORD_NEW = "new"; - static final String TYPE_NAME_VOID = void.class.getName(); - - static final String TYPE_NAME_OBJECT = Object.class.getName(); - - static final String TYPE_NAME_IOEXCEPTION = IOException.class.getName(); - - static final String TYPE_NAME_PACKER = Packer.class.getName(); - - static final String TYPE_NAME_UNPACKER = Unpacker.class.getName(); - - static final String TYPE_NAME_MSGPACKABLE = MessagePackable.class - .getName(); - - static final String TYPE_NAME_MSGUNPACKABLE = MessageUnpackable.class - .getName(); - - static final String TYPE_NAME_MSGCONVERTABLE = MessageConvertable.class - .getName(); - - static final String TYPE_NAME_MSGTYPEEXCEPTION = MessageTypeException.class - .getName(); - - static final String TYPE_NAME_MSGPACKUNPACKABLE = MessagePackUnpackable.class - .getName(); - - static final String TYPE_NAME_MSGPACKOPTIONAL = MessagePackOptional.class - .getName(); - - static final String TYPE_NAME_MSGPACKOREQUIRED = MessagePackRequired.class - .getName(); - static final String CHAR_NAME_SPACE = " "; static final String CHAR_NAME_COMMA = ","; @@ -92,15 +63,27 @@ public class PackUnpackUtil { static final String CHAR_NAME_LEFT_CURLY_BRACHET = "{"; + static final String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]"; + + static final String CHAR_NAME_LEFT_SQUARE_BRACKET = "["; + static final String CHAR_NAME_DOT = "."; static final String CHAR_NAME_SEMICOLON = ";"; - static final String VARIABLE_NAME_PK = "pk"; + static final String VARIABLE_NAME_PK = "_$$_pk"; - static final String VARIABLE_NAME_OBJ = "obj"; + static final String VARIABLE_NAME_SIZE = "_$$_len"; - static final String VARIABLE_NAME_SIZE = "len"; + static final String VARIABLE_NAME_ARRAY = "_$$_ary"; + + static final String VARIABLE_NAME_LIST = "_$$_list"; + + static final String VARIABLE_NAME_MAP = "_$$_map"; + + static final String VARIABLE_NAME_ITER = "_$$_iter"; + + static final String VARIABLE_NAME_MPO1 = "_$$_mpo1"; static final String VARIABLE_NAME_I = "i"; @@ -110,6 +93,18 @@ public class PackUnpackUtil { static final String METHOD_NAME_PUT = "put"; + static final String METHOD_NAME_GET = "get"; + + static final String METHOD_NAME_SIZE = "size"; + + static final String METHOD_NAME_KEYSET = "keySet"; + + static final String METHOD_NAME_ITERATOR = "iterator"; + + static final String METHOD_NAME_HASNEXT = "hasNext"; + + static final String METHOD_NAME_NEXT = "next"; + static final String METHOD_NAME_MSGPACK = "messagePack"; static final String METHOD_NAME_MSGUNPACK = "messageUnpack"; @@ -147,6 +142,8 @@ public class PackUnpackUtil { static final String METHOD_NAME_UNPACKARRAY = "unpackArray"; static final String METHOD_NAME_UNPACKMAP = "unpackMap"; + + static final String METHOD_NAME_ASARRAY = "asArray"; } public static class Enhancer { @@ -180,9 +177,9 @@ public class PackUnpackUtil { setInterfaces(enhCtClass); addConstructor(enhCtClass); Field[] fields = getDeclaredFields(origClass); - addMessagePackMethod(enhCtClass, origCtClass, fields); - addMessageUnpackMethod(enhCtClass, origCtClass, fields); - addMessageConvertMethod(enhCtClass, origCtClass, fields); + addMessagePackMethod(enhCtClass, fields); + addMessageUnpackMethod(enhCtClass, fields); + addMessageConvertMethod(enhCtClass, fields); return createClass(enhCtClass); } @@ -243,11 +240,11 @@ public class PackUnpackUtil { } private void setInterfaces(CtClass enhCtClass) throws NotFoundException { - CtClass pacCtClass = pool.get(Constants.TYPE_NAME_MSGPACKABLE); + CtClass pacCtClass = pool.get(MessagePackable.class.getName()); enhCtClass.addInterface(pacCtClass); - CtClass unpacCtClass = pool.get(Constants.TYPE_NAME_MSGUNPACKABLE); + CtClass unpacCtClass = pool.get(MessageUnpackable.class.getName()); enhCtClass.addInterface(unpacCtClass); - CtClass convCtClass = pool.get(Constants.TYPE_NAME_MSGCONVERTABLE); + CtClass convCtClass = pool.get(MessageConvertable.class.getName()); enhCtClass.addInterface(convCtClass); } @@ -296,24 +293,23 @@ public class PackUnpackUtil { + field.getName()); } - private void addMessagePackMethod(CtClass enhCtClass, - CtClass origCtClass, Field[] fields) + private void addMessagePackMethod(CtClass enhCtClass, Field[] fields) throws CannotCompileException, NotFoundException { StringBuilder sb = new StringBuilder(); sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.TYPE_NAME_VOID); + sb.append(void.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.METHOD_NAME_MSGPACK); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.TYPE_NAME_PACKER); + sb.append(Packer.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.VARIABLE_NAME_PK); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.KEYWORD_THROWS); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.TYPE_NAME_IOEXCEPTION); + sb.append(IOException.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); sb.append(Constants.CHAR_NAME_SPACE); @@ -329,7 +325,7 @@ public class PackUnpackUtil { insertCodeOfMessagePack(sb, field); } sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - //System.out.println("messagePack method: " + sb.toString()); + // System.out.println("messagePack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); enhCtClass.addMethod(newCtMethod); } @@ -345,27 +341,26 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } - private void addMessageUnpackMethod(CtClass enhCtClass, - CtClass origCtClass, Field[] fields) + private void addMessageUnpackMethod(CtClass enhCtClass, Field[] fields) throws CannotCompileException, NotFoundException { StringBuilder sb = new StringBuilder(); sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.TYPE_NAME_VOID); + sb.append(void.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.METHOD_NAME_MSGUNPACK); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.TYPE_NAME_UNPACKER); + sb.append(Unpacker.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.VARIABLE_NAME_PK); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.KEYWORD_THROWS); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.TYPE_NAME_MSGTYPEEXCEPTION); + sb.append(MessageTypeException.class.getName()); sb.append(Constants.CHAR_NAME_COMMA); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.TYPE_NAME_IOEXCEPTION); + sb.append(IOException.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); sb.append(Constants.CHAR_NAME_SPACE); @@ -380,7 +375,7 @@ public class PackUnpackUtil { insertCodeOfMessageUnpack(sb, field, field.getType()); } sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - //System.out.println("messageUnpack method: " + sb.toString()); + // System.out.println("messageUnpack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); enhCtClass.addMethod(newCtMethod); } @@ -680,33 +675,761 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } - private void addMessageConvertMethod(CtClass enhCtClass, - CtClass origCtClass, Field[] fields) + private void addMessageConvertMethod(CtClass enhCtClass, Field[] fields) throws CannotCompileException { + // messageConvert(MessagePackObject obj) throws MessageTypeException StringBuilder sb = new StringBuilder(); - sb.append(Constants.KEYWORD_MODIFIER_PUBLIC).append( - Constants.CHAR_NAME_SPACE).append(Constants.TYPE_NAME_VOID) - .append(Constants.CHAR_NAME_SPACE).append( - Constants.METHOD_NAME_MSGCONVERT).append( - Constants.CHAR_NAME_LEFT_PARENTHESIS).append( - Constants.TYPE_NAME_OBJECT).append( - Constants.CHAR_NAME_SPACE).append( - Constants.VARIABLE_NAME_OBJ).append( - Constants.CHAR_NAME_RIGHT_PARENTHESIS).append( - Constants.CHAR_NAME_SPACE).append( - Constants.KEYWORD_THROWS).append( - Constants.CHAR_NAME_SPACE).append( - Constants.TYPE_NAME_MSGTYPEEXCEPTION).append( - Constants.CHAR_NAME_SPACE).append( - Constants.CHAR_NAME_LEFT_CURLY_BRACHET).append( - Constants.CHAR_NAME_SPACE); - // TODO + sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(void.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.METHOD_NAME_MSGCONVERT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MPO1); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_THROWS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(MessageTypeException.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + insertCodeOfMessagePackObjectArrayGet(sb); + insertCodeOfMesageConvertCalls(sb, fields); sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); //System.out.println("messageConvert method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); enhCtClass.addMethod(newCtMethod); } + private void insertCodeOfMessagePackObjectArrayGet(StringBuilder sb) { + // MessagePackObject[] ary = obj.asArray(); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MPO1); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ASARRAY); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + + private void insertCodeOfMesageConvertCalls(StringBuilder sb, + Field[] fields) { + for (int i = 0; i < fields.length; ++i) { + insertCodeOfMessageConvertCall(sb, fields[i], fields[i] + .getType(), i, null); + } + } + + private void insertCodeOfMessageConvertCall(StringBuilder sb, Field f, + Class c, int i, String name) { + if (c.isPrimitive()) { // primitive type + // f0 = objs[0].intValue(); + if (c.equals(boolean.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asBoolean"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(byte.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asByte"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(short.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asShort"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(int.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asInt"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(long.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asLong"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(float.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asFloat"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(double.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asDouble"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else { + throw new PackUnpackUtilException("fatal error: " + + c.getName()); + } + } else { // reference type + if (c.equals(Boolean.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Boolean.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asBoolean"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Byte.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Byte.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asByte"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Short.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Short.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asShort"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Integer.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Integer.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asInt"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Long.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Long.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asLong"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Float.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Float.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asFloat"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(Double.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Double.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asDouble"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else { + if (c.equals(String.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asString"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(byte[].class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asByteArray"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (c.equals(BigInteger.class)) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asBigInteger"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } else if (List.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForList(sb, f, c, i); + } else if (Map.class.isAssignableFrom(c)) { + insertCodeOfMessageConveretCallForMap(sb, f, c, i); + } else if (MessageConvertable.class.isAssignableFrom(c) + || (getCache(c.getName()) != null)) { + // TODO + // TODO + // TODO + // ((MessageConvertable)f_i).messageConvert(ary[i]); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessageConvertable.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_MSGCONVERT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } else { + throw new MessageTypeException("Type error: " + + c.getName()); + } + } + } + } + + private void insertCodeOfMessageConvertCallForList(StringBuilder sb, + Field field, Class type, int i) { + ParameterizedType generic = (ParameterizedType) field + .getGenericType(); + Class genericType = (Class) generic.getActualTypeArguments()[0]; + + // List list = ary[i].asList(); + sb.append(List.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asList"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // int size = list.size(); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_SIZE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // field initializer + sb.append(field.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(ArrayList.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // for loop + sb.append(Constants.KEYWORD_FOR); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(0); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LESSTHAN); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_PLUS); + sb.append(Constants.CHAR_NAME_PLUS); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + + // block begin + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append("_$$_val"); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_GET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(field.getName()); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ADD); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfMessageConvertCall(sb, null, genericType, -1, "_$$_val"); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + // block end + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + } + + private void insertCodeOfMessageConveretCallForMap(StringBuilder sb, + Field f, Class c, int i) { + ParameterizedType generic = (ParameterizedType) f.getGenericType(); + Class genericType0 = (Class) generic.getActualTypeArguments()[0]; + Class genericType1 = (Class) generic.getActualTypeArguments()[1]; + + // Map map = ary[i].asMap(); + sb.append(Map.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asMap"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // int size = list.size(); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_SIZE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // field initializer + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(HashMap.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // for loop + sb.append(Constants.KEYWORD_FOR); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Iterator.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_KEYSET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ITERATOR); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_HASNEXT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + + // block map. + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append("_$$_key"); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_NEXT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append("_$$_val"); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_GET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append("_$$_key"); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_PUT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfMessageConvertCall(sb, null, genericType0, -1, + "_$$_key"); + sb.append(Constants.CHAR_NAME_COMMA); + sb.append(Constants.CHAR_NAME_SPACE); + insertCodeOfMessageConvertCall(sb, null, genericType1, -1, + "_$$_val"); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + } + private Class createClass(CtClass enhCtClass) throws CannotCompileException { return enhCtClass.toClass(null, null); @@ -749,6 +1472,19 @@ public class PackUnpackUtil { } } + public static Object initEnhancedInstance(MessagePackObject obj, + Class origClass) { + Object ret = newEnhancedInstance(origClass); + ((MessageConvertable) ret).messageConvert(obj); + return ret; + } + + public static Object initEnhancedInstance(MessagePackObject obj, + Object origObj) { + ((MessageConvertable) origObj).messageConvert(obj); + return origObj; + } + @MessagePackUnpackable public static class Image { public String uri = ""; @@ -789,6 +1525,6 @@ public class PackUnpackUtil { ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Unpacker pac = new Unpacker(in); pac.unpack((MessageUnpackable) dst); - //System.out.println(src.equals(dst)); + // System.out.println(src.equals(dst)); } } diff --git a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java index dbea7cb..4b1e666 100644 --- a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java +++ b/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java @@ -12,6 +12,7 @@ import java.util.Map; import junit.framework.TestCase; import org.junit.Test; +import org.msgpack.MessagePackObject; import org.msgpack.MessageUnpackable; import org.msgpack.Packer; import org.msgpack.Unpacker; @@ -19,7 +20,7 @@ import org.msgpack.Unpacker; public class TestMessagePackUnpackable extends TestCase { @Test - public void testPrimitiveTypeFields() throws Exception { + public void testPrimitiveTypeFields01() throws Exception { PrimitiveTypeFieldsClass src = (PrimitiveTypeFieldsClass) PackUnpackUtil .newEnhancedInstance(PrimitiveTypeFieldsClass.class); src.f0 = (byte) 0; @@ -45,6 +46,36 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f6, dst.f6); } + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = (PrimitiveTypeFieldsClass) PackUnpackUtil + .newEnhancedInstance(PrimitiveTypeFieldsClass.class); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) PackUnpackUtil + .initEnhancedInstance(mpo, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertFalse(it.hasNext()); + } + @MessagePackUnpackable public static class PrimitiveTypeFieldsClass { public byte f0; @@ -60,7 +91,7 @@ public class TestMessagePackUnpackable extends TestCase { } @Test - public void testGeneralReferenceTypeFieldsClass() throws Exception { + public void testGeneralReferenceTypeFieldsClass01() throws Exception { GeneralReferenceTypeFieldsClass src = (GeneralReferenceTypeFieldsClass) PackUnpackUtil .newEnhancedInstance(GeneralReferenceTypeFieldsClass.class); src.f0 = 0; @@ -93,6 +124,44 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f9[1], dst.f9[1]); } + @Test + public void testGeneralReferenceTypeFieldsClass02() throws Exception { + GeneralReferenceTypeFieldsClass src = (GeneralReferenceTypeFieldsClass) PackUnpackUtil + .newEnhancedInstance(GeneralReferenceTypeFieldsClass.class); + src.f0 = 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = (long) 3; + src.f4 = (float) 4; + src.f5 = (double) 5; + src.f6 = false; + src.f7 = new BigInteger("7"); + src.f8 = "8"; + src.f9 = new byte[] { 0x01, 0x02 }; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) PackUnpackUtil + .initEnhancedInstance(mpo, + GeneralReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9[0], dst.f9[0]); + assertEquals(src.f9[1], dst.f9[1]); + assertFalse(it.hasNext()); + } + @MessagePackUnpackable public static class GeneralReferenceTypeFieldsClass { public Byte f0; @@ -110,7 +179,7 @@ public class TestMessagePackUnpackable extends TestCase { } } - public void testListTypes() throws Exception { + public void testListTypes01() throws Exception { SampleListTypes src = (SampleListTypes) PackUnpackUtil .newEnhancedInstance(SampleListTypes.class); src.f0 = new ArrayList(); @@ -139,6 +208,39 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f2.get(i), dst.f2.get(i)); } } + + public void testListTypes02() throws Exception { + SampleListTypes src = (SampleListTypes) PackUnpackUtil + .newEnhancedInstance(SampleListTypes.class); + src.f0 = new ArrayList(); + src.f1 = new ArrayList(); + src.f1.add(1); + src.f1.add(2); + src.f1.add(3); + src.f2 = new ArrayList(); + src.f2.add("e1"); + src.f2.add("e2"); + src.f2.add("e3"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + SampleListTypes dst = (SampleListTypes) PackUnpackUtil + .initEnhancedInstance(mpo, SampleListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + for (int i = 0; i < src.f1.size(); ++i) { + assertEquals(src.f1.get(i), dst.f1.get(i)); + } + assertEquals(src.f2.size(), dst.f2.size()); + for (int i = 0; i < src.f2.size(); ++i) { + assertEquals(src.f2.get(i), dst.f2.get(i)); + } + assertFalse(it.hasNext()); + } @MessagePackUnpackable public static class SampleListTypes { @@ -150,7 +252,7 @@ public class TestMessagePackUnpackable extends TestCase { } } - public void testMapTypes() throws Exception { + public void testMapTypes01() throws Exception { SampleMapTypes src = (SampleMapTypes) PackUnpackUtil .newEnhancedInstance(SampleMapTypes.class); src.f0 = new HashMap(); @@ -189,6 +291,49 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f2.get(s2), dst.f2.get(d2)); } } + + public void testMapTypes02() throws Exception { + SampleMapTypes src = (SampleMapTypes) PackUnpackUtil + .newEnhancedInstance(SampleMapTypes.class); + src.f0 = new HashMap(); + src.f1 = new HashMap(); + src.f1.put(1, 1); + src.f1.put(2, 2); + src.f1.put(3, 3); + src.f2 = new HashMap(); + src.f2.put("k1", 1); + src.f2.put("k2", 2); + src.f2.put("k3", 3); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + SampleMapTypes dst = (SampleMapTypes) PackUnpackUtil + .initEnhancedInstance(mpo, SampleMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + Iterator srcf1 = src.f1.keySet().iterator(); + Iterator dstf1 = dst.f1.keySet().iterator(); + while (srcf1.hasNext()) { + Integer s1 = srcf1.next(); + Integer d1 = dstf1.next(); + assertEquals(s1, d1); + assertEquals(src.f1.get(s1), dst.f1.get(d1)); + } + assertEquals(src.f2.size(), dst.f2.size()); + Iterator srcf2 = src.f2.keySet().iterator(); + Iterator dstf2 = dst.f2.keySet().iterator(); + while (srcf2.hasNext()) { + String s2 = srcf2.next(); + String d2 = dstf2.next(); + assertEquals(s2, d2); + assertEquals(src.f2.get(s2), dst.f2.get(d2)); + } + assertFalse(it.hasNext()); + } @MessagePackUnpackable public static class SampleMapTypes { @@ -351,7 +496,7 @@ public class TestMessagePackUnpackable extends TestCase { } @Test - public void testFieldModifiers() throws Exception { + public void testFieldModifiers01() throws Exception { FieldModifiersClass src = (FieldModifiersClass) PackUnpackUtil .newEnhancedInstance(FieldModifiersClass.class); src.f0 = 0; @@ -372,6 +517,31 @@ public class TestMessagePackUnpackable extends TestCase { assertTrue(src.f4 != dst.f4); } + @Test + public void testFieldModifiers02() throws Exception { + FieldModifiersClass src = (FieldModifiersClass) PackUnpackUtil + .newEnhancedInstance(FieldModifiersClass.class); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + FieldModifiersClass dst = (FieldModifiersClass) PackUnpackUtil + .initEnhancedInstance(mpo, FieldModifiersClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 == dst.f3); + assertTrue(src.f4 != dst.f4); + assertFalse(it.hasNext()); + } + @MessagePackUnpackable public static class FieldModifiersClass { public int f0; @@ -385,7 +555,7 @@ public class TestMessagePackUnpackable extends TestCase { } @Test - public void testNestedAnnotatedFieldClass() throws Exception { + public void testNestedAnnotatedFieldClass01() throws Exception { NestedClass src2 = (NestedClass) PackUnpackUtil .newEnhancedInstance(NestedClass.class); BaseClass src = (BaseClass) PackUnpackUtil @@ -407,6 +577,33 @@ public class TestMessagePackUnpackable extends TestCase { assertTrue(src2.f2 == dst.f1.f2); } + @Test + public void testNestedAnnotatedFieldClass02() throws Exception { + NestedClass src2 = (NestedClass) PackUnpackUtil + .newEnhancedInstance(NestedClass.class); + BaseClass src = (BaseClass) PackUnpackUtil + .newEnhancedInstance(BaseClass.class); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + NestedClass dst2 = (NestedClass) PackUnpackUtil + .newEnhancedInstance(NestedClass.class); + BaseClass dst = (BaseClass) PackUnpackUtil + .newEnhancedInstance(BaseClass.class); + dst.f1 = dst2; + dst = (BaseClass) PackUnpackUtil.initEnhancedInstance(mpo, dst); + assertTrue(src.f0 == dst.f0); + assertTrue(src2.f2 == dst.f1.f2); + assertFalse(it.hasNext()); + } + @MessagePackUnpackable public static class BaseClass { public int f0; @@ -425,7 +622,7 @@ public class TestMessagePackUnpackable extends TestCase { } @Test - public void testExtendedClass() throws Exception { + public void testExtendedClass01() throws Exception { SampleSubClass src = (SampleSubClass) PackUnpackUtil .newEnhancedInstance(SampleSubClass.class); src.f0 = 0; @@ -452,6 +649,38 @@ public class TestMessagePackUnpackable extends TestCase { assertTrue(src.f8 == dst.f8); assertTrue(src.f9 != dst.f9); } + + @Test + public void testExtendedClass02() throws Exception { + SampleSubClass src = (SampleSubClass) PackUnpackUtil + .newEnhancedInstance(SampleSubClass.class); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Packer(out).pack(src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Unpacker pac = new Unpacker(in); + Iterator it = pac.iterator(); + assertTrue(it.hasNext()); + MessagePackObject mpo = it.next(); + SampleSubClass dst = (SampleSubClass) PackUnpackUtil + .initEnhancedInstance(mpo, SampleSubClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 == dst.f3); + assertTrue(src.f4 != dst.f4); + assertTrue(src.f5 == dst.f5); + assertTrue(src.f6 == dst.f6); + assertTrue(src.f8 == dst.f8); + assertTrue(src.f9 != dst.f9); + assertFalse(it.hasNext()); + } @MessagePackUnpackable public static class SampleSubClass extends SampleSuperClass { From df8a3e870ae9c350394ded3e2e73f9c0bca023f7 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Thu, 23 Sep 2010 16:18:23 +0900 Subject: [PATCH 07/19] java: refactor annotation-utilities --- .../util/annotation/PackUnpackUtil.java | 678 ++++++------------ 1 file changed, 208 insertions(+), 470 deletions(-) diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java index a337ff9..ddf30b4 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java @@ -81,9 +81,13 @@ public class PackUnpackUtil { static final String VARIABLE_NAME_MAP = "_$$_map"; + static final String VARIABLE_NAME_KEY = "_$$_key"; + + static final String VARIABLE_NAME_VAL = "_$$_val"; + static final String VARIABLE_NAME_ITER = "_$$_iter"; - static final String VARIABLE_NAME_MPO1 = "_$$_mpo1"; + static final String VARIABLE_NAME_MPO = "_$$_mpo"; static final String VARIABLE_NAME_I = "i"; @@ -144,6 +148,26 @@ public class PackUnpackUtil { static final String METHOD_NAME_UNPACKMAP = "unpackMap"; static final String METHOD_NAME_ASARRAY = "asArray"; + + static final String METHOD_NAME_ASBOOLEAN = "asBoolean"; + + static final String METHOD_NAME_ASBYTE = "asByte"; + + static final String METHOD_NAME_ASSHORT = "asShort"; + + static final String METHOD_NAME_ASINT = "asInt"; + + static final String METHOD_NAME_ASFLOAT = "asFloat"; + + static final String METHOD_NAME_ASLONG = "asLong"; + + static final String METHOD_NAME_ASDOUBLE = "asDouble"; + + static final String METHOD_NAME_ASSTRING = "asString"; + + static final String METHOD_NAME_ASBYTEARRAY = "asByteArray"; + + static final String METHOD_NAME_ASBIGINTEGER = "asBigInteger"; } public static class Enhancer { @@ -322,7 +346,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); for (Field field : fields) { - insertCodeOfMessagePack(sb, field); + insertCodeOfMessagePackCall(sb, field); } sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); // System.out.println("messagePack method: " + sb.toString()); @@ -330,7 +354,7 @@ public class PackUnpackUtil { enhCtClass.addMethod(newCtMethod); } - private void insertCodeOfMessagePack(StringBuilder sb, Field field) { + private void insertCodeOfMessagePackCall(StringBuilder sb, Field field) { sb.append(Constants.VARIABLE_NAME_PK); sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_PACK); @@ -371,20 +395,25 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); - for (Field field : fields) { - insertCodeOfMessageUnpack(sb, field, field.getType()); - } + insertCodeOfMessageUnpackCalls(sb, fields); sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); // System.out.println("messageUnpack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); enhCtClass.addMethod(newCtMethod); } - private void insertCodeOfMessageUnpack(StringBuilder sb, Field field, - Class type) throws NotFoundException { + private void insertCodeOfMessageUnpackCalls(StringBuilder sb, + Field[] fields) throws NotFoundException { + for (Field field : fields) { + insertCodeOfMessageUnpackCall(sb, field, field.getType()); + } + } + + private void insertCodeOfMessageUnpackCall(StringBuilder sb, + Field field, Class type) throws NotFoundException { if (type.isPrimitive()) { // primitive type - insertCodeOfMessageUnpackForPrimitiveTypes(sb, field, type); + insertCodeOfMessageUnpackCallForPrimitiveTypes(sb, field, type); } else if (type.equals(Boolean.class) || // Boolean type.equals(Byte.class) || // Byte type.equals(Double.class) || // Double @@ -393,28 +422,29 @@ public class PackUnpackUtil { type.equals(Long.class) || // Long type.equals(Short.class)) { // Short // reference type (wrapper type) - insertCodeOfMessageUnpackForWrapperTypes(sb, field, type); + insertCodeOfMessageUnpackCallForWrapperTypes(sb, field, type); } else if (type.equals(BigInteger.class) || // BigInteger type.equals(String.class) || // String type.equals(byte[].class)) { // byte[] // reference type (other type) - insertCodeOfMessageUnpackForPrimitiveTypes(sb, field, type); + insertCodeOfMessageUnpackCallForPrimitiveTypes(sb, field, type); } else if (List.class.isAssignableFrom(type)) { // List - insertCodeOfMessageUnpackForListType(sb, field, type); + insertCodeOfMessageUnpackCallForListType(sb, field, type); } else if (Map.class.isAssignableFrom(type)) { // Map - insertCodeOfMessageUnpackForMapType(sb, field, type); + insertCodeOfMessageUnpackCallForMapType(sb, field, type); } else if (MessageUnpackable.class.isAssignableFrom(type) || (getCache(type.getName()) != null)) { // MessageUnpackable - insertCodeOfMessageUnpackForMsgUnpackableType(sb, field, type); + insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, field, + type); } else { throw new NotFoundException("unknown type: " + type.getName()); } } - private void insertCodeOfMessageUnpackForPrimitiveTypes( + private void insertCodeOfMessageUnpackCallForPrimitiveTypes( StringBuilder sb, Field field, Class type) throws NotFoundException { // insert a right variable @@ -461,8 +491,9 @@ public class PackUnpackUtil { } } - private void insertCodeOfMessageUnpackForWrapperTypes(StringBuilder sb, - Field field, Class type) throws NotFoundException { + private void insertCodeOfMessageUnpackCallForWrapperTypes( + StringBuilder sb, Field field, Class type) + throws NotFoundException { // insert a right variable if (field != null) { sb.append(field.getName()); @@ -503,7 +534,7 @@ public class PackUnpackUtil { } } - private void insertCodeOfMessageUnpackForListType(StringBuilder sb, + private void insertCodeOfMessageUnpackCallForListType(StringBuilder sb, Field field, Class type) throws NotFoundException { ParameterizedType generic = (ParameterizedType) field .getGenericType(); @@ -570,7 +601,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_ADD); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageUnpack(sb, null, genericType); + insertCodeOfMessageUnpackCall(sb, null, genericType); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); @@ -579,7 +610,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } - private void insertCodeOfMessageUnpackForMapType(StringBuilder sb, + private void insertCodeOfMessageUnpackCallForMapType(StringBuilder sb, Field field, Class type) throws NotFoundException { ParameterizedType generic = (ParameterizedType) field .getGenericType(); @@ -647,10 +678,10 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_PUT); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageUnpack(sb, null, genericType0); + insertCodeOfMessageUnpackCall(sb, null, genericType0); sb.append(Constants.CHAR_NAME_COMMA); sb.append(Constants.CHAR_NAME_SPACE); - insertCodeOfMessageUnpack(sb, null, genericType1); + insertCodeOfMessageUnpackCall(sb, null, genericType1); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); @@ -659,7 +690,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } - private void insertCodeOfMessageUnpackForMsgUnpackableType( + private void insertCodeOfMessageUnpackCallForMsgUnpackableType( StringBuilder sb, Field field, Class type) { // insert a right variable // ignore sb.append(Constants.VARIABLE_NAME_PK); @@ -687,7 +718,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); sb.append(MessagePackObject.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MPO1); + sb.append(Constants.VARIABLE_NAME_MPO); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.KEYWORD_THROWS); @@ -699,7 +730,7 @@ public class PackUnpackUtil { insertCodeOfMessagePackObjectArrayGet(sb); insertCodeOfMesageConvertCalls(sb, fields); sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - //System.out.println("messageConvert method: " + sb.toString()); + // System.out.println("messageConvert method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); enhCtClass.addMethod(newCtMethod); } @@ -714,7 +745,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_EQUAL); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MPO1); + sb.append(Constants.VARIABLE_NAME_MPO); sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_ASARRAY); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); @@ -732,455 +763,161 @@ public class PackUnpackUtil { } private void insertCodeOfMessageConvertCall(StringBuilder sb, Field f, - Class c, int i, String name) { + Class c, int i, String v) { if (c.isPrimitive()) { // primitive type - // f0 = objs[0].intValue(); - if (c.equals(boolean.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asBoolean"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(byte.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asByte"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(short.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asShort"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(int.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asInt"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(long.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asLong"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(float.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asFloat"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(double.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asDouble"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else { - throw new PackUnpackUtilException("fatal error: " - + c.getName()); - } + insertCodeOfMessageConvertCallForPrimTypes(sb, f, c, i, v); } else { // reference type - if (c.equals(Boolean.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Boolean.class.getName()); + if (c.equals(Boolean.class) || c.equals(Byte.class) + || c.equals(Short.class) || c.equals(Integer.class) + || c.equals(Float.class) || c.equals(Long.class) + || c.equals(Double.class)) { + // wrapper type + insertCodeOfMessageConvertCallForWrapTypes(sb, f, c, i, v); + } else if (c.equals(String.class) || c.equals(byte[].class) + || c.equals(BigInteger.class)) { + insertCodeOfMessageConvertCallForPrimTypes(sb, f, c, i, v); + } else if (List.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForList(sb, f, c, i); + } else if (Map.class.isAssignableFrom(c)) { + insertCodeOfMessageConveretCallForMap(sb, f, c, i); + } else if (MessageConvertable.class.isAssignableFrom(c) + || (getCache(c.getName()) != null)) { + // TODO + // TODO + // TODO + // ((MessageConvertable)f_i).messageConvert(ary[i]); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessageConvertable.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_DOT); - sb.append("asBoolean"); + sb.append(Constants.METHOD_NAME_MSGCONVERT); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Byte.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Byte.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asByte"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Short.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Short.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asShort"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Integer.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Integer.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asInt"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Long.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Long.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asLong"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Float.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Float.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asFloat"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(Double.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Double.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asDouble"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } } else { - if (c.equals(String.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asString"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(byte[].class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asByteArray"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (c.equals(BigInteger.class)) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asBigInteger"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } else if (List.class.isAssignableFrom(c)) { - insertCodeOfMessageConvertCallForList(sb, f, c, i); - } else if (Map.class.isAssignableFrom(c)) { - insertCodeOfMessageConveretCallForMap(sb, f, c, i); - } else if (MessageConvertable.class.isAssignableFrom(c) - || (getCache(c.getName()) != null)) { - // TODO - // TODO - // TODO - // ((MessageConvertable)f_i).messageConvert(ary[i]); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessageConvertable.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_MSGCONVERT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } else { - throw new MessageTypeException("Type error: " - + c.getName()); - } + throw new MessageTypeException("Type error: " + c.getName()); } } } + private void insertCodeOfMessageConvertCallForPrimTypes( + StringBuilder sb, Field f, Class c, int i, String name) { + // f0 = objs[0].intValue(); + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + if (c.equals(boolean.class)) { + sb.append(Constants.METHOD_NAME_ASBOOLEAN); + } else if (c.equals(byte.class)) { + sb.append(Constants.METHOD_NAME_ASBYTE); + } else if (c.equals(short.class)) { + sb.append(Constants.METHOD_NAME_ASSHORT); + } else if (c.equals(int.class)) { + sb.append(Constants.METHOD_NAME_ASINT); + } else if (c.equals(float.class)) { + sb.append(Constants.METHOD_NAME_ASFLOAT); + } else if (c.equals(long.class)) { + sb.append(Constants.METHOD_NAME_ASLONG); + } else if (c.equals(double.class)) { + sb.append(Constants.METHOD_NAME_ASDOUBLE); + } else if (c.equals(String.class)) { + sb.append(Constants.METHOD_NAME_ASSTRING); + } else if (c.equals(byte[].class)) { + sb.append(Constants.METHOD_NAME_ASBYTEARRAY); + } else if (c.equals(BigInteger.class)) { + sb.append(Constants.METHOD_NAME_ASBIGINTEGER); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } + + private void insertCodeOfMessageConvertCallForWrapTypes( + StringBuilder sb, Field f, Class c, int i, String v) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + if (c.equals(Boolean.class)) { + sb.append(Boolean.class.getName()); + } else if (c.equals(Byte.class)) { + sb.append(Byte.class.getName()); + } else if (c.equals(Short.class)) { + sb.append(Short.class.getName()); + } else if (c.equals(Integer.class)) { + sb.append(Integer.class.getName()); + } else if (c.equals(Float.class)) { + sb.append(Float.class.getName()); + } else if (c.equals(Long.class)) { + sb.append(Long.class.getName()); + } else if (c.equals(Double.class)) { + sb.append(Double.class.getName()); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(v); + } + sb.append(Constants.CHAR_NAME_DOT); + if (c.equals(Boolean.class)) { + sb.append(Constants.METHOD_NAME_ASBOOLEAN); + } else if (c.equals(Byte.class)) { + sb.append(Constants.METHOD_NAME_ASBYTE); + } else if (c.equals(Short.class)) { + sb.append(Constants.METHOD_NAME_ASSHORT); + } else if (c.equals(Integer.class)) { + sb.append(Constants.METHOD_NAME_ASINT); + } else if (c.equals(Float.class)) { + sb.append(Constants.METHOD_NAME_ASFLOAT); + } else if (c.equals(Long.class)) { + sb.append(Constants.METHOD_NAME_ASLONG); + } else if (c.equals(Double.class)) { + sb.append(Constants.METHOD_NAME_ASDOUBLE); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } + private void insertCodeOfMessageConvertCallForList(StringBuilder sb, Field field, Class type, int i) { ParameterizedType generic = (ParameterizedType) field @@ -1264,7 +1001,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); sb.append(MessagePackObject.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); - sb.append("_$$_val"); + sb.append(Constants.VARIABLE_NAME_VAL); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_EQUAL); sb.append(Constants.CHAR_NAME_SPACE); @@ -1284,7 +1021,8 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_ADD); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageConvertCall(sb, null, genericType, -1, "_$$_val"); + insertCodeOfMessageConvertCall(sb, null, genericType, -1, + Constants.VARIABLE_NAME_VAL); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); @@ -1380,7 +1118,7 @@ public class PackUnpackUtil { // block map. sb.append(MessagePackObject.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); - sb.append("_$$_key"); + sb.append(Constants.VARIABLE_NAME_KEY); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_EQUAL); sb.append(Constants.CHAR_NAME_SPACE); @@ -1396,7 +1134,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); sb.append(MessagePackObject.class.getName()); sb.append(Constants.CHAR_NAME_SPACE); - sb.append("_$$_val"); + sb.append(Constants.VARIABLE_NAME_VAL); sb.append(Constants.CHAR_NAME_SPACE); sb.append(Constants.CHAR_NAME_EQUAL); sb.append(Constants.CHAR_NAME_SPACE); @@ -1407,7 +1145,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_DOT); sb.append(Constants.METHOD_NAME_GET); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append("_$$_key"); + sb.append(Constants.VARIABLE_NAME_KEY); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); @@ -1417,11 +1155,11 @@ public class PackUnpackUtil { sb.append(Constants.METHOD_NAME_PUT); sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); insertCodeOfMessageConvertCall(sb, null, genericType0, -1, - "_$$_key"); + Constants.VARIABLE_NAME_KEY); sb.append(Constants.CHAR_NAME_COMMA); sb.append(Constants.CHAR_NAME_SPACE); insertCodeOfMessageConvertCall(sb, null, genericType1, -1, - "_$$_val"); + Constants.VARIABLE_NAME_VAL); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); From e121f344077bad630fbe4c249c5c80f6a3932a35 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Thu, 23 Sep 2010 17:26:31 +0900 Subject: [PATCH 08/19] java: refactor annotation-utilities and edit those test programs --- .../util/annotation/PackUnpackUtil.java | 182 +++++++++++++----- .../annotation/TestMessagePackUnpackable.java | 17 +- 2 files changed, 134 insertions(+), 65 deletions(-) diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java index ddf30b4..6e6a665 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java @@ -41,10 +41,14 @@ public class PackUnpackUtil { static final String KEYWORD_FOR = "for"; + static final String KEYWORD_IF = "if"; + static final String KEYWORD_THROWS = "throws"; static final String KEYWORD_NEW = "new"; + static final String KEYWORD_NULL = "null"; + static final String CHAR_NAME_SPACE = " "; static final String CHAR_NAME_COMMA = ","; @@ -409,42 +413,43 @@ public class PackUnpackUtil { } } - private void insertCodeOfMessageUnpackCall(StringBuilder sb, - Field field, Class type) throws NotFoundException { - if (type.isPrimitive()) { + private void insertCodeOfMessageUnpackCall(StringBuilder sb, Field f, + Class c) throws NotFoundException { + if (c.isPrimitive()) { // primitive type - insertCodeOfMessageUnpackCallForPrimitiveTypes(sb, field, type); - } else if (type.equals(Boolean.class) || // Boolean - type.equals(Byte.class) || // Byte - type.equals(Double.class) || // Double - type.equals(Float.class) || // Float - type.equals(Integer.class) || // Integer - type.equals(Long.class) || // Long - type.equals(Short.class)) { // Short + insertCodeOfMessageUnpackCallForPrimTypes(sb, f, c); + } else if (c.equals(Boolean.class) || // Boolean + c.equals(Byte.class) || // Byte + c.equals(Double.class) || // Double + c.equals(Float.class) || // Float + c.equals(Integer.class) || // Integer + c.equals(Long.class) || // Long + c.equals(Short.class)) { // Short // reference type (wrapper type) - insertCodeOfMessageUnpackCallForWrapperTypes(sb, field, type); - } else if (type.equals(BigInteger.class) || // BigInteger - type.equals(String.class) || // String - type.equals(byte[].class)) { // byte[] + insertCodeOfMessageUnpackCallForWrapTypes(sb, f, c); + } else if (c.equals(BigInteger.class) || // BigInteger + c.equals(String.class) || // String + c.equals(byte[].class)) { // byte[] // reference type (other type) - insertCodeOfMessageUnpackCallForPrimitiveTypes(sb, field, type); - } else if (List.class.isAssignableFrom(type)) { + insertCodeOfMessageUnpackCallForPrimTypes(sb, f, c); + } else if (List.class.isAssignableFrom(c)) { // List - insertCodeOfMessageUnpackCallForListType(sb, field, type); - } else if (Map.class.isAssignableFrom(type)) { + insertCodeOfMessageUnpackCallForListType(sb, f, c); + } else if (Map.class.isAssignableFrom(c)) { // Map - insertCodeOfMessageUnpackCallForMapType(sb, field, type); - } else if (MessageUnpackable.class.isAssignableFrom(type) - || (getCache(type.getName()) != null)) { + insertCodeOfMessageUnpackCallForMapType(sb, f, c); + } else if (getCache(c.getName()) != null) { + // cached + insertCodeOfMessageUnpackCallForEnhancedType(sb, f, c); + } else if (MessageUnpackable.class.isAssignableFrom(c)) { // MessageUnpackable - insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, field, - type); + insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); } else { - throw new NotFoundException("unknown type: " + type.getName()); + throw new NotFoundException("unknown type: " + c.getName()); } } - private void insertCodeOfMessageUnpackCallForPrimitiveTypes( + private void insertCodeOfMessageUnpackCallForPrimTypes( StringBuilder sb, Field field, Class type) throws NotFoundException { // insert a right variable @@ -491,7 +496,7 @@ public class PackUnpackUtil { } } - private void insertCodeOfMessageUnpackCallForWrapperTypes( + private void insertCodeOfMessageUnpackCallForWrapTypes( StringBuilder sb, Field field, Class type) throws NotFoundException { // insert a right variable @@ -690,8 +695,42 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } + private void insertCodeOfMessageUnpackCallForEnhancedType( + StringBuilder sb, Field f, Class c) { + c = this.getCache(c.getName()); + insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); + } + private void insertCodeOfMessageUnpackCallForMsgUnpackableType( - StringBuilder sb, Field field, Class type) { + StringBuilder sb, Field f, Class c) { + // if (fi == null) { fi = new Foo_$$_Enhanced(); } + sb.append(Constants.KEYWORD_IF); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NULL); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(c.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + // insert a right variable // ignore sb.append(Constants.VARIABLE_NAME_PK); sb.append(Constants.CHAR_NAME_DOT); @@ -700,7 +739,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); sb.append(MessageUnpackable.class.getName()); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(field.getName()); + sb.append(f.getName()); sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); sb.append(Constants.CHAR_NAME_SEMICOLON); sb.append(Constants.CHAR_NAME_SPACE); @@ -779,35 +818,72 @@ public class PackUnpackUtil { } else if (List.class.isAssignableFrom(c)) { insertCodeOfMessageConvertCallForList(sb, f, c, i); } else if (Map.class.isAssignableFrom(c)) { - insertCodeOfMessageConveretCallForMap(sb, f, c, i); - } else if (MessageConvertable.class.isAssignableFrom(c) - || (getCache(c.getName()) != null)) { - // TODO - // TODO - // TODO - // ((MessageConvertable)f_i).messageConvert(ary[i]); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessageConvertable.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_MSGCONVERT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); + insertCodeOfMessageConvertCallForMap(sb, f, c, i); + } else if ((getCache(c.getName()) != null)) { + insertCodeOfMessageConvertCallForEnhancedType(sb, f, c, i); + } else if (MessageConvertable.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); } else { throw new MessageTypeException("Type error: " + c.getName()); } } } + private void insertCodeOfMessageConvertCallForEnhancedType( + StringBuilder sb, Field f, Class c, int i) { + c = getCache(c.getName()); + insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); + } + + private void insertCodeOfMessageConvertCallForMsgConvtblType( + StringBuilder sb, Field f, Class c, int i) { + // if (fi == null) { fi = new Foo_$$_Enhanced(); } + sb.append(Constants.KEYWORD_IF); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NULL); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(c.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); + sb.append(Constants.CHAR_NAME_SPACE); + + // ((MessageConvertable)f_i).messageConvert(ary[i]); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessageConvertable.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_MSGCONVERT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + private void insertCodeOfMessageConvertCallForPrimTypes( StringBuilder sb, Field f, Class c, int i, String name) { // f0 = objs[0].intValue(); @@ -1031,7 +1107,7 @@ public class PackUnpackUtil { sb.append(Constants.CHAR_NAME_SPACE); } - private void insertCodeOfMessageConveretCallForMap(StringBuilder sb, + private void insertCodeOfMessageConvertCallForMap(StringBuilder sb, Field f, Class c, int i) { ParameterizedType generic = (ParameterizedType) f.getGenericType(); Class genericType0 = (Class) generic.getActualTypeArguments()[0]; diff --git a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java index 4b1e666..08c4fa8 100644 --- a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java +++ b/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java @@ -208,7 +208,7 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f2.get(i), dst.f2.get(i)); } } - + public void testListTypes02() throws Exception { SampleListTypes src = (SampleListTypes) PackUnpackUtil .newEnhancedInstance(SampleListTypes.class); @@ -291,7 +291,7 @@ public class TestMessagePackUnpackable extends TestCase { assertEquals(src.f2.get(s2), dst.f2.get(d2)); } } - + public void testMapTypes02() throws Exception { SampleMapTypes src = (SampleMapTypes) PackUnpackUtil .newEnhancedInstance(SampleMapTypes.class); @@ -565,11 +565,8 @@ public class TestMessagePackUnpackable extends TestCase { src.f1 = src2; ByteArrayOutputStream out = new ByteArrayOutputStream(); new Packer(out).pack(src); - NestedClass dst2 = (NestedClass) PackUnpackUtil - .newEnhancedInstance(NestedClass.class); BaseClass dst = (BaseClass) PackUnpackUtil .newEnhancedInstance(BaseClass.class); - dst.f1 = dst2; ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Unpacker pac = new Unpacker(in); pac.unpack((MessageUnpackable) dst); @@ -593,12 +590,8 @@ public class TestMessagePackUnpackable extends TestCase { Iterator it = pac.iterator(); assertTrue(it.hasNext()); MessagePackObject mpo = it.next(); - NestedClass dst2 = (NestedClass) PackUnpackUtil - .newEnhancedInstance(NestedClass.class); - BaseClass dst = (BaseClass) PackUnpackUtil - .newEnhancedInstance(BaseClass.class); - dst.f1 = dst2; - dst = (BaseClass) PackUnpackUtil.initEnhancedInstance(mpo, dst); + BaseClass dst = (BaseClass) PackUnpackUtil.initEnhancedInstance(mpo, + BaseClass.class); assertTrue(src.f0 == dst.f0); assertTrue(src2.f2 == dst.f1.f2); assertFalse(it.hasNext()); @@ -649,7 +642,7 @@ public class TestMessagePackUnpackable extends TestCase { assertTrue(src.f8 == dst.f8); assertTrue(src.f9 != dst.f9); } - + @Test public void testExtendedClass02() throws Exception { SampleSubClass src = (SampleSubClass) PackUnpackUtil From 22ddd91b1f73adc8b0cc402e5346504df4f4a935 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Thu, 23 Sep 2010 20:38:54 +0900 Subject: [PATCH 09/19] java: add several API to annotation-utilities --- .../util/annotation/PackUnpackUtil.java | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java index 6e6a665..e509cd8 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java @@ -193,12 +193,12 @@ public class PackUnpackUtil { classCache.putIfAbsent(origName, enhClass); } - protected Class generate(Class origClass) + protected Class generate(Class origClass, boolean packUnpackable) throws NotFoundException, CannotCompileException { String origName = origClass.getName(); String enhName = origName + Constants.POSTFIX_TYPE_NAME_ENHANCER; CtClass origCtClass = pool.get(origName); - checkClassValidation(origClass); + checkClassValidation(origClass, packUnpackable); checkDefaultConstructorValidation(origClass); CtClass enhCtClass = pool.makeClass(enhName); setSuperclass(enhCtClass, origCtClass); @@ -211,7 +211,7 @@ public class PackUnpackUtil { return createClass(enhCtClass); } - private void checkClassValidation(Class origClass) { + private void checkClassValidation(Class origClass, boolean packUnpackable) { // not public, abstract, final int mod = origClass.getModifiers(); if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) @@ -223,7 +223,9 @@ public class PackUnpackUtil { throwClassValidationException(origClass); } // annotation - checkPackUnpackAnnotation(origClass); + if (!packUnpackable) { + checkPackUnpackAnnotation(origClass); + } } private static void throwClassValidationException(Class origClass) { @@ -1251,18 +1253,17 @@ public class PackUnpackUtil { } private static Enhancer enhancer; - - public static Class getEnhancedClass(Class origClass) { + + public static void registerEnhancedClass(Class origClass, boolean packUnpackable) { if (enhancer == null) { enhancer = new Enhancer(); } - String origName = origClass.getName(); Class enhClass = enhancer.getCache(origName); if (enhClass == null) { // generate a class object related to the original class try { - enhClass = enhancer.generate(origClass); + enhClass = enhancer.generate(origClass, packUnpackable); } catch (NotFoundException e) { throw new PackUnpackUtilException(e.getMessage(), e); } catch (CannotCompileException e) { @@ -1270,33 +1271,57 @@ public class PackUnpackUtil { } // set the generated class to the cache enhancer.setCache(origName, enhClass); + } + } + + public static void registerEnhancedClass(Class origClass) { + registerEnhancedClass(origClass, false); + } + + public static boolean isRegistered(Class origClass) { + if (enhancer == null) { + enhancer = new Enhancer(); } - return enhClass; + return enhancer.getCache(origClass.getName()) != null; } - public static Object newEnhancedInstance(Class origClass) { + public static Class getEnhancedClass(Class origClass, boolean packUnpackable) { + if (!isRegistered(origClass)) { + registerEnhancedClass(origClass, packUnpackable); + } + return enhancer.getCache(origClass.getName()); + } + + public static Class getEnhancedClass(Class origClass) { + return getEnhancedClass(origClass, false); + } + + public static Object newEnhancedInstance(Class origClass, boolean packUnpackable) { try { - Class enhClass = getEnhancedClass(origClass); + Class enhClass = getEnhancedClass(origClass, packUnpackable); // create a new object of the generated class return enhClass.newInstance(); } catch (InstantiationException e) { throw new PackUnpackUtilException(e.getMessage(), e); } catch (IllegalAccessException e) { throw new PackUnpackUtilException(e.getMessage(), e); - } + } } - + + public static Object newEnhancedInstance(Class origClass) { + return newEnhancedInstance(origClass, false); + } + public static Object initEnhancedInstance(MessagePackObject obj, - Class origClass) { - Object ret = newEnhancedInstance(origClass); + Class origClass, boolean packUnpackable) { + Object ret = newEnhancedInstance(origClass, packUnpackable); ((MessageConvertable) ret).messageConvert(obj); return ret; } public static Object initEnhancedInstance(MessagePackObject obj, - Object origObj) { - ((MessageConvertable) origObj).messageConvert(obj); - return origObj; + Class origClass) { + return initEnhancedInstance(obj, origClass, false); } @MessagePackUnpackable @@ -1326,7 +1351,6 @@ public class PackUnpackUtil { } public static void main(final String[] args) throws Exception { - PackUnpackUtil.getEnhancedClass(Image.class); Image src = (Image) PackUnpackUtil.newEnhancedInstance(Image.class); src.title = "msgpack"; src.uri = "http://msgpack.org/"; From 34c008adce9ffd716dfcac11b35490b6b1244f3f Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Thu, 23 Sep 2010 20:40:50 +0900 Subject: [PATCH 10/19] java: refactor annotation-utilities --- .../util/annotation/PackUnpackUtil.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java index e509cd8..0aeb6d8 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java @@ -211,7 +211,8 @@ public class PackUnpackUtil { return createClass(enhCtClass); } - private void checkClassValidation(Class origClass, boolean packUnpackable) { + private void checkClassValidation(Class origClass, + boolean packUnpackable) { // not public, abstract, final int mod = origClass.getModifiers(); if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) @@ -1253,8 +1254,9 @@ public class PackUnpackUtil { } private static Enhancer enhancer; - - public static void registerEnhancedClass(Class origClass, boolean packUnpackable) { + + public static void registerEnhancedClass(Class origClass, + boolean packUnpackable) { if (enhancer == null) { enhancer = new Enhancer(); } @@ -1271,13 +1273,13 @@ public class PackUnpackUtil { } // set the generated class to the cache enhancer.setCache(origName, enhClass); - } + } } - + public static void registerEnhancedClass(Class origClass) { registerEnhancedClass(origClass, false); } - + public static boolean isRegistered(Class origClass) { if (enhancer == null) { enhancer = new Enhancer(); @@ -1285,18 +1287,20 @@ public class PackUnpackUtil { return enhancer.getCache(origClass.getName()) != null; } - public static Class getEnhancedClass(Class origClass, boolean packUnpackable) { + public static Class getEnhancedClass(Class origClass, + boolean packUnpackable) { if (!isRegistered(origClass)) { registerEnhancedClass(origClass, packUnpackable); } return enhancer.getCache(origClass.getName()); } - + public static Class getEnhancedClass(Class origClass) { return getEnhancedClass(origClass, false); } - public static Object newEnhancedInstance(Class origClass, boolean packUnpackable) { + public static Object newEnhancedInstance(Class origClass, + boolean packUnpackable) { try { Class enhClass = getEnhancedClass(origClass, packUnpackable); // create a new object of the generated class @@ -1305,13 +1309,13 @@ public class PackUnpackUtil { throw new PackUnpackUtilException(e.getMessage(), e); } catch (IllegalAccessException e) { throw new PackUnpackUtilException(e.getMessage(), e); - } + } } - + public static Object newEnhancedInstance(Class origClass) { return newEnhancedInstance(origClass, false); } - + public static Object initEnhancedInstance(MessagePackObject obj, Class origClass, boolean packUnpackable) { Object ret = newEnhancedInstance(origClass, packUnpackable); From 93bed9c5df6d4fe7a0defdaeb2f158e27d4feb1d Mon Sep 17 00:00:00 2001 From: tanakh Date: Fri, 24 Sep 2010 01:24:13 +0900 Subject: [PATCH 11/19] haskell: finish template-haskell deriving implement --- haskell/msgpack.cabal | 4 ++ haskell/src/Data/MessagePack/Derive.hs | 62 ++++++++++++++++++-------- haskell/test/Test.hs | 2 +- haskell/test/UserData.hs | 26 +++++++++++ 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/haskell/msgpack.cabal b/haskell/msgpack.cabal index 9c67bdc..9950273 100644 --- a/haskell/msgpack.cabal +++ b/haskell/msgpack.cabal @@ -15,6 +15,10 @@ Stability: Experimental Cabal-Version: >= 1.6 Build-Type: Simple +Extra-source-files: + test/Test.hs + test/UserData.hs + Library Build-depends: base >=4 && <5, transformers >= 0.2.1 && < 0.2.2, diff --git a/haskell/src/Data/MessagePack/Derive.hs b/haskell/src/Data/MessagePack/Derive.hs index cfdb658..e998473 100644 --- a/haskell/src/Data/MessagePack/Derive.hs +++ b/haskell/src/Data/MessagePack/Derive.hs @@ -11,10 +11,11 @@ import Language.Haskell.TH import Data.MessagePack.Pack import Data.MessagePack.Unpack +import Data.MessagePack.Object deriveUnpack :: Name -> Q [Dec] deriveUnpack typName = do - TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + TyConI (DataD _ name _ cons _) <- reify typName return [ InstanceD [] (AppT (ConT ''Unpackable) (ConT name)) @@ -24,20 +25,19 @@ deriveUnpack typName = do where body (NormalC conName elms) = DoE - [ BindS (tupOrList $ map VarP names) (VarE 'get) + [ BindS (tupOrListP $ map VarP names) (VarE 'get) , NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] where names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms - tupOrList ls - | length ls <= 1 = ListP ls - | otherwise = TupP ls + body (RecC conName elms) = + body (NormalC conName $ map (\(_, b, c) -> (b, c)) elms) ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f) derivePack :: Name -> Q [Dec] derivePack typName = do - TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + TyConI (DataD _ name _ cons _) <- reify typName return [ InstanceD [] (AppT (ConT ''Packable) (ConT name)) @@ -48,27 +48,53 @@ derivePack typName = do body (NormalC conName elms) = Clause [ ConP conName $ map VarP names ] - (NormalB $ AppE (VarE 'put) $ tupOrList $ map VarE names) [] + (NormalB $ AppE (VarE 'put) $ tupOrListE $ map VarE names) [] where names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms - tupOrList ls - | length ls <= 1 = ListE ls - | otherwise = TupE ls + body (RecC conName elms) = + body (NormalC conName $ map (\(_, b, c) -> (b, c)) elms) deriveObject :: Name -> Q [Dec] deriveObject typName = do g <- derivePack typName p <- deriveUnpack typName - {- - TyConI (DataD cxt name tyVarBndrs cons names) <- reify typName + + TyConI (DataD _ name _ cons _) <- reify typName let o = InstanceD [] (AppT (ConT ''OBJECT) (ConT name)) - [ FunD 'toObject (map toObjectBody cons) ] - -} - return $ g ++ p -- ++ [o] -{- + [ FunD 'toObject (map toObjectBody cons), + FunD 'tryFromObject [Clause [ VarP oname ] + (NormalB $ ch $ map tryFromObjectBody cons) []]] + + return $ g ++ p ++ [o] where toObjectBody (NormalC conName elms) = Clause - [ ConP conP --} + [ ConP conName $ map VarP names ] + (NormalB $ AppE (VarE 'toObject) $ tupOrListE $ map VarE names) [] + where + names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms + toObjectBody (RecC conName elms) = + toObjectBody (NormalC conName $ map (\(_, b, c) -> (b, c)) elms) + + tryFromObjectBody (NormalC conName elms) = + DoE + [ BindS (tupOrListP $ map VarP names) (AppE (VarE 'tryFromObject) (VarE oname)) + , NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] + where + names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms + tryFromObjectBody (RecC conName elms) = + tryFromObjectBody (NormalC conName $ map (\(_, b, c) -> (b, c)) elms) + + oname = mkName "o" + ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f) + +tupOrListP :: [Pat] -> Pat +tupOrListP ls + | length ls <= 1 = ListP ls + | otherwise = TupP ls + +tupOrListE :: [Exp] -> Exp +tupOrListE ls + | length ls <= 1 = ListE ls + | otherwise = TupE ls diff --git a/haskell/test/Test.hs b/haskell/test/Test.hs index a73ac9a..43af2ef 100644 --- a/haskell/test/Test.hs +++ b/haskell/test/Test.hs @@ -7,7 +7,7 @@ import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as L import Data.MessagePack -mid :: (ObjectGet a, ObjectPut a) => a -> a +mid :: (Packable a, Unpackable a) => a -> a mid = unpack . pack prop_mid_int a = a == mid a diff --git a/haskell/test/UserData.hs b/haskell/test/UserData.hs index 8aced13..73647ff 100644 --- a/haskell/test/UserData.hs +++ b/haskell/test/UserData.hs @@ -10,6 +10,13 @@ data T $(deriveObject ''T) +data U + = C { c1 :: Int, c2 :: String } + | D { d1 :: Double } + deriving (Show) + +$(deriveObject ''U) + main = do let bs = pack $ A 123 "hoge" print bs @@ -17,3 +24,22 @@ main = do let cs = pack $ B 3.14 print cs print (unpack cs :: T) + let oa = toObject $ A 123 "hoge" + print oa + print (fromObject oa :: T) + let ob = toObject $ B 3.14 + print ob + print (fromObject ob :: T) + + let ds = pack $ C 123 "hoge" + print ds + print (unpack ds :: U) + let es = pack $ D 3.14 + print es + print (unpack es :: U) + let oc = toObject $ C 123 "hoge" + print oc + print (fromObject oc :: U) + let od = toObject $ D 3.14 + print od + print (fromObject od :: U) From 894ff716647eeb63b8a04e279faa09092ac9c1c7 Mon Sep 17 00:00:00 2001 From: tanakh Date: Fri, 24 Sep 2010 03:49:31 +0900 Subject: [PATCH 12/19] haskell: fix for empty constructor --- haskell/msgpack.cabal | 2 +- haskell/src/Data/MessagePack/Derive.hs | 28 ++++++++------ haskell/test/UserData.hs | 52 +++++++++++++------------- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/haskell/msgpack.cabal b/haskell/msgpack.cabal index 9950273..98133a9 100644 --- a/haskell/msgpack.cabal +++ b/haskell/msgpack.cabal @@ -1,5 +1,5 @@ Name: msgpack -Version: 0.4.0 +Version: 0.4.0.1 Synopsis: A Haskell binding to MessagePack Description: A Haskell binding to MessagePack diff --git a/haskell/src/Data/MessagePack/Derive.hs b/haskell/src/Data/MessagePack/Derive.hs index e998473..74943e9 100644 --- a/haskell/src/Data/MessagePack/Derive.hs +++ b/haskell/src/Data/MessagePack/Derive.hs @@ -7,6 +7,7 @@ module Data.MessagePack.Derive ( ) where import Control.Applicative +import Control.Monad import Language.Haskell.TH import Data.MessagePack.Pack @@ -24,9 +25,9 @@ deriveUnpack typName = do where body (NormalC conName elms) = - DoE - [ BindS (tupOrListP $ map VarP names) (VarE 'get) - , NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] + DoE $ + tupOrListP (map VarP names) (VarE 'get) ++ + [ NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] where names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms @@ -78,9 +79,9 @@ deriveObject typName = do toObjectBody (NormalC conName $ map (\(_, b, c) -> (b, c)) elms) tryFromObjectBody (NormalC conName elms) = - DoE - [ BindS (tupOrListP $ map VarP names) (AppE (VarE 'tryFromObject) (VarE oname)) - , NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] + DoE $ + tupOrListP (map VarP names) (AppE (VarE 'tryFromObject) (VarE oname)) ++ + [ NoBindS $ AppE (VarE 'return) $ foldl AppE (ConE conName) $ map VarE names ] where names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms tryFromObjectBody (RecC conName elms) = @@ -89,12 +90,17 @@ deriveObject typName = do oname = mkName "o" ch = foldl1 (\e f -> AppE (AppE (VarE '(<|>)) e) f) -tupOrListP :: [Pat] -> Pat -tupOrListP ls - | length ls <= 1 = ListP ls - | otherwise = TupP ls +tupOrListP :: [Pat] -> Exp -> [Stmt] +tupOrListP ls e + | length ls == 0 = + let lsname = mkName "ls" in + [ BindS (VarP lsname) e + , NoBindS $ AppE (VarE 'guard) $ AppE (VarE 'null) $ SigE (VarE lsname) (AppT ListT (ConT ''())) ] + | length ls == 1 = [ BindS (ListP ls) e ] + | otherwise = [ BindS (TupP ls) e ] tupOrListE :: [Exp] -> Exp tupOrListE ls - | length ls <= 1 = ListE ls + | length ls == 0 = SigE (ListE []) (AppT ListT (ConT ''())) + | length ls == 1 = ListE ls | otherwise = TupE ls diff --git a/haskell/test/UserData.hs b/haskell/test/UserData.hs index 73647ff..5e5d0ea 100644 --- a/haskell/test/UserData.hs +++ b/haskell/test/UserData.hs @@ -6,40 +6,38 @@ import Data.MessagePack.Derive data T = A Int String | B Double - deriving (Show) + deriving (Show, Eq) $(deriveObject ''T) data U = C { c1 :: Int, c2 :: String } | D { d1 :: Double } - deriving (Show) + deriving (Show, Eq) $(deriveObject ''U) -main = do - let bs = pack $ A 123 "hoge" - print bs - print (unpack bs :: T) - let cs = pack $ B 3.14 - print cs - print (unpack cs :: T) - let oa = toObject $ A 123 "hoge" - print oa - print (fromObject oa :: T) - let ob = toObject $ B 3.14 - print ob - print (fromObject ob :: T) +data V + = E String | F + deriving (Show, Eq) - let ds = pack $ C 123 "hoge" - print ds - print (unpack ds :: U) - let es = pack $ D 3.14 - print es - print (unpack es :: U) - let oc = toObject $ C 123 "hoge" - print oc - print (fromObject oc :: U) - let od = toObject $ D 3.14 - print od - print (fromObject od :: U) +$(deriveObject ''V) + +test :: (OBJECT a, Show a, Eq a) => a -> IO () +test v = do + let bs = pack v + print bs + print (unpack bs == v) + + let oa = toObject v + print oa + print (fromObject oa == v) + +main = do + test $ A 123 "hoge" + test $ B 3.14 + test $ C 123 "hoge" + test $ D 3.14 + test $ E "hello" + test $ F + return () \ No newline at end of file From e8abcc1765da98885d03cb0ca0784cf332bf0ee0 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 26 Sep 2010 11:36:57 +0900 Subject: [PATCH 13/19] cpp: sbuffer: check initial buffer size != 0 --- cpp/bootstrap | 2 +- cpp/src/msgpack/sbuffer.hpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cpp/bootstrap b/cpp/bootstrap index a95c304..7f3a182 100755 --- a/cpp/bootstrap +++ b/cpp/bootstrap @@ -38,7 +38,7 @@ test -f ChangeLog || touch ChangeLog test -f NEWS || touch NEWS test -f README || cp -f README.md README -if ! ./preprocess; then +if test ! ./preprocess; then exit 1 fi diff --git a/cpp/src/msgpack/sbuffer.hpp b/cpp/src/msgpack/sbuffer.hpp index a9efc6d..14c5d2a 100644 --- a/cpp/src/msgpack/sbuffer.hpp +++ b/cpp/src/msgpack/sbuffer.hpp @@ -28,9 +28,13 @@ class sbuffer : public msgpack_sbuffer { public: sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE) { - base::data = (char*)::malloc(initsz); - if(!base::data) { - throw std::bad_alloc(); + if(initsz == 0) { + base::data = NULL; + } else { + base::data = (char*)::malloc(initsz); + if(!base::data) { + throw std::bad_alloc(); + } } base::size = 0; @@ -80,7 +84,7 @@ public: private: void expand_buffer(size_t len) { - size_t nsize = (base::alloc) ? + size_t nsize = (base::alloc > 0) ? base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; while(nsize < base::size + len) { nsize *= 2; } From 7974060a4010c91f978fe91e74b0e1967dc30a90 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 26 Sep 2010 11:37:37 +0900 Subject: [PATCH 14/19] cpp: zone: adds msgpack_zone_swap and msgpack::zone::swap --- cpp/src/msgpack/zone.h | 11 ++++++++++- cpp/src/msgpack/zone.hpp.erb | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cpp/src/msgpack/zone.h b/cpp/src/msgpack/zone.h index d8c60b6..0f5817f 100644 --- a/cpp/src/msgpack/zone.h +++ b/cpp/src/msgpack/zone.h @@ -1,7 +1,7 @@ /* * MessagePack for C memory pool implementation * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki + * Copyright (C) 2008-2010 FURUHASHI Sadayuki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,8 @@ static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, void (*func)(void* data), void* data); +static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b); + bool msgpack_zone_is_empty(msgpack_zone* zone); void msgpack_zone_clear(msgpack_zone* zone); @@ -129,6 +131,13 @@ bool msgpack_zone_push_finalizer(msgpack_zone* zone, return true; } +void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b) +{ + msgpack_zone tmp = *a; + *a = *b; + *b = tmp; +} + #ifdef __cplusplus } diff --git a/cpp/src/msgpack/zone.hpp.erb b/cpp/src/msgpack/zone.hpp.erb index 1cef05e..c6f5481 100644 --- a/cpp/src/msgpack/zone.hpp.erb +++ b/cpp/src/msgpack/zone.hpp.erb @@ -1,7 +1,7 @@ // // MessagePack for C++ memory pool // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2010 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,6 +43,8 @@ public: void clear(); + void swap(zone& o); + <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>); @@ -111,6 +113,11 @@ inline void zone::clear() msgpack_zone_clear(this); } +inline void zone::swap(zone& o) +{ + msgpack_zone_swap(this, &o); +} + template void zone::object_destructor(void* obj) { From 446a7fbd679fffd6b2b5e3c8b5673ed824aa133f Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 03:05:32 +0900 Subject: [PATCH 15/19] java: adds CustomMessage class (currently not implemented on Packer, Unpacker and ClassTemplate) --- .../java/org/msgpack/CustomConverter.java | 39 +++++++++++++++++++ .../main/java/org/msgpack/CustomMessage.java | 30 ++++++++++++++ .../main/java/org/msgpack/CustomPacker.java | 39 +++++++++++++++++++ .../main/java/org/msgpack/CustomUnpacker.java | 39 +++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 java/src/main/java/org/msgpack/CustomConverter.java create mode 100644 java/src/main/java/org/msgpack/CustomMessage.java create mode 100644 java/src/main/java/org/msgpack/CustomPacker.java create mode 100644 java/src/main/java/org/msgpack/CustomUnpacker.java diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java new file mode 100644 index 0000000..5905419 --- /dev/null +++ b/java/src/main/java/org/msgpack/CustomConverter.java @@ -0,0 +1,39 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.util.Map; +import java.util.HashMap; + +// FIXME public? +class CustomConverter { + public static void register(Class target, MessageConverter converter) { + map.put(target, converter); + } + + public static MessageConverter get(Class target) { + return map.get(target); + } + + public static boolean isRegistered(Class target) { + return map.containsKey(target); + } + + private static Map map = new HashMap(); +} + diff --git a/java/src/main/java/org/msgpack/CustomMessage.java b/java/src/main/java/org/msgpack/CustomMessage.java new file mode 100644 index 0000000..f87898c --- /dev/null +++ b/java/src/main/java/org/msgpack/CustomMessage.java @@ -0,0 +1,30 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +public class CustomMessage { + public static void registerPacker(Class target, MessagePacker packer) { + CustomPacker.register(target, packer); + } + + public static void registerTemplate(Class target, Template tmpl) { + CustomUnpacker.register(target, tmpl); + CustomConverter.register(target, tmpl); + } +} + diff --git a/java/src/main/java/org/msgpack/CustomPacker.java b/java/src/main/java/org/msgpack/CustomPacker.java new file mode 100644 index 0000000..f828c31 --- /dev/null +++ b/java/src/main/java/org/msgpack/CustomPacker.java @@ -0,0 +1,39 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.util.Map; +import java.util.HashMap; + +// FIXME public? +class CustomPacker { + public static void register(Class target, MessagePacker converter) { + map.put(target, converter); + } + + public static MessagePacker get(Class target) { + return map.get(target); + } + + public static boolean isRegistered(Class target) { + return map.containsKey(target); + } + + private static Map map = new HashMap(); +} + diff --git a/java/src/main/java/org/msgpack/CustomUnpacker.java b/java/src/main/java/org/msgpack/CustomUnpacker.java new file mode 100644 index 0000000..255368d --- /dev/null +++ b/java/src/main/java/org/msgpack/CustomUnpacker.java @@ -0,0 +1,39 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.util.Map; +import java.util.HashMap; + +// FIXME public? +class CustomUnpacker { + public static void register(Class target, MessageUnpacker converter) { + map.put(target, converter); + } + + public static MessageUnpacker get(Class target) { + return map.get(target); + } + + public static boolean isRegistered(Class target) { + return map.containsKey(target); + } + + private static Map map = new HashMap(); +} + From 391034a7859dac3e1c77164c46da03026ec4d743 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 03:06:06 +0900 Subject: [PATCH 16/19] java: adds type-conversion mechanisms --- .../java/org/msgpack/AbstractTemplate.java | 27 +++++++++ .../java/org/msgpack/MessageConverter.java | 25 +++++++++ .../java/org/msgpack/MessagePackObject.java | 4 ++ .../main/java/org/msgpack/MessagePacker.java | 25 +++++++++ .../java/org/msgpack/MessageUnpacker.java | 25 +++++++++ java/src/main/java/org/msgpack/Packer.java | 2 + java/src/main/java/org/msgpack/Template.java | 22 ++++++++ java/src/main/java/org/msgpack/Templates.java | 45 +++++++++++++++ java/src/main/java/org/msgpack/Unpacker.java | 15 ++++- .../msgpack/template/ByteArrayTemplate.java | 44 +++++++++++++++ .../org/msgpack/template/ClassTemplate.java | 45 +++++++++++++++ .../org/msgpack/template/ListTemplate.java | 50 +++++++++++++++++ .../org/msgpack/template/MapTemplate.java | 56 +++++++++++++++++++ .../org/msgpack/template/StringTemplate.java | 44 +++++++++++++++ 14 files changed, 427 insertions(+), 2 deletions(-) create mode 100644 java/src/main/java/org/msgpack/AbstractTemplate.java create mode 100644 java/src/main/java/org/msgpack/MessageConverter.java create mode 100644 java/src/main/java/org/msgpack/MessagePacker.java create mode 100644 java/src/main/java/org/msgpack/MessageUnpacker.java create mode 100644 java/src/main/java/org/msgpack/Template.java create mode 100644 java/src/main/java/org/msgpack/Templates.java create mode 100644 java/src/main/java/org/msgpack/template/ByteArrayTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/ClassTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/ListTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/MapTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/StringTemplate.java diff --git a/java/src/main/java/org/msgpack/AbstractTemplate.java b/java/src/main/java/org/msgpack/AbstractTemplate.java new file mode 100644 index 0000000..5b4442e --- /dev/null +++ b/java/src/main/java/org/msgpack/AbstractTemplate.java @@ -0,0 +1,27 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; + +public abstract class AbstractTemplate implements Template { + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return convert(pac.unpackObject()); + } +} + diff --git a/java/src/main/java/org/msgpack/MessageConverter.java b/java/src/main/java/org/msgpack/MessageConverter.java new file mode 100644 index 0000000..8388ddc --- /dev/null +++ b/java/src/main/java/org/msgpack/MessageConverter.java @@ -0,0 +1,25 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; + +public interface MessageConverter { + public Object convert(MessagePackObject obj) throws MessageTypeException; +} + diff --git a/java/src/main/java/org/msgpack/MessagePackObject.java b/java/src/main/java/org/msgpack/MessagePackObject.java index 2424446..f7e9e0e 100644 --- a/java/src/main/java/org/msgpack/MessagePackObject.java +++ b/java/src/main/java/org/msgpack/MessagePackObject.java @@ -132,5 +132,9 @@ public abstract class MessagePackObject implements Cloneable, MessagePackable { } abstract public Object clone(); + + public Object convert(Template tmpl) throws MessageTypeException { + return tmpl.convert(this); + } } diff --git a/java/src/main/java/org/msgpack/MessagePacker.java b/java/src/main/java/org/msgpack/MessagePacker.java new file mode 100644 index 0000000..05d4de5 --- /dev/null +++ b/java/src/main/java/org/msgpack/MessagePacker.java @@ -0,0 +1,25 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; + +public interface MessagePacker { + public void pack(Packer pk, Object target) throws IOException; +} + diff --git a/java/src/main/java/org/msgpack/MessageUnpacker.java b/java/src/main/java/org/msgpack/MessageUnpacker.java new file mode 100644 index 0000000..1817269 --- /dev/null +++ b/java/src/main/java/org/msgpack/MessageUnpacker.java @@ -0,0 +1,25 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; + +public interface MessageUnpacker { + public Object unpack(Unpacker pac) throws IOException, MessageTypeException; +} + diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 139b3b1..687f09c 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -474,6 +474,8 @@ public class Packer { } else if(o instanceof BigInteger) { return packBigInteger((BigInteger)o); } else { + // FIXME check CustomPacker.get(o.getClass()); + // FIXME check annotations throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); } } diff --git a/java/src/main/java/org/msgpack/Template.java b/java/src/main/java/org/msgpack/Template.java new file mode 100644 index 0000000..71e64e0 --- /dev/null +++ b/java/src/main/java/org/msgpack/Template.java @@ -0,0 +1,22 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +public interface Template extends MessageUnpacker, MessageConverter { +} + diff --git a/java/src/main/java/org/msgpack/Templates.java b/java/src/main/java/org/msgpack/Templates.java new file mode 100644 index 0000000..4c3fdae --- /dev/null +++ b/java/src/main/java/org/msgpack/Templates.java @@ -0,0 +1,45 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import org.msgpack.template.*; + +public class Templates { + public static Template tList(Template elementTemplate) { + return new ListTemplate(elementTemplate); + } + + public static Template tMap(Template keyTemplate, Template valueTemplate) { + return new MapTemplate(keyTemplate, valueTemplate); + } + + + public static final Template TString = StringTemplate.getInstance(); + + public static Template tString() { + return TString; + } + + + public static final Template TByteArray = ByteArrayTemplate.getInstance(); + + public static Template tByteArray() { + return TByteArray; + } +} + diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index 3cae502..1b5621f 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -561,12 +561,23 @@ public class Unpacker implements Iterable { return impl.unpackObject(); } + final public boolean tryUnpackNull() throws IOException { + return impl.tryUnpackNull(); + } + + final public Object unpack(MessageUnpacker unpacker) throws IOException, MessageTypeException { + return unpacker.unpack(this); + } + final public void unpack(MessageUnpackable obj) throws IOException, MessageTypeException { obj.messageUnpack(this); } - final public boolean tryUnpackNull() throws IOException { - return impl.tryUnpackNull(); + final public Object unpack(Class klass) throws MessageTypeException { + // FIXME check MessageUnpackable + // FIXME check CustomPacker + // FIXME check annotations + throw new MessageTypeException(); } } diff --git a/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java b/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java new file mode 100644 index 0000000..fe26369 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class ByteArrayTemplate implements Template { + private ByteArrayTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackByteArray(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asByteArray(); + } + + static public ByteArrayTemplate getInstance() { + return instance; + } + + static final ByteArrayTemplate instance = new ByteArrayTemplate(); + + static { + CustomMessage.registerTemplate(byte[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ClassTemplate.java b/java/src/main/java/org/msgpack/template/ClassTemplate.java new file mode 100644 index 0000000..b5ed854 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ClassTemplate.java @@ -0,0 +1,45 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class ClassTemplate implements Template { + private Class klass; + + public ClassTemplate(Class klass) { + this.klass = klass; + } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpack(klass); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + MessageConverter converter = CustomConverter.get(klass); + if(converter != null) { + return converter.convert(from); + } + + // FIXME check annotations + + throw new MessageTypeException(); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ListTemplate.java b/java/src/main/java/org/msgpack/template/ListTemplate.java new file mode 100644 index 0000000..54975f8 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ListTemplate.java @@ -0,0 +1,50 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.util.List; +import java.util.ArrayList; +import java.io.IOException; +import org.msgpack.*; + +public class ListTemplate implements Template { + private Template elementTemplate; + + public ListTemplate(Template elementTemplate) { + this.elementTemplate = elementTemplate; + } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + List list = new ArrayList(length); + for(; length > 0; length--) { + list.add( elementTemplate.unpack(pac) ); + } + return list; + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + MessagePackObject[] array = from.asArray(); + List list = new ArrayList(array.length); + for(MessagePackObject element : array) { + list.add( elementTemplate.convert(element) ); + } + return list; + } +} + diff --git a/java/src/main/java/org/msgpack/template/MapTemplate.java b/java/src/main/java/org/msgpack/template/MapTemplate.java new file mode 100644 index 0000000..d2b4eff --- /dev/null +++ b/java/src/main/java/org/msgpack/template/MapTemplate.java @@ -0,0 +1,56 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.util.Map; +import java.util.HashMap; +import java.io.IOException; +import org.msgpack.*; + +public class MapTemplate implements Template { + private Template keyTemplate; + private Template valueTemplate; + + public MapTemplate(Template keyTemplate, Template valueTemplate) { + this.keyTemplate = keyTemplate; + this.valueTemplate = valueTemplate; + } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + int length = pac.unpackMap(); + Map map = new HashMap(length); + for(; length > 0; length--) { + Object key = keyTemplate.unpack(pac); + Object value = valueTemplate.unpack(pac); + map.put(key, value); + } + return map; + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + Map src = from.asMap(); + Map map = new HashMap(); + for(Map.Entry pair : src.entrySet()) { + Object key = keyTemplate.convert(pair.getKey()); + Object value = valueTemplate.convert(pair.getValue()); + map.put(key, value); + } + return map; + } +} + diff --git a/java/src/main/java/org/msgpack/template/StringTemplate.java b/java/src/main/java/org/msgpack/template/StringTemplate.java new file mode 100644 index 0000000..563112d --- /dev/null +++ b/java/src/main/java/org/msgpack/template/StringTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class StringTemplate implements Template { + private StringTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackString(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asString(); + } + + static public StringTemplate getInstance() { + return instance; + } + + static final StringTemplate instance = new StringTemplate(); + + static { + CustomMessage.registerTemplate(String.class, instance); + } +} + From 7161a235f180fcb23e6451c6a10bfa5a55065eff Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 03:33:21 +0900 Subject: [PATCH 17/19] java: uses CustomMessage class on Packer, Unpacker and ClassTemplate --- .../java/org/msgpack/CustomConverter.java | 4 ++-- .../main/java/org/msgpack/CustomPacker.java | 4 ++-- .../main/java/org/msgpack/CustomUnpacker.java | 4 ++-- java/src/main/java/org/msgpack/Packer.java | 16 +++++++++---- java/src/main/java/org/msgpack/Templates.java | 4 ++++ java/src/main/java/org/msgpack/Unpacker.java | 23 +++++++++++++++---- .../org/msgpack/template/ClassTemplate.java | 23 +++++++++++++++++-- 7 files changed, 62 insertions(+), 16 deletions(-) diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java index 5905419..4351464 100644 --- a/java/src/main/java/org/msgpack/CustomConverter.java +++ b/java/src/main/java/org/msgpack/CustomConverter.java @@ -20,8 +20,8 @@ package org.msgpack; import java.util.Map; import java.util.HashMap; -// FIXME public? -class CustomConverter { +// FIXME package private? +public class CustomConverter { public static void register(Class target, MessageConverter converter) { map.put(target, converter); } diff --git a/java/src/main/java/org/msgpack/CustomPacker.java b/java/src/main/java/org/msgpack/CustomPacker.java index f828c31..f0c6b62 100644 --- a/java/src/main/java/org/msgpack/CustomPacker.java +++ b/java/src/main/java/org/msgpack/CustomPacker.java @@ -20,8 +20,8 @@ package org.msgpack; import java.util.Map; import java.util.HashMap; -// FIXME public? -class CustomPacker { +// FIXME package private? +public class CustomPacker { public static void register(Class target, MessagePacker converter) { map.put(target, converter); } diff --git a/java/src/main/java/org/msgpack/CustomUnpacker.java b/java/src/main/java/org/msgpack/CustomUnpacker.java index 255368d..b6047b8 100644 --- a/java/src/main/java/org/msgpack/CustomUnpacker.java +++ b/java/src/main/java/org/msgpack/CustomUnpacker.java @@ -20,8 +20,8 @@ package org.msgpack; import java.util.Map; import java.util.HashMap; -// FIXME public? -class CustomUnpacker { +// FIXME package private? +public class CustomUnpacker { public static void register(Class target, MessageUnpacker converter) { map.put(target, converter); } diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 687f09c..dd8cdee 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -473,11 +473,19 @@ public class Packer { return packDouble((Double)o); } else if(o instanceof BigInteger) { return packBigInteger((BigInteger)o); - } else { - // FIXME check CustomPacker.get(o.getClass()); - // FIXME check annotations - throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); } + + Class klass = o.getClass(); + + MessagePacker packer = CustomPacker.get(klass); + if(packer != null) { + packer.pack(this, o); + return this; + } + + // FIXME check annotations -> code generation -> CustomMessage.registerPacker + + throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); } } diff --git a/java/src/main/java/org/msgpack/Templates.java b/java/src/main/java/org/msgpack/Templates.java index 4c3fdae..a31dd91 100644 --- a/java/src/main/java/org/msgpack/Templates.java +++ b/java/src/main/java/org/msgpack/Templates.java @@ -28,6 +28,10 @@ public class Templates { return new MapTemplate(keyTemplate, valueTemplate); } + public static Template tClass(Class target) { + return new ClassTemplate(target); + } + public static final Template TString = StringTemplate.getInstance(); diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index 1b5621f..4e39748 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -573,10 +573,25 @@ public class Unpacker implements Iterable { obj.messageUnpack(this); } - final public Object unpack(Class klass) throws MessageTypeException { - // FIXME check MessageUnpackable - // FIXME check CustomPacker - // FIXME check annotations + final public Object unpack(Class klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException { + if(MessageUnpackable.class.isAssignableFrom(klass)) { + Object obj = klass.newInstance(); + ((MessageUnpackable)obj).messageUnpack(this); + return obj; + } + + MessageUnpacker unpacker = CustomUnpacker.get(klass); + if(unpacker != null) { + return unpacker.unpack(this); + } + + // FIXME check annotations -> code generation -> CustomMessage.registerTemplate + + MessageConverter converter = CustomConverter.get(klass); + if(converter != null) { + return converter.convert(unpackObject()); + } + throw new MessageTypeException(); } } diff --git a/java/src/main/java/org/msgpack/template/ClassTemplate.java b/java/src/main/java/org/msgpack/template/ClassTemplate.java index b5ed854..c529edd 100644 --- a/java/src/main/java/org/msgpack/template/ClassTemplate.java +++ b/java/src/main/java/org/msgpack/template/ClassTemplate.java @@ -28,16 +28,35 @@ public class ClassTemplate implements Template { } public Object unpack(Unpacker pac) throws IOException, MessageTypeException { - return pac.unpack(klass); + try { + return pac.unpack(klass); + } catch (IllegalAccessException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } catch (InstantiationException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } } public Object convert(MessagePackObject from) throws MessageTypeException { + if(MessageConvertable.class.isAssignableFrom(klass)) { + Object obj; + try { + obj = klass.newInstance(); + } catch (IllegalAccessException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } catch (InstantiationException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } + ((MessageConvertable)obj).messageConvert(from); + return obj; + } + MessageConverter converter = CustomConverter.get(klass); if(converter != null) { return converter.convert(from); } - // FIXME check annotations + // FIXME check annotations -> code generation -> CustomMessage.registerTemplate throw new MessageTypeException(); } From 002b86198c2a4db8aa6372f12fdaa055b9157e89 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 04:17:20 +0900 Subject: [PATCH 18/19] java: adds ReflectionPacker and ReflectionTemplate --- .../java/org/msgpack/MessageConverter.java | 2 +- .../main/java/org/msgpack/ReflectionBase.java | 26 +++++++ .../java/org/msgpack/ReflectionPacker.java | 49 ++++++++++++ .../java/org/msgpack/ReflectionTemplate.java | 74 +++++++++++++++++++ .../msgpack/TestReflectionPackerTemplate.java | 46 ++++++++++++ 5 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 java/src/main/java/org/msgpack/ReflectionBase.java create mode 100644 java/src/main/java/org/msgpack/ReflectionPacker.java create mode 100644 java/src/main/java/org/msgpack/ReflectionTemplate.java create mode 100644 java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java diff --git a/java/src/main/java/org/msgpack/MessageConverter.java b/java/src/main/java/org/msgpack/MessageConverter.java index 8388ddc..8ad60ae 100644 --- a/java/src/main/java/org/msgpack/MessageConverter.java +++ b/java/src/main/java/org/msgpack/MessageConverter.java @@ -20,6 +20,6 @@ package org.msgpack; import java.io.IOException; public interface MessageConverter { - public Object convert(MessagePackObject obj) throws MessageTypeException; + public Object convert(MessagePackObject from) throws MessageTypeException; } diff --git a/java/src/main/java/org/msgpack/ReflectionBase.java b/java/src/main/java/org/msgpack/ReflectionBase.java new file mode 100644 index 0000000..66ec12a --- /dev/null +++ b/java/src/main/java/org/msgpack/ReflectionBase.java @@ -0,0 +1,26 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; +import java.lang.reflect.*; + +// FIXME mock-up +abstract class ReflectionBase { +} + diff --git a/java/src/main/java/org/msgpack/ReflectionPacker.java b/java/src/main/java/org/msgpack/ReflectionPacker.java new file mode 100644 index 0000000..72406aa --- /dev/null +++ b/java/src/main/java/org/msgpack/ReflectionPacker.java @@ -0,0 +1,49 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; +import java.lang.reflect.*; + +// FIXME mock-up +public class ReflectionPacker extends ReflectionBase implements MessagePacker { + private Class klass; + + private ReflectionPacker(Class klass) { + this.klass = klass; + } + + static public ReflectionPacker create(Class klass) { + // FIXME code generation: generates subclass of ReflectionPacker + // returned instance will be cached by Packer into CustomPacker + return new ReflectionPacker(klass); + } + + public void pack(Packer pk, Object target) throws IOException { + Field[] fields = klass.getDeclaredFields(); + pk.packArray(fields.length); + try { + for(int i=0; i < fields.length; i++) { + pk.pack(fields[i].get(target)); + } + } catch(IllegalAccessException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } + } +} + diff --git a/java/src/main/java/org/msgpack/ReflectionTemplate.java b/java/src/main/java/org/msgpack/ReflectionTemplate.java new file mode 100644 index 0000000..5b49078 --- /dev/null +++ b/java/src/main/java/org/msgpack/ReflectionTemplate.java @@ -0,0 +1,74 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack; + +import java.io.IOException; +import java.lang.reflect.*; +import org.msgpack.template.ClassTemplate; + +// FIXME mock-up +public class ReflectionTemplate extends ReflectionBase implements Template { + private Class klass; + + private ReflectionTemplate(Class klass) { + this.klass = klass; + } + + static public ReflectionTemplate create(Class klass) { + // FIXME code generation: generates subclass of ReflectionPacker + // returned instance will be cached by ClassTemplate into CustomUnpacker/CustomConverter + return new ReflectionTemplate(klass); + } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + // FIXME optimize it + return convert(pac.unpackObject()); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + Object obj; + try { + obj = klass.newInstance(); + } catch (IllegalAccessException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } catch (InstantiationException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } + + // FIXME check Requred/Optional + + Field[] fields = klass.getDeclaredFields(); + MessagePackObject[] array = from.asArray(); + if(fields.length < array.length) { + throw new MessageTypeException(); + } + + try { + for(int i=0; i < fields.length; i++) { + // FIXME generics getDeclaringClass + Object value = new ClassTemplate(fields[i].getType()).convert(array[i]); + fields[i].set(obj, value); + } + } catch(IllegalAccessException e) { + throw new MessageTypeException(e.getMessage()); // FIXME + } + + return obj; + } +} + diff --git a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java new file mode 100644 index 0000000..ddf88a0 --- /dev/null +++ b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java @@ -0,0 +1,46 @@ +package org.msgpack; + +import static org.msgpack.Templates.*; + +import java.util.*; +import java.io.*; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestReflectionPackerTemplate { + + public static class StringFieldClass { + public String s1; + public String s2; + public StringFieldClass() { } + } + + @Test + public void testPackConvert() throws Exception { + tString(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + MessagePacker packer = ReflectionPacker.create(StringFieldClass.class); + + StringFieldClass src = new StringFieldClass(); + + src.s1 = "kumofs"; + src.s2 = "frsyuki"; + + packer.pack(new Packer(out), src); + + Template tmpl = ReflectionTemplate.create(StringFieldClass.class); + + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + + Object obj = tmpl.unpack(new Unpacker(in)); + assertEquals(obj.getClass(), StringFieldClass.class); + + StringFieldClass dst = (StringFieldClass)obj; + assertEquals(src.s1, dst.s1); + assertEquals(src.s2, dst.s2); + } +} + From 0a41b253f3a688cbdd11c2cfcb574f1333b32a0e Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 04:27:44 +0900 Subject: [PATCH 19/19] java: adds templates for primitive types --- java/src/main/java/org/msgpack/Templates.java | 43 ++++++++++++++++-- .../msgpack/template/BigIntegerTemplate.java | 45 +++++++++++++++++++ .../org/msgpack/template/BooleanTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/ByteTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/DoubleTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/FloatTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/IntegerTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/LongTemplate.java | 44 ++++++++++++++++++ .../org/msgpack/template/ShortTemplate.java | 44 ++++++++++++++++++ .../msgpack/TestReflectionPackerTemplate.java | 2 +- 10 files changed, 394 insertions(+), 4 deletions(-) create mode 100644 java/src/main/java/org/msgpack/template/BigIntegerTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/BooleanTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/ByteTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/DoubleTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/FloatTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/IntegerTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/LongTemplate.java create mode 100644 java/src/main/java/org/msgpack/template/ShortTemplate.java diff --git a/java/src/main/java/org/msgpack/Templates.java b/java/src/main/java/org/msgpack/Templates.java index a31dd91..222f625 100644 --- a/java/src/main/java/org/msgpack/Templates.java +++ b/java/src/main/java/org/msgpack/Templates.java @@ -33,15 +33,52 @@ public class Templates { } - public static final Template TString = StringTemplate.getInstance(); + public static final Template TByte = ByteTemplate.getInstance(); + public static Template tByte() { + return TByte; + } + public static final Template TShort = ShortTemplate.getInstance(); + public static Template tShort() { + return TShort; + } + + public static final Template TInteger = IntegerTemplate.getInstance(); + public static Template tInteger() { + return TInteger; + } + + public static final Template TLong = LongTemplate.getInstance(); + public static Template tLong() { + return TLong; + } + + public static final Template TBigInteger = BigIntegerTemplate.getInstance(); + public static Template tBigInteger() { + return TBigInteger; + } + + public static final Template TFloat = FloatTemplate.getInstance(); + public static Template tFloat() { + return TFloat; + } + + public static final Template TDouble = DoubleTemplate.getInstance(); + public static Template tDouble() { + return TDouble; + } + + public static final Template TBoolean = BooleanTemplate.getInstance(); + public static Template tBoolean() { + return TBoolean; + } + + public static final Template TString = StringTemplate.getInstance(); public static Template tString() { return TString; } - public static final Template TByteArray = ByteArrayTemplate.getInstance(); - public static Template tByteArray() { return TByteArray; } diff --git a/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java b/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java new file mode 100644 index 0000000..e8a2993 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java @@ -0,0 +1,45 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import java.math.BigInteger; +import org.msgpack.*; + +public class BigIntegerTemplate implements Template { + private BigIntegerTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackBigInteger(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asBigInteger(); + } + + static public BigIntegerTemplate getInstance() { + return instance; + } + + static final BigIntegerTemplate instance = new BigIntegerTemplate(); + + static { + CustomMessage.registerTemplate(BigInteger.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/BooleanTemplate.java b/java/src/main/java/org/msgpack/template/BooleanTemplate.java new file mode 100644 index 0000000..0d64ecc --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BooleanTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class BooleanTemplate implements Template { + private BooleanTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackBoolean(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asBoolean(); + } + + static public BooleanTemplate getInstance() { + return instance; + } + + static final BooleanTemplate instance = new BooleanTemplate(); + + static { + CustomMessage.registerTemplate(Boolean.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ByteTemplate.java b/java/src/main/java/org/msgpack/template/ByteTemplate.java new file mode 100644 index 0000000..8d0e6e6 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ByteTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class ByteTemplate implements Template { + private ByteTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackByte(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asByte(); + } + + static public ByteTemplate getInstance() { + return instance; + } + + static final ByteTemplate instance = new ByteTemplate(); + + static { + CustomMessage.registerTemplate(Byte.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/DoubleTemplate.java b/java/src/main/java/org/msgpack/template/DoubleTemplate.java new file mode 100644 index 0000000..2e26f50 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/DoubleTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class DoubleTemplate implements Template { + private DoubleTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackDouble(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asDouble(); + } + + static public DoubleTemplate getInstance() { + return instance; + } + + static final DoubleTemplate instance = new DoubleTemplate(); + + static { + CustomMessage.registerTemplate(Double.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/FloatTemplate.java b/java/src/main/java/org/msgpack/template/FloatTemplate.java new file mode 100644 index 0000000..8730172 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/FloatTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class FloatTemplate implements Template { + private FloatTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackFloat(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asFloat(); + } + + static public FloatTemplate getInstance() { + return instance; + } + + static final FloatTemplate instance = new FloatTemplate(); + + static { + CustomMessage.registerTemplate(Float.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/IntegerTemplate.java b/java/src/main/java/org/msgpack/template/IntegerTemplate.java new file mode 100644 index 0000000..c56c044 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/IntegerTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class IntegerTemplate implements Template { + private IntegerTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackInt(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asInt(); + } + + static public IntegerTemplate getInstance() { + return instance; + } + + static final IntegerTemplate instance = new IntegerTemplate(); + + static { + CustomMessage.registerTemplate(Integer.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/LongTemplate.java b/java/src/main/java/org/msgpack/template/LongTemplate.java new file mode 100644 index 0000000..a0c8210 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/LongTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class LongTemplate implements Template { + private LongTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackLong(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asLong(); + } + + static public LongTemplate getInstance() { + return instance; + } + + static final LongTemplate instance = new LongTemplate(); + + static { + CustomMessage.registerTemplate(Long.class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ShortTemplate.java b/java/src/main/java/org/msgpack/template/ShortTemplate.java new file mode 100644 index 0000000..b3bf43b --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ShortTemplate.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2010 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import org.msgpack.*; + +public class ShortTemplate implements Template { + private ShortTemplate() { } + + public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + return pac.unpackShort(); + } + + public Object convert(MessagePackObject from) throws MessageTypeException { + return from.asShort(); + } + + static public ShortTemplate getInstance() { + return instance; + } + + static final ShortTemplate instance = new ShortTemplate(); + + static { + CustomMessage.registerTemplate(Short.class, instance); + } +} + diff --git a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java index ddf88a0..f361eb4 100644 --- a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java +++ b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java @@ -18,7 +18,7 @@ public class TestReflectionPackerTemplate { @Test public void testPackConvert() throws Exception { - tString(); + tString(); // FIXME link StringTemplate ByteArrayOutputStream out = new ByteArrayOutputStream();