mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-29 21:22:06 +01:00
Merge branch 'master' of github.com:msgpack/msgpack
This commit is contained in:
commit
ec9659ff25
@ -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
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 T<%1.upto(i) {|j|%>, 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 <typename T>
|
||||
void zone::object_destructor(void* obj)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name: msgpack
|
||||
Version: 0.3.1.1
|
||||
Version: 0.4.0.1
|
||||
Synopsis: A Haskell binding to MessagePack
|
||||
Description:
|
||||
A Haskell binding to MessagePack <http://msgpack.org/>
|
||||
@ -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,
|
||||
@ -25,17 +29,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
|
||||
|
@ -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
|
||||
|
106
haskell/src/Data/MessagePack/Derive.hs
Normal file
106
haskell/src/Data/MessagePack/Derive.hs
Normal file
@ -0,0 +1,106 @@
|
||||
{-# Language TemplateHaskell #-}
|
||||
|
||||
module Data.MessagePack.Derive (
|
||||
derivePack,
|
||||
deriveUnpack,
|
||||
deriveObject,
|
||||
) where
|
||||
|
||||
import Control.Applicative
|
||||
import Control.Monad
|
||||
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 _ name _ cons _) <- reify typName
|
||||
|
||||
return
|
||||
[ InstanceD [] (AppT (ConT ''Unpackable) (ConT name))
|
||||
[ FunD 'get [Clause [] (NormalB $ ch $ map body cons) []]
|
||||
]]
|
||||
|
||||
where
|
||||
body (NormalC conName elms) =
|
||||
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
|
||||
|
||||
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 _ name _ cons _) <- 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) $ tupOrListE $ map VarE names) []
|
||||
where
|
||||
names = zipWith (\ix _ -> mkName $ "a" ++ show (ix :: Int)) [1..] elms
|
||||
|
||||
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 _ name _ cons _) <- reify typName
|
||||
let o = InstanceD [] (AppT (ConT ''OBJECT) (ConT name))
|
||||
[ 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 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 $
|
||||
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] -> 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 == 0 = SigE (ListE []) (AppT ListT (ConT ''()))
|
||||
| length ls == 1 = ListE ls
|
||||
| otherwise = TupE ls
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
43
haskell/test/UserData.hs
Normal file
43
haskell/test/UserData.hs
Normal file
@ -0,0 +1,43 @@
|
||||
{-# Language TemplateHaskell #-}
|
||||
|
||||
import Data.MessagePack
|
||||
import Data.MessagePack.Derive
|
||||
|
||||
data T
|
||||
= A Int String
|
||||
| B Double
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(deriveObject ''T)
|
||||
|
||||
data U
|
||||
= C { c1 :: Int, c2 :: String }
|
||||
| D { d1 :: Double }
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(deriveObject ''U)
|
||||
|
||||
data V
|
||||
= E String | F
|
||||
deriving (Show, Eq)
|
||||
|
||||
$(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 ()
|
27
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
27
java/src/main/java/org/msgpack/AbstractTemplate.java
Normal file
@ -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());
|
||||
}
|
||||
}
|
||||
|
39
java/src/main/java/org/msgpack/CustomConverter.java
Normal file
39
java/src/main/java/org/msgpack/CustomConverter.java
Normal file
@ -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 package private?
|
||||
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<Class, MessageConverter> map = new HashMap<Class, MessageConverter>();
|
||||
}
|
||||
|
30
java/src/main/java/org/msgpack/CustomMessage.java
Normal file
30
java/src/main/java/org/msgpack/CustomMessage.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
39
java/src/main/java/org/msgpack/CustomPacker.java
Normal file
39
java/src/main/java/org/msgpack/CustomPacker.java
Normal file
@ -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 package private?
|
||||
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<Class, MessagePacker> map = new HashMap<Class, MessagePacker>();
|
||||
}
|
||||
|
39
java/src/main/java/org/msgpack/CustomUnpacker.java
Normal file
39
java/src/main/java/org/msgpack/CustomUnpacker.java
Normal file
@ -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 package private?
|
||||
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<Class, MessageUnpacker> map = new HashMap<Class, MessageUnpacker>();
|
||||
}
|
||||
|
25
java/src/main/java/org/msgpack/MessageConverter.java
Normal file
25
java/src/main/java/org/msgpack/MessageConverter.java
Normal file
@ -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 from) throws MessageTypeException;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
25
java/src/main/java/org/msgpack/MessagePacker.java
Normal file
25
java/src/main/java/org/msgpack/MessagePacker.java
Normal file
@ -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;
|
||||
}
|
||||
|
25
java/src/main/java/org/msgpack/MessageUnpacker.java
Normal file
25
java/src/main/java/org/msgpack/MessageUnpacker.java
Normal file
@ -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;
|
||||
}
|
||||
|
@ -473,9 +473,19 @@ public class Packer {
|
||||
return packDouble((Double)o);
|
||||
} else if(o instanceof BigInteger) {
|
||||
return packBigInteger((BigInteger)o);
|
||||
} else {
|
||||
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()+")");
|
||||
}
|
||||
}
|
||||
|
||||
|
26
java/src/main/java/org/msgpack/ReflectionBase.java
Normal file
26
java/src/main/java/org/msgpack/ReflectionBase.java
Normal file
@ -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 {
|
||||
}
|
||||
|
49
java/src/main/java/org/msgpack/ReflectionPacker.java
Normal file
49
java/src/main/java/org/msgpack/ReflectionPacker.java
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
74
java/src/main/java/org/msgpack/ReflectionTemplate.java
Normal file
74
java/src/main/java/org/msgpack/ReflectionTemplate.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
22
java/src/main/java/org/msgpack/Template.java
Normal file
22
java/src/main/java/org/msgpack/Template.java
Normal file
@ -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 {
|
||||
}
|
||||
|
86
java/src/main/java/org/msgpack/Templates.java
Normal file
86
java/src/main/java/org/msgpack/Templates.java
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// 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 Template tClass(Class target) {
|
||||
return new ClassTemplate(target);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -561,12 +561,38 @@ public class Unpacker implements Iterable<MessagePackObject> {
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/BooleanTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/BooleanTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/ByteTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/ByteTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
64
java/src/main/java/org/msgpack/template/ClassTemplate.java
Normal file
64
java/src/main/java/org/msgpack/template/ClassTemplate.java
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// 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 {
|
||||
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 -> code generation -> CustomMessage.registerTemplate
|
||||
|
||||
throw new MessageTypeException();
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/DoubleTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/DoubleTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/FloatTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/FloatTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/IntegerTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/IntegerTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
50
java/src/main/java/org/msgpack/template/ListTemplate.java
Normal file
50
java/src/main/java/org/msgpack/template/ListTemplate.java
Normal file
@ -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<Object> list = new ArrayList<Object>(length);
|
||||
for(; length > 0; length--) {
|
||||
list.add( elementTemplate.unpack(pac) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public Object convert(MessagePackObject from) throws MessageTypeException {
|
||||
MessagePackObject[] array = from.asArray();
|
||||
List<Object> list = new ArrayList<Object>(array.length);
|
||||
for(MessagePackObject element : array) {
|
||||
list.add( elementTemplate.convert(element) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/LongTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/LongTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
56
java/src/main/java/org/msgpack/template/MapTemplate.java
Normal file
56
java/src/main/java/org/msgpack/template/MapTemplate.java
Normal file
@ -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<Object,Object> map = new HashMap<Object,Object>(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<MessagePackObject,MessagePackObject> src = from.asMap();
|
||||
Map<Object,Object> map = new HashMap();
|
||||
for(Map.Entry<MessagePackObject,MessagePackObject> pair : src.entrySet()) {
|
||||
Object key = keyTemplate.convert(pair.getKey());
|
||||
Object value = valueTemplate.convert(pair.getValue());
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/ShortTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/ShortTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
44
java/src/main/java/org/msgpack/template/StringTemplate.java
Normal file
44
java/src/main/java/org/msgpack/template/StringTemplate.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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(); // FIXME link StringTemplate
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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<MessagePackObject> 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<MessagePackObject> 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<Integer>();
|
||||
@ -140,6 +209,39 @@ public class TestMessagePackUnpackable extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTypes02() throws Exception {
|
||||
SampleListTypes src = (SampleListTypes) PackUnpackUtil
|
||||
.newEnhancedInstance(SampleListTypes.class);
|
||||
src.f0 = new ArrayList<Integer>();
|
||||
src.f1 = new ArrayList<Integer>();
|
||||
src.f1.add(1);
|
||||
src.f1.add(2);
|
||||
src.f1.add(3);
|
||||
src.f2 = new ArrayList<String>();
|
||||
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<MessagePackObject> 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 {
|
||||
public List<Integer> f0;
|
||||
@ -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<Integer, Integer>();
|
||||
@ -190,6 +292,49 @@ public class TestMessagePackUnpackable extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testMapTypes02() throws Exception {
|
||||
SampleMapTypes src = (SampleMapTypes) PackUnpackUtil
|
||||
.newEnhancedInstance(SampleMapTypes.class);
|
||||
src.f0 = new HashMap<Integer, Integer>();
|
||||
src.f1 = new HashMap<Integer, Integer>();
|
||||
src.f1.put(1, 1);
|
||||
src.f1.put(2, 2);
|
||||
src.f1.put(3, 3);
|
||||
src.f2 = new HashMap<String, Integer>();
|
||||
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<MessagePackObject> 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<Integer> srcf1 = src.f1.keySet().iterator();
|
||||
Iterator<Integer> 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<String> srcf2 = src.f2.keySet().iterator();
|
||||
Iterator<String> 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 {
|
||||
public Map<Integer, Integer> f0;
|
||||
@ -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<MessagePackObject> 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
|
||||
@ -395,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);
|
||||
@ -407,6 +574,29 @@ 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<MessagePackObject> it = pac.iterator();
|
||||
assertTrue(it.hasNext());
|
||||
MessagePackObject mpo = it.next();
|
||||
BaseClass dst = (BaseClass) PackUnpackUtil.initEnhancedInstance(mpo,
|
||||
BaseClass.class);
|
||||
assertTrue(src.f0 == dst.f0);
|
||||
assertTrue(src2.f2 == dst.f1.f2);
|
||||
assertFalse(it.hasNext());
|
||||
}
|
||||
|
||||
@MessagePackUnpackable
|
||||
public static class BaseClass {
|
||||
public int f0;
|
||||
@ -425,7 +615,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;
|
||||
@ -453,6 +643,38 @@ public class TestMessagePackUnpackable extends TestCase {
|
||||
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<MessagePackObject> 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 {
|
||||
public int f0;
|
||||
|
@ -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}) );
|
||||
|
12
perl/t/13_booleans.t
Executable file
12
perl/t/13_booleans.t
Executable file
@ -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';
|
18
perl/t/14_invalid_data.t
Executable file
18
perl/t/14_invalid_data.t
Executable file
@ -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;
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user