Exemple #1
0
void slug::slugout(int col)
{
	static int numout = 0;
	if (seen++)
		ERROR "%s slug #%d seen %d times [%s]\n",
			type_name(), serialno(), seen, headstr() WARNING;
	if (type == TM) {
		char *p;
		if ((p = strindex(bufptr(dp), (char *)"x X TM ")))
			p += strlen("x X TM ");		// skip junk
		else
			ERROR "strange TM [%s]\n", headstr() FATAL;
		fprintf(stderr, "%d\t", userpn);	// page # as prefix
		for ( ; p < bufptr((this+1)->dp); p++)
			putc(*p, stderr);
	} else if (type == COORD) {
		for (char *p = bufptr(dp); p < bufptr((this+1)->dp) && *p != '\n'; p++)
			putc(*p, stdout);
		printf(" # P %d X %d", userpn, hpos + col*offset);
		return;
	} else if (type == VBOX) {
		if (numout++ > 0)	// BUG??? might miss something
			printf("s%d\nf%d\n", size, font);
		printf("H%d\n", hpos + col*offset);
	}
	fwrite(bufptr(dp), sizeof(char), (this+1)->dp - dp, stdout);
}
HBufC8* CmsUtils::CreateDEREncodingLC(const CASN1EncBase& aEncoding)
	{	
	TUint len = aEncoding.LengthDER();
	HBufC8* buf = HBufC8::NewMaxLC(len);
	TUint pos = 0;
	TPtr8 bufptr(buf->Des());
	aEncoding.WriteDERL(bufptr, pos);
	return buf;
	}
Exemple #3
0
STATIC void move_buffer(struct buffer FAR *bp, size_t firstbp)
{
  /* connect bp->b_prev and bp->b_next */
  b_next(bp)->b_prev = bp->b_prev;
  b_prev(bp)->b_next = bp->b_next;

  /* insert bp between firstbp and firstbp->b_prev */
  bp->b_prev = bufptr(firstbp)->b_prev;
  bp->b_next = firstbp;
  b_next(bp)->b_prev = FP_OFF(bp);
  b_prev(bp)->b_next = FP_OFF(bp);
}
/**
This method should only be used by CImapAtomParser.
During parsing, a ReAllocL() may be required on the heap buffer that this atom and its 
descendants' string data descriptor points at.
This happens when the heap buffer needs to be expanded.
If this causes the heap buffer's address to change, then this atom and its descendants' 
pointer descriptors need updating.
@param The address of the new heap buffer
@param The address of the data within the heap buffer before the ReAllocL took place.
*/
void CImapAtom::FixupL(const HBufC8 *aNewBuffer, const TText8 *aOldBuffer)
	{
   // Fixup descriptor pointers
	CArrayFixFlat<CImapAtom*>* atomStack = new (ELeave) CArrayFixFlat<CImapAtom*>(10);
	CleanupStack::PushL(atomStack);

	atomStack->AppendL(this);
	CImapAtom* currentAtom;
	while (atomStack->Count() != 0)
   		{
		// Pop the top atom off of the stack
		currentAtom = (*atomStack)[atomStack->Count() - 1];
 		atomStack->ResizeL(atomStack->Count() - 1);
 
		// Fix up the current atom
		if (currentAtom->iAtom.Length()>0)
			{
			// Find offset from start of old buffer
			TInt start=(currentAtom->iAtom.Ptr()-aOldBuffer);

 			// Make new descriptor & assign it
			TPtrC8 bufptr(aNewBuffer->Ptr()+start,currentAtom->iAtom.Length());
			currentAtom->iAtom.Set(bufptr); // Note that we are setting the real iAtom not the copy returned by Atom()
			}
 
		// Add the first sibling to the stack,
		// subsequent siblings are added when this sibling is visited
		CImapAtom* siblingAtom = currentAtom->Next();
		if (siblingAtom)
			{
			atomStack->AppendL(siblingAtom);
			}
   
		// Add child to the stack
		CImapAtom* childAtom = currentAtom->Child();
		if (childAtom)
			{
			atomStack->AppendL(childAtom);
			}			
   		}
   
	CleanupStack::PopAndDestroy(atomStack);
   	}
