Compare commits

..

107 Commits

Author SHA1 Message Date
hoa.nguyen%intel.com
22c40d96b2 removed the report of db filesize in GetStorageInUse.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55763 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-08 21:54:27 +00:00
hoa.nguyen%intel.com
06a79b2069 fixed a bug in SetStoredContentLength so that it will update m_StorageInUse in nsNetDiskCache.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55762 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-08 21:53:57 +00:00
hoa.nguyen%intel.com
ebc4face0d Added SetDiskCacheFolder for filecache test.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55608 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:08:45 +00:00
hoa.nguyen%intel.com
150696bb86 Fixed DB corruption detection and error recovery logic. Removed Preference. Added routine for the special entry in DB.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55606 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:07:56 +00:00
hoa.nguyen%intel.com
683045595b Added a few member according to the new nsIChannel i/f. Converted all the function to use raw file transport instead of nsIOService.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55605 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:07:21 +00:00
hoa.nguyen%intel.com
7f09538b93 Fixed a memory leak on mInfo. Init() now also pass through recordID.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55601 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:06:29 +00:00
hoa.nguyen%intel.com
bb364ef512 member name changed to follow the same convention. Added error recovery routine.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55600 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:05:57 +00:00
hoa.nguyen%intel.com
7c96c92a19 sync now happens once every second. DB filesize is only updated upon sync. A special entry is added to record initial size and entry number of filecache.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55597 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 22:04:56 +00:00
fur%netscape.com
a6defdef4c Merge portability changes and bug fixes from the trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55586 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 17:40:40 +00:00
fur%netscape.com
76159a2caf Updated to NPL 1.1
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55504 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 01:40:45 +00:00
fur%netscape.com
1988cb05b5 Tweak comments
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55499 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 01:14:55 +00:00
fur%netscape.com
dd8c6b3bed Added nsINetDataCacheManager::SetDiskCacheFolder()
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55484 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-07 00:02:58 +00:00
fur%netscape.com
bc64749366 Account for arg changes in NewChannel() API
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55475 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:30:30 +00:00
fur%netscape.com
2e9287bd58 Match NewChannel() API changes on trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55472 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:23:07 +00:00
fur%netscape.com
0f2274a140 Checkpoint
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55471 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:22:37 +00:00
fur%netscape.com
957fa10cac Retire nsINetDataCache::GetCapacity
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55469 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:16:10 +00:00
fur%netscape.com
e603146886 Track trunk API changes
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55467 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:15:32 +00:00
fur%netscape.com
cb698a0df1 + Retired nsINetDataCache::GetCapacity()
+ Fixed gcc build problem


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55466 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:14:38 +00:00
fur%netscape.com
1b918d9ef0 + Added proxy channel arg to NewChannel()
+ Changed name of setProtocolPrivate/getProtocolPrivate to setAnnotation/getAnnotation\
+ Added inUse attribute
+ Touched up comments


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55465 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:08:08 +00:00
fur%netscape.com
6407144c9f Removed capacity attribute
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55464 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:06:44 +00:00
fur%netscape.com
2ed563a178 Merge with trunk makefile.win
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@55462 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-06 23:05:39 +00:00
fur%netscape.com
4becc0b508 Add assertion to cache manager to ensure that it is limiting cache occupancy
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54566 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-29 15:23:34 +00:00
fur%netscape.com
7d5427ea31 Obey the MAX_CONTENT_LENGTH limit
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54565 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-29 15:22:56 +00:00
fur%netscape.com
99904bcc48 Eliminate libs build target, as Warren has done for the rest of the tree
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54545 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-29 02:15:04 +00:00
fur%netscape.com
bcb56c9593 Add strong ref to channel
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54544 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-29 02:14:17 +00:00
fur%netscape.com
f18bc8e6cd Fix ownership issues. Change SetProtocolData/GetProtocolData args
to match new prototype.


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54109 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 07:51:56 +00:00
fur%netscape.com
7d14c5669a Handle NULL load group - they're supposed to be optional
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54108 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 07:51:14 +00:00
fur%netscape.com
c0dd3df02e Fix tons of ref-counting ownership issues and other bug fixes
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54107 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 07:50:25 +00:00
fur%netscape.com
e5cc84978f Checkpoint
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54097 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 05:08:20 +00:00
fur%netscape.com
5694537330 Changed SetProtocolData/GetProtocolData to accept a tag argument so that
multiple cache clients can attach info to the cache database.


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54096 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 05:07:40 +00:00
fur%netscape.com
297c5ceba3 Add/modify APIs to track nsIChannel
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54095 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 05:05:01 +00:00
fur%netscape.com
e0311312f7 Temporarily disable pref-reading code, since it doesn't work in the browser
and the code that measures the size of the cache db, since it's a performance
hog.


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54094 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 05:04:13 +00:00
fur%netscape.com
cf3dc77b02 Fix unitialized variable
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@54093 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-21 05:01:03 +00:00
fur%netscape.com
dd2506a737 Quash warnings
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53842 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-18 06:19:51 +00:00
fur%netscape.com
b1bee1f21c Merge with trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53831 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-18 05:38:26 +00:00
fur%netscape.com
48ecc5625b Added review comments
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53674 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 19:46:28 +00:00
fur%netscape.com
1b791685e6 No longer need factory code. Its been moved to netwerk/cache/builds/nsNetDataCacheModule.cpp
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53663 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 18:21:11 +00:00
fur%netscape.com
dc94d1d6e2 Added review comments
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53647 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 10:08:26 +00:00
hoa.nguyen%intel.com
f5b437ade3 added Unix support
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53574 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 00:21:05 +00:00
hoa.nguyen%intel.com
8c0b4b3e4a changed NPL to MPL
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53573 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 00:16:33 +00:00
hoa.nguyen%intel.com
fb640ab144 added Truncate function
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53572 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 00:07:27 +00:00
hoa.nguyen%intel.com
106e263b33 added support for memory cache
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53570 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 00:00:54 +00:00
fur%netscape.com
85045a8552 Add TestCacheMgr
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53537 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 21:13:19 +00:00
fur%netscape.com
a2279be132 *** empty log message ***
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53536 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 21:12:58 +00:00
fur%netscape.com
0ce702d402 Don't call NS_ERROR() when a record ID is not found
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53533 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 21:12:17 +00:00
fur%netscape.com
f14d03cd67 Fixed CommitFlags()
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53531 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 21:11:14 +00:00
fur%netscape.com
b91343fdf6 Checkpoint
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53520 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 18:30:44 +00:00
fur%netscape.com
2c517489b5 Disable warning, so cache code can run
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53519 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 17:39:35 +00:00
(no author)
ae57da58eb This commit was manufactured by cvs2svn to create branch
'CacheIntegration_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53517 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 17:10:07 +00:00
fur%netscape.com
8d4586dd65 Update components table and macro instantiations to conform to new definitions
in nsIGenericFactory.h


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53499 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 09:06:41 +00:00
fur%netscape.com
9b473ad9be Added starting offset param to interceptAsyncRead() method
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53498 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 08:53:15 +00:00
fur%netscape.com
2ad227a994 Merged with trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53496 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 08:01:58 +00:00
fur%netscape.com
94d8da33c1 Replace 1.0 NPL with 1.1 version
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53487 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 06:13:13 +00:00
fur%netscape.com
81c05809fd Remove dead files
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53486 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 06:08:40 +00:00
fur%netscape.com
e30547b2b2 Remove dead files
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53485 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 05:52:29 +00:00
fur%netscape.com
257f9cfaaa Fix Boogs. Replace 1.0 NPL with 1.1 version
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53484 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-15 05:51:02 +00:00
fur%netscape.com
96e2654e43 Replace 1.0 NPL with 1.1 NPL
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53474 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-14 20:35:26 +00:00
fur%netscape.com
3b023433be Replace 1.0 NPL with 1.1 version
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53472 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-14 19:56:44 +00:00
fur%netscape.com
1b89716afe Added more comments
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53471 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-14 19:50:30 +00:00
fur%netscape.com
ad02058877 Add comments. Change method names
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53470 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-14 18:51:57 +00:00
fur%netscape.com
fa8a3196e7 Merge with trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53434 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 19:35:49 +00:00
fur%netscape.com
5c2c543e58 Fixed bugs which prevented embedded NUL characters
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53431 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 18:45:28 +00:00
fur%netscape.com
c588721cc0 Added NS_NewStorageStream().
Changed method name, Initialize ==> Init


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53430 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 18:43:20 +00:00
fur%netscape.com
0b049b17ba Fix Boogs
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53429 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 18:41:01 +00:00
fur%netscape.com
854ef4631d Merge from trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53268 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-11 22:29:20 +00:00
fur%netscape.com
051c558653 Detect failure to truncate cache entry
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53214 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-11 18:16:24 +00:00
fur%netscape.com
37a04adb09 Killed build warnings. Added stubs for unimplemented methods
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53072 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-10 06:05:33 +00:00
fur%netscape.com
c823c04b45 Combine cache components into module
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@53014 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 22:08:49 +00:00
fur%netscape.com
03cbd000eb Sync with trunk
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52998 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 17:36:48 +00:00
fur%netscape.com
a91e91a1c7 Added Windows makefiles so that the cache manager, file cache and
memory cache components are built as part of netlib and combined into
a single XPCOM module, named "nkcache.dll"


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52970 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:44:04 +00:00
fur%netscape.com
be7a5a48b6 Added call to LimitCacheSize
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52968 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:40:41 +00:00
fur%netscape.com
b2bc7468e8 Add cache manager CID
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52967 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:38:20 +00:00
fur%netscape.com
9692dfd994 Add cache manager ProgID
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52966 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:37:30 +00:00
fur%netscape.com
f3edd4cfb5 Added an owning reference from nsDiskCacheRecordChannel to
its associated nsDiskCacheRecord.  Without this, the channel
may access free'ed memory.


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52962 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:28:39 +00:00
fur%netscape.com
33403345c1 Rename class to avoid name collision with similar code in file cache.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52961 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:25:28 +00:00
fur%netscape.com
20c850de23 Merge with tip
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52960 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:23:35 +00:00
fur%netscape.com
e8b619cd02 Merge with tip
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52959 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:18:25 +00:00
fur%netscape.com
eed396bb92 Stabilize ref-count during construction
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52946 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 18:46:17 +00:00
fur%netscape.com
41d44c070b Eliminate dead files
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52932 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-07 20:19:55 +00:00
fur%netscape.com
698ba42268 Revamped directory structure
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52922 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 19:36:16 +00:00
(no author)
1a0fd23991 This commit was manufactured by cvs2svn to create branch
'CacheIntegration_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52912 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 03:43:56 +00:00
fur%netscape.com
67dded330b Add nsDiskCacheRecordChannel.cpp
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52876 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:18:26 +00:00
fur%netscape.com
936ff4777a Fix compilation errors on Win32
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52874 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:18:04 +00:00
fur%netscape.com
96c55e42f7 Accommodate API changes in nsINetDataCache
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52873 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:17:42 +00:00
fur%netscape.com
82fa0cf06a Got rid of GetReadOnly(). Added GetFlags()
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52872 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:15:05 +00:00
fur%netscape.com
98c8285334 First shot at Win32 makefile
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52869 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:03:02 +00:00
fur%netscape.com
bad4b683f4 Removed SetCapacity() method
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52868 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 22:01:26 +00:00
fur%netscape.com
cb5269a28a Checkpoint
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52864 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 21:47:25 +00:00
fur%netscape.com
74712f3635 Added binary I/O streams
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52860 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 20:02:06 +00:00
fur%netscape.com
9f8ea739db Correct error comment
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52859 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 20:01:39 +00:00
hoa.nguyen%intel.com
97a10dd7c6 Add offset writing for nsOutputStream
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52789 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 18:02:39 +00:00
hoa.nguyen%intel.com
85a132fac0 Add command line switch to test memory and disk cache.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52788 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 18:01:28 +00:00
hoa.nguyen%intel.com
e594eee877 Add proxy channel interface, and misc bug fixes.
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@52787 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 17:59:42 +00:00
hoa.nguyen%intel.com
9148eee3d6 Initial checkin of disk cache modules
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@51580 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-22 22:37:18 +00:00
hoa.nguyen%intel.com
b5989a8382 Initial checkin of disk cache module
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@51579 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-22 22:36:07 +00:00
fur%netscape.com
2b861f60d9 Create a new channel for every call to Write()
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@51335 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-21 01:35:51 +00:00
fur%netscape.com
87db050b37 Added tests for:
nsINetDataCache::GetStorageInUse()
    nsINetDataCacheRecord::SetContentLength()
    nsIOutputStream::Write(), using non-zero starting offsets


git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@51071 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-18 23:55:44 +00:00
fur%netscape.com
ffe483cf95 Initial cut at memory-cache functionality is complete
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@51067 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-18 23:46:08 +00:00
fur%netscape.com
52aa17a1c3 Incorporate nsStorageStream into xpcom.dll
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50814 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:40:42 +00:00
fur%netscape.com
5fdb3aa69e Initial implementation of 'storage stream' - used as the heart of the memory cache
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50812 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:39:45 +00:00
fur%netscape.com
8cae473bc0 Add opaque keys to nsHashtable
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50811 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:38:01 +00:00
fur%netscape.com
0719303755 Fix linkage problem
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50810 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:37:21 +00:00
fur%netscape.com
90d3e40858 Fix bugs in Next(). Prev() and IsDone()
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50809 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:36:35 +00:00
fur%netscape.com
c792b2d35c Changed IDL to generate identical C++ headers, but with better scriptability
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50808 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:32:04 +00:00
fur%netscape.com
7a4377d840 Initial cut at memory cache
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50806 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:24:06 +00:00
fur%netscape.com
a5fa416010 Added TestRawCache.cpp
git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50804 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-15 07:19:52 +00:00
(no author)
49d00db5e2 This commit was manufactured by cvs2svn to create branch
'CacheIntegration_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/CacheIntegration_BRANCH@50589 18797224-902f-48f8-a5cc-f745e15eee43
1999-10-13 10:24:13 +00:00
148 changed files with 24462 additions and 10191 deletions

View File

@@ -1,32 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = ppm png gif jpeg
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

View File

@@ -1,323 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef _GIF_H_
#define _GIF_H_
/* gif2.h
The interface for the GIF87/89a decoder.
*/
// List of possible parsing states
typedef enum {
gif_gather,
gif_init, //1
gif_type,
gif_version,
gif_global_header,
gif_global_colormap,
gif_image_start, //6
gif_image_header,
gif_image_colormap,
gif_image_body,
gif_lzw_start,
gif_lzw, //11
gif_sub_block,
gif_extension,
gif_control_extension,
gif_consume_block,
gif_skip_block,
gif_done, //17
gif_oom,
gif_error,
gif_comment_extension,
gif_application_extension,
gif_netscape_extension_block,
gif_consume_netscape_extension,
gif_consume_comment,
gif_delay,
gif_wait_for_buffer_full,
gif_stop_animating //added for animation stop
} gstate;
/* "Disposal" method indicates how the image should be handled in the
framebuffer before the subsequent image is displayed. */
typedef enum
{
DISPOSE_NOT_SPECIFIED = 0,
DISPOSE_KEEP = 1, /* Leave it in the framebuffer */
DISPOSE_OVERWRITE_BGCOLOR = 2, /* Overwrite with background color */
DISPOSE_OVERWRITE_PREVIOUS = 4 /* Save-under */
} gdispose;
/* A RGB triplet representing a single pixel in the image's colormap
(if present.) */
typedef struct _GIF_RGB
{
PRUint8 red, green, blue, pad; /* Windows requires the fourth byte &
many compilers pad it anyway. */
/* XXX: hist_count appears to be unused */
//PRUint16 hist_count; /* Histogram frequency count. */
} GIF_RGB;
/* Colormap information. */
typedef struct _GIF_ColorMap {
int32 num_colors; /* Number of colors in the colormap.
A negative value can be used to denote a
possibly non-unique set. */
GIF_RGB *map; /* Colormap colors. */
PRUint8 *index; /* NULL, if map is in index order. Otherwise
specifies the indices of the map entries. */
void *table; /* Lookup table for this colormap. Private to
the Image Library. */
} GIF_ColorMap;
/* An indexed RGB triplet. */
typedef struct _GIF_IRGB {
PRUint8 index;
PRUint8 red, green, blue;
} GIF_IRGB;
/* A GIF decoder's state */
typedef struct gif_struct {
void* clientptr;
/* Callbacks for this decoder instance*/
int (PR_CALLBACK *GIFCallback_NewPixmap)();
int (PR_CALLBACK *GIFCallback_BeginGIF)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aLogicalScreenBackgroundRGBIndex);
int (PR_CALLBACK* GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount);
int (PR_CALLBACK* GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey);
int (PR_CALLBACK* GIFCallback_EndImageFrame)(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout);
int (PR_CALLBACK* GIFCallback_SetupColorspaceConverter)();
int (PR_CALLBACK* GIFCallback_ResetPalette)();
int (PR_CALLBACK* GIFCallback_InitTransparentPixel)();
int (PR_CALLBACK* GIFCallback_DestroyTransparentPixel)();
int (PR_CALLBACK* GIFCallback_HaveDecodedRow)(
void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */
int aRow, /* Row number? */
int aDuplicateCount, /* Number of times to duplicate the row? */
PRUint8 aDrawMode, /* il_draw_mode */
int aInterlacePass);
int (PR_CALLBACK *GIFCallback_HaveImageAll)(
void* aClientData);
/* Parsing state machine */
gstate state; /* Curent decoder master state */
PRUint8 *hold; /* Accumulation buffer */
int32 hold_size; /* Capacity, in bytes, of accumulation buffer */
PRUint8 *gather_head; /* Next byte to read in accumulation buffer */
int32 gather_request_size; /* Number of bytes to accumulate */
int32 gathered; /* bytes accumulated so far*/
gstate post_gather_state; /* State after requested bytes accumulated */
int32 requested_buffer_fullness; /* For netscape application extension */
/* LZW decoder state machine */
PRUint8 *stack; /* Base of decoder stack */
PRUint8 *stackp; /* Current stack pointer */
PRUint16 *prefix;
PRUint8 *suffix;
int datasize;
int codesize;
int codemask;
int clear_code; /* Codeword used to trigger dictionary reset */
int avail; /* Index of next available slot in dictionary */
int oldcode;
PRUint8 firstchar;
int count; /* Remaining # bytes in sub-block */
int bits; /* Number of unread bits in "datum" */
int32 datum; /* 32-bit input buffer */
/* Output state machine */
int ipass; /* Interlace pass; Ranges 1-4 if interlaced. */
PRUintn rows_remaining; /* Rows remaining to be output */
PRUintn irow; /* Current output row, starting at zero */
PRUint8 *rgbrow; /* Temporary storage for dithering/mapping */
PRUint8 *rowbuf; /* Single scanline temporary buffer */
PRUint8 *rowend; /* Pointer to end of rowbuf */
PRUint8 *rowp; /* Current output pointer */
/* Parameters for image frame currently being decoded*/
PRUintn x_offset, y_offset; /* With respect to "screen" origin */
PRUintn height, width;
PRUintn last_x_offset, last_y_offset; /* With respect to "screen" origin */
PRUintn last_height, last_width;
int interlaced; /* TRUE, if scanlines arrive interlaced order */
int tpixel; /* Index of transparent pixel */
GIF_IRGB* transparent_pixel;
int is_transparent; /* TRUE, if tpixel is valid */
int control_extension; /* TRUE, if image control extension present */
int is_local_colormap_defined;
gdispose disposal_method; /* Restore to background, leave in place, etc.*/
gdispose last_disposal_method;
GIF_RGB *local_colormap; /* Per-image colormap */
int local_colormap_size; /* Size of local colormap array. */
PRUint32 delay_time; /* Display time, in milliseconds,
for this image in a multi-image GIF */
/* Global (multi-image) state */
int screen_bgcolor; /* Logical screen background color */
int version; /* Either 89 for GIF89 or 87 for GIF87 */
PRUintn screen_width; /* Logical screen width & height */
PRUintn screen_height;
GIF_RGB *global_colormap; /* Default colormap if local not supplied */
int global_colormap_size; /* Size of global colormap array. */
int images_decoded; /* Counts images for multi-part GIFs */
int destroy_pending; /* Stream has ended */
int progressive_display; /* If TRUE, do Haeberli interlace hack */
int loop_count; /* Netscape specific extension block to control
the number of animation loops a GIF renders. */
} gif_struct;
/* Create a new gif_struct */
extern PRBool gif_create(gif_struct **gs);
/* These are the APIs that the client calls to intialize,
push data to, and shut down the GIF decoder. */
PRBool GIFInit(
gif_struct* gs,
void* aClientData,
int (*PR_CALLBACK GIFCallback_NewPixmap)(),
int (*PR_CALLBACK GIFCallback_BeginGIF)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex),
int (*PR_CALLBACK GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount),
int (*PR_CALLBACK GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey),
int (*PR_CALLBACK GIFCallback_EndImageFrame)(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout),
int (*PR_CALLBACK GIFCallback_SetupColorspaceConverter)(),
int (*PR_CALLBACK GIFCallback_ResetPalette)(),
int (*PR_CALLBACK GIFCallback_InitTransparentPixel)(),
int (*PR_CALLBACK GIFCallback_DestroyTransparentPixel)(),
int (*PR_CALLBACK GIFCallback_HaveDecodedRow)(
void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */
int aRow, /* Row number? */
int aDuplicateCount, /* Number of times to duplicate the row? */
PRUint8 aDrawMode, /* il_draw_mode */
int aInterlacePass),
int (*PR_CALLBACK GIFCallback_HaveImageAll)(
void* aClientData)
);
extern void gif_destroy(gif_struct* aGIFStruct);
int gif_write(gif_struct* aGIFStruct, const PRUint8 * buf, PRUint32 numbytes);
PRUint8 gif_write_ready(gif_struct* aGIFStruct);
extern void gif_complete(gif_struct** aGIFStruct);
extern void gif_delay_time_callback(/* void *closure */);
/* Callback functions that the client must implement and pass in
pointers for during the GIFInit call. These will be called back
when the decoder has a decoded rows, frame size information, etc.*/
/* GIFCallback_LogicalScreenSize is called only once to notify the client
of the logical screen size, which will be the size of the total image. */
typedef int (*PR_CALLBACK BEGINGIF_CALLBACK)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aLogicalScreenBackgroundRGBIndex);
typedef int (PR_CALLBACK *GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount);
/* GIFCallback_BeginImageFrame is called at the beginning of each frame of
a GIF.*/
typedef int (PR_CALLBACK *GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFraqeYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight);
extern int GIFCallback_EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout); /* Time in milliseconds this frame should be displayed before the next frame.
This information appears in a sub control block, so we don't
transmit it back to the client until we're done with the frame. */
/*
extern int GIFCallback_SetupColorspaceConverter();
extern int GIFCallback_ResetPalette();
extern int GIFCallback_InitTransparentPixel();
extern int GIFCallback_DestroyTransparentPixel();
*/
extern int GIFCallback_HaveDecodedRow();
extern int GIFCallback_HaveImageAll();
#endif

View File

@@ -1,42 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imggif
LIBRARY_NAME = imggif
IS_COMPONENT = 1
REQUIRES = xpcom necko layout gfx2 imglib2
CPPSRCS = GIF2.cpp nsGIFDecoder2.cpp nsGIFModule.cpp
EXTRA_DSO_LDOPTS = $(GIF_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,52 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imggif
LIBRARY_NAME = imggif
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsGIFDecoder2.obj \
.\$(OBJDIR)\GIF2.obj \
.\$(OBJDIR)\nsGIFModule.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,506 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*/
#include "nsGIFDecoder2.h"
#include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "nsIImage.h"
#include "nsMemory.h"
#include "imgIContainerObserver.h"
#include "nsRect.h"
//////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation
// This is an adaptor between GIF2 and imgIDecoder
NS_IMPL_ISUPPORTS2(nsGIFDecoder2, imgIDecoder, nsIOutputStream);
nsGIFDecoder2::nsGIFDecoder2()
{
NS_INIT_ISUPPORTS();
mImageFrame = nsnull;
mGIFStruct = nsnull;
mAlphaLine = nsnull;
}
nsGIFDecoder2::~nsGIFDecoder2(void)
{
if (mAlphaLine)
nsMemory::Free(mAlphaLine);
if (mGIFStruct) {
gif_destroy(mGIFStruct);
mGIFStruct = nsnull;
}
}
//******************************************************************************
/** imgIDecoder methods **/
//******************************************************************************
//******************************************************************************
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsGIFDecoder2::Init(imgIRequest *aRequest)
{
mImageRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImageContainer));
/* do gif init stuff */
/* Always decode to 24 bit pixdepth */
PRBool created = gif_create(&mGIFStruct);
NS_ASSERTION(created, "gif_create failed");
// Call GIF decoder init routine
GIFInit(
mGIFStruct,
this,
NewPixmap,
BeginGIF,
EndGIF,
BeginImageFrame,
EndImageFrame,
SetupColorspaceConverter,
ResetPalette,
InitTransparentPixel,
DestroyTransparentPixel,
HaveDecodedRow,
HaveImageAll);
return NS_OK;
}
//******************************************************************************
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsGIFDecoder2::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mImageRequest;
NS_IF_ADDREF(*aRequest);
return NS_OK;
}
//******************************************************************************
/** nsIOutputStream methods **/
//******************************************************************************
//******************************************************************************
/* void close (); */
NS_IMETHODIMP nsGIFDecoder2::Close()
{
if (mGIFStruct) {
gif_destroy(mGIFStruct);
mGIFStruct = nsnull;
}
return NS_OK;
}
//******************************************************************************
/* void flush (); */
NS_IMETHODIMP nsGIFDecoder2::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* static callback from nsIInputStream::ReadSegments */
static NS_METHOD ReadDataOut(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, closure);
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
return NS_OK;
}
//******************************************************************************
PRUint32 nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count)
{
// Push the data to the GIF decoder
// First we ask if the gif decoder is ready for more data, and if so, push it.
// In the new decoder, we should always be able to process more data since
// we don't wait to decode each frame in an animation now.
if(gif_write_ready(mGIFStruct)) {
gif_write(mGIFStruct, data, count);
}
return count; // we always consume all the data
}
//******************************************************************************
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
inStr->ReadSegments(
ReadDataOut, // Callback
this,
count,
_retval);
// if error
//mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
return NS_OK;
}
//******************************************************************************
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsGIFDecoder2::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
NS_IMETHODIMP nsGIFDecoder2::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsGIFDecoder2::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
NS_IMETHODIMP nsGIFDecoder2::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
// GIF decoder callback methods. Part of pulic API for GIF2
//******************************************************************************
//******************************************************************************
int BeginGIF(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex)
{
// copy GIF info into imagelib structs
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
if (decoder->mObserver)
decoder->mObserver->OnStartDecode(nsnull, nsnull);
decoder->mImageContainer->Init(aLogicalScreenWidth, aLogicalScreenHeight, decoder->mObserver);
if (decoder->mObserver)
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImageContainer);
return 0;
}
//******************************************************************************
int EndGIF(
void* aClientData,
int aAnimationLoopCount)
{
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
if (decoder->mObserver) {
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImageContainer);
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
decoder->mImageContainer->SetLoopCount(aAnimationLoopCount);
decoder->mImageContainer->DecodingComplete();
return 0;
}
//******************************************************************************
int BeginImageFrame(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey) /* don't have this info yet */
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
decoder->mImageFrame = nsnull; // clear out our current frame reference
decoder->mGIFStruct->x_offset = aFrameXOffset;
decoder->mGIFStruct->y_offset = aFrameYOffset;
decoder->mGIFStruct->width = aFrameWidth;
decoder->mGIFStruct->height = aFrameHeight;
return 0;
}
//******************************************************************************
int EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout) /* Time this frame should be displayed before the next frame
we can't have this in the image frame init because it doesn't
show up in the GIF frame header, it shows up in a sub control
block.*/
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
// We actually have the timeout information before we get the lzw encoded image
// data, at least according to the spec, but we delay in setting the timeout for
// the image until here to help ensure that we have the whole image frame decoded before
// we go off and try to display another frame.
// XXXXXXXX
// decoder->mImageFrame->SetTimeout(aDelayTimeout);
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);
if (decoder->mObserver)
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mImageFrame);
decoder->mImageFrame = nsnull;
return 0;
}
//******************************************************************************
// GIF decoder callback
int HaveImageAll(
void* aClientData)
{
return 0;
}
//******************************************************************************
// GIF decoder callback notification that it has decoded a row
int HaveDecodedRow(
void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row?
int aRowNumber, // Row number?
int aDuplicateCount, // Number of times to duplicate the row?
PRUint8 aDrawMode, // il_draw_mode
int aInterlacePass) // interlace pass (1-4)
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
PRUint32 bpr, abpr;
// We have to delay allocation of the image frame until now because
// we won't have control block info (transparency) until now. The conrol
// block of a GIF stream shows up after the image header since transparency
// is added in GIF89a and control blocks are how the extensions are done.
// How annoying.
if(! decoder->mImageFrame) {
gfx_format format = gfxIFormats::RGB;
if (decoder->mGIFStruct->is_transparent)
format = gfxIFormats::RGB_A1;
#ifdef XP_PC
// XXX this works...
format += 1; // RGB to BGR
#endif
// initalize the frame and append it to the container
decoder->mImageFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
decoder->mImageFrame->Init(
decoder->mGIFStruct->x_offset, decoder->mGIFStruct->y_offset,
decoder->mGIFStruct->width, decoder->mGIFStruct->height, format);
decoder->mImageContainer->AppendFrame(decoder->mImageFrame);
if (decoder->mObserver)
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mImageFrame);
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
if (decoder->mAlphaLine)
nsMemory::Free(decoder->mAlphaLine);
decoder->mAlphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
}
} else {
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
}
if (aRowBufPtr) {
nscoord width;
decoder->mImageFrame->GetWidth(&width);
PRUint32 iwidth = width;
gfx_format format;
decoder->mImageFrame->GetFormat(&format);
// XXX map the data into colors
int cmapsize;
GIF_RGB* cmap;
if(decoder->mGIFStruct->local_colormap) {
cmapsize = decoder->mGIFStruct->local_colormap_size;
cmap = decoder->mGIFStruct->local_colormap;
} else {
cmapsize = decoder->mGIFStruct->global_colormap_size;
cmap = decoder->mGIFStruct->global_colormap;
}
PRUint8* rgbRowIndex = aRGBrowBufPtr;
PRUint8* rowBufIndex = aRowBufPtr;
switch (format) {
case gfxIFormats::RGB:
{
while(rowBufIndex != decoder->mGIFStruct->rowend) {
#ifdef XP_MAC
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
#endif
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
}
break;
case gfxIFormats::BGR:
{
while(rowBufIndex != decoder->mGIFStruct->rowend) {
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
}
break;
case gfxIFormats::RGB_A1:
case gfxIFormats::BGR_A1:
{
memset(aRGBrowBufPtr, 0, bpr);
memset(decoder->mAlphaLine, 0, abpr);
PRUint32 iwidth = (PRUint32)width;
for (PRUint32 x=0; x<iwidth; x++) {
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
#ifdef XP_PC
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
#else
#ifdef XP_MAC
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
#endif
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
#endif
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
} else {
#ifdef XP_MAC
rgbRowIndex+=4;
#else
rgbRowIndex+=3;
#endif
}
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine, abpr, aRowNumber*abpr);
}
break;
default:
break;
}
nsRect r(0, aRowNumber, width, 1);
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mImageFrame, &r);
}
return 0;
}
//******************************************************************************
int ResetPalette()
{
return 0;
}
//******************************************************************************
int SetupColorspaceConverter()
{
return 0;
}
//******************************************************************************
int EndImageFrame()
{
return 0;
}
//******************************************************************************
int NewPixmap()
{
return 0;
}
//******************************************************************************
int InitTransparentPixel()
{
return 0;
}
//******************************************************************************
int DestroyTransparentPixel()
{
return 0;
}

View File

@@ -1,114 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*/
#ifndef _nsGIFDecoder2_h
#define _nsGIFDecoder2_h
#include "nsCOMPtr.h"
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#include "GIF2.h"
#define NS_GIFDECODER2_CID \
{ /* 797bec5a-1dd2-11b2-a7f8-ca397e0179c4 */ \
0x797bec5a, \
0x1dd2, \
0x11b2, \
{0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \
}
//////////////////////////////////////////////////////////////////////
// nsGIFDecoder2 Definition
class nsGIFDecoder2 : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsGIFDecoder2();
virtual ~nsGIFDecoder2();
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_METHOD ProcessData(unsigned char *data, PRUint32 count);
nsCOMPtr<imgIContainer> mImageContainer;
nsCOMPtr<gfxIImageFrame> mImageFrame;
nsCOMPtr<imgIRequest> mImageRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
gif_struct *mGIFStruct;
PRUint8 *mAlphaLine;
};
// static callbacks for the GIF decoder
static int PR_CALLBACK BeginGIF(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex);
static int PR_CALLBACK HaveDecodedRow(
void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row?
int aRow, // Row number?
int aDuplicateCount, // Number of times to duplicate the row?
PRUint8 aDrawMode, // il_draw_mode
int aInterlacePass);
static int PR_CALLBACK NewPixmap();
static int PR_CALLBACK EndGIF(
void* aClientData,
int aAnimationLoopCount);
static int PR_CALLBACK BeginImageFrame(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey);
static int PR_CALLBACK EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout);
static int PR_CALLBACK SetupColorspaceConverter();
static int PR_CALLBACK ResetPalette();
static int PR_CALLBACK InitTransparentPixel();
static int PR_CALLBACK DestroyTransparentPixel();
static int PR_CALLBACK HaveImageAll(
void* aClientData);
#endif

View File

@@ -1,18 +0,0 @@
?AddRef@nsGIFDecoder2@@UAGKXZ ; 2550
?Release@nsGIFDecoder2@@UAGKXZ ; 2550
?gif_write_ready@@YAEPAUgif_struct@@@Z ; 1624
?ProcessData@nsGIFDecoder2@@QAGIPAEI@Z ; 1624
?gif_write@@YAHPAUgif_struct@@PBEI@Z ; 1624
?WriteFrom@nsGIFDecoder2@@UAGIPAVnsIInputStream@@IPAI@Z ; 1309
?Close@nsGIFDecoder2@@UAGIXZ ; 1275
??_GnsGIFDecoder2@@UAEPAXI@Z ; 1275
??0nsGIFDecoder2@@QAE@XZ ; 1275
??1nsGIFDecoder2@@UAE@XZ ; 1275
?QueryInterface@nsGIFDecoder2@@UAGIABUnsID@@PAPAX@Z ; 1275
?GIFInit@@YAHPAUgif_struct@@PAXP6AHXZP6AH1IIE@ZP6AH1H@ZP6AH1IIIIIPAU_GIF_RGB@@@ZP6AH1II@Z2222P6AH1PAE8HHHHEH@ZP6AH1@Z@Z ; 1275
?Init@nsGIFDecoder2@@UAGIPAVimgIRequest@@@Z ; 1275
?Flush@nsGIFDecoder2@@UAGIXZ ; 1275
?gif_destroy@@YAXPAUgif_struct@@@Z ; 1275
?gif_create@@YAHPAPAUgif_struct@@@Z ; 1275
?il_BACat@@YAPADPAPADIPBDI@Z ; 698
_NSGetModule ; 1

View File

