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
1e29e701
Commit
1e29e701
authored
Feb 07, 2015
by
csharptest
Committed by
rogerk
Feb 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix build error for missing method Enum.GetValues() on some platforms
parent
e234691b
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
126 additions
and
105 deletions
+126
-105
AbstractReader.cs
src/ProtocolBuffers.Serialization/AbstractReader.cs
+4
-18
CodedInputStream.cs
src/ProtocolBuffers/CodedInputStream.cs
+1
-81
EnumLite.cs
src/ProtocolBuffers/EnumLite.cs
+121
-6
No files found.
src/ProtocolBuffers.Serialization/AbstractReader.cs
View file @
1e29e701
...
...
@@ -469,24 +469,13 @@ namespace Google.ProtocolBuffers.Serialization
rawValue
=
null
;
if
(
ReadEnum
(
ref
rawValue
))
{
if
(
Enum
.
IsDefined
(
typeof
(
T
),
rawValue
))
{
if
(
rawValue
is
int
)
{
value
=
(
T
)
rawValue
;
}
else
if
(
rawValue
is
string
)
{
value
=
(
T
)
Enum
.
Parse
(
typeof
(
T
),
(
string
)
rawValue
,
false
);
}
else
if
(!
EnumParser
<
T
>.
TryConvert
(
rawValue
,
ref
value
))
{
value
=
default
(
T
);
return
false
;
}
return
true
;
}
}
return
false
;
}
...
...
@@ -560,13 +549,10 @@ namespace Google.ProtocolBuffers.Serialization
{
foreach
(
object
rawValue
in
array
)
{
if
(
rawValue
is
int
)
{
list
.
Add
((
T
)
rawValue
);
}
else
if
(
rawValue
is
string
)
T
val
=
default
(
T
);
if
(
EnumParser
<
T
>.
TryConvert
(
rawValue
,
ref
val
))
{
list
.
Add
(
(
T
)
Enum
.
Parse
(
typeof
(
T
),
(
string
)
rawValue
,
false
)
);
list
.
Add
(
val
);
}
else
{
...
...
src/ProtocolBuffers/CodedInputStream.cs
View file @
1e29e701
...
...
@@ -482,7 +482,7 @@ namespace Google.ProtocolBuffers
where
T
:
struct
,
IComparable
,
IFormattable
{
int
number
=
(
int
)
ReadRawVarint32
();
if
(
Enum
Help
er
<
T
>.
TryConvert
(
number
,
ref
value
))
if
(
Enum
Pars
er
<
T
>.
TryConvert
(
number
,
ref
value
))
{
unknown
=
null
;
return
true
;
...
...
@@ -1860,84 +1860,5 @@ namespace Google.ProtocolBuffers
}
#
endregion
/// <summary>
/// Helper class to make parsing enums faster.
/// </summary>
private
static
class
EnumHelper
<
T
>
where
T
:
struct
{
/// <summary>
/// We use the array form if all values are in the range [0, LimitForArray),
/// otherwise we build a dictionary.
/// </summary>
private
const
int
LimitForArray
=
32
;
// Only one of these will be populated.
private
static
readonly
Dictionary
<
int
,
T
>
dictionary
;
private
static
readonly
T
?[]
values
;
static
EnumHelper
()
{
// It will actually be a T[], but the CLR will let us convert.
int
[]
array
=
(
int
[])
Enum
.
GetValues
(
typeof
(
T
));
if
(
array
.
Length
==
0
)
{
// Empty enum; model with an empty values array.
values
=
new
T
?[
0
];
return
;
}
int
min
=
int
.
MaxValue
;
int
max
=
int
.
MinValue
;
foreach
(
int
number
in
array
)
{
min
=
Math
.
Min
(
number
,
min
);
max
=
Math
.
Max
(
number
,
max
);
}
if
(
min
>=
0
&&
max
<
LimitForArray
)
{
values
=
new
T
?[
max
+
1
];
foreach
(
int
number
in
array
)
{
values
[
number
]
=
(
T
)(
object
)
number
;
}
}
else
{
dictionary
=
new
Dictionary
<
int
,
T
>();
foreach
(
int
number
in
array
)
{
dictionary
[
number
]
=
(
T
)(
object
)
number
;
}
}
}
/// <summary>
/// Tries to convert an integer to its enum representation. This would take an out parameter,
/// but the caller uses ref, so this approach is simpler.
/// </summary>
internal
static
bool
TryConvert
(
int
number
,
ref
T
value
)
{
if
(
values
!=
null
)
{
if
(
number
<
0
||
number
>=
values
.
Length
)
{
return
false
;
}
T
?
maybeValue
=
values
[
number
];
if
(
maybeValue
!=
null
)
{
value
=
maybeValue
.
Value
;
return
true
;
}
return
false
;
}
T
converted
;
if
(
dictionary
.
TryGetValue
(
number
,
out
converted
))
{
value
=
converted
;
return
true
;
}
return
false
;
}
}
}
}
\ No newline at end of file
src/ProtocolBuffers/EnumLite.cs
View file @
1e29e701
...
...
@@ -95,26 +95,140 @@ namespace Google.ProtocolBuffers
public
IEnumLite
FindValueByNumber
(
int
number
)
{
if
(
Enum
.
IsDefined
(
typeof
(
TEnum
),
number
))
TEnum
val
=
default
(
TEnum
);
if
(
EnumParser
<
TEnum
>.
TryConvert
(
number
,
ref
val
))
{
return
new
EnumValue
(
(
TEnum
)(
object
)
number
);
return
new
EnumValue
(
val
);
}
return
null
;
}
public
IEnumLite
FindValueByName
(
string
name
)
{
if
(
Enum
.
IsDefined
(
typeof
(
TEnum
),
name
))
TEnum
val
=
default
(
TEnum
);
if
(
EnumParser
<
TEnum
>.
TryConvert
(
name
,
ref
val
))
{
object
evalue
=
Enum
.
Parse
(
typeof
(
TEnum
),
name
,
false
);
return
new
EnumValue
((
TEnum
)
evalue
);
return
new
EnumValue
(
val
);
}
return
null
;
}
public
bool
IsValidValue
(
IEnumLite
value
)
{
return
Enum
.
IsDefined
(
typeof
(
TEnum
),
value
.
Number
);
TEnum
val
=
default
(
TEnum
);
return
EnumParser
<
TEnum
>.
TryConvert
(
value
.
Number
,
ref
val
);
}
}
public
static
class
EnumParser
<
T
>
where
T
:
struct
,
IComparable
,
IFormattable
{
private
static
readonly
Dictionary
<
int
,
T
>
_byNumber
;
private
static
Dictionary
<
string
,
T
>
_byName
;
static
EnumParser
()
{
int
[]
array
;
try
{
#if CLIENTPROFILE
// It will actually be a T[], but the CLR will let us convert.
array
=
(
int
[])
Enum
.
GetValues
(
typeof
(
T
));
#else
var
temp
=
new
List
<
T
>();
foreach
(
var
fld
in
typeof
(
T
).
GetFields
(
System
.
Reflection
.
BindingFlags
.
Public
|
System
.
Reflection
.
BindingFlags
.
Static
))
{
if
(
fld
.
IsLiteral
&&
fld
.
FieldType
==
typeof
(
T
))
{
temp
.
Add
((
T
)
fld
.
GetValue
(
null
));
}
}
array
=
(
int
[])(
object
)
temp
.
ToArray
();
#endif
}
catch
{
_byNumber
=
null
;
return
;
}
_byNumber
=
new
Dictionary
<
int
,
T
>(
array
.
Length
);
foreach
(
int
i
in
array
)
{
_byNumber
[
i
]
=
(
T
)(
object
)
i
;
}
}
public
static
bool
TryConvert
(
object
input
,
ref
T
value
)
{
if
(
input
is
int
||
input
is
T
)
{
return
TryConvert
((
int
)
input
,
ref
value
);
}
if
(
input
is
string
)
{
return
TryConvert
((
string
)
input
,
ref
value
);
}
return
false
;
}
/// <summary>
/// Tries to convert an integer to its enum representation. This would take an out parameter,
/// but the caller uses ref, so this approach is simpler.
/// </summary>
public
static
bool
TryConvert
(
int
number
,
ref
T
value
)
{
// null indicates an exception at construction, use native IsDefined.
if
(
_byNumber
==
null
)
{
return
Enum
.
IsDefined
(
typeof
(
T
),
number
);
}
T
converted
;
if
(
_byNumber
!=
null
&&
_byNumber
.
TryGetValue
(
number
,
out
converted
))
{
value
=
converted
;
return
true
;
}
return
false
;
}
/// <summary>
/// Tries to convert a string to its enum representation. This would take an out parameter,
/// but the caller uses ref, so this approach is simpler.
/// </summary>
public
static
bool
TryConvert
(
string
name
,
ref
T
value
)
{
// null indicates an exception at construction, use native IsDefined/Parse.
if
(
_byNumber
==
null
)
{
if
(
Enum
.
IsDefined
(
typeof
(
T
),
name
))
{
value
=
(
T
)
Enum
.
Parse
(
typeof
(
T
),
name
,
false
);
return
true
;
}
return
false
;
}
// known race, possible multiple threads each build their own copy; however, last writer will win
var
map
=
_byName
;
if
(
map
==
null
)
{
map
=
new
Dictionary
<
string
,
T
>(
StringComparer
.
Ordinal
);
foreach
(
var
possible
in
_byNumber
.
Values
)
{
map
[
possible
.
ToString
()]
=
possible
;
}
_byName
=
map
;
}
T
converted
;
if
(
map
.
TryGetValue
(
name
,
out
converted
))
{
value
=
converted
;
return
true
;
}
return
false
;
}
}
}
\ No newline at end of file
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