byteArrayOop.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.26 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_byteArrayOop.cpp.incl"
00026 # include <string.h>
00027 # include <errno.h>
00028 
00029 bool byteArrayOopDesc::verify() {
00030   bool flag = memOopDesc::verify();
00031   if (flag) {
00032     int l = length();
00033     if (l < 0) {
00034       error("byteArrayOop %#lx has negative length", this);
00035       flag = false;
00036     }
00037   }
00038   return flag;
00039 }
00040 
00041 char* byteArrayOopDesc::copy_null_terminated(int &Clength) {
00042   // Copy the bytes() part. Always add trailing '\0'. If byte array
00043   // contains '\0', these will be escaped in the copy, i.e. "....\0...".
00044   // Clength is set to length of the copy (may be longer due to escaping).
00045   // Presence of null chars can be detected by comparing Clength to length().
00046 
00047   assert_byteArray(this, "should be a byte array");
00048   Clength = length();
00049   char *res = copy_string((char*) bytes(), Clength);
00050   if (strlen(res) == (unsigned int) Clength) 
00051     return res;                   // Simple case, no '\0' in byte array.
00052   
00053   // Simple case failed ...
00054   smi t = length();               // Copy and 'escape' null chars.
00055   smi i;
00056   for (i = length()-1; i >= 0; i--) 
00057     if (byte_at(i) == '\0') t++; 
00058   // t is total length of result string.
00059   res = NEW_RESOURCE_ARRAY( char, t + 1);
00060   res[t--] = '\0';
00061   Clength  = t;
00062   for (i = length()-1; i >= 0; i--) {
00063     if (byte_at(i) != '\0') {
00064       res[t--] = byte_at(i);
00065     } else {
00066       res[t--] = '0';
00067       res[t--]   = '\\';
00068     }
00069   }
00070   assert(t == -1, "sanity check");
00071   return res;
00072 }
00073 
00074 char* byteArrayOopDesc::copy_c_heap_null_terminated() {
00075   // Copy the bytes() part. Always add trailing '\0'. If byte array
00076   // contains '\0', these will be escaped in the copy, i.e. "....\0...".
00077   // NOTE: The resulting string is allocated in Cheap
00078   
00079   assert_byteArray(this, "should be a byte array");
00080   smi t = length();               // Copy and 'escape' null chars.
00081   smi i;
00082   for (i = length()-1; i >= 0; i--) 
00083     if (byte_at(i) == '\0') t++; 
00084   // t is total length of result string.
00085   char* res = NEW_C_HEAP_ARRAY( char, t + 1);
00086   res[t--] = '\0';
00087   for (i = length()-1; i >= 0; i--) {
00088     if (byte_at(i) != '\0') {
00089       res[t--] = byte_at(i);
00090     } else {
00091       res[t--] = '0';
00092       res[t--]   = '\\';
00093     }
00094   }
00095   assert(t == -1, "sanity check");
00096   return res;
00097 }
00098 
00099 bool byteArrayOopDesc::copy_null_terminated(char* buffer, int max_length) {
00100   // %not optimized
00101   int len = length();
00102   bool is_truncated = false;
00103   if (len > max_length) {
00104     len = max_length - 1;
00105     is_truncated = true;
00106   }
00107 
00108   for (int i = 0; i < len; i++)
00109     buffer[i] = byte_at(i + 1);
00110   buffer[len] = '\0';
00111 
00112   return is_truncated;
00113 }
00114 
00115 void byteArrayOopDesc::bootstrap_object(bootstrap* st) {
00116   memOopDesc::bootstrap_object(st);
00117 
00118   st->read_oop(length_addr());
00119   for (int index = 1; index <= length(); index++) {
00120     byte_at_put(index, st->read_byte());
00121   }
00122 }
00123 
00124 inline int sub_sign(int a, int b) {
00125   if (a < b) return -1;
00126   if (a > b) return  1;
00127   return 0;
00128 }
00129 
00130 inline int compare_as_bytes(const unsigned char* a, const unsigned char* b) {
00131   // machine dependent code; little endian code
00132   if (a[0] - b[0]) return sub_sign(a[0], b[0]);
00133   if (a[1] - b[1]) return sub_sign(a[1], b[1]);
00134   if (a[2] - b[2]) return sub_sign(a[2], b[2]);
00135   return sub_sign(a[3], b[3]);
00136 }
00137 
00138 int byteArrayOopDesc::compare(byteArrayOop arg) {
00139   // Get the addresses of the length fields
00140   const unsigned int* a = (unsigned int*) length_addr();
00141   const unsigned int* b = (unsigned int*) arg->length_addr();
00142 
00143   // Get the word sizes of the arays
00144   int a_size = roundTo(smiOop(*a++)->value() * sizeof(char), sizeof(int)) / sizeof(int);
00145   int b_size = roundTo(smiOop(*b++)->value() * sizeof(char), sizeof(int)) / sizeof(int);
00146 
00147   const unsigned int* a_end = a + min(a_size, b_size);
00148   while(a < a_end) {
00149     if (*b++ != *a++) 
00150       return compare_as_bytes((const unsigned char*) (a-1), (const unsigned char*) (b-1));
00151   }
00152   return sub_sign(a_size, b_size);
00153 }
00154 
00155 int byteArrayOopDesc::compare_doubleBytes(doubleByteArrayOop arg) {
00156   // %not optimized
00157   int s1 = length();
00158   int s2 = arg->length();
00159   int n  = s1 < s2 ? s1 : s2;
00160 
00161   for (int i = 1; i <= n; i++) {
00162     int result = sub_sign(byte_at(i), arg->doubleByte_at(i));
00163     if (result != 0) return result;
00164   }
00165   return sub_sign(s1, s2);
00166 }
00167 
00168 int byteArrayOopDesc::hash_value() {
00169   int len = length();
00170   int result;
00171 
00172   if (len == 0) {
00173     result = 1;
00174   } else if (len == 1) {
00175     result = byte_at(1);
00176   } else {
00177     unsigned int val;
00178     val = byte_at(1);
00179     val = (val << 3) ^ (byte_at(2)         ^ val);
00180     val = (val << 3) ^ (byte_at(len)       ^ val);
00181     val = (val << 3) ^ (byte_at(len-1)     ^ val);
00182     val = (val << 3) ^ (byte_at(len/2 + 1) ^ val);
00183     val = (val << 3) ^ (len                ^ val);
00184     result = markOopDesc::masked_hash(val);
00185   }
00186   return result == 0 ? 1 : result;
00187 }
00188 
00189 char* byteArrayOopDesc::as_string() {
00190   int len = length();
00191   char* str = NEW_RESOURCE_ARRAY(char, len+1);
00192   for (int index = 0; index <len; index++) {
00193     str[index] = byte_at(index+1);
00194   }
00195   str[index] = '\0';
00196   return str;
00197 }
00198 
00199 # include <ctype.h>
00200 
00201 int byteArrayOopDesc::number_of_arguments() const {
00202   int result = 0;
00203   assert(length() > 0, "selector should have a positive length");
00204   
00205   // Return 1 if binary selector
00206   if (ispunct(byte_at(1))) return 1;
00207 
00208   // Return number of colons
00209   for (int index = 1; index <= length(); index++)
00210     if (byte_at(index) == ':')
00211       result++;
00212 
00213   return result;
00214 }
00215 
00216 bool byteArrayOopDesc::is_unary() const {
00217   if (is_binary()) return false;
00218   for (int index = 1; index <= length(); index++)
00219     if (byte_at(index) == ':') return false;
00220   return true;
00221 }
00222 
00223 bool byteArrayOopDesc::is_binary() const {
00224         return ispunct(byte_at(1)) ? true : false;
00225 }
00226 
00227 bool byteArrayOopDesc::is_keyword() const {
00228   if (is_binary()) return false;
00229   for (int index = 1; index <= length(); index++)
00230     if (byte_at(index) == ':') return true;
00231   return false;
00232 }
00233 
00234 byteArrayOop as_byteArrayOop(void* p)
00235 {
00236     return byteArrayOop(as_memOop(p));
00237 }
00238 

Generated on Mon Oct 9 13:37:04 2006 for Strongtalk VM by  doxygen 1.4.7