@@ -1,378 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsMimeTypes.h"
#include "nsMemory.h"
#include "nsIStringStream.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIMimeService.h"
#include "nsCExternalHandlerService.h"
#include "plstr.h"
#include <Files.h>
#include <QuickDraw.h>
// nsIconChannel methods
nsIconChannel::nsIconChannel()
{
NS_INIT_REFCNT();
mStatus = NS_OK;
}
nsIconChannel::~nsIconChannel()
{}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
nsIChannel,
nsIRequest)
nsresult nsIconChannel::Init(nsIURI* uri)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsIconChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
return rv;
}
NS_IMETHODIMP nsIconChannel::Suspend(void)
{
NS_NOTREACHED("nsIconChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::Resume(void)
{
NS_NOTREACHED("nsIconChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream **_retval)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
// get the file name from the url
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
mUrl->GetHost(getter_Copies(fileName));
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
if (url)
url->GetFileBaseName(getter_Copies(filePath));
nsresult rv = NS_OK;
nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
// extract the extension out of the dummy file so we can look it up in the mime service.
char * chFileName = fileName.get(); // get the underlying buffer
char * fileExtension = PL_strrchr(chFileName, '.');
if (!fileExtension) return NS_ERROR_FAILURE; // no file extension to work from.
// look the file extension up in the registry.
nsCOMPtr<nsIMIMEInfo> mimeInfo;
mimeService->GetFromExtension(fileExtension, getter_AddRefs(mimeInfo));
NS_ENSURE_TRUE(mimeInfo, NS_ERROR_FAILURE);
// get the mac creator and file type for this mime object
PRUint32 macType;
PRUint32 macCreator;
mimeInfo->GetMacType(&macType);
mimeInfo->GetMacCreator(&macCreator);
// get a refernce to the desktop database
DTPBRec pb;
OSErr err = noErr;
memset(&pb, 0, sizeof(DTPBRec));
pb.ioCompletion = nil;
pb.ioVRefNum = 0; // default desktop volume
pb.ioNamePtr = nil;
err = PBDTGetPath(&pb);
if (err != noErr) return NS_ERROR_FAILURE;
pb.ioFileCreator = macCreator;
pb.ioFileType = macType;
pb.ioCompletion = nil;
pb.ioTagInfo = 0;
PRUint32 numPixelsInRow = 0;
if (filePath && !nsCRT::strcmp(filePath, "large"))
{
pb.ioDTReqCount = kLarge8BitIconSize;
pb.ioIconType = kLarge8BitIcon;
numPixelsInRow = 32;
}
else
{
pb.ioDTReqCount = kSmall8BitIconSize;
pb.ioIconType = kSmall8BitIcon;
numPixelsInRow = 16;
}
// allocate a buffer large enough to handle the icon
PRUint8 * bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
pb.ioDTBuffer = (Ptr) bitmapData;
err = PBDTGetIcon(&pb, false);
if (err != noErr) return NS_ERROR_FAILURE; // unable to fetch the icon....
nsCString iconBuffer;
iconBuffer.Assign((char) numPixelsInRow);
iconBuffer.Append((char) numPixelsInRow);
CTabHandle cTabHandle = GetCTable(72);
if (!cTabHandle) return NS_ERROR_FAILURE;
HLock((Handle) cTabHandle);
CTabPtr colTable = *cTabHandle;
RGBColor rgbCol;
PRUint8 redValue, greenValue, blueValue;
for (PRUint32 index = 0; index < pb.ioDTReqCount; index ++)
{
// each byte in bitmapData needs to be converted from an 8 bit system color into
// 24 bit RGB data which our special icon image decoder can understand.
ColorSpec colSpec = colTable->ctTable[ bitmapData[index]];
rgbCol = colSpec.rgb;
redValue = rgbCol.red & 0xff;
greenValue = rgbCol.green & 0xff;
blueValue = rgbCol.blue & 0xff;
// for some reason the image code on the mac expects each RGB pixel value to be padded with a preceding byte.
// so add the padding here....
iconBuffer.Append((char) 0);
iconBuffer.Append((char) redValue);
iconBuffer.Append((char) greenValue);
iconBuffer.Append((char) blueValue);
}
HUnlock((Handle) cTabHandle);
DisposeCTable(cTabHandle);
nsMemory::Free(bitmapData);
// now that the color bitmask is taken care of, we need to do the same thing again for the transparency
// bit mask....
if (filePath && !nsCRT::strcmp(filePath, "large"))
{
pb.ioDTReqCount = kLargeIconSize;
pb.ioIconType = kLargeIcon;
}
else
{
pb.ioDTReqCount = kSmallIconSize;
pb.ioIconType = kSmallIcon;
}
// allocate a buffer large enough to handle the icon
bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
pb.ioDTBuffer = (Ptr) bitmapData;
err = PBDTGetIcon(&pb, false);
PRUint32 index = pb.ioDTReqCount/2;
while (index < pb.ioDTReqCount)
{
iconBuffer.Append((char) bitmapData[index]);
iconBuffer.Append((char) bitmapData[index + 1]);
if (numPixelsInRow == 32)
{
iconBuffer.Append((char) bitmapData[index + 2]);
iconBuffer.Append((char) bitmapData[index + 3]);
index += 4;
}
else
{
iconBuffer.Append((char) 255); // 2 bytes of padding
iconBuffer.Append((char) 255);
index += 2;
}
}
nsMemory::Free(bitmapData);
// turn our nsString into a stream looking object...
aListener->OnStartRequest(this, ctxt);
// turn our string into a stream...
nsCOMPtr<nsISupports> streamSupports;
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
{
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup("image/icon");
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsIconChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}

View File

@@ -1,56 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconChannel_h___
#define nsIconChannel_h___
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIURI.h"
class nsIconChannel : public nsIChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
nsIconChannel();
virtual ~nsIconChannel();
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIURI> mOriginalURI;
PRUint32 mLoadAttributes;
PRInt32 mContentLength;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsISupports> mOwner;
nsresult mStatus;
};
#endif /* nsIconChannel_h___ */

View File

@@ -1,62 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Scott MacGregor <mscott@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
DIR=win
MODULE = imgicon
LIBRARY_NAME = imgicon
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsIconDecoder.obj \
.\$(OBJDIR)\nsIconModule.obj \
.\$(OBJDIR)\nsIconProtocolHandler.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(DIST)\lib\imgiconwin_s.lib \
$(NULL)
WIN_LIBS= shell32.lib
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
-I$(DEPTH)\modules\libpr0n\decoders\icon\win \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,195 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*
*/
#include "nsIconDecoder.h"
#include "nsIInputStream.h"
#include "imgIContainer.h"
#include "imgIContainerObserver.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "nsRect.h"
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder);
NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder);
NS_INTERFACE_MAP_BEGIN(nsIconDecoder)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIOutputStream)
NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
NS_INTERFACE_MAP_ENTRY(imgIDecoder)
NS_INTERFACE_MAP_END_THREADSAFE
nsIconDecoder::nsIconDecoder()
{
NS_INIT_ISUPPORTS();
}
nsIconDecoder::~nsIconDecoder()
{ }
/** imgIDecoder methods **/
NS_IMETHODIMP nsIconDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
if (!mFrame) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
NS_IMETHODIMP nsIconDecoder::Close()
{
if (mObserver)
{
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
mObserver->OnStopContainer(nsnull, nsnull, mImage);
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
nsresult rv;
char *buf = (char *)PR_Malloc(count);
if (!buf) return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
// read the data from the input stram...
PRUint32 readLen;
rv = inStr->Read(buf, count, &readLen);
char *data = buf;
if (NS_FAILED(rv)) return rv;
// since WriteFrom is only called once, go ahead and fire the on start notifications..
mObserver->OnStartDecode(nsnull, nsnull);
PRUint32 i = 0;
// Read size
PRInt32 w, h;
w = data[0];
h = data[1];
data += 2;
readLen -= i + 2;
mImage->Init(w, h, mObserver);
if (mObserver)
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame->Init(0, 0, w, h, gfxIFormats::RGB_A1);
mImage->AppendFrame(mFrame);
if (mObserver)
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
PRUint32 bpr, abpr;
nscoord width, height;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->GetAlphaBytesPerRow(&abpr);
mFrame->GetWidth(&width);
mFrame->GetHeight(&height);
i = 0;
PRInt32 rownum = 0; // XXX this better not have a decimal
PRInt32 wroteLen = 0;
do
{
PRUint8 *line = (PRUint8*)data + i*bpr;
mFrame->SetImageData(line, bpr, (rownum++)*bpr);
nsRect r(0, rownum, width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
wroteLen += bpr ;
i++;
} while(rownum < height);
// now we want to send in the alpha data...
for (rownum = 0; rownum < height; rownum ++)
{
PRUint8 * line = (PRUint8*) data + abpr * rownum + height*bpr;
mFrame->SetAlphaData(line, abpr, (rownum)*abpr);
}
PR_FREEIF(buf);
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconDecoder_h__
#define nsIconDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#define NS_ICONDECODER_CID \
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \
0xffc08380, \
0x256c, \
0x11d5, \
{ 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \
}
//////////////////////////////////////////////////////////////////////////////////////////////
// The icon decoder is a decoder specifically tailored for loading icons
// from the OS. We've defined our own little format to represent these icons
// and this decoder takes that format and converts it into 24-bit RGB with alpha channel
// support. It was modeled a bit off the PPM decoder.
//
// Assumptions about the decoder:
// (1) We receive ALL of the data from the icon channel in one OnDataAvailable call. We don't
// support multiple ODA calls yet.
// (2) the format of the incoming data is as follows:
// The first two bytes contain the width and the height of the icon.
// Followed by 3 bytes per pixel for the color bitmap row after row. (for heigh * width * 3 bytes)
// Followed by bit mask data (used for transparency on the alpha channel).
//
//
//////////////////////////////////////////////////////////////////////////////////////////////
class nsIconDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsIconDecoder();
virtual ~nsIconDecoder();
private:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
};
#endif // nsIconDecoder_h__

View File

@@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsIconDecoder.h"
#include "nsIconProtocolHandler.h"
// objects that just require generic constructors
/******************************************************************************
* Protocol CIDs
*/
#define NS_ICONPROTOCOL_CID { 0xd0f9db12, 0x249c, 0x11d5, { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconProtocolHandler)
static nsModuleComponentInfo components[] =
{
{ "icon decoder",
NS_ICONDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/icon",
nsIconDecoderConstructor, },
{ "Icon Protocol Handler",
NS_ICONPROTOCOL_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "icon",
nsIconProtocolHandlerConstructor
}
};
NS_IMPL_NSGETMODULE("nsIconDecoderModule", components)

View File

@@ -1,90 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIconProtocolHandler.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kStandardURICID, NS_STANDARDURL_CID);
////////////////////////////////////////////////////////////////////////////////
nsIconProtocolHandler::nsIconProtocolHandler()
{
NS_INIT_REFCNT();
}
nsIconProtocolHandler::~nsIconProtocolHandler()
{}
NS_IMPL_ISUPPORTS2(nsIconProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP nsIconProtocolHandler::GetScheme(char* *result)
{
*result = nsCRT::strdup("icon");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP nsIconProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP nsIconProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI, nsIURI **result)
{
nsresult rv;
// no concept of a relative icon url
NS_ASSERTION(!aBaseURI, "base url passed into icon protocol handler");
nsCOMPtr<nsIURI> url = do_CreateInstance(kStandardURICID, &rv);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
*result = url;
NS_IF_ADDREF(*result);
return rv;
}
NS_IMETHODIMP nsIconProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result)
{
nsCOMPtr<nsIChannel> channel;
NS_NEWXPCOM(channel, nsIconChannel);
if (channel)
NS_STATIC_CAST(nsIconChannel*,NS_STATIC_CAST(nsIChannel*, channel))->Init(url);
*result = channel;
NS_IF_ADDREF(*result);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,377 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsMimeTypes.h"
#include "nsMemory.h"
#include "nsIStringStream.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
// we need windows.h to read out registry information...
#include <windows.h>
#include <shellapi.h>
// nsIconChannel methods
nsIconChannel::nsIconChannel()
{
NS_INIT_REFCNT();
mStatus = NS_OK;
}
nsIconChannel::~nsIconChannel()
{}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
nsIChannel,
nsIRequest)
nsresult nsIconChannel::Init(nsIURI* uri)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsIconChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
return rv;
}
NS_IMETHODIMP nsIconChannel::Suspend(void)
{
NS_NOTREACHED("nsIconChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::Resume(void)
{
NS_NOTREACHED("nsIconChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream **_retval)
{
return NS_ERROR_FAILURE;
}
void InvertRows(unsigned char * aInitialBuffer, PRUint32 sizeOfBuffer, PRUint32 numBytesPerRow)
{
PRUint32 numRows = sizeOfBuffer / numBytesPerRow;
void * temporaryRowHolder = (void *) nsMemory::Alloc(numBytesPerRow);
PRUint32 currentRow = 0;
PRUint32 lastRow = (numRows - 1) * numBytesPerRow;
while (currentRow < lastRow)
{
// store the current row into a temporary buffer
nsCRT::memcpy(temporaryRowHolder, (void *) &aInitialBuffer[currentRow], numBytesPerRow);
nsCRT::memcpy((void *) &aInitialBuffer[currentRow], (void *)&aInitialBuffer[lastRow], numBytesPerRow);
nsCRT::memcpy((void *) &aInitialBuffer[lastRow], temporaryRowHolder, numBytesPerRow);
lastRow -= numBytesPerRow;
currentRow += numBytesPerRow;
}
}
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
// get the file name from the url
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
mUrl->GetHost(getter_Copies(fileName));
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
if (url)
url->GetFileBaseName(getter_Copies(filePath));
// 1) get a hIcon for the file.
SHFILEINFO sfi;
UINT infoFlags = SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
if (filePath && !nsCRT::strcmp(filePath, "large"))
infoFlags |= SHGFI_LARGEICON;
else // default to small
infoFlags |= SHGFI_SMALLICON;
LONG result= SHGetFileInfo(fileName, FILE_ATTRIBUTE_ARCHIVE, &sfi, sizeof(sfi), infoFlags);
if (result > 0 && sfi.hIcon)
{
// we got a handle to an icon. Now we want to get a bitmap for the icon using GetIconInfo....
ICONINFO pIconInfo;
result = GetIconInfo(sfi.hIcon, &pIconInfo);
if (result > 0)
{
// now we have the bit map we need to get info about the bitmap
BITMAPINFO pBitMapInfo;
BITMAPINFOHEADER pBitMapInfoHeader;
pBitMapInfo.bmiHeader.biBitCount = 0;
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
HDC pDC = CreateCompatibleDC(NULL); // get a device context for the screen.
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
{
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
unsigned char * buffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, pBitMapInfo.bmiHeader.biHeight, (void *) buffer, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0)
{
PRUint32 bytesPerPixel = pBitMapInfo.bmiHeader.biBitCount / 8;
InvertRows(buffer, pBitMapInfo.bmiHeader.biSizeImage, pBitMapInfo.bmiHeader.biWidth * bytesPerPixel);
// Convert our little icon buffer which is padded to 4 bytes per pixel into a nice 3 byte per pixel
// description.
nsCString iconBuffer;
iconBuffer.Assign((char) pBitMapInfo.bmiHeader.biWidth);
iconBuffer.Append((char) pBitMapInfo.bmiHeader.biHeight);
PRInt32 index = 0;
if (pBitMapInfo.bmiHeader.biBitCount == 16)
{
PRUint8 redValue, greenValue, blueValue, partialGreen;
while (index < pBitMapInfo.bmiHeader.biSizeImage)
{
DWORD dst=(DWORD) buffer[index];
PRUint16 num = 0;
num = (PRUint8) buffer[index];
num <<= 8;
num |= (PRUint8) buffer[index+1];
//blueValue = (PRUint8)((*dst)&(0x1F));
//greenValue = (PRUint8)(((*dst)>>5)&(0x1F));
//redValue = (PRUint8)(((*dst)>>10)&(0x1F));
redValue = ((PRUint32) (((float)(num & 0x7c00) / 0x7c00) * 0xFF0000) & 0xFF0000)>> 16;
greenValue = ((PRUint32)(((float)(num & 0x03E0) / 0x03E0) * 0x00FF00) & 0x00FF00)>> 8;
blueValue = ((PRUint32)(((float)(num & 0x001F) / 0x001F) * 0x0000FF) & 0x0000FF);
// now we have the right RGB values...
iconBuffer.Append((char) redValue);
iconBuffer.Append((char) greenValue);
iconBuffer.Append((char) blueValue);
index += bytesPerPixel;
}
}
else
{
while (index <pBitMapInfo.bmiHeader.biSizeImage)
{
iconBuffer.Append((char) buffer[index]);
iconBuffer.Append((char) buffer[index+1]);
iconBuffer.Append((char) buffer[index+2]);
index += bytesPerPixel;
}
}
// now we need to tack on the alpha data...which is hbmMask
pBitMapInfo.bmiHeader.biBitCount = 0;
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
{
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
unsigned char * maskBuffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, pBitMapInfo.bmiHeader.biHeight, (void *) maskBuffer, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0)
{
InvertRows(maskBuffer, pBitMapInfo.bmiHeader.biSizeImage, 4);
index = 0;
// for some reason the bit mask on windows are flipped from the values we really want for transparency.
// So complement each byte in the bit mask.
while (index < pBitMapInfo.bmiHeader.biSizeImage)
{
maskBuffer[index]^=255;
index += 1;
}
iconBuffer.Append((char *) maskBuffer, pBitMapInfo.bmiHeader.biSizeImage);
}
nsMemory::Free(maskBuffer);
} // if we have a mask buffer to apply
// turn our nsString into a stream looking object...
aListener->OnStartRequest(this, ctxt);
// turn our string into a stream...
nsCOMPtr<nsISupports> streamSupports;
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
} // if we got valid bits for the main bitmap mask
nsMemory::Free(buffer);
}
DeleteDC(pDC);
}
}
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
{
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup("image/icon");
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsIconChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}

View File

@@ -1,56 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconChannel_h___
#define nsIconChannel_h___
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIURI.h"
class nsIconChannel : public nsIChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
nsIconChannel();
virtual ~nsIconChannel();
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIURI> mOriginalURI;
PRUint32 mLoadAttributes;
PRInt32 mContentLength;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsISupports> mOwner;
nsresult mStatus;
};
#endif /* nsIconChannel_h___ */

View File

@@ -1,42 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgjpeg
LIBRARY_NAME = imgjpeg
IS_COMPONENT = 1
REQUIRES = xpcom string necko layout jpeg gfx2 imglib2
CPPSRCS = nsJPEGDecoder.cpp nsJPEGFactory.cpp
EXTRA_DSO_LDOPTS = $(JPEG_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,52 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgjpeg
LIBRARY_NAME = imgjpeg
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsJPEGDecoder.obj \
.\$(OBJDIR)\nsJPEGFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\jpeg3250.lib \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,829 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsJPEGDecoder.h"
#include "nsIInputStream.h"
#include "nspr.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "imgIContainerObserver.h"
#include "ImageLogging.h"
NS_IMPL_ISUPPORTS2(nsJPEGDecoder, imgIDecoder, nsIOutputStream)
#if defined(PR_LOGGING)
PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder");
#else
#define gJPEGlog
#endif
void PR_CALLBACK init_source (j_decompress_ptr jd);
boolean PR_CALLBACK fill_input_buffer (j_decompress_ptr jd);
void PR_CALLBACK skip_input_data (j_decompress_ptr jd, long num_bytes);
void PR_CALLBACK term_source (j_decompress_ptr jd);
void PR_CALLBACK my_error_exit (j_common_ptr cinfo);
/* Normal JFIF markers can't have more bytes than this. */
#define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1)
/* Possible states for JPEG source manager */
enum data_source_state {
READING_BACK = 0, /* Must be zero for init purposes */
READING_NEW
};
/*
* Implementation of a JPEG src object that understands our state machine
*/
typedef struct {
/* public fields; must be first in this struct! */
struct jpeg_source_mgr pub;
nsJPEGDecoder *decoder;
} decoder_source_mgr;
nsJPEGDecoder::nsJPEGDecoder()
{
NS_INIT_ISUPPORTS();
mState = JPEG_HEADER;
mFillState = READING_BACK;
mSamples = nsnull;
mSamples3 = nsnull;
mRGBPadRow = nsnull;
mRGBPadRowLength = 0;
mBytesToSkip = 0;
memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
mCompletedPasses = 0;
mBuffer = nsnull;
mBufferLen = mBufferSize = 0;
mBackBuffer = nsnull;
mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
}
nsJPEGDecoder::~nsJPEGDecoder()
{
if (mBuffer)
PR_Free(mBuffer);
if (mBackBuffer)
PR_Free(mBackBuffer);
if (mRGBPadRow)
PR_Free(mRGBPadRow);
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsJPEGDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(mRequest);
aRequest->GetImage(getter_AddRefs(mImage));
/* We set up the normal JPEG error routines, then override error_exit. */
mInfo.err = jpeg_std_error(&mErr.pub);
/* mInfo.err = jpeg_std_error(&mErr.pub); */
mErr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(mErr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
return NS_ERROR_FAILURE;
}
/* Step 1: allocate and initialize JPEG decompression object */
jpeg_create_decompress(&mInfo);
decoder_source_mgr *src;
if (mInfo.src == NULL) {
//mInfo.src = PR_NEWZAP(decoder_source_mgr);
src = PR_NEWZAP(decoder_source_mgr);
if (!src) {
return PR_FALSE;
}
mInfo.src = (struct jpeg_source_mgr *) src;
}
/* Step 2: specify data source (eg, a file) */
/* Setup callback functions. */
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_buffer;
src->pub.skip_input_data = skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.term_source = term_source;
src->decoder = this;
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsJPEGDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsJPEGDecoder::Close()
{
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::Close\n", this));
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
NS_WARNING("Never finished decoding the JPEG.");
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&mInfo);
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsJPEGDecoder::Flush()
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::Flush");
PRUint32 ret;
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
return this->WriteFrom(nsnull, 0, &ret);
return NS_OK;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::WriteFrom", "count", count);
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
// XXX above what is this?
if (inStr) {
if (!mBuffer) {
mBuffer = (JOCTET *)PR_Malloc(count);
mBufferSize = count;
} else if (count > mBufferSize) {
mBuffer = (JOCTET *)PR_Realloc(mBuffer, count);
mBufferSize = count;
}
nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen);
*_retval = mBufferLen;
//nsresult rv = mOutStream->WriteFrom(inStr, count, _retval);
NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- mOutStream->WriteFrom failed");
}
// else no input stream.. Flush() ?
nsresult error_code = NS_ERROR_FAILURE;
/* Return here if there is a fatal error. */
if ((error_code = setjmp(mErr.setjmp_buffer)) != 0) {
return error_code;
}
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- processing JPEG data\n", this));
decoder_source_mgr *src = NS_REINTERPRET_CAST(decoder_source_mgr *, mInfo.src);
switch (mState) {
case JPEG_HEADER:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_HEADER case");
/* Step 3: read file parameters with jpeg_read_header() */
if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED)
return NS_OK; /* I/O suspension */
/*
* Don't allocate a giant and superfluous memory buffer
* when the image is a sequential JPEG.
*/
mInfo.buffered_image = jpeg_has_multiple_scans(&mInfo);
/* Used to set up image size so arrays can be allocated */
jpeg_calc_output_dimensions(&mInfo);
mObserver->OnStartDecode(nsnull, nsnull);
mImage->Init(mInfo.image_width, mInfo.image_height, mObserver);
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
gfx_format format;
#ifdef XP_PC
format = gfxIFormats::BGR;
#else
format = gfxIFormats::RGB;
#endif
mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format);
mImage->AppendFrame(mFrame);
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
/*
* Make a one-row-high sample array that will go away
* when done with image. Always make it big enough to
* hold an RGB row. Since this uses the IJG memory
* manager, it must be allocated before the call to
* jpeg_start_compress().
*/
int row_stride;
if(mInfo.output_components == 1)
row_stride = mInfo.output_width;
else
row_stride = mInfo.output_width * 4; // use 4 instead of mInfo.output_components
// so we don't have to fuss with byte alignment.
// Mac wants 4 anyways.
mSamples = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
JPOOL_IMAGE,
row_stride, 1);
#if defined(XP_PC) || defined(XP_MAC)
// allocate buffer to do byte flipping if needed
if (mInfo.output_components == 3) {
mRGBPadRow = (PRUint8*) PR_MALLOC(row_stride);
mRGBPadRowLength = row_stride;
memset(mRGBPadRow, 0, mRGBPadRowLength);
}
#endif
/* Allocate RGB buffer for conversion from greyscale. */
if (mInfo.output_components != 3) {
row_stride = mInfo.output_width * 4;
mSamples3 = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
JPOOL_IMAGE,
row_stride, 1);
}
mState = JPEG_START_DECOMPRESS;
}
case JPEG_START_DECOMPRESS:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_START_DECOMPRESS case");
/* Step 4: set parameters for decompression */
/* FIXME -- Should reset dct_method and dither mode
* for final pass of progressive JPEG
*/
mInfo.dct_method = JDCT_FASTEST;
mInfo.dither_mode = JDITHER_ORDERED;
mInfo.do_fancy_upsampling = FALSE;
mInfo.enable_2pass_quant = FALSE;
mInfo.do_block_smoothing = TRUE;
/* Step 5: Start decompressor */
if (jpeg_start_decompress(&mInfo) == FALSE)
return NS_OK; /* I/O suspension */
/* If this is a progressive JPEG ... */
if (mInfo.buffered_image) {
mState = JPEG_DECOMPRESS_PROGRESSIVE;
} else {
mState = JPEG_DECOMPRESS_SEQUENTIAL;
}
}
case JPEG_DECOMPRESS_SEQUENTIAL:
{
if (mState == JPEG_DECOMPRESS_SEQUENTIAL)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_SEQUENTIAL case");
if (OutputScanlines(-1) == PR_FALSE)
return NS_OK; /* I/O suspension */
/* If we've completed image output ... */
NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, "We didn't process all of the data!");
mState = JPEG_DONE;
}
}
case JPEG_DECOMPRESS_PROGRESSIVE:
{
if (mState == JPEG_DECOMPRESS_PROGRESSIVE)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_PROGRESSIVE case");
int status;
do {
status = jpeg_consume_input(&mInfo);
} while (!((status == JPEG_SUSPENDED) ||
(status == JPEG_REACHED_EOI)));
switch (status) {
case JPEG_REACHED_EOI:
// End of image
mState = JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT;
break;
case JPEG_SUSPENDED:
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- suspending\n", this));
return NS_OK; /* I/O suspension */
default:
printf("got someo other state!?\n");
}
}
}
case JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT:
{
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT case");
// XXX progressive? ;)
// not really progressive according to the state machine... -saari
jpeg_start_output(&mInfo, mInfo.input_scan_number);
if (OutputScanlines(-1) == PR_FALSE)
return NS_OK; /* I/O suspension */
jpeg_finish_output(&mInfo);
mState = JPEG_DONE;
}
}
case JPEG_DONE:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case");
/* Step 7: Finish decompression */
if (jpeg_finish_decompress(&mInfo) == FALSE)
return NS_OK; /* I/O suspension */
mState = JPEG_SINK_NON_JPEG_TRAILER;
/* we're done dude */
break;
}
case JPEG_SINK_NON_JPEG_TRAILER:
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- entering JPEG_SINK_NON_JPEG_TRAILER case\n", this));
break;
}
return NS_OK;
}
int
nsJPEGDecoder::OutputScanlines(int num_scanlines)
{
int pass = 0;
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
pass = -1;
else
pass = mCompletedPasses + 1;
while ((mInfo.output_scanline < mInfo.output_height) && num_scanlines--) {
JSAMPROW samples;
/* Request one scanline. Returns 0 or 1 scanlines. */
int ns = jpeg_read_scanlines(&mInfo, mSamples, 1);
if (ns != 1) {
return PR_FALSE; /* suspend */
}
/* If grayscale image ... */
if (mInfo.output_components == 1) {
JSAMPLE j;
JSAMPLE *j1 = mSamples[0];
const JSAMPLE *j1end = j1 + mInfo.output_width;
JSAMPLE *j3 = mSamples3[0];
/* Convert from grayscale to RGB. */
while (j1 < j1end) {
#ifdef XP_MAC
j = *j1++;
j3[0] = 0;
j3[1] = j;
j3[2] = j;
j3[3] = j;
j3 += 4;
#else
j = *j1++;
j3[0] = j;
j3[1] = j;
j3[2] = j;
j3 += 3;
#endif
}
samples = mSamples3[0];
} else {
/* 24-bit color image */
#ifdef XP_PC
memset(mRGBPadRow, 0, mInfo.output_width * 4);
PRUint8 *ptrOutputBuf = mRGBPadRow;
JSAMPLE *j1 = mSamples[0];
for (PRUint32 i=0;i<mInfo.output_width;++i) {
ptrOutputBuf[2] = *j1++;
ptrOutputBuf[1] = *j1++;
ptrOutputBuf[0] = *j1++;
ptrOutputBuf += 3;
}
samples = mRGBPadRow;
#else
#ifdef XP_MAC
memset(mRGBPadRow, 0, mInfo.output_width * 4);
PRUint8 *ptrOutputBuf = mRGBPadRow;
JSAMPLE *j1 = mSamples[0];
for (PRUint32 i=0;i<mInfo.output_width;++i) {
ptrOutputBuf[0] = 0;
ptrOutputBuf[1] = *j1++;
ptrOutputBuf[2] = *j1++;
ptrOutputBuf[3] = *j1++;
ptrOutputBuf += 4;
}
samples = mRGBPadRow;
#else
samples = mSamples[0];
#endif
#endif
}
PRUint32 bpr;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->SetImageData(
samples, // data
bpr, // length
(mInfo.output_scanline-1) * bpr); // offset
nsRect r(0, mInfo.output_scanline, mInfo.output_width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
}
return PR_TRUE;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsJPEGDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsJPEGDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsJPEGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsJPEGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* Override the standard error method in the IJG JPEG decoder code. */
void PR_CALLBACK
my_error_exit (j_common_ptr cinfo)
{
nsresult error_code = NS_ERROR_FAILURE;
decoder_error_mgr *err = (decoder_error_mgr *) cinfo->err;
#if 0
#ifdef DEBUG
/*ptn fix later */
if (il_debug >= 1) {
char buffer[JMSG_LENGTH_MAX];
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
ILTRACE(1,("%s\n", buffer));
}
#endif
/* Convert error to a browser error code */
if (cinfo->err->msg_code == JERR_OUT_OF_MEMORY)
error_code = MK_OUT_OF_MEMORY;
else
error_code = MK_IMAGE_LOSSAGE;
#endif
char buffer[JMSG_LENGTH_MAX];
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
fprintf(stderr, "my_error_exit()\n%s\n", buffer);
/* Return control to the setjmp point. */
longjmp(err->setjmp_buffer, error_code);
}
/******************************************************************************/
/*-----------------------------------------------------------------------------
* This is the callback routine from the IJG JPEG library used to supply new
* data to the decompressor when its input buffer is exhausted. It juggles
* multiple buffers in an attempt to avoid unnecessary copying of input data.
*
* (A simpler scheme is possible: It's much easier to use only a single
* buffer; when fill_input_buffer() is called, move any unconsumed data
* (beyond the current pointer/count) down to the beginning of this buffer and
* then load new data into the remaining buffer space. This approach requires
* a little more data copying but is far easier to get right.)
*
* At any one time, the JPEG decompressor is either reading from the necko
* input buffer, which is volatile across top-level calls to the IJG library,
* or the "backtrack" buffer. The backtrack buffer contains the remaining
* unconsumed data from the necko buffer after parsing was suspended due
* to insufficient data in some previous call to the IJG library.
*
* When suspending, the decompressor will back up to a convenient restart
* point (typically the start of the current MCU). The variables
* next_input_byte & bytes_in_buffer indicate where the restart point will be
* if the current call returns FALSE. Data beyond this point must be
* rescanned after resumption, so it must be preserved in case the decompressor
* decides to backtrack.
*
* Returns:
* TRUE if additional data is available, FALSE if no data present and
* the JPEG library should therefore suspend processing of input stream
*---------------------------------------------------------------------------*/
/******************************************************************************/
/* data source manager method
/******************************************************************************/
/******************************************************************************/
/* data source manager method
Initialize source. This is called by jpeg_read_header() before any
data is actually read. May leave
bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
will occur immediately).
*/
void PR_CALLBACK
init_source (j_decompress_ptr jd)
{
}
/******************************************************************************/
/* data source manager method
Skip num_bytes worth of data. The buffer pointer and count should
be advanced over num_bytes input bytes, refilling the buffer as
needed. This is used to skip over a potentially large amount of
uninteresting data (such as an APPn marker). In some applications
it may be possible to optimize away the reading of the skipped data,
but it's not clear that being smart is worth much trouble; large
skips are uncommon. bytes_in_buffer may be zero on return.
A zero or negative skip count should be treated as a no-op.
*/
void PR_CALLBACK
skip_input_data (j_decompress_ptr jd, long num_bytes)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
if (num_bytes > (long)src->pub.bytes_in_buffer) {
/*
* Can't skip it all right now until we get more data from
* network stream. Set things up so that fill_input_buffer
* will skip remaining amount.
*/
src->decoder->mBytesToSkip = (size_t)num_bytes - src->pub.bytes_in_buffer;
src->pub.next_input_byte += src->pub.bytes_in_buffer;
src->pub.bytes_in_buffer = 0;
} else {
/* Simple case. Just advance buffer pointer */
src->pub.bytes_in_buffer -= (size_t)num_bytes;
src->pub.next_input_byte += num_bytes;
}
}
/******************************************************************************/
/* data source manager method
This is called whenever bytes_in_buffer has reached zero and more
data is wanted. In typical applications, it should read fresh data
into the buffer (ignoring the current state of next_input_byte and
bytes_in_buffer), reset the pointer & count to the start of the
buffer, and return TRUE indicating that the buffer has been reloaded.
It is not necessary to fill the buffer entirely, only to obtain at
least one more byte. bytes_in_buffer MUST be set to a positive value
if TRUE is returned. A FALSE return should only be used when I/O
suspension is desired.
*/
boolean PR_CALLBACK
fill_input_buffer (j_decompress_ptr jd)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
unsigned char *new_buffer = (unsigned char *)src->decoder->mBuffer;
PRUint32 new_buflen = src->decoder->mBufferLen;
PRUint32 bytesToSkip = src->decoder->mBytesToSkip;
switch(src->decoder->mFillState) {
case READING_BACK:
{
if (!new_buffer || new_buflen == 0)
return PR_FALSE; /* suspend */
src->decoder->mBufferLen = 0;
if (bytesToSkip != 0) {
if (bytesToSkip < new_buflen) {
/* All done skipping bytes; Return what's left. */
new_buffer += bytesToSkip;
new_buflen -= bytesToSkip;
src->decoder->mBytesToSkip = 0;
} else {
/* Still need to skip some more data in the future */
src->decoder->mBytesToSkip -= (size_t)new_buflen;
return PR_FALSE; /* suspend */
}
}
src->decoder->mBackBufferUnreadLen = src->pub.bytes_in_buffer;
src->pub.next_input_byte = new_buffer;
src->pub.bytes_in_buffer = (size_t)new_buflen;
src->decoder->mFillState = READING_NEW;
return PR_TRUE;
}
break;
case READING_NEW:
{
if (src->pub.next_input_byte != src->decoder->mBuffer) {
/* Backtrack data has been permanently consumed. */
src->decoder->mBackBufferUnreadLen = 0;
src->decoder->mBackBufferLen = 0;
}
/* Save remainder of netlib buffer in backtrack buffer */
PRUint32 new_backtrack_buflen = src->pub.bytes_in_buffer + src->decoder->mBackBufferLen;
/* Make sure backtrack buffer is big enough to hold new data. */
if (src->decoder->mBackBufferSize < new_backtrack_buflen) {
/* Round up to multiple of 16 bytes. */
PRUint32 roundup_buflen = ((new_backtrack_buflen + 15) >> 4) << 4;
if (src->decoder->mBackBufferSize) {
src->decoder->mBackBuffer =
(JOCTET *)PR_REALLOC(src->decoder->mBackBuffer, roundup_buflen);
} else {
src->decoder->mBackBuffer = (JOCTET*)PR_MALLOC(roundup_buflen);
}
/* Check for OOM */
if (!src->decoder->mBackBuffer) {
#if 0
j_common_ptr cinfo = (j_common_ptr)(&src->js->jd);
cinfo->err->msg_code = JERR_OUT_OF_MEMORY;
my_error_exit(cinfo);
#endif
}
src->decoder->mBackBufferSize = (size_t)roundup_buflen;
/* Check for malformed MARKER segment lengths. */
if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
my_error_exit((j_common_ptr)(&src->decoder->mInfo));
}
}
/* Copy remainder of netlib buffer into backtrack buffer. */
nsCRT::memmove(src->decoder->mBackBuffer + src->decoder->mBackBufferLen,
src->pub.next_input_byte,
src->pub.bytes_in_buffer);
/* Point to start of data to be rescanned. */
src->pub.next_input_byte = src->decoder->mBackBuffer + src->decoder->mBackBufferLen - src->decoder->mBackBufferUnreadLen;
src->pub.bytes_in_buffer += src->decoder->mBackBufferUnreadLen;
src->decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
src->decoder->mFillState = READING_BACK;
return PR_FALSE;
}
break;
}
return PR_FALSE;
}
/******************************************************************************/
/* data source manager method */
/*
* Terminate source --- called by jpeg_finish_decompress() after all
* data has been read to clean up JPEG source manager. NOT called by
* jpeg_abort() or jpeg_destroy().
*/
void PR_CALLBACK
term_source (j_decompress_ptr jd)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
if (src->decoder->mObserver) {
src->decoder->mObserver->OnStopFrame(nsnull, nsnull, src->decoder->mFrame);
src->decoder->mObserver->OnStopContainer(nsnull, nsnull, src->decoder->mImage);
src->decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
/* No work necessary here */
}

View File

@@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsJPEGDecoder_h__
#define nsJPEGDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "imgIDecoderObserver.h"
#include "imgIRequest.h"
#include "nsIInputStream.h"
#include "nsIPipe.h"
extern "C" {
#include "jpeglib.h"
}
#include <setjmp.h>
#define NS_JPEGDECODER_CID \
{ /* 5871a422-1dd2-11b2-ab3f-e2e56be5da9c */ \
0x5871a422, \
0x1dd2, \
0x11b2, \
{0xab, 0x3f, 0xe2, 0xe5, 0x6b, 0xe5, 0xda, 0x9c} \
}
typedef struct {
struct jpeg_error_mgr pub; /* "public" fields for IJG library*/
jmp_buf setjmp_buffer; /* For handling catastropic errors */
} decoder_error_mgr;
typedef enum {
JPEG_HEADER, /* Reading JFIF headers */
JPEG_START_DECOMPRESS,
JPEG_DECOMPRESS_PROGRESSIVE, /* Output progressive pixels */
JPEG_DECOMPRESS_SEQUENTIAL, /* Output sequential pixels */
JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT,
JPEG_DONE,
JPEG_SINK_NON_JPEG_TRAILER, /* Some image files have a */
/* non-JPEG trailer */
JPEG_ERROR
} jstate;
class nsJPEGDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsJPEGDecoder();
virtual ~nsJPEGDecoder();
PRBool FillInput(j_decompress_ptr jd);
PRUint32 mBytesToSkip;
protected:
int OutputScanlines(int num_scanlines);
public:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver;
struct jpeg_decompress_struct mInfo;
decoder_error_mgr mErr;
jstate mState;
JSAMPARRAY mSamples;
JSAMPARRAY mSamples3;
PRUint8* mRGBPadRow;
PRUint32 mRGBPadRowLength;
PRInt32 mCompletedPasses;
PRInt32 mPasses;
int mFillState;
JOCTET *mBuffer;
PRUint32 mBufferLen; // amount of data currently in mBuffer
PRUint32 mBufferSize; // size in bytes what mBuffer was created with
JOCTET *mBackBuffer;
PRUint32 mBackBufferLen; // Offset of end of active backtrack data
PRUint32 mBackBufferSize; // size in bytes what mBackBuffer was created with
PRUint32 mBackBufferUnreadLen; // amount of data currently in mBackBuffer
};
#endif // nsJPEGDecoder_h__

