00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00043
00044
00045
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;
00052
00053
00054 smi t = length();
00055 smi i;
00056 for (i = length()-1; i >= 0; i--)
00057 if (byte_at(i) == '\0') t++;
00058
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
00076
00077
00078
00079 assert_byteArray(this, "should be a byte array");
00080 smi t = length();
00081 smi i;
00082 for (i = length()-1; i >= 0; i--)
00083 if (byte_at(i) == '\0') t++;
00084
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
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
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
00140 const unsigned int* a = (unsigned int*) length_addr();
00141 const unsigned int* b = (unsigned int*) arg->length_addr();
00142
00143
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
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
00206 if (ispunct(byte_at(1))) return 1;
00207
00208
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