home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osp1.exe / src / utils / StdTypIO.cpp < prev    next >
C/C++ Source or Header  |  1997-04-02  |  60KB  |  1,693 lines

  1. //====START_GENERATED_PROLOG======================================
  2. //
  3. //
  4. //   COMPONENT_NAME: odmri
  5. //
  6. //   CLASSES: none
  7. //
  8. //   ORIGINS: 82,27
  9. //
  10. //
  11. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  12. //   All Rights Reserved
  13. //   Licensed Materials - Property of IBM
  14. //   US Government Users Restricted Rights - Use, duplication or
  15. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  16. //       
  17. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  18. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  20. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  21. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  22. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  23. //   OR PERFORMANCE OF THIS SOFTWARE.
  24. //
  25. //====END_GENERATED_PROLOG========================================
  26. //
  27. // @(#) 1.38 com/src/utils/StdTypIO.cpp, odmri, od96os2, odos29712d 1/28/97 15:20:17 [ 3/21/97 17:20:57 ]
  28.  
  29. /*
  30.    File:           StdTypIO.cpp
  31.  
  32.    Contains:       functions for read/writing standard typed values from/to storage units
  33.  
  34.    Owned by:       Tantek éelik
  35.  
  36.    Copyright:      ⌐ 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  37.  
  38.    Theory of operation:
  39.  
  40.  The philosophy of StdTypIO is to give the client of the standard type IO functions
  41.  flexibility with respect to where the data is stored while providing a standard for
  42.  the data format used to store the types of data used in the various pieces of
  43.  OpenDoc metadata in order to facilitate document exchange.
  44.  
  45.  The standard type IO functions are designed to be used independent of property &
  46.  value type, and in some/most cases can even be used to manipulate data midstream
  47.  (in the middle of values) by passing in a prefocused storageunit along with the
  48.  offset set correctly, and passing in kODNULL for the prop and the val params.
  49.  
  50.  
  51. */
  52.  
  53. #define _OD_DONT_IMPORT_CPP_
  54.  
  55. #ifndef _ALTPOINT_
  56. #include "AltPoint.h"
  57. #endif
  58.  
  59. #ifndef _ALTPOLY_
  60. #include "AltPoly.h"
  61. #endif
  62.  
  63. #ifndef _ODEXCEPT_
  64. #include <ODExcept.h>
  65. #endif
  66.  
  67. #ifndef _ODDEBUG_
  68. #include "ODDebug.h"
  69. #endif
  70.  
  71. #ifdef _PLATFORM_MACINTOSH_
  72.   #ifndef __SCRIPT__
  73.   #include <Script.h>
  74.   #endif
  75. #endif
  76.  
  77. #ifndef _TEMPITER_
  78. #include <TempIter.h>
  79. #endif
  80.  
  81. #ifndef _ITEXT_
  82. #include <IText.h>
  83. #endif
  84.  
  85. #ifndef __TIME_H__
  86. #include <time.h>
  87. #endif
  88.  
  89. #ifndef _ODMEMORY_
  90. #include <ODMemory.h>
  91. #endif
  92.  
  93. #ifndef SOM_ODStorageUnit_xh
  94. #include <StorageU.xh>
  95. #endif
  96.  
  97. #ifndef SOM_ODStorageUnitView_xh
  98. #include <SUView.xh>
  99. #endif
  100.  
  101. #ifndef _STDTYPIO_
  102. #include "StdTypIO.h"
  103. #endif
  104.  
  105. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  106. #include "StdDefs.xh"
  107. #endif
  108.  
  109. #ifndef _STORUTIL_
  110. #include <StorUtil.h>
  111. #endif
  112.  
  113. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  114. #include "StdTypes.xh"
  115. #endif
  116.  
  117. #ifndef SOM_ODTypeList_xh
  118. #include <TypeList.xh>
  119. #endif
  120.  
  121. #ifndef SOM_ODTypeListIterator_xh
  122. #include <TypLsItr.xh>
  123. #endif
  124.  
  125. #ifdef _PLATFORM_MACINTOSH_
  126. #ifndef __OSUTILS__
  127. #include <OSUtils.h>
  128. #endif
  129. #endif
  130.  
  131. #ifndef _FLIPEND_
  132. #include <FlipEnd.h>
  133. #endif
  134.  
  135. #ifndef _ODUTILS_
  136. #include <ODUtils.h>
  137. #endif
  138.  
  139. #ifndef _UTILERRS_
  140. #include <UtilErrs.h>
  141. #endif
  142.  
  143. #ifndef _TEMPOBJ_
  144. #include <TempObj.h>
  145. #endif
  146.  
  147.  
  148. #include <errno.h>
  149. #if defined(__IBMCPP__) || defined(_IBMR2)
  150. // The following is for the iconv additions.
  151. #include <iconv.h>
  152. #include <nl_types.h>
  153. #include <langinfo.h>
  154. #endif
  155.  
  156. // This code is for error messages
  157. #include <ODMessag.h>
  158.  
  159.  
  160. //==============================================================================
  161. // Constants
  162. //==============================================================================
  163.  
  164. #define         kODBooleanLen           1
  165. #define         kODUShortLen            2
  166. #define         kODSShortLen            2
  167. #define         kODULongLen                     4
  168. #define         kODSLongLen                     4
  169. #define         kODCoordinateLen        4
  170. #define         kODPointLen                     (4*2)
  171. #define         kODRectLen                      (4*4)
  172. #define         kODStorageUnitRefLen 4
  173.  
  174. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  175. #define kIBMCodePagePrefix "IBM-"
  176. #endif
  177.  
  178. #ifdef _PLATFORM_MACINTOSH_
  179. #define useGMT 1
  180. #else
  181. #define useGMT 0
  182. #endif
  183.  
  184. //==============================================================================
  185. // Boolean
  186. //==============================================================================
  187.  
  188. WIN32_DLLEXPORT ODBoolean       ODGetBooleanProp(Environment* ev,
  189.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  190. {
  191.    if (ODSUExistsThenFocus(ev, su, prop, val))
  192.    {
  193.       ODBoolean value;
  194.       StorageUnitGetValue(su, ev, sizeof(ODBoolean), (ODValue)&value);
  195.       return (value ? kODTrue : kODFalse);
  196.    }
  197.    else {
  198.       WARNMSG_DEBUG(WARN_INDEX(-1),"No Boolean Property.");
  199.       return kODFalse;
  200.    }
  201. }
  202.  
  203. WIN32_DLLEXPORT void            ODSetBooleanProp(Environment* ev,
  204.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  205.             ODBoolean value)
  206. {
  207.    ODSUForceFocus(ev, su, prop, val);
  208.    StorageUnitSetValue(su, ev, sizeof(ODBoolean), (ODValue)&value);
  209. }
  210.  
  211. //==============================================================================
  212. // Short
  213. //==============================================================================
  214.  
  215. WIN32_DLLEXPORT ODUShort        ODGetUShortProp(Environment* ev,
  216.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  217. {
  218.    if (ODSUExistsThenFocus(ev, su, prop, val))
  219.    {
  220.       ODUShort value;
  221.       StorageUnitGetValue(su, ev, kODUShortLen, (ODValue)&value);
  222.       return ConvertODUShortFromStd(value);
  223.    }
  224.    else {
  225.       WARNMSG_DEBUG(WARN_INDEX(-1),"No UShort Property.");
  226.       return 0;
  227.    }
  228. }
  229.  
  230. WIN32_DLLEXPORT void            ODSetUShortProp(Environment* ev,
  231.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  232.             ODUShort value)
  233. {
  234.    ODSUForceFocus(ev, su, prop, val);
  235.    value = ConvertODUShortToStd(value);
  236.    StorageUnitSetValue(su, ev, kODUShortLen, (ODValue)&value);
  237. }
  238.  
  239.  
  240. WIN32_DLLEXPORT ODSShort        ODGetSShortProp(Environment* ev,
  241.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  242. {
  243.    if (ODSUExistsThenFocus(ev, su, prop, val))
  244.    {
  245.       ODSShort value;
  246.       StorageUnitGetValue(su, ev, kODSShortLen, (ODValue)&value);
  247.       return ConvertODSShortFromStd(value);
  248.    }
  249.    else {
  250.       WARNMSG_DEBUG(WARN_INDEX(-1),"No SShort Property.");
  251.       return 0;
  252.    }
  253. }
  254.  
  255. WIN32_DLLEXPORT void            ODSetSShortProp(Environment* ev,
  256.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  257.             ODSShort value)
  258. {
  259.    ODSUForceFocus(ev, su, prop, val);
  260.    value = ConvertODSShortToStd(value);
  261.    StorageUnitSetValue(su, ev, kODSShortLen, (ODValue)&value);
  262. }
  263.  
  264.  
  265. //==============================================================================
  266. // Long
  267. //==============================================================================
  268.  
  269. WIN32_DLLEXPORT ODULong         ODGetULongProp(Environment* ev,
  270.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  271. {
  272.    if (ODSUExistsThenFocus(ev, su, prop, val))
  273.    {
  274.       ODULong value;
  275.       StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&value);
  276.       return ConvertODULongFromStd(value);
  277.    }
  278.    else {
  279.       //WARN("No ULong Property.");  // This is EXPECTED in many uses of ODGetULongProp, so this makes sense.
  280.       return 0;
  281.    }
  282. }
  283.  
  284. WIN32_DLLEXPORT void            ODSetULongProp(Environment* ev,
  285.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  286.             ODULong value)
  287. {
  288.    ODSUForceFocus(ev, su, prop, val);
  289.    value = ConvertODULongToStd(value);
  290.    StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&value);
  291. }
  292.  
  293.  
  294. WIN32_DLLEXPORT ODSLong         ODGetSLongProp(Environment* ev,
  295.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  296. {
  297.    if (ODSUExistsThenFocus(ev, su, prop, val))
  298.    {
  299.       ODSLong value;
  300.       StorageUnitGetValue(su, ev, kODSLongLen, (ODValue)&value);
  301.       return ConvertODSLongFromStd(value);
  302.    }
  303.    else {
  304.       WARNMSG_DEBUG(WARN_INDEX(-1),"No SLong Property.");
  305.       return 0;
  306.    }
  307. }
  308.  
  309. WIN32_DLLEXPORT void            ODSetSLongProp(Environment* ev,
  310.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  311.             ODSLong value)
  312. {
  313.    ODSUForceFocus(ev, su, prop, val);
  314.    value = ConvertODSLongToStd(value);
  315.    StorageUnitSetValue(su, ev, kODSLongLen, (ODValue)&value);
  316. }
  317.  
  318.  
  319. //==============================================================================
  320. // ISOStr
  321. //==============================================================================
  322.  
  323. // In: The size parameter is the length of the longest ISOStr which can be written
  324. // to the 'value' buffer.  This does not include the '\0' which is written to the buffer
  325. // at the end.
  326. // In other words, at most (*size)+1 bytes can be written to 'value' by ODGetISOStrProp.
  327. // If the value parameter is NULL, then an ISOStr is allocated and for you and returned.
  328. // Out: The size parameter is the length of the ISOStr which was read in.
  329. // If there is no value at the passed in prop & val then kODNULL is returned.
  330. // This is consistent with the other routines in StdTypIO which return pointers.
  331. // The reason is that there are clients of ODGetISOStrProp which more easily handle the
  332. // flow of control if it just returns kODNULL instead of THROWing. -Tantek
  333. // One such client: ODGetKindFromPartSU in InfoUtil.
  334.  
  335. WIN32_DLLEXPORT ODISOStr        ODGetISOStrProp(Environment* ev,
  336.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  337.             ODISOStr value, ODULong* size)
  338. {
  339.    if (ODSUExistsThenFocus(ev, su, prop, val))
  340.    {
  341.       ODULong valueSize = su->GetSize(ev);
  342.       if (valueSize == 0)
  343.          valueSize++;    /* just to be absolutely safe */
  344.       if (!value)
  345.       {
  346.          value = (ODISOStr)ODNewPtr(valueSize);
  347.       }
  348.       else
  349.       {
  350.          if (size!=kODNULL && valueSize > *size)
  351.             valueSize = *size;
  352.       }
  353.       ODULong length = valueSize - 1;
  354.       StorageUnitGetValue(su, ev, length, (ODValue)value);
  355.       value[length] = '\0';
  356.       if (size!=kODNULL)
  357.          *size = length;
  358.       return value;
  359.    }
  360.    else
  361.    {
  362.       if (size!=kODNULL)
  363.          *size = 0;
  364.       return kODNULL;
  365.    }
  366. }
  367.  
  368. WIN32_DLLEXPORT void            ODSetISOStrProp(Environment* ev,
  369.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  370.             ODISOStr value)
  371. {
  372.    ODSUForceFocus(ev, su, prop, val);
  373.    ODULong oldsize = su->GetSize(ev);
  374.    ODULong newsize = strlen(value)+1;
  375.    StorageUnitSetValue(su, ev, newsize, (ODValue)value);
  376.    if (oldsize > newsize)
  377.       su->DeleteValue(ev, oldsize - newsize);
  378. }
  379.  
  380.  
  381. //==============================================================================
  382. // TypeList
  383. //==============================================================================
  384. //
  385. // Aan ODTypeList property value containing n elements begins with (n+1) offsets,
  386. // followed by n ISO strings with their null termination.  The first n offsets
  387. // identify the starting positions of the corresponding ISO string.  The last
  388. // offset is always equal to the size of the value, and is immediately before
  389. // the first character of the first ISO string (its actually redundant)
  390. // For example, a property value representing an empty ODTypeList will be
  391. // four bytes long and contain offset four, signifying that there are no ISO
  392. // strings present.
  393.  
  394. WIN32_DLLEXPORT void ODGetTypeListProp(Environment* ev,
  395.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  396.             ODTypeList* typeList)
  397. {
  398.    // If an error is thrown, typeList may be partially updated.
  399.  
  400.    if ( ODSUExistsThenFocus(ev, su, prop, val) )
  401.    {
  402.       ODULong valueSize = su->GetSize(ev);
  403.       if ( valueSize >= kODULongLen )
  404.       {
  405.          ODULong index = 0;
  406.          ODULong offset;
  407.          ODULong nextOffset;
  408.  
  409.          su->SetOffset(ev, 0);
  410.          StorageUnitGetValue(su, ev, kODULongLen, (ODValue) &offset);
  411.  
  412.          while ( offset < valueSize )
  413.          {
  414.             su->SetOffset(ev, (index+1)*kODULongLen);
  415.             StorageUnitGetValue(su, ev, kODULongLen, (ODValue) &nextOffset);
  416.  
  417.             su->SetOffset(ev, offset);
  418.  
  419.             TempODType kind = (ODType) ODNewPtr(nextOffset-offset);;
  420.  
  421.             StorageUnitGetValue(su, ev, nextOffset-offset, (ODValue) kind);
  422.             typeList->AddLast(ev, kind);
  423.  
  424.             offset = nextOffset;
  425.             ++index;
  426.          }
  427.       }
  428.    }
  429.    else
  430.    {
  431.       WARNMSG_DEBUG(WARN_INDEX(-1),"No TypeList Property.");
  432.    }
  433. }
  434.  
  435. WIN32_DLLEXPORT void ODSetTypeListProp(Environment* ev,
  436.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  437.             ODTypeList* typeList)
  438. {
  439.    // If an error is thrown, the property value will be truncated to zero length.
  440.  
  441.    ODSUForceFocus(ev, su, prop, val);
  442.    ODULong oldsize = su->GetSize(ev);
  443.  
  444.    ODType kind = kODNULL;
  445.    ODULong index = 0;
  446.    ODULong offset = (typeList->Count(ev)+1)*kODULongLen;
  447.  
  448.    try {
  449.  
  450.       // Write the offset to the first Type value and placeholders for
  451.       // the remaining offsets to be written later
  452.       su->SetOffset(ev, 0);
  453.       while ( su->GetSize(ev) < offset )
  454.          StorageUnitSetValue(su, ev, kODULongLen, (ODValue) &offset);
  455.  
  456.       for( TempODTypeListIterator iter(ev,typeList); iter; iter.Next() )
  457.       {
  458.          kind = iter.Current();
  459.          su->SetOffset(ev, offset);
  460.          ODULong size = strlen(kind)+1;
  461.  
  462.          StorageUnitSetValue(su, ev, size, (ODValue) kind);
  463.          offset += size;
  464.          ++index;
  465.          su->SetOffset(ev, index*kODULongLen);
  466.          StorageUnitSetValue(su, ev, kODULongLen, (ODValue) &offset);
  467.  
  468.          ODDisposePtr(kind);
  469.       }
  470.  
  471.    } catch (ODException _exception) {
  472.  
  473.       ODDisposePtr(kind);
  474.       su->SetOffset(ev, 0);
  475.       su->DeleteValue(ev, oldsize);
  476.       throw;
  477.  
  478.    }
  479.  
  480.    if (oldsize > offset)
  481.    {
  482.       su->SetOffset(ev, offset);
  483.       su->DeleteValue(ev, oldsize - offset);
  484.    }
  485. }
  486.  
  487. //==============================================================================
  488. // IText
  489. //==============================================================================
  490.  
  491.  
  492. // TABLE ONLY HANDLES MACINTOSH EXTENDED CHARACTER SET FOR THE MacRoman SCRIPT,
  493. //      THE langEngligh LANGUAGE, AND A "NORMAL" FONT (I.E. NOT THE "SYMBOL" FONT
  494. //      OR A DINGBAT FONT). PROBABLY VALID FOR OTHER LANGUAGES AS WELL. - NP
  495.  
  496. // NOTE THAT MAC CHARACTERS 0x0000 - 0x007F ARE MAPPED THE SAME UNICODE
  497. //      CHARACTERS. DIFFERENCES APPEAR FROM 0x0080 - 0x00FF
  498.  
  499. ODUShort MacToUniTable[256] =
  500. {
  501. /* 0x0000 */  0x0000,
  502. /* 0x0001 */  0x0001,
  503. /* 0x0002 */  0x0002,
  504. /* 0x0003 */  0x0003,
  505. /* 0x0004 */  0x0004,
  506. /* 0x0005 */  0x0005,
  507. /* 0x0006 */  0x0006,
  508. /* 0x0007 */  0x0007,
  509. /* 0x0008 */  0x0008,
  510. /* 0x0009 */  0x0009,
  511. /* 0x000A */  0x000A,
  512. /* 0x000B */  0x000B,
  513. /* 0x000C */  0x000C,
  514. /* 0x000D */  0x000D,
  515. /* 0x000E */  0x000E,
  516. /* 0x000F */  0x000F,
  517. /* 0x0010 */  0x0010,
  518. /* 0x0011 */  0x0011,
  519. /* 0x0012 */  0x0012,
  520. /* 0x0013 */  0x0013,
  521. /* 0x0014 */  0x0014,
  522. /* 0x0015 */  0x0015,
  523. /* 0x0016 */  0x0016,
  524. /* 0x0017 */  0x0017,
  525. /* 0x0018 */  0x0018,
  526. /* 0x0019 */  0x0019,
  527. /* 0x001A */  0x001A,
  528. /* 0x001B */  0x001B,
  529. /* 0x001C */  0x001C,
  530. /* 0x001D */  0x001D,
  531. /* 0x001E */  0x001E,
  532. /* 0x001F */  0x001F,
  533. /* 0x0020 ' ' */  ' ',
  534. /* 0x0021 '!' */  '!',
  535. /* 0x0022 '"' */  '"',
  536. /* 0x0023 '#' */  '#',
  537. /* 0x0024 '$' */  '$',
  538. /* 0x0025 '%' */  '%',
  539. /* 0x0026 '&' */  '&',
  540. /* 0x0027 '\'' */  '\'',
  541. /* 0x0028 '(' */  '(',
  542. /* 0x0029 ')' */  ')',
  543. /* 0x002A '*' */  '*',
  544. /* 0x002B '+' */  '+',
  545. /* 0x002C ',' */  ',',
  546. /* 0x002D '-' */  '-',
  547. /* 0x002E '.' */  '.',
  548. /* 0x002F '/' */  '/',
  549. /* 0x0030 '0' */  '0',
  550. /* 0x0031 '1' */  '1',
  551. /* 0x0032 '2' */  '2',
  552. /* 0x0033 '3' */  '3',
  553. /* 0x0034 '4' */  '4',
  554. /* 0x0035 '5' */  '5',
  555. /* 0x0036 '6' */  '6',
  556. /* 0x0037 '7' */  '7',
  557. /* 0x0038 '8' */  '8',
  558. /* 0x0039 '9' */  '9',
  559. /* 0x003A ':' */  ':',
  560. /* 0x003B ';' */  ';',
  561. /* 0x003C '<' */  '<',
  562. /* 0x003D '=' */  '=',
  563. /* 0x003E '>' */  '>',
  564. /* 0x003F '?' */  '?',
  565. /* 0x0040 '@' */  '@',
  566. /* 0x0041 'A' */  'A',
  567. /* 0x0042 'B' */  'B',
  568. /* 0x0043 'C' */  'C',
  569. /* 0x0044 'D' */  'D',
  570. /* 0x0045 'E' */  'E',
  571. /* 0x0046 'F' */  'F',
  572. /* 0x0047 'G' */  'G',
  573. /* 0x0048 'H' */  'H',
  574. /* 0x0049 'I' */  'I',
  575. /* 0x004A 'J' */  'J',
  576. /* 0x004B 'K' */  'K',
  577. /* 0x004C 'L' */  'L',
  578. /* 0x004D 'M' */  'M',
  579. /* 0x004E 'N' */  'N',
  580. /* 0x004F 'O' */  'O',
  581. /* 0x0050 'P' */  'P',
  582. /* 0x0051 'Q' */  'Q',
  583. /* 0x0052 'R' */  'R',
  584. /* 0x0053 'S' */  'S',
  585. /* 0x0054 'T' */  'T',
  586. /* 0x0055 'U' */  'U',
  587. /* 0x0056 'V' */  'V',
  588. /* 0x0057 'W' */  'W',
  589. /* 0x0058 'X' */  'X',
  590. /* 0x0059 'Y' */  'Y',
  591. /* 0x005A 'Z' */  'Z',
  592. /* 0x005B '[' */  '[',
  593. /* 0x005C '\\' */  '\\',
  594. /* 0x005D ']' */  ']',
  595. /* 0x005E '^' */  '^',
  596. /* 0x005F '_' */  '_',
  597. /* 0x0060 '`' */  '`',
  598. /* 0x0061 'a' */  'a',
  599. /* 0x0062 'b' */  'b',
  600. /* 0x0063 'c' */  'c',
  601. /* 0x0064 'd' */  'd',
  602. /* 0x0065 'e' */  'e',
  603. /* 0x0066 'f' */  'f',
  604. /* 0x0067 'g' */  'g',
  605. /* 0x0068 'h' */  'h',
  606. /* 0x0069 'i' */  'i',
  607. /* 0x006A 'j' */  'j',
  608. /* 0x006B 'k' */  'k',
  609. /* 0x006C 'l' */  'l',
  610. /* 0x006D 'm' */  'm',
  611. /* 0x006E 'n' */  'n',
  612. /* 0x006F 'o' */  'o',
  613. /* 0x0070 'p' */  'p',
  614. /* 0x0071 'q' */  'q',
  615. /* 0x0072 'r' */  'r',
  616. /* 0x0073 's' */  's',
  617. /* 0x0074 't' */  't',
  618. /* 0x0075 'u' */  'u',
  619. /* 0x0076 'v' */  'v',
  620. /* 0x0077 'w' */  'w',
  621. /* 0x0078 'x' */  'x',
  622. /* 0x0079 'y' */  'y',
  623. /* 0x007A 'z' */  'z',
  624. /* 0x007B '{' */  '{',
  625. /* 0x007C '|' */  '|',
  626. /* 0x007D '}' */  '}',
  627. /* 0x007E '~' */  '~',
  628. /* 0x007F */  0x007F,
  629.  
  630. /* 0x0080 */  0x00C4,   // LATIN CAPITAL LETTER A DIAERESIS
  631. /* 0x0081 */  0x00C5,   // LATIN CAPITAL LETTER A RING
  632. /* 0x0082 */  0x00C7,   // LATIN CAPITAL LETTER C CEDILLA
  633. /* 0x0083 */  0x00C9,   // LATIN CAPITAL LETTER E ACUTE
  634. /* 0x0084 */  0x00D1,   // LATIN CAPITAL LETTER N TILDE
  635. /* 0x0085 */  0x00D6,   // LATIN CAPITAL LETTER O DIAERESIS
  636. /* 0x0086 */  0x00DC,   // LATIN CAPITAL LETTER U DIAERESIS
  637. /* 0x0087 */  0x00E1,   // LATIN SMALL LETTER A ACUTE
  638. /* 0x0088 */  0x00E0,   // LATIN SMALL LETTER A GRAVE
  639. /* 0x0089 */  0x00E2,   // LATIN SMALL LETTER A CIRCUMFLEX
  640. /* 0x008A */  0x00E4,   // LATIN SMALL LETTER A DIAERESIS
  641. /* 0x008B */  0x00E3,   // LATIN SMALL LETTER A TILDE
  642. /* 0x008C */  0x00E5,   // LATIN SMALL LETTER A RING ABOVE
  643. /* 0x008D */  0x00E7,   // LATIN SMALL LETTER C CEDILLA
  644. /* 0x008E */  0x00E9,   // LATIN SMALL LETTER E ACUTE
  645. /* 0x008F */  0x00E8,   // LATIN SMALL LETTER E GRAVE
  646. /* 0x0090 */  0x00EA,   // LATIN SMALL LETTER E CIRCUMFLEX
  647. /* 0x0091 */  0x00EB,   // LATIN SMALL LETTER E DIAERESIS
  648. /* 0x0092 */  0x00ED,   // LATIN SMALL LETTER I ACUTE
  649. /* 0x0093 */  0x00EC,   // LATIN SMALL LETTER I GRAVE
  650. /* 0x0094 */  0x00EE,   // LATIN SMALL LETTER I CIRCUMFLEX
  651. /* 0x0095 */  0x00EF,   // LATIN SMALL LETTER I DIAERESIS
  652. /* 0x0096 */  0x00F1,   // LATIN SMALL LETTER N TILDE
  653. /* 0x0097 */  0x00F3,   // LATIN SMALL LETTER O ACUTE
  654. /* 0x0098 */  0x00F2,   // LATIN SMALL LETTER O GRAVE
  655. /* 0x0099 */  0x00F4,   // LATIN SMALL LETTER O CIRCUMFLEX
  656. /* 0x009A */  0x00F6,   // LATIN SMALL LETTER O DIAERESIS
  657. /* 0x009B */  0x00F5,   // LATIN SMALL LETTER O TILDE
  658. /* 0x009C */  0x00FA,   // LATIN SMALL LETTER U ACUTE
  659. /* 0x009D */  0x00F9,   // LATIN SMALL LETTER U GRAVE
  660. /* 0x009E */  0x00FB,   // LATIN SMALL LETTER U CIRCUMFLEX
  661. /* 0x009F */  0x00FC,   // LATIN SMALL LETTER U DIAERESIS
  662. /* 0x00A0 */  0x2020,   // DAGGER
  663. /* 0x00A1 */  0x00B0,   // DEGREE SIGN
  664. /* 0x00A2 */  0x00A2,   // CENT SIGN
  665. /* 0x00A3 */  0x00A3,   // POUND SIGN
  666. /* 0x00A4 */  0x00A7,   // SECTION SIGN
  667. /* 0x00A5 */  0x2022,   // BULLET
  668. /* 0x00A6 */  0x00B6,   // PILCROW SIGN
  669. /* 0x00A7 */  0x00DF,   // LATIN SMALL LETTER SHARP S
  670. /* 0x00A8 */  0x00AE,   // REGISTERED SIGN
  671. /* 0x00A9 */  0x00A9,   // COPYRIGHT SIGN
  672. /* 0x00AA */  0x2122,   // TRADE MARK SIGN
  673. /* 0x00AB */  0x00B4,   // ACUTE ACCENT
  674. /* 0x00AC */  0x00A8,   // DIAERESIS
  675. /* 0x00AD */  0x2260,   // NOT EQUAL TO
  676. /* 0x00AE */  0x00C6,   // LATIN CAPITAL LETTER LIGATURE A E
  677. /* 0x00AF */  0x00D8,   // LATIN CAPITAL LETTER O STROKE
  678. /* 0x00B0 */  0x221E,   // INFINITY
  679. /* 0x00B1 */  0x00B1,   // PLUS-MINUS SIGN
  680. /* 0x00B2 */  0x2264,   // LESS-THAN OR EQUAL TO
  681. /* 0x00B3 */  0x2265,   // GREATER-THAN OR EQUAL TO
  682. /* 0x00B4 */  0x00A5,   // YEN SIGN
  683. /* 0x00B5 */  0x00B5,   // MICRO SIGN
  684. /* 0x00B6 */  0x2202,   // PARTIAL DIFFERENTIAL
  685. /* 0x00B7 */  0x2211,   // N-ARY SUMMATION
  686. /* 0x00B8 */  0x220F,   // N-ARY PRODUCT
  687. /* 0x00B9 */  0x03C0,   // GREEK SMALL LETTER PI
  688. /* 0x00BA */  0x222B,   // INTEGRAL
  689. /* 0x00BB */  0x00AA,   // FEMININE ORDINAL INDICATOR
  690. /* 0x00BC */  0x00BA,   // MASCULINE ORDINAL INDICATOR
  691. /* 0x00BD */  0x2126,   // OHM SIGN
  692. /* 0x00BE */  0x00E6,   // LATIN SMALL LETTER LIGATURE A E
  693. /* 0x00BF */  0x00F8,   // LATIN SMALL LETTER O SLASH
  694. /* 0x00C0 */  0x00BF,   // INVERTED QUESTION MARK
  695. /* 0x00C1 */  0x00A1,   // INVERTED EXCLAMATION MARK
  696. /* 0x00C2 */  0x00AC,   // NOT SIGN
  697. /* 0x00C3 */  0x221A,   // SQUARE ROOT
  698. /* 0x00C4 */  0x0192,   // LATIN SMALL LETTER F HOOK
  699. /* 0x00C5 */  0x2248,   // ALMOST EQUAL TO
  700. /* 0x00C6 */  0x2206,   // INCREMENT
  701. /* 0x00C7 */  0x00AB,   // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  702. /* 0x00C8 */  0x00BB,   // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  703. /* 0x00C9 */  0x2026,   // HORIZONTAL ELLIPSIS
  704. /* 0x00CA */  0x00A0,   // NO-BREAK SPACE
  705. /* 0x00CB */  0x00C0,   // LATIN CAPITAL LETTER A GRAVE
  706. /* 0x00CC */  0x00C3,   // LATIN CAPITAL LETTER A TILDE
  707. /* 0x00CD */  0x00D5,   // LATIN CAPITAL LETTER O TILDE
  708. /* 0x00CE */  0x0152,   // LATIN CAPITAL LETTER LIGATURE O E
  709. /* 0x00CF */  0x0153,   // LATIN SMALL LETTER LIGATURE O E
  710. /* 0x00D0 */  0x2013,   // EN DASH
  711. /* 0x00D1 */  0x2014,   // EM DASH
  712. /* 0x00D2 */  0x201C,   // LEFT DOUBLE QUOTATION MARK
  713. /* 0x00D3 */  0x201D,   // RIGHT DOUBLE QUOTATION MARK
  714. /* 0x00D4 */  0x2018,   // LEFT SINGLE QUOTATION MARK
  715. /* 0x00D5 */  0x2019,   // RIGHT SINGLE QUOTATION MARK
  716. /* 0x00D6 */  0x00F7,   // DIVISION SIGN
  717. /* 0x00D7 */  0x25CA,   // LOZENGE
  718. /* 0x00D8 */  0x00FF,   // LATIN SMALL LETTER Y DIAERESIS
  719. /* 0x00D9 */  0x0178,   // LATIN CAPITAL LETTER Y DIAERESIS
  720. /* 0x00DA */  0x2044,   // FRACTION SLASH
  721. /* 0x00DB */  0x00A4,   // CURRENCY SIGN
  722. /* 0x00DC */  0x2039,   // SINGLE LEFT-POINTING ANGLE QUOTE MARK
  723. /* 0x00DD */  0x203A,   // SINGLE RIGHT-POINTING ANGLE QUOTE MARK
  724. /* 0x00DE */  0xFB01,   // LATIN SMALL LETTER LIGATURE FI
  725. /* 0x00DF */  0xFB02,   // LATIN SMALL LETTER LIGATURE FL
  726. /* 0x00E0 */  0x2021,   // DOUBLE DAGGER
  727. /* 0x00E1 */  0x00B7,   // MIDDLE DOT
  728. /* 0x00E2 */  0x201A,   // SINGLE LOW-9 QUOTATION MARK
  729. /* 0x00E3 */  0x201E,   // DOUBLE LOW-9 QUOTATION MARK
  730. /* 0x00E4 */  0x2030,   // PER MILLE SIGN
  731. /* 0x00E5 */  0x00C2,   // LATIN CAPITAL LETTER A CIRCUMFLEX
  732. /* 0x00E6 */  0x00CA,   // LATIN CAPITAL LETTER E CIRCUMFLEX
  733. /* 0x00E7 */  0x00C1,   // LATIN CAPITAL LETTER A ACUTE
  734. /* 0x00E8 */  0x00CB,   // LATIN CAPITAL LETTER E DIAERESIS
  735. /* 0x00E9 */  0x00C8,   // LATIN CAPITAL LETTER E GRAVE
  736. /* 0x00EA */  0x00CD,   // LATIN CAPITAL LETTER I ACUTE
  737. /* 0x00EB */  0x00CE,   // LATIN CAPITAL LETTER I CIRCUMFLEX
  738. /* 0x00EC */  0x00CF,   // LATIN CAPITAL LETTER I DIAERESIS
  739. /* 0x00ED */  0x00CC,   // LATIN CAPITAL LETTER I GRAVE
  740. /* 0x00EE */  0x00D3,   // LATIN CAPITAL LETTER O ACUTE
  741. /* 0x00EF */  0x00D4,   // LATIN CAPITAL LETTER O CIRCUMFLEX
  742. /* 0x00F0 */  0xF8FF,   // APPLE LOGO
  743. /* 0x00F1 */  0x00D2,   // LATIN CAPITAL LETTER O GRAVE
  744. /* 0x00F2 */  0x00DA,   // LATIN CAPITAL LETTER U ACUTE
  745. /* 0x00F3 */  0x00DB,   // LATIN CAPITAL LETTER U CIRCUMFLEX
  746. /* 0x00F4 */  0x00D9,   // LATIN CAPITAL LETTER U GRAVE
  747. /* 0x00F5 */  0x0131,   // LATIN SMALL LETTER DOTLESS I
  748. /* 0x00F6 */  0x02C6,   // MODIFIER LETTER CIRCUMFLEX ACCENT
  749. /* 0x00F7 */  0x02DC,   // SMALL TILDE
  750. /* 0x00F8 */  0x00AF,   // MACRON
  751. /* 0x00F9 */  0x02D8,   // BREVE
  752. /* 0x00FA */  0x02D9,   // DOT ABOVE
  753. /* 0x00FB */  0x02DA,   // RING ABOVE
  754. /* 0x00FC */  0x00B8,   // CEDILLA
  755. /* 0x00FD */  0x02DD,   // DOUBLE ACUTE ACCENT
  756. /* 0x00FE */  0x02DB,   // OGONEK
  757. /* 0x00FF */  0x02C7,   // CARON
  758. };
  759.  
  760. //------------------------------------------------------------------------------
  761. // TradMacTextToUnicode
  762. //
  763. //      Using mapping table, convert characters. Note, we make no attempt to handle
  764. //      double-byte characters!
  765. //
  766. //      uniCodeBufferLength is expressed in BYTES!
  767. //
  768. //      Storage will be allocated for *unicodeText with ODNewPtr.
  769. //------------------------------------------------------------------------------
  770.  
  771. void TradMacTextToUnicode(ODUByte* macText, ODULong macTextLength,
  772.                   ODUShort** unicodeText, ODULong* uniCodeBufferLength);
  773.  
  774. void TradMacTextToUnicode(ODUByte* macText, ODULong macTextLength,
  775.                   ODUShort** unicodeText, ODULong* uniCodeBufferLength)
  776. {
  777. /*
  778.  
  779. #if defined(_IBMR2) || defined(__IBMCPP__)
  780.  
  781. should be for both AIX(IBMR2) and VAC++ but AIX has some problem with
  782. passing null strings to iconv. The proper fix is to check that a null 
  783. string is not passed to iconv, but for now (10/30/96) I'll use iconv
  784. for VAC++ only.
  785.  
  786. */
  787. #if defined(__IBMCPP__)
  788.  
  789.    ODUShort*       uniCodeTextPtr;
  790.    *uniCodeBufferLength = macTextLength * 2;
  791.    *unicodeText = uniCodeTextPtr = (ODUShort*)ODNewPtr(*uniCodeBufferLength);
  792. //==========================================================================
  793.    ODUByte* macTextPtr = macText;
  794.  
  795. //==========================================================================
  796. // Query current codepage and build it to pass to converters
  797. //==========================================================================
  798.  
  799.  
  800.    char* fromcode=nl_langinfo(CODESET);
  801. //==========================================================================
  802.    const char tocode[] = "UCS-2";
  803.    iconv_t    cd;
  804.    errno = 0;  // reset the errno value
  805.    int gotCd=1; // a flag to indicate if the iconv_open got a converter descriptor.
  806.  
  807.       // *** convert to unicode
  808.       if ((iconv_t)(-1) == (cd = iconv_open(tocode, fromcode))) {
  809.  
  810.         #if defined(_PLATFORM_WIN32) || defined(_PLATFORM_AIX)
  811.           WARNMSG(WARN_INDEX(AMSG_851),"Failed to iconv_open %s to %s.\n", fromcode, tocode);
  812.         #endif
  813.           gotCd=0;
  814.           *unicodeText = NULL;   // set to null because nothing was converted
  815.           return;
  816.       }
  817.  
  818.     if (gotCd) {
  819.    /* Convert characters in array from current codepage to Unicode. */
  820.     #if defined(_PLATFORM_WIN32_)
  821.        if ((size_t)(-1) == iconv(cd, (char**)&macTextPtr, (size_t*)&macTextLength, (char**)&uniCodeTextPtr, (size_t*)uniCodeBufferLength)) {
  822.     #endif
  823.     #if defined(_PLATFORM_OS2_)
  824.        if ((size_t)(-1) == iconv(cd, (unsigned char**)&macTextPtr, (size_t*)&macTextLength, (unsigned char**)&uniCodeTextPtr, (size_t*)uniCodeBufferLength)) {
  825.     #endif
  826.     #if defined(_PLATFORM_UNIX_)
  827.        if ((size_t)(-1) == iconv(cd, (const char**)&macTextPtr, (size_t*)&macTextLength, (char**)&uniCodeTextPtr, (size_t*)uniCodeBufferLength)) {
  828.     #endif // !defined(_PLATFORM_UNIX_)
  829.            switch(errno)
  830.               {
  831.               case EILSEQ:
  832.                 WARNMSG(WARN_INDEX(AMSG_852),"iconv returned - EILSEQ: An input byte does not belong to the input codeset.\n");
  833.               case E2BIG:
  834.                 WARNMSG(WARN_INDEX(AMSG_853),"iconv returned - E2BIG: outbuf is not large enough to hold the converted value.\n");
  835.               case EINVAL:
  836.                 WARNMSG(WARN_INDEX(AMSG_854),"iconv returned - EINVAL: Incomplete character shift sequence at the end of the input buffer.\n");
  837.               case EBADF:
  838.                 WARNMSG(WARN_INDEX(AMSG_855),"iconv returned - EBADF: cd is not a valid conversion descriptor.\n");
  839.               }
  840.            WARNMSG(WARN_INDEX(AMSG_856),"Fail to convert the characters to unicode set.\n");
  841.            *unicodeText = NULL; // set to null because nothing was converted
  842.            return;
  843.        }
  844.  
  845.      //===========================================================================
  846.      // close the iconv converter
  847.      //===========================================================================
  848.        if (-1 == iconv_close(cd)) {
  849.            WARNMSG(WARN_INDEX(AMSG_857),"Fail to iconv_close.\n");
  850.            return;
  851.        }
  852.      } else {
  853.         //use the table
  854.            for (ODULong i = 0; i < macTextLength; i++)
  855.               uniCodeTextPtr[i] = MacToUniTable[macText[i]];
  856.      } /* endif */
  857.  
  858. #else //It's not AIX's Xlc and it's not VAC++
  859.    #ifdef _PLATFORM_WIN32_
  860.     ODUShort*       unicodeTextPtr;
  861.  
  862.     *uniCodeBufferLength = macTextLength * 2;
  863.     *unicodeText = unicodeTextPtr = (ODUShort*)ODNewPtr(*uniCodeBufferLength);
  864.  
  865.     UINT codePage=GetOEMCP();
  866.  
  867.     LPCSTR source = (LPCSTR)macText;
  868.     LPWSTR target = (LPWSTR)unicodeTextPtr;
  869.  
  870.     int rc=MultiByteToWideChar(
  871.       codePage,         // code page
  872.       MB_ERR_INVALID_CHARS,   // Return error if an invalid character is encountered
  873.       source,             // address of string to map
  874.       macTextLength,      // number of characters in string
  875.       target,             // address of wide-character buffer
  876.       *uniCodeBufferLength // size of buffer
  877.       );
  878.  
  879.     if (rc==0) { //failed to convert, so use the trusty table.
  880.        for (ODULong i = 0; i < macTextLength; i++)
  881.           unicodeTextPtr[i] = MacToUniTable[macText[i]];
  882.     }
  883.    #else
  884.    ODUShort*       uniCodeTextPtr;
  885.  
  886.    *uniCodeBufferLength = macTextLength * 2;
  887.    *unicodeText = uniCodeTextPtr = (ODUShort*)ODNewPtr(*uniCodeBufferLength);
  888.    for (ODULong i = 0; i < macTextLength; i++)
  889.       uniCodeTextPtr[i] = MacToUniTable[macText[i]];
  890.    #endif
  891. #endif
  892. }
  893.  
  894.  
  895. //------------------------------------------------------------------------------
  896. // UnicodeToTradMacText
  897. //
  898. //      Using mapping table, convert characters. Note, we make no attempt to handle
  899. //      most unicode characters above 0x00FF. Most will be mapped to '*'!
  900. //
  901. //      uniCodeTextLength is expressed in BYTES!
  902. //
  903. //      uniCodeTextLength must be even!
  904. //
  905. //      Storage will be allocated for *macText with ODNewPtr.
  906. //------------------------------------------------------------------------------
  907.  
  908. void UnicodeToTradMacText(ODUShort* unicodeText, ODULong uniCodeTextLength,
  909.                   ODUByte** macText, ODULong* macTextLength);
  910.  
  911.  void UnicodeToTradMacText(ODUShort* unicodeText, ODULong uniCodeTextLength,
  912.                   ODUByte** macText, ODULong* macTextLength)
  913. {
  914. #if defined(_IBMR2) || defined(__IBMCPP__)
  915.    ODUByte*        macTextPtr;
  916.    ODULong         numUnicodeChars = *macTextLength = uniCodeTextLength;
  917.    *macText = macTextPtr = (ODUByte*)ODNewPtr(numUnicodeChars);
  918.  
  919. //==========================================================================
  920. //       The following code uses VAC++ iconv utility to convert from
  921. //       Unicode to the current code page running on this OS.
  922. //==========================================================================
  923. //==========================================================================
  924. // Query current codepage and build it to pass to converters
  925. //==========================================================================
  926.  
  927.    char* tocode=nl_langinfo(CODESET);
  928. //==========================================================================
  929.    const char fromcode[] = "UCS-2";
  930.    iconv_t    cd;
  931.    char* unicodeTextPtr = (char*)unicodeText;
  932.    int gotCd=1; // a flag to indicate if the iconv_open got a converter descriptor.
  933.  
  934.    // *** open converter for code page conversion from unicode
  935.    if ((iconv_t)(-1) == (cd = iconv_open(tocode,fromcode))) {
  936.         #if defined(_PLATFORM_WIN32) || defined(_PLATFORM_AIX)
  937.           WARNMSG(WARN_INDEX(AMSG_851),"Failed to iconv_open %s to %s.\n", fromcode, tocode);
  938.         #endif
  939.           gotCd=0;
  940.           *macText = kODNULL; // set to null if error
  941.           return;
  942.    }
  943.  
  944.    /* Convert characters in array from Unicode to current codepage. */
  945.  
  946.     if (gotCd) {
  947.        #if defined(_PLATFORM_WIN32_)
  948.          if ((size_t)(-1) == iconv(cd, (char**)&unicodeTextPtr, (size_t*)&uniCodeTextLength, (char**)&macTextPtr, (size_t*)macTextLength)) {
  949.        #endif
  950.        #if defined(_PLATFORM_OS2_)
  951.          if ((size_t)(-1) == iconv(cd, (unsigned char**)&unicodeTextPtr, (size_t*)&uniCodeTextLength, (unsigned char**)&macTextPtr, (size_t*)macTextLength)) {
  952.        #endif
  953.        #if defined(_PLATFORM_UNIX_)
  954.          if ((size_t)(-1) == iconv(cd, (const char**)&unicodeTextPtr, (size_t*)&uniCodeTextLength, (char**)&macTextPtr, (size_t*)macTextLength)) {
  955.        #endif // !defined(_PLATFORM_UNIX_)
  956.            switch(errno)
  957.               {
  958.               case EILSEQ:
  959.                 WARNMSG(WARN_INDEX(AMSG_852),"iconv returned - EILSEQ: An input byte does not belong to the input codeset.\n");
  960.               case E2BIG:
  961.                 WARNMSG(WARN_INDEX(AMSG_853),"iconv returned - E2BIG: outbuf is not large enough to hold the converted value.\n");
  962.               case EINVAL:
  963.                 WARNMSG(WARN_INDEX(AMSG_854),"iconv returned - EINVAL: Incomplete character shift sequence at the end of the input buffer.\n");
  964.                case EBADF:
  965.                 WARNMSG(WARN_INDEX(AMSG_855),"iconv returned - EBADF: cd is not a valid conversion descriptor.\n");
  966.               }
  967.            WARNMSG(WARN_INDEX(AMSG_856),"Fail to convert the characters to unicode set.\n");
  968.            *macText = NULL; // set to null because nothing was converted
  969.            return;
  970.        }
  971.        *macTextPtr = '\0'; // must put the terminating NULL on the end.
  972.        *macTextLength = *macTextLength +1; // add one to Length for NULL
  973.  
  974.    //===========================================================================
  975.    // close the iconv converter
  976.    //===========================================================================
  977.        if (-1 == iconv_close(cd)) {
  978.            WARNMSG(WARN_INDEX(AMSG_857),"Fail to iconv_close.\n");
  979.           return;
  980.           }
  981.  
  982.      } else {
  983.         //use the table
  984.         for (ODULong i = 0; i < numUnicodeChars; i++)
  985.         {
  986.           // CAN MAP 0x0000 - 0x007F ONE TO ONE.
  987.           if (unicodeText[i] <= 0x007F)
  988.             macTextPtr[i] = unicodeText[i];
  989.           else // LINEAR SEARCH FOR NOW! THIS CODE SHOULD BE REPLACED - NP 1234657
  990.           {
  991.             ODBoolean       foundChar = kODFalse;
  992.  
  993.             for (int tableIndex = 0;
  994.                   tableIndex < sizeof(MacToUniTable);
  995.                   tableIndex++)
  996.             {
  997.                if (MacToUniTable[tableIndex] == unicodeText[i])
  998.                {
  999.                   macTextPtr[i] = tableIndex;
  1000.                   foundChar = kODTrue;
  1001.                   break;
  1002.                }
  1003.             }
  1004.             if (!foundChar)
  1005.                macTextPtr[i] = '*'; // SUBSITUTE ASTERISK FOR UNKNOWN UNICODE
  1006.                                                      //      CHARACTER.
  1007.           }
  1008.         } /* end for */
  1009.      } /* endif */
  1010. #else // if !defined(_IBMR2) && !defined(__IBMCPP__)
  1011.  
  1012.    ODUByte*        macTextPtr;
  1013.    ODULong         numUnicodeChars = *macTextLength = uniCodeTextLength / 2;
  1014.  
  1015.    *macText = macTextPtr = (ODUByte*)ODNewPtr(numUnicodeChars);
  1016.  
  1017. #ifdef _PLATFORM_WIN32_
  1018.  
  1019.    int rc=WideCharToMultiByte(
  1020.     CP_OEMCP,                // code page
  1021.     (DWORD)0,                // performance and mapping flags
  1022.     (LPCWSTR)unicodeText,    // address of wide-character string
  1023.     (int) uniCodeTextLength, // number of characters in string
  1024.     (LPSTR)macTextPtr,       // address of buffer for new string
  1025.     (int) *macTextLength,    // size of mbs buffer
  1026.     NULL,                    // use system default for unmappable characters
  1027.     NULL);                   // don't bother to set a flag if default char. used
  1028.  
  1029.     if (rc==0)  { //if it fails, look it up in a table.
  1030. #endif
  1031.  
  1032.  
  1033.    for (ODULong i = 0; i < numUnicodeChars; i++)
  1034.    {
  1035.       // CAN MAP 0x0000 - 0x007F ONE TO ONE.
  1036.       if (unicodeText[i] <= 0x007F)
  1037.          macTextPtr[i] = unicodeText[i];
  1038.       else // LINEAR SEARCH FOR NOW! THIS CODE SHOULD BE REPLACED - NP 1234657
  1039.       {
  1040.          ODBoolean       foundChar = kODFalse;
  1041.  
  1042.          for (int tableIndex = 0;
  1043.                tableIndex < sizeof(MacToUniTable);
  1044.                tableIndex++)
  1045.          {
  1046.             if (MacToUniTable[tableIndex] == unicodeText[i])
  1047.             {
  1048.                macTextPtr[i] = tableIndex;
  1049.                foundChar = kODTrue;
  1050.                break;
  1051.             }
  1052.          }
  1053.          if (!foundChar)
  1054.             macTextPtr[i] = '*'; // SUBSITUTE ASTERISK FOR UNKNOWN UNICODE
  1055.                                                   //      CHARACTER.
  1056.       }
  1057.    }
  1058.  
  1059. #ifdef _PLATFORM_WIN32_
  1060.   } //end of that if (rc==0).
  1061. #endif
  1062. #endif // if defined(_IBMR2) || defined(__IBMCPP__)
  1063. }
  1064.  
  1065. //------------------------------------------------------------------------------
  1066. // UnicodeToIText
  1067. //
  1068. //      IText will be filled in. If iText is kODNULL, it will be created.
  1069. //------------------------------------------------------------------------------
  1070.  
  1071. ODIText* UnicodeToIText(ODIText* iText, ODUShort* unicodeText,
  1072.                   ODULong unicodeTextLength);
  1073. ODIText* UnicodeToIText(ODIText* iText, ODUShort* unicodeText,
  1074.                   ODULong unicodeTextLength)
  1075. {
  1076.    ODUByte* text;
  1077.    ODULong  textSize;
  1078.  
  1079.    UnicodeToTradMacText(unicodeText, unicodeTextLength, &text, &textSize);
  1080.  
  1081. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1082.    if(!text)  // UnicodeToIText returns NULL if iconv fails
  1083.       return(0);  // return null
  1084. #endif
  1085.    try {
  1086.       if (iText)
  1087.       {
  1088.          ODScriptCode scriptValue;
  1089. #ifdef _PLATFORM_WIN32_
  1090. // For Windows use the special Microsoft API.
  1091.         scriptValue = GetOEMCP();
  1092. #endif
  1093.  
  1094. #ifdef _PLATFORM_MACINTOSH_
  1095. //For Mac hardcode Roman script
  1096.         scriptValue=smRoman;
  1097. #endif
  1098.  
  1099. #if defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1100. //For every one else use the standard XPG/4 API.
  1101.         char* codeset=nl_langinfo(CODESET);
  1102.  
  1103. //Convert the string to a numeric value
  1104.         char* numberPart; //The number part of the code set string.
  1105.  
  1106.            if (strstr(codeset, kIBMCodePagePrefix)) {
  1107.               numberPart=codeset+strlen(kIBMCodePagePrefix);
  1108.               scriptValue=atoi(numberPart);
  1109.            } else {
  1110.               //strstr returned null, "IBM-" is not a part of codeset.
  1111.               //use a default value.
  1112.               scriptValue=0;
  1113.            }
  1114.  
  1115. #endif
  1116.          SetITextScriptCode(iText, scriptValue);
  1117.  
  1118. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1119. // On Intel and AIX platforms code page information is all that is needed. The langcode
  1120. // is set to 0.
  1121.          SetITextLangCode(iText, 0);
  1122. #else
  1123.          SetITextLangCode(iText, langEnglish);
  1124. #endif
  1125.  
  1126.          SetITextText(iText, text, textSize);
  1127.       }
  1128.       else
  1129.          iText = CreateITextFromCharPtr((char*)text);
  1130.    } catch (ODException _exception) {
  1131.       ODDisposePtr(text);
  1132.    }
  1133.  
  1134.    ODDisposePtr(text);
  1135.  
  1136.    return iText;
  1137.  
  1138. }
  1139.  
  1140.  
  1141. const ODULong   kODUnicodeEncodingSize = 2;
  1142. const ODULong   kODUnicodeTextLengthSize = 4;
  1143.  
  1144. //------------------------------------------------------------------------------
  1145. // ODGetITextProp
  1146. //
  1147. //      If iText is kODNULL, it is allocated and passed back.
  1148. //      If not, the _buffer of the text of the iText is disposed and a new _buffer
  1149. //              is allocated and filled.
  1150. //      If there is no value at the passed in prop & val then kODNULL is returned.
  1151. //      This is consistent with the other routines in StdTypIO which return pointers.
  1152. //      The reason is that there may be clients of ODGetITextProp which more easily
  1153. //      handle the flow of control if it just returns kODNULL instead of THROWing. -Tantek
  1154. //------------------------------------------------------------------------------
  1155.  
  1156. WIN32_DLLEXPORT ODIText* ODGetITextProp(Environment* ev,
  1157.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1158.             ODIText* iText)
  1159. {
  1160.  
  1161.    // CHECK FOR EXISTENCE OF TRADITIONAL MAC TEXT FIRST.
  1162.    ODULong         macTextBufferSize = 0;
  1163.    ODBoolean       tradMacTextExists = ODSUExistsThenFocus(ev, su, prop, val);
  1164.  
  1165.    if (tradMacTextExists)
  1166.    {
  1167.       macTextBufferSize = su->GetSize(ev);
  1168.       if (macTextBufferSize == 0)     // if nothing there, treat as if doesn't exist
  1169.          tradMacTextExists = kODFalse;
  1170.       else
  1171.          macTextBufferSize -= sizeof(ODITextFormat);
  1172.          // otherwise, we need to account for the format info
  1173.       }
  1174.  
  1175.       if (tradMacTextExists) {
  1176.         ODITextFormat format;
  1177.         su->SetOffset(ev,0);
  1178.         StorageUnitGetValue(su, ev, sizeof(ODITextFormat),(ODValue)&format);
  1179.         format = ConvertODULongFromStd(format);
  1180.         if( (format != kODTraditionalMacText) &&
  1181.             (format != kODIBMCodePageText )) {
  1182.            WARNMSG_DEBUG(WARN_INDEX(-1),"Reading IText prop in unknown format %ld",format);
  1183.            // Don't throw, it's not that bad.
  1184.            // THROW(kODErrReadErr);           // Is this the best error code?
  1185.         }
  1186.  
  1187. #ifdef _UNICODE_
  1188.     unsigned short *macTextBuffer = (unsigned short *)ODNewPtr(macTextBufferSize);
  1189. #else
  1190.       octet *macTextBuffer = (octet *)ODNewPtr(macTextBufferSize);
  1191. #endif
  1192.       try { // HEY! GROPING OF THE ODITEXT GOING ON HERE! - NP
  1193.          StorageUnitGetValue(su, ev, macTextBufferSize,macTextBuffer);
  1194.          if( !iText ) {
  1195.             iText = new ODIText;
  1196.             iText->format = format;
  1197.          } else
  1198.             ODDisposePtr(iText->text._buffer);
  1199.       } catch (ODException _exception) {
  1200.          ODDisposePtr(macTextBuffer);
  1201.          throw;
  1202.       }
  1203.       iText->text._buffer = macTextBuffer;
  1204.       iText->text._length = macTextBufferSize;
  1205.       iText->text._maximum = macTextBufferSize;
  1206.  
  1207.    }
  1208.    // USE UNICODE IF TRADITIONAL MAC TEXT DOESN'T EXIST.
  1209.    else
  1210.    {
  1211.       ODBoolean       unicodeExists = ODSUExistsThenFocus(ev, su, prop,
  1212.                                                               kODIntlText);
  1213.  
  1214.       ODULong sizeOfValue = 0;
  1215.       ODULong sizeOfValueMinusHeader = 0;
  1216.       ODULong unicodeHeaderSize = kODUnicodeEncodingSize
  1217.                                                         + kODUnicodeTextLengthSize;
  1218.       if (unicodeExists)
  1219.       {
  1220.          sizeOfValue = su->GetSize(ev);
  1221.          if (sizeOfValue == 0)   // if nothing there, treat as if doesn't exist
  1222.             unicodeExists = kODFalse;
  1223.          else
  1224.             // unused for now.
  1225.             sizeOfValueMinusHeader = sizeOfValue - unicodeHeaderSize;
  1226.       }
  1227.  
  1228.       if (unicodeExists)
  1229.       {
  1230.  
  1231.          ODUShort        unicodeEncoding;
  1232.          ODULong         unicodeTextSize;
  1233.  
  1234.          su->SetOffset(ev,0);
  1235.          StorageUnitGetValue(su, ev, kODUnicodeEncodingSize,
  1236.                                             (ODValue)&unicodeEncoding);
  1237.  
  1238.  
  1239. /*    Comparing constants, doesn't make sense.
  1240.          ASSERTMSG(kODUnicodeEncodingSize == 2, kODErrAssertionFailed, "Code is broken. Assuming incorrect size passed to \"FlipEnd\" functions",0);
  1241.          ASSERTMSG(kODUnicodeTextLengthSize == 4, kODErrAssertionFailed, "Code is broken. Assuming incorrect size passed to \"FlipEnd\" functions",0);
  1242. */
  1243.          unicodeEncoding = ConvertODUShortFromStd(unicodeEncoding);
  1244.  
  1245.          if( unicodeEncoding != kODISO10646_1993BaseEncoding )
  1246.          {
  1247.             THROW(kODErrReadErr);           // Is this the best error code?
  1248.          }
  1249.  
  1250.          StorageUnitGetValue(su, ev, kODUnicodeTextLengthSize,
  1251.                                             (ODValue)&unicodeTextSize);
  1252.  
  1253.          unicodeTextSize = ConvertODULongFromStd(unicodeTextSize);
  1254.  
  1255.          octet*  uniCodeTextBuffer;
  1256.  
  1257.          try {
  1258.             uniCodeTextBuffer = (octet *)ODNewPtr(unicodeTextSize);
  1259.             StorageUnitGetValue(su, ev, unicodeTextSize, uniCodeTextBuffer);
  1260.  
  1261.             ConvertODUShortArrayFromStd((ODUShort*)uniCodeTextBuffer,
  1262.                                                      unicodeTextSize / 2);
  1263.  
  1264.             iText = UnicodeToIText(iText, (ODUShort*)uniCodeTextBuffer,
  1265.                                                   unicodeTextSize);
  1266.  
  1267. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1268.             if(!iText)  // UnicodeToIText returns NULL if iconv fails
  1269.                 return (ODIText*) 0;
  1270. #endif
  1271.          } catch (ODException _exception) {
  1272.             ODDisposePtr(uniCodeTextBuffer);
  1273.             throw;
  1274.          }
  1275.  
  1276.          ODDisposePtr(uniCodeTextBuffer);
  1277.       }
  1278.       else
  1279.       {
  1280.          // clear the iText passed in if any.
  1281.          if( iText )
  1282.             SetITextString(iText,(char*)kODNULL);
  1283.  
  1284.          // but make sure we return kODNULL to indicate the lack of a property
  1285.          iText = kODNULL;
  1286.       }
  1287.    }   //this is the other brace to if (tradMacTextExist) {
  1288.  
  1289.    return iText;
  1290. }
  1291.  
  1292. //------------------------------------------------------------------------------
  1293. // ITextToUnicode
  1294. //
  1295. //      Storage passed back must be deallocated with ODDisposePtr
  1296. //------------------------------------------------------------------------------
  1297.  
  1298. void ITextToUnicode(ODIText* iText, ODUShort** unicodeText,
  1299.                   ODULong* unicodeTextLength);
  1300. void ITextToUnicode(ODIText* iText, ODUShort** unicodeText,
  1301.                   ODULong* unicodeTextLength)
  1302. {
  1303.    TradMacTextToUnicode((ODUByte*)GetITextPtr(iText),
  1304.                                          GetITextStringLength(iText), unicodeText,
  1305.                                          unicodeTextLength);
  1306.  
  1307. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1308.    if(!*unicodeText)  // UnicodeToIText returns NULL if iconv fails
  1309.      return;
  1310. #endif
  1311. }
  1312.  
  1313. //------------------------------------------------------------------------------
  1314. // ODSetITextProp
  1315. //------------------------------------------------------------------------------
  1316.  
  1317. WIN32_DLLEXPORT void    ODSetITextProp(Environment* ev,
  1318.          ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1319.          ODIText* iText)
  1320. {
  1321.    ODSUForceFocus(ev, su, prop, val);
  1322.  
  1323.    ODULong oldsize = su->GetSize(ev);
  1324.    ODULong newsize = sizeof(ODITextFormat) + iText->text._length;
  1325.    ODITextFormat format = iText->format;
  1326.    format = ConvertODULongToStd(format);
  1327.    StorageUnitSetValue(su, ev,  sizeof(ODITextFormat),  (ODValue)&format);
  1328. #ifdef _UNICODE_
  1329.   su->SetValue(ev, (ODByteArray*)&iText->text);      // text is an ODByteArray after all
  1330. #else
  1331.    su->SetValue(ev, &iText->text);                 // text is an ODByteArray after all
  1332. #endif
  1333.    if (oldsize > newsize)
  1334.       su->DeleteValue(ev, oldsize - newsize);
  1335.  
  1336.    // WRITE OUT kODIntlText NOW TOO.
  1337. #ifdef _PLATFORM_MAC_
  1338. //On Mac Unicode converison only works for Roman script and English language.
  1339.    if (GetITextScriptCode(iText) == smRoman
  1340.       && GetITextLangCode(iText) == langEnglish)
  1341.    {
  1342. #endif
  1343.       ODSUForceFocus(ev, su, prop, kODIntlText);
  1344.       ODUShort*       unicodeText;
  1345.       ODULong         unicodeTextLength, convertTextLength;
  1346.       const ODUShort  encoding = kODISO10646_1993BaseEncoding;
  1347.       ITextToUnicode(iText, &unicodeText, &unicodeTextLength);
  1348.  
  1349. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_UNIX_)
  1350.       if(!unicodeText)  // ITextToUnicode returns NULL if iconv fails
  1351.          return;
  1352. #endif
  1353.       oldsize = su->GetSize(ev);
  1354.       newsize = kODUnicodeEncodingSize + kODUnicodeTextLengthSize
  1355.                + unicodeTextLength;
  1356.  
  1357. /* Comparing constants doesn't make sense
  1358.       ASSERTMSG(kODUnicodeEncodingSize == 2, kODErrAssertionFailed, "Code is broken. Assuming incorrect size passed to \"FlipEnd\" functions",0);
  1359.       ASSERTMSG(kODUnicodeTextLengthSize == 4, kODErrAssertionFailed, "Code is broken. Assuming incorrect size passed to \"FlipEnd\" functions",0);
  1360. */
  1361.       ConvertODUShortToStd(encoding);
  1362.       StorageUnitSetValue(su, ev, kODUnicodeEncodingSize,
  1363.                                                (ODValue)&encoding);
  1364.  
  1365.       convertTextLength = ConvertODULongToStd(unicodeTextLength);
  1366.       StorageUnitSetValue(su, ev, kODUnicodeTextLengthSize,
  1367.                                             &convertTextLength);
  1368.  
  1369.       ConvertODUShortArrayToStd(unicodeText, unicodeTextLength / 2);
  1370.       StorageUnitSetValue(su, ev, unicodeTextLength,
  1371.                                             unicodeText);
  1372.  
  1373.       ODDisposePtr(unicodeText);
  1374. #ifdef _PLATFORM_MAC_
  1375.    }
  1376. #endif
  1377. }
  1378.  
  1379. //==============================================================================
  1380. // Time_T
  1381. //==============================================================================
  1382.  
  1383. #if useGMT
  1384.  
  1385. // actually most of these can be replaced by a constant that is platform specific
  1386.  
  1387. WIN32_DLLEXPORT static ODTime   diffBtwStdAndLocalTime()
  1388. {
  1389.    MachineLocation theLocation;
  1390.    struct tm date;
  1391.    ODTime baseDate;
  1392.    ODSLong internalGMTDelta;
  1393.  
  1394.    // 1970 Jan 1 in local time
  1395.    date.tm_sec = 0;
  1396.    date.tm_min = 0;
  1397.    date.tm_hour = 0;
  1398.    date.tm_mday = 1;
  1399.    date.tm_mon = 0;
  1400.    date.tm_year = 70;
  1401.    date.tm_isdst = 0;
  1402.    baseDate = (ODTime)mktime(&date);
  1403.  
  1404.    ReadLocation(&theLocation);
  1405.  
  1406.    internalGMTDelta = theLocation.u.gmtDelta & 0x00FFFFFF;
  1407.  
  1408.    if ((internalGMTDelta >> 23) &1)
  1409.       internalGMTDelta |= 0xFF000000;
  1410.  
  1411.    return (baseDate + internalGMTDelta);
  1412. }
  1413. #endif
  1414.  
  1415. WIN32_DLLEXPORT ODTime          ODGetTime_TProp(Environment* ev,
  1416.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  1417. {
  1418.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1419.    {
  1420.       ODTime value;
  1421.       StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&value);
  1422.  
  1423. #if useGMT
  1424.       return (ConvertODULongFromStd(value) + diffBtwStdAndLocalTime());
  1425. #else
  1426.       return ConvertODULongFromStd(value);
  1427. #endif
  1428.    }
  1429.    else {
  1430.       WARNMSG_DEBUG(WARN_INDEX(-1),"No Time_T Property.");
  1431.       return 0;
  1432.    }
  1433. }
  1434.  
  1435. WIN32_DLLEXPORT void            ODSetTime_TProp(Environment* ev,
  1436.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1437.             ODTime value)
  1438. {
  1439.    ODSUForceFocus(ev, su, prop, val);
  1440.  
  1441. #if useGMT
  1442.    value = ConvertODULongToStd(value - diffBtwStdAndLocalTime());
  1443. #else
  1444.    value = ConvertODULongToStd(value);
  1445. #endif
  1446.  
  1447.    StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&value);
  1448. }
  1449.  
  1450.  
  1451. //==============================================================================
  1452. // Point
  1453. //==============================================================================
  1454.  
  1455. //      If there is no value at the passed in prop & val then kODNULL is returned.
  1456. //      This is consistent with the other routines in StdTypIO which return pointers.
  1457. //      The reason is that there may be clients of ODGetPointProp which more easily
  1458. //      handle the flow of control if it just returns kODNULL instead of THROWing. -Tantek
  1459.  
  1460. WIN32_DLLEXPORT ODPoint*        ODGetPointProp(Environment* ev,
  1461.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1462.             ODPoint* value)
  1463. {
  1464.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1465.    {
  1466.       if (!value)
  1467.          value = (ODPoint*)ODNewPtrClear(kODPointLen);
  1468.  
  1469.       StorageUnitGetValue(su, ev, sizeof(ODPoint), (ODValue) value);
  1470.  
  1471.       ConvertODSLongArrayFromStd((ODSLong*) value, sizeof(ODPoint)/sizeof(ODSLong));
  1472.  
  1473.       return value;
  1474.    }
  1475.    else {
  1476.       return kODNULL;
  1477.    }
  1478. }
  1479.  
  1480. WIN32_DLLEXPORT void            ODSetPointProp(Environment* ev,
  1481.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1482.             ODPoint* value)
  1483. {
  1484.    ODSUForceFocus(ev, su, prop, val);
  1485.  
  1486.    ODPoint tmpValue = *value;
  1487.    ConvertODSLongArrayToStd((ODULong*) &tmpValue, sizeof(ODPoint)/sizeof(ODSLong));
  1488.  
  1489.    StorageUnitSetValue(su, ev, sizeof(ODPoint), (ODValue) &tmpValue);
  1490. }
  1491.  
  1492. //==============================================================================
  1493. // Rect
  1494. //==============================================================================
  1495.  
  1496. //      If there is no value at the passed in prop & val then kODNULL is returned.
  1497. //      This is consistent with the other routines in StdTypIO which return pointers.
  1498. //      The reason is that there may be clients of ODGetRectProp which more easily
  1499. //      handle the flow of control if it just returns kODNULL instead of THROWing. -Tantek
  1500.  
  1501. WIN32_DLLEXPORT ODRect*         ODGetRectProp(Environment* ev,
  1502.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1503.             ODRect* value)
  1504. {
  1505.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1506.    {
  1507.       if (!value)
  1508.          value = (ODRect*)ODNewPtrClear(kODRectLen);
  1509.  
  1510.       StorageUnitGetValue(su, ev, sizeof(ODRect), (ODValue) value);
  1511.       ConvertODSLongArrayFromStd((ODSLong*) value, sizeof(ODRect)/sizeof(ODCoordinate));
  1512.  
  1513.       return value;
  1514.    }
  1515.    else {
  1516.       return kODNULL;
  1517.    }
  1518. }
  1519.  
  1520. WIN32_DLLEXPORT void            ODSetRectProp(Environment* ev,
  1521.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1522.             ODRect* value)
  1523. {
  1524.    ODSUForceFocus(ev, su, prop, val);
  1525.  
  1526.    ODRect tmpValue = *value;
  1527.    ConvertODSLongArrayToStd((ODULong*) &tmpValue, sizeof(ODRect)/sizeof(ODCoordinate));
  1528.  
  1529.    StorageUnitSetValue(su, ev, sizeof(ODRect), (ODValue) &tmpValue);
  1530. }
  1531.  
  1532. //==============================================================================
  1533. // StorageUnit Reference
  1534. //==============================================================================
  1535.  
  1536. WIN32_DLLEXPORT ODID            ODGetStrongSURefProp(Environment* ev,
  1537.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  1538. {
  1539.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1540.    {
  1541.       ODStorageUnitRef value;
  1542.       StorageUnitGetValue(su, ev, kODStorageUnitRefLen, (ODValue)&value);
  1543.       if ( su->IsValidStorageUnitRef(ev, value) )
  1544.          return su->GetIDFromStorageUnitRef(ev,value);
  1545.       else
  1546.          return kODNULLID;
  1547.    }
  1548.    else {
  1549.       //WARN("No StrongSURef Property.");// This is EXPECTED in many uses of ODGetStrongSURefProp, so this makes sense.
  1550.       return kODNULLID;
  1551.    }
  1552. }
  1553.  
  1554. WIN32_DLLEXPORT void            ODSetStrongSURefProp(Environment* ev,
  1555.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1556.             ODID id)
  1557. {
  1558.    ODSUForceFocus(ev, su, prop, val);
  1559.    ODStorageUnitRef value;
  1560.    su->GetStrongStorageUnitRef(ev, id, value);
  1561.    StorageUnitSetValue(su, ev, kODStorageUnitRefLen, value);
  1562. }
  1563.  
  1564.  
  1565. WIN32_DLLEXPORT ODID            ODGetWeakSURefProp(Environment* ev,
  1566.             ODStorageUnit* su, ODPropertyName prop, ODValueType val)
  1567. {
  1568.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1569.    {
  1570.       ODStorageUnitRef value;
  1571.       StorageUnitGetValue(su, ev, kODStorageUnitRefLen, (ODValue)&value);
  1572.       ODID id = kODNULLID;
  1573.       if (su->IsValidStorageUnitRef(ev, value))
  1574.          id = su->GetIDFromStorageUnitRef(ev,value);
  1575.  
  1576.       return id;
  1577.    }
  1578.    else {
  1579.       //WARN("No WeakSURef Property."); // This is EXPECTED in many uses of ODGetWeakSURefProp, so this makes sense.
  1580.       return kODNULLID;
  1581.    }
  1582. }
  1583.  
  1584. WIN32_DLLEXPORT void            ODSetWeakSURefProp(Environment* ev,
  1585.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1586.             ODID id)
  1587. {
  1588.    ODSUForceFocus(ev, su, prop, val);
  1589.    ODStorageUnitRef value;
  1590.    su->GetWeakStorageUnitRef(ev, id, value);
  1591.    StorageUnitSetValue(su, ev, kODStorageUnitRefLen, value);
  1592. }
  1593.  
  1594. //==============================================================================
  1595. // Polygon
  1596. //==============================================================================
  1597.  
  1598. //      If there is no value at the passed in prop & val then kODNULL is returned.
  1599. //      This is consistent with the other routines in StdTypIO which return pointers.
  1600. //      The reason is that there may be clients of ODGetPolygonProp which more easily
  1601. //      handle the flow of control if it just returns kODNULL instead of THROWing. -Tantek
  1602.  
  1603. WIN32_DLLEXPORT ODPolygon*      ODGetPolygonProp(Environment* ev,
  1604.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1605.             ODPolygon* value)
  1606. {
  1607.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1608.    {
  1609.       ODULong valueSize = su->GetSize(ev);
  1610.       if (value == kODNULL)
  1611.       {
  1612.          value = new ODPolygon;
  1613.       }
  1614.       // value->Realloc(valueSize); // can't because Realloc is private. Doh!
  1615.       // instead we do the following
  1616.       if (valueSize > 0)
  1617.       {
  1618.          ODPolygonData* data = (ODPolygonData*)ODNewPtr(valueSize);
  1619.          StorageUnitGetValue(su, ev, valueSize, (ODValue)data);
  1620.          ConvertODSLongArrayFromStd(data, valueSize/sizeof(ODSLong));
  1621.          value->SetData(data);
  1622.       }
  1623.       return value;
  1624.    }
  1625.    else
  1626.    {
  1627.       return kODNULL;
  1628.    }
  1629. }
  1630.  
  1631.  
  1632. WIN32_DLLEXPORT void            ODSetPolygonProp(Environment* ev,
  1633.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1634.             const ODPolygon* value)
  1635. {
  1636.    ODSUForceFocus(ev, su, prop, val);
  1637.    ODULong oldsize = su->GetSize(ev);
  1638.    ODULong newsize = value->GetDataSize();
  1639.    ODPtr buf = ODNewPtr(newsize);
  1640.    ODBlockMove(value->GetData(), buf, newsize);
  1641.    ConvertODSLongArrayToStd(buf, newsize/sizeof(ODSLong));
  1642.    StorageUnitSetValue(su, ev, newsize, (ODValue) buf);
  1643.    if (oldsize > newsize)
  1644.       su->DeleteValue(ev, oldsize - newsize);
  1645.    ODDisposePtr(buf);
  1646. }
  1647.  
  1648. //==============================================================================
  1649. // Matrix
  1650. //==============================================================================
  1651.  
  1652. //      If there is no value at the passed in prop & val then kODNULL is returned.
  1653. //      This is consistent with the other routines in StdTypIO which return pointers.
  1654. //      The reason is that there may be clients of ODGetMatrixProp which more easily
  1655. //      handle the flow of control if it just returns kODNULL instead of THROWing. -Tantek
  1656.  
  1657. WIN32_DLLEXPORT ODMatrix*       ODGetMatrixProp(Environment* ev,
  1658.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1659.             ODMatrix* value)
  1660. {
  1661.    if (ODSUExistsThenFocus(ev, su, prop, val))
  1662.    {
  1663.       if (!value)
  1664.          value = (ODMatrix*)ODNewPtrClear(sizeof(ODMatrix));
  1665.  
  1666.       StorageUnitGetValue(su, ev, sizeof(ODMatrix), (ODValue)value);
  1667.       ConvertODSLongArrayFromStd((ODSLong*) value, sizeof(ODMatrix)/sizeof(ODFixed));
  1668.  
  1669.       return value;
  1670.    }
  1671.    else
  1672.    {
  1673.       return kODNULL;
  1674.    }
  1675. }
  1676.  
  1677. WIN32_DLLEXPORT void    ODSetMatrixProp(Environment* ev,
  1678.             ODStorageUnit* su, ODPropertyName prop, ODValueType val,
  1679.             ODMatrix* value)
  1680. {
  1681.    ODSUForceFocus(ev, su, prop, val);
  1682.  
  1683.    ODMatrix tmpValue = *value;
  1684.    ConvertODSLongArrayToStd((ODULong*) &tmpValue, sizeof(ODMatrix)/sizeof(ODFixed));
  1685.  
  1686.    StorageUnitSetValue(su, ev, sizeof(ODMatrix), (ODValue) &tmpValue);
  1687. }
  1688.  
  1689. //==============================================================================
  1690. // IconFamily -- see StdIFmIO.cpp
  1691. //==============================================================================
  1692.  
  1693.