Add explicit binary type to Thrift

Summary: Identical to string in all languages except Java. Java String is NOT binary-safe, so we need to use raw byte[] in that case. PHP/RUBY/Python strings are all binary safe, and C++ std::string works fine and manages memory for you so it's the safest route. Java just needs this tweak.

Reviewed By: aditya

Test Plan: Use "binary" as a type instead of String.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665099 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Slee 2007-04-13 01:57:12 +00:00
parent 4f261c5b23
commit 8d725a2738
9 changed files with 58 additions and 7 deletions

View File

@ -1220,7 +1220,11 @@ void t_java_generator::generate_deserialize_field(ofstream& out,
name;
break;
case t_base_type::TYPE_STRING:
out << "readString();";
if (((t_base_type*)type)->is_binary()) {
out << "readBinary();";
} else {
out << "readString();";
}
break;
case t_base_type::TYPE_BOOL:
out << "readBool();";
@ -1431,7 +1435,11 @@ void t_java_generator::generate_serialize_field(ofstream& out,
"compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
out << "writeString(" << name << ");";
if (((t_base_type*)type)->is_binary()) {
out << "writeBinary(" << name << ");";
} else {
out << "writeString(" << name << ");";
}
break;
case t_base_type::TYPE_BOOL:
out << "writeBool(" << name << ");";
@ -1602,7 +1610,7 @@ string t_java_generator::type_name(t_type* ttype, bool in_container, bool in_ini
}
if (ttype->is_base_type()) {
return base_type_name(((t_base_type*)ttype)->get_base(), in_container);
return base_type_name((t_base_type*)ttype, in_container);
} else if (ttype->is_enum()) {
return (in_container ? "Integer" : "int");
} else if (ttype->is_map()) {
@ -1642,13 +1650,19 @@ string t_java_generator::type_name(t_type* ttype, bool in_container, bool in_ini
* @param tbase The base type
* @param container Is it going in a Java container?
*/
string t_java_generator::base_type_name(t_base_type::t_base tbase,
string t_java_generator::base_type_name(t_base_type* type,
bool in_container) {
t_base_type::t_base tbase = type->get_base();
switch (tbase) {
case t_base_type::TYPE_VOID:
return "void";
case t_base_type::TYPE_STRING:
return "String";
if (type->is_binary()) {
return "byte[]";
} else {
return "String";
}
case t_base_type::TYPE_BOOL:
return "boolean";
case t_base_type::TYPE_BYTE:

View File

@ -124,7 +124,7 @@ class t_java_generator : public t_oop_generator {
std::string java_type_imports();
std::string java_thrift_imports();
std::string type_name(t_type* ttype, bool in_container=false, bool in_init=false);
std::string base_type_name(t_base_type::t_base tbase, bool in_container=false);
std::string base_type_name(t_base_type* tbase, bool in_container=false);
std::string declare_field(t_field* tfield, bool init=false);
std::string function_signature(t_function* tfunction, std::string prefix="");
std::string argument_list(t_struct* tstruct);

View File

@ -47,6 +47,7 @@ extern t_program* g_program;
extern t_type* g_type_void;
extern t_type* g_type_string;
extern t_type* g_type_binary;
extern t_type* g_type_slist;
extern t_type* g_type_bool;
extern t_type* g_type_byte;

View File

@ -42,6 +42,7 @@ t_program* g_program;
t_type* g_type_void;
t_type* g_type_string;
t_type* g_type_binary;
t_type* g_type_slist;
t_type* g_type_bool;
t_type* g_type_byte;
@ -644,6 +645,8 @@ int main(int argc, char** argv) {
// Initialize global types
g_type_void = new t_base_type("void", t_base_type::TYPE_VOID);
g_type_string = new t_base_type("string", t_base_type::TYPE_STRING);
g_type_binary = new t_base_type("string", t_base_type::TYPE_STRING);
((t_base_type*)g_type_binary)->set_binary(true);
g_type_slist = new t_base_type("string", t_base_type::TYPE_STRING);
((t_base_type*)g_type_slist)->set_string_list(true);
g_type_bool = new t_base_type("bool", t_base_type::TYPE_BOOL);

View File

@ -48,7 +48,15 @@ class t_base_type : public t_type {
}
bool is_string_list() const {
return base_ == TYPE_STRING && string_list_;
return (base_ == TYPE_STRING) && string_list_;
}
void set_binary(bool val) {
binary_ = val;
}
bool is_binary() const {
return (base_ == TYPE_STRING) && binary_;
}
void set_string_enum(bool val) {
@ -75,6 +83,7 @@ class t_base_type : public t_type {
t_base base_;
bool string_list_;
bool binary_;
bool string_enum_;
std::vector<std::string> string_enum_vals_;
};

View File

@ -76,6 +76,7 @@ sliteral ("'"[^']*"'")
"i64" { return tok_i64; }
"double" { return tok_double; }
"string" { return tok_string; }
"binary" { return tok_binary; }
"slist" { return tok_slist; }
"senum" { return tok_senum; }
"map" { return tok_map; }

View File

@ -82,6 +82,7 @@ int y_field_val = -1;
%token tok_bool
%token tok_byte
%token tok_string
%token tok_binary
%token tok_slist
%token tok_senum
%token tok_i16
@ -792,6 +793,11 @@ BaseType:
pdebug("BaseType -> tok_string");
$$ = g_type_string;
}
| tok_binary
{
pdebug("BaseType -> tok_binary");
$$ = g_type_binary;
}
| tok_slist
{
pdebug("BaseType -> tok_slist");

View File

@ -126,6 +126,11 @@ public class TBinaryProtocol extends TProtocol {
trans_.write(dat, 0, dat.length);
}
public void writeBinary(byte[] bin) throws TException {
writeI32(bin.length);
trans_.write(bin, 0, bin.length);
}
/**
* Reading methods.
*/
@ -238,4 +243,12 @@ public class TBinaryProtocol extends TProtocol {
trans_.readAll(buf, 0, size);
return new String(buf);
}
public byte[] readBinary() throws TException {
int size = readI32();
byte[] buf = new byte[size];
trans_.readAll(buf, 0, size);
return buf;
}
}

View File

@ -84,6 +84,8 @@ public abstract class TProtocol {
public abstract void writeString(String str) throws TException;
public abstract void writeBinary(byte[] bin) throws TException;
/**
* Reading methods.
*/
@ -126,4 +128,6 @@ public abstract class TProtocol {
public abstract String readString() throws TException;
public abstract byte[] readBinary() throws TException;
}