00001
00013
00014 #include <string.h>
00015
00016 #include "NewtNSOF.h"
00017 #include "NewtErrs.h"
00018 #include "NewtObj.h"
00019 #include "NewtEnv.h"
00020 #include "NewtFns.h"
00021 #include "NewtVM.h"
00022 #include "NewtIconv.h"
00023
00024 #include "utils/endian_utils.h"
00025
00026
00027 #define NSOFIsNOS(verno) ((verno == 1) || (verno == 2))
00028
00029
00030
00031
00032
00034 #ifdef HAVE_LIBICONV
00035 typedef struct {
00036 iconv_t utf16be;
00037 iconv_t macroman;
00038 } nsof_iconv_t;
00039 #endif
00040
00042 typedef struct {
00043 int32_t verno;
00044 uint8_t * data;
00045 uint32_t len;
00046 uint32_t offset;
00047 newtRefVar precedents;
00048 newtErr lastErr;
00049
00050 #ifdef HAVE_LIBICONV
00051 struct {
00052 nsof_iconv_t to;
00053 nsof_iconv_t from;
00054 } cd;
00055 #endif
00056 } nsof_stream_t;
00057
00058
00059
00060 static bool NewtRefIsByte(newtRefArg r);
00061 static bool NewtRefIsSmallRect(newtRefArg r);
00062 static int32_t NewtArraySearch(newtRefArg array, newtRefArg r);
00063
00064 static newtErr NSOFWriteByte(nsof_stream_t * nsof, uint8_t value);
00065 static newtErr NSOFWriteXlong(nsof_stream_t * nsof, int32_t value);
00066 static uint8_t NSOFReadByte(nsof_stream_t * nsof);
00067 static int32_t NSOFReadXlong(nsof_stream_t * nsof);
00068
00069 static newtErr NSOFWritePrecedent(nsof_stream_t * nsof, int32_t pos);
00070 static newtErr NSOFWriteImmediate(nsof_stream_t * nsof, newtRefArg r);
00071 static newtErr NSOFWriteCharacter(nsof_stream_t * nsof, newtRefArg r);
00072 static newtErr NSOFWriteBinary(nsof_stream_t * nsof, newtRefArg r, uint16_t objtype);
00073 static newtErr NSOFWriteSymbol(nsof_stream_t * nsof, newtRefArg r);
00074 static newtErr NSOFWriteNamedMP(nsof_stream_t * nsof, newtRefArg r);
00075 static newtErr NSOFWriteArray(nsof_stream_t * nsof, newtRefArg r);
00076 static newtErr NSOFWriteFrame(nsof_stream_t * nsof, newtRefArg r);
00077 static newtErr NSOFWriteSmallRect(nsof_stream_t * nsof, newtRefArg r);
00078 static newtErr NewtWriteNSOF(nsof_stream_t * nsof, newtRefArg r);
00079
00080 static newtRef NSOFReadBinary(nsof_stream_t * nsof, int type);
00081 static newtRef NSOFReadArray(nsof_stream_t * nsof, int type);
00082 static newtRef NSOFReadFrame(nsof_stream_t * nsof);
00083 static newtRef NSOFReadSymbol(nsof_stream_t * nsof);
00084 static newtRef NSOFReadNamedMP(nsof_stream_t * nsof);
00085 static newtRef NSOFReadSmallRect(nsof_stream_t * nsof);
00086 static newtRef NSOFReadNSOF(nsof_stream_t * nsof);
00087
00088
00089 #pragma mark -
00090
00099 bool NewtRefIsByte(newtRefArg r)
00100 {
00101 if (NewtRefIsInteger(r))
00102 {
00103 int32_t n;
00104
00105 n = NewtRefToInteger(r);
00106
00107 if (0 <= n && n <= 255)
00108 return true;
00109 }
00110
00111 return false;
00112 }
00113
00114
00115
00124 bool NewtRefIsSmallRect(newtRefArg r)
00125 {
00126 if (NewtFrameLength(r) == 4)
00127 {
00128 if (NewtRefIsByte(NcGetSlot(r, NSSYM(top))) &&
00129 NewtRefIsByte(NcGetSlot(r, NSSYM(left))) &&
00130 NewtRefIsByte(NcGetSlot(r, NSSYM(bottom))) &&
00131 NewtRefIsByte(NcGetSlot(r, NSSYM(right))))
00132 {
00133 return true;
00134 }
00135 }
00136
00137 return false;
00138 }
00139
00140
00141
00151 int32_t NewtArraySearch(newtRefArg array, newtRefArg r)
00152 {
00153 newtRef * slots;
00154 uint32_t len;
00155 uint32_t i;
00156
00157 len = NewtArrayLength(array);
00158 slots = NewtRefToSlots(array);
00159
00160 for (i = 0; i < len; i++)
00161 {
00162 if (slots[i] == r)
00163 return i;
00164 }
00165
00166 return -1;
00167 }
00168
00169
00170 #pragma mark -
00171
00182 newtErr NSOFWriteByte(nsof_stream_t * nsof, uint8_t value)
00183 {
00184 if (nsof->data)
00185 {
00186 if (nsof->len <= nsof->offset)
00187 {
00188 nsof->lastErr = kNErrOutOfRange;
00189 return nsof->lastErr;
00190 }
00191
00192 nsof->data[nsof->offset] = value;
00193 }
00194
00195 nsof->offset++;
00196
00197 return kNErrNone;
00198 }
00199
00200
00201
00212 newtErr NSOFWriteXlong(nsof_stream_t * nsof, int32_t value)
00213 {
00214 if (0 <= value && value <= 254)
00215 {
00216 NSOFWriteByte(nsof, value);
00217 }
00218 else
00219 {
00220 NSOFWriteByte(nsof, 0xff);
00221 NSOFWriteByte(nsof, ((uint32_t)value >> 24) & 0xffff);
00222 NSOFWriteByte(nsof, ((uint32_t)value >> 16) & 0xffff);
00223 NSOFWriteByte(nsof, ((uint32_t)value >> 8) & 0xffff);
00224 NSOFWriteByte(nsof, (uint32_t)value & 0xffff);
00225 }
00226
00227 return nsof->lastErr;
00228 }
00229
00230
00231
00239 uint8_t NSOFReadByte(nsof_stream_t * nsof)
00240 {
00241 uint8_t result;
00242
00243 if (nsof->len <= nsof->offset)
00244 {
00245 nsof->lastErr = kNErrNotABinaryObject;
00246 return 0;
00247 }
00248
00249 result = nsof->data[nsof->offset];
00250 nsof->offset++;
00251
00252 return result;
00253 }
00254
00255
00256
00264 int32_t NSOFReadXlong(nsof_stream_t * nsof)
00265 {
00266 int32_t value;
00267
00268 value = NSOFReadByte(nsof);
00269
00270 if (value == 0xff)
00271 {
00272 value = NSOFReadByte(nsof) << 24;
00273 value |= NSOFReadByte(nsof) << 16;
00274 value |= NSOFReadByte(nsof) << 8;
00275 value |= NSOFReadByte(nsof);
00276 }
00277
00278 return value;
00279 }
00280
00281
00282 #pragma mark -
00283
00294 newtErr NSOFWritePrecedent(nsof_stream_t * nsof, int32_t pos)
00295 {
00296 NSOFWriteByte(nsof, kNSOFPrecedent);
00297 NSOFWriteXlong(nsof, pos);
00298
00299 return nsof->lastErr;
00300 }
00301
00302
00303
00314 newtErr NSOFWriteImmediate(nsof_stream_t * nsof, newtRefArg r)
00315 {
00316 NSOFWriteByte(nsof, kNSOFImmediate);
00317 NSOFWriteXlong(nsof, r);
00318
00319 return nsof->lastErr;
00320 }
00321
00322
00323
00334 newtErr NSOFWriteCharacter(nsof_stream_t * nsof, newtRefArg r)
00335 {
00336 int c;
00337
00338 c = NewtRefToCharacter(r);
00339
00340 if (c < 0x100)
00341 {
00342 NSOFWriteByte(nsof, kNSOFCharacter);
00343 NSOFWriteByte(nsof, c);
00344 }
00345 else
00346 {
00347 NSOFWriteByte(nsof, kNSOFUnicodeCharacter);
00348 NSOFWriteByte(nsof, (c >> 8) & 0xff);
00349 NSOFWriteByte(nsof, c & 0xff);
00350 }
00351
00352 return nsof->lastErr;
00353 }
00354
00355
00356
00368 newtErr NSOFWriteBinary(nsof_stream_t * nsof, newtRefArg r, uint16_t objtype)
00369 {
00370 newtRefVar klass;
00371 uint32_t size;
00372 char * buff = NULL;
00373 int type;
00374
00375 klass = NcClassOf(r);
00376
00377 if (klass == NSSYM0(string))
00378 type = kNSOFString;
00379 else
00380 type = kNSOFBinaryObject;
00381
00382 size = NewtBinaryLength(r);
00383
00384 #ifdef HAVE_LIBICONV
00385 if (objtype == kNewtString)
00386 {
00387 size_t bufflen;
00388 char * s;
00389
00390 s = NewtRefToString(r);
00391 buff = NewtIconv(nsof->cd.to.utf16be, (char *)s, size, &bufflen);
00392 if (buff) size = bufflen;
00393 }
00394 #endif
00395
00396 NSOFWriteByte(nsof, type);
00397 NSOFWriteXlong(nsof, size);
00398
00399 if (type == kNSOFBinaryObject)
00400 {
00401 NewtWriteNSOF(nsof, klass);
00402 }
00403
00404 if (nsof->data)
00405 {
00406 uint8_t * data;
00407
00408 data = nsof->data + nsof->offset;
00409
00410 switch (objtype)
00411 {
00412 case kNewtInt32:
00413 if (NSOFIsNOS(nsof->verno))
00414 {
00415 nsof->lastErr = kNErrNSOFWrite;
00416 }
00417 else
00418 {
00419 int32_t n;
00420
00421 n = NewtRefToInteger(r);
00422 n = htonl(n);
00423 memcpy(data, (uint8_t *)&n, sizeof(n));
00424 }
00425 break;
00426
00427 case kNewtReal:
00428 {
00429 double n;
00430
00431 n = NewtRefToReal(r);
00432 n = htond(n);
00433 memcpy(data, (uint8_t *)&n, sizeof(n));
00434 }
00435 break;
00436
00437 default:
00438 if (buff)
00439 memcpy(data, buff, size);
00440 else
00441 memcpy(data, NewtRefToBinary(r), size);
00442 break;
00443 }
00444 }
00445
00446 nsof->offset += size;
00447 if (buff) free(buff);
00448
00449 return nsof->lastErr;
00450 }
00451
00452
00453
00464 newtErr NSOFWriteSymbol(nsof_stream_t * nsof, newtRefArg r)
00465 {
00466 uint32_t size;
00467 char * buff = NULL;
00468 char * name;
00469
00470 size = NewtSymbolLength(r);
00471 name = NewtRefToSymbol(r)->name;
00472
00473 #ifdef HAVE_LIBICONV
00474 {
00475 size_t bufflen;
00476
00477 buff = NewtIconv(nsof->cd.to.macroman, (char *)name, size, &bufflen);
00478
00479 if (buff)
00480 {
00481 name = buff;
00482 size = bufflen;
00483 }
00484 }
00485 #endif
00486
00487 NSOFWriteByte(nsof, kNSOFSymbol);
00488 NSOFWriteXlong(nsof, size);
00489
00490 if (nsof->data) memcpy(nsof->data + nsof->offset, name, size);
00491 nsof->offset += size;
00492
00493 if (buff) free(buff);
00494
00495 return nsof->lastErr;
00496 }
00497
00498
00499 #ifdef __NAMED_MAGIC_POINTER__
00500
00511 newtErr NSOFWriteNamedMP(nsof_stream_t * nsof, newtRefArg r)
00512 {
00513 newtRefVar sym;
00514
00515 sym = NewtMPToSymbol(r);
00516
00517 if (NSOFIsNOS(nsof->verno))
00518 {
00519
00520 NSOFWriteSymbol(nsof, sym);
00521 nsof->lastErr = kNErrNSOFWrite;
00522 }
00523 else
00524 {
00525 uint32_t size;
00526
00527 size = NewtSymbolLength(sym);
00528
00529 NSOFWriteByte(nsof, kNSOFNamedMagicPointer);
00530 NSOFWriteXlong(nsof, size);
00531
00532 if (nsof->data) memcpy(nsof->data + nsof->offset, NewtRefToSymbol(sym)->name, size);
00533 nsof->offset += size;
00534 }
00535
00536 return nsof->lastErr;
00537 }
00538 #endif
00539
00540
00541
00552 newtErr NSOFWriteArray(nsof_stream_t * nsof, newtRefArg r)
00553 {
00554 newtRefVar klass;
00555 newtRef * slots;
00556 uint32_t numSlots;
00557 uint32_t i;
00558 int type;
00559
00560 numSlots = NewtArrayLength(r);
00561 klass = NcClassOf(r);
00562
00563 if (klass == NSSYM0(array))
00564 type = kNSOFPlainArray;
00565 else
00566 type = kNSOFArray;
00567
00568 NSOFWriteByte(nsof, type);
00569
00570 NSOFWriteXlong(nsof, numSlots);
00571
00572 if (type == kNSOFArray)
00573 {
00574 NewtWriteNSOF(nsof, klass);
00575 if (nsof->lastErr != kNErrNone) return nsof->lastErr;
00576 }
00577
00578 slots = NewtRefToSlots(r);
00579
00580 for (i = 0; i < numSlots; i++)
00581 {
00582 NewtWriteNSOF(nsof, slots[i]);
00583 if (nsof->lastErr != kNErrNone) return nsof->lastErr;
00584 }
00585
00586 return nsof->lastErr;
00587 }
00588
00589
00590
00601 newtErr NSOFWriteFrame(nsof_stream_t * nsof, newtRefArg r)
00602 {
00603 newtRefVar map;
00604 newtRef * slots;
00605 uint32_t numSlots;
00606 uint32_t index;
00607 uint32_t i;
00608
00609 numSlots = NewtFrameLength(r);
00610 map = NewtFrameMap(r);
00611
00612 NSOFWriteByte(nsof, kNSOFFrame);
00613 NSOFWriteXlong(nsof, numSlots);
00614
00615 slots = NewtRefToSlots(r);
00616
00617 for (i = 0; i < numSlots; i++)
00618 {
00619 index = 0;
00620 NewtWriteNSOF(nsof, NewtGetMapIndex(map, i, &index));
00621 if (nsof->lastErr != kNErrNone) return nsof->lastErr;
00622 }
00623
00624 for (i = 0; i < numSlots; i++)
00625 {
00626 NewtWriteNSOF(nsof, slots[i]);
00627 if (nsof->lastErr != kNErrNone) return nsof->lastErr;
00628 }
00629
00630 return nsof->lastErr;
00631 }
00632
00633
00634
00645 newtErr NSOFWriteSmallRect(nsof_stream_t * nsof, newtRefArg r)
00646 {
00647 NSOFWriteByte(nsof, kNSOFSmallRect);
00648 NSOFWriteByte(nsof, NewtRefToInteger(NcGetSlot(r, NSSYM(top))));
00649 NSOFWriteByte(nsof, NewtRefToInteger(NcGetSlot(r, NSSYM(left))));
00650 NSOFWriteByte(nsof, NewtRefToInteger(NcGetSlot(r, NSSYM(bottom))));
00651 NSOFWriteByte(nsof, NewtRefToInteger(NcGetSlot(r, NSSYM(right))));
00652
00653 return nsof->lastErr;
00654 }
00655
00656
00657
00668 newtErr NewtWriteNSOF(nsof_stream_t * nsof, newtRefArg r)
00669 {
00670 if (NewtRefIsImmediate(r))
00671 {
00672 if (r == kNewtRefNIL)
00673 NSOFWriteByte(nsof, kNSOFNIL);
00674 else if (NewtRefIsCharacter(r))
00675 NSOFWriteCharacter(nsof, r);
00676 else
00677 NSOFWriteImmediate(nsof, r);
00678 }
00679 else
00680 {
00681 int32_t foundPrecedent;
00682
00683 foundPrecedent = NewtArraySearch(nsof->precedents, r);
00684
00685 if (foundPrecedent < 0)
00686 {
00687 uint16_t objtype;
00688
00689 NcAddArraySlot(nsof->precedents, r);
00690 objtype = NewtGetRefType(r, true);
00691
00692 switch (objtype)
00693 {
00694 case kNewtArray:
00695 NSOFWriteArray(nsof, r);
00696 break;
00697
00698 case kNewtFrame:
00699 if (NewtRefIsSmallRect(r))
00700 NSOFWriteSmallRect(nsof, r);
00701 else
00702 NSOFWriteFrame(nsof, r);
00703 break;
00704
00705 case kNewtSymbol:
00706 NSOFWriteSymbol(nsof, r);
00707 break;
00708
00709 #ifdef __NAMED_MAGIC_POINTER__
00710 case kNewtMagicPointer:
00711 NSOFWriteNamedMP(nsof, r);
00712 break;
00713 #endif
00714
00715 default:
00716 NSOFWriteBinary(nsof, r, objtype);
00717 break;
00718 }
00719 }
00720 else
00721 {
00722 NSOFWritePrecedent(nsof, foundPrecedent);
00723 }
00724 }
00725
00726 return nsof->lastErr;
00727 }
00728
00729
00730
00740 newtRef NsMakeNSOF(newtRefArg rcvr, newtRefArg r, newtRefArg ver)
00741 {
00742 nsof_stream_t nsof;
00743 newtRefVar result;
00744
00745 if (! NewtRefIsInteger(ver))
00746 return NewtThrow(kNErrNotAnInteger, ver);
00747
00748 memset(&nsof, 0, sizeof(nsof));
00749
00750 nsof.verno = NewtRefToInteger(ver);
00751 nsof.precedents = NewtMakeArray(kNewtRefUnbind, 0);
00752 nsof.offset = 1;
00753
00754 #ifdef HAVE_LIBICONV
00755 if (NSOFIsNOS(nsof.verno))
00756 {
00757 char * encoding;
00758
00759 encoding = NewtDefaultEncoding();
00760 nsof.cd.to.utf16be = iconv_open("UTF-16BE", encoding);
00761 nsof.cd.to.macroman = iconv_open("MACROMAN", encoding);
00762 }
00763 else
00764 {
00765 nsof.cd.to.utf16be = (iconv_t)-1;
00766 nsof.cd.to.macroman = (iconv_t)-1;
00767 }
00768 #endif
00769
00770
00771 NewtWriteNSOF(&nsof, r);
00772
00773 if (nsof.lastErr == kNErrNone)
00774 {
00775
00776 result = NewtMakeBinary(NSSYM(NSOF), NULL, nsof.offset, false);
00777
00778 if (NewtRefIsNotNIL(result))
00779 {
00780 NewtSetLength(nsof.precedents, 0);
00781 nsof.data = NewtRefToBinary(result);
00782 nsof.len = nsof.offset;
00783 nsof.offset = 0;
00784
00785 NSOFWriteByte(&nsof, nsof.verno);
00786 NewtWriteNSOF(&nsof, r);
00787 }
00788 }
00789 else
00790 {
00791 result = NewtThrow(nsof.lastErr, r);
00792 }
00793
00794 #ifdef HAVE_LIBICONV
00795 if (nsof.cd.to.utf16be != (iconv_t)-1) iconv_close(nsof.cd.to.utf16be);
00796 if (nsof.cd.to.macroman != (iconv_t)-1) iconv_close(nsof.cd.to.macroman);
00797 #endif
00798
00799 return result;
00800 }
00801
00802
00803 #pragma mark -
00804
00813 newtRef NSOFReadBinary(nsof_stream_t * nsof, int type)
00814 {
00815 newtRefVar klass;
00816 newtRefVar r = kNewtRefUnbind;
00817 int32_t xlen;
00818 uint8_t * data;
00819
00820 xlen = NSOFReadXlong(nsof);
00821
00822 if (type == kNSOFString)
00823 {
00824 klass = NSSYM0(string);
00825 }
00826 else
00827 {
00828 klass = NSOFReadNSOF(nsof);
00829 if (nsof->lastErr != kNErrNone) return kNewtRefUnbind;
00830 }
00831
00832 data = nsof->data + nsof->offset;
00833
00834 if (klass == NSSYM0(int32))
00835 {
00836 if (NSOFIsNOS(nsof->verno))
00837 {
00838 nsof->lastErr = kNErrNSOFRead;
00839 }
00840 else
00841 {
00842 int32_t n;
00843
00844 memcpy(&n, data, sizeof(n));
00845 n = ntohl(n);
00846 r= NewtMakeInteger(n);
00847 }
00848 }
00849 else if (klass == NSSYM0(real))
00850 {
00851 double n;
00852
00853 memcpy(&n, data, sizeof(n));
00854 n = ntohd(n);
00855 r= NewtMakeReal(n);
00856 }
00857 #ifdef HAVE_LIBICONV
00858 else if (NewtIsSubclass(klass, NSSYM0(string)))
00859 {
00860 char * buff;
00861
00862 buff = NewtIconv(nsof->cd.from.utf16be, (char *)data, xlen, NULL);
00863
00864 if (buff)
00865 {
00866 r = NewtMakeString(buff, false);
00867 free(buff);
00868 }
00869 else
00870 {
00871 r = NewtMakeBinary(klass, data, xlen, false);
00872 }
00873 }
00874 #endif
00875 else
00876 {
00877 r = NewtMakeBinary(klass, data, xlen, false);
00878 }
00879
00880 nsof->offset += xlen;
00881
00882 return r;
00883 }
00884
00885
00886
00895 newtRef NSOFReadArray(nsof_stream_t * nsof, int type)
00896 {
00897 newtRefVar klass = kNewtRefUnbind;
00898 newtRefVar r;
00899 int32_t xlen;
00900
00901 xlen = NSOFReadXlong(nsof);
00902
00903 if (type == kNSOFArray)
00904 {
00905 klass = NSOFReadNSOF(nsof);
00906 if (nsof->lastErr != kNErrNone) return kNewtRefUnbind;
00907 }
00908
00909 r = NewtMakeArray(klass, xlen);
00910 NcAddArraySlot(nsof->precedents, r);
00911
00912 if (NewtRefIsNotNIL(r))
00913 {
00914 newtRef * slots;
00915 int32_t i;
00916
00917 slots = NewtRefToSlots(r);
00918
00919 for (i = 0; i < xlen; i++)
00920 {
00921 slots[i] = NSOFReadNSOF(nsof);
00922 if (nsof->lastErr != kNErrNone) break;
00923 }
00924 }
00925
00926 return r;
00927 }
00928
00929
00930
00938 newtRef NSOFReadFrame(nsof_stream_t * nsof)
00939 {
00940 newtRefVar map;
00941 newtRefVar r;
00942 newtRef * slots;
00943 int32_t xlen;
00944 int32_t i;
00945
00946 xlen = NSOFReadXlong(nsof);
00947
00948 if (xlen == 0)
00949 return NcMakeFrame();
00950
00951 map = NewtMakeMap(kNewtRefNIL, xlen, NULL);
00952 r = NewtMakeFrame(map, xlen);
00953 NcAddArraySlot(nsof->precedents, r);
00954
00955 slots = NewtRefToSlots(map);
00956
00957 for (i = 1; i <= xlen; i++)
00958 {
00959 slots[i] = NSOFReadNSOF(nsof);
00960 if (nsof->lastErr != kNErrNone) return kNewtRefUnbind;
00961 }
00962
00963 slots = NewtRefToSlots(r);
00964
00965 for (i = 0; i < xlen; i++)
00966 {
00967 slots[i] = NSOFReadNSOF(nsof);
00968 if (nsof->lastErr != kNErrNone) break;
00969 }
00970
00971 return r;
00972 }
00973
00974
00975
00983 newtRef NSOFReadSymbol(nsof_stream_t * nsof)
00984 {
00985 newtRefVar r = kNewtRefUnbind;
00986 int32_t xlen;
00987 char * name;
00988
00989 xlen = NSOFReadXlong(nsof);
00990 name = malloc(xlen + 1);
00991
00992 if (name)
00993 {
00994 memcpy(name, nsof->data + nsof->offset, xlen);
00995 name[xlen] = '0';
00996
00997 #ifdef HAVE_LIBICONV
00998 {
00999 char * buff;
01000
01001 buff = NewtIconv(nsof->cd.from.macroman, name, xlen + 1, NULL);
01002
01003 if (buff)
01004 {
01005 r = NewtMakeSymbol(buff);
01006 free(buff);
01007 }
01008 }
01009 #endif
01010
01011 if (r == kNewtRefUnbind)
01012 r = NewtMakeSymbol(name);
01013
01014 free(name);
01015 }
01016
01017 nsof->offset += xlen;
01018
01019 return r;
01020 }
01021
01022
01023 #ifdef __NAMED_MAGIC_POINTER__
01024
01032 newtRef NSOFReadNamedMP(nsof_stream_t * nsof)
01033 {
01034 newtRefVar r;
01035
01036 r = NSOFReadSymbol(nsof);
01037
01038 if (NewtRefIsNotNIL(r))
01039 {
01040 if (NSOFIsNOS(nsof->verno))
01041 {
01042 nsof->lastErr = kNErrNSOFRead;
01043
01044 }
01045 else
01046 {
01047 r = NewtSymbolToMP(r);
01048 }
01049 }
01050
01051 return r;
01052 }
01053 #endif
01054
01055
01056
01064 newtRef NSOFReadSmallRect(nsof_stream_t * nsof)
01065 {
01066 newtRefVar r;
01067
01068 r = NcMakeFrame();
01069
01070
01071 NcSetSlot(r, NSSYM(top), NewtMakeInteger(NSOFReadByte(nsof)));
01072 NcSetSlot(r, NSSYM(left), NewtMakeInteger(NSOFReadByte(nsof)));
01073 NcSetSlot(r, NSSYM(bottom), NewtMakeInteger(NSOFReadByte(nsof)));
01074 NcSetSlot(r, NSSYM(right), NewtMakeInteger(NSOFReadByte(nsof)));
01075
01076 return r;
01077 }
01078
01079
01080
01088 newtRef NSOFReadNSOF(nsof_stream_t * nsof)
01089 {
01090 newtRefVar r = kNewtRefUnbind;
01091 int32_t xlen;
01092 int type;
01093
01094 type = NSOFReadByte(nsof);
01095
01096 switch (type)
01097 {
01098 case kNSOFImmediate:
01099 r = (newtRef)NSOFReadXlong(nsof);
01100 break;
01101
01102 case kNSOFCharacter:
01103 r = NewtMakeCharacter(NSOFReadByte(nsof));
01104 break;
01105
01106 case kNSOFUnicodeCharacter:
01107 r = NewtMakeCharacter((uint32_t)NSOFReadByte(nsof) << 8 | NSOFReadByte(nsof));
01108 break;
01109
01110 case kNSOFBinaryObject:
01111 case kNSOFString:
01112 r = NSOFReadBinary(nsof, type);
01113 NcAddArraySlot(nsof->precedents, r);
01114 break;
01115
01116 case kNSOFArray:
01117 case kNSOFPlainArray:
01118 r = NSOFReadArray(nsof, type);
01119 break;
01120
01121 case kNSOFFrame:
01122 r = NSOFReadFrame(nsof);
01123 break;
01124
01125 case kNSOFSymbol:
01126 r = NSOFReadSymbol(nsof);
01127 NcAddArraySlot(nsof->precedents, r);
01128 break;
01129
01130 case kNSOFPrecedent:
01131 xlen = NSOFReadXlong(nsof);
01132 r = NewtGetArraySlot(nsof->precedents, xlen);
01133 break;
01134
01135 case kNSOFNIL:
01136 r = kNewtRefNIL;
01137 break;
01138
01139 case kNSOFSmallRect:
01140 r = NSOFReadSmallRect(nsof);
01141 NcAddArraySlot(nsof->precedents, r);
01142 break;
01143
01144 #ifdef __NAMED_MAGIC_POINTER__
01145 case kNSOFNamedMagicPointer:
01146 r = NSOFReadNamedMP(nsof);
01147 NcAddArraySlot(nsof->precedents, r);
01148 break;
01149 #endif
01150
01151 case kNSOFLargeBinary:
01152 default:
01153
01154 nsof->lastErr = kNErrNSOFRead;
01155 break;
01156 }
01157
01158 return r;
01159 }
01160
01161
01162
01171 newtRef NewtReadNSOF(uint8_t * data, size_t size)
01172 {
01173 nsof_stream_t nsof;
01174 newtRefVar reault;
01175
01176 memset(&nsof, 0, sizeof(nsof));
01177
01178 nsof.data = data;
01179 nsof.len = size;
01180 nsof.precedents = NewtMakeArray(kNewtRefUnbind, 0);
01181 nsof.verno = NSOFReadByte(&nsof);
01182
01183 #ifdef HAVE_LIBICONV
01184 if (NSOFIsNOS(nsof.verno))
01185 {
01186 char * encoding;
01187
01188 encoding = NewtDefaultEncoding();
01189 nsof.cd.from.utf16be = iconv_open(encoding, "UTF-16BE");
01190 nsof.cd.from.macroman = iconv_open(encoding, "MACROMAN");
01191 }
01192 else
01193 {
01194 nsof.cd.from.utf16be = (iconv_t)-1;
01195 nsof.cd.from.macroman = (iconv_t)-1;
01196 }
01197 #endif
01198
01199 reault = NSOFReadNSOF(&nsof);
01200
01201 #ifdef HAVE_LIBICONV
01202 if (nsof.cd.from.utf16be != (iconv_t)-1) iconv_close(nsof.cd.from.utf16be);
01203 if (nsof.cd.from.macroman != (iconv_t)-1) iconv_close(nsof.cd.from.macroman);
01204 #endif
01205
01206 return reault;
01207 }
01208
01209
01210
01219 newtRef NsReadNSOF(newtRefArg rcvr, newtRefArg r)
01220 {
01221 uint32_t len;
01222
01223 if (! NewtRefIsBinary(r))
01224 return NewtThrow(kNErrNotABinaryObject, r);
01225
01226 len = NewtBinaryLength(r);
01227
01228 if (len < 2)
01229 return NewtThrow(kNErrOutOfRange, r);
01230
01231 return NewtReadNSOF(NewtRefToBinary(r), len);
01232 }
01233