10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochpackage org.chromium.mojo.system; 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.nio.ByteBuffer; 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.util.List; 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/** 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Message pipes are bidirectional communication channel for framed data (i.e., messages). Messages 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * can contain plain data and/or Mojo handles. 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochpublic interface MessagePipeHandle extends Handle { 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Flags for the message pipe creation operation. 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public static class CreateFlags extends Flags<CreateFlags> { 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private static final int FLAG_NONE = 0; 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Immutable flag with not bit set. 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public static final CreateFlags NONE = CreateFlags.none().immutable(); 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Dedicated constructor. 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param flags initial value of the flags. 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protected CreateFlags(int flags) { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch super(flags); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return flags with no bit set. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public static CreateFlags none() { 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return new CreateFlags(FLAG_NONE); 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Used to specify creation parameters for a message pipe to |Core#createMessagePipe()|. 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public static class CreateOptions { 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private CreateFlags mFlags = CreateFlags.NONE; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return the flags 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public CreateFlags getFlags() { 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return mFlags; 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Flags for the write operations on MessagePipeHandle . 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public static class WriteFlags extends Flags<WriteFlags> { 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private static final int FLAG_NONE = 0; 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Immutable flag with no bit set. 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public static final WriteFlags NONE = WriteFlags.none().immutable(); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Dedicated constructor. 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param flags initial value of the flag. 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private WriteFlags(int flags) { 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch super(flags); 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return a flag with no bit set. 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public static WriteFlags none() { 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return new WriteFlags(FLAG_NONE); 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Flags for the read operations on MessagePipeHandle. 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public static class ReadFlags extends Flags<ReadFlags> { 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private static final int FLAG_NONE = 0; 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private static final int FLAG_MAY_DISCARD = 1 << 0; 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Immutable flag with no bit set. 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public static final ReadFlags NONE = ReadFlags.none().immutable(); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Dedicated constructor. 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param flags initial value of the flag. 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private ReadFlags(int flags) { 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch super(flags); 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Change the may-discard bit of this flag. If set, if the message is unable to be read for 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * whatever reason (e.g., the caller-supplied buffer is too small), discard the message 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * (i.e., simply dequeue it). 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param mayDiscard the new value of the may-discard bit. 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return this. 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public ReadFlags setMayDiscard(boolean mayDiscard) { 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return setFlag(FLAG_MAY_DISCARD, mayDiscard); 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return a flag with no bit set. 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public static ReadFlags none() { 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return new ReadFlags(FLAG_NONE); 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Result of the |readMessage| method. 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public static class ReadMessageResult { 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The MojoResult value of the read call. 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private int mMojoResult; 1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * If a message was read, the size in bytes of the message, otherwise the size in bytes of 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * the next message. 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private int mMessageSize; 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * If a message was read, the number of handles contained in the message, otherwise the 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * number of handles contained in the next message. 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private int mHandlesCount; 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * If a message was read, the handles contained in the message, undefined otherwise. 1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private List<UntypedHandle> mHandles; 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return the mojoResult 1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public int getMojoResult() { 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return mMojoResult; 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param mojoResult the mojoResult to set 1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void setMojoResult(int mojoResult) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mMojoResult = mojoResult; 1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return the messageSize 1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public int getMessageSize() { 1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return mMessageSize; 1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param messageSize the messageSize to set 1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void setMessageSize(int messageSize) { 1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mMessageSize = messageSize; 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return the handlesCount 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public int getHandlesCount() { 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return mHandlesCount; 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param handlesCount the handlesCount to set 1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void setHandlesCount(int handlesCount) { 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mHandlesCount = handlesCount; 1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @return the handles 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public List<UntypedHandle> getHandles() { 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return mHandles; 2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * @param handles the handles to set 2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void setHandles(List<UntypedHandle> handles) { 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mHandles = handles; 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @see org.chromium.mojo.system.Handle#pass() 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @Override 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public MessagePipeHandle pass(); 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Writes a message to the message pipe endpoint, with message data specified by |bytes| and 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * attached handles specified by |handles|, and options specified by |flags|. If there is no 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * message data, |bytes| may be null, otherwise it must be a direct ByteBuffer. If there are no 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * attached handles, |handles| may be null. 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * <p> 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * If handles are attached, on success the handles will no longer be valid (the receiver will 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * receive equivalent, but logically different, handles). Handles to be sent should not be in 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * simultaneous use (e.g., on another thread). 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void writeMessage(ByteBuffer bytes, List<? extends Handle> handles, WriteFlags flags); 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Reads a message from the message pipe endpoint; also usable to query the size of the next 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * message or discard the next message. |bytes| indicate the buffer/buffer size to receive the 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * message data (if any) and |maxNumberOfHandles| indicate the maximum handle count to receive 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * the attached handles (if any). |bytes| is optional. If null, |maxNumberOfHandles| must be 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * zero, and the return value will indicate the size of the next message. If non-null, it must 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * be a direct ByteBuffer and the return value will indicate if the message was read or not. If 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * the message was read its content will be in |bytes|, and the attached handles will be in the 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * return value. Partial reads are NEVER done. Either a full read is done and |wasMessageRead| 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * will be true, or the read is NOT done and |wasMessageRead| will be false (if |mayDiscard| was 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * set, the message is also discarded in this case). 2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadMessageResult readMessage(ByteBuffer bytes, int maxNumberOfHandles, 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadFlags flags); 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 243