diff --git a/DevTools/IPCCompiler/main.cpp b/DevTools/IPCCompiler/main.cpp index 21e322bc0a9..d495f2efedf 100644 --- a/DevTools/IPCCompiler/main.cpp +++ b/DevTools/IPCCompiler/main.cpp @@ -228,6 +228,7 @@ int main(int argc, char** argv) dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; + dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; @@ -300,8 +301,7 @@ int main(int argc, char** argv) dbg() << " static OwnPtr<" << name << "> decode(BufferStream& stream, size_t& size_in_bytes)"; dbg() << " {"; - if (parameters.is_empty()) - dbg() << " (void)stream;"; + dbg() << " IPC::Decoder decoder(stream);"; for (auto& parameter : parameters) { String initial_value = "{}"; @@ -309,70 +309,19 @@ int main(int argc, char** argv) initial_value = "false"; dbg() << " " << parameter.type << " " << parameter.name << " = " << initial_value << ";"; - if (parameter.type == "String") { - dbg() << " i32 " << parameter.name << "_length = 0;"; - dbg() << " stream >> " << parameter.name << "_length;"; - dbg() << " if (" << parameter.name << "_length == 0) {"; - dbg() << " " << parameter.name << " = String::empty();"; - dbg() << " } else if (" << parameter.name << "_length < 0) {"; - dbg() << " " << parameter.name << " = String();"; - dbg() << " } else {"; - dbg() << " char* " << parameter.name << "_buffer = nullptr;"; - dbg() << " auto " << parameter.name << "_impl = StringImpl::create_uninitialized(static_cast(" << parameter.name << "_length), " << parameter.name << "_buffer);"; - dbg() << " for (size_t i = 0; i < static_cast(" << parameter.name << "_length); ++i) {"; - dbg() << " stream >> " << parameter.name << "_buffer[i];"; - dbg() << " }"; - dbg() << " " << parameter.name << " = *" << parameter.name << "_impl;"; - dbg() << " }"; - } else if (parameter.type == "Gfx::Color") { - dbg() << " u32 " << parameter.name << "_rgba = 0;"; - dbg() << " stream >> " << parameter.name << "_rgba;"; - dbg() << " " << parameter.name << " = Gfx::Color::from_rgba(" << parameter.name << "_rgba);"; - } else if (parameter.type == "Gfx::Size") { - dbg() << " int " << parameter.name << "_width = 0;"; - dbg() << " stream >> " << parameter.name << "_width;"; - dbg() << " int " << parameter.name << "_height = 0;"; - dbg() << " stream >> " << parameter.name << "_height;"; - dbg() << " " << parameter.name << " = { " << parameter.name << "_width, " << parameter.name << "_height };"; - } else if (parameter.type == "Gfx::Point") { - dbg() << " int " << parameter.name << "_x = 0;"; - dbg() << " stream >> " << parameter.name << "_x;"; - dbg() << " int " << parameter.name << "_y = 0;"; - dbg() << " stream >> " << parameter.name << "_y;"; - dbg() << " " << parameter.name << " = { " << parameter.name << "_x, " << parameter.name << "_y };"; - } else if (parameter.type == "Gfx::Rect") { - dbg() << " int " << parameter.name << "_x = 0;"; - dbg() << " stream >> " << parameter.name << "_x;"; - dbg() << " int " << parameter.name << "_y = 0;"; - dbg() << " stream >> " << parameter.name << "_y;"; - dbg() << " int " << parameter.name << "_width = 0;"; - dbg() << " stream >> " << parameter.name << "_width;"; - dbg() << " int " << parameter.name << "_height = 0;"; - dbg() << " stream >> " << parameter.name << "_height;"; - dbg() << " " << parameter.name << " = { " << parameter.name << "_x, " << parameter.name << "_y, " << parameter.name << "_width, " << parameter.name << "_height };"; - } else if (parameter.type == "Vector") { + if (parameter.type == "Vector") { dbg() << " int " << parameter.name << "_size = 0;"; dbg() << " stream >> " << parameter.name << "_size;"; dbg() << " for (int i = 0; i < " << parameter.name << "_size; ++i) {"; - dbg() << " int " << parameter.name << "_x = 0;"; - dbg() << " stream >> " << parameter.name << "_x;"; - dbg() << " int " << parameter.name << "_y = 0;"; - dbg() << " stream >> " << parameter.name << "_y;"; - dbg() << " int " << parameter.name << "_width = 0;"; - dbg() << " stream >> " << parameter.name << "_width;"; - dbg() << " int " << parameter.name << "_height = 0;"; - dbg() << " stream >> " << parameter.name << "_height;"; - dbg() << " " << parameter.name << ".empend(" << parameter.name << "_x, " << parameter.name << "_y, " << parameter.name << "_width, " << parameter.name << "_height);"; + dbg() << " Gfx::Rect rect;"; + dbg() << " if (!decoder.decode(rect))"; + dbg() << " return nullptr;"; + dbg() << " " << parameter.name << ".append(move(rect));"; dbg() << " }"; } else { - dbg() << " stream >> " << parameter.name << ";"; + dbg() << " if (!decoder.decode(" << parameter.name << "))"; + dbg() << " return nullptr;"; } - dbg() << " if (stream.handle_read_failure()) {"; -#ifdef GENERATE_DEBUG_CODE - dbg() << " dbg() << \"Failed to decode " << name << "." << parameter.name << "\";"; -#endif - dbg() << " return nullptr;"; - dbg() << " }"; } StringBuilder builder; diff --git a/Libraries/LibGfx/Color.cpp b/Libraries/LibGfx/Color.cpp index 38078e66bc2..32a0e1b7f1e 100644 --- a/Libraries/LibGfx/Color.cpp +++ b/Libraries/LibGfx/Color.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -344,7 +345,17 @@ Optional Color::from_string(const StringView& string) } } -inline const LogStream& operator<<(const LogStream& stream, Color value) +const LogStream& operator<<(const LogStream& stream, Color value) { return stream << value.to_string(); } + +bool IPC::decode(BufferStream& stream, Color& color) +{ + u32 rgba; + stream >> rgba; + if (stream.handle_read_failure()) + return false; + color = Color::from_rgba(rgba); + return true; +} diff --git a/Libraries/LibGfx/Color.h b/Libraries/LibGfx/Color.h index bfc246c9521..456e3f0724d 100644 --- a/Libraries/LibGfx/Color.h +++ b/Libraries/LibGfx/Color.h @@ -278,3 +278,7 @@ const LogStream& operator<<(const LogStream&, Color); } using Gfx::Color; + +namespace IPC { +bool decode(BufferStream&, Gfx::Color&); +} diff --git a/Libraries/LibGfx/Point.cpp b/Libraries/LibGfx/Point.cpp index 8a42878dce3..e97d883db0f 100644 --- a/Libraries/LibGfx/Point.cpp +++ b/Libraries/LibGfx/Point.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include @@ -40,3 +41,19 @@ const LogStream& operator<<(const LogStream& stream, const Point& value) } } + +namespace IPC { + +bool decode(BufferStream& stream, Gfx::Point& point) +{ + int x; + int y; + stream >> x; + stream >> y; + if (stream.handle_read_failure()) + return false; + point = { x, y }; + return true; +} + +} diff --git a/Libraries/LibGfx/Point.h b/Libraries/LibGfx/Point.h index 854e4426683..410865775d7 100644 --- a/Libraries/LibGfx/Point.h +++ b/Libraries/LibGfx/Point.h @@ -159,3 +159,7 @@ private: const LogStream& operator<<(const LogStream&, const Point&); } + +namespace IPC { +bool decode(BufferStream&, Gfx::Point&); +} diff --git a/Libraries/LibGfx/Rect.cpp b/Libraries/LibGfx/Rect.cpp index 7e335760770..5c39b157892 100644 --- a/Libraries/LibGfx/Rect.cpp +++ b/Libraries/LibGfx/Rect.cpp @@ -142,3 +142,19 @@ const LogStream& operator<<(const LogStream& stream, const Rect& value) } } + +namespace IPC { + +bool decode(BufferStream& stream, Gfx::Rect& rect) +{ + Gfx::Point point; + Gfx::Size size; + if (!decode(stream, point)) + return false; + if (!decode(stream, size)) + return false; + rect = { point, size }; + return true; +} + +} diff --git a/Libraries/LibGfx/Rect.h b/Libraries/LibGfx/Rect.h index 968208516f0..2e3a9702bb4 100644 --- a/Libraries/LibGfx/Rect.h +++ b/Libraries/LibGfx/Rect.h @@ -334,3 +334,7 @@ inline void Point::constrain(const Rect& rect) const LogStream& operator<<(const LogStream&, const Rect&); } + +namespace IPC { +bool decode(BufferStream&, Gfx::Rect&); +} diff --git a/Libraries/LibGfx/Size.cpp b/Libraries/LibGfx/Size.cpp index 1c278d73064..39f6868e5d0 100644 --- a/Libraries/LibGfx/Size.cpp +++ b/Libraries/LibGfx/Size.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include @@ -40,3 +41,19 @@ const LogStream& operator<<(const LogStream& stream, const Size& value) } } + +namespace IPC { + +bool decode(BufferStream& stream, Gfx::Size& size) +{ + int width; + int height; + stream >> width; + stream >> height; + if (stream.handle_read_failure()) + return false; + size = { width, height }; + return true; +} + +} diff --git a/Libraries/LibGfx/Size.h b/Libraries/LibGfx/Size.h index c228ffe6a3c..4156d751d69 100644 --- a/Libraries/LibGfx/Size.h +++ b/Libraries/LibGfx/Size.h @@ -111,3 +111,7 @@ private: const LogStream& operator<<(const LogStream&, const Size&); } + +namespace IPC { +bool decode(BufferStream&, Gfx::Size&); +} diff --git a/Libraries/LibIPC/Decoder.cpp b/Libraries/LibIPC/Decoder.cpp new file mode 100644 index 00000000000..529b8d438ed --- /dev/null +++ b/Libraries/LibIPC/Decoder.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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. + */ + +#include +#include + +namespace IPC { + +bool Decoder::decode(bool& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(u8& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(u16& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(u32& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(u64& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(i8& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(i16& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(i32& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(i64& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(float& value) +{ + m_stream >> value; + return !m_stream.handle_read_failure(); +} + +bool Decoder::decode(String& value) +{ + i32 length = 0; + m_stream >> length; + if (m_stream.handle_read_failure()) + return false; + if (length < 0) { + value = {}; + return true; + } + if (length == 0) { + value = String::empty(); + return true; + } + char* text_buffer = nullptr; + auto text_impl = StringImpl::create_uninitialized(static_cast(length), text_buffer); + for (size_t i = 0; i < static_cast(length); ++i) { + m_stream >> text_buffer[i]; + } + value = *text_impl; + return !m_stream.handle_read_failure(); +} + +} diff --git a/Libraries/LibIPC/Decoder.h b/Libraries/LibIPC/Decoder.h new file mode 100644 index 00000000000..8c254fc0ced --- /dev/null +++ b/Libraries/LibIPC/Decoder.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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. + */ + +#pragma once + +#include +#include + +namespace IPC { + +template +bool decode(BufferStream&, T&) +{ + return false; +} + +class Decoder { +public: + explicit Decoder(BufferStream& stream) + : m_stream(stream) + { + } + + bool decode(bool&); + bool decode(u8&); + bool decode(u16&); + bool decode(u32&); + bool decode(u64&); + bool decode(i8&); + bool decode(i16&); + bool decode(i32&); + bool decode(i64&); + bool decode(float&); + bool decode(String&); + + template + bool decode(T& value) + { + return IPC::decode(m_stream, value); + } + +private: + BufferStream& m_stream; +}; + +} diff --git a/Libraries/LibIPC/Makefile b/Libraries/LibIPC/Makefile index 0250443c1fe..38595cced09 100644 --- a/Libraries/LibIPC/Makefile +++ b/Libraries/LibIPC/Makefile @@ -1,4 +1,5 @@ OBJS = \ + Decoder.o \ Encoder.o \ Endpoint.o \ Message.o