Exemple #5
0
char *slug::headstr()
{
	const int HEADLEN = 65;
	static char buf[2*HEADLEN];
	int j = 0;
	char *s = bufptr(dp);
	int n = (this+1)->dp - dp;
	if (n >= HEADLEN)
		n = HEADLEN;
	for (int i = 0; i < n; i++)
		switch (s[i]) {
			case '\n':
			case '\t':
			case '\0':
			case ' ':
				break;
			default:
				buf[j++] = s[i];
				break;
		}
	buf[j] = 0;
	return buf;
}
// ----------------------------------------------------------------------------
// CURIContainer::DoInternalizeL
// ----------------------------------------------------------------------------
//
void CURIContainer::DoInternalizeL(RReadStream& aReadStream)
{
    TInt length(aReadStream.ReadUint32L());
    HBufC8* buffer = HBufC8::NewLC(length);
    TPtr8 bufptr(buffer->Des());
    aReadStream.ReadL(bufptr, length);
    if(SIPHeaderLookup::ConvertToSIPURI())
    {
        if(FindSIP(bufptr))
        {
            iSIPURI = CSIPURI::DecodeL(bufptr);
        }
        else
        {
            iUri8 = CreateUri8L(bufptr);
        }
    }
    else
    {
        iUri8 = CreateUri8L(bufptr);
    }
    CleanupStack::PopAndDestroy(buffer);
}
// Add the last atom, given a length
void CImapIO::AddAtomL(const TInt aLength)
	{
	// Note buffer position in an atom
	TPtrC8 bufptr(iBuffer->Ptr()+iAtomStart,aLength);

	// Make a new current atom
	CImapAtom *newAtom=new (ELeave) CImapAtom();

	iAtomArray.AppendL(newAtom);
	// Set pointers in it
	newAtom->Set(bufptr);

	// Add it as a child/sibling to the current atom
	if (iNextIsChild)
		iAtom->AddChild(newAtom);
	else
		iAtom->AddNext(newAtom);

	// The next item should be a sibling
	iNextIsChild=EFalse;

	// Make new current
	iAtom=newAtom;
	}
Exemple #8
0
	void MorphErode::erodeU8( Image& dst, const Image& src, size_t radius ) const
	{
		size_t step = radius * 2 + 1;
		size_t curbuf;
		size_t w = src.width();
		size_t h = src.height();
		SIMD* simd = SIMD::instance();
		size_t bstride = Math::pad16( w );
		uint8_t** buf;
		size_t i;

		IMapScoped<uint8_t> mapdst( dst );
		IMapScoped<const uint8_t> mapsrc( src );

		/* allocate and fill buffer */
		ScopedBuffer<uint8_t,true> bufmem( bstride * step );
		ScopedBuffer<uint8_t*,true> bufptr( step );

		buf = bufptr.ptr();
		buf[ 0 ] = bufmem.ptr();
		for( i = 0; i < step; i++ ) {
			if( i != 0 )
				buf[ i ] = buf[ i - 1 ] + bstride;
			simd->erodeSpanU8( buf[ i ], mapsrc.ptr(), w, radius );
			mapsrc++;
		}

		/* upper border */
		simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, radius + 1, w );
		for( i = 1; i < radius; i++ ) {
			uint8_t* prev = mapdst.ptr();
			mapdst++;
			simd->MinValueU8( mapdst.ptr(), ( const uint8_t* ) prev, ( const uint8_t* ) buf[ radius + 1 + i ], w );
		}
		mapdst++;

		/* center */
		curbuf = 0;
		i = h - 2 * radius - 1;
		simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w );
		mapdst++;
		while( i-- ) {
			simd->erodeSpanU8( buf[ curbuf ], mapsrc.ptr(), w, radius );
			curbuf = ( curbuf + 1 ) % step;
			simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w );
			mapdst++;
			mapsrc++;
		}

		/* lower border */
		/* reorder buffer */
		ScopedBuffer<uint8_t*,true> bufptr2( step );
		uint8_t** buf2 = bufptr2.ptr();
		for( i = 0; i < step; i++ )
			buf2[ i ] = buf[ ( curbuf + i ) % step ];

		for( i = 1; i <= radius; i++ ) {
			simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) ( buf2 + i ), step - i, w );
			mapdst++;
		}
	}
