| /********************************************************************** |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| **********************************************************************/ |
| /* -*-C++-*- |
| ****************************************************************************** |
| * |
| * File: LmJavaSignatureHelpers.cpp |
| * Description: Java Signature |
| * |
| * Created: 10/07/2003 |
| * Language: C++ |
| * |
| * |
| ****************************************************************************** |
| */ |
| |
| #include "LmJavaSignatureHelpers.h" |
| #include "str.h" |
| |
| // |
| // unpackSignature(): Unpacks a Java signature. |
| // Callers have to call ::getUnpackedSignatureSize() first and then |
| // allocate so many bytes before calling unpackSignature(). |
| // |
| // Example: For procedure proc(IN int, IN NUMERIC (9,3), INOUT char(50)), |
| // packed signature is (ILjava/math/BigDecimal;[Ljava/lang/String;)V |
| // unpacked signature is (int,java.math.BigDecimal,java.lang.String[]) |
| // |
| // Note: This method does not do extensive error checking. For example, |
| // there is no checks for improper placement of '(', '[' etc. We assume |
| // that this method is called with proper unpackedSignature, that was |
| // generated by us. |
| // |
| |
| Int32 unpackSignature(const char* encodedSignature /*input*/, |
| char *unpackedSignature /*input and output*/) |
| { |
| Int32 outparam = 0; |
| const char *encodedSig = encodedSignature; |
| char *out = unpackedSignature; |
| Int32 retVal = 0; |
| |
| if (*encodedSig != '(') |
| return -1; |
| |
| // Go through the encoded signature and write signature |
| // to unpackedSignature; |
| while (*encodedSig) |
| { |
| switch (*encodedSig) |
| { |
| case '(': |
| { |
| strcpy(out, "("); |
| out++; |
| encodedSig++; |
| } |
| break; |
| |
| case ')': |
| { |
| if (*(encodedSig-1) == '(') |
| strcpy(out, ")"); |
| else |
| strcpy(out-1, ")"); |
| |
| return 0; |
| } |
| break; |
| |
| case '[': |
| { |
| // This param is an OUT/INOUT param. Remember that so |
| // that we can add '[]' later |
| outparam = TRUE; |
| encodedSig++; |
| } |
| break; |
| |
| default: |
| { |
| // Currently 22 is the length of the longest type name. |
| char typeName[32]; |
| |
| // Copy the type name from encodedSig to typeName |
| if (*encodedSig == 'L') |
| { |
| char *end = (char *) strchr(encodedSig, ';'); |
| if (end == NULL) |
| return -1; |
| |
| Lng32 typeLen = end - encodedSig + 1; |
| if (typeLen > 31) |
| return -1; |
| |
| str_cpy_all(typeName, encodedSig, typeLen); |
| typeName[typeLen] = '\0'; |
| } |
| else |
| { |
| typeName[0] = *encodedSig; |
| typeName[1] = '\0'; |
| } |
| |
| // Get corresponding TypeElement for typeName. |
| LmJavaType::TypeElement *e = LmJavaType::getTypeElement(typeName); |
| |
| if (e != NULL) |
| { |
| strcpy(out, e->javaText); |
| out += e->javaTextLen; |
| encodedSig += e->javaTypeNameLen; |
| |
| if (outparam == TRUE) |
| { |
| strcpy(out, "[]"); |
| out += 2; |
| outparam = FALSE; |
| } |
| |
| strcpy(out++, ","); |
| } |
| else |
| { |
| retVal = -1; // This is error situation. |
| return retVal; |
| } |
| } // default case |
| |
| } // switch() |
| |
| } // while() |
| |
| return retVal; |
| } |
| |
| // |
| // getUnpackedSignatureSize() : Calculates the bytes required if |
| // the given (Java) signture is unpacked. |
| // returns size of unpacked signature string |
| // -1 if unrecognized type is in signature |
| // |
| // Also, returns the total number of parameters present in the |
| // unpacked method signature as paramsInSig out argument. |
| Int32 getUnpackedSignatureSize(const char* encodedSignature, Int32 *paramsInSig) |
| { |
| if (encodedSignature == NULL) |
| return 0; |
| |
| Int32 numParams = 0; |
| Int32 size = 0; |
| const char *signature = encodedSignature; |
| |
| while (*signature) |
| { |
| switch (*signature) |
| { |
| case '(': |
| { |
| size++; |
| signature++; |
| } |
| break; |
| |
| case ')': |
| { |
| size++; |
| } |
| if( paramsInSig != NULL ) |
| *paramsInSig = numParams; |
| |
| return size; // Unpacked sig does not contain return type. So return. |
| |
| case '[': |
| { |
| size += 2; // param is OUT/INOUT. So 2 bytes for '[]' |
| signature++; |
| } |
| break; |
| |
| default: |
| { |
| // Currently 22 is the length of the longest type name. |
| char typeName[32]; |
| |
| // Copy the type name from signature to typeName |
| if (*signature == 'L') |
| { |
| char *end = (char *) strchr(signature, ';'); |
| if (end == NULL) |
| return -1; |
| |
| ComUInt32 typeLen = end - signature + 1; |
| if (typeLen > 31) |
| return -1; |
| |
| str_cpy_all(typeName, signature, (Lng32)typeLen); |
| typeName[typeLen] = '\0'; |
| } |
| else |
| { |
| typeName[0] = *signature; |
| typeName[1] = '\0'; |
| } |
| |
| // Get corresponding TypeElement for typeName. |
| LmJavaType::TypeElement *e = LmJavaType::getTypeElement(typeName); |
| |
| if (e != NULL) |
| { |
| size += (e->javaTextLen + 1); // allow a byte for ',' |
| signature += e->javaTypeNameLen; |
| numParams++; |
| } |
| else |
| { |
| return -1; |
| } |
| } // default case |
| |
| } // switch() |
| |
| } // while() |
| |
| if( paramsInSig != NULL ) |
| *paramsInSig = numParams; |
| |
| return size; |
| } |