View File

@@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsJPEGDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDecoder)
static nsModuleComponentInfo components[] =
{
{ "ppm decoder",
NS_JPEGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/jpeg",
nsJPEGDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsJPEGDecoderModule", components)

View File

@@ -1,16 +0,0 @@
?Release@nsJPEGDecoder@@UAGKXZ ; 172
?AddRef@nsJPEGDecoder@@UAGKXZ ; 172
?fill_input_buffer@@YAEPAUjpeg_decompress_struct@@@Z ; 126
?skip_input_data@@YAXPAUjpeg_decompress_struct@@J@Z ; 109
?WriteFrom@nsJPEGDecoder@@UAGIPAVnsIInputStream@@IPAI@Z ; 106
?OutputScanlines@nsJPEGDecoder@@IAEHH@Z ; 93
?init_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
??1nsJPEGDecoder@@UAE@XZ ; 86
?Close@nsJPEGDecoder@@UAGIXZ ; 86
?term_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
?Init@nsJPEGDecoder@@UAGIPAVimgIRequest@@@Z ; 86
??0nsJPEGDecoder@@QAE@XZ ; 86
?Flush@nsJPEGDecoder@@UAGIXZ ; 86
?QueryInterface@nsJPEGDecoder@@UAGIABUnsID@@PAPAX@Z ; 86
??_EnsJPEGDecoder@@UAEPAXI@Z ; 86
_NSGetModule ; 1

View File

@@ -1,26 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH=..\..\..
DIRS = ppm gif png jpeg
!include $(DEPTH)\config\rules.mak

View File

@@ -1,42 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgpng
LIBRARY_NAME = imgpng
IS_COMPONENT = 1
REQUIRES = xpcom necko layout png gfx2 imglib2
CPPSRCS = nsPNGDecoder.cpp nsPNGFactory.cpp
EXTRA_DSO_LDOPTS = $(PNG_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,53 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgpng
LIBRARY_NAME = imgpng
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsPNGDecoder.obj \
.\$(OBJDIR)\nsPNGFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\png.lib \
$(DIST)\lib\zlib.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,553 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsPNGDecoder.h"
#include "nsIInputStream.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "png.h"
#include "nsIStreamObserver.h"
#include "nsRect.h"
#include "nsMemory.h"
#include "imgIContainerObserver.h"
// XXX we need to be sure to fire onStopDecode messages to mObserver in error cases.
NS_IMPL_ISUPPORTS2(nsPNGDecoder, imgIDecoder, nsIOutputStream)
nsPNGDecoder::nsPNGDecoder()
{
NS_INIT_ISUPPORTS();
mPNG = nsnull;
mInfo = nsnull;
colorLine = 0;
alphaLine = 0;
interlacebuf = 0;
}
nsPNGDecoder::~nsPNGDecoder()
{
if (colorLine)
nsMemory::Free(colorLine);
if (alphaLine)
nsMemory::Free(alphaLine);
if (interlacebuf)
nsMemory::Free(interlacebuf);
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsPNGDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
/* do png init stuff */
/* Initialize the container's source image header. */
/* Always decode to 24 bit pixdepth */
mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL,
NULL);
if (!mPNG) {
return NS_ERROR_FAILURE;
}
mInfo = png_create_info_struct(mPNG);
if (!mInfo) {
png_destroy_read_struct(&mPNG, NULL, NULL);
return NS_ERROR_FAILURE;
}
/* use ic as libpng "progressive pointer" (retrieve in callbacks) */
png_set_progressive_read_fn(mPNG, NS_STATIC_CAST(png_voidp, this), nsPNGDecoder::info_callback, nsPNGDecoder::row_callback, nsPNGDecoder::end_callback);
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsPNGDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsPNGDecoder::Close()
{
if (mPNG)
png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL);
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsPNGDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
static NS_METHOD ReadDataOut(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, closure);
// we need to do the setjmp here otherwise bad things will happen
if (setjmp(decoder->mPNG->jmpbuf)) {
png_destroy_read_struct(&decoder->mPNG, &decoder->mInfo, NULL);
// is this NS_ERROR_FAILURE enough?
decoder->mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
return NS_ERROR_FAILURE;
}
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
return NS_OK;
}
PRUint32 nsPNGDecoder::ProcessData(unsigned char *data, PRUint32 count)
{
png_process_data(mPNG, mInfo, data, count);
return count; // we always consume all the data
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
// PRUint32 sourceOffset = *_retval;
inStr->ReadSegments(ReadDataOut, this, count, _retval);
return NS_OK;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsPNGDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPNGDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsPNGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPNGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
{
/* int number_passes; NOT USED */
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, compression_type, filter_type;
int channels;
double LUT_exponent, CRT_exponent = 2.2, display_exponent, aGamma;
png_bytep trans=NULL;
int num_trans =0;
/* always decode to 24-bit RGB or 32-bit RGBA */
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, &compression_type, &filter_type);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
png_set_expand(png_ptr);
}
if (bit_depth == 16)
png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
#ifdef XP_PC
// windows likes BGR
png_set_bgr(png_ptr);
#endif
/* set up gamma correction for Mac, Unix and (Win32 and everything else)
* using educated guesses for display-system exponents; do preferences
* later */
#if defined(XP_MAC)
LUT_exponent = 1.8 / 2.61;
#elif defined(XP_UNIX)
# if defined(__sgi)
LUT_exponent = 1.0 / 1.7; /* typical default for SGI console */
# elif defined(NeXT)
LUT_exponent = 1.0 / 2.2; /* typical default for NeXT cube */
# else
LUT_exponent = 1.0; /* default for most other Unix workstations */
# endif
#else
LUT_exponent = 1.0; /* virtually all PCs and most other systems */
#endif
/* (alternatively, could check for SCREEN_GAMMA environment variable) */
display_exponent = LUT_exponent * CRT_exponent;
if (png_get_gAMA(png_ptr, info_ptr, &aGamma))
png_set_gamma(png_ptr, display_exponent, aGamma);
else
png_set_gamma(png_ptr, display_exponent, 0.45455);
/* let libpng expand interlaced images */
if (interlace_type == PNG_INTERLACE_ADAM7) {
/* number_passes = */
png_set_interlace_handling(png_ptr);
}
/* now all of those things we set above are used to update various struct
* members and whatnot, after which we can get channels, rowbytes, etc. */
png_read_update_info(png_ptr, info_ptr);
channels = png_get_channels(png_ptr, info_ptr);
PR_ASSERT(channels == 3 || channels == 4);
/*---------------------------------------------------------------*/
/* copy PNG info into imagelib structs (formerly png_set_dims()) */
/*---------------------------------------------------------------*/
PRInt32 alpha_bits = 1;
if (channels > 3) {
/* check if alpha is coming from a tRNS chunk and is binary */
if (num_trans) {
/* if it's not a indexed color image, tRNS means binary */
if (color_type == PNG_COLOR_TYPE_PALETTE) {
for (int i=0; i<num_trans; i++) {
if ((trans[i] != 0) && (trans[i] != 255)) {
alpha_bits = 8;
break;
}
}
}
} else {
alpha_bits = 8;
}
}
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
if (decoder->mObserver)
decoder->mObserver->OnStartDecode(nsnull, nsnull);
// since the png is only 1 frame, initalize the container to the width and height of the frame
decoder->mImage->Init(width, height, decoder->mObserver);
if (decoder->mObserver)
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImage);
decoder->mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
#if 0
// XXX should we longjmp to png_ptr->jumpbuf here if we failed?
if (!decoder->mFrame)
return NS_ERROR_FAILURE;
#endif
gfx_format format;
if (channels == 3) {
format = gfxIFormats::RGB;
} else if (channels > 3) {
if (alpha_bits == 8) {
decoder->mImage->GetPreferredAlphaChannelFormat(&format);
} else if (alpha_bits == 1) {
format = gfxIFormats::RGB_A1;
}
}
#ifdef XP_PC
// XXX this works...
format += 1; // RGB to BGR
#endif
// then initalize the frame and append it to the container
decoder->mFrame->Init(0, 0, width, height, format);
decoder->mImage->AppendFrame(decoder->mFrame);
if (decoder->mObserver)
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mFrame);
PRUint32 bpr, abpr;
decoder->mFrame->GetImageBytesPerRow(&bpr);
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
decoder->colorLine = (PRUint8 *)nsMemory::Alloc(bpr);
if (channels > 3)
decoder->alphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
if (interlace_type == PNG_INTERLACE_ADAM7) {
decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels*width*height);
decoder->ibpr = channels*width;
if (!decoder->interlacebuf) {
// return NS_ERROR_FAILURE;
}
}
return;
}
void
nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass)
{
/* libpng comments:
*
* this function is called for every row in the image. If the
* image is interlacing, and you turned on the interlace handler,
* this function will be called for every row in every pass.
* Some of these rows will not be changed from the previous pass.
* When the row is not changed, the new_row variable will be NULL.
* The rows and passes are called in order, so you don't really
* need the row_num and pass, but I'm supplying them because it
* may make your life easier.
*
* For the non-NULL rows of interlaced images, you must call
* png_progressive_combine_row() passing in the row and the
* old row. You can call this function for NULL rows (it will
* just return) and for non-interlaced images (it just does the
* memcpy for you) if it will make the code easier. Thus, you
* can just do this for all cases:
*
* png_progressive_combine_row(png_ptr, old_row, new_row);
*
* where old_row is what was displayed for previous rows. Note
* that the first pass (pass == 0 really) will completely cover
* the old row, so the rows do not have to be initialized. After
* the first pass (and only for interlaced images), you will have
* to pass the current row, and the function will combine the
* old row and the new row.
*/
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
PRUint32 bpr, abpr;
decoder->mFrame->GetImageBytesPerRow(&bpr);
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
png_bytep line;
if (decoder->interlacebuf) {
line = decoder->interlacebuf+(row_num*decoder->ibpr);
png_progressive_combine_row(png_ptr, line, new_row);
}
else
line = new_row;
if (new_row) {
nscoord width;
decoder->mFrame->GetWidth(&width);
PRUint32 iwidth = width;
gfx_format format;
decoder->mFrame->GetFormat(&format);
PRUint8 *aptr, *cptr;
// The mac specific ifdefs in the code below are there to make sure we
// always fill in 4 byte pixels right now, which is what the mac always
// allocates for its pixel buffers in true color mode. This will change
// when we start storing images with color palettes when they don't need
// true color support (GIFs).
switch (format) {
case gfxIFormats::RGB:
case gfxIFormats::BGR:
#ifdef XP_MAC
cptr = decoder->colorLine;
for (PRUint32 x=0; x<iwidth; x++) {
*cptr++ = 0;
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
#else
decoder->mFrame->SetImageData((PRUint8*)line, bpr, row_num*bpr);
#endif
break;
case gfxIFormats::RGB_A1:
case gfxIFormats::BGR_A1:
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
memset(aptr, 0, abpr);
for (PRUint32 x=0; x<iwidth; x++) {
#ifdef XP_MAC
*cptr++ = 0;
#endif
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
if (*line++) {
aptr[x>>3] |= 1<<(7-x&0x7);
}
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
break;
case gfxIFormats::RGB_A8:
case gfxIFormats::BGR_A8:
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
for (PRUint32 x=0; x<iwidth; x++) {
#ifdef XP_MAC
*cptr++ = 0;
#endif
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
*aptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
break;
case gfxIFormats::RGBA:
case gfxIFormats::BGRA:
#ifdef XP_MAC
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
for (PRUint32 x=0; x<iwidth; x++) {
*cptr++ = 0;
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
*aptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
#else
decoder->mFrame->SetImageData(line, bpr, row_num*bpr);
#endif
break;
}
nsRect r(0, row_num, width, 1);
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mFrame, &r);
}
}
void
nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
{
/* libpng comments:
*
* this function is called when the whole image has been read,
* including any chunks after the image (up to and including
* the IEND). You will usually have the same info chunk as you
* had in the header, although some data may have been added
* to the comments and time fields.
*
* Most people won't do much here, perhaps setting a flag that
* marks the image as finished.
*/
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
if (decoder->mObserver) {
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mFrame);
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImage);
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
}

View File

@@ -1,82 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsPNGDecoder_h__
#define nsPNGDecoder_h__
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#include "nsCOMPtr.h"
#include "png.h"
#define NS_PNGDECODER_CID \
{ /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */ \
0x36fa00c2, \
0x1dd2, \
0x11b2, \
{0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \
}
class nsPNGDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsPNGDecoder();
virtual ~nsPNGDecoder();
PR_STATIC_CALLBACK(void)
info_callback(png_structp png_ptr, png_infop info_ptr);
PR_STATIC_CALLBACK(void)
row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass);
PR_STATIC_CALLBACK(void)
end_callback(png_structp png_ptr, png_infop info_ptr);
inline PRUint32 ProcessData(unsigned char *data, PRUint32 count);
public:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
png_structp mPNG;
png_infop mInfo;
PRUint8 *colorLine, *alphaLine;
PRUint8 *interlacebuf;
PRUint32 ibpr;
};
#endif // nsPNGDecoder_h__

View File

@@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsPNGDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder)
static nsModuleComponentInfo components[] =
{
{ "PNG decoder",
NS_PNGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/png",
nsPNGDecoderConstructor, },
{ "PNG decoder",
NS_PNGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/x-png",
nsPNGDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsPNGDecoderModule", components)

View File

@@ -1,42 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgppm
LIBRARY_NAME = imgppm
IS_COMPONENT = 1
REQUIRES = xpcom layout necko gfx2 imglib2
CPPSRCS = nsPPMDecoder.cpp nsPPMFactory.cpp
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,51 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgppm
LIBRARY_NAME = imgppm
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsPPMDecoder.obj \
.\$(OBJDIR)\nsPPMFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,305 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsPPMDecoder.h"
#include "nsIInputStream.h"
#include "imgIContainer.h"
#include "imgIContainerObserver.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "nsRect.h"
NS_IMPL_ISUPPORTS2(nsPPMDecoder, imgIDecoder, nsIOutputStream)
nsPPMDecoder::nsPPMDecoder()
{
NS_INIT_ISUPPORTS();
mDataReceived = 0;
mDataWritten = 0;
mDataLeft = 0;
mPrevData = nsnull;
}
nsPPMDecoder::~nsPPMDecoder()
{
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsPPMDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
if (!mFrame)
return NS_ERROR_FAILURE;
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsPPMDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsPPMDecoder::Close()
{
if (mObserver) {
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
mObserver->OnStopContainer(nsnull, nsnull, mImage);
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsPPMDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
static char *__itoa(int n)
{
char *s;
int i, j, sign, tmp;
/* check sign and convert to positive to stringify numbers */
if ( (sign = n) < 0)
n = -n;
i = 0;
s = (char*) malloc(sizeof(char));
/* grow string as needed to add numbers from powers of 10
* down till none left
*/
do
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start */
s[i] = '\0';
}
while( (n /= 10) > 0);
/* tack on minus sign if we found earlier that this was negative */
if (sign < 0)
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = '-';
}
s[i] = '\0';
/* pop numbers (and sign) off of string to push back into right direction */
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
return s;
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
nsresult rv;
char *buf = (char *)PR_Malloc(count + mDataLeft);
if (!buf)
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
// read the data from the input stram...
PRUint32 readLen;
rv = inStr->Read(buf+mDataLeft, count, &readLen);
PRUint32 dataLen = readLen + mDataLeft;
if (mPrevData) {
strncpy(buf, mPrevData, mDataLeft);
PR_Free(mPrevData);
mPrevData = nsnull;
mDataLeft = 0;
}
char *data = buf;
if (NS_FAILED(rv)) return rv;
if (mDataReceived == 0) {
mObserver->OnStartDecode(nsnull, nsnull);
// Check the magic number
char type;
if ((sscanf(data, "P%c\n", &type) !=1) || (type != '6')) {
return NS_ERROR_FAILURE;
}
int i = 3;
data += i;
#if 0
// XXX
// Ignore comments
while ((input = fgetc(f)) == '#')
fgets(junk, 512, f);
ungetc(input, f);
#endif
// Read size
int w, h, mcv;
if (sscanf(data, "%d %d\n%d\n", &w, &h, &mcv) != 3) {
return NS_ERROR_FAILURE;
}
char *ws = __itoa(w), *hs = __itoa(h), *mcvs = __itoa(mcv);
int j = strlen(ws) + strlen(hs) + strlen(mcvs) + 3;
data += j;
// free(ws);
// free(hs);
// free(mcvs);
readLen -= i + j;
dataLen = readLen; // since this is the first pass, we don't have any data waiting that we need to keep track of
mImage->Init(w, h, mObserver);
if (mObserver)
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame->Init(0, 0, w, h, gfxIFormats::RGB);
mImage->AppendFrame(mFrame);
if (mObserver)
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
}
PRUint32 bpr;
nscoord width;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->GetWidth(&width);
// XXX ceil?
PRUint32 real_bpr = width * 3;
PRUint32 i = 0;
PRUint32 rownum = mDataWritten / real_bpr; // XXX this better not have a decimal
PRUint32 wroteLen = 0;
if (readLen > real_bpr) {
do {
PRUint8 *line = (PRUint8*)data + i*real_bpr;
mFrame->SetImageData(line, real_bpr, (rownum++)*bpr);
nsRect r(0, rownum, width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
wroteLen += real_bpr ;
i++;
} while(dataLen >= real_bpr * (i+1));
}
mDataReceived += readLen; // don't double count previous data that is in 'dataLen'
mDataWritten += wroteLen;
PRUint32 dataLeft = dataLen - wroteLen;
if (dataLeft > 0) {
if (mPrevData) {
mPrevData = (char *)PR_Realloc(mPrevData, mDataLeft + dataLeft);
strncpy(mPrevData + mDataLeft, data+wroteLen, dataLeft);
mDataLeft += dataLeft;
} else {
mDataLeft = dataLeft;
mPrevData = (char *)PR_Malloc(mDataLeft);
strncpy(mPrevData, data+wroteLen, mDataLeft);
}
}
PR_FREEIF(buf);
return NS_OK;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsPPMDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPPMDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsPPMDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPPMDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsPPMDecoder_h__
#define nsPPMDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#define NS_PPMDECODER_CID \
{ /* e90bfa06-1dd1-11b2-8217-f38fe5d431a2 */ \
0xe90bfa06, \
0x1dd1, \
0x11b2, \
{0x82, 0x17, 0xf3, 0x8f, 0xe5, 0xd4, 0x31, 0xa2} \
}
class nsPPMDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsPPMDecoder();
virtual ~nsPPMDecoder();
private:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
PRUint32 mDataReceived;
PRUint32 mDataWritten;
PRUint32 mDataLeft;
char *mPrevData;
};
#endif // nsPPMDecoder_h__

View File

@@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsPPMDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPPMDecoder)
static nsModuleComponentInfo components[] =
{
{ "ppm decoder",
NS_PPMDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/x-portable-pixmap",
nsPPMDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsPPMDecoderModule", components)

View File

@@ -1,111 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "prlog.h"
#include "nsString.h"
#if defined(PR_LOGGING)
extern PRLogModuleInfo *gImgLog;
class LogScope {
public:
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {ENTER}\n",
mFrom, mFunc.get()));
}
/* const char * constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, const char *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%s\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* void ptr constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, const void *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=%p) {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* PRInt32 constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, PRInt32 paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* PRUint32 constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, PRUint32 paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
~LogScope() {
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {EXIT}\n",
mFrom, mFunc.get()));
}
private:
PRLogModuleInfo *mLog;
void *mFrom;
nsCAutoString mFunc;
};
#define LOG_SCOPE(l, s) \
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
NS_STATIC_CAST(void *, this), \
NS_LITERAL_CSTRING(s))
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
NS_STATIC_CAST(void *, this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#else
#define LOG_SCOPE(l, s)
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv)
#endif

View File

@@ -1 +0,0 @@
ImageLogging.h

View File

@@ -1,6 +0,0 @@
imgIContainer.idl
imgIContainerObserver.idl
imgIDecoder.idl
imgIDecoderObserver.idl
imgILoader.idl
imgIRequest.idl

View File

@@ -1,41 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imglib2
EXPORTS = ImageLogging.h
XPIDLSRCS = imgIContainer.idl \
imgIContainerObserver.idl \
imgIDecoder.idl \
imgIDecoderObserver.idl \
imgILoader.idl \
imgIRequest.idl
include $(topsrcdir)/config/rules.mk

View File

@@ -1,109 +0,0 @@
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsISupports.idl"
#include "gfxtypes.idl"
#include "gfxIFormats.idl"
interface gfxIImageFrame;
interface nsIEnumerator;
interface imgIContainerObserver;
/**
* gfxIImageContainer interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see "gfx2"
*/
[scriptable, uuid(5e8405a4-1dd2-11b2-8385-bc8e3446cad3)]
interface imgIContainer : nsISupports
{
/**
* Create a new \a aWidth x \a aHeight sized image container.
*
* @param aWidth The width of the container in which all the
* gfxIImageFrame children will fit.
* @param aHeight The height of the container in which all the
* gfxIImageFrame children will fit.
* @param aObserver Observer to send animation notifications to.
*/
void init(in nscoord aWidth,
in nscoord aHeight,
in imgIContainerObserver aObserver);
/* this should probably be on the device context (or equiv) */
readonly attribute gfx_format preferredAlphaChannelFormat;
/**
* The width of the container rectangle.
*/
readonly attribute nscoord width;
/**
* The height of the container rectangle.
*/
readonly attribute nscoord height;
/**
* Get the current frame that would be drawn if the image was to be drawn now
*/
readonly attribute gfxIImageFrame currentFrame;
readonly attribute unsigned long numFrames;
gfxIImageFrame getFrameAt(in unsigned long index);
/**
* Adds \a item to the end of the list of frames.
* @param item frame to add.
*/
void appendFrame(in gfxIImageFrame item);
void removeFrame(in gfxIImageFrame item);
/* notification when the current frame is done decoding */
void endFrameDecode(in unsigned long framenumber, in unsigned long timeout);
/* notification that the entire image has been decoded */
void decodingComplete();
nsIEnumerator enumerate();
void clear();
void startAnimation();
void stopAnimation();
/* animation stuff */
/**
* number of times to loop the image.
* @note -1 means forever.
*/
attribute long loopCount;
};

View File

@@ -1,46 +0,0 @@
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsISupports.idl"
#include "gfxtypes.idl"
%{C++
#include "nsRect.h"
%}
interface imgIContainer;
interface gfxIImageFrame;
/**
* imgIContainerObserver interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
*/
[uuid(153f1518-1dd2-11b2-b9cd-b16eb63e0471)]
interface imgIContainerObserver : nsISupports
{
[noscript] void frameChanged(in imgIContainer aContainer, in nsISupports aCX,
in gfxIImageFrame aFrame, in nsRect aDirtyRect);
};

View File

@@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsISupports.idl"
#include "nsIOutputStream.idl"
#include "gfxtypes.idl"
interface imgIRequest;
/**
* imgIDecoder interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(9eebf43a-1dd1-11b2-953e-f1782f4cbad3)]
interface imgIDecoder : nsIOutputStream
{
/**
* Initalize an image decoder.
* @param aRequest the request that owns the decoder.
*
* @note The decode should QI \a aRequest to an imgIDecoderObserver
* and should send decoder notifications to the request.
* The decoder should always pass NULL as the first two parameters to
* all of the imgIDecoderObserver APIs.
*/
void init(in imgIRequest aRequest);
/// allows access to the nsIImage we have to put bits in to.
readonly attribute imgIRequest request;
};

View File

@@ -1,80 +0,0 @@
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgIContainerObserver.idl"
interface imgIRequest;
interface imgIContainer;
interface gfxIImageFrame;
%{C++
#include "nsRect.h"
%}
/**
* imgIDecoderObserver interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(350163d2-1dd2-11b2-9e69-89959ecec1f3)]
interface imgIDecoderObserver : imgIContainerObserver
{
/**
* called as soon as the image begins getting decoded
*/
void onStartDecode(in imgIRequest aRequest, in nsISupports cx);
/**
* called once the image has been inited and therefore has a width and height
*/
void onStartContainer(in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer);
/**
* called when each frame is created
*/
void onStartFrame(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame);
/**
* called when some part of the frame has new data in it
*/
[noscript] void onDataAvailable(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame, [const] in nsRect aRect);
/**
* called when a frame is finished decoding
*/
void onStopFrame(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame);
/**
* probably not needed. called right before onStopDecode
*/
void onStopContainer(in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer);
/**
* called when the decoder is dying off
*/
void onStopDecode(in imgIRequest aRequest, in nsISupports cx,
in nsresult status, in wstring statusArg);
};

View File

@@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsISupports.idl"
#include "gfxtypes.idl"
interface imgIDecoderObserver;
interface imgIRequest;
interface nsIChannel;
interface nsILoadGroup;
interface nsIStreamListener;
interface nsIURI;
interface nsISimpleEnumerator;
/**
* imgILoader interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(4c8cf1e0-1dd2-11b2-aff9-c51cdbfcb6da)]
interface imgILoader : nsISupports
{
/**
* Start the load and decode of an image.
* @param uri the URI to load
* @param aObserver the observer
* @param cx some random data
*/
imgIRequest loadImage(in nsIURI uri, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports cx);
/**
* Start the load and decode of an image.
* @param uri the URI to load
* @param aObserver the observer
* @param cx some random data
*/
imgIRequest loadImageWithChannel(in nsIChannel aChannel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener aListener);
};

View File

@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsISupports.idl"
#include "nsIRequest.idl"
interface imgIContainer;
interface imgIDecoderObserver;
interface nsIURI;
/**
* imgIRequest interface
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(ccf705f6-1dd1-11b2-82ef-e18eccf7f7ec)]
interface imgIRequest : nsIRequest
{
/**
* the image container...
* @return the image object associated with the request.
* @attention NEED DOCS
*/
readonly attribute imgIContainer image;
/**
* Bits set in the return value from imageStatus
* @name statusflags
*/
//@{
const long STATUS_NONE = 0x0;
const long STATUS_SIZE_AVAILABLE = 0x1;
const long STATUS_LOAD_COMPLETE = 0x2;
const long STATUS_ERROR = 0x4;
//@}
/**
* something
* @attention NEED DOCS
*/
readonly attribute unsigned long imageStatus;
readonly attribute nsIURI URI;
readonly attribute imgIDecoderObserver decoderObserver;
};
%{C++
/**
* imagelib specific nsresult success and error codes
*/
#define NS_IMAGELIB_SUCCESS_LOAD_FINISHED NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_IMGLIB, 0)
#define NS_IMAGELIB_ERROR_FAILURE NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 5)
#define NS_IMAGELIB_ERROR_NO_DECODER NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 6)
%}

View File

@@ -1,43 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imglib2
XPIDL_MODULE = imglib2
EXPORTS = ImageLogging.h
XPIDLSRCS = \
.\imgIContainer.idl \
.\imgIContainerObserver.idl \
.\imgIDecoder.idl \
.\imgIDecoderObserver.idl \
.\imgILoader.idl \
.\imgIRequest.idl \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,146 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "DummyChannel.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
NS_IMPL_ISUPPORTS1(DummyChannel, nsIChannel)
DummyChannel::DummyChannel(imgIRequest *aRequest, nsILoadGroup *aLoadGroup) :
mRequest(aRequest),
mLoadGroup(aLoadGroup),
mLoadFlags(nsIChannel::LOAD_NORMAL)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
DummyChannel::~DummyChannel()
{
/* destructor code */
}
/* attribute nsIURI originalURI; */
NS_IMETHODIMP DummyChannel::GetOriginalURI(nsIURI * *aOriginalURI)
{
return mRequest->GetURI(aOriginalURI);
}
NS_IMETHODIMP DummyChannel::SetOriginalURI(nsIURI * aOriginalURI)
{
return NS_ERROR_FAILURE;
}
/* attribute nsIURI URI; */
NS_IMETHODIMP DummyChannel::GetURI(nsIURI * *aURI)
{
return mRequest->GetURI(aURI);
}
NS_IMETHODIMP DummyChannel::SetURI(nsIURI * aURI)
{
return NS_ERROR_FAILURE;
}
/* attribute nsISupports owner; */
NS_IMETHODIMP DummyChannel::GetOwner(nsISupports * *aOwner)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP DummyChannel::SetOwner(nsISupports * aOwner)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsILoadGroup loadGroup; */
NS_IMETHODIMP DummyChannel::GetLoadGroup(nsILoadGroup * *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP DummyChannel::SetLoadGroup(nsILoadGroup * aLoadGroup)
{
return NS_ERROR_FAILURE;
}
/* attribute nsLoadFlags loadAttributes; */
NS_IMETHODIMP DummyChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
*aLoadAttributes = mLoadFlags;
return NS_OK;
}
NS_IMETHODIMP DummyChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
mLoadFlags = aLoadAttributes;
return NS_OK;
}
/* attribute nsIInterfaceRequestor notificationCallbacks; */
NS_IMETHODIMP DummyChannel::GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks)
{
return NS_OK;
}
NS_IMETHODIMP DummyChannel::SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks)
{
return NS_OK;
}
/* readonly attribute nsISupports securityInfo; */
NS_IMETHODIMP DummyChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute string contentType; */
NS_IMETHODIMP DummyChannel::GetContentType(char * *aContentType)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP DummyChannel::SetContentType(const char * aContentType)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute long contentLength; */
NS_IMETHODIMP DummyChannel::GetContentLength(PRInt32 *aContentLength)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP DummyChannel::SetContentLength(PRInt32 aContentLength)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* nsIInputStream open (); */
NS_IMETHODIMP DummyChannel::Open(nsIInputStream **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void asyncOpen (in nsIStreamListener listener, in nsISupports ctxt); */
NS_IMETHODIMP DummyChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef DummyChannel_h__
#define DummyChannel_h__
#include "nsIChannel.h"
#include "nsIRequest.h"
#include "nsILoadGroup.h"
#include "imgIRequest.h"
#include "nsCOMPtr.h"
class DummyChannel : public nsIChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICHANNEL
NS_FORWARD_NSIREQUEST(mRequest->)
DummyChannel(imgIRequest *aRequest, nsILoadGroup *aLoadGroup);
~DummyChannel();
private:
/* additional members */
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsLoadFlags mLoadFlags;
};
#endif

View File

@@ -1,166 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "ImageCache.h"
#ifdef MOZ_NEW_CACHE
#include "prlog.h"
#if defined(PR_LOGGING)
extern PRLogModuleInfo *gImgLog;
#else
#define gImgLog
#endif
#include "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsICache.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsICacheEntryDescriptor.h"
static nsCOMPtr<nsICacheSession> gSession = nsnull;
ImageCache::ImageCache()
{
/* member initializers and constructor code */
}
ImageCache::~ImageCache()
{
/* destructor code */
}
void GetCacheSession(nsICacheSession **_retval)
{
if (!gSession) {
nsCOMPtr<nsICacheService> cacheService(do_GetService("@mozilla.org/network/cache-service;1"));
NS_ASSERTION(cacheService, "Unable to get the cache service");
cacheService->CreateSession("images", nsICache::NOT_STREAM_BASED, PR_FALSE, getter_AddRefs(gSession));
NS_ASSERTION(gSession, "Unable to create a cache session");
}
*_retval = gSession;
NS_IF_ADDREF(*_retval);
}
void ImageCache::Shutdown()
{
gSession = nsnull;
}
PRBool ImageCache::Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("ImageCache::Put\n"));
nsresult rv;
nsCOMPtr<nsICacheSession> ses;
GetCacheSession(getter_AddRefs(ses));
nsXPIDLCString spec;
aKey->GetSpec(getter_Copies(spec));
nsCOMPtr<nsICacheEntryDescriptor> entry;
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_WRITE, getter_AddRefs(entry));
if (!entry || NS_FAILED(rv))
return PR_FALSE;
entry->SetCacheElement(NS_STATIC_CAST(nsISupports *, NS_STATIC_CAST(imgIRequest*, request)));
entry->MarkValid();
*aEntry = entry;
NS_ADDREF(*aEntry);
return PR_TRUE;
}
PRBool ImageCache::Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("ImageCache::Get\n"));
nsresult rv;
nsCOMPtr<nsICacheSession> ses;
GetCacheSession(getter_AddRefs(ses));
nsXPIDLCString spec;
aKey->GetSpec(getter_Copies(spec));
nsCOMPtr<nsICacheEntryDescriptor> entry;
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, getter_AddRefs(entry));
if (!entry || NS_FAILED(rv))
return PR_FALSE;
nsCOMPtr<nsISupports> sup;
entry->GetCacheElement(getter_AddRefs(sup));
nsCOMPtr<imgIRequest> req(do_QueryInterface(sup));
*aRequest = NS_REINTERPRET_CAST(imgRequest*, req.get());
NS_IF_ADDREF(*aRequest);
*aEntry = entry;
NS_ADDREF(*aEntry);
return PR_TRUE;
}
PRBool ImageCache::Remove(nsIURI *aKey)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("ImageCache::Remove\n"));
nsresult rv;
nsCOMPtr<nsICacheSession> ses;
GetCacheSession(getter_AddRefs(ses));
nsXPIDLCString spec;
aKey->GetSpec(getter_Copies(spec));
nsCOMPtr<nsICacheEntryDescriptor> entry;
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, getter_AddRefs(entry));
if (!entry || NS_FAILED(rv))
return PR_FALSE;
entry->Doom();
return PR_TRUE;
}
#endif /* MOZ_NEW_CACHE */

View File

@@ -1,72 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef ImageCache_h__
#define ImageCache_h__
#include "nsIURI.h"
#include "imgRequest.h"
#include "prtypes.h"
#ifdef MOZ_NEW_CACHE
#include "nsICacheEntryDescriptor.h"
#else
class nsICacheEntryDescriptor;
#endif
class ImageCache
{
public:
#ifdef MOZ_NEW_CACHE
ImageCache();
~ImageCache();
static void Shutdown(); // for use by the factory
/* additional members */
static PRBool Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry);
static PRBool Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry);
static PRBool Remove(nsIURI *aKey);
#else
ImageCache() { }
~ImageCache() { }
static void Shutdown() { }
/* additional members */
static PRBool Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry) {
return PR_FALSE;
}
static PRBool Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry) {
return PR_FALSE;
}
static PRBool Remove(nsIURI *aKey) {
return PR_FALSE;
}
#endif /* MOZ_NEW_CACHE */
};
#endif

View File

@@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "imgContainer.h"
#include "imgLoader.h"
#include "imgRequest.h"
#include "imgRequestProxy.h"
#include "ImageCache.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(imgContainer)
NS_GENERIC_FACTORY_CONSTRUCTOR(imgLoader)
NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequest)
NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy)
static nsModuleComponentInfo components[] =
{
{ "image container",
NS_IMGCONTAINER_CID,
"@mozilla.org/image/container;1",
imgContainerConstructor, },
{ "image loader",
NS_IMGLOADER_CID,
"@mozilla.org/image/loader;1",
imgLoaderConstructor, },
{ "image request",
NS_IMGREQUEST_CID,
"@mozilla.org/image/request/real;1",
imgRequestConstructor, },
{ "image request proxy",
NS_IMGREQUESTPROXY_CID,
"@mozilla.org/image/request/proxy;1",
imgRequestProxyConstructor, },
};
PR_STATIC_CALLBACK(void)
ImageModuleDestructor(nsIModule *self)
{
ImageCache::Shutdown();
}
NS_IMPL_NSGETMODULE_WITH_DTOR("nsImageLib2Module", components, ImageModuleDestructor)

View File

