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
63d4b5fd
Commit
63d4b5fd
authored
Jun 06, 2013
by
Wink Saville
Committed by
Gerrit Code Review
Jun 06, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Add toString() method to MessageNano."
parents
b0874cc6
a1612155
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
241 additions
and
0 deletions
+241
-0
MessageNano.java
java/src/main/java/com/google/protobuf/nano/MessageNano.java
+8
-0
MessageNanoPrinter.java
...ain/java/com/google/protobuf/nano/MessageNanoPrinter.java
+179
-0
NanoTest.java
java/src/test/java/com/google/protobuf/NanoTest.java
+54
-0
No files found.
java/src/main/java/com/google/protobuf/nano/MessageNano.java
View file @
63d4b5fd
...
@@ -125,4 +125,12 @@ public abstract class MessageNano {
...
@@ -125,4 +125,12 @@ public abstract class MessageNano {
+
"never happen)."
);
+
"never happen)."
);
}
}
}
}
/**
* Intended for debugging purposes only. It does not use ASCII protobuf formatting.
*/
@Override
public
String
toString
()
{
return
MessageNanoPrinter
.
print
(
this
);
}
}
}
java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
0 → 100644
View file @
63d4b5fd
// Protocol Buffers - Google's data interchange format
// Copyright 2013 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package
com
.
google
.
protobuf
.
nano
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Modifier
;
/**
* Static helper methods for printing nano protos.
*
* @author flynn@google.com Andrew Flynn
*/
public
final
class
MessageNanoPrinter
{
// Do not allow instantiation
private
MessageNanoPrinter
()
{}
private
static
final
String
INDENT
=
" "
;
private
static
final
int
MAX_STRING_LEN
=
200
;
/**
* Returns an text representation of a MessageNano suitable for debugging.
*
* <p>Employs Java reflection on the given object and recursively prints primitive fields,
* groups, and messages.</p>
*/
public
static
<
T
extends
MessageNano
>
String
print
(
T
message
)
{
if
(
message
==
null
)
{
return
"null"
;
}
StringBuffer
buf
=
new
StringBuffer
();
try
{
print
(
message
.
getClass
().
getSimpleName
(),
message
.
getClass
(),
message
,
new
StringBuffer
(),
buf
);
}
catch
(
IllegalAccessException
e
)
{
return
"Error printing proto: "
+
e
.
getMessage
();
}
return
buf
.
toString
();
}
/**
* Function that will print the given message/class into the StringBuffer.
* Meant to be called recursively.
*/
private
static
void
print
(
String
identifier
,
Class
<?>
clazz
,
Object
message
,
StringBuffer
indentBuf
,
StringBuffer
buf
)
throws
IllegalAccessException
{
if
(
MessageNano
.
class
.
isAssignableFrom
(
clazz
))
{
// Nano proto message
buf
.
append
(
indentBuf
).
append
(
identifier
);
// If null, just print it and return
if
(
message
==
null
)
{
buf
.
append
(
": "
).
append
(
message
).
append
(
"\n"
);
return
;
}
indentBuf
.
append
(
INDENT
);
buf
.
append
(
" <\n"
);
for
(
Field
field
:
clazz
.
getFields
())
{
// Proto fields are public, non-static variables that do not begin or end with '_'
int
modifiers
=
field
.
getModifiers
();
String
fieldName
=
field
.
getName
();
if
((
modifiers
&
Modifier
.
PUBLIC
)
!=
Modifier
.
PUBLIC
||
(
modifiers
&
Modifier
.
STATIC
)
==
Modifier
.
STATIC
||
fieldName
.
startsWith
(
"_"
)
||
fieldName
.
endsWith
(
"_"
))
{
continue
;
}
Class
<?>
fieldType
=
field
.
getType
();
Object
value
=
field
.
get
(
message
);
if
(
fieldType
.
isArray
())
{
Class
<?>
arrayType
=
fieldType
.
getComponentType
();
// bytes is special since it's not repeated, but is represented by an array
if
(
arrayType
==
byte
.
class
)
{
print
(
fieldName
,
fieldType
,
value
,
indentBuf
,
buf
);
}
else
{
int
len
=
Array
.
getLength
(
value
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Object
elem
=
Array
.
get
(
value
,
i
);
print
(
fieldName
,
arrayType
,
elem
,
indentBuf
,
buf
);
}
}
}
else
{
print
(
fieldName
,
fieldType
,
value
,
indentBuf
,
buf
);
}
}
indentBuf
.
delete
(
indentBuf
.
length
()
-
INDENT
.
length
(),
indentBuf
.
length
());
buf
.
append
(
indentBuf
).
append
(
">\n"
);
}
else
{
// Primitive value
identifier
=
deCamelCaseify
(
identifier
);
buf
.
append
(
indentBuf
).
append
(
identifier
).
append
(
": "
);
if
(
message
instanceof
String
)
{
String
stringMessage
=
sanitizeString
((
String
)
message
);
buf
.
append
(
"\""
).
append
(
stringMessage
).
append
(
"\""
);
}
else
{
buf
.
append
(
message
);
}
buf
.
append
(
"\n"
);
}
}
/**
* Converts an identifier of the format "FieldName" into "field_name".
*/
private
static
String
deCamelCaseify
(
String
identifier
)
{
StringBuffer
out
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
identifier
.
length
();
i
++)
{
char
currentChar
=
identifier
.
charAt
(
i
);
if
(
i
==
0
)
{
out
.
append
(
Character
.
toLowerCase
(
currentChar
));
}
else
if
(
Character
.
isUpperCase
(
currentChar
))
{
out
.
append
(
'_'
).
append
(
Character
.
toLowerCase
(
currentChar
));
}
else
{
out
.
append
(
currentChar
);
}
}
return
out
.
toString
();
}
/**
* Shortens and escapes the given string.
*/
private
static
String
sanitizeString
(
String
str
)
{
if
(!
str
.
startsWith
(
"http"
)
&&
str
.
length
()
>
MAX_STRING_LEN
)
{
// Trim non-URL strings.
str
=
str
.
substring
(
0
,
MAX_STRING_LEN
)
+
"[...]"
;
}
return
escapeString
(
str
);
}
/**
* Escape everything except for low ASCII code points.
*/
private
static
String
escapeString
(
String
str
)
{
int
strLen
=
str
.
length
();
StringBuilder
b
=
new
StringBuilder
(
strLen
);
for
(
int
i
=
0
;
i
<
strLen
;
i
++)
{
char
original
=
str
.
charAt
(
i
);
if
(
original
>=
' '
&&
original
<=
'~'
&&
original
!=
'"'
&&
original
!=
'\''
)
{
b
.
append
(
original
);
}
else
{
b
.
append
(
String
.
format
(
"\\u%04x"
,
(
int
)
original
));
}
}
return
b
.
toString
();
}
}
java/src/test/java/com/google/protobuf/NanoTest.java
View file @
63d4b5fd
...
@@ -2101,4 +2101,58 @@ public class NanoTest extends TestCase {
...
@@ -2101,4 +2101,58 @@ public class NanoTest extends TestCase {
input
.
popLimit
(
limit
);
input
.
popLimit
(
limit
);
assertEquals
(
5
,
input
.
readRawByte
());
assertEquals
(
5
,
input
.
readRawByte
());
}
}
// Test a smattering of various proto types for printing
public
void
testMessageNanoPrinter
()
{
TestAllTypesNano
msg
=
new
TestAllTypesNano
();
msg
.
optionalInt32
=
14
;
msg
.
optionalFloat
=
42.3f
;
msg
.
optionalString
=
"String \"with' both quotes"
;
msg
.
optionalBytes
=
new
byte
[
5
];
msg
.
optionalGroup
=
new
TestAllTypesNano
.
OptionalGroup
();
msg
.
optionalGroup
.
a
=
15
;
msg
.
repeatedInt64
=
new
long
[
2
];
msg
.
repeatedInt64
[
0
]
=
1L
;
msg
.
repeatedInt64
[
1
]
=
-
1L
;
msg
.
repeatedBytes
=
new
byte
[
2
][];
msg
.
repeatedBytes
[
1
]
=
new
byte
[
5
];
msg
.
repeatedGroup
=
new
TestAllTypesNano
.
RepeatedGroup
[
2
];
msg
.
repeatedGroup
[
0
]
=
new
TestAllTypesNano
.
RepeatedGroup
();
msg
.
repeatedGroup
[
0
].
a
=
-
27
;
msg
.
repeatedGroup
[
1
]
=
new
TestAllTypesNano
.
RepeatedGroup
();
msg
.
repeatedGroup
[
1
].
a
=
-
72
;
msg
.
optionalNestedMessage
=
new
TestAllTypesNano
.
NestedMessage
();
msg
.
optionalNestedMessage
.
bb
=
7
;
msg
.
repeatedNestedMessage
=
new
TestAllTypesNano
.
NestedMessage
[
2
];
msg
.
repeatedNestedMessage
[
0
]
=
new
TestAllTypesNano
.
NestedMessage
();
msg
.
repeatedNestedMessage
[
0
].
bb
=
77
;
msg
.
repeatedNestedMessage
[
1
]
=
new
TestAllTypesNano
.
NestedMessage
();
msg
.
repeatedNestedMessage
[
1
].
bb
=
88
;
msg
.
optionalNestedEnum
=
TestAllTypesNano
.
BAZ
;
msg
.
repeatedNestedEnum
=
new
int
[
2
];
msg
.
repeatedNestedEnum
[
0
]
=
TestAllTypesNano
.
BAR
;
msg
.
repeatedNestedEnum
[
1
]
=
TestAllTypesNano
.
FOO
;
String
protoPrint
=
msg
.
toString
();
assertTrue
(
protoPrint
.
contains
(
"TestAllTypesNano <"
));
assertTrue
(
protoPrint
.
contains
(
" optional_int32: 14"
));
assertTrue
(
protoPrint
.
contains
(
" optional_float: 42.3"
));
assertTrue
(
protoPrint
.
contains
(
" optional_double: 0.0"
));
assertTrue
(
protoPrint
.
contains
(
" optional_string: \"String \\u0022with\\u0027 both quotes\""
));
assertTrue
(
protoPrint
.
contains
(
" optional_bytes: [B@"
));
assertTrue
(
protoPrint
.
contains
(
" optionalGroup <\n a: 15\n >"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_int64: 1"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_int64: -1"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_bytes: null\n repeated_bytes: [B@"
));
assertTrue
(
protoPrint
.
contains
(
" repeatedGroup <\n a: -27\n >\n"
+
" repeatedGroup <\n a: -72\n >"
));
assertTrue
(
protoPrint
.
contains
(
" optionalNestedMessage <\n bb: 7\n >"
));
assertTrue
(
protoPrint
.
contains
(
" repeatedNestedMessage <\n bb: 77\n >\n"
+
" repeatedNestedMessage <\n bb: 88\n >"
));
assertTrue
(
protoPrint
.
contains
(
" optional_nested_enum: 3"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_nested_enum: 2\n repeated_nested_enum: 1"
));
assertTrue
(
protoPrint
.
contains
(
" default_int32: 41"
));
assertTrue
(
protoPrint
.
contains
(
" default_string: \"hello\""
));
}
}
}
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