Compare commits
5 Commits
IMGLIB2_NE
...
sdr_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4127f7ed92 | ||
|
|
fc8cd8ebd2 | ||
|
|
26ed09faf4 | ||
|
|
14e542e142 | ||
|
|
fe9b32e930 |
@@ -1,33 +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 = public src decoders
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,41 +0,0 @@
|
||||
/* -*- 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.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):
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsGIFDecoder2.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "GIF Decoder",
|
||||
NS_GIFDECODER2_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/gif",
|
||||
nsGIFDecoder2Constructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsGIFModule2", components)
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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___ */
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- 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.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):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIconProtocolHandler_h___
|
||||
#define nsIconProtocolHandler_h___
|
||||
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
|
||||
class nsIconProtocolHandler : public nsIProtocolHandler, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
|
||||
// nsIconProtocolHandler methods:
|
||||
nsIconProtocolHandler();
|
||||
virtual ~nsIconProtocolHandler();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif /* nsIconProtocolHandler_h___ */
|
||||
@@ -1,46 +0,0 @@
|
||||
#!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):
|
||||
# Scott MacGregor <mscott@netscape.com>
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
MODULE=imgicon
|
||||
|
||||
LIBRARY_NAME=imgiconwin_s
|
||||
|
||||
CPP_OBJS=\
|
||||
.\$(OBJDIR)\nsIconChannel.obj \
|
||||
$(NULL)
|
||||
|
||||
INCS = $(INCS) \
|
||||
-I$(DEPTH)\dist\include \
|
||||
-I..\ \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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___ */
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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 ¶mName, 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 ¶mName, 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 ¶mName, 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 ¶mName, 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
|
||||
@@ -1 +0,0 @@
|
||||
ImageLogging.h
|
||||
@@ -1,6 +0,0 @@
|
||||
imgIContainer.idl
|
||||
imgIContainerObserver.idl
|
||||
imgIDecoder.idl
|
||||
imgIDecoderObserver.idl
|
||||
imgILoader.idl
|
||||
imgIRequest.idl
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
%}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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:
|
||||
};
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
74
mozilla/security/psm/lib/Makefile
Executable file
74
mozilla/security/psm/lib/Makefile
Executable file
@@ -0,0 +1,74 @@
|
||||
#! gmake
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
@@ -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,7 +26,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = ppm png gif jpeg
|
||||
DIRS = protocol client
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
3
mozilla/security/psm/lib/client/MANIFEST
Normal file
3
mozilla/security/psm/lib/client/MANIFEST
Normal file
@@ -0,0 +1,3 @@
|
||||
cmtclist.h
|
||||
cmtcmn.h
|
||||
cmtjs.h
|
||||
74
mozilla/security/psm/lib/client/Makefile
Executable file
74
mozilla/security/psm/lib/client/Makefile
Executable file
@@ -0,0 +1,74 @@
|
||||
#! gmake
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
include config.mk
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
70
mozilla/security/psm/lib/client/Makefile.in
Normal file
70
mozilla/security/psm/lib/client/Makefile.in
Normal file
@@ -0,0 +1,70 @@
|
||||
#! gmake
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
LIBRARY_NAME = cmt
|
||||
|
||||
EXPORTS = \
|
||||
cmtcmn.h \
|
||||
cmtjs.h \
|
||||
cmtclist.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
|
||||
CSRCS = cmtinit.c \
|
||||
cmtssl.c \
|
||||
cmtutils.c \
|
||||
cmtcert.c \
|
||||
cmthash.c \
|
||||
cmtpkcs7.c \
|
||||
cmtres.c \
|
||||
cmtjs.c \
|
||||
cmtevent.c \
|
||||
cmtpasswd.c \
|
||||
cmtadvisor.c \
|
||||
cmtrng.c \
|
||||
cmtsdr.c \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += -L$(DIST)/bin -lprotocol
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
99
mozilla/security/psm/lib/client/cmtadvisor.c
Normal file
99
mozilla/security/psm/lib/client/cmtadvisor.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#ifdef XP_MAC
|
||||
#include "cmtmac.h"
|
||||
#endif
|
||||
|
||||
CMTStatus CMT_SecurityAdvisor(PCMT_CONTROL control, CMTSecurityAdvisorData* data, CMUint32 *resID)
|
||||
{
|
||||
CMTItem message = {0, NULL, 0};
|
||||
SecurityAdvisorRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.infoContext = data->infoContext;
|
||||
request.resID = data->resID;
|
||||
request.hostname = data->hostname;
|
||||
request.senderAddr = data->senderAddr;
|
||||
request.encryptedP7CInfo = data->encryptedP7CInfo;
|
||||
request.signedP7CInfo = data->signedP7CInfo;
|
||||
request.decodeError = data->decodeError;
|
||||
request.verifyError = data->verifyError;
|
||||
request.encryptthis = data->encryptthis;
|
||||
request.signthis = data->signthis;
|
||||
request.numRecipients = data->numRecipients;
|
||||
request.recipients = data->recipients;
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_SECURITY_ADVISOR;
|
||||
|
||||
if (CMT_EncodeMessage(SecurityAdvisorRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SECURITY_ADVISOR)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*resID = reply.value;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
|
||||
if (message.data) {
|
||||
free(message.data);
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1362
mozilla/security/psm/lib/client/cmtcert.c
Normal file
1362
mozilla/security/psm/lib/client/cmtcert.c
Normal file
File diff suppressed because it is too large
Load Diff
111
mozilla/security/psm/lib/client/cmtclist.h
Normal file
111
mozilla/security/psm/lib/client/cmtclist.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef cmtclist_h___
|
||||
#define cmtclist_h___
|
||||
|
||||
typedef struct CMTCListStr CMTCList;
|
||||
/*
|
||||
** Circular linked list
|
||||
*/
|
||||
struct CMTCListStr {
|
||||
CMTCList *next;
|
||||
CMTCList *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
** Insert element "_e" into the list, before "_l".
|
||||
*/
|
||||
#define CMT_INSERT_BEFORE(_e,_l) \
|
||||
(_e)->next = (_l); \
|
||||
(_e)->prev = (_l)->prev; \
|
||||
(_l)->prev->next = (_e); \
|
||||
(_l)->prev = (_e); \
|
||||
|
||||
/*
|
||||
** Insert element "_e" into the list, after "_l".
|
||||
*/
|
||||
#define CMT_INSERT_AFTER(_e,_l) \
|
||||
(_e)->next = (_l)->next; \
|
||||
(_e)->prev = (_l); \
|
||||
(_l)->next->prev = (_e); \
|
||||
(_l)->next = (_e); \
|
||||
|
||||
/*
|
||||
** Append an element "_e" to the end of the list "_l"
|
||||
*/
|
||||
#define CMT_APPEND_LINK(_e,_l) CMT_INSERT_BEFORE(_e,_l)
|
||||
|
||||
/*
|
||||
** Insert an element "_e" at the head of the list "_l"
|
||||
*/
|
||||
#define CMT_INSERT_LINK(_e,_l) CMT_INSERT_AFTER(_e,_l)
|
||||
|
||||
/* Return the head/tail of the list */
|
||||
#define CMT_LIST_HEAD(_l) (_l)->next
|
||||
#define CMT_LIST_TAIL(_l) (_l)->prev
|
||||
|
||||
/*
|
||||
** Remove the element "_e" from it's circular list.
|
||||
*/
|
||||
#define CMT_REMOVE_LINK(_e) \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
|
||||
/*
|
||||
** Remove the element "_e" from it's circular list. Also initializes the
|
||||
** linkage.
|
||||
*/
|
||||
#define CMT_REMOVE_AND_INIT_LINK(_e) \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
(_e)->next = (_e); \
|
||||
(_e)->prev = (_e); \
|
||||
|
||||
/*
|
||||
** Return non-zero if the given circular list "_l" is empty, zero if the
|
||||
** circular list is not empty
|
||||
*/
|
||||
#define CMT_CLIST_IS_EMPTY(_l) \
|
||||
((_l)->next == (_l))
|
||||
|
||||
/*
|
||||
** Initialize a circular list
|
||||
*/
|
||||
#define CMT_INIT_CLIST(_l) \
|
||||
(_l)->next = (_l); \
|
||||
(_l)->prev = (_l); \
|
||||
|
||||
#define CMT_INIT_STATIC_CLIST(_l) \
|
||||
{(_l), (_l)}
|
||||
|
||||
#endif /* cmtclist_h___ */
|
||||
2264
mozilla/security/psm/lib/client/cmtcmn.h
Normal file
2264
mozilla/security/psm/lib/client/cmtcmn.h
Normal file
File diff suppressed because it is too large
Load Diff
480
mozilla/security/psm/lib/client/cmtevent.c
Normal file
480
mozilla/security/psm/lib/client/cmtevent.c
Normal file
@@ -0,0 +1,480 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include <string.h>
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* Typedefs */
|
||||
typedef void (*taskcompleted_handler_fn)(CMUint32 resourceID, CMUint32 numReqProcessed, CMUint32 resultCode, void* data);
|
||||
|
||||
CMTStatus CMT_SetUIHandlerCallback(PCMT_CONTROL control,
|
||||
uiHandlerCallback_fn f, void *data)
|
||||
{
|
||||
return CMT_RegisterEventHandler(control, SSM_UI_EVENT, 0,
|
||||
(void_fun)f, data);
|
||||
}
|
||||
|
||||
void CMT_SetFilePathPromptCallback(PCMT_CONTROL control,
|
||||
filePathPromptCallback_fn f, void* arg)
|
||||
{
|
||||
control->userFuncs.promptFilePath = f;
|
||||
control->userFuncs.filePromptArg = arg;
|
||||
}
|
||||
|
||||
void CMT_SetPromptCallback(PCMT_CONTROL control,
|
||||
promptCallback_fn f, void *arg)
|
||||
{
|
||||
control->userFuncs.promptCallback = f;
|
||||
control->userFuncs.promptArg = arg;
|
||||
}
|
||||
|
||||
void CMT_SetSavePrefsCallback(PCMT_CONTROL control, savePrefsCallback_fn f)
|
||||
{
|
||||
control->userFuncs.savePrefs = f;
|
||||
}
|
||||
|
||||
CMTStatus CMT_RegisterEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID, void_fun handler,
|
||||
void* data)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
/* This is the first connection */
|
||||
if (control->cmtEventHandlers == NULL) {
|
||||
control->cmtEventHandlers = ptr =
|
||||
(PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (!ptr) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
/* Look for another event handler of the same type. Make sure the
|
||||
event handler with a rsrcid of 0 is farther down the list so
|
||||
that it doesn't get chosen when there's an event handler for
|
||||
a specific rsrcid.
|
||||
*/
|
||||
for (ptr=control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->type == type && resourceID != 0) {
|
||||
/* So we've got an event handler that wants to over-ride
|
||||
an existing event handler. We'll put it before the one
|
||||
that's already here.
|
||||
*/
|
||||
if (ptr->previous == NULL) {
|
||||
/* We're going to insert at the front of the list*/
|
||||
control->cmtEventHandlers = ptr->previous =
|
||||
(PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (ptr->previous == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
ptr->previous->next = ptr;
|
||||
ptr = control->cmtEventHandlers;
|
||||
} else {
|
||||
/* We want to insert in the middle of the list */
|
||||
PCMT_EVENT tmpEvent;
|
||||
|
||||
tmpEvent = (PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (tmpEvent == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
tmpEvent->previous = ptr->previous;
|
||||
ptr->previous->next = tmpEvent;
|
||||
tmpEvent->next = ptr;
|
||||
ptr->previous = tmpEvent;
|
||||
ptr = tmpEvent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ptr->next == NULL) break;
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (ptr->next == NULL) {
|
||||
/* We're adding the event handler at the end of the list. */
|
||||
ptr->next = (PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (!ptr->next) {
|
||||
goto loser;
|
||||
}
|
||||
/* Fix up the pointers */
|
||||
ptr->next->previous = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the data */
|
||||
ptr->type = type;
|
||||
ptr->resourceID = resourceID;
|
||||
ptr->handler = handler;
|
||||
ptr->data = data;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_UnregisterEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr, pptr = NULL;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL;
|
||||
pptr = ptr, ptr = ptr->next) {
|
||||
if ((ptr->type == type) && (ptr->resourceID == resourceID)) {
|
||||
if (pptr == NULL) {
|
||||
/* node is at head */
|
||||
control->cmtEventHandlers = ptr->next;
|
||||
if (control->cmtEventHandlers != NULL) {
|
||||
control->cmtEventHandlers->previous = NULL;
|
||||
}
|
||||
free(ptr);
|
||||
return CMTSuccess;
|
||||
}
|
||||
/* node is elsewhere */
|
||||
pptr->next = ptr->next;
|
||||
if (ptr->next != NULL) {
|
||||
ptr->next->previous = pptr;
|
||||
}
|
||||
free(ptr);
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == type) && ((ptr->resourceID == resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetFirstEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == type) && ((ptr->resourceID == resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetNextEventHandler(PCMT_CONTROL control, PCMT_EVENT e)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL || ptr == e;
|
||||
ptr = ptr->next) {
|
||||
}
|
||||
|
||||
for (; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == e->type) && ((ptr->resourceID == e->resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_ProcessEvent(PCMT_CONTROL cm_control)
|
||||
{
|
||||
CMTSocket sock;
|
||||
CMTItem eventData={ 0, NULL, 0 };
|
||||
|
||||
/* Get the control socket */
|
||||
sock = cm_control->sock;
|
||||
|
||||
/* Acquire a lock on the control connection */
|
||||
CMT_LOCK(cm_control->mutex);
|
||||
/* Do another select here to be sure
|
||||
that the socket is readable */
|
||||
if (cm_control->sockFuncs.select(&sock, 1, 1) != sock) {
|
||||
/* There's no event. */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read the event */
|
||||
if (CMT_ReceiveMessage(cm_control, &eventData) == CMTFailure) {
|
||||
goto done;
|
||||
}
|
||||
CMT_UNLOCK(cm_control->mutex);
|
||||
/* Dispatch the event */
|
||||
CMT_DispatchEvent(cm_control, &eventData);
|
||||
return;
|
||||
done:
|
||||
/* Release the lock on the control connection */
|
||||
CMT_UNLOCK(cm_control->mutex);
|
||||
}
|
||||
|
||||
void CMT_EventLoop(PCMT_CONTROL cm_control)
|
||||
{
|
||||
CMTSocket sock;
|
||||
|
||||
/* Get the control socket */
|
||||
sock = cm_control->sock;
|
||||
CMT_ReferenceControlConnection(cm_control);
|
||||
/* Select on the control socket to see if it's readable */
|
||||
while(cm_control->sockFuncs.select(&sock, 1, 0)) {
|
||||
CMT_ProcessEvent(cm_control);
|
||||
}
|
||||
CMT_CloseControlConnection(cm_control);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
CMT_PromptUser(PCMT_CONTROL cm_control, CMTItem *eventData)
|
||||
{
|
||||
char *promptReply = NULL;
|
||||
CMTItem response={ 0, NULL, 0 };
|
||||
PromptRequest request;
|
||||
PromptReply reply;
|
||||
void * clientContext;
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(PromptRequestTemplate, &request, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(request.clientContext);
|
||||
|
||||
if (cm_control->userFuncs.promptCallback == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
promptReply =
|
||||
cm_control->userFuncs.promptCallback(cm_control->userFuncs.promptArg,
|
||||
request.prompt, clientContext, 1);
|
||||
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_PROMPT_EVENT;
|
||||
if (!promptReply) {
|
||||
/* the user canceled the prompt or other errors occurred */
|
||||
reply.cancel = CM_TRUE;
|
||||
}
|
||||
else {
|
||||
/* note that this includes an empty string (zero length) password */
|
||||
reply.cancel = CM_FALSE;
|
||||
}
|
||||
reply.resID = request.resID;
|
||||
reply.promptReply = promptReply;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(PromptReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
loser:
|
||||
if (promptReply != NULL) {
|
||||
cm_control->userFuncs.userFree(promptReply);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_GetFilePath(PCMT_CONTROL cm_control, CMTItem * eventData)
|
||||
{
|
||||
char *fileName=NULL;
|
||||
CMTItem response = { 0, NULL, 0 };
|
||||
FilePathRequest request;
|
||||
FilePathReply reply;
|
||||
|
||||
/* Decode the request */
|
||||
if (CMT_DecodeMessage(FilePathRequestTemplate, &request, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (cm_control->userFuncs.promptFilePath == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
fileName =
|
||||
cm_control->userFuncs.promptFilePath(cm_control->userFuncs.filePromptArg,
|
||||
request.prompt, request.fileRegEx,
|
||||
request.getExistingFile);
|
||||
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_FILE_PATH_EVENT;
|
||||
reply.resID = request.resID;
|
||||
reply.filePath = fileName;
|
||||
|
||||
/* Encode the reply */
|
||||
if (CMT_EncodeMessage(FilePathReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
cm_control->userFuncs.userFree(fileName);
|
||||
loser:
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_SavePrefs(PCMT_CONTROL cm_control, CMTItem* eventData)
|
||||
{
|
||||
SetPrefListMessage request;
|
||||
int i;
|
||||
|
||||
/* decode the request */
|
||||
if (CMT_DecodeMessage(SetPrefListMessageTemplate, &request, eventData) !=
|
||||
CMTSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cm_control->userFuncs.savePrefs == NULL) {
|
||||
/* callback was not registered: bail */
|
||||
return;
|
||||
}
|
||||
cm_control->userFuncs.savePrefs(request.length,
|
||||
(CMTSetPrefElement*)request.list);
|
||||
|
||||
for (i = 0; i < request.length; i++) {
|
||||
if (request.list[i].key != NULL) {
|
||||
free(request.list[i].key);
|
||||
}
|
||||
if (request.list[i].value != NULL) {
|
||||
free(request.list[i].value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_DispatchEvent(PCMT_CONTROL cm_control, CMTItem * eventData)
|
||||
{
|
||||
CMUint32 eventType;
|
||||
CMTItem msgCopy;
|
||||
|
||||
/* Init the msgCopy */
|
||||
msgCopy.data = 0;
|
||||
|
||||
/* Get the event type */
|
||||
if ((eventData->type & SSM_CATEGORY_MASK) != SSM_EVENT_MESSAGE) {
|
||||
/* Somehow there was a message on the socket that was not
|
||||
* an event message. Dropping it on the floor.
|
||||
*/
|
||||
goto loser;
|
||||
}
|
||||
eventType = (eventData->type & SSM_TYPE_MASK);
|
||||
|
||||
/* We must now dispatch the event based on it's type */
|
||||
switch (eventType) {
|
||||
case SSM_UI_EVENT:
|
||||
{
|
||||
PCMT_EVENT p;
|
||||
UIEvent event;
|
||||
void * clientContext = NULL;
|
||||
|
||||
/* Copy the message to allow a second try with the old format */
|
||||
msgCopy.len = eventData->len;
|
||||
msgCopy.data = calloc(msgCopy.len, 1);
|
||||
if (msgCopy.data) {
|
||||
memcpy(msgCopy.data, eventData->data, eventData->len);
|
||||
}
|
||||
|
||||
/* Get the event data first */
|
||||
if (CMT_DecodeMessage(UIEventTemplate, &event, eventData) != CMTSuccess) {
|
||||
/* Attempt to decode using the old format. Modal is True */
|
||||
if (!msgCopy.data ||
|
||||
CMT_DecodeMessage(OldUIEventTemplate, &event, &msgCopy) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set default modal value */
|
||||
event.isModal = CM_TRUE;
|
||||
}
|
||||
|
||||
/* Convert the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(event.clientContext);
|
||||
|
||||
/* Call any handlers for this event */
|
||||
p = CMT_GetEventHandler(cm_control, eventType, event.resourceID);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
(*(uiHandlerCallback_fn)(p->handler))(event.resourceID,
|
||||
clientContext, event.width,
|
||||
event.height, event.isModal, event.url,
|
||||
p->data);
|
||||
break;
|
||||
}
|
||||
|
||||
case SSM_TASK_COMPLETED_EVENT:
|
||||
{
|
||||
PCMT_EVENT p;
|
||||
TaskCompletedEvent event;
|
||||
|
||||
/* Get the event data */
|
||||
if (CMT_DecodeMessage(TaskCompletedEventTemplate, &event, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Call handler for this event */
|
||||
p = CMT_GetEventHandler(cm_control, eventType, event.resourceID);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
(*(taskcompleted_handler_fn)(p->handler))(event.resourceID,
|
||||
event.numTasks,
|
||||
event.result, p->data);
|
||||
break;
|
||||
}
|
||||
case SSM_AUTH_EVENT:
|
||||
CMT_ServicePasswordRequest(cm_control, eventData);
|
||||
break;
|
||||
case SSM_FILE_PATH_EVENT:
|
||||
CMT_GetFilePath(cm_control, eventData);
|
||||
break;
|
||||
case SSM_PROMPT_EVENT:
|
||||
CMT_PromptUser(cm_control, eventData);
|
||||
break;
|
||||
case SSM_SAVE_PREF_EVENT:
|
||||
CMT_SavePrefs(cm_control, eventData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
loser:
|
||||
free(eventData->data);
|
||||
free(msgCopy.data);
|
||||
return;
|
||||
}
|
||||
|
||||
216
mozilla/security/psm/lib/client/cmthash.c
Normal file
216
mozilla/security/psm/lib/client/cmthash.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#include "string.h"
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
CMTStatus CMT_HashCreate(PCMT_CONTROL control, CMUint32 algID,
|
||||
CMUint32 * connID)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = algID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_HASH_STREAM;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the response */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_HASH_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if(sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
/* Send the hello message */
|
||||
control->sockFuncs.send(sock, control->nonce.data, control->nonce.len);
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the connection ID */
|
||||
*connID = reply.connID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
*connID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Destroy(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the cotext implementation data */
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Begin(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Update(PCMT_CONTROL control, CMUint32 connectionID, const unsigned char * buf, CMUint32 len)
|
||||
{
|
||||
CMTSocket sock;
|
||||
CMUint32 sent;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_End(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
unsigned char * result, CMUint32 * resultlen,
|
||||
CMUint32 maxLen)
|
||||
{
|
||||
CMTItem hash = { 0, NULL, 0 };
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !result || !resultlen) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Close the connection */
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the context info */
|
||||
if (CMT_GetStringAttribute(control, connectionID, SSM_FID_HASHCONN_RESULT,
|
||||
&hash) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
if (!hash.data) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*resultlen = hash.len;
|
||||
if (hash.len > maxLen) {
|
||||
memcpy(result, hash.data, maxLen);
|
||||
} else {
|
||||
memcpy(result, hash.data, hash.len);
|
||||
}
|
||||
|
||||
if (hash.data) {
|
||||
free(hash.data);
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (hash.data) {
|
||||
free(hash.data);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
56
mozilla/security/psm/lib/client/cmtimpl.h
Normal file
56
mozilla/security/psm/lib/client/cmtimpl.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __CMTIMPL_H_
|
||||
#define __CMTIMPL_H_
|
||||
|
||||
typedef unsigned long CMT_HANDLE;
|
||||
|
||||
struct _CMTControl {
|
||||
CMT_HANDLE channelID;
|
||||
int socketID;
|
||||
CMTStatus (* cmtEventCallback)(struct _CMTControl * control,
|
||||
CMTItem * event, void * arg);
|
||||
void * cmtEventCallbackArg;
|
||||
struct _CMTData * cmtDataConnection;
|
||||
} _CMTControl;
|
||||
|
||||
|
||||
|
||||
struct _CMTData {
|
||||
CMT_HANDLE channelID;
|
||||
int socketID;
|
||||
struct _CMTData * next;
|
||||
struct _CMTData * previous;
|
||||
};
|
||||
|
||||
#endif /*__CMTIMPL_H_*/
|
||||
484
mozilla/security/psm/lib/client/cmtinit.c
Normal file
484
mozilla/security/psm/lib/client/cmtinit.c
Normal file
@@ -0,0 +1,484 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/tcp.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include <Events.h> // for WaitNextEvent
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#include <direct.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "messages.h"
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#define DIRECTORY_SEPARATOR '/'
|
||||
#elif defined WIN32
|
||||
#define DIRECTORY_SEPARATOR '\\'
|
||||
#elif defined XP_MAC
|
||||
#define DIRECTORY_SEPARATOR ':'
|
||||
#endif
|
||||
|
||||
/* Local defines */
|
||||
#define CARTMAN_PORT 11111
|
||||
#define MAX_PATH_LEN 256
|
||||
|
||||
/* write to the cmnav.log */
|
||||
#if 0
|
||||
#define LOG(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, x); fclose(f); } } while(0);
|
||||
#define LOG_S(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, "%s", x); fclose(f); } } while(0);
|
||||
#define ASSERT(x); if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("\n"); exit(-1); }
|
||||
#else
|
||||
#define LOG(x); ;
|
||||
#define LOG_S(x); ;
|
||||
#define ASSERT(x); ;
|
||||
#endif
|
||||
|
||||
static char*
|
||||
getCurrWorkDir(char *buf, int maxLen)
|
||||
{
|
||||
#if defined WIN32
|
||||
return _getcwd(buf, maxLen);
|
||||
#elif defined XP_UNIX
|
||||
return getcwd(buf, maxLen);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
setWorkingDir(char *path)
|
||||
{
|
||||
#if defined WIN32
|
||||
_chdir(path);
|
||||
#elif defined XP_UNIX
|
||||
chdir(path);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
launch_psm(char *executable)
|
||||
{
|
||||
char command[MAX_PATH_LEN];
|
||||
#ifdef WIN32
|
||||
STARTUPINFO sui;
|
||||
PROCESS_INFORMATION pi;
|
||||
UNALIGNED long *posfhnd;
|
||||
int i;
|
||||
char *posfile;
|
||||
|
||||
sprintf(command,"%s > psmlog", executable);
|
||||
ZeroMemory( &sui, sizeof(sui) );
|
||||
sui.cb = sizeof(sui);
|
||||
sui.cbReserved2 = (WORD)(sizeof( int ) + (3 * (sizeof( char ) +
|
||||
sizeof( long ))));
|
||||
sui.lpReserved2 = calloc( sui.cbReserved2, 1 );
|
||||
*((UNALIGNED int *)(sui.lpReserved2)) = 3;
|
||||
posfile = (char *)(sui.lpReserved2 + sizeof( int ));
|
||||
posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) +
|
||||
(3 * sizeof( char )));
|
||||
|
||||
for ( i = 0, posfile = (char *)(sui.lpReserved2 + sizeof( int )),
|
||||
posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) + (3 * sizeof( char ))) ;
|
||||
i < 3 ; i++, posfile++, posfhnd++ ) {
|
||||
|
||||
*posfile = 0;
|
||||
*posfhnd = (long)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Now, fire up PSM */
|
||||
if (!CreateProcess(NULL, command, NULL, NULL, TRUE, DETACHED_PROCESS,
|
||||
NULL, NULL, &sui, &pi)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
#elif defined XP_UNIX
|
||||
sprintf(command,"./%s &", executable);
|
||||
if (system(command) == -1) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
#else
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
PCMT_CONTROL CMT_EstablishControlConnection(char *inPath,
|
||||
CMT_SocketFuncs *sockFuncs,
|
||||
CMT_MUTEX *mutex)
|
||||
{
|
||||
PCMT_CONTROL control;
|
||||
char *executable;
|
||||
char *newWorkingDir;
|
||||
char oldWorkingDir[MAX_PATH_LEN];
|
||||
int i;
|
||||
char *path = NULL;
|
||||
size_t stringLen;
|
||||
|
||||
/* On the Mac, we do special magic in the Seamonkey PSM component, so
|
||||
if PSM isn't launched by the time we reach this point, we're not doing well. */
|
||||
#ifndef XP_MAC
|
||||
|
||||
struct stat stbuf;
|
||||
|
||||
/*
|
||||
* Create our own copy of path.
|
||||
* I'd like to do a straight strdup here, but that caused problems
|
||||
* for https.
|
||||
*/
|
||||
stringLen = strlen(inPath);
|
||||
|
||||
path = (char*) malloc(stringLen+1);
|
||||
memcpy(path, inPath, stringLen);
|
||||
path[stringLen] = '\0';
|
||||
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
return control;
|
||||
}
|
||||
/*
|
||||
* We have to try to launch it now, so it better be a valid
|
||||
* path.
|
||||
*/
|
||||
if (stat(path, &stbuf) == -1) {
|
||||
goto loser;
|
||||
}
|
||||
/*
|
||||
* Now we have to parse the path and launch the psm server.
|
||||
*/
|
||||
executable = strrchr(path, DIRECTORY_SEPARATOR);
|
||||
if (executable != NULL) {
|
||||
*executable = '\0';
|
||||
executable ++;
|
||||
newWorkingDir = path;
|
||||
} else {
|
||||
executable = path;
|
||||
newWorkingDir = NULL;
|
||||
}
|
||||
if (getCurrWorkDir(oldWorkingDir, MAX_PATH_LEN) == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
setWorkingDir(newWorkingDir);
|
||||
if (launch_psm(executable) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
setWorkingDir(oldWorkingDir);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now try to connect to the psm server. We will try to connect
|
||||
* a maximum of 30 times and then give up.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
for (i=0; i<30; i++) {
|
||||
Sleep(1000);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined XP_UNIX
|
||||
i = 0;
|
||||
while (i<1000) {
|
||||
i += sleep(10);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined(XP_MAC)
|
||||
for (i=0; i<30; i++)
|
||||
{
|
||||
EventRecord theEvent;
|
||||
WaitNextEvent(0, &theEvent, 30, NULL);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* Figure out how to sleep for a while first
|
||||
*/
|
||||
for (i=0; i<30; i++) {
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control!= NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (control == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (path) {
|
||||
free (path);
|
||||
}
|
||||
return control;
|
||||
loser:
|
||||
if (control != NULL) {
|
||||
CMT_CloseControlConnection(control);
|
||||
}
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PCMT_CONTROL CMT_ControlConnect(CMT_MUTEX *mutex, CMT_SocketFuncs *sockFuncs)
|
||||
{
|
||||
PCMT_CONTROL control = NULL;
|
||||
CMTSocket sock=NULL;
|
||||
#ifdef XP_UNIX
|
||||
int unixSock = 1;
|
||||
char path[20];
|
||||
#else
|
||||
int unixSock = 0;
|
||||
char *path=NULL;
|
||||
#endif
|
||||
|
||||
if (sockFuncs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef XP_UNIX
|
||||
sprintf(path, "/tmp/.nsmc-%d", (int)geteuid());
|
||||
#endif
|
||||
|
||||
sock = sockFuncs->socket(unixSock);
|
||||
if (sock == NULL) {
|
||||
LOG("Could not create a socket to connect to Control Connection.\n");
|
||||
goto loser;
|
||||
}
|
||||
/* Connect to the psm process */
|
||||
if (sockFuncs->connect(sock, CARTMAN_PORT, path)) {
|
||||
LOG("Could not connect to Cartman\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
if (sockFuncs->verify(sock) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG("Connected to Cartman\n");
|
||||
|
||||
/* fill in the CMTControl struct */
|
||||
control = (PCMT_CONTROL)calloc(sizeof(CMT_CONTROL), 1);
|
||||
if (control == NULL ) {
|
||||
goto loser;
|
||||
}
|
||||
control->sock = sock;
|
||||
if (mutex != NULL) {
|
||||
control->mutex = (CMT_MUTEX*)calloc(sizeof(CMT_MUTEX),1);
|
||||
if (control->mutex == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
*control->mutex = *mutex;
|
||||
}
|
||||
memcpy(&control->sockFuncs, sockFuncs, sizeof(CMT_SocketFuncs));
|
||||
control->refCount = 1;
|
||||
goto done;
|
||||
|
||||
loser:
|
||||
if (control != NULL) {
|
||||
free(control);
|
||||
}
|
||||
if (sock != NULL) {
|
||||
sockFuncs->close(sock);
|
||||
}
|
||||
control = NULL;
|
||||
|
||||
done:
|
||||
return control;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CloseControlConnection(PCMT_CONTROL control)
|
||||
{
|
||||
/* XXX Don't know what to do here yet */
|
||||
if (control != NULL) {
|
||||
CMInt32 refCount;
|
||||
CMT_LOCK(control->mutex);
|
||||
control->refCount--;
|
||||
refCount = control->refCount;
|
||||
CMT_UNLOCK(control->mutex);
|
||||
if (refCount <= 0) {
|
||||
if (control->mutex != NULL) {
|
||||
free (control->mutex);
|
||||
}
|
||||
control->sockFuncs.close(control->sock);
|
||||
free(control);
|
||||
}
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_Hello(PCMT_CONTROL control, CMUint32 version, char* profile,
|
||||
char* profileDir)
|
||||
{
|
||||
CMTItem message;
|
||||
PCMT_EVENT eventHandler;
|
||||
CMBool doesUI;
|
||||
HelloRequest request;
|
||||
HelloReply reply;
|
||||
|
||||
/* Check the passed parameters */
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
if (!profile) {
|
||||
return CMTFailure;
|
||||
}
|
||||
if (!profileDir) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
/* Create the hello message */
|
||||
eventHandler = CMT_GetEventHandler(control, SSM_UI_EVENT, 0);
|
||||
doesUI = (eventHandler == NULL) ? CM_FALSE : CM_TRUE;
|
||||
|
||||
/* Setup the request struct */
|
||||
request.version = version;
|
||||
request.policy = 0; /* no more policy */
|
||||
request.doesUI = doesUI;
|
||||
request.profile = profile;
|
||||
request.profileDir = profileDir;
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE;
|
||||
|
||||
if (CMT_EncodeMessage(HelloRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_HELLO_MESSAGE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(HelloReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Successful response */
|
||||
if (reply.result == 0) {
|
||||
/* Save the nonce value */
|
||||
control->sessionID = reply.sessionID;
|
||||
control->protocolVersion = reply.version;
|
||||
control->port = reply.httpPort;
|
||||
control->nonce = reply.nonce;
|
||||
control->policy = reply.policy;
|
||||
control->serverStringVersion = reply.stringVersion;
|
||||
|
||||
/* XXX Free the messages */
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
/* XXX Free the messages */
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PassAllPrefs(PCMT_CONTROL control, int num,
|
||||
CMTSetPrefElement* list)
|
||||
{
|
||||
SetPrefListMessage request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
|
||||
if ((control == NULL) || (list == NULL)) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
/* pack the request */
|
||||
request.length = num;
|
||||
request.list = (SetPrefElement*)list;
|
||||
|
||||
if (CMT_EncodeMessage(SetPrefListMessageTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PREF_ACTION;
|
||||
|
||||
/* send the message */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PREF_ACTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* don't really need to check the return value */
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
char* CMT_GetServerStringVersion(PCMT_CONTROL control)
|
||||
{
|
||||
if (control == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return control->serverStringVersion;
|
||||
}
|
||||
556
mozilla/security/psm/lib/client/cmtjs.c
Normal file
556
mozilla/security/psm/lib/client/cmtjs.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtutils.h"
|
||||
#include "cmtjs.h"
|
||||
#include "messages.h"
|
||||
|
||||
CMTStatus
|
||||
CMT_GenerateKeyPair(PCMT_CONTROL control, CMUint32 keyGenContext,
|
||||
CMUint32 mechType, CMTItem *param, CMUint32 keySize,
|
||||
CMUint32 *keyPairId)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
KeyPairGenRequest request = {0, 0, 0, {0, NULL, 0}};
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.keyGenCtxtID = keyGenContext;
|
||||
request.genMechanism = mechType;
|
||||
if (param) {
|
||||
request.params = *param;
|
||||
}
|
||||
request.keySize = keySize;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(KeyPairGenRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_CREATE_KEY_PAIR;
|
||||
|
||||
/* Send the message and get the response */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_CREATE_KEY_PAIR)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*keyPairId = reply.value;
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
*keyPairId = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus
|
||||
CMT_CreateNewCRMFRequest(PCMT_CONTROL control, CMUint32 keyPairID,
|
||||
SSMKeyGenType keyGenType, CMUint32 *reqID)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.value = keyPairID;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION |
|
||||
SSM_CREATE_CRMF_REQ;
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_CREATE_CRMF_REQ)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*reqID = reply.value;
|
||||
|
||||
rv = CMT_SetNumericAttribute(control, *reqID, SSM_FID_CRMFREQ_KEY_TYPE,
|
||||
keyGenType);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_EncodeCRMFRequest(PCMT_CONTROL control, CMUint32 *crmfReqID,
|
||||
CMUint32 numRequests, char ** der)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
EncodeCRMFReqRequest request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.numRequests = numRequests;
|
||||
request.reqIDs = (long *) crmfReqID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(EncodeCRMFReqRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_DER_ENCODE_REQ;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_DER_ENCODE_REQ)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* XXX Should this be a string? Decode the message */
|
||||
if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*der = (char *) reply.item.data;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_ProcessCMMFResponse(PCMT_CONTROL control, char *nickname,
|
||||
char *certRepString, CMBool doBackup,
|
||||
void *clientContext)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMMFCertResponseRequest request;
|
||||
|
||||
if(!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.nickname = nickname;
|
||||
request.base64Der = certRepString;
|
||||
request.doBackup = doBackup;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CMMFCertResponseRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_PROCESS_CMMF_RESP;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_PROCESS_CMMF_RESP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_CreateResource(PCMT_CONTROL control, SSMResourceType resType,
|
||||
CMTItem *params, CMUint32 *rsrcId, CMUint32 *errorCode)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CreateResourceRequest request = {0, {0, NULL, 0}};
|
||||
CreateResourceReply reply;
|
||||
|
||||
request.type = resType;
|
||||
if (params) {
|
||||
request.params = *params;
|
||||
}
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CREATE_RESOURCE;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CREATE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(CreateResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*rsrcId = reply.resID;
|
||||
*errorCode = reply.result;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_SignText(PCMT_CONTROL control, CMUint32 resID, char* stringToSign, char* hostName, char* caOption, CMInt32 numCAs, char** caNames)
|
||||
{
|
||||
CMTItem message;
|
||||
SignTextRequest request;
|
||||
|
||||
|
||||
/* So some basic parameter checking */
|
||||
if (!control || !stringToSign) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resID;
|
||||
request.stringToSign = stringToSign;
|
||||
request.hostName = hostName;
|
||||
request.caOption = caOption;
|
||||
request.numCAs = numCAs;
|
||||
request.caNames = caNames;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(SignTextRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_FORMSIGN_ACTION | SSM_SIGN_TEXT;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_FORMSIGN_ACTION | SSM_SIGN_TEXT)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_ProcessChallengeResponse(PCMT_CONTROL control, char *challengeString,
|
||||
char **responseString)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleStringMessage request;
|
||||
SingleStringMessage reply;
|
||||
|
||||
/* Set the request */
|
||||
request.string = challengeString;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_CHALLENGE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_CHALLENGE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleStringMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*responseString = reply.string;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_FinishGeneratingKeys(PCMT_CONTROL control, CMUint32 keyGenContext)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
|
||||
/* Set up the request */
|
||||
request.value = keyGenContext;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_FINISH_KEY_GEN;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the reply */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_FINISH_KEY_GEN)) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_GetLocalizedString(PCMT_CONTROL control,
|
||||
SSMLocalizedString whichString,
|
||||
char **localizedString)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
GetLocalizedTextReply reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.value = whichString;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_LOCALIZED_TEXT;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_LOCALIZED_TEXT)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetLocalizedTextReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (reply.whichString != whichString) {
|
||||
goto loser;
|
||||
}
|
||||
*localizedString = reply.localizedString;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
*localizedString = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_AddNewModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
char *libraryPath,
|
||||
unsigned long pubMechFlags,
|
||||
unsigned long pubCipherFlags)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
AddNewSecurityModuleRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.moduleName = moduleName;
|
||||
request.libraryPath = libraryPath;
|
||||
request.pubMechFlags = pubMechFlags;
|
||||
request.pubCipherFlags = pubCipherFlags;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(AddNewSecurityModuleRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_ADD_NEW_MODULE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_ADD_NEW_MODULE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the response */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_DeleteModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
int *moduleType)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleStringMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.string = moduleName;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_DEL_MODULE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_DEL_MODULE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*moduleType = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_LogoutAllTokens(PCMT_CONTROL control)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_LOGOUT_ALL;
|
||||
message.data = NULL;
|
||||
message.len = 0;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
return rv;
|
||||
}
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_LOGOUT_ALL)) {
|
||||
return CMTFailure;
|
||||
}
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLCapabilities(PCMT_CONTROL control, CMInt32 *capabilites)
|
||||
{
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
|
||||
message.type = (SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_ENABLED_CIPHERS);
|
||||
message.data = NULL;
|
||||
message.len = 0;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_ENABLED_CIPHERS)) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply,
|
||||
&message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*capabilites = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
555
mozilla/security/psm/lib/client/cmtjs.h
Normal file
555
mozilla/security/psm/lib/client/cmtjs.h
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _CMTJS_H_
|
||||
#define _CMTJS_H_
|
||||
#include "cmtcmn.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "rsrcids.h"
|
||||
/*
|
||||
* Define some constants.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These defines are used in conjuction with the function
|
||||
* CMT_AddNewModule.
|
||||
*/
|
||||
#define PUBLIC_MECH_RSA_FLAG 0x00000001ul
|
||||
#define PUBLIC_MECH_DSA_FLAG 0x00000002ul
|
||||
#define PUBLIC_MECH_RC2_FLAG 0x00000004ul
|
||||
#define PUBLIC_MECH_RC4_FLAG 0x00000008ul
|
||||
#define PUBLIC_MECH_DES_FLAG 0x00000010ul
|
||||
#define PUBLIC_MECH_DH_FLAG 0x00000020ul
|
||||
#define PUBLIC_MECH_FORTEZZA_FLAG 0x00000040ul
|
||||
#define PUBLIC_MECH_RC5_FLAG 0x00000080ul
|
||||
#define PUBLIC_MECH_SHA1_FLAG 0x00000100ul
|
||||
#define PUBLIC_MECH_MD5_FLAG 0x00000200ul
|
||||
#define PUBLIC_MECH_MD2_FLAG 0x00000400ul
|
||||
|
||||
#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul
|
||||
#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul
|
||||
#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul
|
||||
#define PUBLIC_DISABLE_FLAG 0x40000000ul
|
||||
|
||||
|
||||
/*
|
||||
* This is the lone supported constant for the Cipher flag
|
||||
* for CMT_AddNewModule
|
||||
*/
|
||||
#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul
|
||||
|
||||
CMT_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_GenerateKeyPair
|
||||
* -----------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyGenContext
|
||||
* The Resource ID of a key gen context to use for creating the
|
||||
* key pair.
|
||||
* mechType
|
||||
* A PKCS11 mechanism used to generate the key pair. Valid values are:
|
||||
* CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
|
||||
* CKM_DSA_KEY_PAIR_GEN 0x00000010
|
||||
* The definition of these values can be found at
|
||||
* http://www.rsa.com/rsalabs/pubs/pkcs11.html
|
||||
* The psm module currently supports v2.01 of PKCS11
|
||||
* params
|
||||
* This parameter will be used to pass parameters to the Key Pair
|
||||
* generation process. Currently this feature is not supported, so
|
||||
* pass in NULL for this parameter.
|
||||
* keySize
|
||||
* The size (in bits) of the key to generate.
|
||||
* keyPairId
|
||||
* A pointer to pre-allocated memory where the function can place
|
||||
* the value of the resource ID of the key pair that gets created.
|
||||
*
|
||||
* NOTES:
|
||||
* This function will send a message to the psm server requesting that
|
||||
* a public/private key pair be generated. The key gen context will queue
|
||||
* the request. You can send as many key gen requests as you want with a
|
||||
* given key gen context. After sending all the key gen requests, the user
|
||||
* must call CMT_FinishGeneratingKeys so that the key gen context actually
|
||||
* generates the keys.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the request for key generation
|
||||
* was queued successfully and the corresponding resource ID can be found
|
||||
* at *keyPairId. Any other return value indicates an error and the value
|
||||
* at *keyPairId should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_GenerateKeyPair(PCMT_CONTROL control, CMUint32 keyGenContext,
|
||||
CMUint32 mechType, CMTItem *params, CMUint32 keySize,
|
||||
CMUint32 *keyPairId);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_FinishGeneratingKeys
|
||||
* ----------------------------------
|
||||
* INPUTS
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyGenContext
|
||||
* The resource ID of the key gen context which should finish
|
||||
* generating its key pairs.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server notifying the key
|
||||
* gen context with the resource ID of keyGenContext to finish generating
|
||||
* all of the key gen requests it has queued up. After each key gen has
|
||||
* finished, the psm server will send a SSM_TASK_COMPLETED_EVENT. So in order
|
||||
* to detect when all of the key gens are done, the user should register
|
||||
* an event handler. See comments for CMT_RegisterEventHandler for information
|
||||
* on how to successfully register event handler callbacks. You must register
|
||||
* the event handler with keyGenContext as the target resource ID for this
|
||||
* to work correctly.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the key gen context has started to
|
||||
* generate the key pairs in its queue. Any other return value indicates an
|
||||
* error and the key pairs will not be generated.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_FinishGeneratingKeys(PCMT_CONTROL control, CMUint32 keyGenContext);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_CreateNewCRMFRequest
|
||||
* ----------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyPairID
|
||||
* The resource ID of the key pair that should be associated with
|
||||
* the CRMF request created. At the time this function is called,
|
||||
* key pair should have already been created.
|
||||
* keyGenType
|
||||
* An enumeration that explains how the key pair will be used.
|
||||
* Look at the definition of SSMKeyGenType in ssmdefs.h for valid
|
||||
* values and their affects on the request.
|
||||
* reqID
|
||||
* A pointer to a pre-allocatd chunk of memory where the library
|
||||
* can place the resource ID of the new CRMF request.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server requesting that a new
|
||||
* CRMF resource object be created. Each CRMF request must be associated with
|
||||
* a public/private key pair, that is why the keyPairID parameter exists.
|
||||
* The keyGenType parameter is used to initialize the request, eg set the
|
||||
* correct keyUsage extension.
|
||||
*
|
||||
* Before encoding a CRMF request, the user will want to set the appropriate
|
||||
* attributes to build up the request. The supported attributes are:
|
||||
*
|
||||
* Attribute Enumeration Attribute Type What value means
|
||||
* --------------------- -------------- ----------------
|
||||
* SSM_FID_CRMFREQ_REGTOKEN String The value to encode as
|
||||
* the registration token
|
||||
* value for the request.
|
||||
*
|
||||
* SSM_FID_CRMFREQ_AUTHENTICATOR String The value to encode as
|
||||
* authenticator control
|
||||
* in the request.
|
||||
*
|
||||
* SSM_FID_DN String The RFC1485 formatted
|
||||
* DN to include in the
|
||||
* CRMF request.
|
||||
*
|
||||
* For information on how to properly set the attribute of a resource, refer
|
||||
* to the comments for the functions CMT_SetNumericAttribute and
|
||||
* CMT_SetStringAttribute.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates a new CRMF resource was created by
|
||||
* the psm server and has the resource ID placed at *reqID. Any other return
|
||||
* value indicates an error and the value at *reqID should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_CreateNewCRMFRequest(PCMT_CONTROL control, CMUint32 keyPairID,
|
||||
SSMKeyGenType keyGenType, CMUint32 *reqID);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_EncodeCRMFRequest
|
||||
* ------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* crmfReqID
|
||||
* An array of resource ID's for CRMF objects to be encoded.
|
||||
* numRequests
|
||||
* The length of the array crmfReqID that is passed in.
|
||||
* der
|
||||
* A pointer to a pre-allocated pointer for a char* where the library
|
||||
* can place the final DER-encoding of the requests.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server requesting that
|
||||
* a number of CRMF requests be encoded into their appropriate DER
|
||||
* representation. The DER that is sent back will be of the type
|
||||
* CertReqMessages as define in the internet draft for CRMF. To look at the
|
||||
* draft, visit the following URL:
|
||||
* http://search.ietf.org/internet-drafts/internet-draft-ietf-pkix-crmf-01.txt
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates psm successfully encoded the requests
|
||||
* and placed the base64 DER encoded request at *der. Any other return value
|
||||
* indicates an error and the value at *der should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_EncodeCRMFRequest(PCMT_CONTROL control, CMUint32 *crmfReqID,
|
||||
CMUint32 numRequests, char ** der);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_ProcessCMMFResponse
|
||||
* ---------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* nickname
|
||||
* The nickname that should be associated with the certificate
|
||||
* contained in the CMMF Response.
|
||||
* certRepString
|
||||
* This is the base 64 encoded CertRepContent that issues a certificate.
|
||||
* The psm server will decode the base 64 data and then parse the
|
||||
* CertRepContent.
|
||||
* doBackup
|
||||
* A boolean value indicating whether or not psm should initiate the
|
||||
* process of backing up the newly issued certificate into a PKCS-12
|
||||
* file.
|
||||
* clientContext
|
||||
* Client supplied data pointer that is returned to the client during
|
||||
* a UI event.
|
||||
* NOTES:
|
||||
* This function takes a CertRepContent as defined in the CMMF internet draft
|
||||
* (http://search.ietf.org/internet-drafts/draft-ietf-pkix-cmmf-02.txt) and
|
||||
* imports the certificate into the user's database. The certificate will have
|
||||
* the string value of nickanme as it's nickname when added to the database
|
||||
* unless another certificate with that same Distinguished Name (DN) already
|
||||
* exists in the database, in which case the nickname of the certificate that
|
||||
* already exists will be used. If the value passed in for doBackup is
|
||||
* non-zero, then the psm server will initiate the process of backing up the
|
||||
* certificate(s) that were just imported.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the certificate(s) were successfully
|
||||
* added to the database. Any other return value means the certificate(s) could
|
||||
* not be successfully added to the database.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_ProcessCMMFResponse(PCMT_CONTROL control, char *nickname,
|
||||
char *certRepString, CMBool doBackup,
|
||||
void *clientContext);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_CreateResource
|
||||
* ----------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* resType
|
||||
* The enumeration representing the resource type to create.
|
||||
* params
|
||||
* A resource dependent binary string that will be sent to the psm
|
||||
* server. Each resource will expect a binary string it defines.
|
||||
* rsrcId
|
||||
* A pointer to a pre-allocated chunk of memory where the library
|
||||
* can place the resource ID of the newly created resource.
|
||||
* errorCode
|
||||
* A pointer to a pre-allocated chunk of memory where the library
|
||||
* can place the errorCode returned by the psm server after creating
|
||||
* the resource.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server requesting that a new
|
||||
* resource be created. The params parameter depends on the type of resource
|
||||
* being created. Below is a table detailing the format of the params for
|
||||
* a given resource type. Only the resource types listed below can be created
|
||||
* by calling this function.
|
||||
*
|
||||
* Resource Type constant Value for params
|
||||
* ------------------------------ ----------------
|
||||
* SSM_RESTYPE_KEYGEN_CONTEXT NULL
|
||||
* SSM_RESTYPE_SECADVISOR_CONTEXT NULL
|
||||
* SSM_RESTYPE_SIGNTEXT NULL
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess means the psm server received the request and
|
||||
* processed the create resource create. If the value at *errorCode is zero,
|
||||
* then the value at *rsrcId is the resource ID of the newly created resource.
|
||||
* Otherwise, creating the new resource failed and *errorCode contains the
|
||||
* error code returned by the psm server. ???What are the return values and
|
||||
* what do they mean. Any other return value indicates there was an error
|
||||
* in the communication with the psm server and the values at *rsrcId and
|
||||
* *errorCode should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_CreateResource(PCMT_CONTROL control, SSMResourceType resType,
|
||||
CMTItem *params, CMUint32 *rsrcId, CMUint32 *errorCode);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_SignText
|
||||
* ----------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* resID
|
||||
* The resource ID of an SSMSignTextResource.
|
||||
* stringToSign
|
||||
* The string that the psm server should sign.
|
||||
* hostName
|
||||
* The host name of the site that is requesting a string to be
|
||||
* signed. This is used for displaying the UI that tells the user
|
||||
* a web site has requested the use sign some text.
|
||||
* caOption
|
||||
* If the value is "auto" then psm will select the certificate
|
||||
* to use for signing automatically.
|
||||
* If the value is "ask" then psm will display a list of
|
||||
* certificates for signing.
|
||||
* numCAs
|
||||
* The number of CA names included in the array caNames passed in as
|
||||
* the last parameter to this function.
|
||||
* caNames
|
||||
* An array of CA Names to use for filtering the user certs to use
|
||||
* for signing the text.
|
||||
* NOTES
|
||||
* This function will sign the text passed via the parameter stringToSign.
|
||||
* The function will also cause the psm server to send some UI notifying the
|
||||
* user that a site has requested the user sign some text. The hostName
|
||||
* parameter is used in the UI to inform the user which site is requesting
|
||||
* the signed text. The caOption is used to determine if the psm server
|
||||
* should automatically select which personal cert to use in signing the
|
||||
* text. The caNames array is ussed to narrow down the field of personal
|
||||
* certs to use when signing the text. In other words, only personal certs
|
||||
* trusted by the CA's passed in will be used.
|
||||
*
|
||||
* RETURN
|
||||
* If the function returns CMTSuccess, that indicates the psm server
|
||||
* successfully signed the text. The signed text can be retrieved by
|
||||
* calling CMT_GetStringResource and passing in SSM_FID_SIGNTEXT_RESULT
|
||||
* as the field ID. Any other return value indicates an error meaning the
|
||||
* string was not signed successfully.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_SignText(PCMT_CONTROL control, CMUint32 resID, char* stringToSign,
|
||||
char* hostName, char *caOption, CMInt32 numCAs, char** caNames);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_ProcessChallengeResponse
|
||||
* --------------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* challengeString
|
||||
* The base64 encoded Challenge string received as the
|
||||
* Proof-Of-Possession Challenge in response to CRMF request that
|
||||
* specified Challenge-Reponse as the method for Proof-Of-Possession.
|
||||
* responseString
|
||||
* A pointer to pre-allocated char* where the library can place a
|
||||
* copy of the bas64 encoded response to the challenge presented.
|
||||
* NOTES
|
||||
* This function takes the a challenge--that is encrypted with the public key
|
||||
* of a certificate we created--and decrypts it with the private key we
|
||||
* generated. The format of the challenge is as follows:
|
||||
*
|
||||
* Challenge ::= SEQUENCE {
|
||||
* owf AlgorithmIdentifier OPTIONAL,
|
||||
* -- MUST be present in the first Challenge; MAY be omitted in any
|
||||
* -- subsequent Challenge in POPODecKeyChallContent (if omitted,
|
||||
* -- then the owf used in the immediately preceding Challenge is
|
||||
* -- to be used).
|
||||
* witness OCTET STRING,
|
||||
* -- the result of applying the one-way function (owf) to a
|
||||
* -- randomly-generated INTEGER, A. [Note that a different
|
||||
* -- INTEGER MUST be used for each Challenge.]
|
||||
* sender GeneralName,
|
||||
* -- the name of the sender.
|
||||
* key OCTET STRING,
|
||||
* -- the public key used to encrypt the challenge. This will allow
|
||||
* -- the client to find the appropriate key to do the decryption.
|
||||
* challenge OCTET STRING
|
||||
* -- the encryption (under the public key for which the cert.
|
||||
* -- request is being made) of Rand, where Rand is specified as
|
||||
* -- Rand ::= SEQUENCE {
|
||||
* -- int INTEGER,
|
||||
* -- - the randomly-generated INTEGER A (above)
|
||||
* -- senderHash OCTET STRING
|
||||
* -- - the result of applying the one-way function (owf) to
|
||||
* -- - the sender's general name
|
||||
* -- }
|
||||
* -- the size of "int" must be small enough such that "Rand" can be
|
||||
* -- contained within a single PKCS #1 encryption block.
|
||||
* }
|
||||
* This challenge is based on the Challenge initially defined in the CMMF
|
||||
* internet draft, but differs in that this structure includes the sender
|
||||
* as part of the challenge along with the public key and includes a has
|
||||
* of the sender in the encrypted Rand structure. The reason for including
|
||||
* the key is to facilitate looking up the key that should be used to
|
||||
* decipher the challenge. Including the hash of the sender in the encrypted
|
||||
* Rand structure makes the challenge smaller and allows it to fit in
|
||||
* one RSA block.
|
||||
*
|
||||
* The response is of the type POPODecKeyRespContent as defined in the CMMF
|
||||
* internet draft.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates psm successfully parsed and processed
|
||||
* the challenge and created a response. The base64 encoded response to the
|
||||
* challenge is placed at *responseString. Any other return value indicates
|
||||
* an error and the value at *responseString should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_ProcessChallengeResponse(PCMT_CONTROL control, char *challengeString,
|
||||
char **responseString);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_GetLocalizedString
|
||||
* --------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* whichString
|
||||
* The enumerated value corresponding to the localized string to
|
||||
* retrieve from the psm server
|
||||
* localizedString
|
||||
* A pointer to a pre-allocated char* where the library can place
|
||||
* copy of the localized string retrieved from the psm server.
|
||||
* NOTES
|
||||
* This function retrieves a localized string from the psm server. These
|
||||
* strings are useful for strings that aren't localized in the client
|
||||
* making use of the psm server, but need to be displayed by the user. Look
|
||||
* in protocol.h for the enumerations of the localized strings that can
|
||||
* be fetched from psm via this method.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the localized string was retrieved
|
||||
* successfully and the localized value is located at *localizedString. Any
|
||||
* other return value indicates an error and the value at *localizedString
|
||||
* should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_GetLocalizedString(PCMT_CONTROL control,
|
||||
SSMLocalizedString whichString,
|
||||
char **localizedString);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_DeleteModule
|
||||
* --------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* moduleName
|
||||
* The name of the PKCS11 module to delete.
|
||||
* moduleType
|
||||
* A pointer to a pre-allocated integer where the library can place
|
||||
* a value that tells what the type of module was deleted.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server requesting the server
|
||||
* delete a PKCS-11 module stored in psm's security module database. moduleName
|
||||
* is the value passed in as moduleName when the module was added to the
|
||||
* security module database of psm.
|
||||
* The values that may be returned by psm for moduleType are:
|
||||
*
|
||||
* 0 The module was an external module developped by a third party
|
||||
* that was added to the psm security module.
|
||||
*
|
||||
* 1 The module deleted was the internal PKCS-11 module that comes
|
||||
* built in with the psm server.
|
||||
*
|
||||
* 2 The module that was deleted was the FIPS internal module.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the security module was successfully
|
||||
* delete from the psm security module database and the value at *moduleType
|
||||
* will tell what type of module was deleted.
|
||||
* Any other return value indicates an error and the value at *moduleType
|
||||
* should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_DeleteModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
int *moduleType);
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_AddNewModule
|
||||
* --------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* moduleName
|
||||
* The name to be associated with the module once it is added to
|
||||
* the psm security module database.
|
||||
* libraryPath
|
||||
* The path to the library to be loaded. The library should be
|
||||
* loadable at run-time.
|
||||
* pubMechFlags
|
||||
* A bit vector indicating all cryptographic mechanisms that should
|
||||
* be turned on by default. This module will become the default
|
||||
* handler for the mechanisms that are set by this bit vector.
|
||||
* pubCipherFlags
|
||||
* A bit vector indicating all SSL or S/MIME cipher functions
|
||||
* supported by the module. Most modules will pas in 0x0 for this
|
||||
* parameter.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server and requests the .so
|
||||
* file on UNIX or .dll file on Windows be loaded as a PKCS11 module and
|
||||
* be stored in the psm security module database. The module will be stored
|
||||
* with the name moduleName that is passed in and will always expect the
|
||||
* library to live at the path passed in via the parameter libraryPath.
|
||||
* The pubMechFlags tell the psm server how this module should be used.
|
||||
* Valid values are the #define constants defined at the beginning of
|
||||
* this file.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the module was successfully loaded
|
||||
* and placed in the security module database of psm. Any other return value
|
||||
* indicates an error and means the module was not loaded successfully and
|
||||
* not stored in the psm server's security module database.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_AddNewModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
char *libraryPath,
|
||||
unsigned long pubMechFlags,
|
||||
unsigned long pubCipherFlags);
|
||||
|
||||
CMT_END_EXTERN_C
|
||||
|
||||
#endif /*_CMTJS_H_*/
|
||||
75
mozilla/security/psm/lib/client/cmtmac.c
Normal file
75
mozilla/security/psm/lib/client/cmtmac.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "cmtmac.h"
|
||||
#include "macsocket.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#ifndef XP_MAC
|
||||
#error Link with the builtin strdup() on your platform.
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
my_strcpy(char *dest, const char *source)
|
||||
{
|
||||
char *i = dest;
|
||||
const char *j = source;
|
||||
while(*j)
|
||||
*i++ = *j++;
|
||||
*i = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
my_strlen(const char *str)
|
||||
{
|
||||
const char *c = str;
|
||||
int i = 0;
|
||||
|
||||
while(*c++ != '\0')
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
char * strdup(const char *oldstr)
|
||||
{
|
||||
/* used to keep the mac client library from referring to strdup elsewhere */
|
||||
char *newstr;
|
||||
|
||||
newstr = (char *) malloc(my_strlen(oldstr)+1);
|
||||
if (newstr)
|
||||
my_strcpy(newstr, oldstr);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
40
mozilla/security/psm/lib/client/cmtmac.h
Normal file
40
mozilla/security/psm/lib/client/cmtmac.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __CMTMAC_H__
|
||||
#define __CMTMAC_H__
|
||||
|
||||
char * strdup(const char *str);
|
||||
|
||||
#endif
|
||||
119
mozilla/security/psm/lib/client/cmtpasswd.c
Normal file
119
mozilla/security/psm/lib/client/cmtpasswd.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/************************************************************************
|
||||
* Code to handle password requests from the the PSM module.
|
||||
*
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
|
||||
void CMT_SetAppFreeCallback(PCMT_CONTROL control,
|
||||
applicationFreeCallback_fn f)
|
||||
{
|
||||
control->userFuncs.userFree = f;
|
||||
}
|
||||
|
||||
void CMT_ServicePasswordRequest(PCMT_CONTROL cm_control, CMTItem * requestData)
|
||||
{
|
||||
CMTItem response = {0, NULL, 0};
|
||||
PasswordRequest request;
|
||||
PasswordReply reply;
|
||||
void * clientContext;
|
||||
|
||||
/********************************************
|
||||
* What we trying to do here:
|
||||
* 1) Throw up a dialog box and request a password.
|
||||
* 2) Create a message and send it to the PSM module.
|
||||
********************************************
|
||||
*/
|
||||
|
||||
/* Decode the request */
|
||||
if (CMT_DecodeMessage(PasswordRequestTemplate, &request, requestData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(request.clientContext);
|
||||
|
||||
if (cm_control->userFuncs.promptCallback == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
reply.passwd =
|
||||
cm_control->userFuncs.promptCallback(cm_control->userFuncs.promptArg,
|
||||
request.prompt, clientContext, 1);
|
||||
reply.tokenID = request.tokenKey;
|
||||
if (!reply.passwd) {
|
||||
/* the user cancelled the prompt or other errors occurred */
|
||||
reply.result = -1;
|
||||
}
|
||||
else {
|
||||
/* note that this includes an empty string (zero length password) */
|
||||
reply.result = 0;
|
||||
}
|
||||
|
||||
/* Encode the reply */
|
||||
if (CMT_EncodeMessage(PasswordReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message response type */
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_AUTH_EVENT;
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
goto done;
|
||||
loser:
|
||||
/* something has gone wrong */
|
||||
|
||||
done:
|
||||
/*clean up anyway */
|
||||
/* We can't just free up memory allocated by the host
|
||||
application because the versions of free may not match up.
|
||||
When you run the plug-in with an optimized older browser,
|
||||
you'll see tons of Asserts (why they still have asserts in an
|
||||
optimized build is a different question, but without them
|
||||
I wouldn't have figured out this problem) about a pointer not
|
||||
being a valid heap pointer and eventually crash. This was
|
||||
the offending free line.
|
||||
So we need to call a function within the browser that
|
||||
calls the free linked in with it. js_free is
|
||||
such a function. But this is extremely ugly.
|
||||
*/
|
||||
if (reply.passwd)
|
||||
cm_control->userFuncs.userFree(reply.passwd);
|
||||
if (request.prompt)
|
||||
free(request.prompt);
|
||||
return;
|
||||
}
|
||||
|
||||
636
mozilla/security/psm/lib/client/cmtpkcs7.c
Normal file
636
mozilla/security/psm/lib/client/cmtpkcs7.c
Normal file
@@ -0,0 +1,636 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
typedef struct _CMTP7Private {
|
||||
CMTPrivate priv;
|
||||
CMTP7ContentCallback cb;
|
||||
void *cb_arg;
|
||||
} CMTP7Private;
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderStart(PCMT_CONTROL control, void* clientContext, CMUint32 * connectionID, CMInt32 * result,
|
||||
CMTP7ContentCallback cb, void *cb_arg)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMTP7Private *priv=NULL;
|
||||
SingleItemMessage request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.item = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode message */
|
||||
if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM;
|
||||
|
||||
/* Send the message. */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
priv->priv.dest = (CMTReclaimFunc) free;
|
||||
priv->cb = cb;
|
||||
priv->cb_arg = cb_arg;
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if (sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.connect(sock, (short)reply.port,
|
||||
NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.send(sock, control->nonce.data,
|
||||
control->nonce.len) != control->nonce.len){
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*connectionID = reply.connID;
|
||||
|
||||
rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (priv) {
|
||||
free(priv);
|
||||
}
|
||||
|
||||
*result = reply.result;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderUpdate(PCMT_CONTROL control, CMUint32 connectionID, const char * buf, CMUint32 len)
|
||||
{
|
||||
CMUint32 sent;
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char read_buf[128];
|
||||
CMTSocket sock, ctrlsock, selSock, sockArr[2];
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
while ((selSock = control->sockFuncs.select(sockArr,2,1)))
|
||||
{
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else {
|
||||
nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
|
||||
if (nbytes == -1) {
|
||||
goto loser;
|
||||
}
|
||||
if (nbytes == 0) {
|
||||
break;
|
||||
}
|
||||
priv->cb(priv->cb_arg, read_buf, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderFinish(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMUint32 * resourceID)
|
||||
{
|
||||
CMTP7Private *priv;
|
||||
long nbytes;
|
||||
char buf[128];
|
||||
CMTSocket sock, ctrlsock, selSock, sockArr[2];
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
/* drain socket before we close it */
|
||||
control->sockFuncs.shutdown(sock);
|
||||
sockArr[0] = sock;
|
||||
sockArr[1] = ctrlsock;
|
||||
/* Let's see if doing a poll first gets rid of a weird bug where we
|
||||
* lock up the client.
|
||||
*/
|
||||
#ifndef XP_MAC
|
||||
if (control->sockFuncs.select(sockArr,2,1) != NULL)
|
||||
#endif
|
||||
{
|
||||
while (1) {
|
||||
selSock = control->sockFuncs.select(sockArr,2,0);
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else if (selSock == sock) {
|
||||
nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
|
||||
if (nbytes < 0) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
}
|
||||
priv->cb(priv->cb_arg, buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the PKCS7 content info */
|
||||
if (CMT_GetRIDAttribute(control, connectionID, SSM_FID_P7CONN_CONTENT_INFO,
|
||||
resourceID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control) {
|
||||
CMT_CloseDataConnection(control, connectionID);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DestroyContentInfo(PCMT_CONTROL control, CMUint32 resourceID)
|
||||
{
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Delete the resource */
|
||||
if (CMT_DestroyResource(control, resourceID, SSM_FID_P7CONN_CONTENT_INFO) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7VerifyDetachedSignature(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 certUsage, CMUint32 hashAlgID, CMUint32 keepCerts, CMTItem* digest, CMInt32 * result)
|
||||
{
|
||||
CMTItem message;
|
||||
VerifyDetachedSigRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !digest || !result) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.pkcs7ContentID = resourceID;
|
||||
request.certUsage = certUsage;
|
||||
request.hashAlgID = hashAlgID;
|
||||
request.keepCert = (CMBool) keepCerts;
|
||||
request.hash = *digest;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(VerifyDetachedSigRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_VERIFY_DETACHED_SIG;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING |SSM_VERIFY_DETACHED_SIG)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*result = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
*result = reply.value;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7VerifySignature(PCMT_CONTROL control, CMUint32 pubKeyAlgID,
|
||||
CMTItem *pubKeyParams, CMTItem *signerPubKey,
|
||||
CMTItem *computedHash, CMTItem *signature,
|
||||
CMInt32 *result)
|
||||
{
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CreateSigned(PCMT_CONTROL control, CMUint32 scertRID,
|
||||
CMUint32 ecertRID, CMUint32 dig_alg,
|
||||
CMTItem *digest, CMUint32 *ciRID, CMInt32 *errCode)
|
||||
{
|
||||
CMTItem message;
|
||||
CreateSignedRequest request;
|
||||
CreateContentInfoReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !scertRID || !ecertRID || !digest || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.scertRID = scertRID;
|
||||
request.ecertRID = ecertRID;
|
||||
request.dig_alg = dig_alg;
|
||||
request.digest = *digest;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateSignedRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*ciRID = reply.ciRID;
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) == CMTSuccess) {
|
||||
*errCode = reply.errorCode;
|
||||
} else {
|
||||
*errCode = 0;
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CreateEncrypted(PCMT_CONTROL control, CMUint32 scertRID,
|
||||
CMUint32 *rcertRIDs, CMUint32 *ciRID)
|
||||
{
|
||||
CMTItem message;
|
||||
CMInt32 nrcerts;
|
||||
CreateEncryptedRequest request;
|
||||
CreateContentInfoReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !scertRID || !rcertRIDs || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Calculate the number of certs */
|
||||
for (nrcerts =0; rcertRIDs[nrcerts] != 0; nrcerts++) {
|
||||
/* Nothing */
|
||||
;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.scertRID = scertRID;
|
||||
request.nrcerts = nrcerts;
|
||||
request.rcertRIDs = (long *) rcertRIDs;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateEncryptedRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message response type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*ciRID = reply.ciRID;
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderStart(PCMT_CONTROL control, CMUint32 ciRID,
|
||||
CMUint32 *connectionID, CMTP7ContentCallback cb,
|
||||
void *cb_arg)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMTP7Private *priv;
|
||||
PKCS7DataConnectionRequest request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = ciRID;
|
||||
request.clientContext.len = 0;
|
||||
request.clientContext.data = NULL;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(PKCS7DataConnectionRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
priv->priv.dest = (CMTReclaimFunc) free;
|
||||
priv->cb = cb;
|
||||
priv->cb_arg = cb_arg;
|
||||
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if (sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (control->sockFuncs.connect(sock, (short)reply.port,
|
||||
NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (control->sockFuncs.send(sock, control->nonce.data,
|
||||
control->nonce.len) != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*connectionID = reply.connID;
|
||||
|
||||
rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderUpdate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
const char *buf, CMUint32 len)
|
||||
{
|
||||
CMUint32 sent;
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char read_buf[128];
|
||||
CMTSocket sock, ctrlsock, sockArr[2], selSock;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !connectionID || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
while ((selSock = control->sockFuncs.select(sockArr, 2, 1)) != NULL)
|
||||
{
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else {
|
||||
nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
|
||||
if (nbytes == -1) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
} else {
|
||||
priv->cb(priv->cb_arg, read_buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderFinish(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char buf[128];
|
||||
CMTSocket sock, ctrlsock, sockArr[2], selSock;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
control->sockFuncs.shutdown(sock);
|
||||
while (1) {
|
||||
selSock = control->sockFuncs.select(sockArr, 2, 0);
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else if (selSock == sock) {
|
||||
nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
|
||||
if (nbytes < 0) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
} else {
|
||||
priv->cb(priv->cb_arg, buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control) {
|
||||
CMT_CloseDataConnection(control, connectionID);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
479
mozilla/security/psm/lib/client/cmtres.c
Normal file
479
mozilla/security/psm/lib/client/cmtres.c
Normal file
@@ -0,0 +1,479 @@
|
||||
/* -*- mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include <string.h>
|
||||
|
||||
CMTStatus CMT_GetNumericAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMInt32 *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*value = reply.value.u.numeric;
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_SetNumericAttribute(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 fieldID, CMInt32 value)
|
||||
{
|
||||
CMTItem message;
|
||||
SetAttribRequest request;
|
||||
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
request.value.type = SSM_NUMERIC_ATTRIBUTE;
|
||||
request.value.u.numeric = value;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(SetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE;
|
||||
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_PadStringValue(CMTItem *dest, CMTItem src)
|
||||
{
|
||||
dest->data = NewArray(unsigned char, src.len+1);
|
||||
if (dest->data == NULL) {
|
||||
return CMTFailure;
|
||||
}
|
||||
memcpy(dest->data, src.data, src.len);
|
||||
dest->data[src.len] = '\0';
|
||||
dest->len = src.len;
|
||||
free(src.data);
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetStringAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMTItem *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the response */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
return CMT_PadStringValue(value, reply.value.u.string);
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SetStringAttribute(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 fieldID, CMTItem *value)
|
||||
{
|
||||
CMTItem message;
|
||||
SetAttribRequest request;
|
||||
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
request.value.type = SSM_STRING_ATTRIBUTE;
|
||||
request.value.u.string = *value;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_STRING_ATTRIBUTE;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message request type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_STRING_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_DuplicateResource(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 *newResID)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
DupResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = resourceID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_DUPLICATE_RESOURCE;
|
||||
|
||||
/* Send the mesage */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_DUPLICATE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DupResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*newResID = reply.resID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
*newResID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_DestroyResource(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 resourceType)
|
||||
{
|
||||
CMTItem message;
|
||||
DestroyResourceRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.resType = resourceType;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(DestroyResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_DESTROY_RESOURCE;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_DESTROY_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.value == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PickleResource(PCMT_CONTROL control, CMUint32 resourceID, CMTItem * pickledResource)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
PickleResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = resourceID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_PICKLE_RESOURCE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_PICKLE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(PickleResourceReplyTemplate, &reply,&message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*pickledResource = reply.blob;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_UnpickleResource(PCMT_CONTROL control, CMUint32 resourceType, CMTItem pickledResource, CMUint32 * resourceID)
|
||||
{
|
||||
CMTItem message;
|
||||
UnpickleResourceRequest request;
|
||||
UnpickleResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resourceType = resourceType;
|
||||
request.resourceData = pickledResource;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(UnpickleResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_UNPICKLE_RESOURCE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_UNPICKLE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(UnpickleResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*resourceID = reply.resID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
*resourceID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetRIDAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMUint32 *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message response type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*value = reply.value.u.rid;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
270
mozilla/security/psm/lib/client/cmtrng.c
Normal file
270
mozilla/security/psm/lib/client/cmtrng.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
cmtrng.c -- Support for PSM random number generator and the seeding
|
||||
thereof with data from the client.
|
||||
|
||||
Created by mwelch 1999 Oct 21
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
#include <string.h>
|
||||
|
||||
CMTStatus
|
||||
CMT_EnsureInitializedRNGBuf(PCMT_CONTROL control)
|
||||
{
|
||||
if (control->rng.outBuf == NULL)
|
||||
{
|
||||
control->rng.outBuf = (char *) calloc(RNG_OUT_BUFFER_LEN, sizeof(char));
|
||||
if (control->rng.outBuf == NULL)
|
||||
goto loser;
|
||||
|
||||
control->rng.validOutBytes = 0;
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
control->rng.out_end = control->rng.out_cur + RNG_OUT_BUFFER_LEN;
|
||||
|
||||
control->rng.inBuf = (char *) calloc(RNG_IN_BUFFER_LEN, sizeof(char));
|
||||
if (control->rng.outBuf == NULL)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control->rng.outBuf != NULL)
|
||||
{
|
||||
free(control->rng.outBuf);
|
||||
control->rng.outBuf = NULL;
|
||||
}
|
||||
if (control->rng.inBuf != NULL)
|
||||
{
|
||||
free(control->rng.inBuf);
|
||||
control->rng.inBuf = NULL;
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CMT_RequestPSMRandomData(PCMT_CONTROL control,
|
||||
void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
SingleNumMessage req;
|
||||
SingleItemMessage reply;
|
||||
CMTItem message;
|
||||
size_t rv = 0;
|
||||
|
||||
/* Parameter checking */
|
||||
if (!control || !buf || (maxbytes == 0))
|
||||
goto loser;
|
||||
|
||||
/* Initialization. */
|
||||
memset(&reply, 0, sizeof(SingleItemMessage));
|
||||
|
||||
/* Ask PSM for the data. */
|
||||
req.value = maxbytes;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &req) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_MISC_ACTION | SSM_MISC_GET_RNG_DATA;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure)
|
||||
goto loser;
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_MISC_ACTION | SSM_MISC_GET_RNG_DATA))
|
||||
goto loser;
|
||||
|
||||
/* Decode message */
|
||||
if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Success - fill the return buf with what we got */
|
||||
if (reply.item.len > maxbytes)
|
||||
reply.item.len = maxbytes;
|
||||
|
||||
memcpy(buf, reply.item.data, reply.item.len);
|
||||
rv = reply.item.len;
|
||||
|
||||
loser:
|
||||
if (reply.item.data)
|
||||
free(reply.item.data);
|
||||
if (message.data)
|
||||
free(message.data);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t
|
||||
CMT_GenerateRandomBytes(PCMT_CONTROL control,
|
||||
void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
CMUint32 remaining = maxbytes;
|
||||
CMT_RNGState *rng = &(control->rng);
|
||||
char *walk = (char *) buf;
|
||||
|
||||
/* Is there already enough in the incoming cache? */
|
||||
while(remaining > rng->validInBytes)
|
||||
{
|
||||
/* Get what we have on hand. */
|
||||
memcpy(walk, rng->in_cur, rng->validInBytes);
|
||||
walk += rng->validInBytes;
|
||||
remaining -= rng->validInBytes;
|
||||
|
||||
/* Request a buffer from PSM. */
|
||||
rng->validInBytes = CMT_RequestPSMRandomData(control,
|
||||
rng->inBuf,
|
||||
RNG_IN_BUFFER_LEN);
|
||||
if (rng->validInBytes == 0)
|
||||
return (maxbytes - remaining); /* call failed */
|
||||
rng->in_cur = rng->inBuf;
|
||||
}
|
||||
if (remaining > 0)
|
||||
{
|
||||
memcpy(walk, rng->in_cur, remaining);
|
||||
rng->in_cur += remaining;
|
||||
rng->validInBytes -= remaining;
|
||||
}
|
||||
return maxbytes;
|
||||
}
|
||||
|
||||
void
|
||||
cmt_rng_xor(void *dstBuf, void *srcBuf, int len)
|
||||
{
|
||||
unsigned char *s = (unsigned char*) srcBuf;
|
||||
unsigned char *d = (unsigned char*) dstBuf;
|
||||
unsigned char tmp;
|
||||
int i;
|
||||
|
||||
for(i=0; i<len; i++, s++, d++)
|
||||
{
|
||||
tmp = *d;
|
||||
/* I wish C had circular shift operators. So do others on the team. */
|
||||
tmp = ((tmp << 1) | (tmp >> 7));
|
||||
*d = tmp ^ *s;
|
||||
}
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_RandomUpdate(PCMT_CONTROL control, void *data, size_t numbytes)
|
||||
{
|
||||
size_t dataLeft = numbytes, cacheLeft;
|
||||
char *walk = (char *) data;
|
||||
|
||||
if (CMT_EnsureInitializedRNGBuf(control) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* If we have more than what the buffer can handle, wrap around. */
|
||||
cacheLeft = (control->rng.out_end - control->rng.out_cur);
|
||||
while (dataLeft >= cacheLeft)
|
||||
{
|
||||
cmt_rng_xor(control->rng.out_cur, walk, cacheLeft);
|
||||
walk += cacheLeft;
|
||||
dataLeft -= cacheLeft;
|
||||
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
|
||||
/* Max out used space */
|
||||
control->rng.validOutBytes = cacheLeft = RNG_OUT_BUFFER_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
We now have less seed data available than we do space in the buf.
|
||||
Write what we have and update validOutBytes if we're not looping already.
|
||||
*/
|
||||
cmt_rng_xor(control->rng.out_cur, walk, dataLeft);
|
||||
control->rng.out_cur += dataLeft;
|
||||
if (control->rng.validOutBytes < RNG_OUT_BUFFER_LEN)
|
||||
control->rng.validOutBytes += dataLeft;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
size_t
|
||||
CMT_GetNoise(PCMT_CONTROL control, void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
/* ### mwelch - GetNoise and GenerateRandomBytes can be the
|
||||
same function now, because presumably the RNG is being
|
||||
seeded with environmental noise on the PSM end before we
|
||||
make any of these requests */
|
||||
return CMT_GenerateRandomBytes(control, buf, maxbytes);
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_FlushPendingRandomData(PCMT_CONTROL control)
|
||||
{
|
||||
CMTItem message;
|
||||
|
||||
memset(&message, 0, sizeof(CMTItem));
|
||||
|
||||
if (CMT_EnsureInitializedRNGBuf(control) != CMTSuccess)
|
||||
return CMTFailure; /* couldn't initialize RNG buffer */
|
||||
|
||||
if (control->rng.validOutBytes == 0)
|
||||
return CMTSuccess; /* no random data available == we're flushed */
|
||||
|
||||
/* We have random data available. Send this to PSM.
|
||||
We're sending an event, so no reply is needed. */
|
||||
message.type = SSM_EVENT_MESSAGE
|
||||
| SSM_MISC_ACTION
|
||||
| SSM_MISC_PUT_RNG_DATA;
|
||||
message.len = control->rng.validOutBytes;
|
||||
message.data = (unsigned char *) calloc(message.len, sizeof(char));
|
||||
if (!message.data)
|
||||
goto loser;
|
||||
memcpy(message.data, control->rng.outBuf, message.len);
|
||||
|
||||
if (CMT_TransmitMessage(control, &message) == CMTFailure)
|
||||
goto loser;
|
||||
|
||||
/* Clear the RNG ring buffer, we've used that data */
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
control->rng.validOutBytes = 0;
|
||||
/* zero the buffer, because we XOR in new data */
|
||||
memset(control->rng.outBuf, 0, RNG_OUT_BUFFER_LEN);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (message.data)
|
||||
free(message.data);
|
||||
return CMTFailure;
|
||||
done:
|
||||
return CMTSuccess;
|
||||
}
|
||||
237
mozilla/security/psm/lib/client/cmtsdr.c
Normal file
237
mozilla/security/psm/lib/client/cmtsdr.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
cmtsdr.c -- Support for the Secret Decoder Ring, which provides
|
||||
encryption and decryption using stored keys.
|
||||
|
||||
Created by thayes 18 April 2000
|
||||
*/
|
||||
#include "stddef.h"
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "protocolshr.h"
|
||||
#include "rsrcids.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef PROCESS_LOCALLY
|
||||
|
||||
/* Encryption result - contains the key id and the resulting data */
|
||||
/* An empty key id indicates that NO encryption was performed */
|
||||
typedef struct EncryptionResult
|
||||
{
|
||||
CMTItem keyid;
|
||||
CMTItem data;
|
||||
} EncryptionResult;
|
||||
|
||||
/* Constants for testing */
|
||||
static const char *kPrefix = "Encrypted:";
|
||||
|
||||
static CMTItem
|
||||
CMT_CopyDataToItem(const unsigned char *data, CMUint32 len)
|
||||
{
|
||||
CMTItem item;
|
||||
|
||||
item.data = (unsigned char*) calloc(len, 1);
|
||||
item.len = len;
|
||||
memcpy(item.data, data, len);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
static CMTStatus
|
||||
tmp_SendMessage(PCMT_CONTROL control, CMTItem *message)
|
||||
{
|
||||
#ifndef PROCESS_LOCALLY
|
||||
return CMT_SendMessage(control, message);
|
||||
#else
|
||||
if (message->type == SSM_SDR_ENCRYPT_REQUEST)
|
||||
return CMT_DoEncryptionRequest(message);
|
||||
else if (message->type == SSM_SDR_DECRYPT_REQUEST)
|
||||
return CMT_DoDecryptionRequest(message);
|
||||
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
/* End test code */
|
||||
|
||||
CMTStatus
|
||||
CMT_SDREncrypt(PCMT_CONTROL control, void *ctx,
|
||||
const unsigned char *key, CMUint32 keyLen,
|
||||
const unsigned char *data, CMUint32 dataLen,
|
||||
unsigned char **result, CMUint32 *resultLen)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTItem message;
|
||||
EncryptRequestMessage request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.keyid = CMT_CopyDataToItem(key, keyLen);
|
||||
request.data = CMT_CopyDataToItem(data, dataLen);
|
||||
request.ctx = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
reply.item.data = 0;
|
||||
reply.item.len = 0;
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(EncryptRequestTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_SDR_ENCRYPT_REQUEST;
|
||||
|
||||
/* Send */
|
||||
/* if (CMT_SendMessage(control, &message) != CMTSuccess) goto loser; */
|
||||
rv = tmp_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type != SSM_SDR_ENCRYPT_REPLY) { rv = CMTFailure; goto loser; }
|
||||
|
||||
rv = CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
*result = reply.item.data;
|
||||
*resultLen = reply.item.len;
|
||||
|
||||
reply.item.data = 0;
|
||||
|
||||
loser:
|
||||
if (message.data) free(message.data);
|
||||
if (request.keyid.data) free(request.keyid.data);
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SDRDecrypt(PCMT_CONTROL control, void *ctx,
|
||||
const unsigned char *data, CMUint32 dataLen,
|
||||
unsigned char **result, CMUint32 *resultLen)
|
||||
{
|
||||
CMTStatus rv;
|
||||
CMTItem message;
|
||||
DecryptRequestMessage request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.data = CMT_CopyDataToItem(data, dataLen);
|
||||
request.ctx = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
reply.item.data = 0;
|
||||
reply.item.len = 0;
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(DecryptRequestTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_SDR_DECRYPT_REQUEST;
|
||||
|
||||
/* Send */
|
||||
/* if (CMT_SendMessage(control, &message) != CMTSuccess) goto loser; */
|
||||
rv = tmp_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type != SSM_SDR_DECRYPT_REPLY) { rv = CMTFailure; goto loser; }
|
||||
|
||||
rv = CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
*result = reply.item.data;
|
||||
*resultLen = reply.item.len;
|
||||
|
||||
reply.item.data = 0;
|
||||
|
||||
loser:
|
||||
if (message.data) free(message.data);
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SDRChangePassword(PCMT_CONTROL control, void *ctx)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTItem message;
|
||||
SingleItemMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.item = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = (SSM_REQUEST_MESSAGE|SSM_MISC_ACTION|SSM_MISC_UI|SSM_UI_CHANGE_PASSWORD);
|
||||
|
||||
/* Send */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type !=
|
||||
(SSM_REPLY_OK_MESSAGE|SSM_MISC_ACTION|SSM_MISC_UI|SSM_UI_CHANGE_PASSWORD)) {
|
||||
rv = CMTFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
loser:
|
||||
if (request.item.data) free(request.item.data);
|
||||
if (message.data) free(message.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
467
mozilla/security/psm/lib/client/cmtssl.c
Normal file
467
mozilla/security/psm/lib/client/cmtssl.c
Normal file
@@ -0,0 +1,467 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#else /* windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
|
||||
|
||||
CMTStatus CMT_OpenSSLConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
SSMSSLConnectionRequestType flags,
|
||||
CMUint32 port, char * hostIP,
|
||||
char * hostName, CMBool forceHandshake, void* clientContext)
|
||||
{
|
||||
CMTItem message;
|
||||
SSLDataConnectionRequest request;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.flags = flags;
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
request.forceHandshake = forceHandshake;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode message */
|
||||
if (CMT_EncodeMessage(SSLDataConnectionRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_SSL_CONNECTION;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_SSL_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLDataErrorCode(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMInt32* errorCode)
|
||||
{
|
||||
CMUint32 connID;
|
||||
|
||||
if (!control || !errorCode) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the PR error */
|
||||
if (CMT_GetNumericAttribute(control, connID, SSM_FID_SSLDATA_ERROR_VALUE,
|
||||
errorCode) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReleaseSSLSocketStatus(PCMT_CONTROL control, CMTSocket sock)
|
||||
{
|
||||
CMUint32 connectionID;
|
||||
|
||||
if (!control || !sock) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_SetNumericAttribute(control, connectionID,
|
||||
SSM_FID_SSLDATA_DISCARD_SOCKET_STATUS,
|
||||
0) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLSocketStatus(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMTItem* pickledStatus, CMInt32* level)
|
||||
{
|
||||
CMUint32 connectionID;
|
||||
SingleNumMessage request;
|
||||
CMTItem message;
|
||||
PickleSecurityStatusReply reply;
|
||||
|
||||
if (!control || !pickledStatus || !level) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.value = connectionID;
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_CONSERVE_RESOURCE | SSM_PICKLE_SECURITY_STATUS;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_CONSERVE_RESOURCE | SSM_PICKLE_SECURITY_STATUS)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(PickleSecurityStatusReplyTemplate, &reply, &message)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
*pickledStatus = reply.blob;
|
||||
*level = reply.securityLevel;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_OpenTLSConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 port, char* hostIP, char* hostName)
|
||||
{
|
||||
TLSDataConnectionRequest request;
|
||||
CMTItem message;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
|
||||
/* encode the message */
|
||||
if (CMT_EncodeMessage(TLSDataConnectionRequestTemplate, &message, &request)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_TLS_CONNECTION;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_TLS_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_TLSStepUp(PCMT_CONTROL control, CMTSocket sock,
|
||||
void* clientContext)
|
||||
{
|
||||
TLSStepUpRequest request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMUint32 connectionID;
|
||||
|
||||
/* check arguments */
|
||||
if (!control || !sock) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection ID */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.connID = connectionID;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(TLSStepUpRequestTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_TLS_STEPUP;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_TLS_STEPUP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_OpenSSLProxyConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 port, char* hostIP,
|
||||
char* hostName)
|
||||
{
|
||||
TLSDataConnectionRequest request;
|
||||
CMTItem message;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
|
||||
/* encode the message */
|
||||
if (CMT_EncodeMessage(TLSDataConnectionRequestTemplate, &message, &request)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_PROXY_CONNECTION;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_PROXY_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_ProxyStepUp(PCMT_CONTROL control, CMTSocket sock,
|
||||
void* clientContext, char* remoteUrl)
|
||||
{
|
||||
ProxyStepUpRequest request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMUint32 connectionID;
|
||||
|
||||
/* check arguments */
|
||||
if (!control || !sock || !remoteUrl) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection ID */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.connID = connectionID;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
request.url = remoteUrl;
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(ProxyStepUpRequestTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_PROXY_STEPUP;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_PROXY_STEPUP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
636
mozilla/security/psm/lib/client/cmtutils.c
Normal file
636
mozilla/security/psm/lib/client/cmtutils.c
Normal file
@@ -0,0 +1,636 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "newproto.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Local defines */
|
||||
#if 0
|
||||
#define PSM_WAIT_BEFORE_SLEEP (CM_TicksPerSecond() * 60)
|
||||
#define PSM_SPINTIME PSM_WAIT_BEFORE_SLEEP
|
||||
#define PSM_KEEP_CONNECTION_ALIVE (PSM_WAIT_BEFORE_SLEEP * 900)
|
||||
#endif
|
||||
|
||||
/* If you want to dump the messages sent between the plug-in and the PSM
|
||||
* server, then remove the comment for the appropriate define.
|
||||
*/
|
||||
#if 0
|
||||
#define PRINT_SEND_MESSAGES
|
||||
#define PRINT_RECEIVE_MESSAGES
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_SEND_MESSAGES
|
||||
#ifndef DEBUG_MESSAGES
|
||||
#define DEBUG_MESSAGES
|
||||
#endif /*DEBUG_MESSAGES*/
|
||||
#endif /*PRINT_SEND_MESSAGES*/
|
||||
|
||||
#ifdef PRINT_RECEIVE_MESSAGES
|
||||
#ifndef DEBUG_MESSAGES
|
||||
#define DEBUG_MESSAGES
|
||||
#endif /*DEBUG_MESSAGES*/
|
||||
#endif /*PRINT_RECEIVE_MESSAGES*/
|
||||
|
||||
#ifdef DEBUG_MESSAGES
|
||||
#define LOG(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, x); fclose(f); } } while(0);
|
||||
#define LOG_S(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, "%s", x); fclose(f); } } while(0);
|
||||
#define ASSERT(x) if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("\n"); exit(-1); }
|
||||
#else
|
||||
#define LOG(x)
|
||||
#define LOG_S(x)
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
||||
CMUint32
|
||||
cmt_Strlen(char *str)
|
||||
{
|
||||
CMUint32 len = strlen(str);
|
||||
return sizeof(CMInt32) + (((len + 3)/4)*4);
|
||||
}
|
||||
|
||||
CMUint32
|
||||
cmt_Bloblen(CMTItem *blob)
|
||||
{
|
||||
return sizeof(CMInt32) + (((blob->len +3)/4)*4);
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_PackString(char *buf, char *str)
|
||||
{
|
||||
CMUint32 len = strlen(str);
|
||||
CMUint32 networkLen = htonl(len);
|
||||
CMUint32 padlen = ((len + 3)/4)*4;
|
||||
|
||||
memcpy(buf, &networkLen, sizeof(CMUint32));
|
||||
memcpy(buf + sizeof(CMUint32), str, len);
|
||||
memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_PackBlob(char *buf, CMTItem *blob)
|
||||
{
|
||||
CMUint32 len = blob->len;
|
||||
CMUint32 networkLen = htonl(len);
|
||||
CMUint32 padlen = (((blob->len + 3)/4)*4);
|
||||
|
||||
*((CMUint32*)buf) = networkLen;
|
||||
memcpy(buf + sizeof(CMUint32), blob->data, len);
|
||||
memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
|
||||
|
||||
return buf + sizeof(CMUint32) + padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_UnpackString(char *buf, char **str)
|
||||
{
|
||||
char *p = NULL;
|
||||
CMUint32 len, padlen;
|
||||
|
||||
/* Get the string length */
|
||||
len = ntohl(*(CMUint32*)buf);
|
||||
|
||||
/* Get the padded length */
|
||||
padlen = ((len + 3)/4)*4;
|
||||
|
||||
/* Allocate the string and copy the data */
|
||||
p = (char *) malloc(len + 1);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
/* Copy the data and NULL terminate */
|
||||
memcpy(p, buf+sizeof(CMUint32), len);
|
||||
p[len] = 0;
|
||||
|
||||
*str = p;
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
loser:
|
||||
*str = NULL;
|
||||
if (p) {
|
||||
free(p);
|
||||
}
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_UnpackBlob(char *buf, CMTItem **blob)
|
||||
{
|
||||
CMTItem *p = NULL;
|
||||
CMUint32 len, padlen;
|
||||
|
||||
/* Get the blob length */
|
||||
len = ntohl(*(CMUint32*)buf);
|
||||
|
||||
/* Get the padded length */
|
||||
padlen = ((len + 3)/4)*4;
|
||||
|
||||
/* Allocate the CMTItem for the blob */
|
||||
p = (CMTItem*)malloc(sizeof(CMTItem));
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
p->len = len;
|
||||
p->data = (unsigned char *) malloc(len);
|
||||
if (!p->data) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy that data across */
|
||||
memcpy(p->data, buf+sizeof(CMUint32), len);
|
||||
*blob = p;
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
|
||||
loser:
|
||||
*blob = NULL;
|
||||
CMT_FreeMessage(p);
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MESSAGES
|
||||
void prettyPrintMessage(CMTItem *msg)
|
||||
{
|
||||
int numLines = ((msg->len+7)/8);
|
||||
char curBuffer[9], *cursor, string[2], hexVal[8];
|
||||
char hexArray[25];
|
||||
int i, j, numToCopy;
|
||||
|
||||
/*Try printing out 8 bytes at a time. */
|
||||
LOG("\n**********************************************************\n");
|
||||
LOG("About to pretty Print Message\n\n");
|
||||
curBuffer[9] = '\0';
|
||||
hexArray[24] = '\0';
|
||||
hexVal[2] = '\0';
|
||||
string[1] = '\0';
|
||||
LOG("Header Info\n");
|
||||
LOG("Message Type: ");
|
||||
sprintf(hexArray, "%lx\n", msg->type);
|
||||
LOG(hexArray);
|
||||
LOG("Message Length: ");
|
||||
sprintf (hexArray, "%ld\n\n", msg->len);
|
||||
LOG(hexArray);
|
||||
LOG("Body of Message\n");
|
||||
for (i=0, cursor=msg->data; i<numLines; i++, cursor+=8) {
|
||||
/* First copy over the buffer to our local array */
|
||||
numToCopy = ((msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data)) < 8) ?
|
||||
msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data) : 8;
|
||||
memcpy(curBuffer, cursor, 8);
|
||||
for (j=0;j<numToCopy;j++) {
|
||||
string[0] = curBuffer[j];
|
||||
if (isprint(curBuffer[j])) {
|
||||
string[0] = curBuffer[j];
|
||||
} else {
|
||||
string[0] = ' ';
|
||||
}
|
||||
LOG(string);
|
||||
}
|
||||
string[0] = ' ';
|
||||
for (;j<8;j++) {
|
||||
LOG(string);
|
||||
}
|
||||
LOG("\t");
|
||||
for (j=0; j<numToCopy; j++) {
|
||||
sprintf (hexVal,"%.2x", 0x0ff & (unsigned short)curBuffer[j]);
|
||||
LOG(hexVal);
|
||||
LOG(" ");
|
||||
}
|
||||
LOG("\n");
|
||||
}
|
||||
LOG("Done Pretty Printing Message\n");
|
||||
LOG("**********************************************************\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
CMTStatus CMT_SendMessage(PCMT_CONTROL control, CMTItem* message)
|
||||
{
|
||||
CMTStatus status;
|
||||
CMUint32 msgCategory;
|
||||
CMBool done = CM_FALSE;
|
||||
#ifdef PRINT_SEND_MESSAGES
|
||||
LOG("About to print message sent to PSM\n");
|
||||
prettyPrintMessage(message);
|
||||
#endif
|
||||
|
||||
/* Acquire lock on the control connection */
|
||||
CMT_LOCK(control->mutex);
|
||||
|
||||
/* Try to send pending random data */
|
||||
if (message->type != (SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE))
|
||||
{
|
||||
/* If we've already said hello, then flush random data
|
||||
just before sending the request. */
|
||||
status = CMT_FlushPendingRandomData(control);
|
||||
if (status != CMTSuccess)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
status = CMT_TransmitMessage(control, message);
|
||||
if (status != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* We have to deal with other types of data on the socket and */
|
||||
/* handle them accordingly */
|
||||
while (!done) {
|
||||
status = CMT_ReceiveMessage(control, message);
|
||||
if (status != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
msgCategory = (message->type & SSM_CATEGORY_MASK);
|
||||
switch (msgCategory) {
|
||||
case SSM_REPLY_OK_MESSAGE:
|
||||
done = CM_TRUE;
|
||||
break;
|
||||
case SSM_REPLY_ERR_MESSAGE:
|
||||
done = CM_TRUE;
|
||||
break;
|
||||
case SSM_EVENT_MESSAGE:
|
||||
CMT_DispatchEvent(control, message);
|
||||
break;
|
||||
/* XXX FIX THIS!!! For the moment I'm ignoring all other types */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the control connection lock */
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
/* Release the control connection lock */
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_TransmitMessage(PCMT_CONTROL control, CMTItem * message)
|
||||
{
|
||||
CMTMessageHeader header;
|
||||
CMUint32 sent, rv;
|
||||
|
||||
/* Set up the message header */
|
||||
header.type = htonl(message->type);
|
||||
header.len = htonl(message->len);
|
||||
|
||||
/* Send the message header */
|
||||
sent = CMT_WriteThisMany(control, control->sock,
|
||||
(void *)&header, sizeof(CMTMessageHeader));
|
||||
if (sent != sizeof(CMTMessageHeader)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message body */
|
||||
sent = CMT_WriteThisMany(control, control->sock, (void *)message->data,
|
||||
message->len);
|
||||
if (sent != message->len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
free(message->data);
|
||||
message->data = NULL;
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReceiveMessage(PCMT_CONTROL control, CMTItem * response)
|
||||
{
|
||||
CMTMessageHeader header;
|
||||
CMUint32 numread, rv;
|
||||
|
||||
/* Get the message header */
|
||||
numread = CMT_ReadThisMany(control, control->sock,
|
||||
(void *)&header, sizeof(CMTMessageHeader));
|
||||
if (numread != sizeof(CMTMessageHeader)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
response->type = ntohl(header.type);
|
||||
response->len = ntohl(header.len);
|
||||
response->data = (unsigned char *) malloc(response->len);
|
||||
if (response->data == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
numread = CMT_ReadThisMany(control, control->sock,
|
||||
(void *)(response->data), response->len);
|
||||
if (numread != response->len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
#ifdef PRINT_RECEIVE_MESSAGES
|
||||
LOG("About to print message received from PSM.\n");
|
||||
prettyPrintMessage(response);
|
||||
#endif /*PRINT_RECEIVE_MESSAGES*/
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
if (response->data) {
|
||||
free(response->data);
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMUint32 CMT_ReadThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany)
|
||||
{
|
||||
CMUint32 total = 0;
|
||||
|
||||
while (total < thisMany) {
|
||||
int got;
|
||||
got = control->sockFuncs.recv(sock, (void*)((char*)buffer + total),
|
||||
thisMany-total);
|
||||
if (got < 0 ) {
|
||||
break;
|
||||
}
|
||||
total += got;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
CMUint32 CMT_WriteThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany)
|
||||
{
|
||||
CMUint32 total = 0;
|
||||
|
||||
while (total < thisMany) {
|
||||
CMInt32 got;
|
||||
got = control->sockFuncs.send(sock, (void*)((char*)buffer+total),
|
||||
thisMany-total);
|
||||
if (got < 0) {
|
||||
break;
|
||||
}
|
||||
total += got;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
CMTItem* CMT_ConstructMessage(CMUint32 type, CMUint32 length)
|
||||
{
|
||||
CMTItem * p;
|
||||
|
||||
p = (CMTItem*)malloc(sizeof(CMTItem));
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
p->type = type;
|
||||
p->len = length;
|
||||
p->data = (unsigned char *) malloc(length);
|
||||
if (!p->data) {
|
||||
goto loser;
|
||||
}
|
||||
return p;
|
||||
|
||||
loser:
|
||||
CMT_FreeMessage(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_FreeMessage(CMTItem * p)
|
||||
{
|
||||
if (p != NULL) {
|
||||
if (p->data != NULL) {
|
||||
free(p->data);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
CMTStatus CMT_AddDataConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
/* This is the first connection */
|
||||
if (control->cmtDataConnections == NULL) {
|
||||
control->cmtDataConnections = ptr =
|
||||
(PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
|
||||
if (!ptr) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
/* Position at the last entry */
|
||||
for (ptr = control->cmtDataConnections; (ptr != NULL && ptr->next
|
||||
!= NULL); ptr = ptr->next);
|
||||
ptr->next = (PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
|
||||
if (!ptr->next) {
|
||||
goto loser;
|
||||
}
|
||||
/* Fix up the pointers */
|
||||
ptr->next->previous = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
/* Fill in the data */
|
||||
ptr->sock = sock;
|
||||
ptr->connectionID = connectionID;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
int
|
||||
CMT_DestroyDataConnection(PCMT_CONTROL control, CMTSocket sock)
|
||||
{
|
||||
PCMT_DATA ptr, pptr = NULL;
|
||||
int rv=CMTSuccess;
|
||||
|
||||
control->sockFuncs.close(sock);
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL;
|
||||
pptr = ptr, ptr = ptr->next) {
|
||||
if (ptr->sock == sock) {
|
||||
if (pptr == NULL) {
|
||||
/* node is at head */
|
||||
control->cmtDataConnections = ptr->next;
|
||||
if (ptr->priv != NULL)
|
||||
ptr->priv->dest(ptr->priv);
|
||||
free(ptr);
|
||||
return rv;
|
||||
}
|
||||
/* node is elsewhere */
|
||||
pptr->next = ptr->next;
|
||||
if (ptr->priv != NULL)
|
||||
ptr->priv->dest(ptr->priv);
|
||||
free(ptr);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CloseDataConnection(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
/* PCMT_DATA ptr, pptr = NULL; */
|
||||
CMTSocket sock;
|
||||
/* int rv;*/
|
||||
|
||||
/* Get the socket for this connection */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Free data connection associated with this socket */
|
||||
if (CMT_DestroyDataConnection(control, sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetDataConnectionID(PCMT_CONTROL control, CMTSocket sock, CMUint32 * connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->sock == sock) {
|
||||
*connectionID = ptr->connectionID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetDataSocket(PCMT_CONTROL control, CMUint32 connectionID, CMTSocket * sock)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
*sock = ptr->sock;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_SetPrivate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMTPrivate *cmtpriv)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
ptr->priv = cmtpriv;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTPrivate *CMT_GetPrivate(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
return ptr->priv;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_FreeItem(CMTItem *p)
|
||||
{
|
||||
CMT_FreeMessage(p);
|
||||
}
|
||||
|
||||
CMTItem CMT_CopyPtrToItem(void* p)
|
||||
{
|
||||
CMTItem value = {0, NULL, 0};
|
||||
|
||||
if (!p) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value.len = sizeof(p);
|
||||
value.data = (unsigned char *) malloc(value.len);
|
||||
memcpy(value.data, &p, value.len);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void * CMT_CopyItemToPtr(CMTItem value)
|
||||
{
|
||||
void * p = NULL;
|
||||
|
||||
if (value.len == sizeof(void*)) {
|
||||
memcpy(&p, value.data, value.len);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReferenceControlConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_LOCK(control->mutex);
|
||||
control->refCount++;
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
CMT_LockConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_LOCK(control->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CMT_UnlockConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_UNLOCK(control->mutex);
|
||||
}
|
||||
75
mozilla/security/psm/lib/client/cmtutils.h
Normal file
75
mozilla/security/psm/lib/client/cmtutils.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __CMTUTILS_H__
|
||||
#define __CMTUTILS_H__
|
||||
|
||||
#include "cmtcmn.h"
|
||||
|
||||
#define New(type) (type*)malloc(sizeof(type))
|
||||
#define NewArray(type, size) (type*)malloc(sizeof(type)*(size))
|
||||
|
||||
PCMT_EVENT CMT_GetEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID);
|
||||
|
||||
CMUint32 cmt_Strlen(char *str);
|
||||
char *cmt_PackString(char *buf, char *str);
|
||||
char *cmt_UnpackString(char *buf, char **str);
|
||||
|
||||
CMUint32 cmt_Bloblen(CMTItem* len);
|
||||
char *cmt_PackBlob(char *buf, CMTItem * blob);
|
||||
char *cmt_UnpackBlob(char *buf, CMTItem **blob);
|
||||
|
||||
CMTStatus CMT_SendMessage(PCMT_CONTROL control, CMTItem* message);
|
||||
CMTStatus CMT_TransmitMessage(PCMT_CONTROL control, CMTItem * message);
|
||||
CMTStatus CMT_ReceiveMessage(PCMT_CONTROL control, CMTItem * response);
|
||||
CMUint32 CMT_ReadThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany);
|
||||
CMUint32 CMT_WriteThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany);
|
||||
CMTItem* CMT_ConstructMessage(CMUint32 type, CMUint32 length);
|
||||
void CMT_FreeMessage(CMTItem * p);
|
||||
CMTStatus CMT_AddDataConnection(PCMT_CONTROL control, CMTSocket sock, CMUint32 connectionID);
|
||||
CMTStatus CMT_GetDataConnectionID(PCMT_CONTROL control, CMTSocket sock, CMUint32 * connectionID);
|
||||
CMTStatus CMT_GetDataSocket(PCMT_CONTROL control, CMUint32 connectionID, CMTSocket * sock);
|
||||
CMTStatus CMT_CloseDataConnection(PCMT_CONTROL control, CMUint32 connectionID);
|
||||
CMTStatus CMT_SetPrivate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMTPrivate *cmtpriv);
|
||||
CMTPrivate *CMT_GetPrivate(PCMT_CONTROL control, CMUint32 connectionID);
|
||||
void CMT_ServicePasswordRequest(PCMT_CONTROL cm_control, CMTItem * requestData);
|
||||
void CMT_ProcessEvent(PCMT_CONTROL cm_control);
|
||||
void CMT_DispatchEvent(PCMT_CONTROL cm_control, CMTItem * eventData);
|
||||
CMTItem CMT_CopyPtrToItem(void* p);
|
||||
void * CMT_CopyItemToPtr(CMTItem value);
|
||||
|
||||
#endif /* __CMTUTILS_H__ */
|
||||
|
||||
44
mozilla/security/psm/lib/client/config.mk
Normal file
44
mozilla/security/psm/lib/client/config.mk
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PURE_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
125
mozilla/security/psm/lib/client/makefile.win
Normal file
125
mozilla/security/psm/lib/client/makefile.win
Normal file
@@ -0,0 +1,125 @@
|
||||
#//
|
||||
#// 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 the Netscape security libraries.
|
||||
#//
|
||||
#// The Initial Developer of the Original Code is Netscape
|
||||
#// Communications Corporation. Portions created by Netscape are
|
||||
#// Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
#// Rights Reserved.
|
||||
#//
|
||||
#// Contributor(s):
|
||||
#//
|
||||
#// Alternatively, the contents of this file may be used under the
|
||||
#// terms of the GNU General Public License Version 2 or later (the
|
||||
#// "GPL"), in which case the provisions of the GPL are applicable
|
||||
#// instead of those above. If you wish to allow use of your
|
||||
#// version of this file only under the terms of the GPL and not to
|
||||
#// allow others to use your version of this file under the MPL,
|
||||
#// indicate your decision by deleting the provisions above and
|
||||
#// replace them with the notice and other provisions required by
|
||||
#// the GPL. If you do not delete the provisions above, a recipient
|
||||
#// may use your version of this file under either the MPL or the
|
||||
#// GPL.
|
||||
#//
|
||||
IGNORE_MANIFEST=1
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the ssl library
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
!ifndef MOZ_DEBUG
|
||||
OPTIMIZER=-Os -UDEBUG -DNDEBUG
|
||||
!endif
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH= ..\..\..\..
|
||||
|
||||
!ifndef MAKE_OBJ_TYPE
|
||||
MAKE_OBJ_TYPE=EXE
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBNAME=cmt
|
||||
PDBFILE=$(LIBNAME).pdb
|
||||
|
||||
LINCS = -I$(PUBLIC)\security \
|
||||
-I$(PUBLIC)\nspr \
|
||||
-I$(DEPTH)\include \
|
||||
-I..\include
|
||||
|
||||
!ifndef OS_CONFIG
|
||||
OS_CONFIG = WIN$(MOZ_BITS)
|
||||
!endif
|
||||
|
||||
LCFLAGS = -DEXPORT_VERSION -DLIB_BUILD
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\cmtinit.obj \
|
||||
.\$(OBJDIR)\cmtssl.obj \
|
||||
.\$(OBJDIR)\cmtutils.obj \
|
||||
.\$(OBJDIR)\cmtpkcs7.obj \
|
||||
.\$(OBJDIR)\cmthash.obj \
|
||||
.\$(OBJDIR)\cmtcert.obj \
|
||||
.\$(OBJDIR)\cmtres.obj \
|
||||
.\$(OBJDIR)\cmtjs.obj \
|
||||
.\$(OBJDIR)\cmtevent.obj \
|
||||
.\$(OBJDIR)\cmtpasswd.obj \
|
||||
.\$(OBJDIR)\cmtadvisor.obj \
|
||||
.\$(OBJDIR)\cmtrng.obj \
|
||||
.\$(OBJDIR)\cmtsdr.obj \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
|
||||
#// (these must be defined before the common makefiles are included)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBRARY=.\$(OBJDIR)\$(LIBNAME).lib
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// install headers
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
INSTALL_DIR=$(PUBLIC)\security
|
||||
INSTALL_FILE_LIST=cmtcmn.h cmtjs.h cmtclist.h
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
export:: INSTALL_FILES
|
||||
|
||||
64
mozilla/security/psm/lib/client/manifest.mn
Normal file
64
mozilla/security/psm/lib/client/manifest.mn
Normal file
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
CORE_DEPTH = ../../..
|
||||
DEPTH = ../../..
|
||||
|
||||
EXPORTS = \
|
||||
cmtcmn.h \
|
||||
cmtjs.h \
|
||||
cmtclist.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
|
||||
CSRCS = cmtinit.c \
|
||||
cmtssl.c \
|
||||
cmtutils.c \
|
||||
cmtcert.c \
|
||||
cmthash.c \
|
||||
cmtpkcs7.c \
|
||||
cmtres.c \
|
||||
cmtjs.c \
|
||||
cmtevent.c \
|
||||
cmtpasswd.c \
|
||||
cmtadvisor.c \
|
||||
cmtrng.c \
|
||||
cmtsdr.c \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES = nspr security
|
||||
|
||||
LIBRARY_NAME = cmt
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/include
|
||||
128
mozilla/security/psm/lib/client/sample/Makefile
Normal file
128
mozilla/security/psm/lib/client/sample/Makefile
Normal file
@@ -0,0 +1,128 @@
|
||||
#! gmake
|
||||
#
|
||||
# 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 the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
ifneq ($(OS_ARCH), WINNT)
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
# On linux, we link with libstdc++
|
||||
CPLUSPLUSRUNTIME = -L /usr/lib -lstdc++ -lm
|
||||
else
|
||||
# libC, presumably, is what we must link with elsewhere
|
||||
CPLUSPLUSRUNTIME = -lC -lm
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), SunOS)
|
||||
ifeq ($(OS_RELEASE), 5.5.1)
|
||||
OS_LIBS += -ldl -lsocket -lnsl -lthread -lposix4
|
||||
endif
|
||||
ifeq ($(OS_RELEASE), 5.6)
|
||||
OS_LIBS += -ldl -lsocket -lnsl -lthread -lposix4
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
ifdef USE_PTHREADS
|
||||
# Replace OS_LIBS, because the order of libpthread, libdl, and libc are
|
||||
# very important. Otherwise you get horrible crashes.
|
||||
OS_LIBS = -lpthread -ldl -lc
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
LDFLAGS += /NODEFAULTLIB:library
|
||||
endif
|
||||
|
||||
EXTRA_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)cmt.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)protocol.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
EXTRA_LIBS += wsock32.lib \
|
||||
winmm.lib \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
link:
|
||||
if test -f $(PROGRAM); then \
|
||||
echo "rm $(PROGRAM)"; \
|
||||
rm $(PROGRAM); \
|
||||
fi; \
|
||||
gmake \
|
||||
|
||||
build_sample:
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
cd $(CORE_DEPTH)/coreconf; gmake
|
||||
endif
|
||||
cd $(CORE_DEPTH)/security; gmake import; gmake export
|
||||
cd ../../protocol; gmake
|
||||
cd ..; gmake
|
||||
gmake
|
||||
|
||||
250
mozilla/security/psm/lib/client/sample/appsock.c
Normal file
250
mozilla/security/psm/lib/client/sample/appsock.c
Normal file
@@ -0,0 +1,250 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "appsock.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
CMT_SocketFuncs socketFuncs = {
|
||||
APP_GetSocket,
|
||||
APP_Connect,
|
||||
APP_VerifyUnixSocket,
|
||||
APP_Send,
|
||||
APP_Select,
|
||||
APP_Receive,
|
||||
APP_Shutdown,
|
||||
APP_Close
|
||||
};
|
||||
|
||||
CMTSocket APP_GetSocket(int unixSock)
|
||||
{
|
||||
APPSocket *sock;
|
||||
int on = 1;
|
||||
|
||||
#ifndef XP_UNIX
|
||||
if (unixSock) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
sock = malloc(sizeof(APPSocket));
|
||||
if (sock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (unixSock) {
|
||||
sock->sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
} else {
|
||||
sock->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
if (sock->sock < 0) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
if (!unixSock &&
|
||||
setsockopt(sock->sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&on,
|
||||
sizeof(on))) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sock->isUnix = unixSock;
|
||||
#ifdef XP_UNIX
|
||||
memset (&sock->servAddr, 0, sizeof(struct sockaddr_un));
|
||||
#endif
|
||||
return (CMTSocket)sock;
|
||||
}
|
||||
|
||||
CMTStatus APP_Connect(CMTSocket sock, short port, char *path)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
struct sockaddr_in iServAddr;
|
||||
const struct sockaddr *servAddr;
|
||||
size_t addrLen;
|
||||
int error;
|
||||
|
||||
if (cmSock->isUnix){
|
||||
#ifndef XP_UNIX
|
||||
return CMTFailure;
|
||||
#else
|
||||
cmSock->servAddr.sun_family = AF_UNIX;
|
||||
memcpy(&cmSock->servAddr.sun_path, path, strlen(path)+1);
|
||||
servAddr = (const struct sockaddr*)&cmSock->servAddr;
|
||||
addrLen = sizeof(cmSock->servAddr);
|
||||
#endif
|
||||
} else {
|
||||
iServAddr.sin_family = AF_INET;
|
||||
iServAddr.sin_port = htons(port);
|
||||
iServAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
servAddr = (const struct sockaddr*)&iServAddr;
|
||||
addrLen = sizeof(struct sockaddr_in);
|
||||
}
|
||||
while (connect(cmSock->sock, servAddr, addrLen) != 0) {
|
||||
#ifdef WIN32
|
||||
error = WSAGetLastError();
|
||||
if (error == WSAEISCONN) {
|
||||
break;
|
||||
}
|
||||
if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK) &&
|
||||
(error!= WSAEINVAL)) {
|
||||
goto loser;
|
||||
}
|
||||
#else
|
||||
error = errno;
|
||||
if (error == EISCONN) {
|
||||
break;
|
||||
}
|
||||
if (error != EINPROGRESS) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus APP_VerifyUnixSocket(CMTSocket sock)
|
||||
{
|
||||
#ifndef XP_UNIX
|
||||
return CMTFailure;
|
||||
#else
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
struct stat statbuf;
|
||||
|
||||
if (!cmSock->isUnix) {
|
||||
return CMTFailure;
|
||||
}
|
||||
rv = stat(cmSock->servAddr.sun_path, &statbuf);
|
||||
if (rv < 0) {
|
||||
goto loser;
|
||||
}
|
||||
if (statbuf.st_uid != geteuid()) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
close(cmSock->sock);
|
||||
free(cmSock);
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t APP_Send(CMTSocket sock, void *buffer, size_t length)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*) sock;
|
||||
|
||||
return send(cmSock->sock, buffer, length, 0);
|
||||
}
|
||||
|
||||
CMTSocket APP_Select(CMTSocket *socks, int numsocks, int poll)
|
||||
{
|
||||
APPSocket **sockArr = (APPSocket**)socks;
|
||||
SOCKET nsocks = 0;
|
||||
int i, rv;
|
||||
struct timeval timeout;
|
||||
fd_set readfds;
|
||||
|
||||
#ifdef WIN32
|
||||
win_startover:
|
||||
#endif
|
||||
FD_ZERO(&readfds);
|
||||
for (i=0; i<numsocks; i++) {
|
||||
FD_SET(sockArr[i]->sock, &readfds);
|
||||
if (sockArr[i]->sock > nsocks) {
|
||||
nsocks = sockArr[i]->sock;
|
||||
}
|
||||
}
|
||||
if (poll) {
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
rv = select(nsocks+1, &readfds, NULL, NULL, (poll) ? &timeout : NULL);
|
||||
|
||||
#ifdef WIN32
|
||||
/* XXX Win95/98 Bug (Q177346)
|
||||
* select() with no timeout might return even if there is no data
|
||||
* pending or no error has occurred. To get around this problem,
|
||||
* we loop if these erroneous conditions happen.
|
||||
*/
|
||||
if (poll == 0 && rv == 0) {
|
||||
goto win_startover;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Figure out which socket was selected */
|
||||
if (rv == -1 || rv == 0) {
|
||||
goto loser;
|
||||
}
|
||||
for (i=0; i<numsocks; i++) {
|
||||
if (FD_ISSET(sockArr[i]->sock, &readfds)) {
|
||||
return (CMTSocket)sockArr[i];
|
||||
}
|
||||
}
|
||||
loser:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t APP_Receive(CMTSocket sock, void *buffer, size_t bufSize)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
|
||||
return recv(cmSock->sock, buffer, bufSize, 0);
|
||||
}
|
||||
|
||||
CMTStatus APP_Shutdown(CMTSocket sock)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
|
||||
rv = shutdown(cmSock->sock, 1);
|
||||
return (rv == 0) ? CMTSuccess : CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus APP_Close(CMTSocket sock)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
rv = close(cmSock->sock);
|
||||
#else
|
||||
rv = closesocket(cmSock->sock);
|
||||
#endif
|
||||
free(cmSock);
|
||||
return (rv == 0) ? CMTSuccess : CMTFailure;
|
||||
}
|
||||
69
mozilla/security/psm/lib/client/sample/appsock.h
Normal file
69
mozilla/security/psm/lib/client/sample/appsock.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- Mode: C; tab-width: 4; 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _APPSOCK_H_
|
||||
#define _APPSOCK_H_
|
||||
#include "cmtcmn.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
#endif
|
||||
|
||||
typedef struct APPSocketStr {
|
||||
SOCKET sock;
|
||||
int isUnix;
|
||||
#ifdef XP_UNIX
|
||||
struct sockaddr_un servAddr;
|
||||
#endif
|
||||
} APPSocket;
|
||||
|
||||
extern CMT_SocketFuncs socketFuncs;
|
||||
|
||||
CMTStatus APP_Close(CMTSocket sock);
|
||||
CMTStatus APP_Shutdown(CMTSocket sock);
|
||||
size_t APP_Receive(CMTSocket sock, void *buffer, size_t bufSize);
|
||||
CMTSocket APP_Select(CMTSocket *socks, int numsocks, int poll);
|
||||
size_t APP_Send(CMTSocket sock, void *buffer, size_t length);
|
||||
CMTStatus APP_VerifyUnixSocket(CMTSocket sock);
|
||||
CMTStatus APP_Connect(CMTSocket sock, short port, char *path);
|
||||
CMTSocket APP_GetSocket(int unixSock);
|
||||
|
||||
|
||||
#endif /* _APPSOCK_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user