Exemple #9
0
void CX520AttributeTypeAndValue::ConstructL(TAttributeType aType, const TDesC8& aValue)
	{
	// iType is string representation of OID corresponding to the aType.
	TPtrC ptr;
	TInt maxlen = 64; // a reasonable default
	TTagType type = EASN1PrintableString; // the default for all except email, unstructured name and domain component
	switch(aType)
		{
		case ECommonName: 
			ptr.Set(KX520CommonName); 
			maxlen = KX520MaxCNLength;
			break;
		case ELocalityName:
			ptr.Set(KX520LocalityName);
			maxlen = KX520MaxLLength;
			break;
		case EStateOrProvinceName:
			ptr.Set(KX520StateOrProvinceName);
			maxlen = KX520MaxSOPLength;
			break;
		case EPostalCode:
			ptr.Set(KX520PostalCode);
			maxlen = KX520MaxPostalCodeLength;
			break;
		case EOrganizationName:
			ptr.Set(KX520OrganizationName);
			maxlen = KX520MaxOLength;
			break;
		case EOrganizationalUnitName:
			ptr.Set(KX520OrganizationalUnitName);
			maxlen = KX520MaxOULength;
			break;
		case ETitle:
			ptr.Set(KX520Title);
			maxlen = KX520MaxTLength;
			break;
		case EDNQualifier:
			ptr.Set(KX520DNQualifier);
			maxlen = 64; // no information was found on this one, so set to a safe minimum
			break;
		case ECountryName:
			ptr.Set(KX520CountryName);
			maxlen = KX520MaxCNLength;
			break;
		case EGivenName:
			ptr.Set(KX520GivenName);
			maxlen = KX520MaxGNLength;
			break;
		case ESurname:
			ptr.Set(KX520Surname);
			maxlen = KX520MaxSLength;
			break;
		case EInitials:
			ptr.Set(KX520Initials);
			maxlen = KX520MaxILength;
			break;
		case EGenerationQualifier:
			ptr.Set(KX520GenerationQualifier);
			maxlen = KX520MaxGQLength;
			break;
		case EPKCS9EmailAddress:
			ptr.Set(KPKCS9EmailAddress);
			maxlen = KPKCS9MaxEmailAddressLength;
			type = EASN1IA5String;
			break;
		case ESerialNumber:
			ptr.Set(KX520SerialNumber);
			maxlen = KX520MaxSNLength;
			break;
		case ERFC2247DomainComponent:
			ptr.Set(KRFC2247DomainComponent);
			maxlen = KRFC2247MaxDomainComponentLength;
			type = EASN1IA5String;
			break;
		case ERFC2256Street:
			ptr.Set(KRFC2256Street);
			maxlen = KRFC2256StreetLength;
			break;
		case EPKCS9UnstructuredName:
			{
			ptr.Set(KPKCS9UnstructuredName);
			maxlen = KPKCS9MaxUnstructuredNameLength;
			// Determine the encoded value. It could be a IA5String or a UTF8String
			TASN1DecGeneric decoderGeneric(aValue);
			decoderGeneric.InitL();
			type = decoderGeneric.Tag();	
			break;	
			}
		case EX520Description:
			{
			ptr.Set(KX520Description);
			maxlen = KX520MaxDescriptionLength;
			break;
			}
		default:
			User::Leave(KErrArgument);
		}
	// Verify if the passed length is within limits
	if(aValue.Length() > maxlen)
		User::Leave(KErrArgument);

	// Allocate OID string for iType
	iType = ptr.AllocL();

	// iValue must be stored in ASN.1-encoded form
	CASN1EncOctetString* enc = CASN1EncOctetString::NewLC(aValue);
	enc->SetTag(type, EUniversal);
	TUint len = enc->LengthDER();
	HBufC8* buf = HBufC8::NewMaxLC(len);
	TUint pos = 0;
	TPtr8 bufptr(buf->Des());
	enc->WriteDERL(bufptr, pos);
	iValue = bufptr.AllocL();
	CleanupStack::PopAndDestroy(2);
	}
Exemple #10
0
STATIC struct buffer FAR *searchblock(ULONG blkno, COUNT dsk)
{
  int fat_count = 0;
  struct buffer FAR *bp;
  size_t lastNonFat = 0;
  size_t uncacheBuf = 0;
  seg bufseg = FP_SEG(firstbuf);
  size_t firstbp = FP_OFF(firstbuf);

#ifdef DISPLAY_GETBLOCK
  printf("[searchblock %d, blk %ld, buf ", dsk, blkno);
#endif

  /* Search through buffers to see if the required block  */
  /* is already in a buffer                               */

  bp = MK_FP(bufseg, firstbp);
  do
  {
    if ((bp->b_blkno == blkno) &&
        (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
    {
      /* found it -- rearrange LRU links      */
#ifdef DISPLAY_GETBLOCK
      printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));
#endif
      bp->b_flag &= ~BFR_UNCACHE;  /* reset uncache attribute */
      if (FP_OFF(bp) != firstbp)
      {
        *(UWORD *)&firstbuf = FP_OFF(bp);
        move_buffer(bp, firstbp);
      }
      return bp;
    }

    if (bp->b_flag & BFR_UNCACHE)
      uncacheBuf = FP_OFF(bp);

    if (bp->b_flag & BFR_FAT)
      fat_count++;
    else
      lastNonFat = FP_OFF(bp);
    bp = b_next(bp);
  } while (FP_OFF(bp) != firstbp);

  /*
     now take either the last buffer in chain (not used recently)
     or, if we are low on FAT buffers, the last non FAT buffer
   */

  if (uncacheBuf)
  {
    bp = bufptr(uncacheBuf);
  }
  else if (bp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat)
  {
    bp = bufptr(lastNonFat);
  }
  else
  {
    bp = b_prev(bufptr(firstbp));
  }

  bp->b_flag |= BFR_UNCACHE;  /* set uncache attribute */

#ifdef DISPLAY_GETBLOCK
  printf("MISS, replace %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));
#endif

  if (FP_OFF(bp) != firstbp)          /* move to front */
  {
    move_buffer(bp, firstbp);
    *(UWORD *)&firstbuf = FP_OFF(bp);
  }
  return bp;
}
// Process the received buffer, creating atoms as we go
void CImapIO::ProcessBufferL()
	{
	// Process the buffer
	TChar byte;

	DBG((LogText(_L8("CImapIO::ProcessBuffer(iParserState=%d, Length=%d)"),iParserState,iReceive.Length())));

	for(TInt pos=0;pos<iReceive.Length();pos++)
		{
		// Note that we've processed stuff
		iBytesRead++;

		// Byte to process
		byte=iReceive[pos];

		switch(iParserState)
			{
		case EIOStateAtomWait:
			switch(byte)
				{
			case '(':
			case '[':
			case '<':
				{
				// Make a new current atom
				CImapAtom *newAtom=new (ELeave) CImapAtom();

				iAtomArray.AppendL(newAtom);
				// Add it as a sibling to the current atom
				if (iNextIsChild)
					iAtom->AddChild(newAtom);
				else
					iAtom->AddNext(newAtom);

				// The next item should be a child
				iNextIsChild=ETrue;

				// Push current atom onto atom stack, make new current
				iAtom=newAtom;
				PushL(iAtom);

				// Store the open bracket in the buffer, so we can tell what it is
				TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1);
				BufferAppendL(byte);
				iAtom->Set(bufptr);

				break;
				}

			case ')':
			case ']':
				// End of this nesting level: pop last atom off stack and
				// make it the new current one
				iAtom=PopL();

				// Any new atoms will be siblings, not children
				iNextIsChild=EFalse;

				break;

			case '{':
				// Start of a literal length
				iLiteralLength=0;
				iParserState=EIOStateLiteralLength;
				break;

			case ' ':
				// Whitespace. Ignore! This state only happens with whitespace
				// after a close )] or a endquote "
				break;

			case '\r':
				// Newline after a close )] or endquote "
				iParserState=EIOStateWaitLF;
				break;

			case '\"':
				// Quotes: we don't keep them, so the atom starts at the next
				// character.
				iAtomStart=iBuffer->Length();
				iParserState=EIOStateInAtom;
				iParserQuoted=ETrue;
				iGotEscape=EFalse;
				break;

			default:
				// Start new atom in buffer
				iAtomStart=iBuffer->Length();
				BufferAppendL(byte);
				iParserState=EIOStateInAtom;
				iParserQuoted=EFalse;
				break;
				}
			break;

		case EIOStateInAtom:
			if (iParserQuoted)
				{
				// Look for another quote
				if (byte=='\"')
					{
					// Just had an escape character?
					if (iGotEscape)
						{
						// Add the character
						BufferAppendL(byte);
						iGotEscape=EFalse;
						}
					else
						{
						// It's the terminator: Add the atom, minus the quotes
						AddAtomL();
						iParserState=EIOStateAtomWait;
						}
					}
				// fix for INC51597 and DEF053082:if a " has been missed out by the server, this will end the atom at a \r
				else if(!iGotEscape && byte == '\r')
					{
					AddAtomL();
					iParserState = EIOStateWaitLF;
					}
				else
					{
					// Escape character?
					if (!iGotEscape && byte=='\\')
						{
						// Got one
						iGotEscape=ETrue;
						}
					else
						{
						// Add to buffer
						BufferAppendL(byte);
						iGotEscape=EFalse;
						}
					}
				}
			else
				{
				if (byte==' ' || byte=='\r')
					{
					AddAtomL();
				
					// Either go back to looking for an atom, or a LF
					iParserState=(byte=='\r')?EIOStateWaitLF:EIOStateAtomWait;
					}
				else if (byte=='(' || byte=='[')
					{
					// Add this atom
					AddAtomL();

					// Make a new current atom
					CImapAtom *newAtom=new (ELeave) CImapAtom();
					iAtomArray.AppendL(newAtom);

					// Add it as a sibling to the current atom
					if (iNextIsChild)
						iAtom->AddChild(newAtom);
					else
						iAtom->AddNext(newAtom);

					// The next item should be a child
					iNextIsChild=ETrue;

					// Push current atom onto atom stack, make new current
					iAtom=newAtom;
					PushL(iAtom);

					// Store the open bracket in the buffer, so we can tell what it is
					TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1);
					BufferAppendL(byte);
					iAtom->Set(bufptr);

					iParserState=EIOStateAtomWait;
					}
				else if (byte==')' || byte==']' || byte == '>')
					{
					// Although these bytes usually indicate the end of an atom,
					// they can also legitimately appear in a text field.
					// If this is the end of an atom, then it must be a child or
					// sibling atom in which case there will be an entry on the atom
					// stack. If there is no entry on the atom stack, then this must
					// be a text field so just add the byte to the buffer.
					if (iAtomStack.Count() > 0)
						{
						// Add this atom
						AddAtomL();

						// End of this nesting level: pop last atom off stack and
						// make it the new current one
						iAtom=PopL();

						// Any new atoms will be siblings, not children
						iNextIsChild=EFalse;

						iParserState=EIOStateAtomWait;
						}
					else
						{
						BufferAppendL(byte);
						}
					}
				else
					{
					// Add to buffer
					BufferAppendL(byte);
					}
				}
			break;

		case EIOStateWaitLF:
			// After LF, this is end of line, finish!
			if (byte=='\n')
				{
				// Remove everything from the buffer, we've finished
				iReceive.Delete(0,pos+1);

				// Reset bytes read count & complete
				iBytesRead=0;

				// Complete with KErrFoundEOL
				DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete in EIOStateWaitLF"))));
				Complete(KErrFoundEOL);
				return;
				}
			break;

		case EIOStateLiteralLength:
			// Digit?
			if (byte.IsDigit())
				{
				// Add it to the total
				iLiteralLength=(iLiteralLength*10)+(byte-(TChar)'0');
				if (iLiteralLength <0)
					User::Leave(KErrCorrupt);
				}
			else if (byte=='}')
				{
				// Need to skip CR, LF
				iLiteralSkip=2;
				iParserState=EIOStateLiteralSkip;

				// Add the atom (with the length we know, but no data) to the
				// structure now, so that the partial structure can be parsed.
				iAtomStart=iBuffer->Length();
				AddAtomL(iLiteralLength);
				}
			break;

		case EIOStateLiteralSkip:
			// Skipping...
			if (--iLiteralSkip==0)
				{
				// Is literal 0 bytes long?
				if (iLiteralLength==0)
					{
					// Nothing to follow
					iParserState=EIOStateAtomWait;
					}
				else
					{
					// Non-empty literal: go into fetch state
					iParserState=EIOStateLiteralFetch;
					}
				}
			break;

		case EIOStateLiteralFetch:
			// Fetching
			
			TInt fetchLength(0);
			if(KReceiveBuffer<iLiteralLength)
				{
				fetchLength = KReceiveBuffer;
				}
			else
				{
				fetchLength = iLiteralLength;
				}
			
			if(fetchLength > iReceive.Length()-pos)
				{
				fetchLength = iReceive.Length()-pos;
				}
// 			need to extend buffer ?
			DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(1):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
			if (iBuffer->Length() + iLiteralLength > iBufferSize)
				{
				HBufC8 *oldbuffer=iBuffer;
				const TText8 *oldbufptr=iBuffer->Ptr();
			
				// Extend by extra amount + round up by KIOBufferGranularity
				iBufferSize += iLiteralLength;
				iBufferSize += (KIOBufferGranularity - (iBufferSize % KIOBufferGranularity));
				iBuffer=iBuffer->ReAllocL(iBufferSize);

				// Buffer moved?
				if (iBuffer!=oldbuffer)
					{
					// Fixup buffer tree pointers
					iRootAtom->FixupL(iBuffer,oldbufptr);
					}
				DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(2):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
				}
			iBuffer->Des().Append(iReceive.Mid(pos,fetchLength));
			// adjust loop to account for data copy
			pos+=fetchLength-1;
			iLiteralLength-=fetchLength; 			
			DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(3):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
			if (iLiteralLength==0)
				{
				// Atom is already saved (we add literal atoms before they
				// are stored)
				iParserState=EIOStateAtomWait;
				}
			break;
			}
		}
	
	iReceive.Zero();
	// At start of line, or if we're not doing a partial return, we need to
	// queue another read here
	if (iBytesRead==0 || !iReturnPartialLine)
		{
		// We've processed this buffer: queue a read. We only complete (above)
		// when we've had a whole reply, including terminating CRLF.
		DBG((LogText(_L8("CImapIO::ProcessBufferL(): queuing read, iBytesRead=%d, iReturnPartialLine is %d"), iBytesRead, iReturnPartialLine)));
                QueueRead();
		}
	else
		{
		// Have we got 'enough' of the partial line?
		if (iBytesRead<iBytesToRead)
			{
			// Not enough yet: queue another partial read, for the remainder
			iBytesToRead-=iBytesRead;
			QueueRead();
			}
		else
			{
			// Partial line parsed: return success (client will requeue)
			DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete on partial line"))));
			Complete(KErrNone);
			}
		}
	}