@@ -1,49 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imglib2
LIBRARY_NAME = imglib2
IS_COMPONENT = 1
REQUIRES = xpcom string necko nkcache layout timer gfx2
CPPSRCS = \
DummyChannel.cpp \
ImageCache.cpp \
ImageFactory.cpp \
imgContainer.cpp \
imgLoader.cpp \
imgRequest.cpp \
imgRequestProxy.cpp
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,555 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
* Chris Saari <saari@netscape.com>
*/
#include "imgContainer.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "gfxIImageFrame.h"
#include "nsIImage.h"
NS_IMPL_ISUPPORTS3(imgContainer, imgIContainer, nsITimerCallback,imgIDecoderObserver)
//******************************************************************************
imgContainer::imgContainer()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mCurrentDecodingFrameIndex = 0;
mCurrentAnimationFrameIndex = 0;
mCurrentFrameIsFinishedDecoding = PR_FALSE;
mDoneDecoding = PR_FALSE;
mAnimating = PR_FALSE;
mObserver = nsnull;
}
//******************************************************************************
imgContainer::~imgContainer()
{
if (mTimer)
mTimer->Cancel();
/* destructor code */
mFrames.Clear();
}
//******************************************************************************
/* void init (in nscoord aWidth, in nscoord aHeight, in imgIContainerObserver aObserver); */
NS_IMETHODIMP imgContainer::Init(nscoord aWidth, nscoord aHeight, imgIContainerObserver *aObserver)
{
if (aWidth <= 0 || aHeight <= 0) {
NS_WARNING("error - negative image size\n");
return NS_ERROR_FAILURE;
}
mSize.SizeTo(aWidth, aHeight);
mObserver = getter_AddRefs(NS_GetWeakReference(aObserver));
return NS_OK;
}
//******************************************************************************
/* readonly attribute gfx_format preferredAlphaChannelFormat; */
NS_IMETHODIMP imgContainer::GetPreferredAlphaChannelFormat(gfx_format *aFormat)
{
/* default.. platform's should probably overwrite this */
*aFormat = gfxIFormats::RGB_A8;
return NS_OK;
}
//******************************************************************************
/* readonly attribute nscoord width; */
NS_IMETHODIMP imgContainer::GetWidth(nscoord *aWidth)
{
*aWidth = mSize.width;
return NS_OK;
}
//******************************************************************************
/* readonly attribute nscoord height; */
NS_IMETHODIMP imgContainer::GetHeight(nscoord *aHeight)
{
*aHeight = mSize.height;
return NS_OK;
}
//******************************************************************************
/* readonly attribute gfxIImageFrame currentFrame; */
NS_IMETHODIMP imgContainer::GetCurrentFrame(gfxIImageFrame * *aCurrentFrame)
{
if(mCompositingFrame)
return mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aCurrentFrame); // addrefs again
else
return this->GetFrameAt(mCurrentAnimationFrameIndex, aCurrentFrame);
}
//******************************************************************************
/* readonly attribute unsigned long numFrames; */
NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames)
{
return mFrames.Count(aNumFrames);
}
//******************************************************************************
/* gfxIImageFrame getFrameAt (in unsigned long index); */
NS_IMETHODIMP imgContainer::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval)
{
nsISupports *sup = mFrames.ElementAt(index); // addrefs
if (!sup)
return NS_ERROR_FAILURE;
nsresult rv;
rv = sup->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)_retval); // addrefs again
NS_RELEASE(sup);
return rv;
}
//******************************************************************************
/* void appendFrame (in gfxIImageFrame item); */
NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item)
{
// If we don't have a composite frame already allocated, make sure that our container
// size is the same the frame size. Otherwise, we'll either need the composite frame
// for animation compositing (GIF) or for filling in with a background color.
// XXX IMPORTANT: this means that the frame should be initialized BEFORE appending to container
PRUint32 numFrames;
this->GetNumFrames(&numFrames);
if(!mCompositingFrame) {
nsRect frameRect;
item->GetRect(frameRect);
// We used to create a compositing frame if any frame was smaller than the logical
// image size. You could create a single frame that was 10x10 in the middle of
// an 20x20 logical screen and have the extra screen space filled by the image
// background color. However, it turns out that neither NS4.x nor IE correctly
// support this, and as a result there are many GIFs out there that look "wrong"
// when this is correctly supported. So for now, we only create a compositing frame
// if we have more than one frame in the image.
if(/*(frameRect.x != 0) ||
(frameRect.y != 0) ||
(frameRect.width != mSize.width) ||
(frameRect.height != mSize.height) ||*/
(numFrames >= 1)) // Not sure if I want to create a composite frame for every anim. Could be smarter.
{
mCompositingFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
mCompositingFrame->Init(0, 0, mSize.width, mSize.height, gfxIFormats::RGB);
nsCOMPtr<nsIImage> img(do_GetInterface(mCompositingFrame));
img->SetDecodedRect(0, 0, mSize.width, mSize.height);
nsCOMPtr<gfxIImageFrame> firstFrame;
this->GetFrameAt(0, getter_AddRefs(firstFrame));
firstFrame->DrawTo(mCompositingFrame, 0, 0, mSize.width, mSize.height);
}
}
// If this is our second frame, init a timer so we don't display
// the next frame until the delay timer has expired for the current
// frame.
if (!mTimer && (numFrames >= 1)) {
PRInt32 timeout;
nsCOMPtr<gfxIImageFrame> currentFrame;
this->GetFrameAt(mCurrentDecodingFrameIndex, getter_AddRefs(currentFrame));
currentFrame->GetTimeout(&timeout);
if (timeout != -1 &&
timeout >= 0) { // -1 means display this frame forever
if(mAnimating) {
// Since we have more than one frame we need a timer
mTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimer->Init(
NS_STATIC_CAST(nsITimerCallback*, this),
timeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
}
}
}
if (numFrames > 0) mCurrentDecodingFrameIndex++;
mCurrentFrameIsFinishedDecoding = PR_FALSE;
return mFrames.AppendElement(NS_STATIC_CAST(nsISupports*, item));
}
//******************************************************************************
/* void removeFrame (in gfxIImageFrame item); */
NS_IMETHODIMP imgContainer::RemoveFrame(gfxIImageFrame *item)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* void endFrameDecode (in gfxIImageFrame item, in unsigned long timeout); */
NS_IMETHODIMP imgContainer::EndFrameDecode(PRUint32 aFrameNum, PRUint32 aTimeout)
{
// It is now okay to start the timer for the next frame in the animation
mCurrentFrameIsFinishedDecoding = PR_TRUE;
nsCOMPtr<gfxIImageFrame> currentFrame;
this->GetFrameAt(aFrameNum-1, getter_AddRefs(currentFrame));
currentFrame->SetTimeout(aTimeout);
if (!mTimer && mAnimating){
PRUint32 numFrames;
this->GetNumFrames(&numFrames);
if (numFrames > 1) {
if (aTimeout != -1 &&
aTimeout >= 0) { // -1 means display this frame forever
mAnimating = PR_TRUE;
mTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
aTimeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
}
}
}
return NS_OK;
}
//******************************************************************************
/* void decodingComplete (); */
NS_IMETHODIMP imgContainer::DecodingComplete(void)
{
mDoneDecoding = PR_TRUE;
return NS_OK;
}
//******************************************************************************
/* nsIEnumerator enumerate (); */
NS_IMETHODIMP imgContainer::Enumerate(nsIEnumerator **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void clear (); */
NS_IMETHODIMP imgContainer::Clear()
{
return mFrames.Clear();
}
//******************************************************************************
/* void startAnimation () */
NS_IMETHODIMP imgContainer::StartAnimation()
{
mAnimating = PR_TRUE;
if (mTimer)
return NS_OK;
PRUint32 numFrames;
this->GetNumFrames(&numFrames);
if (numFrames > 1) {
PRInt32 timeout;
nsCOMPtr<gfxIImageFrame> currentFrame;
this->GetCurrentFrame(getter_AddRefs(currentFrame));
if (currentFrame) {
currentFrame->GetTimeout(&timeout);
if (timeout != -1 &&
timeout >= 0) { // -1 means display this frame forever
mAnimating = PR_TRUE;
if(!mTimer) mTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
timeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
}
} else {
// XXX hack.. the timer notify code will do the right thing, so just get that started
mAnimating = PR_TRUE;
if(!mTimer) mTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
100, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
}
}
return NS_OK;
}
//******************************************************************************
/* void stopAnimation (); */
NS_IMETHODIMP imgContainer::StopAnimation()
{
mAnimating = PR_FALSE;
if (!mTimer)
return NS_OK;
mTimer->Cancel();
mTimer = nsnull;
// don't bother trying to change the frame (to 0, etc.) here.
// No one is listening.
return NS_OK;
}
//******************************************************************************
/* attribute long loopCount; */
NS_IMETHODIMP imgContainer::GetLoopCount(PRInt32 *aLoopCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP_(void) imgContainer::Notify(nsITimer *timer)
{
NS_ASSERTION(mTimer == timer, "uh");
if(!mAnimating || !mTimer)
return;
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
if (!observer) {
// the imgRequest that owns us is dead, we should die now too.
this->StopAnimation();
return;
}
nsCOMPtr<gfxIImageFrame> nextFrame;
PRInt32 timeout = 100;
PRUint32 numFrames;
GetNumFrames(&numFrames);
if(!numFrames)
return;
// If we're done decoding the next frame, go ahead and display it now and reinit
// the timer with the next frame's delay time.
PRUint32 previousAnimationFrameIndex = mCurrentAnimationFrameIndex;
if (mCurrentFrameIsFinishedDecoding && !mDoneDecoding) {
// If we have the next frame in the sequence set the timer callback from it
GetFrameAt(mCurrentAnimationFrameIndex+1, getter_AddRefs(nextFrame));
if (nextFrame) {
// Go to next frame in sequence
nextFrame->GetTimeout(&timeout);
mCurrentAnimationFrameIndex++;
} else {
// twiddle our thumbs
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
if(!nextFrame) return;
nextFrame->GetTimeout(&timeout);
}
} else if (mDoneDecoding){
if ((numFrames-1) == mCurrentAnimationFrameIndex) {
// Go back to the beginning of the animation
GetFrameAt(0, getter_AddRefs(nextFrame));
if(!nextFrame) return;
mCurrentAnimationFrameIndex = 0;
nextFrame->GetTimeout(&timeout);
} else {
mCurrentAnimationFrameIndex++;
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
if(!nextFrame) return;
nextFrame->GetTimeout(&timeout);
}
} else {
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
if(!nextFrame) return;
}
if(timeout >= 0)
mTimer->SetDelay(timeout);
else
this->StopAnimation();
nsRect dirtyRect;
// update the composited frame
if(mCompositingFrame && (previousAnimationFrameIndex != mCurrentAnimationFrameIndex)) {
nsCOMPtr<gfxIImageFrame> frameToUse;
DoComposite(getter_AddRefs(frameToUse), &dirtyRect, previousAnimationFrameIndex, mCurrentAnimationFrameIndex);
// do notification to FE to draw this frame, but hand it the compositing frame
observer->FrameChanged(this, nsnull, mCompositingFrame, &dirtyRect);
}
else {
nextFrame->GetRect(dirtyRect);
// do notification to FE to draw this frame
observer->FrameChanged(this, nsnull, nextFrame, &dirtyRect);
}
}
//******************************************************************************
// DoComposite gets called when the timer for animation get fired and we have to
// update the composited frame of the animation.
void imgContainer::DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect, PRInt32 aPrevFrame, PRInt32 aNextFrame)
{
NS_ASSERTION(aDirtyRect, "DoComposite aDirtyRect is null");
NS_ASSERTION(mCompositingFrame, "DoComposite mCompositingFrame is null");
*aFrameToUse = nsnull;
PRUint32 numFrames;
this->GetNumFrames(&numFrames);
PRInt32 nextFrameIndex = aNextFrame;
PRInt32 prevFrameIndex = aPrevFrame;
if(nextFrameIndex >= numFrames) nextFrameIndex = numFrames-1;
if(prevFrameIndex >= numFrames) prevFrameIndex = numFrames-1;
nsCOMPtr<gfxIImageFrame> prevFrame;
this->GetFrameAt(prevFrameIndex, getter_AddRefs(prevFrame));
PRInt32 prevFrameDisposalMethod;
prevFrame->GetFrameDisposalMethod(&prevFrameDisposalMethod);
nsCOMPtr<gfxIImageFrame> nextFrame;
this->GetFrameAt(nextFrameIndex, getter_AddRefs(nextFrame));
PRInt32 x;
PRInt32 y;
PRInt32 width;
PRInt32 height;
nextFrame->GetX(&x);
nextFrame->GetY(&y);
nextFrame->GetWidth(&width);
nextFrame->GetHeight(&height);
switch (prevFrameDisposalMethod) {
default:
case 0: // DISPOSE_NOT_SPECIFIED
case 1: // DISPOSE_KEEP Leave previous frame in the framebuffer
mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aFrameToUse); // addrefs again
//XXX blit into the composite frame too!!!
nextFrame->DrawTo(mCompositingFrame, x, y, width, height);
// we're drawing only the updated frame
(*aDirtyRect).x = x;
(*aDirtyRect).y = y;
(*aDirtyRect).width = width;
(*aDirtyRect).height = height;
break;
case 2: // DISPOSE_OVERWRITE_BGCOLOR Overwrite with background color
//XXX overwrite mCompositeFrame with background color
gfx_color backgroundColor;
nextFrame->GetBackgroundColor(&backgroundColor);
//XXX Do background color overwrite of mCompositeFrame here
// blit next frame into this clean slate
nextFrame->DrawTo(mCompositingFrame, x, y, width, height);
// In this case we need to blit the whole composite frame
(*aDirtyRect).x = 0;
(*aDirtyRect).y = 0;
(*aDirtyRect).width = mSize.width;
(*aDirtyRect).height = mSize.height;
mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aFrameToUse); // addrefs again
break;
case 4: // DISPOSE_OVERWRITE_PREVIOUS Save-under
//XXX Reblit previous composite into frame buffer
//
(*aDirtyRect).x = 0;
(*aDirtyRect).y = 0;
(*aDirtyRect).width = mSize.width;
(*aDirtyRect).height = mSize.height;
break;
}
// Get the next frame's disposal method, if it is it DISPOSE_OVER, save off
// this mCompositeFrame for reblitting when this timer gets fired again and
// we
PRInt32 nextFrameDisposalMethod;
nextFrame->GetFrameDisposalMethod(&nextFrameDisposalMethod);
//XXX if(nextFrameDisposalMethod == 4)
// blit mPreviousCompositeFrame with this frame
}
//******************************************************************************
/* void onStartDecode (in imgIRequest aRequest, in nsISupports cx); */
NS_IMETHODIMP imgContainer::OnStartDecode(imgIRequest *aRequest, nsISupports *cx)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* void onStartContainer (in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer); */
NS_IMETHODIMP imgContainer::OnStartContainer(imgIRequest *aRequest, nsISupports *cx, imgIContainer *aContainer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* void onStartFrame (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame); */
NS_IMETHODIMP imgContainer::OnStartFrame(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* [noscript] void onDataAvailable (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame, [const] in nsRect aRect); */
NS_IMETHODIMP imgContainer::OnDataAvailable(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame, const nsRect * aRect)
{
if(mCompositingFrame && !mCurrentDecodingFrameIndex) {
// Update the composite frame
PRInt32 x;
aFrame->GetX(&x);
aFrame->DrawTo(mCompositingFrame, x, aRect->y, aRect->width, aRect->height);
}
return NS_OK;
}
//******************************************************************************
/* void onStopFrame (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame); */
NS_IMETHODIMP imgContainer::OnStopFrame(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* void onStopContainer (in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer); */
NS_IMETHODIMP imgContainer::OnStopContainer(imgIRequest *aRequest, nsISupports *cx, imgIContainer *aContainer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* void onStopDecode (in imgIRequest aRequest, in nsISupports cx, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgContainer::OnStopDecode(imgIRequest *aRequest, nsISupports *cx, nsresult status, const PRUnichar *statusArg)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* [noscript] void frameChanged (in imgIContainer aContainer, in nsISupports aCX, in gfxIImageFrame aFrame, in nsRect aDirtyRect); */
NS_IMETHODIMP imgContainer::FrameChanged(imgIContainer *aContainer, nsISupports *aCX, gfxIImageFrame *aFrame, nsRect * aDirtyRect)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -1,95 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
* Chris Saari <saari@netscape.com>
*/
#ifndef __imgContainer_h__
#define __imgContainer_h__
#include "imgIContainer.h"
#include "imgIContainerObserver.h"
#include "nsSize.h"
#include "nsSupportsArray.h"
#include "nsCOMPtr.h"
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "nsWeakReference.h"
#define NS_IMGCONTAINER_CID \
{ /* 5e04ec5e-1dd2-11b2-8fda-c4db5fb666e0 */ \
0x5e04ec5e, \
0x1dd2, \
0x11b2, \
{0x8f, 0xda, 0xc4, 0xdb, 0x5f, 0xb6, 0x66, 0xe0} \
}
class imgContainer : public imgIContainer,
public nsITimerCallback,
public imgIDecoderObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGICONTAINER
NS_DECL_IMGIDECODEROBSERVER
NS_DECL_IMGICONTAINEROBSERVER
NS_IMETHOD_(void) Notify(nsITimer *timer);
imgContainer();
virtual ~imgContainer();
private:
/* additional members */
nsSupportsArray mFrames;
nsSize mSize;
PRUint32 mCurrentDecodingFrameIndex; // 0 to numFrames-1
PRUint32 mCurrentAnimationFrameIndex; // 0 to numFrames-1
PRBool mCurrentFrameIsFinishedDecoding;
PRBool mDoneDecoding;
PRBool mAnimating;
nsWeakPtr mObserver;
// GIF specific bits
nsCOMPtr<nsITimer> mTimer;
// GIF animations will use the mCompositingFrame to composite images
// and just hand this back to the caller when it is time to draw the frame.
nsCOMPtr<gfxIImageFrame> mCompositingFrame;
// Private function for doing the frame compositing of animations and in cases
// where there is a backgound color and single frame placed withing a larger
// logical screen size. Smart GIF compressors may do this to save space.
void DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect,
PRInt32 aPrevFrame, PRInt32 aNextFrame);
};
#endif /* __imgContainer_h__ */

View File

@@ -1,242 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgLoader.h"
#include "imgIRequest.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "nsIIOService.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
#include "imgRequest.h"
#include "imgRequestProxy.h"
#include "ImageCache.h"
#include "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "ImageLogging.h"
NS_IMPL_ISUPPORTS1(imgLoader, imgILoader)
imgLoader::imgLoader()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
imgLoader::~imgLoader()
{
/* destructor code */
}
/* imgIRequest loadImage (in nsIURI uri, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports cx); */
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx, imgIRequest **_retval)
{
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
if (!aURI)
return NS_ERROR_NULL_POINTER;
#if defined(PR_LOGGING)
nsXPIDLCString spec;
aURI->GetSpec(getter_Copies(spec));
LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", spec.get());
#endif
imgRequest *request = nsnull;
#ifdef MOZ_NEW_CACHE
nsCOMPtr<nsICacheEntryDescriptor> entry;
ImageCache::Get(aURI, &request, getter_AddRefs(entry)); // addrefs request
if (request && entry && aLoadGroup) {
/* this isn't exactly what I want here. This code will re-doom every cache hit in a document while
it is force reloading. So for multiple copies of an image on a page, when you force reload, this
will cause you to get seperate loads for each copy of the image... this sucks.
*/
PRUint32 flags = 0;
PRBool doomRequest = PR_FALSE;
aLoadGroup->GetDefaultLoadAttributes(&flags);
if (flags & nsIChannel::FORCE_RELOAD)
doomRequest = PR_TRUE;
else {
nsCOMPtr<nsIRequest> r;
aLoadGroup->GetDefaultLoadRequest(getter_AddRefs(r));
if (r) {
nsCOMPtr<nsIChannel> c(do_QueryInterface(r));
if (c) {
c->GetLoadAttributes(&flags);
if (flags & nsIChannel::FORCE_RELOAD)
doomRequest = PR_TRUE;
}
}
}
if (doomRequest) {
entry->Doom(); // doom this thing.
entry = nsnull;
NS_RELEASE(request);
request = nsnull;
}
}
#endif
if (!request) {
/* no request from the cache. do a new load */
LOG_SCOPE(gImgLog, "imgLoader::LoadImage |cache miss|");
nsCOMPtr<nsIIOService> ioserv(do_GetService("@mozilla.org/network/io-service;1"));
if (!ioserv) return NS_ERROR_FAILURE;
nsCOMPtr<nsIChannel> newChannel;
ioserv->NewChannelFromURI(aURI, getter_AddRefs(newChannel));
if (!newChannel) return NS_ERROR_FAILURE;
if (aLoadGroup) {
PRUint32 flags;
aLoadGroup->GetDefaultLoadAttributes(&flags);
newChannel->SetLoadAttributes(flags);
}
NS_NEWXPCOM(request, imgRequest);
if (!request) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(request);
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgLoader::LoadImage -- Created new imgRequest [request=%p]\n", this, request));
#ifdef MOZ_NEW_CACHE
ImageCache::Put(aURI, request, getter_AddRefs(entry));
#endif
#ifdef MOZ_NEW_CACHE
request->Init(newChannel, entry);
#else
request->Init(newChannel, nsnull);
#endif
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
// XXX are we calling this too early?
newChannel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener *, request), nsnull);
} else {
/* request found in cache. use it */
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgLoader::LoadImage |cache hit| [request=%p]\n",
this, request));
}
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgLoader::LoadImage -- creating proxy request.\n", this));
imgRequestProxy *proxyRequest;
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(proxyRequest);
// init adds itself to imgRequest's list of observers
proxyRequest->Init(request, aLoadGroup, aObserver, cx);
NS_RELEASE(request);
*_retval = NS_STATIC_CAST(imgIRequest*, proxyRequest);
NS_ADDREF(*_retval);
NS_RELEASE(proxyRequest);
return NS_OK;
}
/* imgIRequest loadImageWithChannel(in nsIChannel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *cx, nsIStreamListener **listener, imgIRequest **_retval)
{
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
imgRequest *request = nsnull;
nsCOMPtr<nsIURI> uri;
channel->GetOriginalURI(getter_AddRefs(uri));
#ifdef MOZ_NEW_CACHE
nsCOMPtr<nsICacheEntryDescriptor> entry;
ImageCache::Get(uri, &request, getter_AddRefs(entry)); // addrefs request
#endif
if (request) {
// we have this in our cache already.. cancel the current (document) load
// XXX
// if *listener is null when we return here, the caller should probably cancel
// the channel instead of us doing it here.
channel->Cancel(NS_BINDING_ABORTED); // this should fire an OnStopRequest
*listener = nsnull; // give them back a null nsIStreamListener
} else {
NS_NEWXPCOM(request, imgRequest);
if (!request) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(request);
#ifdef MOZ_NEW_CACHE
ImageCache::Put(uri, request, getter_AddRefs(entry));
#endif
#ifdef MOZ_NEW_CACHE
request->Init(channel, entry);
#else
request->Init(channel, nsnull);
#endif
*listener = NS_STATIC_CAST(nsIStreamListener*, request);
NS_IF_ADDREF(*listener);
}
imgRequestProxy *proxyRequest;
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(proxyRequest);
// init adds itself to imgRequest's list of observers
proxyRequest->Init(request, nsnull, aObserver, cx);
NS_RELEASE(request);
*_retval = NS_STATIC_CAST(imgIRequest*, proxyRequest);
NS_ADDREF(*_retval);
NS_RELEASE(proxyRequest);
return NS_OK;
}

View File

@@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgILoader.h"
#ifdef LOADER_THREADSAFE
#include "prlock.h"
#endif
#define NS_IMGLOADER_CID \
{ /* 9f6a0d2e-1dd1-11b2-a5b8-951f13c846f7 */ \
0x9f6a0d2e, \
0x1dd1, \
0x11b2, \
{0xa5, 0xb8, 0x95, 0x1f, 0x13, 0xc8, 0x46, 0xf7} \
}
class imgLoader : public imgILoader
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGILOADER
imgLoader();
virtual ~imgLoader();
private:
};

View File

@@ -1,821 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgRequest.h"
#include "nsIAtom.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIHTTPChannel.h"
#include "nsIInputStream.h"
#include "imgILoader.h"
#include "nsIComponentManager.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "gfxIImageFrame.h"
#ifdef MOZ_NEW_CACHE
#include "nsICachingChannel.h"
#endif
#include "ImageCache.h"
#include "ImageLogging.h"
#if defined(PR_LOGGING)
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
#endif
NS_IMPL_ISUPPORTS7(imgRequest, imgIRequest, nsIRequest,
imgIDecoderObserver, imgIContainerObserver,
nsIStreamListener, nsIStreamObserver,
nsISupportsWeakReference)
imgRequest::imgRequest() :
mObservers(0), mLoading(PR_FALSE), mProcessing(PR_FALSE), mStatus(imgIRequest::STATUS_NONE), mState(0)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
imgRequest::~imgRequest()
{
/* destructor code */
}
nsresult imgRequest::Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry)
{
// XXX we should save off the thread we are getting called on here so that we can proxy all calls to mDecoder to it.
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::Init\n", this));
NS_ASSERTION(!mImage, "imgRequest::Init -- Multiple calls to init");
NS_ASSERTION(aChannel, "imgRequest::Init -- No channel");
mChannel = aChannel;
#ifdef MOZ_NEW_CACHE
mCacheEntry = aCacheEntry;
#endif
// XXX do not init the image here. this has to be done from the image decoder.
mImage = do_CreateInstance("@mozilla.org/image/container;1");
return NS_OK;
}
nsresult imgRequest::AddObserver(imgIDecoderObserver *observer)
{
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddObserver", "observer", observer);
mObservers.AppendElement(NS_STATIC_CAST(void*, observer));
// OnStartDecode
if (mState & onStartDecode)
observer->OnStartDecode(nsnull, nsnull);
// OnStartContainer
if (mState & onStartContainer)
observer->OnStartContainer(nsnull, nsnull, mImage);
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
PRUint32 nframes;
mImage->GetNumFrames(&nframes);
if (nframes > 0) {
nsCOMPtr<gfxIImageFrame> frame;
// Is this a single frame image?
if (nframes == 1) {
// Get the first frame
mImage->GetFrameAt(0, getter_AddRefs(frame));
NS_ASSERTION(frame, "GetFrameAt gave back a null frame!");
} else if (nframes > 1) {
/* multiple frames, we'll use the current one */
mImage->GetCurrentFrame(getter_AddRefs(frame));
NS_ASSERTION(frame, "GetCurrentFrame gave back a null frame!");
}
// OnStartFrame
observer->OnStartFrame(nsnull, nsnull, frame);
if (!(mState & onStopContainer)) {
// OnDataAvailable
nsRect r;
frame->GetRect(r); // XXX we shouldn't send the whole rect here
observer->OnDataAvailable(nsnull, nsnull, frame, &r);
} else {
// OnDataAvailable
nsRect r;
frame->GetRect(r); // We're done loading this image, send the the whole rect
observer->OnDataAvailable(nsnull, nsnull, frame, &r);
// OnStopFrame
observer->OnStopFrame(nsnull, nsnull, frame);
}
}
// OnStopContainer
if (mState & onStopContainer)
observer->OnStopContainer(nsnull, nsnull, mImage);
nsresult status;
if (mStatus & imgIRequest::STATUS_LOAD_COMPLETE)
status = NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
else if (mStatus & imgIRequest::STATUS_ERROR)
status = NS_IMAGELIB_ERROR_FAILURE;
// OnStopDecode
if (mState & onStopDecode)
observer->OnStopDecode(nsnull, nsnull, status, nsnull);
if (mImage && (mObservers.Count() == 1)) {
PRUint32 nframes;
mImage->GetNumFrames(&nframes);
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::AddObserver -- starting animation\n", this));
mImage->StartAnimation();
}
if (mState & onStopRequest) {
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(observer));
PR_ASSERT(observer);
ob->OnStopRequest(nsnull, nsnull, status, nsnull);
}
return NS_OK;
}
nsresult imgRequest::RemoveObserver(imgIDecoderObserver *observer, nsresult status)
{
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::RemoveObserver", "observer", observer);
mObservers.RemoveElement(NS_STATIC_CAST(void*, observer));
if (mObservers.Count() == 0) {
if (mImage) {
PRUint32 nframes;
mImage->GetNumFrames(&nframes);
if (nframes > 1) {
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::RemoveObserver -- stopping animation\n", this));
mImage->StopAnimation();
}
}
if (mChannel && mLoading) {
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::RemoveObserver -- load in progress. canceling\n", this));
this->RemoveFromCache();
this->Cancel(NS_BINDING_ABORTED);
if (!(mState & onStopDecode)) {
// make sure that observer gets an onStopRequest message sent to it
observer->OnStopDecode(nsnull, nsnull, NS_IMAGELIB_ERROR_FAILURE, nsnull);
}
if (!(mState & onStopRequest)) {
// make sure that observer gets an onStopRequest message sent to it
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(observer));
PR_ASSERT(observer);
ob->OnStopRequest(nsnull, nsnull, NS_BINDING_ABORTED, nsnull);
}
}
}
return NS_OK;
}
PRBool imgRequest::RemoveFromCache()
{
LOG_SCOPE(gImgLog, "imgRequest::RemoveFromCache");
#ifdef MOZ_NEW_CACHE
if (mCacheEntry) {
mCacheEntry->Doom();
mCacheEntry = nsnull;
} else {
NS_WARNING("imgRequest::RemoveFromCache -- no entry!");
}
#endif
return PR_TRUE;
}
/** nsIRequest / imgIRequest methods **/
/* readonly attribute wstring name; */
NS_IMETHODIMP imgRequest::GetName(PRUnichar * *aName)
{
NS_NOTYETIMPLEMENTED("imgRequest::GetName");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* boolean isPending (); */
NS_IMETHODIMP imgRequest::IsPending(PRBool *_retval)
{
NS_NOTYETIMPLEMENTED("imgRequest::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsresult status; */
NS_IMETHODIMP imgRequest::GetStatus(nsresult *aStatus)
{
NS_NOTYETIMPLEMENTED("imgRequest::GetStatus");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void cancel (in nsresult status); */
NS_IMETHODIMP imgRequest::Cancel(nsresult status)
{
LOG_SCOPE(gImgLog, "imgRequest::Cancel");
if (mImage) {
PRUint32 nframes;
mImage->GetNumFrames(&nframes);
if (nframes > 1) {
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::RemoveObserver -- stopping animation\n", this));
mImage->StopAnimation();
}
}
if (mChannel && mLoading)
mChannel->Cancel(NS_BINDING_ABORTED); // should prolly use status here
return NS_OK;
}
/* void suspend (); */
NS_IMETHODIMP imgRequest::Suspend()
{
NS_NOTYETIMPLEMENTED("imgRequest::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void resume (); */
NS_IMETHODIMP imgRequest::Resume()
{
NS_NOTYETIMPLEMENTED("imgRequest::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
/** imgIRequest methods **/
/* readonly attribute imgIContainer image; */
NS_IMETHODIMP imgRequest::GetImage(imgIContainer * *aImage)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::GetImage\n", this));
*aImage = mImage;
NS_IF_ADDREF(*aImage);
return NS_OK;
}
/* readonly attribute unsigned long imageStatus; */
NS_IMETHODIMP imgRequest::GetImageStatus(PRUint32 *aStatus)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::GetImageStatus\n", this));
*aStatus = mStatus;
return NS_OK;
}
/* readonly attribute nsIURI URI; */
NS_IMETHODIMP imgRequest::GetURI(nsIURI **aURI)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::GetURI\n", this));
if (mChannel)
return mChannel->GetOriginalURI(aURI);
else if (mURI) {
*aURI = mURI;
NS_ADDREF(*aURI);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
/* readonly attribute imgIDecoderObserver decoderObserver; */
NS_IMETHODIMP imgRequest::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
{
return NS_ERROR_FAILURE;
}
/** imgIContainerObserver methods **/
/* [noscript] void frameChanged (in imgIContainer container, in nsISupports cx, in gfxIImageFrame newframe, in nsRect dirtyRect); */
NS_IMETHODIMP imgRequest::FrameChanged(imgIContainer *container, nsISupports *cx, gfxIImageFrame *newframe, nsRect * dirtyRect)
{
LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->FrameChanged(container, cx, newframe, dirtyRect);
}
return NS_OK;
}
/** imgIDecoderObserver methods **/
/* void onStartDecode (in imgIRequest request, in nsISupports cx); */
NS_IMETHODIMP imgRequest::OnStartDecode(imgIRequest *request, nsISupports *cx)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartDecode");
mState |= onStartDecode;
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStartDecode(request, cx);
}
return NS_OK;
}
/* void onStartContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
NS_IMETHODIMP imgRequest::OnStartContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartContainer");
mState |= onStartContainer;
mStatus |= imgIRequest::STATUS_SIZE_AVAILABLE;
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStartContainer(request, cx, image);
}
return NS_OK;
}
/* void onStartFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartFrame");
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStartFrame(request, cx, frame);
}
return NS_OK;
}
/* [noscript] void onDataAvailable (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame, [const] in nsRect rect); */
NS_IMETHODIMP imgRequest::OnDataAvailable(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame, const nsRect * rect)
{
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable");
nsCOMPtr<imgIDecoderObserver> container = do_QueryInterface(mImage);
container->OnDataAvailable(request, cx, frame, rect);
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnDataAvailable(request, cx, frame, rect);
}
return NS_OK;
}
/* void onStopFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
{
NS_ASSERTION(frame, "imgRequest::OnStopFrame called with NULL frame");
LOG_SCOPE(gImgLog, "imgRequest::OnStopFrame");
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
#ifdef MOZ_NEW_CACHE
if (mCacheEntry) {
PRUint32 cacheSize = 0;
mCacheEntry->GetDataSize(&cacheSize);
PRUint32 imageSize = 0;
PRUint32 alphaSize = 0;
frame->GetImageDataLength(&imageSize);
frame->GetAlphaDataLength(&alphaSize);
mCacheEntry->SetDataSize(cacheSize + imageSize + alphaSize);
}
#endif
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStopFrame(request, cx, frame);
}
return NS_OK;
}
/* void onStopContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
mState |= onStopContainer;
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStopContainer(request, cx, image);
}
return NS_OK;
}
/* void onStopDecode (in imgIRequest request, in nsISupports cx, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgRequest::OnStopDecode(imgIRequest *aRequest, nsISupports *aCX, nsresult aStatus, const PRUnichar *aStatusArg)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStopDecode");
if (mState & onStopDecode) {
NS_WARNING("OnStopDecode called multiple times.");
return NS_OK;
}
mState |= onStopDecode;
if (!(mStatus & imgIRequest::STATUS_ERROR) && NS_FAILED(aStatus))
mStatus |= imgIRequest::STATUS_ERROR;
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
nsresult status;
if (mStatus & imgIRequest::STATUS_LOAD_COMPLETE)
status = NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
else if (mStatus & imgIRequest::STATUS_ERROR)
status = NS_IMAGELIB_ERROR_FAILURE;
while (++i < count) {
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (ob) ob->OnStopDecode(aRequest, aCX, status, aStatusArg);
}
return NS_OK;
}
/** nsIStreamObserver methods **/
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder");
NS_ASSERTION(!mLoading, "imgRequest::OnStartRequest -- we are loading again?");
/* set our loading flag to true */
mLoading = PR_TRUE;
/* notify our kids */
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
imgIDecoderObserver *iob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
if (iob) {
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(iob));
if (ob) ob->OnStartRequest(aRequest, ctxt);
}
}
/* do our real work */
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
if (!mChannel) {
PR_LOG(gImgLog, PR_LOG_ALWAYS,
(" `-> Channel already stopped or no channel!?.\n"));
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIHTTPChannel> httpChannel(do_QueryInterface(chan));
if (httpChannel) {
PRUint32 httpStatus;
httpChannel->GetResponseStatus(&httpStatus);
if (httpStatus == 404) {
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::OnStartRequest -- http status = 404. canceling.\n", this));
mStatus |= imgIRequest::STATUS_ERROR;
this->Cancel(NS_BINDING_ABORTED);
this->RemoveFromCache();
return NS_BINDING_ABORTED;
}
}
/* get the expires info */
#if defined(MOZ_NEW_CACHE)
if (mCacheEntry) {
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(chan));
if (cacheChannel) {
nsCOMPtr<nsISupports> cacheToken;
cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));
if (cacheToken) {
nsCOMPtr<nsICacheEntryDescriptor> entryDesc(do_QueryInterface(cacheToken));
if (entryDesc) {
PRUint32 expiration;
/* get the expiration time from the caching channel's token */
entryDesc->GetExpirationTime(&expiration);
/* set the expiration time on our entry */
mCacheEntry->SetExpirationTime(expiration);
}
}
}
}
#endif
return NS_OK;
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status, const PRUnichar *statusArg)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::OnStopRequest\n", this));
NS_ASSERTION(mChannel && mLoading, "imgRequest::OnStopRequest -- received multiple OnStopRequest");
mState |= onStopRequest;
/* set our loading flag to false */
mLoading = PR_FALSE;
/* set our processing flag to false */
mProcessing = PR_FALSE;
#ifdef MOZ_NEW_CACHE
/* break the cycle from the cache entry. */
mCacheEntry = nsnull;
#endif
if (NS_FAILED(status)) {
mStatus |= imgIRequest::STATUS_ERROR;
this->RemoveFromCache();
this->Cancel(status); // stops animations
} else {
mStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
}
mChannel->GetOriginalURI(getter_AddRefs(mURI));
mChannel = nsnull; // we no longer need the channel
if (mDecoder) {
mDecoder->Flush();
mDecoder->Close();
mDecoder = nsnull; // release the decoder so that it can rest peacefully ;)
}
/* notify the kids */
PRInt32 i = -1;
PRInt32 count = mObservers.Count();
while (++i < count) {
void *item = NS_STATIC_CAST(void *, mObservers[i]);
if (item) {
imgIDecoderObserver *iob = NS_STATIC_CAST(imgIDecoderObserver*, item);
if (iob) {
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(iob));
if (ob) ob->OnStopRequest(aRequest, ctxt, status, statusArg);
}
}
}
// if there was an error loading the image, (mState & onStopDecode) won't be true.
// Send an onStopDecode message
if (!(mState & onStopDecode)) {
this->OnStopDecode(nsnull, nsnull, status, statusArg);
}
return NS_OK;
}
/* prototype for this defined below */
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in, void* closure, const char* fromRawSegment,
PRUint32 toOffset, PRUint32 count, PRUint32 *writeCount);
/** nsIStreamListener methods **/
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::OnDataAvailable\n", this));
NS_ASSERTION(mChannel, "imgRequest::OnDataAvailable -- no channel!");
if (!mProcessing) {
/* set our processing flag to true if this is the first OnDataAvailable() */
mProcessing = PR_TRUE;
/* look at the first few bytes and see if we can tell what the data is from that
* since servers tend to lie. :(
*/
PRUint32 out;
inStr->ReadSegments(sniff_mimetype_callback, this, count, &out);
#ifdef NS_DEBUG
/* NS_WARNING if the content type from the channel isn't the same if the sniffing */
#endif
if (!mContentType.get()) {
nsXPIDLCString contentType;
nsresult rv = mChannel->GetContentType(getter_Copies(contentType));
if (NS_FAILED(rv)) {
PR_LOG(gImgLog, PR_LOG_ERROR,
("[this=%p] imgRequest::OnStartRequest -- Content type unavailable from the channel\n",
this));
this->RemoveFromCache();
return NS_BINDING_ABORTED; //NS_BASE_STREAM_CLOSED;
}
mContentType = contentType;
}
#if defined(PR_LOGGING)
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequest::OnStartRequest -- Content type is %s\n", this, mContentType.get()));
#endif
nsCAutoString conid("@mozilla.org/image/decoder;2?type=");
conid += mContentType.get();
mDecoder = do_CreateInstance(conid);
if (!mDecoder) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnStartRequest -- Decoder not available\n", this));
// no image decoder for this mimetype :(
this->Cancel(NS_BINDING_ABORTED);
this->RemoveFromCache();
// XXX notify the person that owns us now that wants the imgIContainer off of us?
return NS_IMAGELIB_ERROR_NO_DECODER;
}
mDecoder->Init(NS_STATIC_CAST(imgIRequest*, this));
}
if (!mDecoder) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnDataAvailable -- no decoder\n", this));
return NS_BASE_STREAM_CLOSED;
}
PRUint32 wrote;
nsresult rv = mDecoder->WriteFrom(inStr, count, &wrote);
return NS_OK;
}
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
imgRequest *request = NS_STATIC_CAST(imgRequest*, closure);
NS_ASSERTION(request, "request is null!");
if (count > 0)
request->SniffMimeType(fromRawSegment, count);
*writeCount = 0;
return NS_ERROR_FAILURE;
}
void
imgRequest::SniffMimeType(const char *buf, PRUint32 len)
{
/* Is it a GIF? */
if (len >= 4 && !nsCRT::strncmp(buf, "GIF8", 4)) {
mContentType = NS_LITERAL_CSTRING("image/gif");
return;
}
/* or a PNG? */
if (len >= 4 && ((unsigned char)buf[0]==0x89 &&
(unsigned char)buf[1]==0x50 &&
(unsigned char)buf[2]==0x4E &&
(unsigned char)buf[3]==0x47))
{
mContentType = NS_LITERAL_CSTRING("image/png");
return;
}
/* maybe a JPEG (JFIF)? */
/* JFIF files start with SOI APP0 but older files can start with SOI DQT
* so we test for SOI followed by any marker, i.e. FF D8 FF
* this will also work for SPIFF JPEG files if they appear in the future.
*
* (JFIF is 0XFF 0XD8 0XFF 0XE0 <skip 2> 0X4A 0X46 0X49 0X46 0X00)
*/
if (len >= 3 &&
((unsigned char)buf[0])==0xFF &&
((unsigned char)buf[1])==0xD8 &&
((unsigned char)buf[2])==0xFF)
{
mContentType = NS_LITERAL_CSTRING("image/jpeg");
return;
}
/* or how about ART? */
/* ART begins with JG (4A 47). Major version offset 2.
* Minor version offset 3. Offset 4 must be NULL.
*/
if (len >= 5 &&
((unsigned char) buf[0])==0x4a &&
((unsigned char) buf[1])==0x47 &&
((unsigned char) buf[4])==0x00 )
{
mContentType = NS_LITERAL_CSTRING("image/x-jg");
return;
}
/* none of the above? I give up */
}

View File

@@ -1,113 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef imgRequest_h__
#define imgRequest_h__
#include "imgIRequest.h"
#include "nsIRunnable.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "imgIContainer.h"
#include "imgIDecoder.h"
#include "imgIDecoderObserver.h"
#include "nsIStreamListener.h"
#include "nsCOMPtr.h"
#include "nsVoidArray.h"
#include "nsWeakReference.h"
#include "nsString.h"
#ifdef MOZ_NEW_CACHE
#include "nsICacheEntryDescriptor.h"
#else
class nsICacheEntryDescriptor;
#endif
#define NS_IMGREQUEST_CID \
{ /* 9f733dd6-1dd1-11b2-8cdf-effb70d1ea71 */ \
0x9f733dd6, \
0x1dd1, \
0x11b2, \
{0x8c, 0xdf, 0xef, 0xfb, 0x70, 0xd1, 0xea, 0x71} \
}
enum {
onStartDecode = 0x1,
onStartContainer = 0x2,
onStopContainer = 0x4,
onStopDecode = 0x8,
onStopRequest = 0x16
};
class imgRequest : public imgIRequest,
public imgIDecoderObserver,
public nsIStreamListener,
public nsSupportsWeakReference
{
public:
imgRequest();
virtual ~imgRequest();
/* additional members */
nsresult Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry);
nsresult AddObserver(imgIDecoderObserver *observer);
nsresult RemoveObserver(imgIDecoderObserver *observer, nsresult status);
PRBool RemoveFromCache();
void SniffMimeType(const char *buf, PRUint32 len);
NS_DECL_ISUPPORTS
NS_DECL_IMGIREQUEST
NS_DECL_NSIREQUEST
NS_DECL_IMGIDECODEROBSERVER
NS_DECL_IMGICONTAINEROBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER
private:
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<imgIDecoder> mDecoder;
nsVoidArray mObservers;
PRBool mLoading;
PRBool mProcessing;
PRUint32 mStatus;
PRUint32 mState;
nsCString mContentType;
#ifdef MOZ_NEW_CACHE
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; /* we hold on to this to this so long as we have observers */
#endif
};
#endif

View File

@@ -1,316 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgRequestProxy.h"
#include "nsXPIDLString.h"
#include "nsIInputStream.h"
#include "imgILoader.h"
#include "nsIComponentManager.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "imgRequest.h"
#include "nsString.h"
#include "DummyChannel.h"
#include "nspr.h"
#include "ImageLogging.h"
NS_IMPL_ISUPPORTS5(imgRequestProxy, imgIRequest, nsIRequest, imgIDecoderObserver, imgIContainerObserver, nsIStreamObserver)
imgRequestProxy::imgRequestProxy() :
mCanceled(PR_FALSE)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
imgRequestProxy::~imgRequestProxy()
{
/* destructor code */
// XXX pav
// it isn't the job of the request proxy to cancel itself.
// if your object goes away and you want to cancel the load, then do it yourself.
// cancel here for now until i make this work right like the above comment
Cancel(NS_ERROR_FAILURE);
}
nsresult imgRequestProxy::Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx)
{
PR_ASSERT(request);
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
mOwner = NS_STATIC_CAST(imgIRequest*, request);
mObserver = aObserver;
// XXX we should save off the thread we are getting called on here so that we can proxy all calls to mDecoder to it.
mContext = cx;
// XXX we should only create a channel, etc if the image isn't finished loading already.
nsISupports *inst = nsnull;
inst = new DummyChannel(this, aLoadGroup);
NS_ADDREF(inst);
nsresult res = inst->QueryInterface(NS_GET_IID(nsIChannel), getter_AddRefs(mDummyChannel));
NS_RELEASE(inst);
nsCOMPtr<nsILoadGroup> loadGroup;
mDummyChannel->GetLoadGroup(getter_AddRefs(loadGroup));
if (loadGroup) {
loadGroup->AddRequest(mDummyChannel, cx);
}
request->AddObserver(this);
return NS_OK;
}
/** nsIRequest / imgIRequest methods **/
/* readonly attribute wstring name; */
NS_IMETHODIMP imgRequestProxy::GetName(PRUnichar * *aName)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* boolean isPending (); */
NS_IMETHODIMP imgRequestProxy::IsPending(PRBool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsresult status; */
NS_IMETHODIMP imgRequestProxy::GetStatus(nsresult *aStatus)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void cancel (in nsresult status); */
NS_IMETHODIMP imgRequestProxy::Cancel(nsresult status)
{
if (mCanceled)
return NS_ERROR_FAILURE;
LOG_SCOPE(gImgLog, "imgRequestProxy::Cancel");
mCanceled = PR_TRUE;
NS_ASSERTION(mOwner, "canceling request proxy twice");
nsresult rv = NS_REINTERPRET_CAST(imgRequest*, mOwner.get())->RemoveObserver(this, status);
mOwner = nsnull;
return rv;
}
/* void suspend (); */
NS_IMETHODIMP imgRequestProxy::Suspend()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void resume (); */
NS_IMETHODIMP imgRequestProxy::Resume()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/** imgIRequest methods **/
/* readonly attribute imgIContainer image; */
NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
{
if (!mOwner)
return NS_ERROR_FAILURE;
return mOwner->GetImage(aImage);
}
/* readonly attribute unsigned long imageStatus; */
NS_IMETHODIMP imgRequestProxy::GetImageStatus(PRUint32 *aStatus)
{
if (!mOwner) {
*aStatus = imgIRequest::STATUS_ERROR;
return NS_ERROR_FAILURE;
}
return mOwner->GetImageStatus(aStatus);
}
/* readonly attribute nsIURI URI; */
NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
{
if (!mOwner)
return NS_ERROR_FAILURE;
return mOwner->GetURI(aURI);
}
/* readonly attribute imgIDecoderObserver decoderObserver; */
NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
{
*aDecoderObserver = mObserver;
NS_IF_ADDREF(*aDecoderObserver);
return NS_OK;
}
/** imgIContainerObserver methods **/
/* [noscript] void frameChanged (in imgIContainer container, in nsISupports cx, in gfxIImageFrame newframe, in nsRect dirtyRect); */
NS_IMETHODIMP imgRequestProxy::FrameChanged(imgIContainer *container, nsISupports *cx, gfxIImageFrame *newframe, nsRect * dirtyRect)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::FrameChanged\n", this));
if (mObserver)
mObserver->FrameChanged(container, mContext, newframe, dirtyRect);
return NS_OK;
}
/** imgIDecoderObserver methods **/
/* void onStartDecode (in imgIRequest request, in nsISupports cx); */
NS_IMETHODIMP imgRequestProxy::OnStartDecode(imgIRequest *request, nsISupports *cx)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStartDecode\n", this));
if (mObserver)
mObserver->OnStartDecode(this, mContext);
return NS_OK;
}
/* void onStartContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
NS_IMETHODIMP imgRequestProxy::OnStartContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStartContainer\n", this));
if (mObserver)
mObserver->OnStartContainer(this, mContext, image);
return NS_OK;
}
/* void onStartFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequestProxy::OnStartFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStartFrame\n", this));
if (mObserver)
mObserver->OnStartFrame(this, mContext, frame);
return NS_OK;
}
/* [noscript] void onDataAvailable (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame, [const] in nsRect rect); */
NS_IMETHODIMP imgRequestProxy::OnDataAvailable(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame, const nsRect * rect)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnDataAvailable\n", this));
if (mObserver)
mObserver->OnDataAvailable(this, mContext, frame, rect);
return NS_OK;
}
/* void onStopFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequestProxy::OnStopFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStopFrame\n", this));
if (mObserver)
mObserver->OnStopFrame(this, mContext, frame);
return NS_OK;
}
/* void onStopContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
NS_IMETHODIMP imgRequestProxy::OnStopContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStopContainer\n", this));
if (mObserver)
mObserver->OnStopContainer(this, mContext, image);
return NS_OK;
}
/* void onStopDecode (in imgIRequest request, in nsISupports cx, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgRequestProxy::OnStopDecode(imgIRequest *request, nsISupports *cx, nsresult status, const PRUnichar *statusArg)
{
PR_LOG(gImgLog, PR_LOG_DEBUG,
("[this=%p] imgRequestProxy::OnStopDecode\n", this));
if (mObserver)
mObserver->OnStopDecode(this, mContext, status, statusArg);
return NS_OK;
}
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
NS_IMETHODIMP imgRequestProxy::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
return NS_OK;
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult statusCode, in wstring statusText); */
NS_IMETHODIMP imgRequestProxy::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult statusCode, const PRUnichar *statusText)
{
if (!mDummyChannel)
return NS_OK;
nsCOMPtr<nsILoadGroup> loadGroup;
mDummyChannel->GetLoadGroup(getter_AddRefs(loadGroup));
if (loadGroup) {
loadGroup->RemoveRequest(mDummyChannel, mContext, statusCode, statusText);
}
mDummyChannel = nsnull;
return NS_OK;
}

View File

@@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "imgRequest.h"
#include "imgIDecoderObserver.h"
#include "imgIContainer.h"
#include "imgIDecoder.h"
#include "nsIStreamObserver.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsCOMPtr.h"
#define NS_IMGREQUESTPROXY_CID \
{ /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */ \
0x20557898, \
0x1dd2, \
0x11b2, \
{0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
}
class imgRequestProxy : public imgIRequest,
public imgIDecoderObserver,
public nsIStreamObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIREQUEST
NS_DECL_NSIREQUEST
NS_DECL_IMGIDECODEROBSERVER
NS_DECL_IMGICONTAINEROBSERVER
NS_DECL_NSISTREAMOBSERVER
imgRequestProxy();
virtual ~imgRequestProxy();
/* additional members */
nsresult Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx);
private:
nsCOMPtr<imgIDecoderObserver> mObserver;
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<imgIRequest> mOwner;
nsCOMPtr<nsIChannel> mDummyChannel;
PRBool mCanceled;
};

View File

@@ -1,56 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imglib2
LIBRARY_NAME = imglib2
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\DummyChannel.obj \
.\$(OBJDIR)\ImageCache.obj \
.\$(OBJDIR)\ImageFactory.obj \
.\$(OBJDIR)\imgContainer.obj \
.\$(OBJDIR)\imgLoader.obj \
.\$(OBJDIR)\imgRequest.obj \
.\$(OBJDIR)\imgRequestProxy.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,90 +0,0 @@
?AddRef@imgRequestProxy@@UAGKXZ ; 143798
?Release@imgContainer@@UAGKXZ ; 120291
?OnDataAvailable@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 84442
?QueryInterface@imgContainer@@UAGIABUnsID@@PAPAX@Z ; 76980
?OnDataAvailable@imgContainer@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 75604
?OnDataAvailable@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 75604
?AddRef@DummyChannel@@UAGKXZ ; 45629
?QueryInterface@DummyChannel@@UAGIABUnsID@@PAPAX@Z ; 45310
?GetImage@imgRequest@@UAGIPAPAVimgIContainer@@@Z ; 41814
?Release@DummyChannel@@UAGKXZ ; 41716
?GetImage@imgRequestProxy@@UAGIPAPAVimgIContainer@@@Z ; 40453
?GetFrameAt@imgContainer@@UAGIIPAPAVgfxIImageFrame@@@Z ; 39613
?GetHeight@imgContainer@@UAGIPAH@Z ; 32348
?Release@imgRequest@@UAGKXZ ; 31603
?AddRef@imgRequest@@UAGKXZ ; 31603
?GetNumFrames@imgContainer@@UAGIPAI@Z ; 28342
?GetImageStatus@imgRequestProxy@@UAGIPAI@Z ; 27464
?Release@imgRequestProxy@@UAGKXZ ; 23383
?GetCurrentFrame@imgContainer@@UAGIPAPAVgfxIImageFrame@@@Z ; 19319
?QueryInterface@imgRequest@@UAGIABUnsID@@PAPAX@Z ; 16120
?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 13764
?FrameChanged@imgRequestProxy@@UAGIPAVimgIContainer@@PAVnsISupports@@PAVgfxIImageFrame@@PAUnsRect@@@Z ; 13455
?QueryInterface@imgRequestProxy@@UAGIABUnsID@@PAPAX@Z ; 10170
?Notify@imgContainer@@UAGXPAVnsITimer@@@Z ; 9611
??0nsQueryReferent@@QAE@PAVnsIWeakReference@@PAI@Z ; 9611
?FrameChanged@imgRequest@@UAGIPAVimgIContainer@@PAVnsISupports@@PAVgfxIImageFrame@@PAUnsRect@@@Z ; 9609
?DoComposite@imgContainer@@AAEXPAPAVgfxIImageFrame@@PAUnsRect@@HH@Z ; 9608
?GetLoadAttributes@DummyChannel@@UAGIPAI@Z ; 8258
?Cancel@imgRequestProxy@@UAGII@Z ; 7509
?GetLoadGroup@DummyChannel@@UAGIPAPAVnsILoadGroup@@@Z ; 7456
?GetURI@imgRequest@@UAGIPAPAVnsIURI@@@Z ; 5395
?GetURI@imgRequestProxy@@UAGIPAPAVnsIURI@@@Z ; 5395
?GetCacheSession@@YAXPAPAVnsICacheSession@@@Z ; 5165
?GetWidth@imgContainer@@UAGIPAH@Z ; 4675
?Release@imgLoader@@UAGKXZ ; 3791
?AddObserver@imgRequest@@QAEIPAVimgIDecoderObserver@@@Z ; 3789
?Get@ImageCache@@SAHPAVnsIURI@@PAPAVimgRequest@@PAPAVnsICacheEntryDescriptor@@@Z ; 3789
?RemoveObserver@imgRequest@@QAEIPAVimgIDecoderObserver@@I@Z ; 3789
?Init@imgRequestProxy@@QAEIPAVimgRequest@@PAVnsILoadGroup@@PAVimgIDecoderObserver@@PAVnsISupports@@@Z ; 3789
?QueryInterface@imgLoader@@UAGIABUnsID@@PAPAX@Z ; 3789
??0imgRequestProxy@@QAE@XZ ; 3789
??0DummyChannel@@QAE@PAVimgIRequest@@PAVnsILoadGroup@@@Z ; 3789
?LoadImage@imgLoader@@UAGIPAVnsIURI@@PAVnsILoadGroup@@PAVimgIDecoderObserver@@PAVnsISupports@@PAPAVimgIRequest@@@Z ; 3789
??1imgRequestProxy@@UAE@XZ ; 3667
??1DummyChannel@@QAE@XZ ; 3667
??_EimgRequestProxy@@UAEPAXI@Z ; 3667
?OnStopRequest@imgRequestProxy@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 3667
?OnStopDecode@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@IPBG@Z ; 3652
?OnStartContainer@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 3652
?OnStopContainer@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 3652
?OnStartDecode@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@@Z ; 3652
?OnStopFrame@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 3491
?OnStartFrame@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 3491
?OnStartRequest@imgRequestProxy@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 2714
?OnStopFrame@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 2082
?AppendFrame@imgContainer@@UAGIPAVgfxIImageFrame@@@Z ; 2082
?OnStartFrame@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 2082
?EndFrameDecode@imgContainer@@UAGIII@Z ; 1996
?StartAnimation@imgContainer@@UAGIXZ ; 1747
?OnDataAvailable@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 1415
??0imgContainer@@QAE@XZ ; 1376
??1imgRequest@@UAE@XZ ; 1376
?OnStopRequest@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 1376
?Init@imgRequest@@QAEIPAVnsIChannel@@PAVnsICacheEntryDescriptor@@@Z ; 1376
??1imgContainer@@UAE@XZ ; 1376
?Put@ImageCache@@SAHPAVnsIURI@@PAVimgRequest@@PAPAVnsICacheEntryDescriptor@@@Z ; 1376
??_GimgRequest@@UAEPAXI@Z ; 1376
??_EimgContainer@@UAEPAXI@Z ; 1376
??0imgRequest@@QAE@XZ ; 1376
?OnStartRequest@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 1367
?OnStartContainer@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 1361
?Init@imgContainer@@UAGIHHPAVimgIContainerObserver@@@Z ; 1361
?OnStartDecode@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@@Z ; 1361
?SniffMimeType@imgRequest@@QAEXPBDI@Z ; 1361
?OnStopContainer@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 1361
?OnStopDecode@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@IPBG@Z ; 1361
?GetContentType@DummyChannel@@UAGIPAPAD@Z ; 1275
?DecodingComplete@imgContainer@@UAGIXZ ; 1275
?Cancel@DummyChannel@@UAGII@Z ; 122
?StopAnimation@imgContainer@@UAGIXZ ; 121
?GetDecoderObserver@imgRequestProxy@@UAGIPAPAVimgIDecoderObserver@@@Z ; 84
??0nsGetInterface@@QAE@PAVnsISupports@@PAI@Z ; 77
_NSGetModule ; 1
??_EimgLoader@@UAEPAXI@Z ; 1
??1imgLoader@@UAE@XZ ; 1
?Shutdown@ImageCache@@SAXXZ ; 1
??0imgLoader@@QAE@XZ ; 1
?do_GetService@@YA?BVnsGetServiceByContractID@@PBDPAI@Z ; 1
?Cancel@imgRequest@@UAGII@Z ; 1
?RemoveFromCache@imgRequest@@QAEHXZ ; 1

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,22 @@
#
# The contents of this file are subject to the Mozilla Public
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code
#
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Contributor(s):
#
DEPTH = ../..
@@ -26,8 +26,13 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src decoders
DIRS = \
public \
memcache \
filecache \
mgr \
build \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,3 +1,4 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
@@ -18,8 +19,15 @@
#
# Contributor(s):
DEPTH=..\..
DIRS = public src decoders
DEPTH=..\..
DIRS= \
public \
mgr \
memcache \
filecache \
build \
$(NULL)
include <$(DEPTH)\config\rules.mak>
!include $(DEPTH)\config\rules.mak

54
mozilla/netwerk/cache/build/Makefile.in vendored Normal file
View File

@@ -0,0 +1,54 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = nkcacke
LIBRARY_NAME = necko_cache
IS_COMPONENT = 1
CPPSRCS = nsNetDataCacheModule.cpp
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libnkcachemgr_s.a \
$(DIST)/lib/libnkfilecache_s.a \
$(DIST)/lib/libnkmemcache_s.a \
$(DIST)/lib/libmozdbm_s.a \
$(DIST)/lib/libxpcomio_s.a \
$(NULL)
LOCAL_INCLUDES = \
-I$(DEPTH)/netwerk/cache/memcache \
-I$(DEPTH)/netwerk/cache/filecache \
-I$(DEPTH)/netwerk/cache/mgr \
$(NULL)
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL) \
$(NULL)
include $(topsrcdir)/config/rules.mk
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile

View File

@@ -0,0 +1,51 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
DEPTH=..\..\..
MODULE=nkcache
MAKE_OBJ_TYPE=DLL
DLLNAME=nkcache
DLL=.\$(OBJDIR)\$(DLLNAME).dll
CPP_OBJS= \
.\$(OBJDIR)\nsNetDataCacheModule.obj \
$(NULL)
LLIBS= \
$(DIST)\lib\nkcachemgr_s.lib \
$(DIST)\lib\nkfilecache_s.lib \
$(DIST)\lib\nkmemcache_s.lib \
$(DIST)\lib\dbm32.lib \
$(DIST)\lib\xpcom.lib \
$(LIBNSPR)
INCS = $(INCS) \
-I$(DEPTH)\netwerk\cache\memcache \
-I$(DEPTH)\netwerk\cache\filecache \
-I$(DEPTH)\netwerk\cache\mgr \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib

View File

@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
#include "nsCOMPtr.h"
#include "nsIModule.h"
#include "nscore.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIGenericFactory.h"
#include "nsINetDataCache.h"
#include "nsINetDataCacheManager.h"
#include "nsMemCacheCID.h"
#include "nsMemCache.h"
#include "nsNetDiskCache.h"
#include "nsNetDiskCacheCID.h"
#include "nsCacheManager.h"
// Factory method to create a new nsMemCache instance. Used
// by nsNetDataCacheModule
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemCache, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNetDiskCache, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCacheManager, Init)
static nsModuleComponentInfo components[] = {
{ "Memory Cache", NS_MEM_CACHE_FACTORY_CID, NS_NETWORK_MEMORY_CACHE_PROGID, nsMemCacheConstructor },
{ "File Cache", NS_NETDISKCACHE_CID, NS_NETWORK_FILE_CACHE_PROGID, nsNetDiskCacheConstructor },
{ "Cache Manager",NS_CACHE_MANAGER_CID, NS_NETWORK_CACHE_MANAGER_PROGID,nsCacheManagerConstructor }
};
NS_IMPL_NSGETMODULE("Network Data Cache", components)

View File

@@ -0,0 +1,60 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator.
#
# The Initial Developer of the Original Code is Intel Corp.
# Portions created by Intel Corp. are
# Copyright (C) 1999, 1999 Intel Corp. All
# Rights Reserved.
#
# Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
# Carl Wong <carl.wong@intel.com>
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = nkcache
LIBRARY_NAME = nkfilecache_s
REQUIRES = nspr dbm
EXTRA_DSO_LDOPTS += -L$(DIST)/lib -lmozdbm_s
EXPORTS=nsNetDiskCacheCID.h \
nsNetDiskCache.h \
nsIDBAccessor.h \
nsDBAccessor.h \
$(NULL)
CPPSRCS = \
nsDBAccessor.cpp\
nsDBEnumerator.cpp \
nsNetDiskCache.cpp \
nsDiskCacheRecord.cpp \
nsDiskCacheRecordChannel.cpp \
$(NULL)
EXTRA_LIBS = $(NSPR_LIBS)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,44 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = nkcache
LIBRARY_NAME = nkfilecache_s
CPP_OBJS= \
.\$(OBJDIR)\nsDBAccessor.obj \
.\$(OBJDIR)\nsDBEnumerator.obj \
.\$(OBJDIR)\nsNetDiskCache.obj \
.\$(OBJDIR)\nsDiskCacheRecord.obj \
.\$(OBJDIR)\nsDiskCacheRecordChannel.obj \
$(NULL)
EXPORTS=nsNetDiskCacheCID.h
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -rf $(OBJDIR)
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,416 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* This file is part of filecache implementation.
*
* nsIDBAccessor is a interface that shields all the direct database access
* method from nsNetDiskCache.
*
* nsDBAccessor is a implementation of the nsIDBAccessor interface. It
* uses dbm(Berkely) as the database.
*
* a nsDiskCacheRecord is mapped into two entries in the database,
* key->recordID
* recordID->metadata
*/
#include "nsDBAccessor.h"
#include "nscore.h"
#include "prtypes.h"
#include "plhash.h"
#include "nsCRT.h"
nsDBAccessor::nsDBAccessor() :
mDB(0) ,
mDBFile(0) ,
mSessionID(0) ,
mSessionCntr(0) ,
mDBFilesize(0)
{
mLastSyncTime = PR_IntervalNow() ;
NS_INIT_REFCNT();
}
nsDBAccessor::~nsDBAccessor()
{
Shutdown() ;
}
//
// Implement nsISupports methods
//
NS_IMPL_ISUPPORTS(nsDBAccessor, NS_GET_IID(nsIDBAccessor))
///////////////////////////////////////////////////////////
// nsIDBAccessor methods
NS_IMETHODIMP
nsDBAccessor::Init(nsIFileSpec* dbfile)
{
char* dbname ;
// this should cover all platforms.
dbfile->GetNativePath(&dbname) ;
mDBFile = dbfile ;
// FUR - how is page size chosen ? It's worth putting a comment
// in here about the possible usefulness of tuning these parameters
HASHINFO hash_info = {
16*1024 , /* bucket size */
0 , /* fill factor */
0 , /* number of elements */
0 , /* bytes to cache */
0 , /* hash function */
0} ; /* byte order */
mDB = dbopen(dbname,
O_RDWR | O_CREAT ,
0600 ,
DB_HASH ,
& hash_info) ;
nsCRT::free(dbname) ;
if(!mDB)
return NS_ERROR_FAILURE ;
// set mSessionID
DBT db_key, db_data ;
db_key.data = NS_CONST_CAST(char*, SessionKey) ;
db_key.size = PL_strlen(SessionKey) ;
int status = (*mDB->get)(mDB, &db_key, &db_data, 0) ;
if(status == -1) {
NS_ERROR("ERROR: failed get session id in database.") ;
return NS_ERROR_FAILURE ;
}
if(status == 0) {
// get the last session id
PRInt16 *old_ID = NS_STATIC_CAST(PRInt16*, db_data.data) ;
if(*old_ID < ini_sessionID) {
NS_ERROR("ERROR: Bad Session ID in database, corrupted db.") ;
return NS_ERROR_FAILURE ;
}
mSessionID = *old_ID + 1 ;
}
else if(status == 1) {
// must be a new db
mSessionID = ini_sessionID ;
}
db_data.data = NS_REINTERPRET_CAST(void*, &mSessionID) ;
db_data.size = sizeof(PRInt16) ;
// store the new session id
status = (*mDB->put)(mDB, &db_key, &db_data, 0) ;
if(status == 0) {
(*mDB->sync)(mDB, 0) ;
// initialize database filesize
return mDBFile->GetFileSize(&mDBFilesize) ;
}
else {
NS_ERROR("reset session ID failure.") ;
return NS_ERROR_FAILURE ;
}
}
NS_IMETHODIMP
nsDBAccessor::Shutdown(void)
{
if(mDB) {
(*mDB->sync)(mDB, 0) ;
(*mDB->close)(mDB) ;
mDB = nsnull ;
}
return NS_OK ;
}
NS_IMETHODIMP
nsDBAccessor::Get(PRInt32 aID, void** anEntry, PRUint32 *aLength)
{
if(!anEntry)
return NS_ERROR_NULL_POINTER ;
*anEntry = nsnull ;
*aLength = 0 ;
NS_ASSERTION(mDB, "no database") ;
DBT db_key, db_data ;
db_key.data = NS_REINTERPRET_CAST(void*, &aID) ;
db_key.size = sizeof(PRInt32) ;
int status = 0 ;
status = (*mDB->get)(mDB, &db_key, &db_data, 0) ;
if(status == 0) {
*anEntry = db_data.data ;
*aLength = db_data.size ;
return NS_OK ;
}
else if(status == 1)
return NS_OK ;
else
return NS_ERROR_FAILURE ;
}
NS_IMETHODIMP
nsDBAccessor::Put(PRInt32 aID, void* anEntry, PRUint32 aLength)
{
NS_ASSERTION(mDB, "no database") ;
DBT db_key, db_data ;
db_key.data = NS_REINTERPRET_CAST(void*, &aID) ;
db_key.size = sizeof(PRInt32) ;
db_data.data = anEntry ;
db_data.size = aLength ;
if(0 == (*mDB->put)(mDB, &db_key, &db_data, 0)) {
return Sync() ;
}
else {
return NS_ERROR_FAILURE ;
}
}
/*
* It's more important to remove the id->metadata entry first since
* key->id mapping is just a reference
*/
NS_IMETHODIMP
nsDBAccessor::Del(PRInt32 aID, void* anEntry, PRUint32 aLength)
{
NS_ASSERTION(mDB, "no database") ;
DBT db_key ;
// delete recordID->metadata
db_key.data = NS_REINTERPRET_CAST(void*, &aID) ;
db_key.size = sizeof(PRInt32) ;
PRInt32 status = -1 ;
status = (*mDB->del)(mDB, &db_key, 0) ;
if(-1 == status) {
return NS_ERROR_FAILURE ;
}
// delete key->recordID
db_key.data = anEntry ;
db_key.size = aLength ;
status = (*mDB->del)(mDB, &db_key, 0) ;
if(-1 == status) {
return NS_ERROR_FAILURE ;
}
return Sync() ;
}
NS_IMETHODIMP
nsDBAccessor::GetID(const char* key, PRUint32 length, PRInt32* aID)
{
NS_ASSERTION(mDB, "no database") ;
DBT db_key, db_data ;
db_key.data = NS_CONST_CAST(char*, key) ;
db_key.size = length ;
int status = (*mDB->get)(mDB, &db_key, &db_data, 0) ;
if(status == 0) {
// found recordID
*aID = *(NS_REINTERPRET_CAST(PRInt32*, db_data.data)) ;
return NS_OK ;
}
else if(status == 1) {
// create a new one
PRInt32 id = 0 ;
id = mSessionID << 16 | mSessionCntr++ ;
// add new id into mDB
db_data.data = NS_REINTERPRET_CAST(void*, &id) ;
db_data.size = sizeof(PRInt32) ;
status = (*mDB->put)(mDB, &db_key, &db_data, 0) ;
if(status != 0) {
NS_ERROR("updating db failure.") ;
return NS_ERROR_FAILURE ;
}
*aID = id ;
return Sync() ;
}
else {
NS_ERROR("ERROR: keydb failure.") ;
return NS_ERROR_FAILURE ;
}
}
NS_IMETHODIMP
nsDBAccessor::EnumEntry(void** anEntry, PRUint32* aLength, PRBool bReset)
{
if(!anEntry)
return NS_ERROR_NULL_POINTER ;
*anEntry = nsnull ;
*aLength = 0 ;
NS_ASSERTION(mDB, "no database") ;
PRUint32 flag ;
if(bReset)
flag = R_FIRST ;
else
flag = R_NEXT ;
DBT db_key, db_data ;
PRUint32 len = PL_strlen(SessionKey) ;
int status ;
do {
status = (*mDB->seq)(mDB, &db_key, &db_data, flag) ;
flag = R_NEXT ;
if(status == -1)
return NS_ERROR_FAILURE ;
// get next if it's a key->recordID
if(db_key.size > sizeof(PRInt32) && db_data.size == sizeof(PRInt32))
continue ;
// get next if it's a sessionID entry
if(db_key.size == len && db_data.size == sizeof(PRInt16))
continue ;
// recordID is always 32 bits long
if(db_key.size == sizeof(PRInt32))
break ;
} while(!status) ;
if (0 == status) {
*anEntry = db_data.data ;
*aLength = db_data.size ;
}
return NS_OK ;
}
/*
* returns the cached database file size.
* mDBFilesize will be updated during Sync().
*/
NS_IMETHODIMP
nsDBAccessor::GetDBFilesize(PRUint32* aSize)
{
*aSize = mDBFilesize ;
return NS_OK ;
}
NS_IMETHODIMP
nsDBAccessor::GetSpecialEntry(void** anEntry, PRUint32* aLength)
{
if(!anEntry)
return NS_ERROR_NULL_POINTER ;
*anEntry = nsnull ;
*aLength = 0 ;
DBT db_key, db_data ;
db_key.data = NS_CONST_CAST(char*, SpecialEntry) ;
db_key.size = PL_strlen(SpecialEntry) ;
int status = (*mDB->get)(mDB, &db_key, &db_data, 0) ;
if(status == -1) {
NS_ERROR("ERROR: failed get special entry in database.") ;
return NS_ERROR_FAILURE ;
}
if(status == 0) {
*anEntry = db_data.data ;
*aLength = db_data.size ;
}
return NS_OK ;
}
NS_IMETHODIMP
nsDBAccessor::SetSpecialEntry(void* anEntry, PRUint32 aLength)
{
DBT db_key, db_data ;
db_key.data = NS_CONST_CAST(char*, SpecialEntry) ;
db_key.size = PL_strlen(SpecialEntry) ;
db_data.data = anEntry ;
db_data.size = aLength ;
if(0 == (*mDB->put)(mDB, &db_key, &db_data, 0)) {
(*mDB->sync)(mDB, 0) ;
return NS_OK ;
}
else {
return NS_ERROR_FAILURE ;
}
}
/*
* sync routine is only called when the SyncInterval is reached. Otherwise
* it just returns. If db synced, the filesize will be updated at the
* same time.
*/
nsresult
nsDBAccessor::Sync(void)
{
PRIntervalTime time = PR_IntervalNow() ;
PRIntervalTime duration = time - mLastSyncTime ;
if (PR_IntervalToMilliseconds(duration) > SyncInterval) {
int status = (*mDB->sync)(mDB, 0) ;
if(status == 0) {
// printf("\tsynced\n") ;
mLastSyncTime = time ;
// update db filesize here
return mDBFile->GetFileSize(&mDBFilesize) ;
} else
return NS_ERROR_FAILURE ;
} else {
// printf("\tnot synced\n") ;
return NS_OK ;
}
}

View File

@@ -0,0 +1,93 @@
/*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* This file is part of filecache implementation.
*
* nsIDBAccessor is a interface that shields all the direct database access
* method from nsNetDiskCache.
*
* nsDBAccessor is a implementation of the nsIDBAccessor interface. It
* uses dbm(Berkely) as the database.
*
*/
#ifndef _NSIDBACCESSOR_H_
#define _NSIDBACCESSOR_H_
#include "nsIDBAccessor.h"
#include "mcom_db.h"
#include "prinrval.h"
#include "nsCOMPtr.h"
// bogus string for the key of session id
static const char * const SessionKey = "SK" ;
// bogus string for the size
static const char * const SpecialEntry = "SE" ;
// initial session id number
static const PRInt16 ini_sessionID = 0xff ;
static const PRUint16 SyncInterval = 1000 ;
class nsDBAccessor : public nsIDBAccessor
{
public:
NS_DECL_ISUPPORTS
nsDBAccessor() ;
virtual ~nsDBAccessor() ;
NS_IMETHOD Init(nsIFileSpec* dbfile) ;
NS_IMETHOD Shutdown(void) ;
NS_IMETHOD Put(PRInt32 aID, void* anEntry, PRUint32 aLength) ;
NS_IMETHOD Get(PRInt32 aID, void** anEntry, PRUint32 *aLength) ;
NS_IMETHOD Del(PRInt32 aID, void* anEntry, PRUint32 aLength) ;
NS_IMETHOD GetID(const char* key, PRUint32 length, PRInt32* aID) ;
NS_IMETHOD EnumEntry(void* *anEntry, PRUint32* aLength, PRBool bReset) ;
NS_IMETHOD GetDBFilesize(PRUint32* aSize) ;
NS_IMETHOD GetSpecialEntry(void** anEntry, PRUint32 *aLength) ;
NS_IMETHOD SetSpecialEntry(void* anEntry, PRUint32 aLength) ;
protected:
nsresult Sync(void) ;
private:
DB * mDB ;
nsCOMPtr<nsIFileSpec> mDBFile ;
PRInt16 mSessionID ;
PRInt16 mSessionCntr ;
PRIntervalTime mLastSyncTime ;
PRUint32 mDBFilesize ; // cached DB filesize,
// updated on every sync for now
} ;
#endif // _NSIDBACCESSOR_H_

View File

@@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* This file is part of filecache implementation.
*
* It implements a simple iterator for the database, see nsDBAccessor.
*/
#include "nsDBEnumerator.h"
#include "nsDiskCacheRecord.h"
nsDBEnumerator::nsDBEnumerator(nsIDBAccessor* aDB, nsNetDiskCache* aCache) :
m_DB(aDB) ,
m_DiskCache(aCache) ,
m_tempEntry(0) ,
m_tempEntry_length(0) ,
m_CacheEntry(0) ,
m_bReset(PR_TRUE)
{
NS_INIT_REFCNT();
}
nsDBEnumerator::~nsDBEnumerator()
{
NS_IF_RELEASE(m_CacheEntry) ;
}
//
// Implement nsISupports methods
//
NS_IMPL_ISUPPORTS(nsDBEnumerator, NS_GET_IID(nsIEnumerator))
/////////////////////////////////////////////////////////////////
// nsISimpleEnumerator methods
NS_IMETHODIMP
nsDBEnumerator::HasMoreElements(PRBool *_retval)
{
*_retval = PR_FALSE ;
nsresult rv = m_DB->EnumEntry(&m_tempEntry, &m_tempEntry_length, m_bReset) ;
if(NS_FAILED(rv)) {
// do some error recovery
m_DiskCache->DBRecovery() ;
return rv ;
}
m_bReset = PR_FALSE ;
if(m_tempEntry && m_tempEntry_length != 0)
*_retval = PR_TRUE ;
return NS_OK ;
}
// this routine does not create a new item by itself
// Rather it reuses the item inside the object. So if you need to use the
// item later, you have to
// create a new item specifically, using copy constructor or some other dup
// function. And don't forget to release it after you're done
//
NS_IMETHODIMP
nsDBEnumerator::GetNext(nsISupports **_retval)
{
if(!m_CacheEntry) {
m_CacheEntry = new nsDiskCacheRecord(m_DB, m_DiskCache) ;
if(m_CacheEntry)
NS_ADDREF(m_CacheEntry) ;
else
return NS_ERROR_OUT_OF_MEMORY ;
}
if(!_retval)
return NS_ERROR_NULL_POINTER ;
*_retval = nsnull ;
nsresult rv = m_CacheEntry->RetrieveInfo(m_tempEntry, m_tempEntry_length) ;
if(NS_FAILED(rv))
return rv ;
*_retval = NS_STATIC_CAST(nsISupports*, m_CacheEntry) ;
NS_ADDREF(*_retval) ; // all good getter addref
return NS_OK ;
}

View File

@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* This file is part of filecache implementation.
*
* It implements a simple iterator for the database, see nsDBAccessor.
*/
#ifndef _NS_DBENUMERATOR_H_
#define _NS_DBENUMERATOR_H_
#include "nsISimpleEnumerator.h"
#include "nsINetDataCacheRecord.h"
#include "nsIDBAccessor.h"
#include "nsCOMPtr.h"
#include "nsNetDiskCache.h"
#include "nsDiskCacheRecord.h"
class nsCachedDiskData ; /* forward decl */
class nsDBEnumerator : public nsISimpleEnumerator {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
nsDBEnumerator(nsIDBAccessor* aDB, nsNetDiskCache* aCache) ;
virtual ~nsDBEnumerator() ;
private:
nsCOMPtr<nsIDBAccessor> m_DB ;
nsCOMPtr<nsNetDiskCache> m_DiskCache ;
void * m_tempEntry ;
PRUint32 m_tempEntry_length ;
nsDiskCacheRecord* m_CacheEntry ;
PRBool m_bReset ;
};
#endif // _NS_DBENUMERATOR_H_

View File

