Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
d7af73cc
Commit
d7af73cc
authored
Mar 18, 2009
by
Jean-Baptiste Queru
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'remotes/korg/cupcake' into merge
parents
35be73bf
82155ace
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
325 additions
and
19 deletions
+325
-19
ProtoBuf.java
src/com/google/common/io/protocol/ProtoBuf.java
+127
-7
ProtoBufType.java
src/com/google/common/io/protocol/ProtoBufType.java
+48
-2
ProtoBufUtil.java
src/com/google/common/io/protocol/ProtoBufUtil.java
+150
-10
No files found.
src/com/google/common/io/protocol/ProtoBuf.java
View file @
d7af73cc
...
...
@@ -46,12 +46,12 @@ public class ProtoBuf {
private
static
final
String
MSG_UNSUPPORTED
=
"Unsupp.Type"
;
// names copied from //net/proto2/internal/wire_format.cc
private
static
final
int
WIRETYPE_END_GROUP
=
4
;
private
static
final
int
WIRETYPE_FIXED32
=
5
;
private
static
final
int
WIRETYPE_FIXED64
=
1
;
private
static
final
int
WIRETYPE_LENGTH_DELIMITED
=
2
;
private
static
final
int
WIRETYPE_START_GROUP
=
3
;
private
static
final
int
WIRETYPE_VARINT
=
0
;
static
final
int
WIRETYPE_END_GROUP
=
4
;
static
final
int
WIRETYPE_FIXED32
=
5
;
static
final
int
WIRETYPE_FIXED64
=
1
;
static
final
int
WIRETYPE_LENGTH_DELIMITED
=
2
;
static
final
int
WIRETYPE_START_GROUP
=
3
;
static
final
int
WIRETYPE_VARINT
=
0
;
/** Maximum number of bytes for VARINT wire format (64 bit, 7 bit/byte) */
private
static
final
int
VARINT_MAX_BYTES
=
10
;
...
...
@@ -62,7 +62,7 @@ public class ProtoBuf {
new
Long
(
10
),
new
Long
(
11
),
new
Long
(
12
),
new
Long
(
13
),
new
Long
(
14
),
new
Long
(
15
)};
private
final
ProtoBufType
msgType
;
private
ProtoBufType
msgType
;
private
final
Vector
values
=
new
Vector
();
/**
...
...
@@ -123,6 +123,20 @@ public class ProtoBuf {
insertLong
(
tag
,
getCount
(
tag
),
value
);
}
/**
* Appends the given (repeated) tag with the given float value.
*/
public
void
addFloat
(
int
tag
,
float
value
)
{
insertFloat
(
tag
,
getCount
(
tag
),
value
);
}
/**
* Appends the given (repeated) tag with the given double value.
*/
public
void
addDouble
(
int
tag
,
double
value
)
{
insertDouble
(
tag
,
getCount
(
tag
),
value
);
}
/**
* Appends the given (repeated) tag with the given group or message value.
*/
...
...
@@ -130,6 +144,28 @@ public class ProtoBuf {
insertProtoBuf
(
tag
,
getCount
(
tag
),
value
);
}
/**
* Adds a new protobuf for the specified tag, setting the child protobuf's
* type correctly for the tag.
* @param tag the tag for which to create a new protobuf
* @return the newly created protobuf
*/
public
ProtoBuf
addNewProtoBuf
(
int
tag
)
{
ProtoBuf
child
=
newProtoBufForTag
(
tag
);
addProtoBuf
(
tag
,
child
);
return
child
;
}
/**
* Creates and returns a new protobuf for the specified tag, setting the new
* protobuf's type correctly for the tag.
* @param tag the tag for which to create a new protobuf
* @return the newly created protobuf
*/
public
ProtoBuf
newProtoBufForTag
(
int
tag
)
{
return
new
ProtoBuf
((
ProtoBufType
)
msgType
.
getData
(
tag
));
}
/**
* Appends the given (repeated) tag with the given String value.
*/
...
...
@@ -196,6 +232,34 @@ public class ProtoBuf {
return
((
Long
)
getObject
(
tag
,
index
,
ProtoBufType
.
TYPE_INT64
)).
longValue
();
}
/**
* Returns the float value for the given tag.
*/
public
float
getFloat
(
int
tag
)
{
return
Float
.
intBitsToFloat
(
getInt
(
tag
));
}
/**
* Returns the float value for the given repeated tag at the given index.
*/
public
float
getFloat
(
int
tag
,
int
index
)
{
return
Float
.
intBitsToFloat
(
getInt
(
tag
,
index
));
}
/**
* Returns the double value for the given tag.
*/
public
double
getDouble
(
int
tag
)
{
return
Double
.
longBitsToDouble
(
getLong
(
tag
));
}
/**
* Returns the double value for the given repeated tag at the given index.
*/
public
double
getDouble
(
int
tag
,
int
index
)
{
return
Double
.
longBitsToDouble
(
getLong
(
tag
,
index
));
}
/**
* Returns the group or nested message for the given tag.
*/
...
...
@@ -234,6 +298,20 @@ public class ProtoBuf {
return
msgType
;
}
/**
* Sets the type definition of this protocol buffer. Used internally in
* ProtoBufUtil for incremental reading.
*
* @param type the new type
*/
void
setType
(
ProtoBufType
type
)
{
if
(
values
.
size
()
!=
0
||
(
msgType
!=
null
&&
type
!=
null
&&
type
!=
msgType
))
{
throw
new
IllegalArgumentException
();
}
this
.
msgType
=
type
;
}
/**
* Convenience method for determining whether a tag has a value. Note: in
* contrast to getCount(tag) > 0, this method takes the default value
...
...
@@ -652,6 +730,20 @@ public class ProtoBuf {
?
SMALL_NUMBERS
[(
int
)
value
]
:
new
Long
(
value
));
}
/**
* Sets the given tag to the given double value.
*/
public
void
setDouble
(
int
tag
,
double
value
)
{
setLong
(
tag
,
Double
.
doubleToLongBits
(
value
));
}
/**
* Sets the given tag to the given float value.
*/
public
void
setFloat
(
int
tag
,
float
value
)
{
setInt
(
tag
,
Float
.
floatToIntBits
(
value
));
}
/**
* Sets the given tag to the given Group or nested Message.
*/
...
...
@@ -659,6 +751,18 @@ public class ProtoBuf {
setObject
(
tag
,
pb
);
}
/**
* Sets a new protobuf for the specified tag, setting the child protobuf's
* type correctly for the tag.
* @param tag the tag for which to create a new protobuf
* @return the newly created protobuf
*/
public
ProtoBuf
setNewProtoBuf
(
int
tag
)
{
ProtoBuf
child
=
newProtoBufForTag
(
tag
);
setProtoBuf
(
tag
,
child
);
return
child
;
}
/**
* Sets the given tag to the given String value.
*/
...
...
@@ -695,6 +799,20 @@ public class ProtoBuf {
?
SMALL_NUMBERS
[(
int
)
value
]
:
new
Long
(
value
));
}
/**
* Inserts the given float value for the given tag at the given index.
*/
public
void
insertFloat
(
int
tag
,
int
index
,
float
value
)
{
insertInt
(
tag
,
index
,
Float
.
floatToIntBits
(
value
));
}
/**
* Inserts the given double value for the given tag at the given index.
*/
public
void
insertDouble
(
int
tag
,
int
index
,
double
value
)
{
insertLong
(
tag
,
index
,
Double
.
doubleToLongBits
(
value
));
}
/**
* Inserts the given group or message for the given tag at the given index.
*/
...
...
@@ -739,6 +857,8 @@ public class ProtoBuf {
case
ProtoBufType
.
TYPE_UINT64
:
case
ProtoBufType
.
TYPE_SINT32
:
case
ProtoBufType
.
TYPE_SINT64
:
case
ProtoBufType
.
TYPE_FLOAT
:
case
ProtoBufType
.
TYPE_DOUBLE
:
return
;
}
}
else
if
(
object
instanceof
byte
[]){
...
...
src/com/google/common/io/protocol/ProtoBufType.java
View file @
d7af73cc
// Copyright 2007
The Android Open Source Project
// Copyright 2007
Google Inc.
// All Rights Reserved.
package
com
.
google
.
common
.
io
.
protocol
;
...
...
@@ -9,7 +9,6 @@ import java.util.*;
* This class can be used to create a memory model of a .proto file. Currently,
* it is assumed that tags ids are not large. This could be improved by storing
* a start offset, relaxing the assumption to a dense number space.
*
*/
public
class
ProtoBufType
{
// Note: Values 0..15 are reserved for wire types!
...
...
@@ -121,4 +120,51 @@ public class ProtoBufType {
public
String
toString
()
{
return
typeName
;
}
/**
* {@inheritDoc}
* <p>Two ProtoBufTypes are equals if the fields types are the same.
*/
public
boolean
equals
(
Object
object
)
{
if
(
null
==
object
)
{
// trivial check
return
false
;
}
else
if
(
this
==
object
)
{
// trivial check
return
true
;
}
else
if
(
this
.
getClass
()
!=
object
.
getClass
())
{
// different class
return
false
;
}
ProtoBufType
other
=
(
ProtoBufType
)
object
;
return
stringEquals
(
types
,
other
.
types
);
}
/**
* {@inheritDoc}
*/
public
int
hashCode
()
{
if
(
types
!=
null
)
{
return
types
.
hashCode
();
}
else
{
return
super
.
hashCode
();
}
}
public
static
boolean
stringEquals
(
CharSequence
a
,
CharSequence
b
)
{
if
(
a
==
b
)
return
true
;
int
length
;
if
(
a
!=
null
&&
b
!=
null
&&
(
length
=
a
.
length
())
==
b
.
length
())
{
if
(
a
instanceof
String
&&
b
instanceof
String
)
{
return
a
.
equals
(
b
);
}
else
{
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
if
(
a
.
charAt
(
i
)
!=
b
.
charAt
(
i
))
return
false
;
}
return
true
;
}
}
return
false
;
}
}
src/com/google/common/io/protocol/ProtoBufUtil.java
View file @
d7af73cc
// Copyright 2008
The Android Open Source Project
// Copyright 2008
Google Inc. All Rights Reserved.
package
com
.
google
.
common
.
io
.
protocol
;
import
java.io.*
;
/**
* Utility functions for dealing with ProtoBuf objects consolidated from
* previous spot implementations across the codebase.
...
...
@@ -24,14 +26,39 @@ public final class ProtoBufUtil {
public
static
String
getSubProtoValueOrEmpty
(
ProtoBuf
proto
,
int
sub
,
int
tag
)
{
try
{
ProtoBuf
subProto
=
(
proto
!=
null
&&
proto
.
has
(
sub
))
?
proto
.
getProtoBuf
(
sub
)
:
null
;
return
getProtoValueOrEmpty
(
subProto
,
tag
);
return
getProtoValueOrEmpty
(
getSubProtoOrNull
(
proto
,
sub
),
tag
);
}
catch
(
ClassCastException
e
)
{
return
""
;
}
}
/** Convenience method to get a subproto if the proto has it. */
public
static
ProtoBuf
getSubProtoOrNull
(
ProtoBuf
proto
,
int
sub
)
{
return
(
proto
!=
null
&&
proto
.
has
(
sub
))
?
proto
.
getProtoBuf
(
sub
)
:
null
;
}
/**
* Get an int with "tag" from the proto buffer. If the given field can't be
* retrieved, return the provided default value.
*
* @param proto The proto buffer.
* @param tag The tag value that identifies which protocol buffer field to
* retrieve.
* @param defaultValue The value to return if the field can't be retrieved.
* @return The result which should be an integer.
*/
public
static
int
getProtoValueOrDefault
(
ProtoBuf
proto
,
int
tag
,
int
defaultValue
)
{
try
{
return
(
proto
!=
null
&&
proto
.
has
(
tag
))
?
proto
.
getInt
(
tag
)
:
defaultValue
;
}
catch
(
IllegalArgumentException
e
)
{
return
defaultValue
;
}
catch
(
ClassCastException
e
)
{
return
defaultValue
;
}
}
/**
* Get an Int with "tag" from the proto buffer.
* If the given field can't be retrieved, return 0.
...
...
@@ -42,12 +69,25 @@ public final class ProtoBufUtil {
* @return The result which should be an integer.
*/
public
static
int
getProtoValueOrZero
(
ProtoBuf
proto
,
int
tag
)
{
return
getProtoValueOrDefault
(
proto
,
tag
,
0
);
}
/**
* Get an Long with "tag" from the proto buffer.
* If the given field can't be retrieved, return 0.
*
* @param proto The proto buffer.
* @param tag The tag value that identifies which protocol buffer field to
* retrieve.
* @return The result which should be an integer.
*/
public
static
long
getProtoLongValueOrZero
(
ProtoBuf
proto
,
int
tag
)
{
try
{
return
(
proto
!=
null
&&
proto
.
has
(
tag
))
?
proto
.
get
Int
(
tag
)
:
0
;
return
(
proto
!=
null
&&
proto
.
has
(
tag
))
?
proto
.
get
Long
(
tag
)
:
0L
;
}
catch
(
IllegalArgumentException
e
)
{
return
0
;
return
0
L
;
}
catch
(
ClassCastException
e
)
{
return
0
;
return
0
L
;
}
}
...
...
@@ -70,6 +110,39 @@ public final class ProtoBufUtil {
}
}
/**
* Reads a single protocol buffer from the given input stream. This method is
* provided where the client needs incremental access to the contents of a
* protocol buffer which contains a sequence of protocol buffers.
* <p />
* Please use {@link #getInputStreamForProtoBufResponse} to obtain an input
* stream suitable for this method.
*
* @param umbrellaType the type of the "outer" protocol buffer containing
* the message to read
* @param is the stream to read the protocol buffer from
* @param result the result protocol buffer (must be empty, will be filled
* with the data read and the type will be set)
* @return the tag id of the message, -1 at the end of the stream
*/
public
static
int
readNextProtoBuf
(
ProtoBufType
umbrellaType
,
InputStream
is
,
ProtoBuf
result
)
throws
IOException
{
long
tagAndType
=
ProtoBuf
.
readVarInt
(
is
,
true
/* permits EOF */
);
if
(
tagAndType
==
-
1
)
{
return
-
1
;
}
if
((
tagAndType
&
7
)
!=
ProtoBuf
.
WIRETYPE_LENGTH_DELIMITED
)
{
throw
new
IOException
(
"Message expected"
);
}
int
tag
=
(
int
)
(
tagAndType
>>>
3
);
result
.
setType
((
ProtoBufType
)
umbrellaType
.
getData
(
tag
));
int
length
=
(
int
)
ProtoBuf
.
readVarInt
(
is
,
false
);
result
.
parse
(
is
,
length
);
return
tag
;
}
/**
* A wrapper for <code> getProtoValueOrNegativeOne </code> that drills into
* a sub message returning the long value if it exists, returning -1 if it
...
...
@@ -85,13 +158,80 @@ public final class ProtoBufUtil {
public
static
long
getSubProtoValueOrNegativeOne
(
ProtoBuf
proto
,
int
sub
,
int
tag
)
{
try
{
ProtoBuf
subProto
=
(
proto
!=
null
&&
proto
.
has
(
sub
))
?
proto
.
getProtoBuf
(
sub
)
:
null
;
return
getProtoValueOrNegativeOne
(
subProto
,
tag
);
return
getProtoValueOrNegativeOne
(
getSubProtoOrNull
(
proto
,
sub
),
tag
);
}
catch
(
IllegalArgumentException
e
)
{
return
-
1
;
}
catch
(
ClassCastException
e
)
{
return
-
1
;
}
}
/**
* A wrapper for {@link #getProtoValueOrDefault(ProtoBuf, int, int)} that
* drills into a sub message returning the int value if it exists, returning
* the given default if it does not.
*
* @param proto The proto buffer.
* @param tag The tag value that identifies which protocol buffer field to
* retrieve.
* @param sub The sub tag value that identifies which protocol buffer
* sub-field to retrieve.
* @param defaultValue The value to return if the field is not present.
* @return The result which should be a long.
*/
public
static
int
getSubProtoValueOrDefault
(
ProtoBuf
proto
,
int
sub
,
int
tag
,
int
defaultValue
)
{
try
{
return
getProtoValueOrDefault
(
getSubProtoOrNull
(
proto
,
sub
),
tag
,
defaultValue
);
}
catch
(
IllegalArgumentException
e
)
{
return
defaultValue
;
}
catch
(
ClassCastException
e
)
{
return
defaultValue
;
}
}
/**
* Creates a sub ProtoBuf of the given Protobuf and sets it.
*
* @param proto The proto buffer.
* @param tag The tag value that identifies which protocol buffer field to
* create.
* @return the sub ProtoBuf generated.
*/
public
static
ProtoBuf
createProtoBuf
(
ProtoBuf
proto
,
int
tag
)
{
ProtoBuf
child
=
proto
.
createGroup
(
tag
);
proto
.
setProtoBuf
(
tag
,
child
);
return
child
;
}
/**
* Creates a sub ProtoBuf of the given Protobuf and adds it.
*
* @param proto The proto buffer.
* @param tag The tag value that identifies which protocol buffer field to
* add.
* @return the sub ProtoBuf generated.
*/
public
static
ProtoBuf
addProtoBuf
(
ProtoBuf
proto
,
int
tag
)
{
ProtoBuf
child
=
proto
.
createGroup
(
tag
);
proto
.
addProtoBuf
(
tag
,
child
);
return
child
;
}
/**
* Writes the ProtoBuf to the given DataOutput. This is useful for unit
* tests.
*
* @param output The data output to write to.
* @param protoBuf The proto buffer.
*/
public
static
void
writeProtoBufToOutput
(
DataOutput
output
,
ProtoBuf
protoBuf
)
throws
IOException
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
protoBuf
.
outputTo
(
baos
);
byte
[]
bytes
=
baos
.
toByteArray
();
output
.
writeInt
(
bytes
.
length
);
output
.
write
(
bytes
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment