merge tags/2.6.0 into trunk
This commit is contained in:
parent
786379af47
commit
1eba9d9c74
44
CHANGES.txt
44
CHANGES.txt
@ -1,3 +1,47 @@
|
||||
2014-08-15 version 2.6.0:
|
||||
|
||||
General
|
||||
* Added oneofs(unions) feature. Fields in the same oneof will share
|
||||
memory and at most one field can be set at the same time. Use the
|
||||
oneof keyword to define a oneof like:
|
||||
message SampleMessage {
|
||||
oneof test_oneof {
|
||||
string name = 4;
|
||||
YourMessage sub_message = 9;
|
||||
}
|
||||
}
|
||||
* Files, services, enums, messages, methods and enum values can be marked
|
||||
as deprecated now.
|
||||
* Added Support for list values, including lists of mesaages, when
|
||||
parsing text-formatted protos in C++ and Java.
|
||||
For example: foo: [1, 2, 3]
|
||||
|
||||
C++
|
||||
* Enhanced customization on TestFormat printing.
|
||||
* Added SwapFields() in reflection API to swap a subset of fields.
|
||||
Added SetAllocatedMessage() in reflection API.
|
||||
* Repeated primitive extensions are now packable. The
|
||||
[packed=true] option only affects serializers. Therefore, it is
|
||||
possible to switch a repeated extension field to packed format
|
||||
without breaking backwards-compatibility.
|
||||
* Various speed optimizations.
|
||||
|
||||
Java
|
||||
* writeTo() method in ByteString can now write a substring to an
|
||||
output stream. Added endWith() method for ByteString.
|
||||
* ByteString and ByteBuffer are now supported in CodedInputStream
|
||||
and CodedOutputStream.
|
||||
* java_generate_equals_and_hash can now be used with the LITE_RUNTIME.
|
||||
|
||||
Python
|
||||
* A new C++-backed extension module (aka "cpp api v2") that replaces the
|
||||
old ("cpp api v1") one. Much faster than the pure Python code. This one
|
||||
resolves many bugs and is recommended for general use over the
|
||||
pure Python when possible.
|
||||
* Descriptors now have enum_types_by_name and extension_types_by_name dict
|
||||
attributes.
|
||||
* Support for Python 3.
|
||||
|
||||
2013-02-27 version 2.5.0:
|
||||
|
||||
General
|
||||
|
@ -12,7 +12,7 @@ AC_PREREQ(2.59)
|
||||
# In the SVN trunk, the version should always be the next anticipated release
|
||||
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
|
||||
# the size of one file name in the dist tarfile over the 99-char limit.)
|
||||
AC_INIT([Protocol Buffers],[2.5.1-pre],[protobuf@googlegroups.com],[protobuf])
|
||||
AC_INIT([Protocol Buffers],[2.6.0],[protobuf@googlegroups.com],[protobuf])
|
||||
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "addressbook.pb.h"
|
||||
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
|
||||
using namespace std;
|
||||
|
||||
// Iterates though all people in the AddressBook and prints info about them.
|
||||
|
@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>2.5.1-pre</version>
|
||||
<version>2.6.0</version>
|
||||
<packaging>bundle</packaging>
|
||||
<name>Protocol Buffer Java API</name>
|
||||
<description>
|
||||
|
@ -47,9 +47,9 @@ Installation
|
||||
|
||||
$ python setup.py build
|
||||
$ python setup.py google_test
|
||||
|
||||
|
||||
if you want to test c++ implementation, run:
|
||||
$ python setup.py google_test --cpp_implementation
|
||||
$ python setup.py test
|
||||
|
||||
If some tests fail, this library may not work correctly on your
|
||||
system. Continue at your own risk.
|
||||
@ -66,7 +66,7 @@ Installation
|
||||
|
||||
$ python setup.py install
|
||||
or:
|
||||
$ python setup.py install --cpp_implementation
|
||||
$ python setup.py install --nocpp_implementation
|
||||
|
||||
This step may require superuser privileges.
|
||||
NOTE: To use C++ implementation, you need to install C++ protobuf runtime
|
||||
@ -101,8 +101,7 @@ You need to export this variable before running setup.py script to build and
|
||||
install the extension. You must also set the variable at runtime, otherwise
|
||||
the pure-Python implementation will be used. In a future release, we will
|
||||
change the default so that C++ implementation is used whenever it is available.
|
||||
It is strongly recommended to run `python setup.py google_test
|
||||
--cpp_implementation` after setting the
|
||||
It is strongly recommended to run `python setup.py test` after setting the
|
||||
variable to "cpp", so the tests will be against C++ implemented Python
|
||||
messages.
|
||||
|
||||
|
@ -41,7 +41,6 @@ import copy
|
||||
import gc
|
||||
import operator
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from google.apputils import basetest
|
||||
from google.protobuf import unittest_import_pb2
|
||||
@ -1557,20 +1556,7 @@ class ReflectionTest(basetest.TestCase):
|
||||
|
||||
def assertNotInitialized(self, proto):
|
||||
self.assertFalse(proto.IsInitialized())
|
||||
try:
|
||||
proto.SerializeToString()
|
||||
except message.EncodeError:
|
||||
return
|
||||
except:
|
||||
# C++ implementation in opensource do not consider the catched
|
||||
# exception google.protobuf.message.EncodeError same as
|
||||
# message.EncodeError. Add an additional catch to deal with it.
|
||||
if api_implementation.Type() == 'python':
|
||||
raise self.failureException('message.EncodeError not raised')
|
||||
self.assertEqual('<class \'google.protobuf.message.EncodeError\'>',
|
||||
str(sys.exc_info()[0]))
|
||||
else:
|
||||
raise self.failureException('message.EncodeError not raised')
|
||||
self.assertRaises(message.EncodeError, proto.SerializeToString)
|
||||
# "Partial" serialization doesn't care if message is uninitialized.
|
||||
proto.SerializePartialToString()
|
||||
|
||||
@ -2500,13 +2486,6 @@ class SerializationTest(basetest.TestCase):
|
||||
# Check if the exception message is the right one.
|
||||
self.assertEqual(exception, str(ex))
|
||||
return
|
||||
except:
|
||||
# C++ implementation in opensource do not consider the catched
|
||||
# exception google.protobuf.message.EncodeError same as
|
||||
# message.EncodeError. Add an additional catch to deal with it.
|
||||
if api_implementation.Type() == 'python':
|
||||
raise self.failureException('%s not raised' % str(exc_class))
|
||||
self.assertEqual(exception, str(sys.exc_info()[1]))
|
||||
else:
|
||||
raise self.failureException('%s not raised' % str(exc_class))
|
||||
|
||||
|
0
python/google/protobuf/pyext/__init__.py
Normal file
0
python/google/protobuf/pyext/__init__.py
Normal file
@ -83,6 +83,23 @@ def GenerateUnittestProtos():
|
||||
generate_proto("google/protobuf/internal/factory_test2.proto")
|
||||
generate_proto("google/protobuf/pyext/python.proto")
|
||||
|
||||
def MakeTestSuite():
|
||||
# Test C++ implementation
|
||||
import unittest
|
||||
import google.protobuf.pyext.descriptor_cpp2_test as descriptor_cpp2_test
|
||||
import google.protobuf.pyext.message_factory_cpp2_test \
|
||||
as message_factory_cpp2_test
|
||||
import google.protobuf.pyext.reflection_cpp2_generated_test \
|
||||
as reflection_cpp2_generated_test
|
||||
|
||||
loader = unittest.defaultTestLoader
|
||||
suite = unittest.TestSuite()
|
||||
for test in [ descriptor_cpp2_test,
|
||||
message_factory_cpp2_test,
|
||||
reflection_cpp2_generated_test]:
|
||||
suite.addTest(loader.loadTestsFromModule(test))
|
||||
return suite
|
||||
|
||||
class clean(_clean):
|
||||
def run(self):
|
||||
# Delete generated files in the code tree.
|
||||
@ -119,14 +136,14 @@ class build_py(_build_py):
|
||||
# release that are subject to conversion.
|
||||
# See code reference in previous code review.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# C++ implementation extension
|
||||
cpp_impl = '--cpp_implementation'
|
||||
if cpp_impl in sys.argv:
|
||||
ext_module_list = []
|
||||
nocpp = '--nocpp_implementation'
|
||||
if nocpp in sys.argv:
|
||||
sys.argv.remove(cpp_impl)
|
||||
test_dir = "google/protobuf/pyext"
|
||||
ext_module_list = [Extension(
|
||||
else:
|
||||
# C++ implementation extension
|
||||
ext_module_list.append(Extension(
|
||||
"google.protobuf.pyext._message",
|
||||
[ "google/protobuf/pyext/descriptor.cc",
|
||||
"google/protobuf/pyext/message.cc",
|
||||
@ -134,20 +151,17 @@ if __name__ == '__main__':
|
||||
"google/protobuf/pyext/repeated_scalar_container.cc",
|
||||
"google/protobuf/pyext/repeated_composite_container.cc" ],
|
||||
define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')],
|
||||
include_dirs = [ ".", "../src" ],
|
||||
include_dirs = [ ".", "../src"],
|
||||
libraries = [ "protobuf" ],
|
||||
library_dirs = [ '../src/.libs' ],
|
||||
)]
|
||||
else:
|
||||
test_dir = "google/protobuf/internal"
|
||||
ext_module_list = []
|
||||
|
||||
))
|
||||
|
||||
setup(name = 'protobuf',
|
||||
version = '2.6-pre',
|
||||
version = '2.6.0',
|
||||
packages = [ 'google' ],
|
||||
namespace_packages = [ 'google' ],
|
||||
google_test_dir = test_dir,
|
||||
test_suite = 'setup.MakeTestSuite',
|
||||
google_test_dir = "google/protobuf/internal",
|
||||
# Must list modules explicitly so that we don't install tests.
|
||||
py_modules = [
|
||||
'google.protobuf.internal.api_implementation',
|
||||
|
@ -43,6 +43,7 @@ nobase_include_HEADERS = \
|
||||
google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
|
||||
google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
|
||||
google/protobuf/stubs/atomicops_internals_generic_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_macosx.h \
|
||||
google/protobuf/stubs/atomicops_internals_mips_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_pnacl.h \
|
||||
@ -52,6 +53,7 @@ nobase_include_HEADERS = \
|
||||
google/protobuf/stubs/common.h \
|
||||
google/protobuf/stubs/platform_macros.h \
|
||||
google/protobuf/stubs/once.h \
|
||||
google/protobuf/stubs/stl_util.h \
|
||||
google/protobuf/stubs/template_util.h \
|
||||
google/protobuf/stubs/type_traits.h \
|
||||
google/protobuf/descriptor.h \
|
||||
@ -102,7 +104,6 @@ libprotobuf_lite_la_SOURCES = \
|
||||
google/protobuf/stubs/hash.h \
|
||||
google/protobuf/stubs/map_util.h \
|
||||
google/protobuf/stubs/shared_ptr.h \
|
||||
google/protobuf/stubs/stl_util.h \
|
||||
google/protobuf/stubs/stringprintf.cc \
|
||||
google/protobuf/stubs/stringprintf.h \
|
||||
google/protobuf/extension_set.cc \
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#if GOOGLE_PROTOBUF_VERSION < 2005001
|
||||
#if GOOGLE_PROTOBUF_VERSION < 2006000
|
||||
#error This file was generated by a newer version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please update
|
||||
#error your headers.
|
||||
#endif
|
||||
#if 2005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
|
||||
#if 2006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
|
||||
#error This file was generated by an older version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please
|
||||
#error regenerate this file with a newer version of protoc.
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#if GOOGLE_PROTOBUF_VERSION < 2005001
|
||||
#if GOOGLE_PROTOBUF_VERSION < 2006000
|
||||
#error This file was generated by a newer version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please update
|
||||
#error your headers.
|
||||
#endif
|
||||
#if 2005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
|
||||
#if 2006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
|
||||
#error This file was generated by an older version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please
|
||||
#error regenerate this file with a newer version of protoc.
|
||||
|
@ -192,6 +192,8 @@ GOOGLE_PROTOBUF_ATOMICOPS_ERROR
|
||||
#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
|
||||
#elif defined(__native_client__)
|
||||
#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
|
||||
#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
|
||||
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
|
||||
#else
|
||||
GOOGLE_PROTOBUF_ATOMICOPS_ERROR
|
||||
#endif
|
||||
|
137
src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
Normal file
137
src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
Normal file
@ -0,0 +1,137 @@
|
||||
// Copyright 2013 Red Hat Inc. All rights reserved.
|
||||
//
|
||||
// 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 Red Hat 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.
|
||||
|
||||
// This file is an internal atomic implementation, use atomicops.h instead.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
|
||||
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace internal {
|
||||
|
||||
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
|
||||
Atomic32 old_value,
|
||||
Atomic32 new_value) {
|
||||
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
|
||||
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
|
||||
Atomic32 new_value) {
|
||||
return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
|
||||
Atomic32 increment) {
|
||||
return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
|
||||
Atomic32 increment) {
|
||||
return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
|
||||
Atomic32 old_value,
|
||||
Atomic32 new_value) {
|
||||
__atomic_compare_exchange(ptr, &old_value, &new_value, true,
|
||||
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
|
||||
Atomic32 old_value,
|
||||
Atomic32 new_value) {
|
||||
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
|
||||
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
|
||||
__atomic_store_n(ptr, value, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
inline void MemoryBarrier() {
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
|
||||
__atomic_store_n(ptr, value, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
|
||||
__atomic_store_n(ptr, value, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
|
||||
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
|
||||
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
|
||||
return __atomic_load_n(ptr, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
#ifdef __LP64__
|
||||
|
||||
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
|
||||
__atomic_store_n(ptr, value, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
|
||||
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
|
||||
Atomic64 old_value,
|
||||
Atomic64 new_value) {
|
||||
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
|
||||
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
|
||||
Atomic64 old_value,
|
||||
Atomic64 new_value) {
|
||||
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
|
||||
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#endif // defined(__LP64__)
|
||||
|
||||
} // namespace internal
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
|
@ -113,24 +113,24 @@ namespace internal {
|
||||
|
||||
// The current version, represented as a single integer to make comparison
|
||||
// easier: major * 10^6 + minor * 10^3 + micro
|
||||
#define GOOGLE_PROTOBUF_VERSION 2005001
|
||||
#define GOOGLE_PROTOBUF_VERSION 2006000
|
||||
|
||||
// The minimum library version which works with the current version of the
|
||||
// headers.
|
||||
#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2005001
|
||||
#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000
|
||||
|
||||
// The minimum header version which works with the current version of
|
||||
// the library. This constant should only be used by protoc's C++ code
|
||||
// generator.
|
||||
static const int kMinHeaderVersionForLibrary = 2005001;
|
||||
static const int kMinHeaderVersionForLibrary = 2006000;
|
||||
|
||||
// The minimum protoc version which works with the current version of the
|
||||
// headers.
|
||||
#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2005001
|
||||
#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000
|
||||
|
||||
// The minimum header version which works with the current version of
|
||||
// protoc. This constant should only be used in VerifyVersion().
|
||||
static const int kMinHeaderVersionForProtoc = 2005001;
|
||||
static const int kMinHeaderVersionForProtoc = 2006000;
|
||||
|
||||
// Verifies that the headers and libraries are compatible. Use the macro
|
||||
// below to call this.
|
||||
|
@ -65,6 +65,14 @@
|
||||
#elif defined(__ppc__)
|
||||
#define GOOGLE_PROTOBUF_ARCH_PPC 1
|
||||
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
||||
#elif defined(__GNUC__) && \
|
||||
(((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
|
||||
// We fallback to the generic GCC >= 4.7 implementation in atomicops.h
|
||||
# if __LP64__
|
||||
# define GOOGLE_PROTOBUF_ARCH_64_BIT 1
|
||||
# else
|
||||
# define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
||||
# endif
|
||||
#else
|
||||
#error Host architecture was not detected as supported by protobuf
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user