Exemple #12
0
	static void morphTemplate( Image& dst, const Image& src, size_t radius,
								void ( SIMD::*hfunc )( TYPE*, const TYPE*, size_t, size_t ) const,
								void ( SIMD::*hfuncborder )( TYPE*, const TYPE*, const TYPE*, size_t ) const,
								void ( SIMD::*vfunc )( TYPE*, const TYPE**, size_t, size_t ) const
							 )
	{
		SIMD* simd = SIMD::instance();
		const size_t boxsize = radius * 2 + 1;
		size_t curbuf;
		size_t w = src.width();
		size_t h = src.height();
		size_t bstride = Math::pad16( sizeof( TYPE ) * w ) / sizeof( TYPE ); //FIXME: does this always work - it should
		TYPE** buf;
		size_t i;

		IMapScoped<TYPE> mapdst( dst );
		IMapScoped<const TYPE> mapsrc( src );

		/* allocate and fill buffer */
		ScopedBuffer<TYPE,true> bufmem( bstride * boxsize );
		ScopedBuffer<TYPE*,true> bufptr( boxsize );

		buf = bufptr.ptr();
		buf[ 0 ] = bufmem.ptr();
		for( i = 0; i < boxsize; i++ ) {
			if( i != 0 )
				buf[ i ] = buf[ i - 1 ] + bstride;
			( simd->*hfunc )( buf[ i ], mapsrc.ptr(), w, radius );
			mapsrc++;
		}

		/* upper border */
		( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, radius + 1, w );
		for( i = 1; i < radius; i++ ) {
			TYPE* prev = mapdst.ptr();
			mapdst++;
			( simd->*hfuncborder )( mapdst.ptr(), ( const TYPE* ) prev, ( const TYPE* ) buf[ radius + 1 + i ], w );
		}
		mapdst++;

		/* center */
		curbuf = 0;
		i = h - 2 * radius - 1;
		( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w );
		mapdst++;
		while( i-- ) {
			( simd->*hfunc )( buf[ curbuf ], mapsrc.ptr(), w, radius );
			curbuf = ( curbuf + 1 ) % boxsize;
			( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w );
			mapdst++;
			mapsrc++;
		}

		/* lower border */
		/* reorder buffer */
		ScopedBuffer<TYPE*,true> bufptr2( boxsize );
		TYPE** buf2 = bufptr2.ptr();
		for( i = 0; i < boxsize; i++ )
			buf2[ i ] = buf[ ( curbuf + i ) % boxsize ];

		for( i = 1; i <= radius; i++ ) {
			( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) ( buf2 + i ), boxsize - i, w );
			mapdst++;
		}
	}
Exemple #13
0
slug getslug(FILE *fp)
{
	if (inbuf == NULL) {
		if ((inbuf = (char *)malloc(ninbuf = DELTABUF)) == NULL)
			ERROR "no room for %ld character input buffer\n", ninbuf FATAL;
		inbp = inbuf;
	}
	if (wherebuf() > (ssize_t)(ninbuf-5000)) {
		// this is still flaky -- lines can be very long
		int where = wherebuf();	// where we were
		if ((inbuf = (char *)realloc(inbuf, ninbuf += DELTABUF)) == NULL)
			ERROR "no room for %ld character input buffer\n", ninbuf FATAL;
		ERROR "grew input buffer to %ld characters\n", ninbuf WARNING;
		inbp = inbuf + where;	// same offset in new array
	}
	static int baseV = 0;	// first V command of preceding slug
	static int curV = 0, curH = 0;
	static int font = 0, size = 0;
	static int baseadj = 0;
	static int ncol = 1, offset = 0;	// multi-column stuff
	char str[1000], str2[1000], buf[3000], *p;
	int firstV = 0, firstH = 0;
	int maxV = curV;
	int ocurV = curV, mxv = 0, dx = 0;
	int sawD = 0;		// > 0 if have seen D...
	slug ret;
	ret.serialnum = serialnum++;
	ret.type = VBOX;	// use the same as last by default
	ret.dv = curV - baseV;
	ret.hpos = curH;
	ret.base =  ret.parm = ret.parm2 = ret.seen = 0;
	ret.font = font;
	ret.size = size;
	ret.dp = wherebuf();
	ret.ncol = ncol;
	ret.offset = offset;
	ret.linenum = linenum;	// might be low

	for (;;) {
		int c, m, n;	// for input values
		int sign;		// hoisted from case 'h' below
		switch (c = getc(fp)) {
		case EOF:
			ret.type = EOF;
			ret.dv = 0;
			if (baseadj)
				printf("# adjusted %d bases\n", baseadj);
			printf("# %d characters, %d lines\n", wherebuf(), linenum);
			return ret;
		case 'V':
			fscanf(fp, "%d", &n);
			if (firstV++ == 0) {
				ret.dv = n - baseV;
				baseV = n;
			} else {
				sprintf(buf, "v%d", n - curV);
				adds(buf);
			}
			curV = n;
			maxV = max(maxV, curV);
			break;
		case 'H':		// absolute H motion
			fscanf(fp, "%d", &n);
			if (firstH++ == 0) {
				ret.hpos = n;
			} else {
				sprintf(buf, "h%d", n - curH);
				adds(buf);
			}
			curH = n;
			break;
		case 'h':		// relative H motion
			addc(c);
			sign = 1;
			if ((c = getc(fp)) == '-') {
				addc(c);
				sign = -1;
				c = getc(fp);
			}
			for (n = 0; isdigit(c); c = getc(fp)) {
				addc(c);
				n = 10 * n + c - '0';
			}
			curH += n * sign;
			ungetc(c, fp);
			break;
		case 'x':	// device control: x ...
			addc(c);
			fgets(buf, sizeof(buf), fp);
			linenum++;
			adds(buf);
			if (buf[0] == ' ' && buf[1] == 'X') {	// x X ...
				if (2 != sscanf(buf+2, "%s %d", str, &n))
					n = 0;
				if (eq(str, "SP")) {	// X SP n
					ret.type = SP;	// paddable SPace
					ret.dv = n;	// of height n
				} else if (eq(str, "BS")) {
					ret.type = BS;	// Breakable Stream
					ret.parm = n;	// >=n VBOXES on a page
				} else if (eq(str, "BF")) {
					ret.type = BF;	// Breakable Float
					ret.parm = ret.parm2 = n;
							// n = pref center (as UF)
				} else if (eq(str, "US")) {
					ret.type = US;	// Unbreakable Stream
					ret.parm = n;
				} else if (eq(str, "UF")) {
					ret.type = UF;	// Unbreakable Float
					ret.parm = ret.parm2 = n;
							// n = preferred center
							// to select several,
							// use several UF lines
				} else if (eq(str, "PT")) {
					ret.type = PT;	// Page Title
					ret.parm = n;
				} else if (eq(str, "BT")) {
					ret.type = BT;	// Bottom Title
					ret.parm = n;
				} else if (eq(str, "END")) {
					ret.type = END;
					ret.parm = n;
				} else if (eq(str, "TM")) {
					ret.type = TM;	// Terminal Message
					ret.dv = 0;
				} else if (eq(str, "COORD")) {
					ret.type = COORD;// page COORDinates
					ret.dv = 0;
				} else if (eq(str, "NE")) {
					ret.type = NE;	// NEed to break page
					ret.dv = n;	// if <n units left
				} else if (eq(str, "MC")) {
					ret.type = MC;	// Multiple Columns
					sscanf(buf+2, "%s %d %d",
						str, &ncol, &offset);
					ret.ncol = ncol;
					ret.offset = offset;
				} else if (eq(str, "CMD")) {
					ret.type = CMD;	// CoMmaNd
					sscanf(buf+2, "%s %s", str2, str);
					if (eq(str, "FC"))	// Freeze 2-Col
						ret.parm = FC;
					else if (eq(str, "FL"))	// FLush
						ret.parm = FL;
					else if (eq(str, "BP"))	// Break Page
						ret.parm = BP;
					else ERROR "unknown command %s\n",
						str WARNING;
				} else if (eq(str, "PARM")) {
					ret.type = PARM;// PARaMeter
					sscanf(buf+2, "%s %s %d", str2, str, &ret.parm2);
					if (eq(str, "NP"))	// New Page
						ret.parm = NP;
					else if (eq(str, "FO"))	// FOoter
						ret.parm = FO;
					else if (eq(str, "PL")) // Page Length
						ret.parm = PL;
					else if (eq(str, "MF")) // MinFull
						ret.parm = MF;
					else if (eq(str, "CT")) // ColTol
						ret.parm = CT;
					else if (eq(str, "WARN")) //WARNings?
						ret.parm = WARN;
					else if (eq(str, "DBG"))// DeBuG
						ret.parm = DBG;
					else ERROR "unknown parameter %s\n",
						str WARNING;
				} else
					break;		// out of switch
				if (firstV > 0)
					ERROR "weird x X %s in mid-VBOX\n",
						str WARNING;
				return ret;
			}
			break;
		case 'n':	// end of line
			fscanf(fp, "%d %d", &n, &m);
			ret.ht = n;
			ret.base = m;
			getc(fp);	// newline
			linenum++;
			sprintf(buf, "n%d %d\n", ret.ht, ret.base);
			adds(buf);
			if (!firstV++)
				baseV = curV;
			// older incarnations of this program used ret.base
			// in complicated and unreliable ways;
			// example:  if ret.ht + ret.base < ret.dv, ret.base = 0
			// this was meant to avoid double-counting the space
			// around displayed equations; it didn't work
			// Now, we believe ret.base = 0, otherwise we give it
			// a value we have computed.
			if (ret.base == 0 && sawD == 0)
				return ret;	// don't fiddle 0-bases
			if (ret.base != maxV - baseV) {
				ret.base = maxV - baseV;
				baseadj++;
			}
			if (ret.type != VBOX)
				ERROR "%s slug (type %d) has base = %d\n",
					ret.type_name(), ret.type, ret.base WARNING;
			return ret;
		case 'p':	// new page
			fscanf(fp, "%d", &n);
			ret.type = PAGE;
			curV = baseV = ret.dv = 0;
			ret.parm = n;	// just in case someone needs it
			return ret;
		case 's':	// size change snnn
			fscanf(fp, "%d", &size);
			sprintf(buf, "s%d\n", size);
			adds(buf);
			break;
		case 'f':	// font fnnn
			fscanf(fp, "%d", &font);
			sprintf(buf, "f%d\n", font);
			adds(buf);
			break;
		case '\n':
			linenum++;
			/* fall through */
		case ' ':
			addc(c);
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			// two motion digits plus a character
			addc(c);
			n = c - '0';
			addc(c = getc(fp));
			curH += 10 * n + c - '0';
			addc(getc(fp));
			if (!firstV++)
				baseV = curV;
			break;
		case 'c':	// single ascii character
			addc(c);
			addc(getc(fp));
			if (!firstV++)
				baseV = curV;
			break;
		case 'C':	// Cxyz\n
		case 'N':	// Nnnn\n
			addc(c);
			while ((c = getc(fp)) != ' ' && c != '\n')
				addc(c);
			addc(c);
			if (!firstV++)
				baseV = curV;
			linenum++;
			break;
		case 'D':	// draw function: D.*\n
			sawD++;
			p = bufptr(wherebuf());	// where does the D start
			addc(c);
			while ((c = getc(fp)) != '\n')
				addc(c);
			addc(c);
			if (!firstV++)
				baseV = curV;
			ocurV = curV, mxv = 0, dx = 0;
			curV += getDy(p, &dx, &mxv);	// figure out how big it is
			maxV = max(max(maxV, curV), ocurV+mxv);
			curH += dx;
			linenum++;
			break;
		case 'v':	// relative vertical vnnn
			addc(c);
			if (!firstV++)
				baseV = curV;
			sign = 1;
			if ((c = getc(fp)) == '-') {
				addc(c);
				sign = -1;
				c = getc(fp);
			}
			for (n = 0; isdigit(c); c = getc(fp)) {
				addc(c);
				n = 10 * n + c - '0';
			}
			ungetc(c, fp);
			curV += n * sign;
			maxV = max(maxV, curV);
			addc('\n');
			break;
		case 'w':	// word space
			addc(c);
			break;
		case '#':	// comment
			addc(c);
			while ((c = getc(fp)) != '\n')
				addc(c);
			addc('\n');
			linenum++;
			break;
		default:
			ERROR "unknown input character %o %c (%50.50s)\n",
				c, c, bufptr(wherebuf()-50) WARNING;
			break;
		}
	}
}