@@ -0,0 +1,456 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#include "nsDiskCacheRecord.h"
#include "nsINetDataDiskCache.h"
#include "nsNetDiskCacheCID.h"
#include "nsDiskCacheRecordChannel.h"
#include "nsFileStream.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIProtocolHandler.h"
#include "nsIIOService.h"
#include "nsIAllocator.h"
#include "plstr.h"
#include "prprf.h"
#include "prmem.h"
#include "prlog.h"
#include "prtypes.h"
#include "netCore.h"
#include "nsDBAccessor.h"
#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN)
ERROR! Must have a byte order
#endif
#ifdef IS_LITTLE_ENDIAN
#define COPY_INT32(_a,_b) memcpy(_a, _b, sizeof(int32))
#else
#define COPY_INT32(_a,_b) /* swap */ \
do { \
((char *)(_a))[0] = ((char *)(_b))[3]; \
((char *)(_a))[1] = ((char *)(_b))[2]; \
((char *)(_a))[2] = ((char *)(_b))[1]; \
((char *)(_a))[3] = ((char *)(_b))[0]; \
} while(0)
#endif
nsDiskCacheRecord::nsDiskCacheRecord(nsIDBAccessor* db, nsNetDiskCache* aCache) :
mKey(0) ,
mKeyLength(0) ,
mRecordID(0) ,
mMetaData(0) ,
mMetaDataLength(0) ,
mDB(db) ,
mInfo(0) ,
mInfoSize(0) ,
mNumChannels(0) ,
mDiskCache(aCache)
{
NS_INIT_REFCNT();
NS_ASSERTION(mDiskCache, "Must have an nsNetDiskCache");
NS_ADDREF(mDiskCache);
}
// mem alloced. so caller should do free() on key.
NS_IMETHODIMP
nsDiskCacheRecord::Init(const char* key, PRUint32 length, PRInt32 ID)
{
NS_NewFileSpec(getter_AddRefs(mFile));
if(!mFile)
return NS_ERROR_OUT_OF_MEMORY ;
// copy key
mKeyLength = length ;
mKey = NS_STATIC_CAST(char*, nsAllocator::Alloc(mKeyLength*sizeof(char))) ;
if(!mKey)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(mKey, key, length) ;
// get RecordID
mRecordID = ID ;
// setup the file name
nsCOMPtr<nsIFileSpec> dbFolder ;
mDiskCache->GetDiskCacheFolder(getter_AddRefs(dbFolder)) ;
nsresult rv = mFile->FromFileSpec(dbFolder) ;
if(NS_FAILED(rv))
return NS_ERROR_FAILURE ;
// dir is a hash result of mRecordID%32, hope it's enough
char filename[9], dirName[3] ;
PR_snprintf(dirName, 3, "%02x", (((PRUint32)mRecordID) % 32)) ;
mFile->AppendRelativeUnixPath(dirName) ;
PR_snprintf(filename, 9, "%08x", mRecordID) ;
mFile->AppendRelativeUnixPath(filename) ;
return NS_OK ;
}
nsDiskCacheRecord::~nsDiskCacheRecord()
{
if(mKey)
nsAllocator::Free(mKey) ;
if(mMetaData)
nsAllocator::Free(mMetaData) ;
if(mInfo)
nsAllocator::Free(mInfo) ;
NS_IF_RELEASE(mDiskCache);
}
//
// Implement nsISupports methods
//
NS_IMPL_ISUPPORTS(nsDiskCacheRecord, NS_GET_IID(nsINetDataCacheRecord))
///////////////////////////////////////////////////////////////////////
// nsINetDataCacheRecord methods
// yes, mem alloced on *_retval.
NS_IMETHODIMP
nsDiskCacheRecord::GetKey(PRUint32 *length, char** _retval)
{
if(!_retval)
return NS_ERROR_NULL_POINTER ;
*length = mKeyLength ;
*_retval = NS_STATIC_CAST(char*, nsAllocator::Alloc(mKeyLength*sizeof(char))) ;
if(!*_retval)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(*_retval, mKey, mKeyLength) ;
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecord::GetRecordID(PRInt32* aRecordID)
{
*aRecordID = mRecordID ;
return NS_OK ;
}
// yes, mem alloced on *_retval.
NS_IMETHODIMP
nsDiskCacheRecord::GetMetaData(PRUint32 *length, char **_retval)
{
if(!_retval)
return NS_ERROR_NULL_POINTER ;
// always null the return value first.
*_retval = nsnull ;
*length = mMetaDataLength ;
if(mMetaDataLength) {
*_retval = NS_STATIC_CAST(char*, nsAllocator::Alloc(mMetaDataLength*sizeof(char))) ;
if(!*_retval)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(*_retval, mMetaData, mMetaDataLength) ;
}
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecord::SetMetaData(PRUint32 length, const char* data)
{
// set the mMetaData
mMetaDataLength = length ;
if(mMetaData)
nsAllocator::Free(mMetaData) ;
mMetaData = NS_STATIC_CAST(char*, nsAllocator::Alloc(mMetaDataLength*sizeof(char))) ;
if(!mMetaData) {
return NS_ERROR_OUT_OF_MEMORY ;
}
memcpy(mMetaData, data, length) ;
// Generate mInfo
nsresult rv = GenInfo() ;
if(NS_FAILED(rv))
return rv ;
// write through into mDB
rv = mDB->Put(mRecordID, mInfo, mInfoSize) ;
return rv ;
}
NS_IMETHODIMP
nsDiskCacheRecord::GetStoredContentLength(PRUint32 *aStoredContentLength)
{
return mFile->GetFileSize(aStoredContentLength) ;
}
// untill nsIFileSpec::Truncate() is in, we have to do all this ugly stuff
NS_IMETHODIMP
nsDiskCacheRecord::SetStoredContentLength(PRUint32 aStoredContentLength)
{
PRUint32 len = 0 ;
nsresult rv = mFile->GetFileSize(&len) ;
if(NS_FAILED(rv))
return rv ;
if(len < aStoredContentLength)
{
NS_ERROR("Error: can not set filesize to something bigger than itself.\n") ;
return NS_ERROR_FAILURE ;
}
else {
rv = mFile->Truncate(aStoredContentLength) ;
if(NS_FAILED(rv))
return rv ;
mDiskCache->m_StorageInUse -= (len - aStoredContentLength) ;
return NS_OK ;
}
}
NS_IMETHODIMP
nsDiskCacheRecord::Delete(void)
{
if(mNumChannels)
return NS_ERROR_NOT_AVAILABLE ;
PRUint32 len ;
mFile->GetFileSize(&len) ;
nsFileSpec cache_file ;
nsresult rv = mFile->GetFileSpec(&cache_file) ;
if(NS_FAILED(rv))
return NS_ERROR_FAILURE ;
cache_file.Delete(PR_TRUE) ;
// updata the storage size
mDiskCache->m_StorageInUse -= len ;
rv = mDB->Del(mRecordID, mKey, mKeyLength) ;
if(NS_FAILED(rv))
return NS_ERROR_FAILURE ;
else
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecord::GetFilename(nsIFileSpec * *aFilename)
{
if(!aFilename)
return NS_ERROR_NULL_POINTER ;
*aFilename = mFile ;
NS_ADDREF(*aFilename) ;
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecord::NewChannel(nsILoadGroup *loadGroup, nsIChannel **_retval)
{
nsDiskCacheRecordChannel* channel = new nsDiskCacheRecordChannel(this, loadGroup) ;
if(!channel)
return NS_ERROR_OUT_OF_MEMORY ;
nsresult rv = channel->Init() ;
if(NS_FAILED(rv))
return rv ;
NS_ADDREF(channel) ;
*_retval = NS_STATIC_CAST(nsIChannel*, channel) ;
return NS_OK ;
}
//////////////////////////////////////////////////////////////////////////
// nsDiskCacheRecord methods
// file name is represented by a url string. I hope this would be more
// generic
nsresult
nsDiskCacheRecord::GenInfo()
{
if(mInfo)
nsAllocator::Free(mInfo) ;
char* file_url=nsnull ;
PRUint32 name_len ;
mFile->GetURLString(&file_url) ;
name_len = PL_strlen(file_url)+1 ;
mInfoSize = sizeof(PRUint32) ; // checksum for mInfoSize
mInfoSize += sizeof(PRInt32) ; // RecordID
mInfoSize += sizeof(PRUint32) ; // key length
mInfoSize += mKeyLength ; // key
mInfoSize += sizeof(PRUint32) ; // metadata length
mInfoSize += mMetaDataLength ; // metadata
mInfoSize += sizeof(PRUint32) ; // filename length
mInfoSize += name_len ; // filename
void* newInfo = nsAllocator::Alloc(mInfoSize*sizeof(char)) ;
if(!newInfo) {
return NS_ERROR_OUT_OF_MEMORY ;
}
// copy the checksum mInfoSize
char* cur_ptr = NS_STATIC_CAST(char*, newInfo) ;
COPY_INT32(cur_ptr, &mInfoSize) ;
cur_ptr += sizeof(PRUint32) ;
// copy RecordID
COPY_INT32(cur_ptr, &mRecordID) ;
cur_ptr += sizeof(PRInt32) ;
// copy key length
COPY_INT32(cur_ptr, &mKeyLength) ;
cur_ptr += sizeof(PRUint32) ;
// copy key
memcpy(cur_ptr, mKey, mKeyLength) ;
cur_ptr += mKeyLength ;
// copy metadata length
COPY_INT32(cur_ptr, &mMetaDataLength) ;
cur_ptr += sizeof(PRUint32) ;
// copy metadata
memcpy(cur_ptr, mMetaData, mMetaDataLength) ;
cur_ptr += mMetaDataLength ;
// copy file name length
COPY_INT32(cur_ptr, &name_len) ;
cur_ptr += sizeof(PRUint32) ;
// copy file name
memcpy(cur_ptr, file_url, name_len) ;
cur_ptr += name_len ;
PR_ASSERT(cur_ptr == NS_STATIC_CAST(char*, newInfo) + mInfoSize);
mInfo = newInfo ;
return NS_OK ;
}
/*
* This Method suppose to get all the info from the db record
* and set them to accroding members. the original values
* will all be overwritten. only minimal error checking is performed.
*/
NS_IMETHODIMP
nsDiskCacheRecord::RetrieveInfo(void* aInfo, PRUint32 aInfoLength)
{
// reset everything
if(mInfo) {
nsAllocator::Free(mInfo) ;
mInfo = nsnull ;
}
if(mKey) {
nsAllocator::Free(mKey) ;
mKey = nsnull ;
}
if(mMetaData) {
nsAllocator::Free(mMetaData) ;
mMetaData = nsnull ;
}
char * cur_ptr = NS_STATIC_CAST(char*, aInfo) ;
char* file_url ;
PRUint32 name_len ;
// set mInfoSize
COPY_INT32(&mInfoSize, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
// check this at least
if(mInfoSize != aInfoLength)
return NS_ERROR_FAILURE ;
// set mRecordID
COPY_INT32(&mRecordID, cur_ptr) ;
cur_ptr += sizeof(PRInt32) ;
// set mKeyLength
COPY_INT32(&mKeyLength, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
// set mKey
mKey = NS_STATIC_CAST(char*, nsAllocator::Alloc(mKeyLength*sizeof(char))) ;
if(!mKey)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(mKey, cur_ptr, mKeyLength) ;
cur_ptr += mKeyLength ;
PRInt32 id ;
mDB->GetID(mKey, mKeyLength, &id) ;
NS_ASSERTION(id==mRecordID, "\t ++++++ bad record, somethings wrong\n") ;
// set mMetaDataLength
COPY_INT32(&mMetaDataLength, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
// set mMetaData
mMetaData = NS_STATIC_CAST(char*, nsAllocator::Alloc(mMetaDataLength*sizeof(char))) ;
if(!mMetaData)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(mMetaData, cur_ptr, mMetaDataLength) ;
cur_ptr += mMetaDataLength ;
// get mFile name length
COPY_INT32(&name_len, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
// get mFile native name
file_url = NS_STATIC_CAST(char*, nsAllocator::Alloc(name_len*sizeof(char))) ;
if(!file_url)
return NS_ERROR_OUT_OF_MEMORY ;
memcpy(file_url, cur_ptr, name_len) ;
cur_ptr += name_len ;
PR_ASSERT(cur_ptr == NS_STATIC_CAST(char*, aInfo) + mInfoSize);
// create mFile if Init() isn't called
if(!mFile) {
NS_NewFileSpec(getter_AddRefs(mFile));
if(!mFile)
return NS_ERROR_OUT_OF_MEMORY ;
}
// setup mFile
mFile->SetURLString(file_url) ;
return NS_OK ;
}

View File

@@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#ifndef _NET_CACHEDDISKDATA_H_
#define _NET_CACHEDDISKDATA_H_
#include "nsINetDataCacheRecord.h"
#include "nsCOMPtr.h"
#include "nsIDBAccessor.h"
#include "prtypes.h"
#include "nsILoadGroup.h"
#include "nsIFileChannel.h"
#include "nsNetDiskCache.h"
class nsDiskCacheRecord : public nsINetDataCacheRecord
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINETDATACACHERECORD
protected:
nsDiskCacheRecord(nsIDBAccessor* db, nsNetDiskCache* aCache) ;
virtual ~nsDiskCacheRecord() ;
NS_IMETHOD RetrieveInfo(void* aInfo, PRUint32 aInfoLength) ;
NS_IMETHOD Init(const char* key, PRUint32 length, PRInt32 ID) ;
nsresult GenInfo(void) ;
private:
char* mKey ;
PRUint32 mKeyLength ;
PRInt32 mRecordID ;
char* mMetaData ;
PRUint32 mMetaDataLength ;
nsCOMPtr<nsIFileSpec> mFile ;
nsCOMPtr<nsIDBAccessor> mDB ;
void* mInfo ;
PRUint32 mInfoSize ;
PRUint32 mNumChannels ;
nsNetDiskCache* mDiskCache ;
friend class nsDiskCacheRecordChannel ;
friend class nsDBEnumerator ;
friend class nsNetDiskCache ;
} ;
#endif // _NET_CACHEDDISKDATA_H_

View File

@@ -0,0 +1,552 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* Most of the code are taken from nsFileChannel.
*/
#include "nsDiskCacheRecordChannel.h"
#include "nsIFileTransportService.h"
//#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsIOutputStream.h"
#include "netCore.h"
#include "nsIMIMEService.h"
#include "nsISupportsUtils.h"
//static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
// This is copied from nsMemCacheChannel, We should consolidate these two.
class WriteStreamWrapper : public nsIOutputStream
{
public:
WriteStreamWrapper(nsDiskCacheRecordChannel* aChannel,
nsIOutputStream *aBaseStream) ;
virtual ~WriteStreamWrapper() ;
static nsresult
Create(nsDiskCacheRecordChannel* aChannel, nsIOutputStream *aBaseStream, nsIOutputStream* *aWrapper) ;
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSIOUTPUTSTREAM
private:
nsDiskCacheRecordChannel* mChannel;
nsCOMPtr<nsIOutputStream> mBaseStream;
} ;
// implement nsISupports
NS_IMPL_ISUPPORTS(WriteStreamWrapper, NS_GET_IID(nsIOutputStream))
WriteStreamWrapper::WriteStreamWrapper(nsDiskCacheRecordChannel* aChannel,
nsIOutputStream *aBaseStream)
: mChannel(aChannel), mBaseStream(aBaseStream)
{
NS_INIT_REFCNT();
NS_ADDREF(mChannel);
}
WriteStreamWrapper::~WriteStreamWrapper()
{
NS_RELEASE(mChannel);
}
nsresult
WriteStreamWrapper::Create(nsDiskCacheRecordChannel*aChannel, nsIOutputStream *aBaseStream, nsIOutputStream* * aWrapper)
{
WriteStreamWrapper *wrapper = new WriteStreamWrapper(aChannel, aBaseStream);
if (!wrapper) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(wrapper);
*aWrapper = wrapper;
return NS_OK;
}
NS_IMETHODIMP
WriteStreamWrapper::Write(const char *aBuffer, PRUint32 aCount, PRUint32 *aNumWritten)
{
*aNumWritten = 0;
nsresult rv = mBaseStream->Write(aBuffer, aCount, aNumWritten);
mChannel->NotifyStorageInUse(*aNumWritten);
return rv;
}
NS_IMETHODIMP
WriteStreamWrapper::Flush()
{
return mBaseStream->Flush();
}
NS_IMETHODIMP
WriteStreamWrapper::Close()
{
return mBaseStream->Close();
}
nsDiskCacheRecordChannel::nsDiskCacheRecordChannel(nsDiskCacheRecord *aRecord,
nsILoadGroup *aLoadGroup)
: mRecord(aRecord) ,
mLoadGroup(aLoadGroup)
{
NS_INIT_REFCNT() ;
NS_ADDREF(mRecord);
mRecord->mNumChannels++ ;
}
nsDiskCacheRecordChannel::~nsDiskCacheRecordChannel()
{
mRecord->mNumChannels-- ;
NS_RELEASE(mRecord);
}
// I know that I gave conflicting advice on the issue of file
// transport versus file protocol handler, but I thought that the
// last word was that we would use the raw transport, when I wrote:
//
// > I just thought of an argument for the other side of the coin, i.e. the
// > benefit of *not* reusing the file protocol handler: On the Mac, it's
// > expensive to convert from a string URL to an nsFileSpec, because the Mac
// > is brain-dead and scans every directory on the path to the file. It's
// > cheaper to create a nsFileSpec for a cache file by combining a single,
// > static nsFileSpec that corresponds to the cache directory with the
// > relative path to the cache file (using nsFileSpec's operator +). This
// > operation is optimized on the Mac to avoid the scanning operation.
//
// The Mac guys will eat us alive if we do path string to nsFileSpec
// conversions for every cache file we open.
nsresult
nsDiskCacheRecordChannel::Init(void)
{
nsresult rv = mRecord->mFile->GetFileSpec(&mSpec) ;
#ifdef XP_MAC
// Don't assume we actually created a good file spec
FSSpec theSpec = mSpec.GetFSSpec();
if (!theSpec.name[0]) {
NS_ERROR("failed to create a file spec");
// Since we didn't actually create the file spec
// we return an error
return NS_ERROR_MALFORMED_URI;
}
#endif
return rv ;
}
nsresult
nsDiskCacheRecordChannel::NotifyStorageInUse(PRInt32 aBytesUsed)
{
return mRecord->mDiskCache->m_StorageInUse += aBytesUsed ;
}
// implement nsISupports
NS_IMPL_ISUPPORTS4(nsDiskCacheRecordChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIStreamObserver)
// implement nsIRequest
NS_IMETHODIMP
nsDiskCacheRecordChannel::IsPending(PRBool *aIsPending)
{
*aIsPending = PR_FALSE ;
if(!mFileTransport)
return NS_OK ;
return mFileTransport->IsPending(aIsPending) ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::Cancel(void)
{
if(!mFileTransport)
return NS_ERROR_FAILURE ;
return mFileTransport->Cancel() ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::Suspend(void)
{
if(!mFileTransport)
return NS_ERROR_FAILURE ;
return mFileTransport->Suspend() ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::Resume(void)
{
if(!mFileTransport)
return NS_ERROR_FAILURE ;
return mFileTransport->Resume() ;
}
// implement nsIChannel
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetOriginalURI(nsIURI* *aURI)
{
// FUR - might need to implement this - not sure
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetURI(nsIURI * *aURI)
{
if(!mFileTransport)
return NS_ERROR_FAILURE ;
return mFileTransport->GetURI(aURI) ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::OpenInputStream(PRUint32 aStartPosition,
PRInt32 aReadCount,
nsIInputStream* *aResult)
{
nsresult rv ;
if(mFileTransport)
return NS_ERROR_IN_PROGRESS ;
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv) ;
if(NS_FAILED(rv)) return rv ;
rv = fts->CreateTransport(mSpec, "load", 0, 0, getter_AddRefs(mFileTransport)) ;
if(NS_FAILED(rv))
return rv ;
// we don't need to worry about notification callbacks
rv = mFileTransport->OpenInputStream(aStartPosition, aReadCount, aResult) ;
if(NS_FAILED(rv))
mFileTransport = nsnull ;
return rv ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::OpenOutputStream(PRUint32 startPosition,
nsIOutputStream* *aResult)
{
nsresult rv ;
NS_ENSURE_ARG(aResult) ;
if(mFileTransport)
return NS_ERROR_IN_PROGRESS ;
nsCOMPtr<nsIOutputStream> outputStream ;
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv) ;
if(NS_FAILED(rv)) return rv ;
rv = fts->CreateTransport(mSpec, "load", 0, 0, getter_AddRefs(mFileTransport)) ;
if(NS_FAILED(rv))
return rv ;
// we don't need to worry about notification callbacks
rv = mFileTransport->OpenOutputStream(startPosition, getter_AddRefs(outputStream)) ;
if(NS_FAILED(rv)) {
mFileTransport = nsnull ;
return rv ;
}
return WriteStreamWrapper::Create(this, outputStream, aResult) ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::AsyncOpen(nsIStreamObserver *observer,
nsISupports *ctxt)
{
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::AsyncRead(PRUint32 aStartPosition,
PRInt32 aReadCount,
nsISupports *aContext,
nsIStreamListener *aListener)
{
nsresult rv ;
if(mFileTransport)
return NS_ERROR_IN_PROGRESS ;
mRealListener = aListener;
nsCOMPtr<nsIStreamListener> tempListener = this;
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(mRealListener, &newListener);
if (NS_SUCCEEDED(rv)) {
mRealListener = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddChannel(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->CreateTransport(mSpec, "load", 0, 0, getter_AddRefs(mFileTransport));
if (NS_FAILED(rv)) return rv;
// no callbacks
rv = mFileTransport->AsyncRead(aStartPosition,
aReadCount,
aContext,
tempListener);
if (NS_FAILED(rv)) {
// release the transport so that we don't think we're in progress
mFileTransport = nsnull;
}
return rv;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::AsyncWrite(nsIInputStream *fromStream,
PRUint32 startPosition,
PRInt32 writeCount,
nsISupports *ctxt,
nsIStreamObserver *observer)
{
/*
if(!mFileTransport)
return NS_ERROR_FAILURE ;
return mFileTransport->AsyncWrite(fromStream,
startPosition,
writeCount,
ctxt,
observer) ;
*/
// I can't do this since the write is not monitored, and I won't be
// able to updata the storage.
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
#define DUMMY_TYPE "text/html"
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetContentType(char * *aContentType)
{
nsresult rv ;
if (mSpec.IsDirectory()) {
*aContentType = nsCRT::strdup("application/http-index-format");
return *aContentType ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
else {
// I wish I can make this simplier
char* urlStr ;
mRecord->mFile->GetURLString(&urlStr) ;
// file: URLs (currently) have no additional structure beyond that provided by standard
// URLs, so there is no "outer" given to CreateInstance
nsCOMPtr<nsIURI> url;
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
NS_GET_IID(nsIURI),
//(void**)&url);
getter_AddRefs(url)) ;
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)urlStr);
if (NS_FAILED(rv))
return rv;
NS_WITH_SERVICE(nsIMIMEService, MIMEService, kMIMEServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = MIMEService->GetTypeFromURI(url, aContentType);
if (NS_SUCCEEDED(rv)) return rv;
}
// if all else fails treat it as text/html?
*aContentType = nsCRT::strdup(DUMMY_TYPE);
if (!*aContentType) {
return NS_ERROR_OUT_OF_MEMORY;
} else {
return NS_OK;
}
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetContentLength(PRInt32 *aContentLength)
{
nsresult rv;
PRUint32 length;
rv = mRecord->mFile->GetFileSize(&length);
if (NS_SUCCEEDED(rv)) {
*aContentLength = (PRInt32)length;
} else {
*aContentLength = -1;
}
return rv;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get() ;
NS_IF_ADDREF(*aOwner) ;
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner ;
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_OK ;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsDiskCacheRecordChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamListener methods:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsDiskCacheRecordChannel::OnStartRequest(nsIChannel* transportChannel, nsISupports* context)
{
NS_ASSERTION(mRealListener, "No listener...");
return mRealListener->OnStartRequest(this, context);
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::OnStopRequest(nsIChannel* transportChannel, nsISupports* context,
nsresult aStatus, const PRUnichar* aMsg)
{
nsresult rv;
rv = mRealListener->OnStopRequest(this, context, aStatus, aMsg);
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
mLoadGroup->RemoveChannel(this, context, aStatus, aMsg);
}
}
// Release the reference to the consumer stream listener...
mRealListener = null_nsCOMPtr();
mFileTransport = null_nsCOMPtr();
return rv;
}
NS_IMETHODIMP
nsDiskCacheRecordChannel::OnDataAvailable(nsIChannel* transportChannel, nsISupports* context,
nsIInputStream *aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
{
nsresult rv;
rv = mRealListener->OnDataAvailable(this, context, aIStream,
aSourceOffset, aLength);
//
// If the connection is being aborted cancel the transport. This will
// insure that the transport will go away even if it is blocked waiting
// for the consumer to empty the pipe...
//
if (NS_FAILED(rv)) {
mFileTransport->Cancel();
}
return rv;
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#ifndef _ns_DiskCacheRecordChannel_h_
#define _ns_DiskCacheRecordChannel_h_
#include "nsIChannel.h"
#include "nsCOMPtr.h"
#include "nsDiskCacheRecord.h"
#include "nsIStreamListener.h"
/*
* This class is plagiarized from nsMemCacheChannel
*/
class nsDiskCacheRecordChannel : public nsIChannel,
public nsIStreamListener
{
public:
nsDiskCacheRecordChannel(nsDiskCacheRecord *aRecord, nsILoadGroup *aLoadGroup);
virtual ~nsDiskCacheRecordChannel() ;
// Declare nsISupports methods
NS_DECL_ISUPPORTS
// Declare nsIRequest methods
NS_DECL_NSIREQUEST
// Declare nsIChannel methods
NS_DECL_NSICHANNEL
// Declare nsIStreamObserver methods
NS_DECL_NSISTREAMOBSERVER
// Declare nsIStreamListener methods
NS_DECL_NSISTREAMLISTENER
nsresult Init(void) ;
private:
nsresult NotifyStorageInUse(PRInt32 aBytesUsed) ;
nsDiskCacheRecord* mRecord ;
nsCOMPtr<nsILoadGroup> mLoadGroup ;
nsCOMPtr<nsISupports> mOwner ;
nsCOMPtr<nsIChannel> mFileTransport ;
nsFileSpec mSpec ;
nsCOMPtr<nsIStreamListener> mRealListener;
friend class WriteStreamWrapper ;
} ;
#endif // _ns_DiskCacheRecordChannel_h_

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#ifndef _NS_IDBACCESSOR_H_
#define _NS_IDBACCESSOR_H_
#include "nsISupports.h"
#include "nsIFileSpec.h"
// nsIDBAccessorIID {6AADD4D0-7785-11d3-87FE-000629D01344}
#define NS_IDBACCESSOR_IID \
{ 0x6aadd4d0, 0x7785, 0x11d3, \
{0x87, 0xfe, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44}}
// nsDBAccessorCID {6AADD4D1-7785-11d3-87FE-000629D01344}
#define NS_DBACCESSOR_CID \
{ 0x6aadd4d1, 0x7785, 0x11d3, \
{ 0x87, 0xfe, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44 }}
class nsIDBAccessor : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDBACCESSOR_IID)
NS_IMETHOD Init(nsIFileSpec* DBFile) = 0 ;
NS_IMETHOD Shutdown(void) = 0 ;
NS_IMETHOD Put(PRInt32 aID, void* anEntry, PRUint32 aLength) = 0 ;
NS_IMETHOD Get(PRInt32 aID, void** anEntry, PRUint32 *aLength) = 0 ;
NS_IMETHOD Del(PRInt32 aID, void* anEntry, PRUint32 aLength) = 0 ;
NS_IMETHOD GetID(const char* key, PRUint32 length, PRInt32* aID) = 0 ;
NS_IMETHOD EnumEntry(void* *anEntry, PRUint32* aLength, PRBool bReset) = 0 ;
NS_IMETHOD GetDBFilesize(PRUint32* aSize) = 0 ;
NS_IMETHOD GetSpecialEntry(void** anEntry, PRUint32 *aLength) = 0 ;
NS_IMETHOD SetSpecialEntry(void* anEntry, PRUint32 aLength) = 0 ;
} ;
#endif // _NS_IDBACCESSOR_H_

View File

@@ -0,0 +1,704 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#include "nsNetDiskCache.h"
#include "nscore.h"
#include "plstr.h"
#include "prprf.h"
#include "prtypes.h"
#include "prio.h"
#include "prsystem.h" // Directory Seperator
#include "plhash.h"
#include "prclist.h"
#include "prmem.h"
#include "prlog.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIPref.h"
#include "mcom_db.h"
#include "nsDBEnumerator.h"
#include "nsDiskCacheRecord.h"
#include "netCore.h"
#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN)
ERROR! Must have a byte order
#endif
#ifdef IS_LITTLE_ENDIAN
#define COPY_INT32(_a,_b) memcpy(_a, _b, sizeof(int32))
#else
#define COPY_INT32(_a,_b) /* swap */ \
do { \
((char *)(_a))[0] = ((char *)(_b))[3]; \
((char *)(_a))[1] = ((char *)(_b))[2]; \
((char *)(_a))[2] = ((char *)(_b))[1]; \
((char *)(_a))[3] = ((char *)(_b))[0]; \
} while(0)
#endif
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID) ;
static NS_DEFINE_CID(kDBAccessorCID, NS_DBACCESSOR_CID) ;
static const PRUint32 DISK_CACHE_SIZE_DEFAULT = 5*1024*1024 ; // 5MB
static const char * const DISK_CACHE_PREF = "browser.cache.disk_cache_size";
static const char * const CACHE_DIR_PREF = "browser.cache.directory";
class nsDiskCacheRecord ;
nsNetDiskCache::nsNetDiskCache() :
m_Enabled(PR_TRUE) ,
m_NumEntries(0) ,
m_pNextCache(0) ,
m_pDiskCacheFolder(0) ,
m_StorageInUse(0) ,
m_DB(0) ,
m_DBCorrupted(PR_FALSE)
{
// set it to INF for now
m_MaxEntries = (PRUint32)-1 ;
NS_INIT_REFCNT();
}
nsNetDiskCache::~nsNetDiskCache()
{
SetSpecialEntry() ;
NS_IF_RELEASE(m_DB) ;
// FUR
// I think that, eventually, we also want a distinguished key in the DB which
// means "clean cache shutdown". You clear this flag when the db is first
// opened and set it just before the db is closed. If the db wasn't shutdown
// cleanly in a prior session, i.e. because the app crashed, on startup you
// scan all the individual files in directories and look for "orphans",
// i.e. cache files which don't have corresponding entries in the db. That's
// also when storage-in-use and number of entries would be recomputed.
//
// We don't necessarily need all this functionality immediately, though.
if(m_DBCorrupted) {
nsFileSpec cacheFolder ;
m_pDiskCacheFolder->GetFileSpec(&cacheFolder) ;
char nameInt[6] ;
for(nsDirectoryIterator di(cacheFolder, PR_FALSE); di.Exists(); di++) {
char* filename = di.Spec().GetLeafName() ;
char* pname = nameInt ;
pname = PL_strncpyz(pname, filename, 6) ;
if(PL_strcmp(pname, "trash") == 0)
RemoveFolder(di.Spec()) ;
nsCRT::free(filename) ;
}
}
}
NS_IMETHODIMP
nsNetDiskCache::Init(void)
{
nsresult rv ;
// don't initialize if no cache folder is set.
if(!m_pDiskCacheFolder) return NS_OK ;
if(!m_DB) {
m_DB = new nsDBAccessor() ;
if(!m_DB)
return NS_ERROR_OUT_OF_MEMORY ;
else
NS_ADDREF(m_DB) ;
}
// create cache sub directories
nsCOMPtr<nsIFileSpec> cacheSubDir;
rv = NS_NewFileSpec(getter_AddRefs(cacheSubDir));
for (int i=0; i < 32; i++) {
rv = cacheSubDir->FromFileSpec(m_pDiskCacheFolder) ;
if(NS_FAILED(rv))
return rv ;
char dirName[3];
PR_snprintf (dirName, 3, "%0.2x", i);
cacheSubDir->AppendRelativeUnixPath (dirName) ;
CreateDir(cacheSubDir);
}
return InitDB() ;
}
NS_IMETHODIMP
nsNetDiskCache::InitDB(void)
{
nsresult rv ;
if(!m_DBFile) {
NS_NewFileSpec(getter_AddRefs(m_DBFile)) ;
if(!m_DBFile)
return NS_ERROR_OUT_OF_MEMORY ;
}
rv = m_DBFile->FromFileSpec(m_pDiskCacheFolder) ;
if(NS_FAILED(rv))
return rv ;
m_DBFile->AppendRelativeUnixPath("cache.db") ;
rv = m_DB->Init(m_DBFile) ;
if(rv == NS_ERROR_FAILURE) {
// try recovery if error
DBRecovery() ;
}
rv = GetSpecialEntry() ;
if(rv == NS_ERROR_FAILURE) {
// try recovery if error
DBRecovery() ;
}
return rv ;
}
//////////////////////////////////////////////////////////////////////////
// nsISupports methods
NS_IMPL_ISUPPORTS3(nsNetDiskCache,
nsINetDataDiskCache,
nsINetDataCache,
nsISupports)
///////////////////////////////////////////////////////////////////////////
// nsINetDataCache Method
NS_IMETHODIMP
nsNetDiskCache::GetDescription(PRUnichar* *aDescription)
{
nsAutoString description("Disk Cache") ;
*aDescription = description.ToNewUnicode() ;
if(!*aDescription)
return NS_ERROR_OUT_OF_MEMORY ;
return NS_OK ;
}
/* don't alloc mem for nsICachedNetData.
* RecordID is generated using the same scheme in nsCacheDiskData,
* see GetCachedNetData() for detail.
*/
NS_IMETHODIMP
nsNetDiskCache::Contains(const char* key, PRUint32 length, PRBool *_retval)
{
*_retval = PR_FALSE ;
NS_ASSERTION(m_DB, "no db.") ;
PRInt32 id = 0 ;
nsresult rv = m_DB->GetID(key, length, &id) ;
if(NS_FAILED(rv)) {
// try recovery if error
DBRecovery() ;
return rv ;
}
void* info = 0 ;
PRUint32 info_size = 0 ;
rv = m_DB->Get(id, &info, &info_size) ;
if(NS_SUCCEEDED(rv) && info)
*_retval = PR_TRUE ;
if(NS_FAILED(rv)) {
// try recovery if error
DBRecovery() ;
}
return rv ;
}
/* regardless if it's cached or not, a copy of nsNetDiskCache would
* always be returned. so release it appropriately.
* if mem alloced, updata m_NumEntries also.
* for now, the new nsCachedNetData is not written into db yet since
* we have nothing to write.
*/
NS_IMETHODIMP
nsNetDiskCache::GetCachedNetData(const char* key, PRUint32 length, nsINetDataCacheRecord **_retval)
{
NS_ASSERTION(m_DB, "no db.") ;
nsresult rv = 0 ;
if (!_retval)
return NS_ERROR_NULL_POINTER ;
*_retval = nsnull ;
PRInt32 id = 0 ;
rv = m_DB->GetID(key, length, &id) ;
if(NS_FAILED(rv)) {
// try recovery if error
DBRecovery() ;
return rv ;
}
// construct an empty record
nsDiskCacheRecord* newRecord = new nsDiskCacheRecord(m_DB, this) ;
if(!newRecord)
return NS_ERROR_OUT_OF_MEMORY ;
rv = newRecord->Init(key, length, id) ;
if(NS_FAILED(rv)) {
delete newRecord ;
return rv ;
}
NS_ADDREF(newRecord) ; // addref for _retval
*_retval = (nsINetDataCacheRecord*) newRecord ;
void* info = 0 ;
PRUint32 info_size = 0 ;
rv = m_DB->Get(id, &info, &info_size) ;
if(NS_SUCCEEDED(rv) && info) {
// this is a previously cached record
nsresult r1 ;
r1 = newRecord->RetrieveInfo(info, info_size) ;
if(NS_SUCCEEDED(rv))
return NS_OK ;
else {
// probably a bad one
NS_RELEASE(newRecord) ;
*_retval = nsnull ;
return r1;
}
} else if (NS_SUCCEEDED(rv) && !info) {
// this is a new record.
m_NumEntries ++ ;
return NS_OK ;
} else {
// database error.
DBRecovery() ;
return rv ;
}
}
/* get an nsICachedNetData, mem needs to be de-alloced if not found. */
NS_IMETHODIMP
nsNetDiskCache::GetCachedNetDataByID(PRInt32 RecordID, nsINetDataCacheRecord **_retval)
{
NS_ASSERTION(m_DB, "no db.") ;
if (!_retval)
return NS_ERROR_NULL_POINTER ;
*_retval = nsnull ;
nsresult rv ;
void* info = 0 ;
PRUint32 info_size = 0 ;
rv = m_DB->Get(RecordID, &info, &info_size) ;
if(NS_SUCCEEDED(rv) && info) {
// construct an empty record if only found in db
nsDiskCacheRecord* newRecord = new nsDiskCacheRecord(m_DB, this) ;
if(!newRecord)
return NS_ERROR_OUT_OF_MEMORY ;
NS_ADDREF(newRecord) ; // addref for _retval
rv = newRecord->RetrieveInfo(info, info_size) ;
if(NS_SUCCEEDED(rv)) {
*_retval = (nsINetDataCacheRecord*) newRecord ;
return NS_OK ;
}
else {
// bad record, I guess
NS_RELEASE(newRecord) ; // release if bad things happen
return rv ;
}
} else {
NS_ERROR("Error: RecordID not in DB\n") ;
DBRecovery() ;
return rv ;
}
}
NS_IMETHODIMP
nsNetDiskCache::GetEnabled(PRBool *aEnabled)
{
*aEnabled = m_Enabled ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::SetEnabled(PRBool aEnabled)
{
m_Enabled = aEnabled ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::GetFlags(PRUint32 *aFlags)
{
*aFlags = FILE_PER_URL_CACHE;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::GetNumEntries(PRUint32 *aNumEntries)
{
*aNumEntries = m_NumEntries ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::GetMaxEntries(PRUint32 *aMaxEntries)
{
*aMaxEntries = m_MaxEntries ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::NewCacheEntryIterator(nsISimpleEnumerator **_retval)
{
NS_ASSERTION(m_DB, "no db.") ;
if(!_retval)
return NS_ERROR_NULL_POINTER ;
*_retval = nsnull ;
nsISimpleEnumerator* enumerator = new nsDBEnumerator(m_DB, this) ;
if(enumerator) {
NS_ADDREF(enumerator) ;
*_retval = enumerator ;
return NS_OK ;
}
else
return NS_ERROR_OUT_OF_MEMORY ;
}
NS_IMETHODIMP
nsNetDiskCache::GetNextCache(nsINetDataCache * *aNextCache)
{
if(!aNextCache)
return NS_ERROR_NULL_POINTER ;
*aNextCache = m_pNextCache ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::SetNextCache(nsINetDataCache *aNextCache)
{
m_pNextCache = aNextCache ;
return NS_OK ;
}
// db size can always be measured at the last minute. Since it's hard
// to know before hand.
NS_IMETHODIMP
nsNetDiskCache::GetStorageInUse(PRUint32 *aStorageInUse)
{
NS_ASSERTION(m_DB, "no db.") ;
PRUint32 total_size = m_StorageInUse ;
/*
PRUint32 len = 0 ;
// add the size of the db.
m_DB->GetDBFilesize(&len) ;
total_size += len ;
*/
// we need size in kB
total_size = total_size >> 10 ;
*aStorageInUse = total_size ;
return NS_OK ;
}
/*
* The whole cache dirs can be whiped clean since all the cache
* files are resides in seperate hashed dirs. It's safe to do so.
*/
NS_IMETHODIMP
nsNetDiskCache::RemoveAll(void)
{
NS_ASSERTION(m_DB, "no db.") ;
NS_ASSERTION(m_pDiskCacheFolder, "no cache folder.") ;
// remove all the sub folders
nsFileSpec cacheSubDir;
for (int i=0; i < 32; i++) {
m_pDiskCacheFolder->GetFileSpec(&cacheSubDir) ;
char dirName[3];
PR_snprintf (dirName, 3, "%0.2x", i);
cacheSubDir += dirName ;
RemoveFolder(cacheSubDir) ;
}
// don't forget the db file itself
m_DB->Shutdown() ;
nsFileSpec dbfile ;
m_DBFile->GetFileSpec(&dbfile) ;
dbfile.Delete(PR_TRUE) ;
// reinitilize
return Init() ;
}
//////////////////////////////////////////////////////////////////
// nsINetDataDiskCache methods
NS_IMETHODIMP
nsNetDiskCache::GetDiskCacheFolder(nsIFileSpec * *aDiskCacheFolder)
{
*aDiskCacheFolder = nsnull ;
NS_ASSERTION(m_pDiskCacheFolder, "no cache folder.") ;
*aDiskCacheFolder = m_pDiskCacheFolder ;
NS_ADDREF(*aDiskCacheFolder) ;
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::SetDiskCacheFolder(nsIFileSpec * aDiskCacheFolder)
{
if(!m_pDiskCacheFolder) {
NS_NewFileSpec(getter_AddRefs(m_pDiskCacheFolder));
if(!m_pDiskCacheFolder)
return NS_ERROR_OUT_OF_MEMORY ;
m_pDiskCacheFolder = aDiskCacheFolder ;
return Init() ;
}
else {
char *newfolder, *oldfolder ;
m_pDiskCacheFolder->GetNativePath(&oldfolder) ;
aDiskCacheFolder->GetNativePath(&newfolder) ;
if(PL_strcmp(newfolder, oldfolder) != 0) {
m_pDiskCacheFolder = aDiskCacheFolder ;
// do we need to blow away old cache before building a new one?
// return RemoveAll() ;
m_DB->Shutdown() ;
return Init() ;
} else
return NS_OK ;
}
}
//////////////////////////////////////////////////////////////////
// nsNetDiskCache methods
// create a directory (recursively)
NS_IMETHODIMP
nsNetDiskCache::CreateDir(nsIFileSpec* dir_spec)
{
PRBool does_exist ;
nsCOMPtr<nsIFileSpec> p_spec ;
dir_spec->Exists(&does_exist) ;
if(does_exist)
return NS_OK ;
nsresult rv = dir_spec->GetParent(getter_AddRefs(p_spec)) ;
if(NS_FAILED(rv))
return rv ;
p_spec->Exists(&does_exist) ;
if(!does_exist) {
CreateDir(p_spec) ;
rv = dir_spec->CreateDir() ;
if(NS_FAILED(rv))
return rv ;
}
else {
rv = dir_spec->CreateDir() ;
if(NS_FAILED(rv))
return rv ;
}
return NS_OK ;
}
// We can't afford to make a *separate* pass over the whole db on every
// startup, just to figure out m_NumEntries and m_StorageInUse. (This is a
// several second operation on a large db). We'll likely need to store
// distinguished keys in the db that contain these values and update them
// incrementally, except when failure to shut down the db cleanly is detected.
NS_IMETHODIMP
nsNetDiskCache::GetSpecialEntry(void)
{
void* pInfo ;
PRUint32 InfoSize ;
nsresult rv = m_DB->GetSpecialEntry(&pInfo, &InfoSize) ;
if(NS_FAILED(rv))
return rv ;
if(!pInfo && InfoSize == 0) {
// must be a new DB
m_NumEntries = 0 ;
m_StorageInUse = 0 ;
}
else {
char * cur_ptr = NS_STATIC_CAST(char*, pInfo) ;
// get m_NumEntries
COPY_INT32(&m_NumEntries, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
// get m_StorageInUse
COPY_INT32(&m_StorageInUse, cur_ptr) ;
cur_ptr += sizeof(PRUint32) ;
PR_ASSERT(cur_ptr == NS_STATIC_CAST(char*, pInfo) + InfoSize);
}
return NS_OK ;
}
NS_IMETHODIMP
nsNetDiskCache::SetSpecialEntry(void)
{
PRUint32 InfoSize ;
InfoSize = sizeof m_NumEntries ;
InfoSize += sizeof m_StorageInUse ;
void* pInfo = nsAllocator::Alloc(InfoSize*sizeof(char)) ;
if(!pInfo)
return NS_ERROR_OUT_OF_MEMORY ;
char* cur_ptr = NS_STATIC_CAST(char*, pInfo) ;
COPY_INT32(cur_ptr, &m_NumEntries) ;
cur_ptr += sizeof(PRUint32) ;
COPY_INT32(cur_ptr, &m_StorageInUse) ;
cur_ptr += sizeof(PRUint32) ;
PR_ASSERT(cur_ptr == NS_STATIC_CAST(char*, pInfo) + InfoSize);
return m_DB->SetSpecialEntry(pInfo, InfoSize) ;
}
// this routine will be called everytime we have a db corruption.
// m_DB will be re-initialized, m_StorageInUse and m_NumEntries will
// be reset.
NS_IMETHODIMP
nsNetDiskCache::DBRecovery(void)
{
// rename all the sub cache dirs and remove them later during dtor.
nsresult rv = RenameCacheSubDirs() ;
if(NS_FAILED(rv))
return rv ;
// remove corrupted db file, don't care if db->shutdown fails or not.
m_DB->Shutdown() ;
nsFileSpec dbfile ;
m_DBFile->GetFileSpec(&dbfile) ;
dbfile.Delete(PR_TRUE) ;
// make sure it's not there any more
PRBool exists = dbfile.Exists() ;
if(exists) {
NS_ERROR("can't remove old db.") ;
return NS_ERROR_FAILURE ;
}
// reinitilize DB
return InitDB() ;
}
// this routine will add string "trash" to current CacheSubDir names.
// e.g. 00->trash00, 1f->trash1f. and update the m_DBCorrupted.
NS_IMETHODIMP
nsNetDiskCache::RenameCacheSubDirs(void)
{
nsCOMPtr<nsIFileSpec> cacheSubDir;
nsresult rv = NS_NewFileSpec(getter_AddRefs(cacheSubDir)) ;
for (int i=0; i < 32; i++) {
rv = cacheSubDir->FromFileSpec(m_pDiskCacheFolder) ;
if(NS_FAILED(rv))
return rv ;
char oldName[3], newName[8];
PR_snprintf(oldName, 3, "%0.2x", i) ;
cacheSubDir->AppendRelativeUnixPath(oldName) ;
// re-name the directory
PR_snprintf(newName, 8, "trash%0.2x", i) ;
rv = cacheSubDir->Rename(newName) ;
if(NS_FAILED(rv))
// TODO, error checking
return NS_ERROR_FAILURE ;
}
// update m_DBCorrupted
m_DBCorrupted = PR_TRUE ;
return NS_OK ;
}
// this routine is used by dtor and RemoveAll() to clean up dirs.
NS_IMETHODIMP
nsNetDiskCache::RemoveFolder(nsFileSpec aFolder)
{
for(nsDirectoryIterator di(aFolder, PR_FALSE); di.Exists(); di++) {
di.Spec().Delete(PR_TRUE) ;
}
aFolder.Delete(PR_FALSE) ; // recursive delete
return NS_OK ;
}

View File

@@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
/*
* This file is part of filecache implementation.
*
* nsNetDiskCache is the main disk cache module that will create
* the cache database, and then store and retrieve nsDiskCacheRecord
* objects from it. It also contains some basic error recovery procedure.
*/
#ifndef __gen_nsNetDiskCache_h__
#define __gen_nsNetDiskCache_h__
#include "nsINetDataDiskCache.h"
#include "nsNetDiskCacheCID.h"
#include "nsCOMPtr.h"
#include "nsIPref.h"
#include "nsDBAccessor.h"
class nsIURI; /* forward decl */
class nsICachedNetData; /* forward decl */
class nsISimpleEnumerator; /* forward decl */
class nsIFileSpec; /* forward decl */
/* starting interface: nsNetDiskCache */
class nsNetDiskCache : public nsINetDataDiskCache {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINETDATACACHE
NS_DECL_NSINETDATADISKCACHE
NS_IMETHOD Init(void) ;
nsNetDiskCache() ;
virtual ~nsNetDiskCache() ;
protected:
NS_IMETHOD InitDB(void) ;
NS_IMETHOD CreateDir(nsIFileSpec* dir_spec) ;
NS_IMETHOD GetSpecialEntry(void) ;
NS_IMETHOD SetSpecialEntry(void) ;
NS_IMETHOD RenameCacheSubDirs(void) ;
NS_IMETHOD DBRecovery(void) ;
NS_IMETHOD RemoveFolder(nsFileSpec aFolder) ;
private:
PRBool m_Enabled ;
PRUint32 m_NumEntries ;
nsCOMPtr<nsINetDataCache> m_pNextCache ;
nsCOMPtr<nsIFileSpec> m_pDiskCacheFolder ;
nsCOMPtr<nsIFileSpec> m_DBFile ;
PRUint32 m_MaxEntries ;
PRUint32 m_StorageInUse ;
nsIDBAccessor* m_DB ;
// this is used to indicate a db corruption
PRBool m_DBCorrupted ;
friend class nsDiskCacheRecord ;
friend class nsDiskCacheRecordChannel ;
friend class nsDBEnumerator ;
} ;
#endif /* __gen_nsNetDiskCache_h__ */

View File

@@ -0,0 +1,32 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is Intel Corp.
* Portions created by Intel Corp. are
* Copyright (C) 1999, 1999 Intel Corp. All
* Rights Reserved.
*
* Contributor(s): Yixiong Zou <yixiong.zou@intel.com>
* Carl Wong <carl.wong@intel.com>
*/
#ifndef _nsNetDiskCacheCID_h_
#define _nsNetDiskCacheCID_h_
#define NS_NETDISKCACHE_CID_STR "ECFEEA00-7201-11d3-87FE-000629D01344"
#define NS_NETDISKCACHE_CID \
{ 0xecfeea00, 0x7201, 0x11d3, \
{ 0x87, 0xfe, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44 }}
#endif /* _nsNetDiskCacheCID_h_ */

View File

@@ -0,0 +1,50 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
REQUIRES = libreg xpcom
CPPSRCS = \
diskcache.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=)
ifdef NO_LD_ARCHIVE_FLAGS
LOST_SYM_LIBS = -lxpcomds_s -lxptinfo -lmozreg_s
endif
LIBS = \
-lmozjs \
-lxpcom \
-lmozdbm_s \
$(MOZ_NECKO_UTIL_LIBS) \
$(LOST_SYM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = -I$(srcdir)/..
DEFINES += -DUSE_NSREG -DCACHE

View File

@@ -0,0 +1,836 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIStreamListener.h"
#include "nsIStreamObserver.h"
#include "nsIServiceManager.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIEventQueue.h"
#include "nsIEventQueueService.h"
#include "nsIChannel.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include <stdio.h>
#include <unistd.h>
#include "nsINetDataCache.h"
#include "nsINetDataCacheRecord.h"
//#include "nsMemCacheCID.h"
#include "nsNetDiskCache.h"
#include "nsIPref.h"
#include "prenv.h"
#include "nsIFileStream.h"
// Number of test entries to be placed in the cache
#define NUM_CACHE_ENTRIES 250
// Cache content stream length will have random length between zero and
// MAX_CONTENT_LENGTH bytes
#define MAX_CONTENT_LENGTH 20000
// Length of random-data cache entry key
#define CACHE_KEY_LENGTH 15
// Length of random-data cache entry meta-data
#define CACHE_METADATA_LENGTH 100
//static NS_DEFINE_CID(kMemCacheCID, NS_MEM_CACHE_FACTORY_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kDiskCacheCID, NS_NETDISKCACHE_CID) ;
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
// Mapping from test case number to RecordID
static PRInt32 recordID[NUM_CACHE_ENTRIES];
static PRInt32
mapRecordIdToTestNum(PRInt32 aRecordID)
{
int i;
for (i = 0; i < NUM_CACHE_ENTRIES; i++) {
if (recordID[i] == aRecordID)
return i;
}
return -1;
}
// A supply of stream data to either store or compare with
class nsITestDataStream {
public:
virtual ~nsITestDataStream() {};
virtual PRUint32 Next() = 0;
virtual void Read(char* aBuf, PRUint32 aCount) = 0;
virtual PRBool Match(char* aBuf, PRUint32 aCount) = 0;
virtual void Skip(PRUint32 aCount) = 0;
};
// A reproducible stream of random data.
class RandomStream : public nsITestDataStream {
public:
RandomStream(PRUint32 aSeed) {
mStartSeed = mState = aSeed;
}
PRUint32 GetStartSeed() {
return mStartSeed;
}
PRUint32 Next() {
mState = 1103515245 * mState + 12345;
return mState;
}
void Read(char* aBuf, PRUint32 aCount) {
PRUint32 i;
for (i = 0; i < aCount; i++) {
*aBuf++ = Next();
}
}
PRBool
Match(char* aBuf, PRUint32 aCount) {
PRUint32 i;
for (i = 0; i < aCount; i++) {
if (*aBuf++ != (char)(Next() & 0xff))
return PR_FALSE;
}
return PR_TRUE;
}
void
Skip(PRUint32 aCount) {
while (aCount--)
Next();
}
protected:
PRUint32 mState;
PRUint32 mStartSeed;
};
// A stream of data that increments on each byte that is read, modulo 256
class CounterStream : public nsITestDataStream {
public:
CounterStream(PRUint32 aSeed) {
mStartSeed = mState = aSeed;
}
PRUint32 GetStartSeed() {
return mStartSeed;
}
PRUint32 Next() {
mState += 1;
mState &= 0xff;
return mState;
}
void Read(char* aBuf, PRUint32 aCount) {
PRUint32 i;
for (i = 0; i < aCount; i++) {
*aBuf++ = Next();
}
}
PRBool
Match(char* aBuf, PRUint32 aCount) {
PRUint32 i;
for (i = 0; i < aCount; i++) {
if (*aBuf++ != (char)Next())
return PR_FALSE;
}
return PR_TRUE;
}
void
Skip(PRUint32 aCount) {
mState += aCount;
mState &= 0xff;
}
protected:
PRUint32 mState;
PRUint32 mStartSeed;
};
static int gNumReaders = 0;
static PRUint32 gTotalBytesRead = 0;
static PRUint32 gTotalDuration = 0;
class nsReader : public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
nsReader()
: mStartTime(0), mBytesRead(0)
{
NS_INIT_REFCNT();
gNumReaders++;
}
virtual ~nsReader() {
delete mTestDataStream;
gNumReaders--;
}
nsresult
Init(nsIChannel *aChannel, nsITestDataStream* aRandomStream, PRUint32 aExpectedStreamLength) {
mChannel = aChannel;
mTestDataStream = aRandomStream;
mExpectedStreamLength = aExpectedStreamLength;
mRefCnt = 1;
return NS_OK;
}
NS_IMETHOD OnStartRequest(nsIChannel* channel,
nsISupports* context) {
mStartTime = PR_IntervalNow();
return NS_OK;
}
NS_IMETHOD OnDataAvailable(nsIChannel* channel,
nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength) {
char buf[1025];
while (aLength > 0) {
PRUint32 amt;
PRBool match;
aIStream->Read(buf, sizeof buf, &amt);
if (amt == 0) break;
aLength -= amt;
mBytesRead += amt;
match = mTestDataStream->Match(buf, amt);
NS_ASSERTION(match, "Stored data was corrupted on read");
}
return NS_OK;
}
NS_IMETHOD OnStopRequest(nsIChannel* channel,
nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg) {
PRIntervalTime endTime;
PRIntervalTime duration;
endTime = PR_IntervalNow();
duration = (endTime - mStartTime);
if (NS_FAILED(aStatus)) printf("channel failed.\n");
// printf("read %d bytes\n", mBytesRead);
NS_ASSERTION(mBytesRead == mExpectedStreamLength,
"Stream in cache is wrong length");
gTotalBytesRead += mBytesRead;
gTotalDuration += duration;
// Release channel
mChannel = 0;
return NS_OK;
}
protected:
PRIntervalTime mStartTime;
PRUint32 mBytesRead;
nsITestDataStream* mTestDataStream;
PRUint32 mExpectedStreamLength;
nsCOMPtr<nsIChannel> mChannel;
};
NS_IMPL_ISUPPORTS2(nsReader, nsIStreamListener, nsIStreamObserver)
static nsIEventQueue* eventQueue;
nsresult
InitQueue() {
nsresult rv;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get event queue service");
rv = eventQService->CreateThreadEventQueue();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create event queue");
rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQueue);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get event queue for main thread");
return NS_OK;
}
// Process events until all streams are OnStopRequest'ed
nsresult
WaitForEvents() {
while (gNumReaders) {
eventQueue->ProcessPendingEvents();
}
return NS_OK;
}
// Read data for a single cache record and compare against testDataStream
nsresult
TestReadStream(nsINetDataCacheRecord *record, nsITestDataStream *testDataStream,
PRUint32 expectedStreamLength)
{
nsCOMPtr<nsIChannel> channel;
nsresult rv;
PRUint32 actualContentLength;
rv = record->NewChannel(0, getter_AddRefs(channel));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
rv = record->GetStoredContentLength(&actualContentLength);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(actualContentLength == expectedStreamLength,
"nsINetDataCacheRecord::GetContentLength() busted ?");
nsReader *reader = new nsReader;
reader->AddRef();
rv = reader->Init(channel, testDataStream, expectedStreamLength);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
rv = channel->AsyncRead(0, -1, 0, reader);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
reader->Release();
return NS_OK;
}
// Check that records can be retrieved using their record-ID, in addition
// to using the opaque key.
nsresult
TestRecordID(nsINetDataCache *cache)
{
nsresult rv;
nsCOMPtr<nsINetDataCacheRecord> record;
RandomStream *randomStream;
PRUint32 metaDataLength;
char cacheKey[CACHE_KEY_LENGTH];
char *metaData;
PRUint32 testNum;
PRBool match;
for (testNum = 0; testNum < NUM_CACHE_ENTRIES; testNum++) {
randomStream = new RandomStream(testNum);
randomStream->Read(cacheKey, sizeof cacheKey);
rv = cache->GetCachedNetDataByID(recordID[testNum], getter_AddRefs(record));
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't obtain record using record ID");
// Match against previously stored meta-data
rv = record->GetMetaData(&metaDataLength, &metaData);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get record meta-data");
match = randomStream->Match(metaData, metaDataLength);
NS_ASSERTION(match, "Meta-data corrupted or incorrect");
nsAllocator::Free(metaData);
delete randomStream;
}
return NS_OK;
}
// Check that all cache entries in the database are enumerated and that
// no duplicates appear.
nsresult
TestEnumeration(nsINetDataCache *cache)
{
nsresult rv;
nsCOMPtr<nsINetDataCacheRecord> record;
nsCOMPtr<nsISupports> tempISupports;
nsCOMPtr<nsISimpleEnumerator> iterator;
RandomStream *randomStream;
PRUint32 metaDataLength;
char cacheKey[CACHE_KEY_LENGTH];
char *metaData;
PRUint32 testNum;
PRBool match;
PRInt32 recID;
int numRecords = 0;
// Iterate over all records in the cache
rv = cache->NewCacheEntryIterator(getter_AddRefs(iterator));
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create new cache entry iterator");
PRBool notDone;
while (1) {
// Done iterating ?
rv = iterator->HasMoreElements(&notDone);
if (NS_FAILED(rv)) return rv;
if (!notDone)
break;
// Get next record in iteration
rv = iterator->GetNext(getter_AddRefs(tempISupports));
NS_ASSERTION(NS_SUCCEEDED(rv), "iterator bustage");
record = do_QueryInterface(tempISupports);
numRecords++;
// Get record ID
rv = record->GetRecordID(&recID);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get Record ID");
testNum = mapRecordIdToTestNum(recID);
NS_ASSERTION(testNum != -1, "Corrupted Record ID ?");
// Erase mapping from table, so that duplicate enumerations are detected
recordID[testNum] = -1;
// Make sure stream matches test data
randomStream = new RandomStream(testNum);
randomStream->Read(cacheKey, sizeof cacheKey);
// Match against previously stored meta-data
rv = record->GetMetaData(&metaDataLength, &metaData);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get record meta-data");
match = randomStream->Match(metaData, metaDataLength);
NS_ASSERTION(match, "Meta-data corrupted or incorrect");
nsAllocator::Free(metaData);
delete randomStream;
}
NS_ASSERTION(numRecords == NUM_CACHE_ENTRIES, "Iteration bug");
return NS_OK;
}
// Read the test data that was written in FillCache(), checking for
// corruption, truncation.
nsresult
TestRead(nsINetDataCache *cache)
{
nsresult rv;
PRBool inCache;
nsCOMPtr<nsINetDataCacheRecord> record;
RandomStream *randomStream;
PRUint32 metaDataLength;
char cacheKey[CACHE_KEY_LENGTH];
char *metaData, *storedCacheKey;
PRUint32 testNum, storedCacheKeyLength;
PRBool match;
for (testNum = 0; testNum < NUM_CACHE_ENTRIES; testNum++) {
randomStream = new RandomStream(testNum);
randomStream->Read(cacheKey, sizeof cacheKey);
// Ensure that entry is in the cache
rv = cache->Contains(cacheKey, sizeof cacheKey, &inCache);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(inCache, "nsINetDataCache::Contains error");
rv = cache->GetCachedNetData(cacheKey, sizeof cacheKey, getter_AddRefs(record));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
// Match against previously stored meta-data
match = record->GetMetaData(&metaDataLength, &metaData);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
match = randomStream->Match(metaData, metaDataLength);
NS_ASSERTION(match, "Meta-data corrupted or incorrect");
nsAllocator::Free(metaData);
// Test GetKey() method
rv = record->GetKey(&storedCacheKeyLength, &storedCacheKey);
NS_ASSERTION(NS_SUCCEEDED(rv) &&
(storedCacheKeyLength == sizeof cacheKey) &&
!memcmp(storedCacheKey, &cacheKey[0], sizeof cacheKey),
"nsINetDataCacheRecord::GetKey failed");
nsAllocator::Free(storedCacheKey);
PRUint32 expectedStreamLength = randomStream->Next() & 0xffff;
TestReadStream(record, randomStream, expectedStreamLength);
}
WaitForEvents();
// Compute rate in MB/s
double rate = gTotalBytesRead / PR_IntervalToMilliseconds(gTotalDuration);
rate *= NUM_CACHE_ENTRIES;
rate *= 1000;
rate /= (1024 * 1024);
printf("Read %d bytes at a rate of %5.1f MB per second \n",
gTotalBytesRead, rate);
return NS_OK;
}
// Repeatedly call SetStoredContentLength() on a cache entry and make
// read the stream's data to ensure that it's not corrupted by the effect
nsresult
TestTruncation(nsINetDataCache *cache)
{
nsresult rv;
nsCOMPtr<nsINetDataCacheRecord> record;
RandomStream *randomStream;
char cacheKey[CACHE_KEY_LENGTH];
randomStream = new RandomStream(0);
randomStream->Read(cacheKey, sizeof cacheKey);
rv = cache->GetCachedNetData(cacheKey, sizeof cacheKey, getter_AddRefs(record));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
randomStream->Skip(CACHE_METADATA_LENGTH);
PRUint32 initialStreamLength = randomStream->Next() & 0xffff;
delete randomStream;
PRUint32 i;
PRUint32 delta = initialStreamLength / 64;
for (i = initialStreamLength; i >= delta; i -= delta) {
PRUint32 expectedStreamLength = i;
// Do the truncation
record->SetStoredContentLength(expectedStreamLength);
randomStream = new RandomStream(0);
randomStream->Skip(CACHE_KEY_LENGTH + CACHE_METADATA_LENGTH + 1);
TestReadStream(record, randomStream, expectedStreamLength);
WaitForEvents();
}
return NS_OK;
}
// Write known data to random offsets in a single cache entry and test
// resulting stream for correctness.
nsresult
TestOffsetWrites(nsINetDataCache *cache)
{
nsresult rv;
nsCOMPtr<nsINetDataCacheRecord> record;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIOutputStream> outStream;
char buf[512];
char cacheKey[CACHE_KEY_LENGTH];
RandomStream *randomStream;
randomStream = new RandomStream(0);
randomStream->Read(cacheKey, sizeof cacheKey);
rv = cache->GetCachedNetData(cacheKey, sizeof cacheKey, getter_AddRefs(record));
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't access record via opaque cache key");
nsCOMPtr<nsIFileSpec> file ;
record->GetFilename(getter_AddRefs(file)) ;
char* name ;
file->GetUnixStyleFilePath(&name) ;
printf(" file name is %s \n", name) ;
// Write buffer-fulls of data at random offsets into the cache entry.
// Data written is (offset % 0xff)
PRUint32 startingOffset;
PRUint32 streamLength = 0;
PRUint32 len = 0 ;
CounterStream *counterStream;
int i = 0;
for (i = 0; i < 257; i++) {
rv = record->NewChannel(0, getter_AddRefs(channel));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
startingOffset = streamLength ? streamLength - (randomStream->Next() % sizeof buf): 0;
rv = channel->OpenOutputStream(startingOffset, getter_AddRefs(outStream));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
truncate(name, startingOffset) ;
counterStream = new CounterStream(startingOffset);
counterStream->Read(buf, sizeof buf);
nsresult status ;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(outStream, &status);
if (NS_FAILED(status)) {
// mState = END_WRITE;
return NS_ERROR_FAILURE;
}
PRIntn offset ;
ras->Tell(&offset) ;
// printf(" offset is %d \n", offset) ;
PRUint32 numWritten;
rv = outStream->Write(buf, sizeof buf, &numWritten);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(numWritten == sizeof buf, "Write() bug?");
streamLength = startingOffset + sizeof buf;
rv = outStream->Close();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't close channel");
delete counterStream;
record->GetStoredContentLength(&len) ;
if(len != streamLength)
printf(" offset = %d is wrong, filesize = %d\n", startingOffset, len) ;
}
/*
rv = record->NewChannel(0, getter_AddRefs(channel));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
startingOffset = 208;
rv = channel->OpenOutputStream(startingOffset, getter_AddRefs(outStream));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
counterStream = new CounterStream(startingOffset);
counterStream->Read(buf, sizeof buf);
nsresult status ;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(outStream, &status);
if (NS_FAILED(status)) {
// mState = END_WRITE;
return NS_ERROR_FAILURE;
}
PRIntn offset = 0 ;
ras->Tell(&offset) ;
printf(" offset is %d \n", offset) ;
PRUint32 numWritten;
rv = outStream->Write(buf, sizeof buf, &numWritten);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(numWritten == sizeof buf, "Write() bug?");
streamLength = startingOffset + sizeof buf;
rv = outStream->Close();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't close channel");
delete counterStream;
record->GetStoredContentLength(&len) ;
if(len != streamLength)
printf(" offset = %d is wrong, filesize = %d\n", startingOffset, len) ;
*/
delete randomStream;
counterStream = new CounterStream(0);
TestReadStream(record, counterStream, streamLength);
WaitForEvents();
return NS_OK;
}
// Create entries in the network data cache, using random data for the
// key, the meta-data and the stored content data.
nsresult
FillCache(nsINetDataCache *cache)
{
nsresult rv;
PRBool inCache;
nsCOMPtr<nsINetDataCacheRecord> record;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIOutputStream> outStream;
char buf[1000];
PRUint32 metaDataLength;
char cacheKey[CACHE_KEY_LENGTH];
char metaData[CACHE_METADATA_LENGTH];
PRUint32 testNum;
char *data;
RandomStream *randomStream;
PRIntervalTime startTime = PR_IntervalNow();
for (testNum = 0; testNum < NUM_CACHE_ENTRIES; testNum++) {
randomStream = new RandomStream(testNum);
randomStream->Read(cacheKey, sizeof cacheKey);
// No entry should be in cache until we add it
rv = cache->Contains(cacheKey, sizeof cacheKey, &inCache);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(!inCache, "nsINetDataCache::Contains error");
rv = cache->GetCachedNetData(cacheKey, sizeof cacheKey, getter_AddRefs(record));
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't access record via opaque cache key");
// Test nsINetDataCacheRecord::GetRecordID()
rv = record->GetRecordID(&recordID[testNum]);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get Record ID");
// Test nsINetDataCache::GetNumEntries()
PRUint32 numEntries = (PRUint32)-1;
rv = cache->GetNumEntries(&numEntries);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get number of cache entries");
NS_ASSERTION(numEntries == testNum + 1, "GetNumEntries failure");
// Record meta-data should be initially empty
rv = record->GetMetaData(&metaDataLength, &data);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
if ((metaDataLength != 0) || (data != 0))
return NS_ERROR_FAILURE;
// Store random data as meta-data
randomStream->Read(metaData, sizeof metaData);
record->SetMetaData(sizeof metaData, metaData);
rv = record->NewChannel(0, getter_AddRefs(channel));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
rv = channel->OpenOutputStream(0, getter_AddRefs(outStream));
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
PRUint32 beforeOccupancy;
rv = cache->GetStorageInUse(&beforeOccupancy);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get cache occupancy");
int streamLength = randomStream->Next() & 0xffff;
int remaining = streamLength;
while (remaining) {
PRUint32 numWritten;
int amount = PR_MIN(sizeof buf, remaining);
randomStream->Read(buf, amount);
rv = outStream->Write(buf, amount, &numWritten);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(numWritten == (PRUint32)amount, "Write() bug?");
remaining -= amount;
}
outStream->Close();
PRUint32 afterOccupancy;
rv = cache->GetStorageInUse(&afterOccupancy);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get cache occupancy");
PRUint32 streamLengthInKB = streamLength >> 10;
NS_ASSERTION((afterOccupancy - beforeOccupancy) >= streamLengthInKB,
"nsINetDataCache::GetStorageInUse() is busted");
// *Now* there should be an entry in the cache
rv = cache->Contains(cacheKey, sizeof cacheKey, &inCache);
NS_ASSERTION(NS_SUCCEEDED(rv), " ");
NS_ASSERTION(inCache, "nsINetDataCache::Contains error");
delete randomStream;
}
PRIntervalTime endTime = PR_IntervalNow();
return NS_OK;
}
nsresult NS_AutoregisterComponents()
{
nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup,
NULL /* default */);
return rv;
}
PRBool initPref ()
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefPtr, kPrefCID, &rv);
if (NS_FAILED(rv))
return false;
nsCOMPtr<nsIFileSpec> fileSpec;
rv = NS_NewFileSpec (getter_AddRefs(fileSpec));
if (NS_FAILED(rv))
return false;
nsCString defaultPrefFile = PR_GetEnv ("MOZILLA_FIVE_HOME");
if (defaultPrefFile.Length())
defaultPrefFile += "/";
else
defaultPrefFile = "./";
defaultPrefFile += "default_prefs.js";
fileSpec->SetUnixStyleFilePath (defaultPrefFile.GetBuffer());
PRBool exists = false;
fileSpec->Exists(&exists);
if (exists)
prefPtr->ReadUserPrefsFrom(fileSpec);
else
return false;
return true;
}
int
main(int argc, char* argv[])
{
initPref() ;
nsresult rv;
nsCOMPtr<nsINetDataCache> cache;
rv = NS_AutoregisterComponents();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't register XPCOM components");
rv = nsComponentManager::CreateInstance(kDiskCacheCID, nsnull,
NS_GET_IID(nsINetDataCache),
getter_AddRefs(cache));
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create memory cache factory");
InitQueue();
PRUnichar* description;
rv = cache->GetDescription(&description);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get cache description");
nsCAutoString descStr(description);
printf("Testing: %s\n", descStr.GetBuffer());
rv = cache->RemoveAll();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't clear cache");
PRUint32 startOccupancy;
rv = cache->GetStorageInUse(&startOccupancy);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get cache occupancy");
PRUint32 numEntries = (PRUint32)-1;
rv = cache->GetNumEntries(&numEntries);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get number of cache entries");
NS_ASSERTION(numEntries == 0, "Couldn't clear cache");
rv = FillCache(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't fill cache with random test data");
rv = TestRead(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't read random test data from cache");
rv = TestRecordID(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't index records using record ID");
rv = TestEnumeration(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't successfully enumerate records");
rv = TestTruncation(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't successfully truncate records");
rv = TestOffsetWrites(cache);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't successfully write to records using non-zero offsets");
rv = cache->RemoveAll();
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't clear cache");
rv = cache->GetNumEntries(&numEntries);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get number of cache entries");
NS_ASSERTION(numEntries == 0, "Couldn't clear cache");
PRUint32 endOccupancy;
rv = cache->GetStorageInUse(&endOccupancy);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't get cache occupancy");
NS_ASSERTION(startOccupancy == endOccupancy, "Cache occupancy not correctly computed ?");
return 0;
}

View File

@@ -0,0 +1,48 @@
# Generated automatically from Makefile.in by configure.
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = nkcache
LIBRARY_NAME = nkmemcache_s
REQUIRES = nspr dbm
EXPORTS=nsMemCacheCID.h \
nsMemCache.h \
$(NULL)
CPPSRCS = \
nsMemCache.cpp \
nsMemCacheRecord.cpp \
nsMemCacheChannel.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,42 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = nkcache
LIBRARY_NAME = nkmemcache_s
CPP_OBJS = \
.\$(OBJDIR)\nsMemCache.obj \
.\$(OBJDIR)\nsMemCacheRecord.obj \
.\$(OBJDIR)\nsMemCacheChannel.obj \
$(NULL)
EXPORTS=nsMemCacheCID.h
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -rf $(OBJDIR)
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,334 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
/**
* nsMemCache is the implementation of an in-memory network-data
* cache, used to cache the responses to network retrieval commands.
* Each cache entry may contain both content, e.g. GIF image data, and
* associated metadata, e.g. HTTP headers. Each entry is indexed by
* two different keys: a record id number and an opaque key, which is
* created by the cache manager by combining the URI with a "secondary
* key", e.g. HTTP post data.
*/
#include "nsMemCache.h"
#include "nsMemCacheRecord.h"
#include "nsIGenericFactory.h"
#include "nsString.h"
#include "nsHashtable.h"
#include "nsHashtableEnumerator.h"
#include "nsEnumeratorUtils.h"
PRInt32 nsMemCache::gRecordSerialNumber = 0;
nsMemCache::nsMemCache()
: mNumEntries(0), mOccupancy(0), mEnabled(PR_TRUE),
mHashTable(0)
{
NS_INIT_REFCNT();
}
nsMemCache::~nsMemCache()
{
nsresult rv;
rv = RemoveAll();
NS_ASSERTION(NS_SUCCEEDED(rv) && (mNumEntries == 0),
"Failure to shut down memory cache. "
"Somewhere, someone is holding references to at least one cache record");
delete mHashTable;
}
nsresult
nsMemCache::Init()
{
mHashTable = new nsHashtable(256);
if (!mHashTable)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsMemCache, NS_GET_IID(nsINetDataCache))
NS_IMETHODIMP
nsMemCache::GetDescription(PRUnichar * *aDescription)
{
nsAutoString description("Memory Cache");
*aDescription = description.ToNewUnicode();
if (!*aDescription)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::Contains(const char *aKey, PRUint32 aKeyLength, PRBool *aFound)
{
nsOpaqueKey *opaqueKey = new nsOpaqueKey(aKey, aKeyLength);
if (!opaqueKey)
return NS_ERROR_OUT_OF_MEMORY;
*aFound = mHashTable->Exists(opaqueKey);
delete opaqueKey;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetCachedNetData(const char *aKey, PRUint32 aKeyLength,
nsINetDataCacheRecord* *aRecord)
{
nsresult rv;
nsMemCacheRecord* record = 0;
nsOpaqueKey *opaqueKey2 = 0;
nsOpaqueKey *opaqueKey3 = 0;
nsOpaqueKey *opaqueKey;
opaqueKey = new nsOpaqueKey(aKey, aKeyLength);
if (!opaqueKey)
goto out_of_memory;
record = (nsMemCacheRecord*)mHashTable->Get(opaqueKey);
delete opaqueKey;
// No existing cache database entry was found. Create a new one.
// This requires two mappings in the hash table:
// Record ID ==> record
// Opaque key ==> record
if (!record) {
record = new nsMemCacheRecord;
if (!record)
goto out_of_memory;
rv = record->Init(aKey, aKeyLength, ++gRecordSerialNumber, this);
if (NS_FAILED(rv)) goto out_of_memory;
// Index the record by opaque key
opaqueKey2 = new nsOpaqueKey(record->mKey, record->mKeyLength);
if (!opaqueKey2) goto out_of_memory;
mHashTable->Put(opaqueKey2, record);
// Index the record by it's record ID
char *recordIDbytes = NS_REINTERPRET_CAST(char *, &record->mRecordID);
opaqueKey3 = new nsOpaqueKey(recordIDbytes,
sizeof record->mRecordID);
if (!opaqueKey3) {
// Clean up the first record from the hash table
mHashTable->Remove(opaqueKey);
goto out_of_memory;
}
mHashTable->Put(opaqueKey3, record);
// The hash table holds on to the record
record->AddRef();
delete opaqueKey2;
delete opaqueKey3;
mNumEntries++;
}
record->AddRef();
*aRecord = record;
return NS_OK;
out_of_memory:
delete opaqueKey2;
delete opaqueKey3;
delete record;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsMemCache::GetCachedNetDataByID(PRInt32 RecordID,
nsINetDataCacheRecord* *aRecord)
{
nsOpaqueKey opaqueKey(NS_REINTERPRET_CAST(const char *, &RecordID),
sizeof RecordID);
*aRecord = (nsINetDataCacheRecord*)mHashTable->Get(&opaqueKey);
if (*aRecord) {
NS_ADDREF(*aRecord);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_METHOD
nsMemCache::Delete(nsMemCacheRecord* aRecord)
{
nsMemCacheRecord *removedRecord;
char *recordIDbytes = NS_REINTERPRET_CAST(char *, &aRecord->mRecordID);
nsOpaqueKey opaqueRecordIDKey(recordIDbytes,
sizeof aRecord->mRecordID);
removedRecord = (nsMemCacheRecord*)mHashTable->Remove(&opaqueRecordIDKey);
NS_ASSERTION(removedRecord == aRecord, "memory cache database inconsistent");
nsOpaqueKey opaqueKey(aRecord->mKey, aRecord->mKeyLength);
removedRecord = (nsMemCacheRecord*)mHashTable->Remove(&opaqueKey);
NS_ASSERTION(removedRecord == aRecord, "memory cache database inconsistent");
aRecord->Release();
mNumEntries--;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetEnabled(PRBool *aEnabled)
{
NS_ENSURE_ARG(aEnabled);
*aEnabled = mEnabled;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::SetEnabled(PRBool aEnabled)
{
mEnabled = aEnabled;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetFlags(PRUint32 *aFlags)
{
NS_ENSURE_ARG(aFlags);
*aFlags = MEMORY_CACHE;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetNumEntries(PRUint32 *aNumEntries)
{
NS_ENSURE_ARG(aNumEntries);
*aNumEntries = mNumEntries;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetMaxEntries(PRUint32 *aMaxEntries)
{
NS_ENSURE_ARG(aMaxEntries);
*aMaxEntries = MEM_CACHE_MAX_ENTRIES;
return NS_OK;
}
static NS_METHOD
HashEntryConverter(nsHashKey *aKey, void *aValue,
void *unused, nsISupports **retval)
{
nsMemCacheRecord *record;
nsOpaqueKey *opaqueKey;
record = (nsMemCacheRecord*)aValue;
opaqueKey = (nsOpaqueKey*)aKey;
// Hash table keys that index cache entries by their record ID
// shouldn't be enumerated.
if ((opaqueKey->GetKeyLength() == sizeof(PRInt32))) {
#ifdef DEBUG
PRInt32 recordID;
record->GetRecordID(&recordID);
NS_ASSERTION(*((PRInt32*)opaqueKey->GetKey()) == recordID,
"Key has incorrect key length");
#endif
return NS_ERROR_FAILURE;
}
NS_IF_ADDREF(record);
*retval = NS_STATIC_CAST(nsISupports*, record);
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::NewCacheEntryIterator(nsISimpleEnumerator* *aIterator)
{
nsCOMPtr<nsIEnumerator> iterator;
NS_ENSURE_ARG(aIterator);
NS_NewHashtableEnumerator(mHashTable, HashEntryConverter,
mHashTable, getter_AddRefs(iterator));
return NS_NewAdapterEnumerator(aIterator, iterator);
}
NS_IMETHODIMP
nsMemCache::GetNextCache(nsINetDataCache* *aNextCache)
{
NS_ENSURE_ARG(aNextCache);
*aNextCache = mNextCache;
NS_ADDREF(*aNextCache);
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::SetNextCache(nsINetDataCache* aNextCache)
{
mNextCache = aNextCache;
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::GetStorageInUse(PRUint32 *aStorageInUse)
{
NS_ENSURE_ARG(aStorageInUse);
// Convert from bytes to KB
*aStorageInUse = (mOccupancy >> 10);
return NS_OK;
}
NS_IMETHODIMP
nsMemCache::RemoveAll(void)
{
PRBool failed;
nsCOMPtr<nsISimpleEnumerator> iterator;
nsCOMPtr<nsISupports> recordSupports;
nsCOMPtr<nsINetDataCacheRecord> record;
nsresult rv;
failed = PR_FALSE;
rv = NewCacheEntryIterator(getter_AddRefs(iterator));
if (NS_FAILED(rv))
return rv;
PRBool notDone;
while (1) {
rv = iterator->HasMoreElements(&notDone);
if (NS_FAILED(rv)) return rv;
if (!notDone)
break;
iterator->GetNext(getter_AddRefs(recordSupports));
record = do_QueryInterface(recordSupports);
recordSupports = 0;
PRUint32 bytesUsed;
record->GetStoredContentLength(&bytesUsed);
rv = record->Delete();
if (NS_FAILED(rv)) {
failed = PR_TRUE;
continue;
}
mOccupancy -= bytesUsed;
}
if (failed)
return NS_ERROR_FAILURE;
return NS_OK;
}

View File

@@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
/**
* nsMemCache is the implementation of an in-memory network-data
* cache, used to cache the responses to network retrieval commands.
* Each cache entry may contain both content, e.g. GIF image data, and
* associated metadata, e.g. HTTP headers. Each entry is indexed by
* two different keys: a record id number and an opaque key, which is
* created by the cache manager by combining the URI with a "secondary
* key", e.g. HTTP post data.
*/
#ifndef _nsMemCache_h_
#define _nsMemCache_h_
#include "nsINetDataCache.h"
// Maximum number of URIs that may be resident in the cache
#define MEM_CACHE_MAX_ENTRIES 1000
#define MEM_CACHE_SEGMENT_SIZE (1 << 12)
#define MEM_CACHE_MAX_ENTRY_SIZE (1 << 20)
class nsHashtable;
class nsMemCacheRecord;
class nsMemCache : public nsINetDataCache
{
public:
nsMemCache();
virtual ~nsMemCache();
nsresult Init();
// nsISupports methods
NS_DECL_ISUPPORTS
// nsINetDataCache methods
NS_DECL_NSINETDATACACHE
// Factory
static NS_METHOD nsMemCacheConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult);
protected:
PRUint32 mNumEntries;
PRUint32 mOccupancy; // Memory used, in bytes
PRBool mEnabled; // If false, bypass mem cache
nsINetDataCache* mNextCache;
// Mapping from either opaque key or record ID to nsMemCacheRecord
nsHashtable* mHashTable;
// Used to assign record ID's
static PRInt32 gRecordSerialNumber;
NS_METHOD Delete(nsMemCacheRecord* aRecord);
friend class nsMemCacheRecord;
friend class nsMemCacheChannel;
};
#endif // _nsMemCache_h_

View File

@@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
// XPCOM Class ID for the network data in-memory cache
#ifndef nsMEMCACHECID_h__
#define nsMEMCACHECID_h__
// {e4710560-7de2-11d3-90cb-0040056a906e}
#define NS_MEM_CACHE_FACTORY_CID \
{ \
0xe4710560, \
0x7de2, \
0x11d3, \
{0x90, 0xcb, 0x00, 0x40, 0x05, 0x6a, 0x90, 0x6e} \
}
#endif // nsMEMCACHECID_h__

View File

@@ -0,0 +1,462 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
#include "nsMemCache.h"
#include "nsMemCacheChannel.h"
#include "nsIStreamListener.h"
#include "nsIChannel.h"
#include "nsIStorageStream.h"
#include "nsIOutputStream.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsNetUtil.h"
#include "nsILoadGroup.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
NS_IMPL_ISUPPORTS(nsMemCacheChannel, NS_GET_IID(nsIChannel))
void
nsMemCacheChannel::NotifyStorageInUse(PRInt32 aBytesUsed)
{
mRecord->mCache->mOccupancy += aBytesUsed;
}
/**
* This class acts as an adaptor around a synchronous input stream to add async
* read capabilities. It adds methods for initiating, suspending, resuming and
* cancelling async reads.
*/
class AsyncReadStreamAdaptor : public nsIInputStream {
public:
AsyncReadStreamAdaptor(nsMemCacheChannel* aChannel, nsIInputStream *aSyncStream):
mSyncStream(aSyncStream), mDataAvailCursor(0),
mRemaining(0), mAvailable(0), mChannel(aChannel), mAborted(PR_FALSE), mSuspended(PR_FALSE)
{
NS_INIT_REFCNT();
NS_ADDREF(mChannel);
}
virtual ~AsyncReadStreamAdaptor() {
mChannel->mAsyncReadStream = 0;
NS_RELEASE(mChannel);
}
NS_DECL_ISUPPORTS
nsresult
IsPending(PRBool* aIsPending) {
*aIsPending = (mRemaining != 0) && !mAborted;
return NS_OK;
}
nsresult
Cancel(void) {
mAborted = PR_TRUE;
return mStreamListener->OnStopRequest(mChannel, mContext, NS_BINDING_ABORTED, nsnull);
}
nsresult
Suspend(void) { mSuspended = PR_TRUE; return NS_OK; }
nsresult
Resume(void) {
if (!mSuspended)
return NS_ERROR_FAILURE;
mSuspended = PR_FALSE;
return NextListenerEvent();
}
NS_IMETHOD
Available(PRUint32 *aNumBytes) { return mAvailable; }
NS_IMETHOD
Read(char* aBuf, PRUint32 aCount, PRUint32 *aBytesRead) {
if (mAborted)
return NS_ERROR_ABORT;
*aBytesRead = 0;
aCount = PR_MIN(aCount, mAvailable);
nsresult rv = mSyncStream->Read(aBuf, aCount, aBytesRead);
mAvailable -= *aBytesRead;
if (NS_FAILED(rv) && (rv != NS_BASE_STREAM_WOULD_BLOCK)) {
Fail();
return rv;
}
if (!mSuspended && !mAvailable) {
rv = NextListenerEvent();
if (NS_FAILED(rv)) {
Fail();
return rv;
}
}
return NS_OK;
}
NS_IMETHOD
Close() {
nsresult rv = mSyncStream->Close();
mSyncStream = 0;
mContext = 0;
mStreamListener = 0;
return rv;
}
nsresult
AsyncRead(PRUint32 aStartPosition, PRInt32 aReadCount,
nsISupports* aContext, nsIStreamListener* aListener) {
nsresult rv;
nsIEventQueue *eventQ;
mContext = aContext;
mStreamListener = aListener;
mRemaining = aReadCount;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueService, &rv);
if (NS_FAILED(rv)) return rv;
rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ);
if (NS_FAILED(rv)) return rv;
rv = NS_NewAsyncStreamListener(aListener, eventQ,
getter_AddRefs(mStreamListener));
NS_RELEASE(eventQ);
if (NS_FAILED(rv)) return rv;
rv = mStreamListener->OnStartRequest(mChannel, aContext);
if (NS_FAILED(rv)) return rv;
return NextListenerEvent();
}
protected:
nsresult
Fail(void) {
mAborted = PR_TRUE;
return mStreamListener->OnStopRequest(mChannel, mContext, NS_BINDING_FAILED, nsnull);
}
nsresult
NextListenerEvent() {
PRUint32 available;
nsresult rv = mSyncStream->Available(&available);
if (NS_FAILED(rv)) return rv;
available -= mAvailable;
available = PR_MIN(available, mRemaining);
if (available) {
PRUint32 size = PR_MIN(available, MEM_CACHE_SEGMENT_SIZE);
rv = mStreamListener->OnDataAvailable(mChannel, mContext, this,
mDataAvailCursor, size);
mDataAvailCursor += size;
mRemaining -= size;
mAvailable += size;
return rv;
} else {
rv = mStreamListener->OnStopRequest(mChannel, mContext, NS_OK, nsnull);
AsyncReadStreamAdaptor* thisAlias = this;
NS_RELEASE(thisAlias);
return rv;
}
}
private:
nsCOMPtr<nsISupports> mContext; // Opaque context passed to AsyncRead()
nsCOMPtr<nsIStreamListener> mStreamListener; // Stream listener that has been proxied
nsCOMPtr<nsIInputStream> mSyncStream; // Underlying synchronous stream that is
// being converted to an async stream
PRUint32 mDataAvailCursor;
PRUint32 mRemaining; // Size of AsyncRead request less bytes for
// consumer OnDataAvailable's that were fired
PRUint32 mAvailable; // Number of bytes for which OnDataAvailable fired
nsMemCacheChannel* mChannel; // Associated memory cache channel, strong link
// but can not use nsCOMPtr
PRBool mAborted; // Abort() has been called
PRBool mSuspended; // Suspend() has been called
};
NS_IMPL_ISUPPORTS(AsyncReadStreamAdaptor, NS_GET_IID(nsIInputStream))
// The only purpose of this output stream wrapper is to adjust the cache's
// overall occupancy as new data flows into the cache entry.
class MemCacheWriteStreamWrapper : public nsIOutputStream {
public:
MemCacheWriteStreamWrapper(nsMemCacheChannel* aChannel, nsIOutputStream *aBaseStream):
mBaseStream(aBaseStream), mChannel(aChannel)
{
NS_INIT_REFCNT();
NS_ADDREF(mChannel);
}
virtual ~MemCacheWriteStreamWrapper() { NS_RELEASE(mChannel); };
static nsresult
Create(nsMemCacheChannel* aChannel, nsIOutputStream *aBaseStream, nsIOutputStream* *aWrapper) {
MemCacheWriteStreamWrapper *wrapper =
new MemCacheWriteStreamWrapper(aChannel, aBaseStream);
if (!wrapper) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(wrapper);
*aWrapper = wrapper;
return NS_OK;
}
NS_DECL_ISUPPORTS
NS_IMETHOD
Write(const char *aBuffer, PRUint32 aCount, PRUint32 *aNumWritten) {
*aNumWritten = 0;
nsresult rv = mBaseStream->Write(aBuffer, aCount, aNumWritten);
mChannel->NotifyStorageInUse(*aNumWritten);
return rv;
}
NS_IMETHOD
Flush() { return mBaseStream->Flush(); }
NS_IMETHOD
Close() { return mBaseStream->Close(); }
private:
nsCOMPtr<nsIOutputStream> mBaseStream;
nsMemCacheChannel* mChannel;
};
NS_IMPL_ISUPPORTS(MemCacheWriteStreamWrapper, NS_GET_IID(nsIOutputStream))
nsMemCacheChannel::nsMemCacheChannel(nsMemCacheRecord *aRecord, nsILoadGroup *aLoadGroup)
: mRecord(aRecord)
{
NS_INIT_REFCNT();
mRecord->mNumChannels++;
}
nsMemCacheChannel::~nsMemCacheChannel()
{
mRecord->mNumChannels--;
}
NS_IMETHODIMP
nsMemCacheChannel::IsPending(PRBool* aIsPending)
{
*aIsPending = PR_FALSE;
if (!mAsyncReadStream)
return NS_OK;
return mAsyncReadStream->IsPending(aIsPending);
}
NS_IMETHODIMP
nsMemCacheChannel::Cancel(void)
{
if (!mAsyncReadStream)
return NS_ERROR_FAILURE;
return mAsyncReadStream->Cancel();
}
NS_IMETHODIMP
nsMemCacheChannel::Suspend(void)
{
if (!mAsyncReadStream)
return NS_ERROR_FAILURE;
return mAsyncReadStream->Suspend();
}
NS_IMETHODIMP
nsMemCacheChannel::Resume(void)
{
if (!mAsyncReadStream)
return NS_ERROR_FAILURE;
return mAsyncReadStream->Resume();
}
NS_IMETHODIMP
nsMemCacheChannel::GetOriginalURI(nsIURI * *aURI)
{
// Not required
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetURI(nsIURI * *aURI)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::OpenInputStream(PRUint32 aStartPosition, PRInt32 aReadCount,
nsIInputStream* *aResult)
{
nsresult rv;
NS_ENSURE_ARG(aResult);
if (mInputStream)
return NS_ERROR_NOT_AVAILABLE;
rv = mRecord->mStorageStream->NewInputStream(aStartPosition, getter_AddRefs(mInputStream));
*aResult = mInputStream;
NS_ADDREF(*aResult);
return rv;
}
NS_IMETHODIMP
nsMemCacheChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream* *aResult)
{
nsresult rv;
NS_ENSURE_ARG(aResult);
nsCOMPtr<nsIOutputStream> outputStream;
PRUint32 oldLength;
mRecord->mStorageStream->GetLength(&oldLength);
rv = mRecord->mStorageStream->GetOutputStream(startPosition, getter_AddRefs(outputStream));
if (NS_FAILED(rv)) return rv;
if (startPosition < oldLength)
NotifyStorageInUse(startPosition - oldLength);
return MemCacheWriteStreamWrapper::Create(this, outputStream, aResult);
}
NS_IMETHODIMP
nsMemCacheChannel::AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt)
{
// Not required
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::AsyncRead(PRUint32 aStartPosition, PRInt32 aReadCount,
nsISupports *aContext, nsIStreamListener *aListener)
{
nsCOMPtr<nsIInputStream> inputStream;
nsresult rv = OpenInputStream(aStartPosition, aReadCount, getter_AddRefs(inputStream));
if (NS_FAILED(rv)) return rv;
AsyncReadStreamAdaptor *asyncReadStreamAdaptor;
asyncReadStreamAdaptor = new AsyncReadStreamAdaptor(this, inputStream);
if (!asyncReadStreamAdaptor)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(asyncReadStreamAdaptor);
mAsyncReadStream = asyncReadStreamAdaptor;
rv = asyncReadStreamAdaptor->AsyncRead(aStartPosition, aReadCount, aContext, aListener);
if (NS_FAILED(rv))
delete asyncReadStreamAdaptor;
return rv;
}
NS_IMETHODIMP
nsMemCacheChannel::AsyncWrite(nsIInputStream *fromStream, PRUint32 startPosition,
PRInt32 writeCount, nsISupports *ctxt,
nsIStreamObserver *observer)
{
// Not required to be implemented
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetContentType(char* *aContentType)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetContentLength(PRInt32 *aContentLength)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheChannel::SetOwner(nsISupports* aOwner)
{
// Not required to be implemented, since it is implemented by cache manager
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
// Not required to be implemented, since it is implemented by cache manager
NS_ASSERTION(0, "nsMemCacheChannel method unexpectedly called");
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
#ifndef _nsMemCacheChannel_h_
#define _nsMemCacheChannel_h_
#include "nsMemCacheRecord.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
class AsyncReadStreamAdaptor;
class nsMemCacheChannel : public nsIChannel
{
public:
// Constructors and Destructor
nsMemCacheChannel(nsMemCacheRecord *aRecord, nsILoadGroup *aLoadGroup);
virtual ~nsMemCacheChannel();
// Declare nsISupports methods
NS_DECL_ISUPPORTS
// Declare nsIRequest methods
NS_DECL_NSIREQUEST
// Declare nsIChannel methods
NS_DECL_NSICHANNEL
protected:
void NotifyStorageInUse(PRInt32 aBytesUsed);
nsCOMPtr<nsMemCacheRecord> mRecord;
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsISupports> mOwner;
AsyncReadStreamAdaptor* mAsyncReadStream; // non-owning pointer
friend class MemCacheWriteStreamWrapper;
friend class AsyncReadStreamAdaptor;
};
#endif // _nsMemCacheChannel_h_

View File

@@ -0,0 +1,164 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
#include "nsMemCache.h"
#include "nsMemCacheRecord.h"
#include "nsMemCacheChannel.h"
#include "nsIAllocator.h"
#include "nsStorageStream.h"
static NS_DEFINE_IID(kINetDataCacheRecord, NS_INETDATACACHERECORD_IID);
nsMemCacheRecord::nsMemCacheRecord()
: mKey(0), mKeyLength(0), mMetaData(0), mMetaDataLength(0), mNumChannels(0)
{
NS_INIT_REFCNT();
}
nsMemCacheRecord::~nsMemCacheRecord()
{
if (mMetaData)
delete[] mMetaData;
if (mKey)
delete[] mKey;
}
NS_IMPL_ISUPPORTS(nsMemCacheRecord, NS_GET_IID(nsINetDataCacheRecord))
NS_IMETHODIMP
nsMemCacheRecord::GetKey(PRUint32 *aLength, char **aResult)
{
NS_ENSURE_ARG(aResult);
*aResult = (char *)nsAllocator::Alloc(mKeyLength);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
memcpy(*aResult, mKey, mKeyLength);
*aLength = mKeyLength;
return NS_OK;
}
nsresult
nsMemCacheRecord::Init(const char *aKey, PRUint32 aKeyLength,
PRUint32 aRecordID, nsMemCache *aCache)
{
nsresult rv;
NS_ASSERTION(!mKey, "Memory cache record key set multiple times");
rv = NS_NewStorageStream(MEM_CACHE_SEGMENT_SIZE, MEM_CACHE_MAX_ENTRY_SIZE,
getter_AddRefs(mStorageStream));
if (NS_FAILED(rv)) return rv;
mKey = new char[aKeyLength];
if (!mKey)
return NS_ERROR_OUT_OF_MEMORY;
memcpy(mKey, aKey, aKeyLength);
mKeyLength = aKeyLength;
mRecordID = aRecordID;
mCache = aCache;
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheRecord::GetRecordID(PRInt32 *aRecordID)
{
NS_ENSURE_ARG(aRecordID);
*aRecordID = mRecordID;
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheRecord::GetMetaData(PRUint32 *aLength, char **aResult)
{
NS_ENSURE_ARG(aResult);
*aResult = 0;
if (mMetaDataLength) {
*aResult = (char*)nsAllocator::Alloc(mMetaDataLength);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
memcpy(*aResult, mMetaData, mMetaDataLength);
}
*aLength = mMetaDataLength;
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheRecord::SetMetaData(PRUint32 aLength, const char *aData)
{
if (mMetaData)
delete[] mMetaData;
mMetaData = new char[aLength];
if (!mMetaData)
return NS_ERROR_OUT_OF_MEMORY;
memcpy(mMetaData, aData, aLength);
mMetaDataLength = aLength;
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheRecord::GetStoredContentLength(PRUint32 *aStoredContentLength)
{
NS_ENSURE_ARG(aStoredContentLength);
return mStorageStream->GetLength(aStoredContentLength);
}
NS_IMETHODIMP
nsMemCacheRecord::SetStoredContentLength(PRUint32 aStoredContentLength)
{
PRUint32 before, after;
mStorageStream->GetLength(&before);
nsresult rv = mStorageStream->SetLength(aStoredContentLength);
if (NS_FAILED(rv)) return rv;
mStorageStream->GetLength(&after);
mCache->mOccupancy -= (before - after);
return NS_OK;
}
NS_IMETHODIMP
nsMemCacheRecord::Delete(void)
{
if (mNumChannels)
return NS_ERROR_NOT_AVAILABLE;
return mCache->Delete(this);
}
NS_IMETHODIMP
nsMemCacheRecord::GetFilename(nsIFileSpec* *aFilename)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMemCacheRecord::NewChannel(nsILoadGroup *aLoadGroup, nsIChannel* *aResult)
{
NS_ENSURE_ARG(aResult);
nsMemCacheChannel* channel = new nsMemCacheChannel(this, aLoadGroup);
if (!channel)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(channel);
*aResult = NS_STATIC_CAST(nsIChannel*, channel);
return NS_OK;
}

View File

@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
*/
#ifndef _nsMemCacheRecord_h_
#define _nsMemCacheRecord_h_
#include "nsINetDataCacheRecord.h"
#include "nsIStorageStream.h"
#include "nsCOMPtr.h"
class nsMemCache;
class nsMemCacheRecord : public nsINetDataCacheRecord
{
public:
// Declare interface methods
NS_DECL_ISUPPORTS
NS_DECL_NSINETDATACACHERECORD
protected:
// Constructors and Destructor
nsMemCacheRecord();
virtual ~nsMemCacheRecord();
nsresult Init(const char *aKey, PRUint32 aKeyLength,
PRUint32 aRecordID, nsMemCache *aCache);
char* mKey; // opaque database key for this record
PRUint32 mKeyLength; // length, in bytes, of mKey
PRInt32 mRecordID; // An alternate key for this record
char* mMetaData; // opaque URI metadata
PRUint32 mMetaDataLength; // length, in bytes, of mMetaData
nsMemCache* mCache; // weak pointer to the cache database
// that this record inhabits
nsCOMPtr<nsIStorageStream> mStorageStream;
PRUint32 mNumChannels; // Count un-Release'ed nsIChannels
friend class nsMemCache;
friend class nsMemCacheChannel;
};
#endif // _nsMemCacheRecord_h_

55
mozilla/netwerk/cache/mgr/Makefile.in vendored Normal file
View File

@@ -0,0 +1,55 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = nkcache
LIBRARY_NAME = nkcachemgr_s
REQUIRES = nspr
EXPORTS = \
nsCacheManager.h \
$(NULL)
CPPSRCS = \
nsCacheManager.cpp \
nsCachedNetData.cpp \
nsReplacementPolicy.cpp \
nsCacheEntryChannel.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)/../public -I$(srcdir)/../include
EXTRA_LIBS = $(NSPR_LIBS)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

45
mozilla/netwerk/cache/mgr/Makefile.win vendored Executable file
View File

@@ -0,0 +1,45 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = nkcache
LIBRARY_NAME = nkcachemgr_s
CPP_OBJS = \
.\$(OBJDIR)\nsCacheManager.obj \
.\$(OBJDIR)\nsCachedNetData.obj \
.\$(OBJDIR)\nsReplacementPolicy.obj \
.\$(OBJDIR)\nsCacheEntryChannel.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -rf $(OBJDIR)
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,261 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Scott Furman, fur@netscape.com
*/
#include "nsCacheManager.h"
#include "nsCacheEntryChannel.h"
#include "nsIOutputStream.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIStreamListener.h"
nsCacheEntryChannel::nsCacheEntryChannel(nsCachedNetData* aCacheEntry, nsIChannel* aChannel,
nsILoadGroup* aLoadGroup):
nsChannelProxy(aChannel), mCacheEntry(aCacheEntry), mLoadGroup(aLoadGroup), mLoadAttributes(0)
{
NS_ASSERTION(aCacheEntry->mChannelCount < 0xFF, "Overflowed channel counter");
mCacheEntry->mChannelCount++;
NS_INIT_REFCNT();
}
nsCacheEntryChannel::~nsCacheEntryChannel()
{
mCacheEntry->mChannelCount--;
}
NS_IMPL_ISUPPORTS3(nsCacheEntryChannel, nsISupports, nsIChannel, nsIRequest)
// A proxy for nsIOutputStream
class CacheOutputStream : public nsIOutputStream {
public:
CacheOutputStream(nsIOutputStream *aOutputStream, nsCachedNetData *aCacheEntry):
mOutputStream(aOutputStream), mCacheEntry(aCacheEntry), mStartTime(PR_Now())
{ NS_INIT_REFCNT(); }
virtual ~CacheOutputStream() {
mCacheEntry->NoteDownloadTime(mStartTime, PR_Now());
mCacheEntry->ClearFlag(nsCachedNetData::UPDATE_IN_PROGRESS);
}
NS_DECL_ISUPPORTS
NS_IMETHOD Close() {
return mOutputStream->Close();
}
NS_IMETHOD Flush() { return mOutputStream->Flush(); }
NS_IMETHOD
Write(const char *aBuf, PRUint32 aCount, PRUint32 *aActualBytes) {
nsresult rv;
*aActualBytes = 0;
rv = mOutputStream->Write(aBuf, aCount, aActualBytes);
mCacheEntry->mLogicalLength += *aActualBytes;
if (NS_FAILED(rv)) return rv;
nsCacheManager::LimitCacheSize();
return rv;
}
protected:
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCOMPtr<nsCachedNetData> mCacheEntry;
// Time at which stream was opened
PRTime mStartTime;
};
NS_IMPL_ISUPPORTS(CacheOutputStream, NS_GET_IID(nsIOutputStream))
NS_IMETHODIMP
nsCacheEntryChannel::OpenOutputStream(PRUint32 aStartPosition, nsIOutputStream* *aOutputStream)
{
nsresult rv;
nsCOMPtr<nsIOutputStream> baseOutputStream;
rv = mChannel->OpenOutputStream(aStartPosition, getter_AddRefs(baseOutputStream));
if (NS_FAILED(rv)) return rv;
mCacheEntry->NoteUpdate();
mCacheEntry->NoteAccess();
mCacheEntry->mLogicalLength = aStartPosition;
*aOutputStream = new CacheOutputStream(baseOutputStream, mCacheEntry);
if (!*aOutputStream)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aOutputStream);
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryChannel::OpenInputStream(PRUint32 aStartPosition, PRInt32 aReadCount,
nsIInputStream* *aInputStream)
{
mCacheEntry->NoteAccess();
return mChannel->OpenInputStream(aStartPosition, aReadCount, aInputStream);
}
class CacheManagerStreamListener: public nsIStreamListener {
public:
CacheManagerStreamListener(nsIStreamListener *aListener,
nsILoadGroup *aLoadGroup, nsIChannel *aChannel):
mListener(aListener), mLoadGroup(aLoadGroup), mChannel(aChannel)
{ NS_INIT_REFCNT(); }
virtual ~CacheManagerStreamListener() {}
private:
NS_DECL_ISUPPORTS
NS_IMETHOD
OnDataAvailable(nsIChannel *channel, nsISupports *aContext,
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) {
return mListener->OnDataAvailable(mChannel, aContext, inStr, sourceOffset, count);
}
NS_IMETHOD
OnStartRequest(nsIChannel *channel, nsISupports *aContext) {
if (mLoadGroup)
mLoadGroup->AddChannel(mChannel, aContext);
return mListener->OnStartRequest(mChannel, aContext);
}
NS_IMETHOD
OnStopRequest(nsIChannel *channel, nsISupports *aContext,
nsresult status, const PRUnichar *errorMsg) {
nsresult rv;
rv = mListener->OnStopRequest(mChannel, aContext, status, errorMsg);
if (mLoadGroup)
mLoadGroup->RemoveChannel(mChannel, aContext, status, errorMsg);
return rv;
}
private:
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIChannel> mChannel;
};
NS_IMPL_ISUPPORTS2(CacheManagerStreamListener, nsIStreamListener, nsIStreamObserver)
NS_IMETHODIMP
nsCacheEntryChannel::AsyncRead(PRUint32 aStartPosition, PRInt32 aReadCount,
nsISupports *aContext, nsIStreamListener *aListener)
{
nsresult rv;
mCacheEntry->NoteAccess();
nsCOMPtr<nsIStreamListener> headListener;
if (mLoadGroup) {
mLoadGroup->GetDefaultLoadAttributes(&mLoadAttributes);
// Create a load group "proxy" listener...
nsCOMPtr<nsILoadGroupListenerFactory> factory;
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (NS_SUCCEEDED(rv) && factory) {
rv = factory->CreateLoadGroupListener(aListener,
getter_AddRefs(headListener));
if (NS_FAILED(rv)) return rv;
}
} else {
headListener = aListener;
}
CacheManagerStreamListener* cacheManagerStreamListener;
nsIChannel *channelForListener;
channelForListener = mProxyChannel ? mProxyChannel.get() : NS_STATIC_CAST(nsIChannel*, this);
cacheManagerStreamListener =
new CacheManagerStreamListener(headListener, mLoadGroup, channelForListener);
if (!cacheManagerStreamListener) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cacheManagerStreamListener);
rv = mChannel->AsyncRead(aStartPosition, aReadCount, aContext,
cacheManagerStreamListener);
NS_RELEASE(cacheManagerStreamListener);
return rv;
}
// No async writes allowed to the cache yet
NS_IMETHODIMP
nsCacheEntryChannel::AsyncWrite(nsIInputStream *aFromStream, PRUint32 aStartPosition,
PRInt32 aWriteCount, nsISupports *aContext,
nsIStreamObserver *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCacheEntryChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
NS_IMETHODIMP
nsCacheEntryChannel::GetURI(nsIURI * *aURI)
{
char* spec;
nsresult rv;
rv = mCacheEntry->GetUriSpec(&spec);
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = serv->NewURI(spec, 0, aURI);
nsAllocator::Free(spec);
return rv;
}
NS_IMETHODIMP
nsCacheEntryChannel::GetOriginalURI(nsIURI * *aURI)
{
// FIXME - should return original URI passed into NewChannel() ?
return NS_ERROR_NOT_IMPLEMENTED;
}

Some files were not shown because too many files have changed in this diff Show More