VirtualBox

Changeset 36883 in vbox


Ignore:
Timestamp:
Apr 29, 2011 9:40:55 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71461
Message:

webservice: pass octet arrays as base64 strings

Location:
trunk/src/VBox/Main
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/glue/glue-java.xsl

    r36814 r36883  
    288288  <xsl:param name="type" />
    289289  <xsl:param name="safearray" />
    290   <xsl:param name="forceelem" />
    291 
    292   <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
    293 
    294   <xsl:choose>
     290  <xsl:param name="forceelem" /> 
     291
     292  <xsl:choose>     
    295293    <xsl:when test="($G_vboxGlueStyle='xpcom')">
     294      <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
     295
    296296      <xsl:choose>
    297297        <xsl:when test="$type='long long'">
     
    368368
    369369    <xsl:when test="($G_vboxGlueStyle='jaxws')">
     370      <xsl:variable name="needarray" select="($safearray='yes' and not($type='octet')) and not($forceelem='yes')" />
     371     
    370372      <xsl:if test="$needarray">
    371373        <xsl:value-of select="'List&lt;'" />
     
    388390        </xsl:when>
    389391
     392        <!-- we encode byte arrays as Base64 strings. -->
     393        <xsl:when test="$type='octet'">
     394          <xsl:value-of select="'/*base64*/String'" />
     395        </xsl:when>
     396
    390397        <xsl:when test="$type='long long'">
    391398          <xsl:value-of select="'Long'" />
     
    405412
    406413        <xsl:when test="$type='short'">
    407           <xsl:value-of select="'Short'" />
    408         </xsl:when>
    409 
    410         <xsl:when test="$type='octet'">
    411414          <xsl:value-of select="'Short'" />
    412415        </xsl:when>
     
    650653        </xsl:when>
    651654        <xsl:when test="$idltype='octet'">
    652           <xsl:value-of select="concat('Helper.wrapBytes(',$value,')')"/>
     655          <xsl:value-of select="concat('Helper.decodeBase64(',$value,')')"/>
    653656        </xsl:when>
    654657        <xsl:otherwise>
     
    957960
    958961    <xsl:when test="($idltype='octet') and ($safearray='yes')">
    959       <xsl:value-of select="concat('Helper.unwrapBytes(', $value,')')"/>
     962      <xsl:value-of select="concat('Helper.encodeBase64(', $value,')')"/>
    960963    </xsl:when>
    961964
     
    10311034
    10321035     <xsl:when test="($idltype='octet') and ($safearray='yes')">
    1033        <xsl:value-of select="concat('Helper.unwrapBytes(',$value,')')"/>
     1036       <xsl:value-of select="concat('Helper.encodeBase64(',$value,')')"/>
    10341037     </xsl:when>
    10351038
     
    32403243        }
    32413244    }
    3242     // temporary methods, will bo away soon
    3243     public static byte[] wrapBytes(List<Short> arr)
    3244     {
    3245        if (arr == null)
    3246           return null;
    3247        int i = 0;
    3248        byte[] rv = new byte[arr.size()];
    3249        for (short s : arr)
    3250            rv[i++] = (byte)(s & 0xff);
    3251        return rv;
    3252     }
    3253 
    3254     public static List<Short> unwrapBytes(byte[] arr)
    3255     {
    3256        if (arr == null)
    3257           return null;
    3258        List<Short> ret = new ArrayList<Short>(arr.length);
    3259        for (byte b : arr) {
    3260           ret.add((short)b);
    3261        }
    3262        return ret;
     3245   
     3246    /* Pretty naive Base64 encoder/decoder. */
     3247    private static final char[] valToChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
     3248    private static final int[] charToVal = new int[256];
     3249
     3250    /* Initialize recoding alphabet. */
     3251    static
     3252    {
     3253        for (int i = 0; i < charToVal.length; i++)
     3254            charToVal[i] = -1;
     3255
     3256        for (int i = 0; i < valToChar.length; i++)
     3257           charToVal[valToChar[i]] = i;
     3258
     3259        charToVal['='] = 0;
     3260    }
     3261
     3262    public static String encodeBase64(byte[] data)
     3263    {
     3264        if (data == null)
     3265            return null;
     3266
     3267        if (data.length == 0)
     3268            return "";
     3269
     3270        int fullTriplets = data.length / 3;
     3271        int resultLen = ((data.length - 1) / 3 + 1) * 4;
     3272        char[] result = new char[resultLen];
     3273        int dataIndex = 0, stringIndex = 0;
     3274
     3275        for (int i = 0; i < fullTriplets; i++)
     3276        {
     3277            int ch1 = data[dataIndex++] & 0xff;
     3278            result[stringIndex++] = valToChar[ch1 >> 2];
     3279            int ch2 = data[dataIndex++] & 0xff;
     3280            result[stringIndex++] = valToChar[((ch1 << 4) & 0x3f) | (ch2 >> 4)];
     3281            int ch3 = data[dataIndex++] & 0xff;
     3282            result[stringIndex++] = valToChar[((ch2 << 2) & 0x3f) | (ch3 >> 6)];
     3283            result[stringIndex++] = valToChar[ch3 & 0x3f];
     3284        }
     3285       
     3286        switch (data.length - dataIndex)
     3287        {
     3288            case 0:
     3289                // do nothing
     3290                break;
     3291            case 1:
     3292            {
     3293                int ch1 = data[dataIndex++] & 0xff;
     3294                result[stringIndex++] = valToChar[ch1 >> 2];
     3295                result[stringIndex++] = valToChar[(ch1 << 4) & 0x3f];
     3296                result[stringIndex++] = '=';
     3297                result[stringIndex++] = '=';
     3298                break;
     3299            }
     3300            case 2:
     3301            {
     3302                int ch1 = data[dataIndex++] & 0xff;
     3303                result[stringIndex++] = valToChar[ch1 >> 2];
     3304                int ch2 = data[dataIndex++] & 0xff;
     3305                result[stringIndex++] = valToChar[((ch1 << 4) & 0x3f) | (ch2 >> 4)];
     3306                result[stringIndex++] = valToChar[(ch2 << 2) & 0x3f];
     3307                result[stringIndex++] = '=';
     3308                break;
     3309            }
     3310            default:
     3311                throw new RuntimeException("bug!");
     3312        }
     3313
     3314        return new String(result);
     3315    }
     3316
     3317    private static int skipInvalid(String str, int stringIndex)
     3318    {
     3319        while (charToVal[str.charAt(stringIndex)] < 0)
     3320            stringIndex++;
     3321
     3322        return stringIndex;
     3323    }
     3324
     3325    public static byte[] decodeBase64(String str)
     3326    {
     3327        if (str == null)
     3328            return null;
     3329       
     3330        int stringLength = str.length();
     3331        if (stringLength == 0)
     3332            return new byte[0];
     3333
     3334        int validChars = 0, padChars = 0;
     3335        for (int i = 0; i < str.length(); i++)
     3336        {
     3337            char ch = str.charAt(i);
     3338
     3339            if (charToVal[ch] >= 0)
     3340                validChars++;
     3341
     3342            if (ch == '=')
     3343                padChars++;
     3344        }
     3345       
     3346        if ((validChars * 3 % 4) != 0)
     3347            throw new RuntimeException("invalid encoded string "+str);
     3348
     3349        int resultLength = validChars * 3 / 4 - padChars;
     3350        byte[] result = new byte[resultLength];
     3351
     3352        int dataIndex = 0, stringIndex = 0;
     3353        int quadraplets = validChars / 4;
     3354
     3355        for (int i=0; i<quadraplets; i++)
     3356        {
     3357            stringIndex = skipInvalid(str, stringIndex);
     3358            int ch1 = str.charAt(stringIndex++);
     3359            stringIndex = skipInvalid(str, stringIndex);
     3360            int ch2 = str.charAt(stringIndex++);
     3361            stringIndex = skipInvalid(str, stringIndex);
     3362            int ch3 = str.charAt(stringIndex++);
     3363            stringIndex = skipInvalid(str, stringIndex);
     3364            int ch4 = str.charAt(stringIndex++);
     3365
     3366            result[dataIndex++] = (byte)(((charToVal[ch1] << 2) | charToVal[ch2] >> 4) & 0xff);
     3367            /* we check this to ensure that we don't override data with '=' padding. */
     3368            if (dataIndex < result.length)
     3369                result[dataIndex++] = (byte)(((charToVal[ch2] << 4) | charToVal[ch3] >> 2) & 0xff);
     3370            if (dataIndex < result.length)
     3371                result[dataIndex++] = (byte)(((charToVal[ch3] << 6) | charToVal[ch4]) & 0xff);
     3372        }
     3373       
     3374        return result;
    32633375    }
    32643376}
  • trunk/src/VBox/Main/webservice/vboxweb.cpp

    r36702 r36883  
    4747#include <iprt/path.h>
    4848#include <iprt/system.h>
     49#include <iprt/base64.h>
    4950
    5051// workaround for compile problems on gcc 4.1
     
    11901191}
    11911192
     1193/** Code to handle string <-> byte arrays base64 conversion. */
     1194std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData))
     1195{
     1196
     1197    com::SafeArray<BYTE> sfaData(ComSafeArrayInArg(aData));
     1198    ssize_t cbData = sfaData.size();
     1199
     1200    if (cbData == 0)
     1201        return "";
     1202
     1203    ssize_t cchOut = RTBase64EncodedLength(cbData);
     1204
     1205    RTCString aStr;
     1206
     1207    aStr.reserve(cchOut+1);
     1208    int rc = RTBase64Encode(sfaData.raw(), cbData,
     1209                            aStr.mutableRaw(), aStr.capacity(),
     1210                            NULL);
     1211    AssertRC(rc);
     1212    aStr.jolt();
     1213
     1214    return aStr.c_str();
     1215}
     1216
     1217void Base64DecodeByteArray(std::string& aStr, ComSafeArrayOut(BYTE, aData))
     1218{
     1219    const char* pszStr = aStr.c_str();
     1220    ssize_t cbOut = RTBase64DecodedSize(pszStr, NULL);
     1221
     1222    Assert(cbOut > 0);
     1223
     1224    com::SafeArray<BYTE> result(cbOut);
     1225    int rc = RTBase64Decode(pszStr, result.raw(), cbOut, NULL, NULL);
     1226    AssertRC(rc);
     1227
     1228    result.detachTo(ComSafeArrayOutArg(aData));
     1229}
     1230
    11921231/**
    11931232 * Raises a SOAP runtime fault. Implementation for the RaiseSoapRuntimeFault template
  • trunk/src/VBox/Main/webservice/vboxweb.h

    r35458 r36883  
    9797std::string ConvertComString(const com::Guid &bstr);
    9898
     99std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData));
     100
     101void Base64DecodeByteArray(std::string& aStr, ComSafeArrayOut(BYTE, aData));
    99102/****************************************************************************
    100103 *
  • trunk/src/VBox/Main/webservice/websrv-cpp.xsl

    r34563 r36883  
    412412      </xsl:choose>
    413413    </xsl:when>
    414     <xsl:when test="//collection[@name=$type]">
    415       <xsl:variable name="thatif" select="//collection[@name=$type]" />
    416       <xsl:variable name="thatifname" select="$thatif/@name" />
    417       <xsl:value-of select="concat('ComPtr&lt;', $thatifname, '&gt;')" />
    418     </xsl:when>
    419414    <xsl:otherwise>
    420415      <xsl:call-template name="fatalError">
     
    543538  <xsl:call-template name="emitNewlineIndent8" />
    544539
    545   <xsl:choose>
     540  <xsl:choose>   
     541     <xsl:when test="$safearray='yes' and $type='octet'">
     542       <xsl:value-of select="concat('com::SafeArray&lt;BYTE&gt; comcall_',$name, ';')" />
     543       <xsl:call-template name="emitNewlineIndent8" />
     544       <xsl:value-of select="concat('Base64DecodeByteArray(',$structprefix,$name,', ComSafeArrayAsOutParam(comcall_',$name, '));')" />
     545    </xsl:when>
     546
    546547    <xsl:when test="$safearray='yes'">
    547548      <xsl:value-of select="concat('size_t c', $name, ' = ', $structprefix, $name, '.size();')" />
     
    598599          <xsl:call-template name="emitNewlineIndent8" />
    599600          <xsl:value-of select="concat('    comcall_', $name, '[i] = ', $G_funcPrefixInputEnumConverter, $type, '(', $structprefix, $name, '[i]);')" />
    600         </xsl:when>
    601          <xsl:when test="$type='octet'">
    602           <xsl:call-template name="emitNewlineIndent8" />
    603           <xsl:value-of select="concat('    comcall_', $name, '[i] = ', $structprefix, $name, '[i];')" />
    604         </xsl:when>
     601        </xsl:when>       
    605602        <xsl:otherwise>
    606603          <xsl:call-template name="fatalError">
     
    995992
    996993  <xsl:choose>
     994    <xsl:when test="$safearray='yes' and $type='octet'">
     995      <xsl:value-of select="concat($receiverVariable, ' = Base64EncodeByteArray(ComSafeArrayAsInParam(', $varname,'));')" />
     996      <xsl:call-template name="emitNewlineIndent8" />
     997    </xsl:when>
     998
    997999    <xsl:when test="$safearray='yes'">
    9981000      <xsl:value-of select="concat('for (size_t i = 0; i &lt; ', $varname, '.size(); ++i)')" />
  • trunk/src/VBox/Main/webservice/websrv-python.xsl

    r31117 r36883  
    6464  <xsl:param name="safearray" />
    6565
    66   <xsl:call-template name="emitConvertedType">
    67     <xsl:with-param name="ifname" select="$ifname" />
    68     <xsl:with-param name="methodname" select="$methodname" />
    69     <xsl:with-param name="type" select="$type" />
    70   </xsl:call-template>
    71   <xsl:text>(</xsl:text>
    72    <xsl:text>self.mgr,</xsl:text>
    73   <xsl:value-of select="$value"/>
    74   <xsl:if test="$safearray='yes'">
    75     <xsl:value-of select="', True'"/>
    76   </xsl:if>
    77   <xsl:text>)</xsl:text>
     66  <xsl:choose>
     67    <xsl:when test="$type='octet' and $safearray">
     68      <xsl:value-of select="concat('self.mgr.decodebase64(',$value,')')" />
     69    </xsl:when>
     70    <xsl:otherwise>
     71      <xsl:call-template name="emitConvertedType">
     72        <xsl:with-param name="ifname" select="$ifname" />
     73        <xsl:with-param name="methodname" select="$methodname" />
     74        <xsl:with-param name="type" select="$type" />
     75      </xsl:call-template>
     76      <xsl:text>(</xsl:text>
     77      <xsl:text>self.mgr,</xsl:text>
     78      <xsl:value-of select="$value"/>
     79      <xsl:if test="$safearray='yes'">
     80        <xsl:value-of select="', True'"/>
     81      </xsl:if>
     82      <xsl:text>)</xsl:text>
     83    </xsl:otherwise>
     84  </xsl:choose>
    7885</xsl:template>
    7986
     
    342349</xsl:template>
    343350
     351<xsl:template name="convertInParam">
     352  <xsl:param name="type" />
     353  <xsl:param name="safearray" />
     354  <xsl:param name="arg" />
     355 
     356   <xsl:choose>
     357     <xsl:when test="$type='octet' and $safearray">
     358        <xsl:value-of select="concat('self.mgr.encodebase64(',$arg,')')" />
     359     </xsl:when>
     360     <xsl:otherwise>
     361        <xsl:value-of select="$arg" />
     362      </xsl:otherwise>
     363   </xsl:choose>
     364</xsl:template>
     365
    344366<xsl:template name="genreq">
    345367       <xsl:text>req=</xsl:text><xsl:value-of select="../@name"/>_<xsl:value-of select="@name"/>RequestMsg()
    346368       req._this=self.handle
    347369       <xsl:for-each select="param[@dir='in']">
    348        req._<xsl:value-of select="@name" />=_arg_<xsl:value-of select="@name" />
     370       req._<xsl:value-of select="@name" />=<xsl:call-template name="convertInParam">
     371           <xsl:with-param name="type" select="@type" />
     372           <xsl:with-param name="safearray" select="@safearray" />
     373           <xsl:with-param name="arg" select="concat('_arg_', @name)" />
     374         </xsl:call-template>
    349375       </xsl:for-each>
    350376       val=self.mgr.getPort().<xsl:value-of select="../@name"/>_<xsl:value-of select="@name"/>(req)
     
    443469
    444470<xsl:template match="/">
    445 <xsl:text># Copyright (C) 2008-2010 Oracle Corporation
     471<xsl:text># Copyright (C) 2008-2011 Oracle Corporation
    446472#
    447473# This file is part of a free software library; you can redistribute
     
    679705            return self.handle &gt;= other
    680706
    681 import struct
    682 
    683 class Octet(Number):
    684   def __init__(self, mgr, handle, isarray = False):
    685        self.handle = handle
    686        self.mgr = mgr
    687        self.isarray = isarray
    688 
    689   def __getitem__(self, index):
    690       if self.isarray:
    691           return Octet(self.mgr, self.handle[index])
    692       raise TypeError, "iteration over non-sequence"
     707class Octet:
     708  def __init__(self, mgr, handle, isarray = False):
     709       self.mgr = mgr
     710       self.isarray = isarray
     711       if isarray:
     712           self.handle = mgr.decodebase64(handle)
     713       else:
     714           raise TypeError, "only octet arrays"
     715
     716  def __getitem__(self, index):
     717      return self.handle[index]
    693718
    694719  def __str__(self):
    695        if self.isarray:
    696            # array of octets is binary data
    697            list = map (None, self.handle)
    698            return struct.pack("%dB" % (len(list)), *list)
    699        else:
    700            return str(self.handle)
     720       return str(self.handle)
     721
     722  def __len__(self):
     723      return self.handle.__len__()
    701724
    702725class UnsignedInt(Number):
     
    844867       <xsl:call-template name="interfacestruct"/>
    845868  </xsl:for-each>
    846   <xsl:for-each select="//collection">
    847        <xsl:call-template name="collection"/>
    848   </xsl:for-each>
    849869  <xsl:for-each select="//enum">
    850870       <xsl:call-template name="enum"/>
    851871  </xsl:for-each>
     872
     873import base64
    852874
    853875class IWebsessionManager2(IWebsessionManager):
     
    866888      return self.port
    867889
     890  def decodebase64(self, str):
     891      return base64.decodestring(str)
     892
     893  def encodebase64(self, str):
     894      return base64.encodestring(str)
     895
    868896</xsl:template>
    869897
  • trunk/src/VBox/Main/webservice/websrv-wsdl.xsl

    r33540 r36883  
    211211  <xsl:call-template name="debugMsg"><xsl:with-param name="msg" select="concat('....convertTypeAndEmitPartOrElement: arg name: ', $name)" /></xsl:call-template>
    212212  <xsl:choose>
     213    <xsl:when test="$safearray='yes' and $type='octet'">
     214      <!-- we pass octet arrays as Base64-encoded strings. -->
     215       <xsl:element name="{$elname}">
     216         <xsl:attribute name="name"><xsl:value-of select="$name" /></xsl:attribute>
     217        <xsl:attribute name="type"><xsl:value-of select="'xsd:string'" /></xsl:attribute>
     218      </xsl:element>
     219    </xsl:when>
     220
    213221    <xsl:when test="$safearray='yes'">
    214222      <xsl:element name="{$elname}"> <!-- <part> or <element> -->
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette