00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stlib/ByteArray.h>
00026 #include <stlib/EncodedStream.h>
00027 #include <stlib/Integer.h>
00028 #include <stlib/InternalEncodedStreamFactory.h>
00029 #include <stlib/String.h>
00030 #include <stlib/SOOBoundsError.h>
00031
00032 #include <string.h>
00033
00034 ByteArray::ByteArray(int size)
00035 {
00036 bytes = NULL;
00037 tally = size;
00038 if (tally) {
00039 bytes = (unsigned char *) GC_malloc(tally * sizeof(unsigned char));
00040 bzero(bytes, tally);
00041 }
00042 }
00043
00044 ByteArray::ByteArray(const ByteArray &origin)
00045 {
00046 bytes = NULL;
00047 tally = origin.tally;
00048 if (tally) {
00049 bytes = (unsigned char *) GC_malloc(tally * sizeof(unsigned char));
00050 memcpy(bytes, origin.bytes, tally);
00051 }
00052 }
00053
00054 ByteArray::ByteArray(const char *buffer, int size)
00055 {
00056 bytes = NULL;
00057 tally = size;
00058 if (tally) {
00059 bytes = (unsigned char *) GC_malloc(tally * sizeof(unsigned char));
00060 memcpy(bytes, buffer, tally);
00061 }
00062 }
00063
00064 ByteArray::~ByteArray()
00065 {
00066 if (tally)
00067 GC_free(bytes);
00068 }
00069
00070
00071 ByteArray *ByteArray::fromStringEncoding(const String *string, String *encoding)
00072 {
00073 EncodedStream *stream = (new ByteArray(string->size()))->withEncoding(encoding)->writeStream();
00074 stream->nextPutAll(string);
00075 return dynamic_cast<ByteArray *>(stream->contents());
00076 }
00077
00078
00079 Object* ByteArray::at(int index) const
00080 {
00081 if (index < 0 || index >= tally) {
00082 SubscriptOutOfBoundsError *ex;
00083 ex = new SubscriptOutOfBoundsError(__PRETTY_FUNCTION__, index);
00084 ex->raiseFrom(this);
00085 }
00086 return Integer::value(bytes[index] & 0xFF);
00087 }
00088
00089 void ByteArray::put(int index, Object* obj)
00090 {
00091 if (index < 0 || index >= tally) {
00092 SubscriptOutOfBoundsError *ex;
00093 ex = new SubscriptOutOfBoundsError(__PRETTY_FUNCTION__, index);
00094 ex->raiseFrom(this);
00095 }
00096 checkObject(obj, __PRETTY_FUNCTION__);
00097 unsigned char val = ((Number *) obj)->asLong();
00098 bytes[index] = val & 0xFF;
00099 }
00100
00101 void ByteArray::replace(long start, long stop, unsigned char *collection)
00102 {
00103 replace(start, stop, collection, 0);
00104 }
00105
00106 void ByteArray::replace(long start, long stop,
00107 unsigned char *collection, long startIndex)
00108 {
00109 memcpy(&bytes[start], &collection[startIndex], stop - start);
00110 }
00111
00112 void ByteArray::changeSize(long newSize)
00113 {
00114 unsigned char *oldBytes = bytes;
00115 long i;
00116
00117 bytes = (unsigned char *) GC_malloc(newSize * sizeof(unsigned char));
00118
00119
00120
00121
00122 for (i = 0; i < newSize && i < tally; i++) {
00123 bytes[i] = oldBytes[i];
00124 }
00125
00126 for (; i < newSize; i++) {
00127 bytes[i] = 0;
00128 }
00129 tally = newSize;
00130 GC_free(oldBytes);
00131 }
00132
00133 void ByteArray::add(Object *obj)
00134 {
00135 shouldNotImplement(__PRETTY_FUNCTION__);
00136 }
00137
00138 Object* ByteArray::copy(void)
00139 {
00140 return new ByteArray(*this);
00141 }
00142
00143 Object* ByteArray::copyEmpty(long int size)
00144 {
00145 return new ByteArray(size);
00146 }
00147
00148
00149 long ByteArray::hash(void) const
00150 {
00151 long hashConst = 0x23451;
00152 int length = size();
00153
00154 if (length > 0) {
00155 hashConst ^= bytes[0];
00156 if (length > 1) {
00157 hashConst ^= bytes[length-1];
00158 if (length > 3) {
00159 hashConst ^= bytes[length/2-1] ^ bytes[length/2+1];
00160 }
00161 }
00162 }
00163 return hashConst;
00164 }
00165
00166 bool ByteArray::isEqual(const Object *object) const
00167 {
00168 return object->isEqualToByteArray(this);
00169 }
00170
00171 bool ByteArray::isEqual(const char *array, int size) const
00172 {
00173 if (size != tally) return false;
00174 return memcmp(bytes, array, tally) == 0;
00175 }
00176
00177 bool ByteArray::isEqualToByteArray(const Object *array) const
00178 {
00179 return dynamic_cast<const ByteArray *>(array)->isEqual((char *) bytes, tally);
00180 }
00181
00182
00183 ByteArray *ByteArray::asByteArray(void)
00184 {
00185 return this;
00186 }
00187
00188 char *ByteArray::asCString(void)
00189 {
00190 char *cString = (char *) GC_malloc((tally + 1) * sizeof(char));
00191 memcpy(cString, bytes, tally);
00192 cString[tally] = 0;
00193 return cString;
00194 }
00195
00196 String *ByteArray::asString(void)
00197 {
00198 return new String(this);
00199 }
00200
00201 String *ByteArray::asStringWithEncoding(String *encoding)
00202 {
00203 return dynamic_cast<String *>(withEncoding(encoding)->readStream()->upToEnd());
00204 }
00205
00206 String *ByteArray::asStringWithEncoding(const char *encoding)
00207 {
00208 return asStringWithEncoding(new String(encoding));
00209 }
00210
00211 unsigned long ByteArray::asInteger(void)
00212 {
00213 return asNumberWithRadix(256);
00214 }
00215
00216 unsigned long ByteArray::asNumberWithRadix(int radix)
00217 {
00218 unsigned long number = 0;
00219
00220 for (long i = 0; i < tally; i++) {
00221 number = number * radix + bytes[i];
00222 }
00223 return number;
00224 }
00225
00226 unsigned char *ByteArray::rawBytes(void) const
00227 {
00228
00229
00230
00231 unsigned char *retbytes = (unsigned char *) GC_malloc(tally * sizeof(unsigned char *));
00232
00233 memcpy(retbytes, bytes, tally);
00234 return retbytes;
00235 }
00236
00237 const unsigned char *ByteArray::rawBytesReadOnly(void) const
00238 {
00239 return bytes;
00240 }
00241
00242
00243 InternalEncodedStreamFactory *ByteArray::withEncoding(String *encoding)
00244 {
00245 return new InternalEncodedStreamFactory(this, encoding);
00246 }
00247
00248 InternalEncodedStreamFactory *ByteArray::withEncoding(const char *encoding)
00249 {
00250 return withEncoding(new String(encoding));
00251 }
00252
00253
00254 bool ByteArray::isByteArray(void)
00255 {
00256 return true;
00257 }
00258
00259
00260 void ByteArray::checkObject(Object *obj, const char *sel)
00261 {
00262 if (obj->isNumber()) {
00263 Number* n = (Number *) obj;
00264 long long l = n->asLongLong();
00265 if (l < 0 || l > 255) {
00266 Error *e = new Error(new String("Invalid value!"), new String(sel), obj);
00267 e->raiseFrom(this);
00268 }
00269 } else {
00270 Error *e = new Error(new String("Not a Number instance!"), new String(sel), obj);
00271 e->raiseFrom(this);
00272 }
00273 }