Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / common / font_config_ipc_linux.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/font_config_ipc_linux.h"
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <sys/mman.h>
10 #include <sys/socket.h>
11 #include <sys/stat.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14
15 #include "base/debug/trace_event.h"
16 #include "base/file_util.h"
17 #include "base/pickle.h"
18 #include "base/posix/unix_domain_socket_linux.h"
19 #include "skia/ext/refptr.h"
20 #include "skia/ext/skia_utils_base.h"
21 #include "third_party/skia/include/core/SkData.h"
22 #include "third_party/skia/include/core/SkStream.h"
23
24 namespace content {
25
26 // Return a stream from the file descriptor, or NULL on failure.
27 SkStream* StreamFromFD(int fd) {
28   skia::RefPtr<SkData> data = skia::AdoptRef(SkData::NewFromFD(fd));
29   if (!data) {
30     return NULL;
31   }
32   return new SkMemoryStream(data.get());
33 }
34
35 void CloseFD(int fd) {
36   int err = IGNORE_EINTR(close(fd));
37   DCHECK(!err);
38 }
39
40 FontConfigIPC::FontConfigIPC(int fd)
41     : fd_(fd) {
42 }
43
44 FontConfigIPC::~FontConfigIPC() {
45   CloseFD(fd_);
46 }
47
48 bool FontConfigIPC::matchFamilyName(const char familyName[],
49                                     SkTypeface::Style requestedStyle,
50                                     FontIdentity* outFontIdentity,
51                                     SkString* outFamilyName,
52                                     SkTypeface::Style* outStyle) {
53   TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName");
54   size_t familyNameLen = familyName ? strlen(familyName) : 0;
55   if (familyNameLen > kMaxFontFamilyLength)
56     return false;
57
58   Pickle request;
59   request.WriteInt(METHOD_MATCH);
60   request.WriteData(familyName, familyNameLen);
61   request.WriteUInt32(requestedStyle);
62
63   uint8_t reply_buf[2048];
64   const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf,
65                                                   sizeof(reply_buf), NULL,
66                                                   request);
67   if (r == -1)
68     return false;
69
70   Pickle reply(reinterpret_cast<char*>(reply_buf), r);
71   PickleIterator iter(reply);
72   bool result;
73   if (!reply.ReadBool(&iter, &result))
74     return false;
75   if (!result)
76     return false;
77
78   SkString     reply_family;
79   FontIdentity reply_identity;
80   uint32_t     reply_style;
81   if (!skia::ReadSkString(reply, &iter, &reply_family) ||
82       !skia::ReadSkFontIdentity(reply, &iter, &reply_identity) ||
83       !reply.ReadUInt32(&iter, &reply_style)) {
84     return false;
85   }
86
87   if (outFontIdentity)
88     *outFontIdentity = reply_identity;
89   if (outFamilyName)
90     *outFamilyName = reply_family;
91   if (outStyle)
92     *outStyle = static_cast<SkTypeface::Style>(reply_style);
93
94   return true;
95 }
96
97 SkStream* FontConfigIPC::openStream(const FontIdentity& identity) {
98   TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream");
99   Pickle request;
100   request.WriteInt(METHOD_OPEN);
101   request.WriteUInt32(identity.fID);
102
103   int result_fd = -1;
104   uint8_t reply_buf[256];
105   const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf,
106                                                   sizeof(reply_buf),
107                                                   &result_fd, request);
108
109   if (r == -1)
110     return NULL;
111
112   Pickle reply(reinterpret_cast<char*>(reply_buf), r);
113   bool result;
114   PickleIterator iter(reply);
115   if (!reply.ReadBool(&iter, &result) ||
116       !result) {
117     if (result_fd)
118       CloseFD(result_fd);
119     return NULL;
120   }
121
122   SkStream* stream = StreamFromFD(result_fd);
123   CloseFD(result_fd);
124   return stream;
125 }
126
127 }  // namespace content
128