diff options
Diffstat (limited to 'lib/erl_interface')
-rw-r--r-- | lib/erl_interface/doc/src/ei.xml | 36 | ||||
-rw-r--r-- | lib/erl_interface/include/ei.h | 6 | ||||
-rw-r--r-- | lib/erl_interface/src/decode/decode_tuple_header.c | 23 | ||||
-rw-r--r-- | lib/erl_interface/src/encode/encode_tuple_header.c | 19 | ||||
-rw-r--r-- | lib/erl_interface/src/misc/ei_decode_term.c | 3 | ||||
-rw-r--r-- | lib/erl_interface/src/misc/ei_x_encode.c | 12 |
6 files changed, 93 insertions, 6 deletions
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml index ab185c9179..1756ee8a7d 100644 --- a/lib/erl_interface/doc/src/ei.xml +++ b/lib/erl_interface/doc/src/ei.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2013</year> + <year>2001</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -417,6 +417,27 @@ ei_x_encode_empty_list(&x); </desc> </func> <func> + <name><ret>int</ret><nametext>ei_encode_map_header(char *buf, int *index, int arity)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_map_header(ei_x_buff* x, int arity)</nametext></name> + <fsummary>Encode a map</fsummary> + <desc> + <p>This function encodes a map header, with a specified arity. The next + <c>arity</c> terms encoded will be the keys of the map, and the next + <c>arity</c> terms after that will be the corresponding values in + same order.</p> + <p>E.g. to encode the map <c>#{a => "Apple", b => "Banana"}</c>:</p> + <pre> +ei_x_encode_map_header(&x, 2); +ei_x_encode_atom(&x, "a"); +ei_x_encode_atom(&x, "b"); +ei_x_encode_string(&x, "Apple"); +ei_x_encode_string(&x, "Banana"); + </pre> + <p>A correctly encoded map can not have duplicate keys, but no check + for duplicate keys is done by this function.</p> + </desc> + </func> + <func> <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name> <fsummary>Fetch the type and size of an encoded term</fsummary> <desc> @@ -638,6 +659,19 @@ ei_x_encode_empty_list(&x); </desc> </func> <func> + <name><ret>int</ret><nametext>ei_decode_map_header(const char *buf, int *index, int *arity)</nametext></name> + <fsummary>Decode a map</fsummary> + <desc> + <p>This function decodes a map header from the binary + format. The number of key-value pairs is returned in + <c>arity</c>. Keys and values follows, first all keys and then all values, + which makes a total of <c>arity*2</c> terms. + Keys and values are paired according to their order, the first key + with the first value and so on. If <c>arity</c> is zero, it's an empty map. + A correctly encoded map does not have duplicate keys.</p> + </desc> + </func> + <func> <name><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name> <fsummary>Decode a term, without prior knowledge of type</fsummary> <desc> diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h index 9b83385a46..a3eb437f88 100644 --- a/lib/erl_interface/include/ei.h +++ b/lib/erl_interface/include/ei.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * Copyright Ericsson AB 1998-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -131,6 +131,7 @@ #define ERL_SMALL_BIG_EXT 'n' #define ERL_LARGE_BIG_EXT 'o' #define ERL_NEW_FUN_EXT 'p' +#define ERL_MAP_EXT 't' #define ERL_FUN_EXT 'u' #define ERL_NEW_CACHE 'N' /* c nodes don't know these two */ @@ -467,6 +468,8 @@ int ei_encode_list_header(char *buf, int *index, int arity); int ei_x_encode_list_header(ei_x_buff* x, long n); #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0) int ei_x_encode_empty_list(ei_x_buff* x); +int ei_encode_map_header(char *buf, int *index, int arity); +int ei_x_encode_map_header(ei_x_buff* x, long n); /* * ei_get_type() returns the type and "size" of the item at @@ -507,6 +510,7 @@ int ei_decode_term(const char *buf, int *index, void *t); /* ETERM** actually */ int ei_decode_trace(const char *buf, int *index, erlang_trace *p); int ei_decode_tuple_header(const char *buf, int *index, int *arity); int ei_decode_list_header(const char *buf, int *index, int *arity); +int ei_decode_map_header(const char *buf, int *index, int *arity); /* * ei_decode_ei_term() returns 1 if term is decoded, 0 if term is OK, diff --git a/lib/erl_interface/src/decode/decode_tuple_header.c b/lib/erl_interface/src/decode/decode_tuple_header.c index c0ba14ea47..698be1b97a 100644 --- a/lib/erl_interface/src/decode/decode_tuple_header.c +++ b/lib/erl_interface/src/decode/decode_tuple_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -45,3 +45,24 @@ int ei_decode_tuple_header(const char *buf, int *index, int *arity) return 0; } + +int ei_decode_map_header(const char *buf, int *index, int *arity) +{ + const char *s = buf + *index; + const char *s0 = s; + int i; + + switch ((i=get8(s))) { + case ERL_MAP_EXT: + if (arity) *arity = get32be(s); + else s += 4; + break; + + default: + return -1; + } + + *index += s-s0; + + return 0; +} diff --git a/lib/erl_interface/src/encode/encode_tuple_header.c b/lib/erl_interface/src/encode/encode_tuple_header.c index 97a3d1f808..5b11e60447 100644 --- a/lib/erl_interface/src/encode/encode_tuple_header.c +++ b/lib/erl_interface/src/encode/encode_tuple_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -47,3 +47,20 @@ int ei_encode_tuple_header(char *buf, int *index, int arity) return 0; } +int ei_encode_map_header(char *buf, int *index, int arity) +{ + char *s = buf + *index; + char *s0 = s; + + if (arity < 0) return -1; + + if (!buf) s += 5; + else { + put8(s,ERL_MAP_EXT); + put32be(s,arity); + } + + *index += s-s0; + + return 0; +} diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c index ce5ae5b19d..2e7317f781 100644 --- a/lib/erl_interface/src/misc/ei_decode_term.c +++ b/lib/erl_interface/src/misc/ei_decode_term.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -100,6 +100,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term) term->size = get16be(s); return 0; case ERL_LIST_EXT: + case ERL_MAP_EXT: term->arity = get32be(s); break; case ERL_BINARY_EXT: diff --git a/lib/erl_interface/src/misc/ei_x_encode.c b/lib/erl_interface/src/misc/ei_x_encode.c index 14d0b56b8f..10542c88a5 100644 --- a/lib/erl_interface/src/misc/ei_x_encode.c +++ b/lib/erl_interface/src/misc/ei_x_encode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -206,6 +206,16 @@ int ei_x_encode_tuple_header(ei_x_buff* x, long n) return ei_encode_tuple_header(x->buff, &x->index, n); } +int ei_x_encode_map_header(ei_x_buff* x, long n) +{ + int i = x->index; + if (ei_encode_map_header(NULL, &i, n) == -1) + return -1; + if (!x_fix_buff(x, i)) + return -1; + return ei_encode_map_header(x->buff, &x->index, n); +} + int ei_x_encode_atom(ei_x_buff* x, const char* s) { return ei_x_encode_atom_len_as(x, s, strlen(s), ERLANG_LATIN1, ERLANG_LATIN1); |