home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / e / epmmac2.zip / EPM_EA.E < prev    next >
Text File  |  1992-12-14  |  11KB  |  266 lines

  1. ; Various routines used for manipulating extended attributes.  Used by EPM.
  2.  
  3. const
  4.    EAT_ASCII    = \253\255    -- FFFD
  5.    EAT_MVMT     = \223\255    -- FFDF
  6.  
  7. ;  Returns 1 if attribute name exists; sets VAR args.  EA_SEG, EA_OFS =
  8. ; start of EA buffer.  EA_PTR1, 2 = pointers to start of entry and value,
  9. ; respectively, if name was found.  EA_LEN, EA_ENTRYLEN, EA_VALUELEN = length
  10. ; of EA area, of entry, and of value, respectively.
  11. ; Dependencies:  None
  12. defproc find_ea(name, var ea_seg, var ea_ofs, var ea_ptr1, var ea_ptr2, var ea_len, var ea_entrylen, var ea_valuelen) =
  13.    ea_long = atol(.eaarea)
  14. ;  ea_seg = itoa(rightstr(ea_long,2),10)
  15.    ea_seg = ltoa(rightstr(ea_long,2)\0\0,10)
  16. ;  ea_ofs = itoa(leftstr(ea_long,2),10)
  17.    ea_ofs = ltoa(leftstr(ea_long,2)\0\0,10)
  18.    if not .eaarea then return ''; endif
  19.    ea_len  = ltoa(peek(ea_seg, ea_ofs, 4),10)
  20.    ea_end = ea_ofs + ea_len
  21.    ea_ptr1 = ea_ofs + 4                     -- Point past length of FEAList
  22.    do while ea_ptr1 < ea_len
  23. ;     ea_flag = itoa(peek(ea_seg, ea_ptr1, 1)\0,16)
  24. compile if EVERSION < '6.00'
  25.       ea_namelen  = asc(peek(ea_seg, ea_ptr1+1, 1))
  26. ;     ea_valuelen = itoa(peek(ea_seg, ea_ptr1+2, 2),10)
  27.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+2, 2)\0\0,10)
  28.       ea_entrylen = ea_namelen + 5 + ea_valuelen
  29.       if name = peekz(ea_seg, ea_ptr1+4) then
  30.          ea_ptr2 = ea_ptr1+5+ea_namelen  -- Point to start of EA value
  31.          return 1
  32.       endif
  33. compile else
  34.       ea_namelen  = asc(peek(ea_seg, ea_ptr1+5, 1))
  35. ;     ea_valuelen = itoa(peek(ea_seg, ea_ptr1+6, 2),10)
  36.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+6, 2)\0\0,10)
  37.       ea_entrylen = ltoa(peek(ea_seg, ea_ptr1, 2)\0\0,10)
  38.       if not ea_entrylen then
  39.          ea_entrylen = ea_len - ea_ptr1
  40.       endif
  41.       if name = peekz(ea_seg, ea_ptr1+8) then
  42.          ea_ptr2 = ea_ptr1+9+ea_namelen  -- Point to start of EA value
  43.          return 1
  44.       endif
  45. compile endif
  46.       ea_ptr1 = ea_ptr1 + ea_entrylen       -- Point to start of next entry
  47.    enddo
  48.  
  49.  
  50. ; Dependencies:  None
  51. defc addea, add_ea =                 -- Adds a single name / value pair to an existing EA list
  52.    parse arg name data
  53.    if name='' then
  54.       sayerror 'ADD_EA <name> <value> adds the extended attribute value specified to the current file.'
  55.       return
  56.    endif
  57.    name_len = length(name)
  58.    data_len = length(data)
  59.    ea_len_incr = 9 + name_len + data_len
  60. compile if EVERSION >= '6.00'
  61.    ea_len_incr = ((ea_len_incr+3)%4)*4;  -- align on 32bit boundary
  62. compile endif
  63.    if .eaarea then
  64.       ea_long = atol(.eaarea)
  65. ;     ea_seg = itoa(rightstr(ea_long,2),10)
  66.       ea_seg = ltoa(rightstr(ea_long,2)\0\0,10)
  67. ;     ea_ofs = itoa(leftstr(ea_long,2),10)
  68.       ea_ofs = ltoa(leftstr(ea_long,2)\0\0,10)
  69.       ea_old_len  = ltoa(peek(ea_seg, ea_ofs, 4),10)
  70. compile if EPM32
  71.       dynalinkc(E_DLL,
  72.                 'myrealloc',
  73.                 ea_long ||
  74.                 atol(ea_old_len+ea_len_incr) ||
  75.                 atol(0),
  76.                 2)
  77.  
  78.       r = 0
  79. compile else
  80.       r =  dynalink('DOSCALLS',           -- Dynamic link library name
  81.                '#38',                     -- DosReAllocSeg
  82.                atoi(ea_old_len+ea_len_incr) ||  -- Number of bytes requested
  83.                rightstr(ea_long,2) )
  84. compile endif  -- EPM32
  85.       ea_ptr = ea_seg
  86.    else
  87. compile if EPM32
  88.       ea_buffer = atol(dynalinkc(E_DLL,
  89.                             'mymalloc',
  90.                             atol(ea_len_incr+4), 2))
  91.  
  92.       ea_ptr  = ltoa(substr(ea_buffer, 3, 2)\0\0, 10)
  93.  
  94.       r = 0
  95. compile else
  96.       ea_buffer = "00"                    -- Initialize string pointer.
  97.       r =  dynalink('DOSCALLS',           -- Dynamic link library name
  98.                '#34',                     -- DosAllocSeg
  99.                atoi(ea_len_incr+4)    ||  -- Number of bytes requested
  100.                selector(ea_buffer)    ||  -- String selector
  101.                offset(ea_buffer)      ||  -- String offset
  102.                atoi(0) )                  -- Share information
  103. ;     ea_ptr = itoa(ea_buffer,10)
  104.       ea_ptr = ltoa(ea_buffer\0\0,10)
  105. compile endif  -- EPM32
  106.       ea_ofs = 0
  107.       ea_old_len  = 4           -- Point past length field
  108.    endif
  109.  
  110.    if r then sayerror ERROR__MSG r ALLOC_HALTED__MSG; stop; endif
  111.    poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
  112.    ea_ofs = ea_ofs + ea_old_len
  113. compile if EVERSION < '6.00'
  114.    poke ea_ptr, ea_ofs  , \0              -- Start of EA:  flag byte
  115.    poke ea_ptr, ea_ofs+1, chr(name_len)
  116.    poke ea_ptr, ea_ofs+2, atoi(data_len + 4)     -- Value length = len(data) + len(data_type) + len(data_len)
  117.    poke ea_ptr, ea_ofs+4, name
  118.    poke ea_ptr, ea_ofs+4+name_len, \0     -- Null byte after name
  119.    poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
  120.    poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
  121.    poke ea_ptr, ea_ofs+9+name_len, data
  122. compile else
  123.  
  124.    -- we need to make sure the last entry is marked with zero length
  125.    --   to find the last entry, just look for
  126.    --   a bogus entry.  "\1\2\4\3\5" seems pretty unlikely.
  127.    call find_ea("\1\2\4\3\5", xx_seg, xx_ofs, xx_ptr1, xx_ptr2, xx_len, xx_entrylen, xx_valuelen);
  128.    if (xx_len>4) and xx_entrylen then
  129.       poke ea_ptr, xx_len-xx_entrylen, atol(xx_entrylen);
  130.    endif
  131.  
  132.    poke ea_ptr, ea_ofs+0, atol(0) -- Start of EA:  size (last one is always marked as zero)
  133.    poke ea_ptr, ea_ofs+4, \0              -- flag byte
  134.    poke ea_ptr, ea_ofs+5, chr(name_len)
  135.    poke ea_ptr, ea_ofs+6, atoi(data_len + 4)     -- Value length = len(data) + len(data_type) + len(data_len)
  136.    poke ea_ptr, ea_ofs+8, name
  137.    poke ea_ptr, ea_ofs+8+name_len, \0     -- Null byte after name
  138.    poke ea_ptr, ea_ofs+9+name_len, EAT_ASCII
  139.    poke ea_ptr, ea_ofs+11+name_len, atoi(data_len)
  140.    poke ea_ptr, ea_ofs+13+name_len, data
  141. compile endif
  142.    .eaarea = mpfrom2short(ea_ptr,0)
  143.  
  144.  
  145. ; Dependencies:  find_ea
  146. defproc get_EAT_ASCII_value(name) =  -- Returns the value for a given attribute name
  147.    if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  148.       stuff = peek(ea_seg, ea_ptr2, min(ea_valuelen,4))
  149.       if leftstr(stuff,2) = EAT_ASCII & ea_valuelen > 4 then
  150.          return peek(ea_seg, ea_ptr2+4, min(itoa(substr(stuff,3,2),10),MAXCOL))
  151.       endif
  152.    endif
  153.  
  154.  
  155. ; Dependencies:  find_ea()
  156. defproc delete_ea(name) =
  157.    parse arg name .
  158.    if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  159.       return
  160.    endif
  161.    newlen = ea_len - ea_entrylen
  162.    poke ea_seg, ea_ofs, atol(newlen)
  163. compile if EVERSION < '5.21'
  164.    junk = 'junk'  -- Avoid problem due to bug in MEMCPYX in EPM 5.20
  165. compile endif
  166.    if ea_ptr1+ea_entrylen < ea_len then  -- If in the middle, close it up
  167.       call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
  168.    endif
  169. compile if EPM32
  170. --   call dynalinkc('DOSCALLS',
  171. --                  '#305',                -- DosSetMem
  172. --                  atol(ea_seg\0\0) ||
  173. --                  atol(.eaarea) ||
  174. --                  atol(newlen)  ||
  175. --                  atol(19) )             -- PAG_READ | PAG_WRITE | PAG_COMMIT
  176.    call dynalinkc(E_DLL,
  177.                 'myrealloc',
  178.                 \0\0 || ea_seg ||
  179.                 atol(newlen) ||
  180.                 atol(0),
  181.                 2)
  182.  
  183.       r = 0
  184. compile else
  185.    call dynalink('DOSCALLS',           -- Dynamic link library name
  186.             '#38',                     -- DosReAllocSeg
  187.             atoi(newlen)           ||  -- Number of bytes requested
  188.             atoi(ea_seg) )
  189. compile endif  -- EPM32
  190.  
  191.  
  192. ; Dependencies:  find_ea(), delete_ea(), add_ea
  193. defc type =
  194.    found = find_ea('.TYPE', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  195.    if not found | ea_valuelen=0 then
  196.       answer = winmessagebox(TYPE_TITLE__MSG, NO_FILE_TYPE__MSG, 16388) -- YESNO + MOVEABLE
  197.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  198. ;     type = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), MAXCOL))
  199.       type = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  200.       answer = winmessagebox(TYPE_TITLE__MSG, ONE_FILE_TYPE__MSG\13 type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  201.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_MVMT then
  202. ;     ea_numentries = itoa(peek(ea_seg, ea_ptr2+4, 2),10)
  203.       ea_numentries = ltoa(peek(ea_seg, ea_ptr2+4, 2)\0\0,10)
  204.       if ea_numentries=1 then
  205.          type = ONE_FILE_TYPE__MSG
  206.       else
  207.          type = MANY_FILE_TYPES__MSG
  208.       endif
  209.       ea_entry_ofs = ea_ptr2+6
  210.       do i=1 to ea_numentries
  211. ;        ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
  212.          ea_entrylen = ltoa(peek(ea_seg, ea_entry_ofs+2, 2)\0\0,10)
  213.          if peek(ea_seg, ea_entry_ofs, 2)=EAT_ASCII then
  214.             type = type\13 || peek(ea_seg, ea_entry_ofs+4,min(ea_entrylen,MAXCOL))
  215.          else
  216.             type = type\13 || NON_ASCII__MSG
  217.          endif
  218.          ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
  219.       enddo
  220.       answer = winmessagebox(TYPE_TITLE__MSG, type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  221.    else
  222.       answer = winmessagebox(TYPE_TITLE__MSG, NON_ASCII_TYPE__MSG\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  223.    endif
  224.    if answer=6 then
  225. compile if EVERSION < 5.21
  226.       newtype = listbox(SELECT_TYPE__MSG, TYPE_LIST__MSG)
  227.       if newtype then
  228. compile else
  229.       parse value listbox(TYPE_TITLE__MSG, TYPE_LIST__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, 0, 0, 0, 0,
  230.                           atoi(1) || atoi(1) || atoi(6040) || gethwndc(APP_HANDLE) ||
  231.                           SELECT_TYPE__MSG) with button 2 newtype \0
  232.       if newtype & (button=\1) then
  233. compile endif
  234.          if found then call delete_ea('.TYPE'); endif
  235.          'add_ea .TYPE' newtype
  236.       endif
  237.    endif
  238.  
  239.  
  240. ; Dependencies:  find_ea(), delete_ea(), add_ea
  241. defc subject =
  242.    found = find_ea('.SUBJECT', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  243.    subj = ''
  244.    if not found | ea_valuelen=0 then
  245.       answer = winmessagebox(SUBJ_TITLE__MSG, NO_SUBJECT__MSG, 16388) -- YESNO + MOVEABLE
  246.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  247. ;     subj = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), MAXCOL))
  248.       subj = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  249.       answer = winmessagebox(SUBJ_TITLE__MSG, SUBJECT_IS__MSG\13 subj\13\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  250.    else
  251.       answer = winmessagebox(SUBJ_TITLE__MSG, NON_ASCII_SUBJECT__MSG\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  252.    endif
  253.    if answer=6 then
  254. compile if EVERSION < 5.21  -- The old way
  255.       newsubj = entrybox(SELECT_SUBJECT__MSG, '', subj, 40, 40)
  256.       if newsubj then
  257. compile else
  258.       parse value entrybox(SUBJ_TITLE__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, subj, 40, 40,
  259.              atoi(1) || atoi(6050) || gethwndc(APP_HANDLE) || SELECT_SUBJECT__MSG) with button 2 newsubj \0
  260.       if newsubj & (button=\1) then
  261. compile endif
  262.          if found then call delete_ea('.SUBJECT'); endif
  263.          'add_ea .SUBJECT' newsubj
  264.       endif
  265.    endif
  266.