NewtNSOF.c

説明を見る。
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* __NAMED_MAGIC_POINTER__ */
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 /* __NAMED_MAGIC_POINTER__ */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 /* __NAMED_MAGIC_POINTER__ */
01054 
01055 
01056 /*------------------------------------------------------------------------*/
01064 newtRef NSOFReadSmallRect(nsof_stream_t * nsof)
01065 {
01066     newtRefVar  r;
01067 
01068     r = NcMakeFrame();
01069     // 将来は map を共有すること
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 /* __NAMED_MAGIC_POINTER__ */
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 /* HAVE_LIBICONV */
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 /* HAVE_LIBICONV */
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 

NEWT/0に対してThu Nov 23 16:50:43 2006に生成されました。  doxygen 1.5.0