Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
7e399991
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
7e399991
编写于
8月 15, 2018
作者:
C
Chinmay Garde
提交者:
GitHub
8月 15, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add message encoding/decoding utility to FML. (#6017)
上级
e3687f70
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
385 addition
and
0 deletion
+385
-0
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+3
-0
fml/BUILD.gn
fml/BUILD.gn
+3
-0
fml/message.cc
fml/message.cc
+108
-0
fml/message.h
fml/message.h
+204
-0
fml/message_unittests.cc
fml/message_unittests.cc
+67
-0
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
7e399991
...
...
@@ -579,6 +579,9 @@ TYPE: LicenseType.bsd
FILE: ../../../flutter/fml/file.h
FILE: ../../../flutter/fml/macros.h
FILE: ../../../flutter/fml/mapping.cc
FILE: ../../../flutter/fml/message.cc
FILE: ../../../flutter/fml/message.h
FILE: ../../../flutter/fml/message_unittests.cc
FILE: ../../../flutter/fml/native_library.h
FILE: ../../../flutter/fml/paths.cc
FILE: ../../../flutter/fml/platform/fuchsia/paths_fuchsia.cc
...
...
fml/BUILD.gn
浏览文件 @
7e399991
...
...
@@ -32,6 +32,8 @@ source_set("fml") {
"memory/weak_ptr.h",
"memory/weak_ptr_internal.cc",
"memory/weak_ptr_internal.h",
"message.cc",
"message.h",
"message_loop.cc",
"message_loop.h",
"message_loop_impl.cc",
...
...
@@ -163,6 +165,7 @@ executable("fml_unittests") {
"memory/ref_counted_unittest.cc",
"memory/weak_ptr_unittest.cc",
"message_loop_unittests.cc",
"message_unittests.cc",
"string_view_unittest.cc",
"synchronization/thread_annotations_unittest.cc",
"synchronization/thread_checker_unittest.cc",
...
...
fml/message.cc
0 → 100644
浏览文件 @
7e399991
// Copyright 2018 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/message.h"
#include "flutter/fml/logging.h"
namespace
fml
{
Message
::
Message
()
=
default
;
Message
::~
Message
()
=
default
;
static
uint32_t
NextPowerOfTwoSize
(
uint32_t
x
)
{
if
(
x
==
0
)
{
return
1
;
}
--
x
;
x
|=
x
>>
1
;
x
|=
x
>>
2
;
x
|=
x
>>
4
;
x
|=
x
>>
8
;
x
|=
x
>>
16
;
return
x
+
1
;
}
const
uint8_t
*
Message
::
GetBuffer
()
const
{
return
buffer_
;
}
size_t
Message
::
GetBufferSize
()
const
{
return
buffer_length_
;
}
size_t
Message
::
GetDataLength
()
const
{
return
data_length_
;
}
size_t
Message
::
GetSizeRead
()
const
{
return
size_read_
;
}
bool
Message
::
Reserve
(
size_t
size
)
{
if
(
buffer_length_
>=
size
)
{
return
true
;
}
return
Resize
(
NextPowerOfTwoSize
(
size
));
}
bool
Message
::
Resize
(
size_t
size
)
{
if
(
buffer_
==
nullptr
)
{
// This is the initial resize where we have no previous buffer.
FML_DCHECK
(
buffer_length_
==
0
);
void
*
buffer
=
::
malloc
(
size
);
const
bool
success
=
buffer
!=
nullptr
;
if
(
success
)
{
buffer_
=
static_cast
<
uint8_t
*>
(
buffer
);
buffer_length_
=
size
;
}
return
success
;
}
FML_DCHECK
(
size
>
buffer_length_
);
void
*
resized
=
::
realloc
(
buffer_
,
size
);
const
bool
success
=
resized
!=
nullptr
;
// In case of failure, the input buffer to realloc is still valid.
if
(
success
)
{
buffer_
=
static_cast
<
uint8_t
*>
(
resized
);
buffer_length_
=
size
;
}
return
success
;
}
uint8_t
*
Message
::
PrepareEncode
(
size_t
size
)
{
if
(
!
Reserve
(
data_length_
+
size
))
{
return
nullptr
;
}
auto
old_length
=
data_length_
;
data_length_
+=
size
;
return
buffer_
+
old_length
;
}
uint8_t
*
Message
::
PrepareDecode
(
size_t
size
)
{
if
((
size
+
size_read_
)
>
buffer_length_
)
{
return
nullptr
;
}
auto
buffer
=
buffer_
+
size_read_
;
size_read_
+=
size
;
return
buffer
;
}
void
Message
::
ResetRead
()
{
size_read_
=
0
;
}
}
// namespace fml
fml/message.h
0 → 100644
浏览文件 @
7e399991
// Copyright 2018 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FML_MESSAGE_H_
#define FLUTTER_FML_MESSAGE_H_
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <memory>
#include <type_traits>
#include <utility>
#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/macros.h"
namespace
fml
{
#define FML_SERIALIZE(message, value) \
if (!message.Encode(value)) { \
return false; \
}
#define FML_SERIALIZE_TRAITS(message, value, traits) \
if (!message.Encode<traits>(value)) { \
return false; \
}
#define FML_DESERIALIZE(message, value) \
if (!message.Decode(value)) { \
return false; \
}
#define FML_DESERIALIZE_TRAITS(message, value, traits) \
if (!message.Decode<traits>(value)) { \
return false; \
}
class
Message
;
class
MessageSerializable
{
public:
virtual
~
MessageSerializable
()
=
default
;
virtual
bool
Serialize
(
Message
&
message
)
const
=
0
;
virtual
bool
Deserialize
(
Message
&
message
)
=
0
;
virtual
size_t
GetSerializableTag
()
const
{
return
0
;
};
};
// The traits passed to the encode/decode calls that accept traits should be
// something like the following.
//
// class MessageSerializableTraits {
// static size_t GetSerializableTag(const T&);
// static std::unique_ptr<T> CreateForSerializableTag(size_t tag);
// };
template
<
class
T
>
struct
Serializable
:
public
std
::
integral_constant
<
bool
,
std
::
is_trivially_copyable
<
T
>::
value
||
std
::
is_base_of
<
MessageSerializable
,
T
>::
value
>
{
};
// Utility class to encode and decode |Serializable| types to and from a buffer.
// Elements have to be read back into the same order they were written.
class
Message
{
public:
Message
();
~
Message
();
const
uint8_t
*
GetBuffer
()
const
;
size_t
GetBufferSize
()
const
;
size_t
GetDataLength
()
const
;
size_t
GetSizeRead
()
const
;
void
ResetRead
();
// Encoders.
template
<
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_trivially_copyable
<
T
>
::
value
>>
FML_WARN_UNUSED_RESULT
bool
Encode
(
const
T
&
value
)
{
if
(
auto
buffer
=
PrepareEncode
(
sizeof
(
T
)))
{
::
memcpy
(
buffer
,
&
value
,
sizeof
(
T
));
return
true
;
}
return
false
;
}
FML_WARN_UNUSED_RESULT
bool
Encode
(
const
MessageSerializable
&
value
)
{
return
value
.
Serialize
(
*
this
);
}
template
<
typename
Traits
,
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_base_of
<
MessageSerializable
,
T
>
::
value
>>
FML_WARN_UNUSED_RESULT
bool
Encode
(
const
std
::
unique_ptr
<
T
>&
value
)
{
// Encode if null.
if
(
!
Encode
(
static_cast
<
bool
>
(
value
)))
{
return
false
;
}
if
(
!
value
)
{
return
true
;
}
// Encode the type.
if
(
!
Encode
(
Traits
::
GetSerializableTag
(
*
value
.
get
())))
{
return
false
;
}
// Encode the value.
if
(
!
Encode
(
*
value
.
get
()))
{
return
false
;
}
return
true
;
}
// Decoders.
template
<
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_trivially_copyable
<
T
>
::
value
>>
FML_WARN_UNUSED_RESULT
bool
Decode
(
T
&
value
)
{
if
(
auto
buffer
=
PrepareDecode
(
sizeof
(
T
)))
{
::
memcpy
(
&
value
,
buffer
,
sizeof
(
T
));
return
true
;
}
return
false
;
}
FML_WARN_UNUSED_RESULT
bool
Decode
(
MessageSerializable
&
value
)
{
return
value
.
Deserialize
(
*
this
);
}
template
<
typename
Traits
,
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_base_of
<
MessageSerializable
,
T
>
::
value
>>
FML_WARN_UNUSED_RESULT
bool
Decode
(
std
::
unique_ptr
<
T
>&
value
)
{
// Decode if null.
bool
is_null
=
false
;
if
(
!
Decode
(
is_null
))
{
return
false
;
}
if
(
is_null
)
{
return
true
;
}
// Decode type.
size_t
tag
=
0
;
if
(
!
Decode
(
tag
))
{
return
false
;
}
std
::
unique_ptr
<
T
>
new_value
=
Traits
::
CreateForSerializableTag
(
tag
);
if
(
!
new_value
)
{
return
false
;
}
// Decode value.
if
(
!
Decode
(
*
new_value
.
get
()))
{
return
false
;
}
std
::
swap
(
value
,
new_value
);
return
true
;
}
private:
uint8_t
*
buffer_
=
nullptr
;
size_t
buffer_length_
=
0
;
size_t
data_length_
=
0
;
size_t
size_read_
=
0
;
FML_WARN_UNUSED_RESULT
bool
Reserve
(
size_t
size
);
FML_WARN_UNUSED_RESULT
bool
Resize
(
size_t
size
);
FML_WARN_UNUSED_RESULT
uint8_t
*
PrepareEncode
(
size_t
size
);
FML_WARN_UNUSED_RESULT
uint8_t
*
PrepareDecode
(
size_t
size
);
FML_DISALLOW_COPY_AND_ASSIGN
(
Message
);
};
}
// namespace fml
#endif // FLUTTER_FML_MESSAGE_H_
fml/message_unittests.cc
0 → 100644
浏览文件 @
7e399991
// Copyright 2018 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/message.h"
#include "gtest/gtest.h"
namespace
fml
{
struct
TestStruct
{
int
a
=
12
;
char
b
=
'x'
;
float
c
=
99.0
f
;
};
TEST
(
MessageTest
,
CanEncodeTriviallyCopyableTypes
)
{
Message
message
;
ASSERT_TRUE
(
message
.
Encode
(
12
));
ASSERT_TRUE
(
message
.
Encode
(
11.0
f
));
ASSERT_TRUE
(
message
.
Encode
(
'a'
));
TestStruct
s
;
ASSERT_TRUE
(
message
.
Encode
(
s
));
ASSERT_GE
(
message
.
GetDataLength
(),
0u
);
ASSERT_GE
(
message
.
GetBufferSize
(),
0u
);
ASSERT_EQ
(
message
.
GetSizeRead
(),
0u
);
}
TEST
(
MessageTest
,
CanDecodeTriviallyCopyableTypes
)
{
Message
message
;
ASSERT_TRUE
(
message
.
Encode
(
12
));
ASSERT_TRUE
(
message
.
Encode
(
11.0
f
));
ASSERT_TRUE
(
message
.
Encode
(
'a'
));
TestStruct
s
;
s
.
a
=
10
;
s
.
b
=
'y'
;
s
.
c
=
11.1
f
;
ASSERT_TRUE
(
message
.
Encode
(
s
));
ASSERT_GE
(
message
.
GetDataLength
(),
0u
);
ASSERT_GE
(
message
.
GetBufferSize
(),
0u
);
ASSERT_EQ
(
message
.
GetSizeRead
(),
0u
);
int
int1
=
0
;
ASSERT_TRUE
(
message
.
Decode
(
int1
));
ASSERT_EQ
(
12
,
int1
);
float
float1
=
0.0
f
;
ASSERT_TRUE
(
message
.
Decode
(
float1
));
ASSERT_EQ
(
float1
,
11.0
f
);
char
char1
=
'x'
;
ASSERT_TRUE
(
message
.
Decode
(
char1
));
ASSERT_EQ
(
char1
,
'a'
);
TestStruct
s1
;
ASSERT_TRUE
(
message
.
Decode
(
s1
));
ASSERT_EQ
(
s1
.
a
,
10
);
ASSERT_EQ
(
s1
.
b
,
'y'
);
ASSERT_EQ
(
s1
.
c
,
11.1
f
);
ASSERT_NE
(
message
.
GetSizeRead
(),
0u
);
ASSERT_EQ
(
message
.
GetDataLength
(),
message
.
GetSizeRead
());
}
}
// namespace fml
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录