> Hi everyone, > > I have a modest proposal for an enhancement to the > SceMiMessageData class as follows: > > void > SetMessage(const SceMiU32 *messageData, SceMiEC *ec = NULL); > > Fills the data array with the contents of the array pointed to by > the messageData argument. It shall be an error if messageData is > NULL. The behavior of the method shall be undefined if the array > pointed to by messageData is smaller than the size of the data > array [of the SceMiMessageData object]. > > void > SetWordRange(unsigned int i, unsigned int range, > const SceMiU32 *words, SceMiEC *ec = NULL); > > Sets range elements of the data array starting with element i from > the array pointed to by the words argument. It shall be an error > if words is NULL. The data array shall be unchanged if range is 0. > It shall be an error if i is greater than or equal to the size of > the data array. It shall be an error if i + range is greater than > the size of the data array [this could be relaxed]. The behavior > of the method shall be undefined if the array pointed to by > words is smaller than range. > > void > GetMessage(SceMiU32 *messageData, SceMiEC *ec = NULL); > > Copy the data array into the array pointed to by the messageData > argument. It shall be an error if messageData is NULL. The > behavior of the method shall be undefined if the array pointed to > by messageData is smaller than the size of the data array [of the > SceMiMessageData object]. > > void > GetWordRange(unsigned int i, unsigned int range, > SceMiU32 *words, SceMiEC *ec = NULL); > > Copy range elements of the data array starting with element i from > the array pointed to by the words argument. It shall be an error > if words is NULL. The data array shall be unchanged if range is 0. > It shall be an error if i is greater than or equal to the size of > the data array. It shall be an error if i + range is greater than > the size of the data array [this could be relaxed]. The behavior > of the method shall be undefined if the array pointed to by > words is smaller than range. > > In terms of semantics, SetMessage(messageData) is equivalent to > (except for error handling): > > for (int i = 0; i < message.WidthInWords(); i++) > message.Set(i, messageData[i]); > > GetMessage(messageData) is equivalent to: > > for (int i = 0; i < message.WidthInWords(); i++) > messageData[i] = message.Get(i); > > SetWordRange(start, range, words) is equivalent to: > > for (int i = 0; i < range; i++) > message.Set(start + i, words[i]); > > GetWordRange(start, range, words) is equivalent to: > > for (int i = 0; i < range; i++) > words[i] = message.Get(start + i); johnS: The main reason we defined the functions the way they are is safety. In their current definition, it is fully possible to error check for invalid function argument values. While the functions you propose are certainly helpful, they have a safety issue because it is possible to pass pointers to invalid or inadequate storage areas and there is no way for the implementation to error check for this. The undefined behavior you refer to can lead to very subtle effects such as heap corruption or SEGVs that would manifest themselves inside the API function itself. In their current form error checking against this is fully feasible. Depending on implementations, it is possible to provide lower performing variants of the functions with comprehensive error checking or, alternatively, less robust error checking with higher performance. The implementation can decide what tradeoff to provide here. But the interface itself guarantees that it is possible to check for all illegal combinations of arguments if it is desired. All of the functions you give are (as you've shown) relatively trivial derivations of the API functions provided so increased functionality can be easily layered over the functions at the application level - say via macros or inlined functions. > > Also > > SetMessage(messageData) === SetWordRange(0, WidthInWords(), messageData) > GetMessage(messageData) === GetWordRange(0, WidthInWords(), messageData) > > The rationale for this proposal is two-fold: > > 1) Convenience for cases where the message already exists in form of > a data array; > > 2) Provide an avenue for the API to optimize the transfer of > message data from the user's representation to the internal > representation. For instance, the SetMessage() and GetMessage() > methods could be done using memcpy() in some implementations. > memcpy() is more efficient than the explicit loop in many cases. > This is in keeping with the performance goals of SCE-MI. >